void *thread (void *arg) { thd_t *t = arg; char *key, *fence_name = NULL; int i, flags = 0; struct timespec t0; uint32_t rank; flux_future_t *f; flux_kvs_txn_t *txn; if (!(t->h = flux_open (NULL, 0))) { log_err ("%d: flux_open", t->n); goto done; } if (flux_get_rank (t->h, &rank) < 0) { log_err ("%d: flux_get_rank", t->n); goto done; } for (i = 0; i < count; i++) { if (!(txn = flux_kvs_txn_create ())) log_err_exit ("flux_kvs_txn_create"); key = xasprintf ("%s.%"PRIu32".%d.%d", prefix, rank, t->n, i); if (fopt) fence_name = xasprintf ("%s-%d", prefix, i); if (sopt) monotime (&t0); if (flux_kvs_txn_pack (txn, 0, key, "i", 42) < 0) log_err_exit ("%s", key); if (nopt && (i % nopt_divisor) == 0) flags |= FLUX_KVS_NO_MERGE; else flags = 0; if (fopt) { if (!(f = flux_kvs_fence (t->h, flags, fence_name, fence_nprocs, txn)) || flux_future_get (f, NULL) < 0) log_err_exit ("flux_kvs_fence"); flux_future_destroy (f); } else { if (!(f = flux_kvs_commit (t->h, flags, txn)) || flux_future_get (f, NULL) < 0) log_err_exit ("flux_kvs_commit"); flux_future_destroy (f); } if (sopt && zlist_append (t->perf, ddup (monotime_since (t0))) < 0) oom (); free (key); free (fence_name); flux_kvs_txn_destroy (txn); } done: if (t->h) flux_close (t->h); return NULL; }
static int attr_list_rpc (attr_ctx_t *ctx) { flux_future_t *f; json_t *array, *value; size_t index; int rc = -1; if (!(f = flux_rpc (ctx->h, "attr.list", NULL, FLUX_NODEID_ANY, 0))) goto done; if (flux_rpc_get_unpack (f, "{s:o}", "names", &array) < 0) goto done; zlist_destroy (&ctx->names); if (!(ctx->names = zlist_new ())) goto done; json_array_foreach (array, index, value) { const char *name = json_string_value (value); if (!name) { errno = EPROTO; goto done; } if (zlist_append (ctx->names, strdup (name)) < 0) { errno = ENOMEM; goto done; } } zlist_sort (ctx->names, (zlist_compare_fn *)attr_strcmp); rc = 0; done: flux_future_destroy (f); return rc; }
static int depthfirst_map_one (flux_t *h, const char *key, int dirskip, restart_map_f cb, void *arg) { flux_jobid_t id; flux_future_t *f; const char *eventlog; struct job *job = NULL; char path[64]; int rc = -1; if (strlen (key) <= dirskip) { errno = EINVAL; return -1; } if (fluid_decode (key + dirskip + 1, &id, FLUID_STRING_DOTHEX) < 0) return -1; if (flux_job_kvs_key (path, sizeof (path), id, "eventlog") < 0) { errno = EINVAL; return -1; } if (!(f = flux_kvs_lookup (h, NULL, 0, path))) goto done; if (flux_kvs_lookup_get (f, &eventlog) < 0) goto done; if (!(job = job_create_from_eventlog (id, eventlog))) goto done; if (cb (job, arg) < 0) goto done; rc = 1; done: flux_future_destroy (f); job_decref (job); return rc; }
// 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 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); }
int main (int argc, char *argv[]) { flux_t *h; const char *key; flux_future_t *f; if (argc != 2) { fprintf (stderr, "Usage: waitcreate_cancel key\n"); return (1); } key = argv[1]; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (!(f = flux_kvs_lookup (h, NULL, FLUX_KVS_WAITCREATE, key))) log_err_exit ("flux_kvs_lookup"); if (flux_kvs_lookup_cancel (f) < 0) log_err_exit ("flux_kvs_lookup_cancel"); if (flux_kvs_lookup_get (f, NULL) < 0) { if (errno != ENODATA) log_err_exit ("flux_kvs_lookup_get"); flux_future_destroy (f); } else log_msg_exit ("flux_kvs_lookup_get returned success"); flux_close (h); return (0); }
static int extract_raw_rdl_alloc (flux_t *h, int64_t j, json_object *jcb) { int i; json_object *ra = Jnew_ar (); bool processing = true; for (i=0; processing; ++i) { char *key = lwj_key (h, j, ".rank.%d.cores", i); flux_future_t *f = NULL; int64_t cores = 0; if (!key || !(f = flux_kvs_lookup (h, 0, key)) || flux_kvs_lookup_get_unpack (f, "I", &cores) < 0) { if (errno != EINVAL) flux_log_error (h, "extract %s", key); processing = false; } else { json_object *elem = Jnew (); json_object *o = Jnew (); Jadd_int64 (o, JSC_RDL_ALLOC_CONTAINED_NCORES, cores); json_object_object_add (elem, JSC_RDL_ALLOC_CONTAINED, o); json_object_array_add (ra, elem); } free (key); flux_future_destroy (f); } json_object_object_add (jcb, JSC_RDL_ALLOC, ra); return 0; }
void test_nsrc (flux_t *h, uint32_t nodeid) { flux_future_t *f; const char *json_str; const int count = 10000; int i, seq = -1; json_t *o; if (!(f = flux_rpc_pack (h, "req.nsrc", FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE, "{s:i}", "count", count))) log_err_exit ("%s", __FUNCTION__); flux_future_destroy (f); for (i = 0; i < count; i++) { flux_msg_t *msg; if (!(msg = flux_recv (h, FLUX_MATCH_ANY, 0))) 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 || !(o = json_loads (json_str, 0, NULL)) || json_unpack (o, "{s:i}", "seq", &seq) < 0) log_msg_exit ("%s: decode %d payload", __FUNCTION__, i); if (seq != i) log_msg_exit ("%s: decode %d - seq mismatch %d", __FUNCTION__, i, seq); json_decref (o); flux_msg_destroy (msg); } }
static int update_rdl (flux_t *h, int64_t j, const char *rs) { int rc = -1; char *key = lwj_key (h, j, ".rdl"); flux_kvs_txn_t *txn = NULL; flux_future_t *f = NULL; if (!(txn = flux_kvs_txn_create ())) { flux_log_error (h, "txn_create"); goto done; } if (flux_kvs_txn_pack (txn, 0, key, "s", rs) < 0) { flux_log_error (h, "update %s", key); goto done; } if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) { flux_log_error (h, "commit failed"); goto done; } flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new rdl.", j); rc = 0; done: flux_kvs_txn_destroy (txn); flux_future_destroy (f); free (key); return rc; }
static int attr_set_rpc (attr_ctx_t *ctx, const char *name, const char *val) { flux_future_t *f; attr_t *attr; int rc = -1; #if JANSSON_VERSION_HEX >= 0x020800 /* $? format specifier was introduced in jansson 2.8 */ f = flux_rpc_pack (ctx->h, "attr.set", FLUX_NODEID_ANY, 0, "{s:s, s:s?}", "name", name, "value", val); #else f = flux_rpc_pack (ctx->h, "attr.set", FLUX_NODEID_ANY, 0, val ? "{s:s, s:s}" : "{s:s, s:n}", "name", name, "value", val); #endif if (!f) goto done; if (flux_future_get (f, NULL) < 0) goto done; if (val) { if (!(attr = attr_create (val, 0))) goto done; zhash_update (ctx->hash, name, attr); zhash_freefn (ctx->hash, name, attr_destroy); } else zhash_delete (ctx->hash, name); rc = 0; done: flux_future_destroy (f); return rc; }
void watch_continuation (flux_future_t *f, void *arg) { int *last = arg; int i; if (flux_kvs_lookup_get_unpack (f, "i", &i) < 0) { if (errno == ENODATA) { flux_future_destroy (f); // ENODATA (like EOF on response stream) if (verbose) printf ("< ENODATA\n"); } else log_err_exit ("flux_lookup_get_unpack"); return; } if (verbose) printf ("< %s=%d\n", key, i); if (i != *last + 1) log_msg_exit ("%s: got %d, expected %d", __FUNCTION__, i, *last + 1); if (++wrxcount == totcount) flux_kvs_lookup_cancel (f); *last = i; flux_future_reset (f); }
void commit_continuation (flux_future_t *f, void *arg) { if (flux_future_get (f, NULL) < 0) log_err_exit ("flux_kvs_commit"); rxcount++; flux_future_destroy (f); }
void test_clog (flux_t *h, uint32_t nodeid) { flux_future_t *f; if (!(f = flux_rpc (h, "req.clog", NULL, nodeid, 0)) || flux_rpc_get (f, NULL) < 0) log_err_exit ("req.clog"); flux_future_destroy (f); }
void test_sink (flux_t *h, uint32_t nodeid) { flux_future_t *f; if (!(f = flux_rpc_pack (h, "req.sink", nodeid, 0, "{s:f}", "pi", 3.14)) || flux_future_get (f, NULL) < 0) log_err_exit ("%s", __FUNCTION__); flux_future_destroy (f); }
static int update_rdesc (flux_t *h, int64_t j, json_object *o) { int rc = -1; int64_t nnodes = 0; int64_t ntasks = 0; int64_t walltime = 0; char *key1 = NULL; char *key2 = NULL; char *key3 = NULL; flux_kvs_txn_t *txn = NULL; flux_future_t *f = NULL; if (!Jget_int64 (o, JSC_RDESC_NNODES, &nnodes)) goto done; if (!Jget_int64 (o, JSC_RDESC_NTASKS, &ntasks)) goto done; if (!Jget_int64 (o, JSC_RDESC_WALLTIME, &walltime)) goto done; if ((nnodes < 0) || (ntasks < 0) || (walltime < 0)) goto done; key1 = lwj_key (h, j, ".nnodes"); key2 = lwj_key (h, j, ".ntasks"); key3 = lwj_key (h, j, ".walltime"); if (!key1 || !key2 || !key3) goto done; if (!(txn = flux_kvs_txn_create ())) { flux_log_error (h, "txn_create"); goto done; } if (flux_kvs_txn_pack (txn, 0, key1, "I", nnodes) < 0) { flux_log_error (h, "update %s", key1); goto done; } if (flux_kvs_txn_pack (txn, 0, key2, "I", ntasks) < 0) { flux_log_error (h, "update %s", key2); goto done; } if (flux_kvs_txn_pack (txn, 0, key3, "I", walltime) < 0) { flux_log_error (h, "update %s", key3); goto done; } if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) { flux_log_error (h, "commit failed"); goto done; } flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new resources.", j); rc = 0; done: flux_future_destroy (f); flux_kvs_txn_destroy (txn); free (key1); free (key2); free (key3); return rc; }
void *watchthread (void *arg) { thd_t *t = arg; watch_count_t wc; flux_kvs_txn_t *txn; flux_future_t *f; flux_reactor_t *r; flux_watcher_t *pw = NULL; flux_watcher_t *tw = NULL; if (!(t->h = flux_open (NULL, 0))) log_err_exit ("flux_open"); /* Make sure key doesn't already exist, initial value may affect * test by chance (i.e. initial value = 0, commit 0 and thus no * change) */ if (!(txn = flux_kvs_txn_create ())) log_err_exit ("flux_kvs_txn_create"); if (flux_kvs_txn_unlink (txn, 0, key) < 0) log_err_exit ("flux_kvs_txn_unlink"); if (!(f = flux_kvs_commit (t->h, 0, txn)) || flux_future_get (f, NULL) < 0) log_err_exit ("flux_kvs_commit"); flux_future_destroy (f); flux_kvs_txn_destroy (txn); r = flux_get_reactor (t->h); if (flux_kvs_watch (t->h, key, watch_count_cb, t) < 0) log_err_exit ("flux_kvs_watch %s", key); pw = flux_prepare_watcher_create (r, watch_prepare_cb, NULL); wc.t = t; wc.lastcount = -1; /* So test won't hang if there's a bug */ tw = flux_timer_watcher_create (r, WATCH_TIMEOUT, WATCH_TIMEOUT, watch_timeout_cb, &wc); flux_watcher_start (pw); flux_watcher_start (tw); if (flux_reactor_run (r, 0) < 0) log_err_exit ("flux_reactor_run"); flux_watcher_destroy (pw); flux_watcher_destroy (tw); flux_close (t->h); return NULL; }
/* 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); }
static void runlevel_timeout (flux_reactor_t *reactor, flux_watcher_t *w, int revents, void *arg) { runlevel_t *r = arg; flux_future_t *f; flux_log (r->h, LOG_ERR, "runlevel %d timeout, sending SIGTERM", r->level); if (!(f = flux_subprocess_kill (r->rc[r->level].p, SIGTERM))) flux_log_error (r->h, "flux_subprocess_kill"); /* don't care about response */ flux_future_destroy (f); }
int register_content_backing_service (flux_t *h) { int rc, saved_errno; flux_future_t *f; if (!(f = flux_service_register (h, "content-backing"))) return -1; rc = flux_future_get (f, NULL); saved_errno = errno; flux_future_destroy (f); errno = saved_errno; return rc; }
void test_err (flux_t *h, uint32_t nodeid) { flux_future_t *f; if (!(f = flux_rpc (h, "req.err", NULL, nodeid, 0))) log_err_exit ("error sending request"); if (flux_future_get (f, NULL) == 0) log_msg_exit ("%s: succeeded when should've failed", __FUNCTION__); if (errno != 42) log_msg_exit ("%s: got errno %d instead of 42", __FUNCTION__, errno); flux_future_destroy (f); }
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); }
void test_src (flux_t *h, uint32_t nodeid) { flux_future_t *f; int i; if (!(f = flux_rpc (h, "req.src", NULL, nodeid, 0)) || flux_rpc_get_unpack (f, "{s:i}", "wormz", &i) < 0) log_err_exit ("%s", __FUNCTION__); if (i != 42) log_msg_exit ("%s: didn't get expected payload", __FUNCTION__); flux_future_destroy (f); }
static void xping (flux_t *h, uint32_t nodeid, uint32_t xnodeid, const char *svc) { flux_future_t *f; const char *route; if (!(f = flux_rpc_pack (h, "req.xping", nodeid, 0, "{s:i s:s}", "rank", xnodeid, "service", svc)) || flux_rpc_get_unpack (f, "{s:s}", "route", &route) < 0) log_err_exit ("req.xping"); printf ("hops=%d\n", count_hops (route)); flux_future_destroy (f); }
void test_echo (flux_t *h, uint32_t nodeid) { const char *s; flux_future_t *f; if (!(f = flux_rpc_pack (h, "req.echo", nodeid, 0, "{s:s}", "mumble", "burble")) || flux_rpc_get_unpack (f, "{s:s}", "mumble", &s) < 0) log_err_exit ("%s", __FUNCTION__); if (strcmp (s, "burble") != 0) log_msg_exit ("%s: returned payload wasn't an echo", __FUNCTION__); flux_future_destroy (f); }
// Send an event to all modules that the simulation has completed int send_complete_event (flux_t *h) { int rc = 0; flux_future_t *future = NULL; future = flux_rpc (h, "sim.complete", NULL, FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE); if (!future) { rc = -1; } flux_future_destroy (future); return rc; }
static int update_rdl_alloc (flux_t *h, int64_t j, json_object *o) { int i = 0; int rc = -1; int size = 0; json_object *ra_e = NULL; const char *key = NULL; zhash_t *rtab = NULL; int64_t *ncores = NULL; flux_kvs_txn_t *txn = NULL; flux_future_t *f = NULL; if (!(rtab = zhash_new ())) oom (); if (!Jget_ar_len (o, &size)) goto done; for (i=0; i < (int) size; ++i) { if (!Jget_ar_obj (o, i, &ra_e)) goto done; /* 'o' represents an array of per-node core count to use. * However, becasue the same rank can appear multiple times * in this array in emulation mode, update_hash_1ra is * used to determine the total core count per rank. */ if ( (rc = update_hash_1ra (h, j, ra_e, rtab)) < 0) goto done; } if (!(txn = flux_kvs_txn_create ())) { flux_log_error (h, "txn_create"); goto done; } FOREACH_ZHASH (rtab, key, ncores) { if ( (rc = flux_kvs_txn_pack (txn, 0, key, "I", *ncores)) < 0) { flux_log_error (h, "put %s", key); goto done; } } if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) { flux_log (h, LOG_ERR, "update_pdesc commit failed"); goto done; } rc = 0; done: flux_future_destroy (f); flux_kvs_txn_destroy (txn); zhash_destroy (&rtab); return rc; }
/* 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; int seq, myseq = 0; zlist_t *defer = zlist_new (); bool popped = false; flux_msg_t *z; json_t *o; if (!defer) oom (); if (!(f = flux_rpc_pack (h, "req.nsrc", FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE, "{s:i}", "count", count))) 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 || !(o = json_loads (json_str, 0, NULL)) || json_unpack (o, "{s:i}", "seq", &seq) < 0) log_msg_exit ("%s: decode - payload", __FUNCTION__); json_decref (o); 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); }
static int depthfirst_map (flux_t *h, const char *key, int dirskip, restart_map_f cb, void *arg) { flux_future_t *f; const flux_kvsdir_t *dir; flux_kvsitr_t *itr; const char *name; int path_level; int count = 0; int rc = -1; path_level = restart_count_char (key + dirskip, '.'); if (!(f = flux_kvs_lookup (h, NULL, FLUX_KVS_READDIR, key))) return -1; if (flux_kvs_lookup_get_dir (f, &dir) < 0) { if (errno == ENOENT && path_level == 0) rc = 0; goto done; } if (!(itr = flux_kvsitr_create (dir))) goto done; while ((name = flux_kvsitr_next (itr))) { char *nkey; int n; if (!flux_kvsdir_isdir (dir, name)) continue; if (!(nkey = flux_kvsdir_key_at (dir, name))) goto done_destroyitr; if (path_level == 3) // orig 'key' = .A.B.C, thus 'nkey' is complete n = depthfirst_map_one (h, nkey, dirskip, cb, arg); else n = depthfirst_map (h, nkey, dirskip, cb, arg); if (n < 0) { int saved_errno = errno; free (nkey); errno = saved_errno; goto done_destroyitr; } count += n; free (nkey); } rc = count; done_destroyitr: flux_kvsitr_destroy (itr); done: flux_future_destroy (f); return rc; }
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; }
/* 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); }