/* Route string will not include the endpoints. */ static void ping_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { module_t *p = arg; const char *json_str; JSON o = NULL; char *route = NULL; char *route_plus_uuid = NULL; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) goto done; if (!(o = Jfromstr (json_str))) { errno = EPROTO; goto done; } if (!(route = flux_msg_get_route_string (msg))) goto done; route_plus_uuid = xasprintf ("%s!%.5s", route, module_get_uuid (p)); Jadd_str (o, "route", route_plus_uuid); rc = 0; done: if (flux_respond (h, msg, rc < 0 ? errno : 0, rc < 0 ? NULL : Jtostr (o)) < 0) FLUX_LOG_ERROR (h); Jput (o); if (route_plus_uuid) free (route_plus_uuid); if (route) free (route); }
static void rmmod_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { struct sched_plugin_loader *sploader = arg; struct sched_plugin *plugin = sched_plugin_get (sploader); const char *json_str; char *name = NULL; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) goto done; if (flux_rmmod_json_decode (json_str, &name) < 0) goto done; if (!plugin || strcmp (name, plugin->name) != 0) { errno = ENOENT; goto done; } sched_plugin_unload (sploader); flux_log (h, LOG_INFO, "%s unloaded", name); rc = 0; done: if (flux_respond (h, msg, rc < 0 ? errno : 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); if (name) free (name); }
int sequence_request_handler (seqhash_t *s, const flux_msg_t *msg, JSON *outp) { const char *json_str, *topic; const char *method; JSON in = NULL; int rc = -1; *outp = NULL; if (flux_request_decode (msg, &topic, &json_str) < 0) goto done; if (!(in = Jfromstr (json_str))) { errno = EPROTO; goto done; } method = topic + 8; if (strcmp (method, "fetch") == 0) rc = handle_seq_fetch (s, in, outp); else if (strcmp (method, "set") == 0) rc = handle_seq_set (s, in, outp); else if (strcmp (method, "destroy") == 0) rc = handle_seq_destroy (s, in, outp); else errno = ENOSYS; done: Jput (in); return (rc); }
/* Return 'n' sequenced responses. */ void nsrc_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str; int saved_errno; JSON o = Jnew (); int i, count; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) { saved_errno = errno; goto done; } if (!(o = Jfromstr (json_str)) || !Jget_int (o, "count", &count)) { saved_errno = errno = EPROTO; goto done; } for (i = 0; i < count; i++) { Jadd_int (o, "seq", i); if (flux_respond (h, msg, 0, Jtostr (o)) < 0) { saved_errno = errno; flux_log_error (h, "%s: flux_respond", __FUNCTION__); goto done; } } rc = 0; done: if (rc < 0) { if (flux_respond (h, msg, saved_errno, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); } Jput (o); }
int rpctest_nodeid_cb (flux_t h, int type, zmsg_t **zmsg, void *arg) { int errnum = 0; uint32_t nodeid; JSON o = NULL; int flags; if (flux_request_decode (*zmsg, NULL, NULL) < 0 || flux_msg_get_nodeid (*zmsg, &nodeid, &flags) < 0) { errnum = errno; goto done; } if (nodeid == nodeid_fake_error) { nodeid_fake_error = -1; errnum = EPERM; /* an error not likely to be seen */ goto done; } o = Jnew (); Jadd_int (o, "nodeid", nodeid); Jadd_int (o, "flags", flags); done: (void)flux_respond (h, *zmsg, errnum, Jtostr (o)); Jput (o); zmsg_destroy (zmsg); return 0; }
/* no-payload response */ void rpctest_hello_cb (flux_t h, flux_msg_watcher_t *w, const flux_msg_t *msg, void *arg) { int errnum = 0; if (flux_request_decode (msg, NULL, NULL) < 0) { errnum = errno; goto done; } done: (void)flux_respond (h, msg, errnum, NULL); }
/* Proxy ping. */ void xping_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; const char *json_str; int saved_errno; int rank, seq = ctx->ping_seq++; const char *service; char *hashkey = NULL; JSON in = Jnew (); JSON o = NULL; flux_msg_t *cpy; if (flux_request_decode (msg, NULL, &json_str) < 0) { saved_errno = errno; goto error; } if (!(o = Jfromstr (json_str)) || !Jget_int (o, "rank", &rank) || !Jget_str (o, "service", &service)) { saved_errno = errno = EPROTO; goto error; } flux_log (h, LOG_DEBUG, "Rxping rank=%d service=%s", rank, service); Jadd_int (in, "seq", seq); flux_log (h, LOG_DEBUG, "Tping seq=%d %d!%s", seq, rank, service); flux_rpc_t *rpc; if (!(rpc = flux_rpc (h, service, Jtostr (in), rank, FLUX_RPC_NORESPONSE))) { saved_errno = errno; goto error; } flux_rpc_destroy (rpc); if (!(cpy = flux_msg_copy (msg, true))) { saved_errno = errno; goto error; } hashkey = xasprintf ("%d", seq); zhash_update (ctx->ping_requests, hashkey, cpy); zhash_freefn (ctx->ping_requests, hashkey, (zhash_free_fn *)flux_msg_destroy); Jput (o); Jput (in); if (hashkey) free (hashkey); return; error: if (flux_respond (h, msg, saved_errno, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); Jput (o); Jput (in); }
/* request payload echoed in response */ void rpctest_echo_cb (flux_t h, flux_msg_watcher_t *w, const flux_msg_t *msg, void *arg) { int errnum = 0; const char *json_str; if (flux_request_decode (msg, NULL, &json_str) < 0) { errnum = errno; goto done; } done: (void)flux_respond (h, msg, errnum, json_str); }
/* request payload echoed in response */ int rpctest_echo_cb (flux_t h, int type, zmsg_t **zmsg, void *arg) { int errnum = 0; const char *json_str; if (flux_request_decode (*zmsg, NULL, &json_str) < 0) { errnum = errno; goto done; } done: (void)flux_respond (h, *zmsg, errnum, json_str); zmsg_destroy (zmsg); return 0; }
int rpctest_hello_cb (flux_t h, int type, zmsg_t **zmsg, void *arg) { int errnum = 0; if (flux_request_decode (*zmsg, NULL, NULL) < 0) { errnum = errno; goto done; } hello_count++; done: (void)flux_respond (h, *zmsg, errnum, NULL); zmsg_destroy (zmsg); return 0; }
static void lsmod_request_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { json_t *mods = NULL; if (flux_request_decode (msg, NULL, NULL) < 0) goto error; mods = module_list (); if (flux_respond_pack (h, msg, "{s:O}", "mods", mods) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); json_decref (mods); return; error: if (flux_respond_error (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); }
/* Echo a json payload back to requestor. */ void echo_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str; int saved_errno; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) { saved_errno = errno; goto done; } rc = 0; done: if (flux_respond (h, msg, rc < 0 ? saved_errno : 0, rc < 0 ? NULL : json_str) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); }
/* sched-hello: * Scheduler obtains a list of jobs that have resources allocated. */ static void hello_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { struct alloc_ctx *ctx = arg; struct job *job; json_t *o = NULL; json_t *jobid; if (flux_request_decode (msg, NULL, NULL) < 0) goto error; flux_log (h, LOG_DEBUG, "scheduler: hello"); if (!(o = json_array ())) goto nomem; job = queue_first (ctx->queue); while (job) { if (job->has_resources) { if (!(jobid = json_integer (job->id))) goto nomem; if (json_array_append_new (o, jobid) < 0) { json_decref (jobid); goto nomem; } } job = queue_next (ctx->queue); } if (flux_respond_pack (h, msg, "{s:O}", "alloc", o) < 0) flux_log_error (h, "%s: flux_respond_pack", __FUNCTION__); /* Restart any free requests that might have been interrupted * when scheduler was last unloaded. */ job = queue_first (ctx->queue); while (job) { if (event_job_action (ctx->event_ctx, job) < 0) flux_log_error (h, "%s: event_job_action", __FUNCTION__); job = queue_next (ctx->queue); } json_decref (o); return; nomem: errno = ENOMEM; error: if (flux_respond_error (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); json_decref (o); }
int hello_decode (const flux_msg_t *msg, int *rank) { const char *json_str, *topic_str; JSON in = NULL; int rc = -1; if (flux_request_decode (msg, &topic_str, &json_str) < 0) goto done; if (!(in = Jfromstr (json_str)) || !Jget_int (in, "rank", rank) || strcmp (topic_str, "cmb.hello") != 0) { errno = EPROTO; goto done; } rc = 0; done: Jput (in); return rc; }
/* request nodeid and flags returned in response */ void rpctest_nodeid_cb (flux_t h, flux_msg_watcher_t *w, const flux_msg_t *msg, void *arg) { int errnum = 0; uint32_t nodeid; JSON o = NULL; int flags; if (flux_request_decode (msg, NULL, NULL) < 0 || flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) { errnum = errno; goto done; } o = Jnew (); Jadd_int (o, "nodeid", nodeid); Jadd_int (o, "flags", flags); done: (void)flux_respond (h, msg, errnum, Jtostr (o)); Jput (o); }
static void ping_request_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *json_str; char *route_str = NULL; char *full_route_str = NULL; char *resp_str = NULL; uint32_t rank, userid, rolemask; if (flux_request_decode (msg, NULL, &json_str) < 0) goto error; if (flux_msg_get_rolemask (msg, &rolemask) < 0) goto error; if (flux_msg_get_userid (msg, &userid) < 0) goto error; if (!(route_str = flux_msg_get_route_string (msg))) goto error; if (flux_get_rank (h, &rank) < 0) goto error; if (asprintf (&full_route_str, "%s!%u", route_str, rank) < 0) { errno = ENOMEM; goto error; } if (!(resp_str = make_json_response_payload (json_str, full_route_str, userid, rolemask))) { goto error; } if (flux_respond (h, msg, resp_str) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); free (route_str); free (full_route_str); free (resp_str); return; error: if (flux_respond_error (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); free (route_str); free (full_route_str); free (resp_str); }
static void stop_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { if (flux_request_decode (msg, NULL, NULL) < 0) goto error; #if WITH_TCMALLOC if (!IsHeapProfilerRunning ()) { errno = EINVAL; goto error; } HeapProfilerStop(); #else errno = ENOSYS; goto error; #endif /* WITH_TCMALLOC */ if (flux_respond (h, msg, 0, NULL) < 0) FLUX_LOG_ERROR (h); return; error: if (flux_respond (h, msg, errno, NULL) < 0) FLUX_LOG_ERROR (h); }
static void lsmod_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { struct sched_plugin_loader *sploader = arg; struct sched_plugin *plugin = sched_plugin_get (sploader); flux_modlist_t *mods = NULL; zfile_t *zf = NULL; char *json_str = NULL; struct stat sb; int rc = -1; if (flux_request_decode (msg, NULL, NULL) < 0) goto done; if (!(mods = flux_modlist_create ())) goto done; if (plugin) { if (stat (plugin->path, &sb) < 0) goto done; if (!(zf = zfile_new (NULL, plugin->path))) goto done; if (flux_modlist_append (mods, plugin->name, sb.st_size, zfile_digest (zf), 0, FLUX_MODSTATE_RUNNING) < 0) goto done; } if (!(json_str = flux_lsmod_json_encode (mods))) goto done; rc = 0; done: if (flux_respond (h, msg, rc < 0 ? errno : 0, rc < 0 ? NULL : json_str) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); if (mods) flux_modlist_destroy (mods); zfile_destroy (&zf); if (json_str) free (json_str); }
/* Accept a json payload, verify it and return error if it doesn't * match expected. */ void sink_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str; int saved_errno; JSON o = NULL; double d; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) { saved_errno = errno; goto done; } if (!(o = Jfromstr (json_str)) || !Jget_double (o, "pi", &d) || d != 3.14) { saved_errno = errno = EPROTO; goto done; } rc = 0; done: if (flux_respond (h, msg, rc < 0 ? saved_errno : 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); Jput (o); }
static void insmod_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { struct sched_plugin_loader *sploader = arg; struct sched_plugin *plugin = sched_plugin_get (sploader); const sched_params_t *sp = sched_params_get (h); const char *json_str; char *path = NULL; char *argz = NULL; size_t argz_len = 0; int rc = -1; if (flux_request_decode (msg, NULL, &json_str) < 0) goto done; if (flux_insmod_json_decode (json_str, &path, &argz, &argz_len) < 0) goto done; if (plugin) { errno = EEXIST; goto done; } if (sched_plugin_load (sploader, path) < 0) goto done; if (sploader->plugin->process_args (sploader->h, argz, argz_len, sp) < 0) { goto done; } rc = 0; done: if (flux_respond (h, msg, rc < 0 ? errno : 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); if (path) free (path); if (argz) free (argz); }
int main (int argc, char *argv[]) { flux_msg_t *msg; const char *topic, *s; const char *json_str = "{\"a\":42}"; const void *d; const char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; int i, l, len = strlen (data); plan (NO_PLAN); /* no topic is an error */ errno = 0; ok ((msg = flux_request_encode (NULL, json_str)) == NULL && errno == EINVAL, "flux_request_encode returns EINVAL with no topic string"); ok ((msg = flux_request_encode_raw (NULL, data, strlen (data))) == NULL && errno == EINVAL, "flux_request_encode_raw returns EINVAL with no topic string"); /* without payload */ ok ((msg = flux_request_encode ("foo.bar", NULL)) != NULL, "flux_request_encode works with NULL payload"); topic = NULL; ok (flux_request_decode (msg, &topic, NULL) == 0 && topic != NULL && !strcmp (topic, "foo.bar"), "flux_request_decode returns encoded topic"); ok (flux_request_decode (msg, NULL, NULL) == 0, "flux_request_decode topic is optional"); errno = 0; ok (flux_request_decode (msg, NULL, &s) == 0 && s == NULL, "flux_request_decode returns s = NULL when expected payload is missing"); flux_msg_destroy(msg); /* with JSON payload */ ok ((msg = flux_request_encode ("foo.bar", json_str)) != NULL, "flux_request_encode works with payload"); s = NULL; ok (flux_request_decode (msg, NULL, &s) == 0 && s != NULL && !strcmp (s, json_str), "flux_request_decode returns encoded payload"); topic = NULL; i = 0; ok (flux_request_unpack (msg, &topic, "{s:i}", "a", &i) == 0 && i == 42 && topic != NULL && !strcmp (topic, "foo.bar"), "flux_request_unpack returns encoded payload"); errno = 0; ok (flux_request_decode (msg, NULL, NULL) == 0, "flux_request_decode works with payload but don't want the payload"); flux_msg_destroy(msg); /* without payload (raw) */ ok ((msg = flux_request_encode_raw ("foo.bar", NULL, 0)) != NULL, "flux_request_encode_raw works with NULL payload"); topic = NULL; ok (flux_request_decode_raw (msg, &topic, &d, &l) == 0 && topic != NULL && !strcmp (topic, "foo.bar"), "flux_request_decode_raw returns encoded topic"); ok (flux_request_decode_raw (msg, NULL, &d, &l) == 0, "flux_request_decode_raw topic is optional"); d = (char *)&d; l = 1; ok (flux_request_decode_raw (msg, NULL, &d, &l) == 0 && l == 0 && d == NULL, "flux_request_decode_raw returned NULL payload"); flux_msg_destroy(msg); /* with raw payload */ ok ((msg = flux_request_encode_raw ("foo.bar", data, len)) != NULL, "flux_request_encode_raw works with payload"); d = NULL; l = 0; ok (flux_request_decode_raw (msg, NULL, &d, &l) == 0 && d != NULL && l == len && memcmp (d, data, len) == 0, "flux_request_decode_raw returns encoded payload"); flux_msg_destroy(msg); done_testing(); return (0); }
static void enter_request_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; barrier_t *b; json_object *o = NULL; char *sender = NULL; const char *name; int count, nprocs, hopcount; const char *json_str; if (flux_request_decode (msg, NULL, &json_str) < 0 || flux_msg_get_route_first (msg, &sender) < 0) { flux_log_error (ctx->h, "%s: decoding request", __FUNCTION__); goto done; } if (!(o = Jfromstr (json_str)) || !Jget_str (o, "name", &name) || !Jget_int (o, "count", &count) || !Jget_int (o, "nprocs", &nprocs)) { errno = EPROTO; flux_log_error (ctx->h, "%s: decoding request", __FUNCTION__); goto done; } if (!(b = zhash_lookup (ctx->barriers, name))) b = barrier_create (ctx, name, nprocs); /* Distinguish client (tracked) vs downstream barrier plugin (untracked). * A client, distinguished by hopcount > 0, can only enter barrier once. */ if (!Jget_int (o, "hopcount", &hopcount)) { if (barrier_add_client (b, sender, msg) < 0) { flux_respond (ctx->h, msg, EEXIST, NULL); flux_log (ctx->h, LOG_ERR, "abort %s due to double entry by client %s", name, sender); if (exit_event_send (ctx->h, b->name, ECONNABORTED) < 0) flux_log_error (ctx->h, "exit_event_send"); goto done; } } /* If the count has been reached, terminate the barrier; * o/w set timer to pass count upstream and zero it here. */ b->count += count; if (b->count == b->nprocs) { if (exit_event_send (ctx->h, b->name, 0) < 0) flux_log_error (ctx->h, "exit_event_send"); } else if (ctx->rank > 0 && !ctx->timer_armed) { flux_timer_watcher_reset (ctx->timer, barrier_reduction_timeout_sec, 0.); flux_watcher_start (ctx->timer); ctx->timer_armed = true; } done: if (o) json_object_put (o); if (sender) free (sender); }