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 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 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); }
/* 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); }
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); }
/* 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[]) { int rc; zsock_t *zs; pthread_t tid; pthread_attr_t attr; flux_msg_t *msg; flux_sec_t *sec; int n; log_init (basename (argv[0])); if (argc != 1 && argc != 2) { fprintf (stderr, "Usage: tmunge [--fake]\n"); exit (1); } if (argc == 2) { if (!strcmp (argv[1], "--fake")) sec_typemask |= FLUX_SEC_FAKEMUNGE; else log_msg_exit ("unknown option %s", argv[1]); } if (!(sec = flux_sec_create (sec_typemask, NULL))) log_err_exit ("flux_sec_create"); if (flux_sec_comms_init (sec) < 0) log_err_exit ("flux_sec_comms_init: %s", flux_sec_errstr (sec)); if (!(zs = zsock_new_sub (uri, ""))) log_err_exit ("S: zsock_new_sub"); if (!(cs = zsock_new_pub (uri))) log_err_exit ("S: zsock_new_pub"); if ((rc = pthread_attr_init (&attr))) log_errn (rc, "S: pthread_attr_init"); if ((rc = pthread_create (&tid, &attr, thread, NULL))) log_errn (rc, "S: pthread_create"); /* Handle one client message. */ if (!(msg = flux_msg_recvzsock_munge (zs, sec))) log_err_exit ("S: flux_msg_recvzsock_munge: %s", flux_sec_errstr (sec)); //zmsg_dump (zmsg); if ((n = flux_msg_frames (msg)) != 4) log_err_exit ("S: expected 4 frames, got %d", n); flux_msg_destroy (msg); /* Wait for thread to terminate, then clean up. */ if ((rc = pthread_join (tid, NULL))) log_errn (rc, "S: pthread_join"); zsock_destroy (&zs); zsock_destroy (&cs); flux_sec_destroy (sec); log_fini (); return 0; }
// Recevied a reply to a trigger ("sim.reply") static void reply_cb (flux_t *h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { const char *json_str = NULL; json_t *request = NULL; ctx_t *ctx = arg; sim_state_t *curr_sim_state = ctx->sim_state; sim_state_t *reply_sim_state; if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL || !(request = Jfromstr (json_str))) { flux_log (h, LOG_ERR, "%s: bad reply message", __FUNCTION__); Jput (request); return; } // De-serialize and get new info reply_sim_state = json_to_sim_state (request); copy_new_state_data (ctx, curr_sim_state, reply_sim_state); if (handle_next_event (ctx) < 0) { flux_log (h, LOG_DEBUG, "No events remaining"); if (ctx->exit_on_complete) { log_msg_exit ("exit_on_complete is set. Exiting now."); } else { send_complete_event (h); } } free_simstate (reply_sim_state); Jput (request); }
/* This is a sanity check that watch/unwatch in a loop doesn't * leak matchtags. */ void test_unwatchloop (int argc, char **argv) { int i; flux_t *h; char *key; if (argc != 1) { fprintf (stderr, "Usage: unwatch key\n"); exit (1); } key = argv[0]; if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); uint32_t avail = flux_matchtag_avail (h, 0); for (i = 0; i < 1000; i++) { if (kvs_watch_int (h, key, unwatchloop_cb, NULL) < 0) log_err_exit ("kvs_watch_int[%d] %s", i, key); if (kvs_unwatch (h, key) < 0) log_err_exit ("kvs_unwatch[%d] %s", i, key); } uint32_t leaked = avail - flux_matchtag_avail (h, 0); if (leaked > 0) log_msg_exit ("leaked %u matchtags", leaked); flux_close (h); }
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); }
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); }
/* Timer pops every 1 ms, writing a new value to key. * After 10 calls, it calls kvs_unwatch(). * After 20 calls, it calls flux_reactor_stop(). * The kvs_unwatch_cb() counts the number of times it is called, should be 10. */ void test_unwatch (int argc, char **argv) { struct timer_ctx ctx; flux_reactor_t *r; int count = 0; flux_watcher_t *timer; if (argc != 1) { fprintf (stderr, "Usage: unwatch key\n"); exit (1); } ctx.key = argv[0]; if (!(ctx.h = flux_open (NULL, 0))) log_err_exit ("flux_open"); r = flux_get_reactor (ctx.h); if (kvs_watch_int (ctx.h, ctx.key, unwatch_watch_cb, &count) < 0) log_err_exit ("kvs_watch_int %s", ctx.key); if (!(timer = flux_timer_watcher_create (r, 0.001, 0.001, unwatch_timer_cb, &ctx))) log_err_exit ("flux_timer_watcher_create"); flux_watcher_start (timer); if (flux_reactor_run (r, 0) < 0) log_err_exit ("flux_reactor_run"); if (count != 10) log_msg_exit ("watch called %d times (should be 10)", count); flux_watcher_destroy (timer); flux_close (ctx.h); }
static void lstopo_argz_init (char *cmd, char **argzp, size_t *argz_lenp, char *extra_args[]) { char *extra; size_t extra_len; int e; char *argv[] = { cmd, "-i", "-", "--if", "xml", "--of", "console", NULL }; if ( (e = argz_create (argv, argzp, argz_lenp)) != 0 || (e = argz_create (extra_args, &extra, &extra_len)) != 0) log_msg_exit ("argz_create: %s", strerror (e)); /* Append any extra args in av[] */ if ((e = argz_append (argzp, argz_lenp, extra, extra_len)) != 0) log_msg_exit ("argz_append: %s", strerror (e)); free (extra); }
void ipaddr_getprimary (char *buf, int len) { char hostname[HOST_NAME_MAX + 1]; struct addrinfo hints, *res = NULL; int e; if (gethostname (hostname, sizeof (hostname)) < 0) log_err_exit ("gethostname"); memset (&hints, 0, sizeof (hints)); hints.ai_family = PF_UNSPEC; hints.ai_socktype = SOCK_STREAM; if ((e = getaddrinfo (hostname, NULL, &hints, &res)) || res == NULL) log_msg_exit ("getaddrinfo %s: %s", hostname, gai_strerror (e)); if ((e = getnameinfo (res->ai_addr, res->ai_addrlen, buf, len, NULL, 0, NI_NUMERICHOST))) log_msg_exit ("getnameinfo %s: %s", hostname, gai_strerror (e)); freeaddrinfo (res); }
static void register_builtin_subcommands (optparse_t *p) { extern struct builtin_cmd builtin_cmds[]; struct builtin_cmd *cmd = &builtin_cmds[0]; while (cmd->reg_fn) { if (cmd->reg_fn (p) < 0) log_msg_exit ("register builtin %s failed\n", cmd->name); cmd++; } }
static int cmd_lstopo (optparse_t *p, int ac, char *av[]) { int status; struct hwloc_topo *t = hwloc_topo_create (p); assert (t != NULL); status = exec_lstopo (p, ac, av, hwloc_topo_topology (t)); if (status) { if (WIFEXITED (status) && WEXITSTATUS (status) != ENOENT) log_msg_exit ("lstopo: Exited with %d", WEXITSTATUS (status)); if (WIFSIGNALED (status) && WTERMSIG (status) != SIGPIPE) log_msg_exit ("lstopo: %s%s", strsignal (WTERMSIG (status)), WCOREDUMP (status) ? " (core dumped)" : ""); } hwloc_topo_destroy (t); return (0); }
void setup_keydir (struct environment *env, int flags) { const char *dir = getenv ("FLUX_SEC_DIRECTORY"); char *new_dir = NULL; if (!dir) dir = flux_conf_get ("keydir", flags); if (!dir) { struct passwd *pw = getpwuid (getuid ()); if (!pw) log_msg_exit ("Who are you!?!"); dir = new_dir = xasprintf ("%s/.flux", pw->pw_dir); } if (!dir) log_msg_exit ("Could not determine keydir"); environment_set (env, "FLUX_SEC_DIRECTORY", dir, 0); if (new_dir) free (new_dir); }
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); }
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); }
void dirgetas (flux_t *h, const char *dir, const char *key, const char *type) { kvsdir_t *d; if (kvs_get_dir (h, &d, "%s", dir) < 0) log_err_exit ("kvs_get_dir %s", dir); if (type == NULL) { char *value; if (kvsdir_get (d, key, &value) < 0) log_err_exit ("kvsdir_get %s", key); printf ("%s\n", value); free (value); } else if (!strcmp (type, "int")) { int value; if (kvsdir_get_int (d, key, &value) < 0) log_err_exit ("kvsdir_get_int %s", key); printf ("%d\n", value); } else if (!strcmp (type, "int64")) { int64_t value; if (kvsdir_get_int64 (d, key, &value) < 0) log_err_exit ("kvsdir_get_int64 %s", key); printf ("%" PRIi64 "\n", value); } else if (!strcmp (type, "boolean")) { bool value; if (kvsdir_get_boolean (d, key, &value) < 0) log_err_exit ("kvsdir_get_int64 %s", key); printf ("%s\n", value ? "true" : "false"); } else if (!strcmp (type, "double")) { double value; if (kvsdir_get_double (d, key, &value) < 0) log_err_exit ("kvsdir_get_int64 %s", key); printf ("%f\n", value); } else if (!strcmp (type, "string")) { char *s; if (kvsdir_get_string (d, key, &s) < 0) log_err_exit ("kvsdir_get_string %s", key); printf ("%s\n", s); free (s); } else { log_msg_exit ("unknown type (use int/int64/boolean/double/string)"); } kvsdir_destroy (d); }
static int cmd_env (optparse_t *p, int ac, char *av[]) { int n = optparse_option_index (p); if (av && av[n]) { execvp (av[n], av+n); /* no return if sucessful */ log_err_exit ("execvp (%s)", av[n]); } else { struct environment *env = optparse_get_data (p, "env"); if (env == NULL) log_msg_exit ("flux-env: failed to get flux envirnoment!"); print_environment (env); } return (0); }
static void store_completion (flux_rpc_t *rpc, void *arg) { flux_reactor_t *r = arg; const char *blobref; int blobref_size; if (flux_rpc_get_raw (rpc, &blobref, &blobref_size) < 0) log_err_exit ("store"); if (!blobref || blobref[blobref_size - 1] != '\0') log_msg_exit ("store: protocol error"); //printf ("%s\n", blobref); flux_rpc_destroy (rpc); if (--spam_cur_inflight < spam_max_inflight/2) flux_reactor_stop (r); }
int main (int argc, char *argv[]) { flux_t h; int ch; char *message = NULL; size_t len = 0; int severity = LOG_NOTICE; char *appname = "logger"; int e; log_init ("flux-logger"); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 'h': /* --help */ usage (); break; case 's': /* --severity LEVEL */ if ((severity = stdlog_string_to_severity (optarg)) < 0) log_msg_exit ("invalid severity: Use emerg|alert|crit|err|warning|notice|info|debug"); break; case 'n': /* --appname NAME */ appname = optarg; break; default: usage (); break; } } if (optind == argc) usage (); if ((e = argz_create (argv + optind, &message, &len)) != 0) log_errn_exit (e, "argz_create"); argz_stringify (message, len, ' '); if (!(h = flux_open (NULL, 0))) log_err_exit ("flux_open"); flux_log_set_appname (h, appname); flux_log (h, severity, "%s", message); flux_close (h); free (message); log_fini (); return 0; }
/* * 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); }
void exec_subcommand (const char *searchpath, bool vopt, char *argv[]) { if (strchr (argv[0], '/')) { exec_subcommand_dir (vopt, NULL, argv, NULL); log_err_exit ("%s", argv[0]); } else { char *cpy = xstrdup (searchpath); char *dir, *saveptr = NULL, *a1 = cpy; while ((dir = strtok_r (a1, ":", &saveptr))) { exec_subcommand_dir (vopt, dir, argv, "flux-"); a1 = NULL; } free (cpy); log_msg_exit ("`%s' is not a flux command. See 'flux --help'", argv[0]); } }
void test_src (flux_t *h, uint32_t nodeid) { flux_future_t *f; const char *json_str; json_object *out = NULL; int i; if (!(f = flux_rpc (h, "req.src", NULL, nodeid, 0)) || flux_rpc_get (f, &json_str) < 0) log_err_exit ("%s", __FUNCTION__); if (!json_str || !(out = Jfromstr (json_str)) || !Jget_int (out, "wormz", &i) || i != 42) log_msg_exit ("%s: didn't get expected payload", __FUNCTION__); Jput (out); flux_future_destroy (f); }
void test_echo (flux_t *h, uint32_t nodeid) { json_object *in = Jnew (); json_object *out = NULL; const char *json_str; const char *s; flux_future_t *f; Jadd_str (in, "mumble", "burble"); if (!(f = flux_rpc (h, "req.echo", Jtostr (in), nodeid, 0)) || flux_rpc_get (f, &json_str) < 0) log_err_exit ("%s", __FUNCTION__); if (!json_str || !(out = Jfromstr (json_str)) || !Jget_str (out, "mumble", &s) || strcmp (s, "burble") != 0) log_msg_exit ("%s: returned payload wasn't an echo", __FUNCTION__); Jput (in); Jput (out); flux_future_destroy (f); }
int main (int argc, char *argv[]) { thd_t *thd; int i, rc; int ch; tstat_t ts; struct timespec t0; log_init (basename (argv[0])); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 'f': fopt = true; fence_nprocs = strtoul (optarg, NULL, 10); if (!fence_nprocs) log_msg_exit ("fence value must be > 0"); break; case 's': sopt = true; break; case 'n': nopt = true; nopt_divisor = strtoul (optarg, NULL, 10); if (!nopt_divisor) log_msg_exit ("nopt value must be > 0"); break; default: usage (); } } if (argc - optind != 3) usage (); nthreads = strtoul (argv[optind++], NULL, 10); if (!nthreads) log_msg_exit ("thread count must be > 0"); count = strtoul (argv[optind++], NULL, 10); if (!count) log_msg_exit ("commit count must be > 0"); prefix = argv[optind++]; memset (&ts, 0, sizeof (ts)); thd = xzmalloc (sizeof (*thd) * nthreads); if (sopt) monotime (&t0); for (i = 0; i < nthreads; i++) { thd[i].n = i; if (!(thd[i].perf = zlist_new ())) oom (); if ((rc = pthread_attr_init (&thd[i].attr))) log_errn (rc, "pthread_attr_init"); if ((rc = pthread_create (&thd[i].t, &thd[i].attr, thread, &thd[i]))) log_errn (rc, "pthread_create"); } for (i = 0; i < nthreads; i++) { if ((rc = pthread_join (thd[i].t, NULL))) log_errn (rc, "pthread_join"); if (sopt) { double *e; while ((e = zlist_pop (thd[i].perf))) { tstat_push (&ts, *e); free (e); } } zlist_destroy (&thd[i].perf); } if (sopt) { json_t *o; char *s; if (!(o = json_pack ("{s:{s:i s:f s:f s:f s:f} s:f}", "put+commit times (sec)", "count", tstat_count (&ts), "min", tstat_min (&ts)*1E-3, "mean", tstat_mean (&ts)*1E-3, "stddev", tstat_stddev (&ts)*1E-3, "max", tstat_max (&ts)*1E-3, "put+commit throughput (#/sec)", (double)(count*nthreads) / (monotime_since (t0)*1E-3)))) log_err_exit ("json_pack"); if (!(s = json_dumps (o, JSON_INDENT(2)))) log_err_exit ("json_dumps"); printf ("%s\n", s); json_decref (o); free (s); } free (thd); log_fini (); return 0; }
int main (int argc, char *argv[]) { thd_t *thd; int i, rc, ch; log_init (basename (argv[0])); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 'n': nopt = true; break; default: usage (); } } if (argc - optind != 2) usage (); threadcount = strtoul (argv[optind++], NULL, 10); if (!threadcount) log_msg_exit ("thread count must be > 0"); prefix = argv[optind++]; key = xasprintf ("%s.%s", prefix, KEYSUFFIX); /* +1 for watch thread */ thd = xzmalloc (sizeof (*thd) * (threadcount + 1)); /* start watch thread */ thd[threadcount].n = threadcount; if ((rc = pthread_attr_init (&thd[threadcount].attr))) log_errn (rc, "pthread_attr_init"); if ((rc = pthread_create (&thd[threadcount].t, &thd[threadcount].attr, watchthread, &thd[threadcount]))) log_errn (rc, "pthread_create"); /* Wait for watch thread to setup */ pthread_mutex_lock (&watch_init_lock); while (!watch_init) pthread_cond_wait (&watch_init_cond, &watch_init_lock); pthread_mutex_unlock (&watch_init_lock); /* start commit threads */ for (i = 0; i < threadcount; i++) { thd[i].n = i; if ((rc = pthread_attr_init (&thd[i].attr))) log_errn (rc, "pthread_attr_init"); if ((rc = pthread_create (&thd[i].t, &thd[i].attr, committhread, &thd[i]))) log_errn (rc, "pthread_create"); } /* +1 for watch thread */ for (i = 0; i < (threadcount + 1); i++) { if ((rc = pthread_join (thd[i].t, NULL))) log_errn (rc, "pthread_join"); } printf("%d\n", changecount); free (thd); free (key); log_fini (); return 0; }
int main (int argc, char *argv[]) { int ch; int pad_bytes = 0; char *target; flux_watcher_t *tw = NULL; struct ping_ctx ctx = { .period = 1.0, .rank = NULL, .nodeid = FLUX_NODEID_ANY, .topic = NULL, .pad = NULL, .count = -1, .send_count = 0, .batch = false, }; log_init ("flux-ping"); while ((ch = getopt_long (argc, argv, OPTIONS, longopts, NULL)) != -1) { switch (ch) { case 'h': /* --help */ usage (); break; case 'p': /* --pad bytes */ pad_bytes = strtoul (optarg, NULL, 10); break; case 'd': /* --delay seconds */ ctx.period = strtod (optarg, NULL); if (ctx.period < 0) usage (); break; case 'r': /* --rank NODESET */ ctx.rank = optarg; break; case 'c': /* --count N */ ctx.count = strtoul (optarg, NULL, 10); break; case 'b': /* --batch-request */ ctx.batch = true; break; default: usage (); break; } } if (optind != argc - 1) usage (); if (ctx.batch && ctx.count == -1) log_msg_exit ("--batch should only be used with --count"); target = argv[optind++]; /* Create null terminated pad string for reuse in each message. * By default it's the empty string. */ ctx.pad = xzmalloc (pad_bytes + 1); memset (ctx.pad, 'p', pad_bytes); /* If "rank!" is prepended to the target, and there is no --rank * argument, snip it off and set the rank. If it's just the bare * rank, assume the target is "cmb". */ if (ctx.rank == NULL) { char *p; nodeset_t *ns = NULL; if ((p = strchr (target, '!'))) { *p++ = '\0'; ctx.rank = target; target = p; } else if ((ns = nodeset_create_string (target)) != NULL) { ctx.rank = target; target = "cmb"; nodeset_destroy (ns); } else if (!strcmp (target, "all")) { ctx.rank = target; target = "cmb"; } } /* Use singleton rpc if there's only one nodeid */ if (ctx.rank != NULL) { nodeset_t *ns = nodeset_create_string (ctx.rank); if (ns) { if (nodeset_count (ns) == 1) { ctx.nodeid = nodeset_min (ns); ctx.rank = NULL; } nodeset_destroy (ns); } } ctx.topic = xasprintf ("%s.ping", target); if (!(ctx.h = flux_open (NULL, 0))) log_err_exit ("flux_open"); if (!(ctx.reactor = flux_get_reactor (ctx.h))) log_err_exit ("flux_get_reactor"); /* In batch mode, requests are sent before reactor is started * to process responses. o/w requests are set in a timer watcher. */ if (ctx.batch) { while (ctx.send_count < ctx.count) { send_ping (&ctx); usleep ((useconds_t)(ctx.period * 1E6)); } } else { tw = flux_timer_watcher_create (ctx.reactor, ctx.period, ctx.period, timer_cb, &ctx); if (!tw) log_err_exit ("error creating watchers"); flux_watcher_start (tw); } if (flux_reactor_run (ctx.reactor, 0) < 0) log_err_exit ("flux_reactor_run"); /* Clean up. */ flux_watcher_destroy (tw); free (ctx.topic); free (ctx.pad); flux_close (ctx.h); log_fini (); return 0; }