Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions doc/man5/flux-config-resource.rst
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,21 @@ rediscover
(optional) If true, force rediscovery of resources using HWLOC, rather
then using the R and HWLOC XML from the enclosing instance.

reserve
(optional) A string value that defines cores to reserve for the OS
and the broker ranks on which to reserve them. The argument is specified
as::

cores[@ranks] [cores[@ranks]]...

where cores is an RFC 22 idset specifying the cores to reserve, and
the optional ranks is an RFC 22 idset specifying the ranks on which to
reserve them. If ``@ranks`` is not supplied, then cores will be reserved
on all ranks. Multiple instances of ``cores[@ranks]`` may be specified
(separated by whitespace) to reserve a different set of cores on different
ranks. For example, ``0-3@0 0`` would reserve cores 0-3 on rank 0 and
core 0 on all other ranks.

Note that updates to the resource table are ignored until the next Flux
restart.

Expand Down
2 changes: 1 addition & 1 deletion src/cmd/flux-resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ class FluxResourceConfig(UtilConfig):
"description": "Format including resource list details",
"format": (
"{state:>10} ?+:{queue:<5} ?:{propertiesx:<10.10+} {nnodes:>6} "
"+:{ncores:>6} ?:+{ngpus:>5} {rlist}"
"+:{ncores:>6} ?+:{ngpus:>5} {rlist}"
),
},
}
Expand Down
1 change: 1 addition & 0 deletions src/common/librlist/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ librlist_la_SOURCES = \
match.c \
rlist.c \
rlist.h \
corespec.c \
rlist_private.h

librlist_hwloc_la_SOURCES = \
Expand Down
187 changes: 187 additions & 0 deletions src/common/librlist/corespec.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
/************************************************************\
* Copyright 2025 Lawrence Livermore National Security, LLC
* (c.f. AUTHORS, NOTICE.LLNS, COPYING)
*
* This file is part of the Flux resource manager framework.
* For details, see https://github.com/flux-framework.
*
* SPDX-License-Identifier: LGPL-3.0
\************************************************************/

#if HAVE_CONFIG_H
#include "config.h"
#endif

#include <errno.h>
#include <string.h>

#include <flux/core.h>
#include <flux/idset.h>

#include "src/common/libczmqcontainers/czmq_containers.h"
#include "src/common/libutil/errprintf.h"

#include "rlist.h"
#include "rnode.h"
#include "rlist_private.h"

struct core_spec {
char *spec;
struct idset *cores;
struct idset *ranks;
};

static void core_spec_destroy (struct core_spec *spec)

Check warning on line 34 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L34

Added line #L34 was not covered by tests
{
if (spec) {
int saved_errno = errno;
idset_destroy (spec->cores);
idset_destroy (spec->ranks);
free (spec->spec);
free (spec);
errno = saved_errno;

Check warning on line 42 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L36-L42

Added lines #L36 - L42 were not covered by tests
}
}

Check warning on line 44 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L44

Added line #L44 was not covered by tests

static struct core_spec *core_spec_create (const char *s, flux_error_t *errp)

Check warning on line 46 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L46

Added line #L46 was not covered by tests
{
idset_error_t error;
struct core_spec *spec;
const char *ranks = NULL;
const char *cores;
int len = -1;

Check warning on line 52 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L48-L52

Added lines #L48 - L52 were not covered by tests

cores = s;
if ((ranks = strchr (cores, '@'))) {
len = ranks - cores;
ranks++;

Check warning on line 57 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L54-L57

Added lines #L54 - L57 were not covered by tests
}
if (!(spec = calloc (1, sizeof (*spec)))
|| !(spec->spec = strdup (s))) {
errprintf (errp, "Out of memory");
goto error;

Check warning on line 62 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L59-L62

Added lines #L59 - L62 were not covered by tests
}
if ((ranks && !(spec->ranks = idset_decode_ex (ranks, -1, 0, 0, &error)))
|| !(spec->cores = idset_decode_ex (cores, len, 0, 0, &error))) {
errprintf (errp, "%s", error.text);
goto error;

Check warning on line 67 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L64-L67

Added lines #L64 - L67 were not covered by tests
}
if ((spec->ranks && idset_count (spec->ranks) == 0)
|| idset_count (spec->cores) == 0) {
errprintf (errp, "ranks/cores cannot be empty");
goto error;

Check warning on line 72 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L69-L72

Added lines #L69 - L72 were not covered by tests
}
return spec;
error:
core_spec_destroy (spec);
return NULL;

Check warning on line 77 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L75-L77

Added lines #L75 - L77 were not covered by tests
}

