Skip to content

Commit

Permalink
Merge pull request flux-framework#2736 from grondo/flux-module-reload
Browse files Browse the repository at this point in the history
flux-module: add reload command
  • Loading branch information
mergify[bot] authored Feb 12, 2020
2 parents 47e59f3 + ebfcade commit 3af5a6b
Show file tree
Hide file tree
Showing 10 changed files with 94 additions and 53 deletions.
5 changes: 5 additions & 0 deletions doc/man1/flux-module.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ Remove module 'name'. The service that will unload the module is
inferred from the name specified on the command line. If '-f, --force'
is used, then do not error if module 'name' is not loaded.

*reload* [--force] 'name' ['module-arguments' ...]::
Reload module 'name'. This is equivalent to running 'flux module remove'
followed by 'flux module load'. It is a fatal error if module 'name' is
not loaded during removal unless the `-f, --force` option is specified.

*list* ['service']::
List modules loaded by 'service', or by flux-broker(1) if 'service' is unspecified.

Expand Down
85 changes: 67 additions & 18 deletions src/cmd/flux-module.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ const int max_idle = 99;
int cmd_list (optparse_t *p, int argc, char **argv);
int cmd_remove (optparse_t *p, int argc, char **argv);
int cmd_load (optparse_t *p, int argc, char **argv);
int cmd_reload (optparse_t *p, int argc, char **argv);
int cmd_info (optparse_t *p, int argc, char **argv);
int cmd_stats (optparse_t *p, int argc, char **argv);
int cmd_debug (optparse_t *p, int argc, char **argv);
Expand Down Expand Up @@ -101,13 +102,27 @@ static struct optparse_subcommand subcommands[] = {
0,
remove_opts,
},
{ "unload",
"[OPTIONS] module",
"Unload module",
cmd_remove,
OPTPARSE_SUBCMD_HIDDEN,
remove_opts,
},
{ "load",
"[OPTIONS] module",
"Load module",
cmd_load,
0,
legacy_opts,
},
{ "reload",
"[OPTIONS] module",
"Reload module",
cmd_reload,
0,
remove_opts,
},
{ "info",
"[OPTIONS] module",
"Display module info",
Expand Down Expand Up @@ -140,7 +155,8 @@ int usage (optparse_t *p, struct optparse_option *o, const char *optarg)
fprintf (stderr, "flux module subcommands:\n");
s = subcommands;
while (s->name) {
fprintf (stderr, " %-15s %s\n", s->name, s->doc);
if (!(s->flags & OPTPARSE_SUBCMD_HIDDEN))
fprintf (stderr, " %-15s %s\n", s->name, s->doc);
s++;
}
exit (1);
Expand Down Expand Up @@ -265,12 +281,11 @@ char *getservice (const char *modname)
return service;
}

