static int internal_content_load (optparse_t *p, int ac, char *av[]) { int n; const char *blobref; uint8_t *data; int size; flux_t *h; flux_rpc_t *rpc; const char *topic; n = optparse_optind (p); if (n != ac - 1) { optparse_print_usage (p); exit (1); } blobref = av[n]; if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (optparse_hasopt (p, "bypass-cache")) topic = "content-backing.load"; else topic = "content.load"; if (!(rpc = flux_rpc_raw (h, topic, blobref, strlen (blobref) + 1, 0, 0))) log_err_exit ("%s", topic); if (flux_rpc_get_raw (rpc, &data, &size) < 0) log_err_exit ("%s", topic); if (write_all (STDOUT_FILENO, data, size) < 0) log_err_exit ("write"); flux_rpc_destroy (rpc); flux_close (h); return (0); }
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++; }
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); } }
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); }
static void copy_f2k (flux_t *h, const char *src, const char *dst, int kzoutflags, int blocksize) { int srcfd = STDIN_FILENO; kz_t *kzout; char *data; int len; if (strcmp (src, "-") != 0) { if ((srcfd = open (src, O_RDONLY)) < 0) log_err_exit ("%s", src); } if (!(kzout = kz_open (h, dst, kzoutflags))) log_err_exit ("kz_open %s", dst); data = xzmalloc (blocksize); while ((len = read (srcfd, data, blocksize)) > 0) { if (kz_put (kzout, data, len) < 0) log_err_exit ("kz_put %s", dst); } if (len < 0) log_err_exit ("read %s", src); free (data); if (kz_close (kzout) < 0) log_err_exit ("kz_close %s", dst); }
void send_czmq (char *buf, int len) { zctx_t *zctx; void *zs; zmsg_t *zmsg; if (!(zctx = zctx_new ())) log_err_exit ("C: zctx_new"); if (lopt) /* zctx linger default = 0 (flush none) */ zctx_set_linger (zctx, linger); if (!(zs = zsocket_new (zctx, ZMQ_DEALER))) log_err_exit ("C: zsocket_new"); //if (lopt) // doesn't work here // zsocket_set_linger (zs, linger); if (iopt) zsocket_set_immediate (zs, imm); //zsocket_set_sndhwm (zs, 0); /* unlimited */ if (zsocket_connect (zs, "%s", uri) < 0) log_err_exit ("C: zsocket_connect"); if (!(zmsg = zmsg_new ())) oom (); if (zmsg_pushmem (zmsg, buf, bufsize) < 0) oom (); if (zmsg_send (&zmsg, zs) < 0) log_err_exit ("C: zmsg_send"); if (sleep_usec > 0) usleep (sleep_usec); zctx_destroy (&zctx); }
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 internal_content_store (optparse_t *p, int ac, char *av[]) { const uint32_t blob_size_limit = 1048576; /* RFC 10 */ uint8_t *data; int size; flux_t *h; flux_rpc_t *rpc; const char *topic; if (optparse_optind (p) != ac) { optparse_print_usage (p); exit (1); } if ((size = read_all (STDIN_FILENO, &data)) < 0) log_err_exit ("read"); if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (optparse_hasopt (p, "dry-run")) { int flags; const char *hashfun; if (size > blob_size_limit) log_errn_exit (EFBIG, "content-store"); if (!(hashfun = flux_attr_get (h, "content-hash", &flags))) log_err_exit ("flux_attr_get content-hash"); if (!strcmp (hashfun, "sha1")) { uint8_t hash[SHA1_DIGEST_SIZE]; char hashstr[SHA1_STRING_SIZE]; SHA1_CTX sha1_ctx; SHA1_Init (&sha1_ctx); SHA1_Update (&sha1_ctx, (uint8_t *)data, size); SHA1_Final (&sha1_ctx, hash); sha1_hashtostr (hash, hashstr); printf ("%s\n", hashstr); } else log_msg_exit ("content-store: unsupported hash function: %s", hashfun); } else { const char *blobref; int blobref_size; if (optparse_hasopt (p, "bypass-cache")) topic = "content-backing.store"; else topic = "content.store"; if (!(rpc = flux_rpc_raw (h, topic, data, size, 0, 0))) log_err_exit ("%s", topic); if (flux_rpc_get_raw (rpc, &blobref, &blobref_size) < 0) log_err_exit ("%s", topic); if (!blobref || blobref[blobref_size - 1] != '\0') log_msg_exit ("%s: protocol error", topic); printf ("%s\n", blobref); flux_rpc_destroy (rpc); } flux_close (h); free (data); return (0); }
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; }
/* 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 int selfmod_watch_cb (const char *key, int val, void *arg, int errnum) { log_msg ("%s: value = %d errnum = %d", __FUNCTION__, val, errnum); flux_t *h = arg; if (kvs_put_int (h, key, val + 1) < 0) log_err_exit ("%s: kvs_put_int", __FUNCTION__); if (kvs_commit (h) < 0) log_err_exit ("%s: kvs_commit", __FUNCTION__); return (val == 0 ? -1 : 0); }
/* 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); }
int main (int argc, char *argv[]) { flux_t h; int ch = 0; int64_t jobid = -1; char *sfn = NULL; char *cfn = NULL; wjctx_t *ctx = NULL; log_init ("flux-waitjob"); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 'h': /* --help */ usage (); break; case 's': /* --sync-start */ sfn = xstrdup (optarg); break; case 'c': /* --sync-complete */ cfn = xstrdup (optarg); break; default: usage (); break; } } if (optind == argc) usage (); jobid = strtol (argv[optind], NULL, 10); if (jobid <= 0) log_err_exit ("jobid must be a positive number"); else if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); ctx = getctx (h); if (sfn) ctx->start = sfn; if (cfn) ctx->complete = cfn; ctx->jobid = jobid; flux_log_set_appname (h, "waitjob"); wait_job_complete (h); flux_close (h); log_fini (); return 0; }
int main (int argc, char **argv) { flux_t h; flux_msg_t *msg; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (!(msg = flux_event_encode ("snack.bar.closing", NULL))) log_err_exit ("flux_event_encode"); if (flux_send (h, msg, 0) < 0) log_err_exit ("flux_send"); flux_msg_destroy (msg); flux_close (h); return (0); }
int main (int argc, char *argv[]) { int ch; const char *type = NULL; const char *directory = NULL; const char *key; flux_t *h; log_init ("getas"); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 't': /* --type TYPE */ type = optarg; break; case 'd': /* --directory DIR */ directory = optarg; break; default: usage (); break; } } if (optind != argc - 1) usage (); key = argv[optind++]; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (directory) dirgetas (h, directory, key, type); else getas (h, key, type); flux_close (h); }
static int cmd_setattr (optparse_t *p, int ac, char *av[]) { int n; const char *name = NULL, *val = NULL; flux_t h; log_init ("flux-setattr"); n = optparse_optind (p); if (optparse_hasopt (p, "expunge") && n == ac - 1) { name = av[n]; } else if (!optparse_hasopt (p, "expunge") && n == ac - 2) { name = av[n]; val = av[n + 1]; } else { optparse_print_usage (p); exit (1); } h = builtin_get_flux_handle (p); if (flux_attr_set (h, name, val) < 0) log_err_exit ("%s", av[1]); flux_close (h); return (0); }
flux_future_t *commit_int (flux_t *h, const char *k, int v) { flux_kvs_txn_t *txn; flux_future_t *f; if (!(txn = flux_kvs_txn_create ())) log_err_exit ("flux_kvs_txn_create"); if (flux_kvs_txn_pack (txn, 0, k, "i", v) < 0) log_err_exit ("flux_kvs_txn_pack"); if (!(f = flux_kvs_commit (h, ns, FLUX_KVS_NO_MERGE, txn))) log_err_exit ("flux_kvs_commit"); flux_kvs_txn_destroy (txn); if (verbose) printf("> %s=%d\n", k, v); return f; }
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); }
static void unwatch_timer_cb (flux_reactor_t *r, flux_watcher_t *w, int revents, void *arg) { struct timer_ctx *ctx = arg; static int count = 0; log_msg ("%s", __FUNCTION__); if (kvs_put_int (ctx->h, ctx->key, count++) < 0) log_err_exit ("%s: kvs_put_int", __FUNCTION__); if (kvs_commit (ctx->h) < 0) log_err_exit ("%s: kvs_commit", __FUNCTION__); if (count == 10) { if (kvs_unwatch (ctx->h, ctx->key) < 0) log_err_exit ("%s: kvs_unwatch", __FUNCTION__); } else if (count == 20) flux_reactor_stop (r); }
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); }
zhash_t *get_command_list_hash (const char *pattern) { int rc; size_t i; glob_t gl; zhash_t *zh = NULL; rc = glob (pattern, GLOB_ERR, NULL, &gl); switch (rc) { case 0: break; /* have results, fall-through. */ case GLOB_ABORTED: /* No help.d directory? */ goto out; break; case GLOB_NOMATCH: goto out; break; default: fprintf (stderr, "glob: unknown error %d\n", rc); break; } zh = zhash_new (); //zhash_set_destructor (zh, (czmq_destructor *) zlist_destroy); for (i = 0; i < gl.gl_pathc; i++) { const char *file = gl.gl_pathv[i]; if (command_list_read (zh, file) < 0) log_err_exit ("%s: failed to read content\n", file); } globfree (&gl); out: return (zh); }
/* * Gather concatenated hwloc xml topo file with resource-hwloc.topo RPC * and save results until destroyed by hwloc_topo_destroy (). */ static struct hwloc_topo * hwloc_topo_create (optparse_t *p) { const char *json_str; struct hwloc_topo *t = xzmalloc (sizeof (*t)); if (!(t->h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); t->rpc = flux_rpc (t->h, "resource-hwloc.topo", NULL, 0, 0); if (!t->rpc || (flux_rpc_get (t->rpc, NULL, &json_str) < 0)) log_err_exit ("flux_rpc"); if (!(t->o = Jfromstr (json_str)) || !Jget_str (t->o, "topology", &t->topo)) log_msg_exit ("failed to parse json topology"); return (t); }
static void register_event (ctx_t *ctx, const char *name, flux_msg_handler_f cb) { struct flux_match match = FLUX_MATCH_EVENT; flux_msg_handler_t *w; match.topic_glob = xasprintf ("%s.%s", module_get_name (ctx->p), name); if (!(w = flux_msg_handler_create (ctx->h, match, cb, ctx->p))) log_err_exit ("flux_msg_handler_create"); flux_msg_handler_start (w); if (zlist_append (ctx->handlers, w) < 0) oom (); if (flux_event_subscribe (ctx->h, match.topic_glob) < 0) log_err_exit ("%s: flux_event_subscribe %s", __FUNCTION__, match.topic_glob); free (match.topic_glob); }
void shutdown_set_handle (shutdown_t *s, flux_t h) { struct flux_match match = FLUX_MATCH_EVENT; s->h = h; match.topic_glob = "shutdown"; if (!(s->shutdown = flux_msg_handler_create (s->h, match, shutdown_handler, s))) log_err_exit ("flux_msg_handler_create"); flux_msg_handler_start (s->shutdown); if (flux_event_subscribe (s->h, "shutdown") < 0) log_err_exit ("flux_event_subscribe"); if (flux_get_rank (s->h, &s->myrank) < 0) log_err_exit ("flux_get_rank"); }
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 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); }
flux_t builtin_get_flux_handle (optparse_t *p) { flux_t h = NULL; if ((h = optparse_get_data (p, "flux_t"))) flux_incref (h); else if ((h = flux_open (NULL, 0)) == NULL) log_err_exit ("flux_open"); return h; }
static ns_t *ns_guess (flux_t h) { ns_t *ns = xzmalloc (sizeof (*ns)); uint32_t size, rank; if (flux_get_rank (h, &rank) < 0) log_err_exit ("flux_get_rank"); if (flux_get_size (h, &size) < 0) log_err_exit ("flux_get_size"); ns->ok = nodeset_create (); ns->slow = nodeset_create (); ns->fail = nodeset_create (); ns->unknown = nodeset_create (); if (!ns->ok || !ns->slow || !ns->fail || !ns->unknown) oom (); nodeset_add_range (ns->ok, rank, size - 1); return ns; }
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 internal_heaptrace_stop (optparse_t *p, int ac, char *av[]) { flux_t *h; flux_rpc_t *rpc; if (optparse_optind (p) != ac) { optparse_print_usage (p); exit (1); } if (!(h = builtin_get_flux_handle (p))) log_err_exit ("flux_open"); if (!(rpc = flux_rpc (h, "cmb.heaptrace.stop", NULL, FLUX_NODEID_ANY, 0)) || flux_rpc_get (rpc, NULL) < 0) log_err_exit ("cmb.heaptrace.stop"); flux_rpc_destroy (rpc); flux_close (h); return (0); }