static struct rnode *core_spec_copy (const struct rnode *orig,

Check warning on line 80 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L80

Added line #L80 was not covered by tests
struct core_spec *spec)
{
struct rnode *n = NULL;

Check warning on line 83 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L83

Added line #L83 was not covered by tests

/* If spec->ranks is NULL, this indicates all ranks
*/
if (!spec->ranks || idset_test (spec->ranks, orig->rank)) {

Check warning on line 87 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L87

Added line #L87 was not covered by tests
/* Create new rnode object with just the cores intersection, keeping
* hostname and properties.
*/
struct idset *ids = idset_intersect (orig->cores->ids, spec->cores);
if (ids != NULL
&& idset_count (ids) > 0
&& (n = rnode_create_idset (orig->hostname, orig->rank, ids))) {
n->properties = zhashx_dup (orig->properties);

Check warning on line 95 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L91-L95

Added lines #L91 - L95 were not covered by tests
}
idset_destroy (ids);

Check warning on line 97 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L97

Added line #L97 was not covered by tests
}
return n;

Check warning on line 99 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L99

Added line #L99 was not covered by tests
}

static void core_spec_destructor (void **item)

Check warning on line 102 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L102

Added line #L102 was not covered by tests
{
if (item) {
struct core_spec *spec = *item;
core_spec_destroy (spec);
*item = NULL;

Check warning on line 107 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L104-L107

Added lines #L104 - L107 were not covered by tests
}
}

Check warning on line 109 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L109

Added line #L109 was not covered by tests

static zlistx_t *core_spec_list_create (const char *core_spec,

Check warning on line 111 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L111

Added line #L111 was not covered by tests
flux_error_t *errp)
{
char *copy;
char *str;
char *spec;
char *sp = NULL;
zlistx_t *l = zlistx_new ();

Check warning on line 118 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L114-L118

Added lines #L114 - L118 were not covered by tests

if (!l || !(copy = strdup (core_spec)))
return NULL;
str = copy;

Check warning on line 122 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L120-L122

Added lines #L120 - L122 were not covered by tests

zlistx_set_destructor (l, core_spec_destructor);

Check warning on line 124 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L124

Added line #L124 was not covered by tests

while ((spec = strtok_r (str, " \t", &sp))) {
struct core_spec *cspec;
if (!(cspec = core_spec_create (spec, errp)))
goto error;
if (!zlistx_add_end (l, cspec)) {
errprintf (errp, "Out of memory");
goto error;

Check warning on line 132 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L126-L132

Added lines #L126 - L132 were not covered by tests
}
str = NULL;
}
free (copy);
return l;
error:
free (copy);
zlistx_destroy (&l);
return NULL;

Check warning on line 141 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L136-L141

Added lines #L136 - L141 were not covered by tests
}

struct rlist *rlist_copy_core_spec (const struct rlist *orig,

Check warning on line 144 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L144

Added line #L144 was not covered by tests
const char *core_spec,
flux_error_t *errp)
{
struct core_spec *spec;
struct rlist *rl = NULL;
zlistx_t *l;

Check warning on line 150 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L148-L150

Added lines #L148 - L150 were not covered by tests

if (!(l = core_spec_list_create (core_spec, errp)))

Check warning on line 152 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L152

Added line #L152 was not covered by tests
return NULL;

spec = zlistx_first (l);
while (spec) {
struct rlist *tmp;
if (!(tmp = rlist_copy_internal (orig,

Check warning on line 158 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L155-L158

Added lines #L155 - L158 were not covered by tests
(rnode_copy_f) core_spec_copy,
(void *) spec))) {
errprintf (errp, "failed to copy spec '%s'", spec->spec);
goto error;

Check warning on line 162 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L161-L162

Added lines #L161 - L162 were not covered by tests
}
if (rl != NULL) {
if (rlist_add (rl, tmp) < 0) {
errprintf (errp,

Check warning on line 166 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L164-L166

Added lines #L164 - L166 were not covered by tests
"rlist_add '%s' failed: %s",
spec->spec,
strerror (errno));
goto error;

Check warning on line 170 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L169-L170

Added lines #L169 - L170 were not covered by tests
}
rlist_destroy (tmp);

Check warning on line 172 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L172

Added line #L172 was not covered by tests
}
else
rl = tmp;
spec = zlistx_next (l);

Check warning on line 176 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L176

Added line #L176 was not covered by tests
}
zlistx_destroy (&l);
return rl;
error:
rlist_destroy (rl);
zlistx_destroy (&l);
return NULL;

Check warning on line 183 in src/common/librlist/corespec.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/corespec.c#L178-L183

Added lines #L178 - L183 were not covered by tests
}