int cmd_load (optparse_t *p, int argc, char **argv)
static void module_load (flux_t *h, optparse_t *p, int argc, char **argv)
{
char *modname;
char *modpath;
int n;
flux_t *h;
flux_future_t *f;

if ((n = optparse_option_index (p)) == argc) {
Expand All @@ -291,8 +306,6 @@ int cmd_load (optparse_t *p, int argc, char **argv)
n++;
}

if (!(h = flux_open (NULL, 0)))
log_err_exit ("flux_open");
if (!(f = flux_rpc_pack (h,
topic,
optparse_get_int (p, "rank", FLUX_NODEID_ANY),
Expand All @@ -314,28 +327,24 @@ int cmd_load (optparse_t *p, int argc, char **argv)
json_decref (args);
free (modpath);
free (modname);
}

int cmd_load (optparse_t *p, int argc, char **argv)
{
flux_t *h;
if (!(h = flux_open (NULL, 0)))
log_err_exit ("flux_open");
module_load (h, p, argc, argv);
flux_close (h);
return 0;
}

int cmd_remove (optparse_t *p, int argc, char **argv)
static void module_remove (flux_t *h, const char *modname, optparse_t *p)
{
char *modname;
flux_t *h;
flux_future_t *f;
int n;

if ((n = optparse_option_index (p)) != argc - 1) {
optparse_print_usage (p);
exit (1);
}
modname = argv[n++];

char *service = getservice (modname);
char *topic = xasprintf ("%s.rmmod", service);

if (!(h = flux_open (NULL, 0)))
log_err_exit ("flux_open");
if (!(f = flux_rpc_pack (h,
topic,
optparse_get_int (p, "rank", FLUX_NODEID_ANY),
Expand All @@ -351,10 +360,50 @@ int cmd_remove (optparse_t *p, int argc, char **argv)
flux_future_destroy (f);
free (topic);
free (service);
}

int cmd_remove (optparse_t *p, int argc, char **argv)
{
char *modname;
flux_t *h;
int n;

if ((n = optparse_option_index (p)) != argc - 1) {
optparse_print_usage (p);
exit (1);
}
modname = argv[n++];

if (!(h = flux_open (NULL, 0)))
log_err_exit ("flux_open");

module_remove (h, modname, p);

flux_close (h);
return (0);
}

int cmd_reload (optparse_t *p, int argc, char **argv)
{
char *modname;
char *modpath;
flux_t *h;
int n;

if ((n = optparse_option_index (p)) == argc) {
optparse_print_usage (p);
exit (1);
}
parse_modarg (argv[n], &modname, &modpath);

if (!(h = flux_open (NULL, 0)))
log_err_exit ("flux_open");

module_remove (h, modname, p);
module_load (h, p, argc, argv);
return (0);
}

/* Translate an array of service names to a comma-delimited string.
* If list is empty, NULL is returned.
* If skip != NULL, skip over that name in the list (intended to be
Expand Down
5 changes: 5 additions & 0 deletions t/t0003-module.t
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ test_expect_success 'module: load test module' '
flux module load \
${FLUX_BUILD_DIR}/t/module/.libs/parent.so
'
test_expect_success 'module: reload test module' '
flux module reload \
${FLUX_BUILD_DIR}/t/module/.libs/parent.so
'

test_expect_success 'module: lsmod shows test module' '
flux module list | grep parent
Expand Down Expand Up @@ -251,6 +255,7 @@ test_expect_success 'flux module -h lists subcommands' '
! flux module -h 2>module.help &&
grep -q list module.help &&
grep -q remove module.help &&
grep -q reload module.help &&
grep -q load module.help &&
grep -q info module.help &&
grep -q stats module.help &&
Expand Down
7 changes: 2 additions & 5 deletions t/t0015-cron.t
Original file line number Diff line number Diff line change
Expand Up @@ -274,11 +274,8 @@ test_expect_success 'flux-cron can set stop-on-failure' '
'

## Reload cron module with sync enabled
test_expect_success 'flux module remove cron' '
flux module remove cron
'
test_expect_success 'module load with sync' '
flux module load cron sync=cron.sync sync_epsilon=0.025
test_expect_success 'module reload with sync' '
flux module reload cron sync=cron.sync sync_epsilon=0.025
'
test_expect_success 'sync and sync_epsilon are set as expected' '
flux cron sync | grep "cron\.sync.*epsilon=0.025"
Expand Down
3 changes: 1 addition & 2 deletions t/t1003-kvs-stress.t
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,7 @@ test_expect_success 'kvs: test that KVS_NO_MERGE works with kvs_commit()' '
# transaction-merge option test
test_expect_success 'kvs: transaction-merge disabling works' '
THREADS=64 &&
flux module remove kvs &&
flux module load kvs transaction-merge=0 &&
flux module reload kvs transaction-merge=0 &&
OUTPUT=`${FLUX_BUILD_DIR}/t/kvs/transactionmerge ${THREADS} $(basename ${SHARNESS_TEST_FILE})` &&
test "$OUTPUT" = "${THREADS}"
'
Expand Down
12 changes: 4 additions & 8 deletions t/t2200-job-ingest.t
Original file line number Diff line number Diff line change
Expand Up @@ -152,8 +152,7 @@ test_expect_success 'submit request with empty payload fails with EPROTO(71)' '
'

test_expect_success 'job-ingest: test validator with version 1 enforced' '
flux exec -r all flux module remove job-ingest &&
flux exec -r all flux module load job-ingest \
flux exec -r all flux module reload job-ingest \
validator=${BINDINGS_VALIDATOR} validator-args="--require-version,1"
'

Expand All @@ -162,8 +161,7 @@ test_expect_success 'job-ingest: v1 jobspecs accepted with v1 requirement' '
'

test_expect_success 'job-ingest: test non-python validator' '
flux exec -r all flux module remove job-ingest &&
flux exec -r all flux module load job-ingest \
flux exec -r all flux module reload job-ingest \
validator=${FAKE_VALIDATOR}
'

Expand All @@ -172,8 +170,7 @@ test_expect_success 'job-ingest: submit succeeds with non-python validator' '
'

test_expect_success 'job-ingest: test python jsonschema validator' '
flux exec -r all flux module remove job-ingest &&
flux exec -r all flux module load job-ingest \
flux exec -r all flux module reload job-ingest \
validator=${JSONSCHEMA_VALIDATOR} validator-args=--schema,${SCHEMA}
'

Expand All @@ -190,8 +187,7 @@ test_expect_success 'job-ingest: invalid jobs rejected by jsonschema validator'
'

test_expect_success 'job-ingest: validator unexpected exit is handled' '
flux exec -r all flux module remove job-ingest &&
flux exec -r all flux module load job-ingest \
flux exec -r all flux module reload job-ingest \
validator=${BAD_VALIDATOR} &&
test_must_fail flux job submit basic.json 2>badvalidator.out &&
grep "unexpectedly exited" badvalidator.out
Expand Down
6 changes: 2 additions & 4 deletions t/t2202-job-manager.t
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,7 @@ test_expect_success 'job-manager: that job is now the first job' '
'

test_expect_success 'job-manager: reload the job manager' '
flux module remove job-manager &&
flux module load job-manager
flux module reload job-manager
'

test_expect_success 'job-manager: queue was successfully reconstructed' '
Expand Down Expand Up @@ -229,8 +228,7 @@ test_expect_success 'job-manager: no jobs in the queue' '
'

test_expect_success 'job-manager: reload the job manager' '
flux module remove job-manager &&
flux module load job-manager
flux module reload job-manager
'

test_expect_success 'job-manager: still no jobs in the queue' '
Expand Down
3 changes: 1 addition & 2 deletions t/t2203-job-manager-dummysched.t
Original file line number Diff line number Diff line change
Expand Up @@ -95,8 +95,7 @@ test_expect_success 'job-manager: canceled job has exception, free events' '

test_expect_success 'job-manager: reload sched-dummy --cores=4' '
flux dmesg -C &&
flux module remove sched-dummy &&
flux module load ${SCHED_DUMMY} --cores=4 &&
flux module reload ${SCHED_DUMMY} --cores=4 &&
flux dmesg | grep "hello_cb:" >hello.dmesg
'

Expand Down
12 changes: 4 additions & 8 deletions t/t2204-job-info.t
Original file line number Diff line number Diff line change
Expand Up @@ -343,8 +343,7 @@ wait_inactive() {
}

test_expect_success 'reload the job-info module' '
flux exec -r all flux module remove job-info &&
flux exec -r all flux module load job-info &&
flux exec -r all flux module reload job-info &&
wait_inactive
'

Expand Down Expand Up @@ -435,8 +434,7 @@ test_expect_success 'flux job lists full path for job name if first argument not
'

test_expect_success 'reload the job-info module' '
flux exec -r all flux module remove job-info &&
flux exec -r all flux module load job-info
flux exec -r all flux module reload job-info
'

test_expect_success 'verify job names preserved across restart' '
Expand Down Expand Up @@ -471,8 +469,7 @@ test_expect_success 'flux job list outputs ntasks correctly (4 tasks)' '
'

test_expect_success 'reload the job-info module' '
flux exec -r all flux module remove job-info &&
flux exec -r all flux module load job-info
flux exec -r all flux module reload job-info
'

test_expect_success 'verify task count preserved across restart' '
Expand Down Expand Up @@ -525,8 +522,7 @@ test_expect_success 'flux job list outputs nnodes/ranks correctly (5 tasks, / 3
'

test_expect_success 'reload the job-info module' '
flux exec -r all flux module remove job-info &&
flux exec -r all flux module load job-info
flux exec -r all flux module reload job-info
'

test_expect_success 'verify nnodes preserved across restart' '
Expand Down
9 changes: 3 additions & 6 deletions t/t2300-sched-simple.t
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ list_R() {
}

test_expect_success 'sched-simple: reload ingest module with lax validator' '
flux exec -r all flux module remove job-ingest &&
flux exec -r all flux module load job-ingest validator-args="--schema,${SCHEMA}" \
flux exec -r all flux module reload job-ingest validator-args="--schema,${SCHEMA}" \
validator=${JSONSCHEMA_VALIDATOR}
'
test_expect_success 'sched-simple: generate jobspec for simple test job' '
Expand Down Expand Up @@ -103,8 +102,7 @@ test_expect_success 'sched-simple: cancel all jobs' '
test "$($query)" = "rank[0-1]/core[0-1]"
'
test_expect_success 'sched-simple: reload in best-fit mode' '
flux module remove sched-simple &&
flux module load sched-simple mode=best-fit
flux module reload sched-simple mode=best-fit
'
test_expect_success 'sched-simple: submit 5 more jobs' '
flux job submit basic.json >job6.id &&
Expand Down Expand Up @@ -161,8 +159,7 @@ test_expect_success 'sched-simple: check allocations for running jobs' '
test_cmp first-fit-allocs.expected first-fit-allocs.out
'
test_expect_success 'sched-simple: reload with outstanding allocations' '
flux module remove sched-simple &&
flux module load sched-simple &&
flux module reload sched-simple &&
flux dmesg | grep "hello: alloc rank0/core0" &&
test "$($query)" = ""
'
Expand Down

0 comments on commit 3af5a6b

Please sign in to comment.