void send_ping (struct ping_ctx *ctx) { struct timespec t0; json_object *in = Jnew (); flux_rpc_t *rpc; struct ping_data *pdata = xzmalloc (sizeof (*pdata)); pdata->tstat = xzmalloc (sizeof (*(pdata->tstat))); pdata->seq = 0; pdata->route = NULL; pdata->rpc_count = 0; Jadd_int (in, "seq", ctx->send_count); monotime (&t0); Jadd_int64 (in, "time.tv_sec", t0.tv_sec); Jadd_int64 (in, "time.tv_nsec", t0.tv_nsec); Jadd_str (in, "pad", ctx->pad); if (ctx->rank) rpc = flux_rpc_multi (ctx->h, ctx->topic, Jtostr (in), ctx->rank, 0); else rpc = flux_rpc (ctx->h, ctx->topic, Jtostr (in), ctx->nodeid, 0); if (!rpc) log_err_exit ("flux_rpc"); flux_rpc_aux_set (rpc, pdata, ping_data_free); if (flux_rpc_then (rpc, ping_continuation, ctx) < 0) log_err_exit ("flux_rpc_then"); Jput (in); ctx->send_count++; }
/* 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); }
/* 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; }
void test_nsrc (flux_t *h, uint32_t nodeid) { flux_future_t *f; const int count = 10000; json_object *in = Jnew (); const char *json_str; json_object *out = NULL; int i, seq; Jadd_int (in, "count", count); if (!(f = flux_rpc (h, "req.nsrc", Jtostr (in), FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE))) log_err_exit ("%s", __FUNCTION__); flux_future_destroy (f); for (i = 0; i < count; i++) { flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0); if (!msg) log_err_exit ("%s", __FUNCTION__); if (flux_response_decode (msg, NULL, &json_str) < 0) log_msg_exit ("%s: decode %d", __FUNCTION__, i); if (!json_str || !(out = Jfromstr (json_str)) || !Jget_int (out, "seq", &seq)) log_msg_exit ("%s: decode %d payload", __FUNCTION__, i); if (seq != i) log_msg_exit ("%s: decode %d - seq mismatch %d", __FUNCTION__, i, seq); Jput (out); flux_msg_destroy (msg); } Jput (in); }
void cmd_copy_tokvs (flux_t h, int argc, char **argv) { char *file, *key; int fd, len; uint8_t *buf; JSON o; if (argc != 2) msg_exit ("copy-tokvs: specify key and filename"); key = argv[0]; file = argv[1]; if (!strcmp (file, "-")) { if ((len = read_all (STDIN_FILENO, &buf)) < 0) err_exit ("stdin"); } else { if ((fd = open (file, O_RDONLY)) < 0) err_exit ("%s", file); if ((len = read_all (fd, &buf)) < 0) err_exit ("%s", file); (void)close (fd); } o = Jnew (); util_json_object_add_data (o, "data", buf, len); if (kvs_put (h, key, Jtostr (o)) < 0) err_exit ("%s", key); if (kvs_commit (h) < 0) err_exit ("kvs_commit"); Jput (o); free (buf); }
static void dump_kvs_val (const char *key, const char *json_str) { JSON o = Jfromstr (json_str); if (!o) { printf ("%s: invalid JSON", key); return; } switch (json_object_get_type (o)) { case json_type_null: printf ("%s = nil\n", key); break; case json_type_boolean: printf ("%s = %s\n", key, json_object_get_boolean (o) ? "true" : "false"); break; case json_type_double: printf ("%s = %f\n", key, json_object_get_double (o)); break; case json_type_int: printf ("%s = %d\n", key, json_object_get_int (o)); break; case json_type_string: printf ("%s = %s\n", key, json_object_get_string (o)); break; case json_type_array: case json_type_object: default: printf ("%s = %s\n", key, Jtostr (o)); break; } Jput (o); }
static void request_hwloc_reload (flux_t h, const char *nodeset, const char *walk_topology) { flux_rpc_t *rpc; JSON o = NULL; const char *json_str = NULL; if ((o = hwloc_reload_json_create (walk_topology))) json_str = Jtostr (o); if (!(rpc = flux_rpc_multi (h, "resource-hwloc.reload", json_str, nodeset, 0))) log_err_exit ("flux_rpc_multi"); while (!flux_rpc_completed (rpc)) { const char *json_str; uint32_t nodeid = FLUX_NODEID_ANY; if (flux_rpc_get (rpc, &nodeid, &json_str) < 0) { if (nodeid == FLUX_NODEID_ANY) log_err ("flux_rpc_get"); else log_err ("rpc(%"PRIu32")", nodeid); } } flux_rpc_destroy (rpc); Jput (o); }
// builds the trigger request and sends it to "mod_name" // converts sim_state to JSON, formats request tag based on "mod_name" static int send_trigger (flux_t *h, const char *mod_name, sim_state_t *sim_state) { int rc = 0; flux_future_t *future = NULL; json_t *o = NULL; char *topic = NULL; // Reset the next timer for "mod_name" to -1 before we trigger double *next_time = zhash_lookup (sim_state->timers, mod_name); *next_time = -1; o = sim_state_to_json (sim_state); topic = xasprintf ("%s.trigger", mod_name); future = flux_rpc (h, topic, Jtostr (o), FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE); if (!future) { flux_log (h, LOG_ERR, "failed to send trigger to %s", mod_name); rc = -1; } Jput (o); free (topic); flux_future_destroy (future); return rc; }
void cache_get_stats (struct cache *cache, tstat_t *ts, int *sizep, int *incompletep, int *dirtyp) { zlist_t *keys; struct cache_entry *hp; char *ref; int size = 0; int incomplete = 0; int dirty = 0; if (!(keys = zhash_keys (cache->zh))) oom (); while ((ref = zlist_pop (keys))) { hp = zhash_lookup (cache->zh, ref); if (cache_entry_get_valid (hp)) { int obj_size = strlen (Jtostr (hp->o)); size += obj_size; tstat_push (ts, obj_size); } else incomplete++; if (cache_entry_get_dirty (hp)) dirty++; free (ref); } zlist_destroy (&keys); if (sizep) *sizep = size; if (incompletep) *incompletep = incomplete; if (dirtyp) *dirtyp = dirty; }
static flux_rpc_t *dmesg_rpc (flux_t h, int seq, bool follow) { flux_rpc_t *rpc; JSON o = Jnew (); Jadd_int (o, "seq", seq); Jadd_bool (o, "follow", follow); rpc = flux_rpc (h, "cmb.dmesg", Jtostr (o), FLUX_NODEID_ANY, 0); Jput (o); return rpc; }
/* 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); }
flux_msg_t *flux_heartbeat_encode (int epoch) { flux_msg_t *msg; JSON o = Jnew (); Jadd_int (o, "epoch", epoch); msg = flux_event_encode ("hb", Jtostr (o)); Jput (o); return msg; }
/* This test is to make sure that deferred responses are handled in order. * Arrange for module to source 10K sequenced responses. Messages 5000-5499 * are "put back" on the handle using flux_putmsg(). We ensure that * the 10K messages are nonetheless received in order. */ void test_putmsg (flux_t *h, uint32_t nodeid) { flux_future_t *f; const char *json_str; const int count = 10000; const int defer_start = 5000; const int defer_count = 500; json_object *in = Jnew (); json_object *out = NULL; int seq, myseq = 0; zlist_t *defer = zlist_new (); bool popped = false; flux_msg_t *z; if (!defer) oom (); Jadd_int (in, "count", count); if (!(f = flux_rpc (h, "req.nsrc", Jtostr (in), FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE))) log_err_exit ("%s", __FUNCTION__); flux_future_destroy (f); do { flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0); if (!msg) log_err_exit ("%s", __FUNCTION__); if (flux_response_decode (msg, NULL, &json_str) < 0) log_msg_exit ("%s: decode", __FUNCTION__); if (!json_str || !(out = Jfromstr (json_str)) || !Jget_int (out, "seq", &seq)) log_msg_exit ("%s: decode - payload", __FUNCTION__); Jput (out); if (seq >= defer_start && seq < defer_start + defer_count && !popped) { if (zlist_append (defer, msg) < 0) oom (); if (seq == defer_start + defer_count - 1) { while ((z = zlist_pop (defer))) { if (flux_requeue (h, z, FLUX_RQ_TAIL) < 0) log_err_exit ("%s: flux_requeue", __FUNCTION__); flux_msg_destroy (z); } popped = true; } continue; } if (seq != myseq) log_msg_exit ("%s: expected %d got %d", __FUNCTION__, myseq, seq); myseq++; flux_msg_destroy (msg); } while (myseq < count); zlist_destroy (&defer); Jput (in); }
/* 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); }
void test_sink (flux_t *h, uint32_t nodeid) { flux_future_t *f; json_object *in = Jnew(); Jadd_double (in, "pi", 3.14); if (!(f = flux_rpc (h, "req.sink", Jtostr (in), nodeid, 0)) || flux_future_get (f, NULL) < 0) log_err_exit ("%s", __FUNCTION__); Jput (in); flux_future_destroy (f); }
/* 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); }
int jsc_query_jcb (flux_t *h, int64_t jobid, const char *key, char **jcb) { int rc; json_object *o = NULL; rc = query_jcb_obj (h, jobid, key, &o); if (rc < 0) goto done; *jcb = o ? xstrdup (Jtostr (o)) : NULL; done: Jput (o); return rc; }
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 int update_1pdesc (flux_t *h, flux_kvs_txn_t *txn, int r, int64_t j, json_object *o, json_object *ha, json_object *ea) { flux_future_t *f = NULL; int rc = -1; json_object *d = NULL; char *key; const char *json_str; const char *hn = NULL, *en = NULL; int64_t pid = 0, hindx = 0, eindx = 0, hrank = 0; if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_PID, &pid)) return -1; if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_HINDX, &hindx)) return -1; if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_EINDX, &eindx)) return -1; if (!Jget_ar_str (ha, (int)hindx, &hn)) return -1; if (!Jget_ar_str (ea, (int)eindx, &en)) return -1; key = lwj_key (h, j, ".%d.procdesc", r); if (!key || !(f = flux_kvs_lookup (h, 0, key)) || flux_kvs_lookup_get (f, &json_str) < 0 || !(d = Jfromstr (json_str))) { flux_log_error (h, "extract %s", key); goto done; } Jadd_str (d, "command", en); Jadd_int64 (d, "pid", pid); errno = 0; if ( (hrank = strtoul (hn, NULL, 10)) && errno != 0) { flux_log (h, LOG_ERR, "invalid hostname %s", hn); goto done; } Jadd_int64 (d, "nodeid", (int64_t)hrank); if (flux_kvs_txn_put (txn, 0, key, Jtostr (d)) < 0) { flux_log_error (h, "put %s", key); goto done; } rc = 0; done: flux_future_destroy (f); free (key); if (d) Jput (d); return rc; }
flux_msg_t *shutdown_vencode (double grace, int exitcode, int rank, const char *fmt, va_list ap) { flux_msg_t *msg; JSON out = Jnew (); char reason[REASON_MAX]; vsnprintf (reason, sizeof (reason), fmt, ap); Jadd_str (out, "reason", reason); Jadd_double (out, "grace", grace); Jadd_int (out, "rank", rank); Jadd_int (out, "exitcode", exitcode); msg = flux_event_encode ("shutdown", Jtostr (out)); Jput (out); return msg; }
flux_msg_t *hello_encode (int rank) { flux_msg_t *msg = NULL; JSON out = Jnew (); Jadd_int (out, "rank", rank); if (!(msg = flux_request_encode ("cmb.hello", Jtostr (out)))) goto error; if (flux_msg_set_nodeid (msg, 0, 0) < 0) goto error; Jput (out); return msg; error: flux_msg_destroy (msg); Jput (out); return NULL; }
static int exit_event_send (flux_t h, const char *name, int errnum) { JSON o = Jnew (); zmsg_t *zmsg = NULL; int rc = -1; Jadd_str (o, "name", name); Jadd_int (o, "errnum", errnum); if (!(zmsg = flux_event_encode ("barrier.exit", Jtostr (o)))) goto done; if (flux_sendmsg (h, &zmsg) < 0) goto done; rc = 0; done: Jput (o); zmsg_destroy (&zmsg); return rc; }
static int dmesg_clear (flux_t h, int seq) { flux_rpc_t *rpc; JSON o = Jnew (); int rc = -1; Jadd_int (o, "seq", seq); if (!(rpc = flux_rpc (h, "cmb.dmesg.clear", Jtostr (o), FLUX_NODEID_ANY, 0))) goto done; if (flux_rpc_get (rpc, NULL, NULL) < 0) goto done; rc = 0; done: flux_rpc_destroy (rpc); Jput (o); return rc; }
static int op_event_unsubscribe (void *impl, const char *topic) { ctx_t *c = impl; assert (c->magic == CTX_MAGIC); flux_rpc_t *rpc = NULL; JSON in = Jnew (); int rc = 0; Jadd_str (in, "topic", topic); if (!(rpc = flux_rpc (c->h, "local.unsub", Jtostr (in), FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL, NULL) < 0) goto done; rc = 0; done: flux_rpc_destroy (rpc); Jput (in); return rc; }
static int exit_event_send (flux_t *h, const char *name, int errnum) { json_object *o = Jnew (); flux_msg_t *msg = NULL; int rc = -1; Jadd_str (o, "name", name); Jadd_int (o, "errnum", errnum); if (!(msg = flux_event_encode ("barrier.exit", Jtostr (o)))) goto done; if (flux_send (h, msg, 0) < 0) goto done; rc = 0; done: Jput (o); flux_msg_destroy (msg); return rc; }
static int update_1pdesc (flux_t h, int r, int64_t j, JSON o, JSON ha, JSON ea) { int rc = -1; JSON d = NULL; char *key; char *json_str = NULL; const char *hn = NULL, *en = NULL; int64_t pid = 0, hindx = 0, eindx = 0, hrank = 0; if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_PID, &pid)) return -1; if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_HINDX, &hindx)) return -1; if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_EINDX, &eindx)) return -1; if (!Jget_ar_str (ha, (int)hindx, &hn)) return -1; if (!Jget_ar_str (ea, (int)eindx, &en)) return -1; key = xasprintf ("lwj.%"PRId64".%"PRId32".procdesc", j, r); if (kvs_get (h, key, &json_str) < 0 || !(d = Jfromstr (json_str))) { flux_log_error (h, "extract %s", key); goto done; } Jadd_str (d, "command", en); Jadd_int64 (d, "pid", pid); errno = 0; if ( (hrank = strtoul (hn, NULL, 10)) && errno != 0) { flux_log (h, LOG_ERR, "invalid hostname %s", hn); goto done; } Jadd_int64 (d, "nodeid", (int64_t)hrank); if (kvs_put (h, key, Jtostr (d)) < 0) { flux_log_error (h, "put %s", key); goto done; } rc = 0; done: free (key); if (d) Jput (d); if (json_str) free (json_str); return rc; }
// Given the kvs dir of a job, change the state of the job and // timestamp the change static int update_job_state (ctx_t *ctx, int64_t jobid, flux_kvsdir_t *kvs_dir, job_state_t new_state, double update_time) { int rc; double t_starting = SIM_TIME_NONE; double t_running = SIM_TIME_NONE; double t_completing = SIM_TIME_NONE; double t_complete = SIM_TIME_NONE; switch (new_state) { case J_STARTING: t_starting = update_time; break; case J_RUNNING: t_running = update_time; break; case J_COMPLETING: t_completing = update_time; break; case J_COMPLETE: t_complete = update_time; break; default: flux_log (ctx->h, LOG_ERR, "Unknown state %d", (int) new_state); return -1; } json_t *jcb = Jnew (); json_t *o = Jnew (); Jadd_int64 (o, JSC_STATE_PAIR_NSTATE, (int64_t) new_state); Jadd_obj (jcb, JSC_STATE_PAIR, o); jsc_update_jcb(ctx->h, jobid, JSC_STATE_PAIR, Jtostr (jcb)); rc = set_job_timestamps (kvs_dir, t_starting, t_running, t_completing, t_complete, SIM_TIME_NONE); // io if (rc < 0) flux_log_error (ctx->h, "%s: set_job_timestamps", __FUNCTION__); Jput (jcb); Jput (o); 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 flux_msg_t *op_recv (void *impl, int flags) { ctx_t *ctx = impl; assert (ctx->magic == MODHANDLE_MAGIC); zmq_pollitem_t zp = { .events = ZMQ_POLLIN, .socket = ctx->sock, .revents = 0, .fd = -1, }; flux_msg_t *msg = NULL; if (connect_socket (ctx) < 0) goto done; if ((flags & FLUX_O_NONBLOCK)) { int n; if ((n = zmq_poll (&zp, 1, 0L)) <= 0) { if (n == 0) errno = EWOULDBLOCK; goto done; } } msg = flux_msg_recvzsock (ctx->sock); done: return msg; } static int op_event_subscribe (void *impl, const char *topic) { ctx_t *ctx = impl; assert (ctx->magic == MODHANDLE_MAGIC); json_object *in = Jnew (); flux_rpc_t *rpc = NULL; int rc = -1; if (connect_socket (ctx) < 0) goto done; Jadd_str (in, "topic", topic); if (!(rpc = flux_rpc (ctx->h, "cmb.sub", Jtostr (in), FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL) < 0) goto done; rc = 0; done: Jput (in); flux_rpc_destroy (rpc); return rc; }