/* vi: ts=4 sw=4 expandtab
*/
32 changes: 17 additions & 15 deletions src/common/librlist/rlist.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,11 +214,9 @@
return 0;
}

typedef struct rnode * (*rnode_copy_f) (const struct rnode *, void *arg);

static struct rlist *rlist_copy_internal (const struct rlist *orig,
rnode_copy_f cpfn,
void *arg)
struct rlist *rlist_copy_internal (const struct rlist *orig,
rnode_copy_f cpfn,
void *arg)
{
struct rnode *n;
struct rlist *rl = rlist_create ();
Expand Down Expand Up @@ -535,17 +533,9 @@
return n;
}

struct rlist *rlist_diff (const struct rlist *rla, const struct rlist *rlb)
int rlist_subtract (struct rlist *rl, const struct rlist *rlb)
{
struct rnode *n;
struct rlist *rl = rlist_create ();

if (!rl || rlist_append (rl, rla) < 0) {
rlist_destroy (rl);
return NULL;
}

n = zlistx_first (rlb->nodes);
struct rnode *n = zlistx_first (rlb->nodes);
while (n) {
/* Attempt to find and "detach" the rank which we're diffing.
*/
Expand All @@ -567,6 +557,18 @@
}
n = zlistx_next (rlb->nodes);
}
return 0;
}

struct rlist *rlist_diff (const struct rlist *rla, const struct rlist *rlb)
{
struct rlist *rl = rlist_create ();
if (!rl
|| rlist_append (rl, rla) < 0
|| rlist_subtract (rl, rlb) < 0) {
rlist_destroy (rl);
return NULL;

Check warning on line 570 in src/common/librlist/rlist.c

View check run for this annotation

Codecov / codecov/patch

src/common/librlist/rlist.c#L569-L570

Added lines #L569 - L570 were not covered by tests
}
return rl;
}

Expand Down
17 changes: 17 additions & 0 deletions src/common/librlist/rlist.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,11 @@ int rlist_append (struct rlist *rl, const struct rlist *rl2);
*/
int rlist_add (struct rlist *rl, const struct rlist *rl2);

/* Subtract resources in `rl2` from `rl`. It is not an error if
* resources in rl2 are not present in `rl`.
*/
int rlist_subtract (struct rlist *rl, const struct rlist *rl2);

/* Return the set difference of 'rlb' from 'rla'.
*/
struct rlist *rlist_diff (const struct rlist *rla, const struct rlist *rlb);
Expand Down Expand Up @@ -287,5 +292,17 @@ char *rlist_properties_encode (const struct rlist *rl);

struct rlist *rlist_from_config (json_t *conf, flux_error_t *errp);

/* Create a copy of rlist 'rl' using 'core_spec', which indicates a
* set of cores via the form:
*
* cores[@ranks] [cores[@ranks]]...
*
* Where 'cores' is an idset of cores to copy and the optional 'ranks'
* and idset of ranks from which to copy them. It is not an error to
* specify cores and or ranks that do not exist in the source rlist 'rl'.
*/
struct rlist *rlist_copy_core_spec (const struct rlist *rl,
const char *spec,
flux_error_t *errp);

#endif /* !HAVE_SCHED_RLIST_H */
6 changes: 6 additions & 0 deletions src/common/librlist/rlist_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,10 @@

int rlist_add_rnode (struct rlist *rl, struct rnode *n);

typedef struct rnode * (*rnode_copy_f) (const struct rnode *, void *arg);

struct rlist *rlist_copy_internal (const struct rlist *orig,
rnode_copy_f cpfn,
void *arg);

#endif /* !HAVE_SCHED_RLIST_PRIVATE_H */
Loading
Loading