/* 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); }
/* Reply to all queued requests. */ void flush_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = getctx (h); flux_msg_t *req; while ((req = zlist_pop (ctx->clog_requests))) { /* send clog response */ if (flux_respond (h, req, 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); } /* send flush response */ if (flux_respond (h, msg, 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); }
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); }
/* 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 stats_clear_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { flux_clr_msgcounters (h); if (flux_respond (h, msg, 0, NULL) < 0) FLUX_LOG_ERROR (h); }
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; }
/* Handle the simplest possible request. * Verify that everything is as expected; log it and stop the reactor if not. */ void null_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; const char *topic; int type, size; void *buf; uint32_t nodeid; int flags; if (!msg) { flux_log (h, LOG_ERR, "%s: got NULL msg!", __FUNCTION__); goto error; } if (flux_msg_get_type (msg, &type) < 0) { flux_log_error (h, "%s: flux_msg_get_type", __FUNCTION__); goto error; } if (type != FLUX_MSGTYPE_REQUEST) { flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__, flux_msg_typestr (type)); goto error; } if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) { flux_log_error (h, "%s: flux_msg_get_nodeid", __FUNCTION__); goto error; } if (nodeid != ctx->rank && nodeid != FLUX_NODEID_ANY) { flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__, nodeid); goto error; } if (flux_msg_get_topic (msg, &topic) < 0) { flux_log_error (h, "%s: flux_msg_get_topic", __FUNCTION__); goto error; } if (strcmp (topic, "req.null") != 0) { flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__, topic); goto error; } if (flux_msg_get_payload (msg, &flags, &buf, &size) == 0) { flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__, size); goto error; } if (errno != EPROTO) { flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__, strerror (errno)); goto error; } if (flux_respond (h, msg, 0, NULL) < 0) { flux_log_error (h, "%s: flux_respond", __FUNCTION__); goto error; } return; error: flux_reactor_stop_error (flux_get_reactor (h)); }
static int send_enter_response (const char *key, void *item, void *arg) { flux_msg_t *msg = item; barrier_t *b = arg; flux_respond (b->ctx->h, msg, b->errnum, NULL); return 0; }
void priority_handle_request (flux_t *h, struct queue *queue, struct event_ctx *event_ctx, const flux_msg_t *msg) { uint32_t userid; uint32_t rolemask; flux_jobid_t id; struct job *job; int priority; const char *errstr = NULL; if (flux_request_unpack (msg, NULL, "{s:I s:i}", "id", &id, "priority", &priority) < 0 || flux_msg_get_userid (msg, &userid) < 0 || flux_msg_get_rolemask (msg, &rolemask) < 0) goto error; if (priority < FLUX_JOB_PRIORITY_MIN || priority > FLUX_JOB_PRIORITY_MAX) { errstr = "priority value is out of range"; errno = EINVAL; goto error; } if (!(job = queue_lookup_by_id (queue, id))) { errstr = "unknown job"; goto error; } /* Security: guests can only adjust jobs that they submitted. */ if (!(rolemask & FLUX_ROLE_OWNER) && userid != job->userid) { errstr = "guests can only reprioritize their own jobs"; errno = EPERM; goto error; } /* Security: guests can only reduce priority, or increase up to default. */ if (!(rolemask & FLUX_ROLE_OWNER) && priority > MAXOF (FLUX_JOB_PRIORITY_DEFAULT, job->priority)) { errstr = "guests can only adjust priority <= default"; errno = EPERM; goto error; } /* Post event, change job's queue position, and respond. */ if (event_job_post_pack (event_ctx, job, "priority", "{ s:i s:i }", "userid", userid, "priority", priority) < 0) goto error; queue_reorder (queue, job, job->queue_handle); if (flux_respond (h, msg, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); return; error: if (flux_respond_error (h, msg, errno, errstr) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); }
/* Return a fixed json payload */ void src_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { JSON o = Jnew (); Jadd_int (o, "wormz", 42); if (flux_respond (h, msg, 0, Jtostr (o)) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); Jput (o); }
/* increment integer and send it back */ void rpctest_incr_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { int i; if (flux_request_decodef (msg, NULL, "{s:i}", "n", &i) < 0) flux_respond (h, msg, errno, NULL); else flux_respondf (h, msg, "{s:i}", "n", i + 1); }
/* Return number of queued clog requests */ void count_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = getctx (h); JSON o = Jnew (); Jadd_int (o, "count", zlist_size (ctx->clog_requests)); if (flux_respond (h, msg, 0, Jtostr (o)) < 0) flux_log_error (h, "%s: flux_json_respond", __FUNCTION__); Jput (o); }
/* 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); }
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); }
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; }
/* 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; }
static void dump_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *reason; if (flux_request_unpack (msg, NULL, "{s:s}", "reason", &reason) < 0) goto error; #if WITH_TCMALLOC if (!IsHeapProfilerRunning ()) { errno = EINVAL; goto error; } HeapProfilerDump (reason); #else errno = ENOSYS; goto error; #endif 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 rusage_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { JSON out = NULL; int rc = -1; if (getrusage_json (RUSAGE_THREAD, &out) < 0) goto done; rc = 0; done: if (flux_respond (h, msg, rc < 0 ? errno : 0, rc < 0 ? NULL : Jtostr (out)) < 0) FLUX_LOG_ERROR (h); Jput (out); }
static void start_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *filename; if (flux_request_unpack (msg, NULL, "{s:s}", "filename", &filename) < 0) goto error; #if WITH_TCMALLOC if (IsHeapProfilerRunning ()) { errno = EINVAL; goto error; } HeapProfilerStart (filename); #else errno = ENOSYS; goto error; #endif 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); }
/* KVS commit completed. * Respond to original request which was copied and passed as 'arg'. */ static void commit_continuation (flux_future_t *f, void *arg) { flux_t *h = flux_future_get_flux (f); flux_msg_t *msg = arg; if (flux_future_get (f, NULL) < 0) { if (flux_respond_error (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); } else { if (flux_respond (h, msg, 0, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); } flux_msg_destroy (msg); flux_future_destroy (f); }
/* 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__); }
static void rmmod_request_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *name; if (flux_request_unpack (msg, NULL, "{s:s}", "name", &name) < 0) goto error; if (!zhash_lookup (modules, name)) { errno = ENOENT; goto error; } zhash_delete (modules, name); flux_log (h, LOG_DEBUG, "rmmod %s", name); if (flux_respond (h, msg, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); return; error: if (flux_respond_error (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); }
/* 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 stats_get_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { flux_msgcounters_t mcs; JSON out = Jnew (); flux_get_msgcounters (h, &mcs); Jadd_int (out, "#request (tx)", mcs.request_tx); Jadd_int (out, "#request (rx)", mcs.request_rx); Jadd_int (out, "#response (tx)", mcs.response_tx); Jadd_int (out, "#response (rx)", mcs.response_rx); Jadd_int (out, "#event (tx)", mcs.event_tx); Jadd_int (out, "#event (rx)", mcs.event_rx); Jadd_int (out, "#keepalive (tx)", mcs.keepalive_tx); Jadd_int (out, "#keepalive (rx)", mcs.keepalive_rx); if (flux_respond (h, msg, 0, Jtostr (out)) < 0) FLUX_LOG_ERROR (h); Jput (out); }
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 insmod_request_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *path; json_t *args; size_t index; json_t *value; char *argz = NULL; size_t argz_len = 0; module_t *m = NULL; error_t e; if (flux_request_unpack (msg, NULL, "{s:s s:o}", "path", &path, "args", &args) < 0) goto error; if (!json_is_array (args)) goto proto; json_array_foreach (args, index, value) { if (!json_is_string (value)) goto proto; if ((e = argz_add (&argz, &argz_len, json_string_value (value)))) { errno = e; goto error; } } if (!(m = module_create (path, argz, argz_len))) goto error; flux_log (h, LOG_DEBUG, "insmod %s", m->name); if (flux_respond (h, msg, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); free (argz); return; proto: errno = EPROTO; error: if (flux_respond_error (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond_error", __FUNCTION__); free (argz); }
/* Handle ping response for proxy ping. * Match it with a request and respond to that request. */ void ping_response_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; const char *json_str; JSON o = NULL; JSON out = Jnew ();; int seq; const char *route; flux_msg_t *req = NULL; char *hashkey = NULL; if (flux_response_decode (msg, NULL, &json_str) < 0) { flux_log_error (h, "%s: flux_response_decode", __FUNCTION__); goto done; } if (!(o = Jfromstr (json_str)) || !Jget_int (o, "seq", &seq) || !Jget_str (o, "route", &route)) { errno = EPROTO; flux_log_error (h, "%s: payload", __FUNCTION__); goto done; } flux_log (h, LOG_DEBUG, "Rping seq=%d %s", seq, route); hashkey = xasprintf ("%d", seq); if (!(req = zhash_lookup (ctx->ping_requests, hashkey))) { flux_log_error (h, "%s: unsolicited ping response", __FUNCTION__); goto done; } flux_log (h, LOG_DEBUG, "Txping seq=%d %s", seq, route); Jadd_str (out, "route", route); if (flux_respond (h, req, 0, Jtostr (out)) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); zhash_delete (ctx->ping_requests, hashkey); done: if (hashkey) free (hashkey); Jput (o); Jput (out); }
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); }