int flux_rpc_get (flux_rpc_t *rpc, uint32_t *nodeid, const char **json_str) { int rc = -1; if (rpc->oneway) { errno = EINVAL; goto done; } if (!rpc->rx_msg && !(rpc->rx_msg = flux_recv (rpc->h, rpc->m, 0))) goto done; flux_msg_destroy (rpc->rx_msg_consumed); /* invalidate last-got payload */ rpc->rx_msg_consumed = rpc->rx_msg; rpc->rx_msg = NULL; rpc->rx_count++; if (nodeid) { uint32_t matchtag; if (flux_msg_get_matchtag (rpc->rx_msg_consumed, &matchtag) < 0) goto done; *nodeid = lookup_nodeid (rpc, matchtag); } if (flux_response_decode (rpc->rx_msg_consumed, NULL, json_str) < 0) goto done; rc = 0; done: return rc; }
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; }
static int rpc_request_send (flux_rpc_t *rpc, int n, const char *topic, const char *json_str, uint32_t nodeid) { flux_msg_t *msg; int flags = 0; int rc = -1; if (!(msg = flux_request_encode (topic, json_str))) goto done; if (flux_msg_set_matchtag (msg, rpc->m.matchtag + n) < 0) goto done; if (nodeid == FLUX_NODEID_UPSTREAM) { flags |= FLUX_MSGFLAG_UPSTREAM; if (flux_get_rank (rpc->h, &nodeid) < 0) goto done; } if (flux_msg_set_nodeid (msg, nodeid, flags) < 0) goto done; if (flux_send (rpc->h, msg, 0) < 0) goto done; rc = 0; done: if (msg) flux_msg_destroy (msg); 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); }
static int op_send (void *impl, const flux_msg_t *msg, int flags) { ctx_t *c = impl; assert (c->magic == CTX_MAGIC); int type; flux_msg_t *cpy = NULL; int rc = -1; if (!(cpy = flux_msg_copy (msg, true))) goto done; if (flux_msg_get_type (cpy, &type) < 0) goto done; switch (type) { case FLUX_MSGTYPE_REQUEST: case FLUX_MSGTYPE_EVENT: if (flux_msg_enable_route (cpy) < 0) goto done; if (flux_msg_push_route (cpy, fake_uuid) < 0) goto done; break; } if (msglist_append (c->queue, cpy) < 0) goto done; cpy = NULL; /* c->queue now owns cpy */ rc = 0; done: if (cpy) flux_msg_destroy (cpy); return rc; }
static int send_state_event (flux_t h, job_state_t st, int64_t j) { flux_msg_t *msg; char *json = NULL; char *topic = NULL; int rc = -1; if ((asprintf (&json, "{\"lwj\":%"PRId64"}", j) < 0) || (asprintf (&topic, "jsc.state.%s", jsc_job_num2state (st)) < 0)) { errno = ENOMEM; flux_log_error (h, "create state change event: %s", jsc_job_num2state (st)); goto done; } if ((msg = flux_event_encode (topic, json)) == NULL) { flux_log_error (h, "flux_event_encode"); goto done; } if (flux_send (h, msg, 0) < 0) flux_log_error (h, "flux_send event"); flux_msg_destroy (msg); rc = 0; done: free (topic); free (json); return rc; }
flux_msg_t *flux_event_encode (const char *topic, const char *json_str) { flux_msg_t *msg = NULL; if (!topic) { errno = EINVAL; goto error; } if (!(msg = flux_msg_create (FLUX_MSGTYPE_EVENT))) goto error; if (flux_msg_set_topic (msg, topic) < 0) goto error; if (flux_msg_enable_route (msg) < 0) goto error; if (json_str && flux_msg_set_payload_json (msg, json_str) < 0) goto error; return msg; error: if (msg) { int saved_errno = errno; flux_msg_destroy (msg); errno = saved_errno; } return NULL; }
/* Send sched.free request for job. * Update flags. */ int free_request (struct alloc_ctx *ctx, struct job *job) { flux_msg_t *msg; if (!(msg = flux_request_encode ("sched.free", NULL))) return -1; if (flux_msg_pack (msg, "{s:I}", "id", job->id) < 0) goto error; if (flux_send (ctx->h, msg, 0) < 0) goto error; flux_msg_destroy (msg); return 0; error: flux_msg_destroy (msg); return -1; }
static void send_create_event (flux_t h, int64_t id, char *topic) { flux_msg_t *msg; char *json = NULL; if (asprintf (&json, "{\"lwj\":%ld}", id) < 0) { errno = ENOMEM; flux_log_error (h, "failed to create state change event"); goto out; } if ((msg = flux_event_encode (topic, json)) == NULL) { flux_log_error (h, "failed to create state change event"); goto out; } if (flux_send (h, msg, 0) < 0) flux_log_error (h, "reserved event failed"); flux_msg_destroy (msg); /* Workaround -- wait for our own event to be published with a * blocking recv. XXX: Remove when publish is synchronous. */ wait_for_event (h, id, topic); out: free (json); }
void cmd_dropcache_all (flux_t h, int argc, char **argv) { if (argc != 0) msg_exit ("dropcache-all: takes no arguments"); flux_msg_t *msg = flux_event_encode ("kvs.dropcache", NULL); if (!msg || flux_send (h, msg, 0) < 0) err_exit ("flux_send"); flux_msg_destroy (msg); }
/* Reactor loop just unblocked. */ static void check_cb (flux_reactor_t *r, flux_watcher_t *w, int revents, void *arg) { ctx_t *ctx = arg; flux_msg_t *msg = flux_keepalive_encode (0, FLUX_MODSTATE_RUNNING); if (!msg || flux_send (ctx->h, msg, 0) < 0) flux_log_error (ctx->h, "error sending keepalive"); flux_msg_destroy (msg); }
static void defer_destroy (zlist_t **l) { flux_msg_t *msg; if (*l) { while ((msg = zlist_pop (*l))) flux_msg_destroy (msg); zlist_destroy (l); } }
void wait_destroy (wait_t *w) { if (w) { assert (w->magic == WAIT_MAGIC); assert (w->usecount == 0); flux_msg_destroy (w->hand.msg); w->magic = ~WAIT_MAGIC; free (w); } }
int publisher_send (struct publisher *pub, const flux_msg_t *msg) { flux_msg_t *cpy; if (!(cpy = flux_msg_copy (msg, true))) return -1; if (flux_msg_clear_route (cpy) < 0) goto error; if (flux_msg_set_seq (cpy, ++pub->seq) < 0) goto error_restore_seq; send_event (pub, cpy); flux_msg_destroy (cpy); return 0; error_restore_seq: pub->seq--; error: flux_msg_destroy (cpy); return -1; }
void check_codec (void) { flux_msg_t *msg; int epoch; ok ((msg = flux_heartbeat_encode (44000)) != NULL, "flux_heartbeat_encode works"); ok (flux_heartbeat_decode (msg, &epoch) == 0 && epoch == 44000, "flux_heartbeat_decode works and returns encoded epoch"); flux_msg_destroy (msg); }
/* Send sched.alloc request for job. * Update flags. */ int alloc_request (struct alloc_ctx *ctx, struct job *job) { flux_msg_t *msg; if (!(msg = flux_request_encode ("sched.alloc", NULL))) return -1; if (flux_msg_pack (msg, "{s:I s:i s:i s:f}", "id", job->id, "priority", job->priority, "userid", job->userid, "t_submit", job->t_submit) < 0) goto error; if (flux_send (ctx->h, msg, 0) < 0) goto error; flux_msg_destroy (msg); return 0; error: flux_msg_destroy (msg); return -1; }
static void wait_for_event (flux_t h, int64_t id, char *topic) { struct flux_match match = { .typemask = FLUX_MSGTYPE_EVENT, .matchtag = FLUX_MATCHTAG_NONE, }; match.topic_glob = topic; flux_msg_t *msg = flux_recv (h, match, 0); flux_msg_destroy (msg); return; }
int flux_rpc_next (flux_rpc_t *rpc) { assert (rpc->magic == RPC_MAGIC); if (flux_fatality (rpc->h)) return -1; if (rpc->rx_count >= rpc->rx_expected) return -1; flux_msg_destroy (rpc->rx_msg); rpc->rx_msg = NULL; rpc->rx_errnum = 0; return 0; }
flux_msg_t *flux_event_encode (const char *topic, const char *s) { flux_msg_t *msg = flux_event_create (topic); if (!msg) goto error; if (s && flux_msg_set_string (msg, s) < 0) goto error; return msg; error: flux_msg_destroy (msg); return NULL; }
void wait_destroy (wait_t *w, double *msec) { assert (w->magic == WAIT_MAGIC); assert (w->usecount == 0); if (msec) *msec = monotime_since (w->t0); flux_msg_destroy (w->hand.msg); if (w->id) free (w->id); w->magic = ~WAIT_MAGIC; free (w); }
static int client_send (client_t *c, const flux_msg_t *msg) { flux_msg_t *cpy = flux_msg_copy (msg, true); int rc; if (!cpy) { errno = ENOMEM; return -1; } rc = client_send_nocopy (c, &cpy); flux_msg_destroy (cpy); return rc; }
static int defer_requeue (zlist_t **l, flux_t h) { flux_msg_t *msg; if (*l) { while ((msg = zlist_pop (*l))) { int rc = flux_requeue (h, msg, FLUX_RQ_TAIL); flux_msg_destroy (msg); if (rc < 0) return -1; } } return 0; }
flux_msg_t *flux_event_encode_raw (const char *topic, const void *data, int len) { flux_msg_t *msg = flux_event_create (topic); if (!msg) goto error; if (data && flux_msg_set_payload (msg, data, len) < 0) goto error; return msg; error: flux_msg_destroy (msg); return NULL; }
static flux_msg_t *flux_event_vpack (const char *topic, const char *fmt, va_list ap) { flux_msg_t *msg = flux_event_create (topic); if (!msg) goto error; if (flux_msg_vpack (msg, fmt, ap) < 0) goto error; return msg; error: flux_msg_destroy (msg); return NULL; }
int main (int argc, char *argv[]) { flux_t *h; flux_msg_t *msg; const char *topic; const char *reason; int flags; plan (NO_PLAN); if (!(h = loopback_create (0))) BAIL_OUT ("loopback_create failed"); /* Send request */ ok (flux_panic (h, 0, 0, "fubar") == 0, "flux_panic works"); /* Receive request on the loopback */ msg = flux_recv (h, FLUX_MATCH_ANY, 0); ok (msg != NULL, "flux_recv received message on loop"); ok (flux_request_unpack (msg, &topic, "{s:s s:i}", "reason", &reason, "flags", &flags) == 0, "flux_request_unpack worked on panic request"); ok (topic != NULL && !strcmp (topic, "cmb.panic"), "topic string is correct"); ok (!strcmp (reason, "fubar"), "reason is correct"); ok (flags == 0, "flags is correct"); flux_msg_destroy (msg); /* invalid arguments */ errno = 0; ok (flux_panic (NULL, 0, 0, "foo") < 0 && errno == EINVAL, "flux_panic h=NULL fails with EINVAL"); errno = 0; ok (flux_panic (h, 0, 1, "foo") < 0 && errno == EINVAL, "flux_panic flags=1 fails with EINVAL"); errno = 0; ok (flux_panic (h, 0, 0, NULL) < 0 && errno == EINVAL, "flux_panic reason=NULL fails with EINVAL"); flux_close (h); done_testing(); return (0); }
void pub_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { struct publisher *pub = arg; const char *topic; const char *payload = NULL; // optional int flags; uint32_t rolemask, userid; flux_msg_t *event = NULL; if (flux_request_unpack (msg, NULL, "{s:s s:i s?:s}", "topic", &topic, "flags", &flags, "payload", &payload) < 0) goto error; if ((flags & ~(FLUX_MSGFLAG_PRIVATE)) != 0) { errno = EPROTO; goto error; } if (flux_msg_get_rolemask (msg, &rolemask) < 0) goto error; if (flux_msg_get_userid (msg, &userid) < 0) goto error; if (!(event = encode_event (topic, flags, rolemask, userid, ++pub->seq, payload))) goto error_restore_seq; send_event (pub, event); if (flux_respond_pack (h, msg, "{s:i}", "seq", pub->seq) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); flux_msg_destroy (event); return; error_restore_seq: pub->seq--; error: if (flux_respond (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); flux_msg_destroy (event); }
int main (int argc, char *argv[]) { flux_msg_t *msg; flux_t h; flux_reactor_t *reactor; plan (35); (void)setenv ("FLUX_CONNECTOR_PATH", CONNECTOR_PATH, 0); ok ((h = flux_open ("loop://", FLUX_O_COPROC)) != NULL, "opened loop connector"); if (!h) BAIL_OUT ("can't continue without loop handle"); ok ((reactor = flux_get_reactor (h)) != NULL, "obtained reactor"); if (!reactor) BAIL_OUT ("can't continue without reactor"); flux_fatal_set (h, fatal_err, NULL); flux_fatal_error (h, __FUNCTION__, "Foo"); ok (fatal_tested == true, "flux_fatal function is called on fatal error"); /* create nodeset for last _then test */ ok ((then_ns = nodeset_create ()) != NULL, "nodeset created ok"); ok (flux_msghandler_addvec (h, htab, htablen, NULL) == 0, "registered message handlers"); /* test continues in rpctest_begin_cb() so that rpc calls * can sleep while we answer them */ ok ((msg = flux_request_encode ("rpctest.begin", NULL)) != NULL && flux_send (h, msg, 0) == 0, "sent message to initiate test"); ok (flux_reactor_run (reactor, 0) == 0, "reactor completed normally"); flux_msg_destroy (msg); /* Check result of last _then test */ ok (nodeset_count (then_ns) == 128, "then callback worked with correct nodemap"); nodeset_destroy (then_ns); flux_rpc_destroy (then_r); flux_close (h); done_testing(); return (0); }
static int hello_sendmsg (hello_t *hello, uint32_t rank) { flux_msg_t *msg; int rc = -1; if (!(msg = hello_encode (rank))) goto done; if (flux_send (hello->h, msg, 0) < 0) goto done; rc = 0; done: flux_msg_destroy (msg); return rc; }
static int send_request (flux_t h, const char *topic) { int rc = -1; flux_msg_t *msg = flux_request_encode (topic, NULL); if (!msg || flux_send (h, msg, 0) < 0) { fprintf (stderr, "%s: flux_send failed: %s", __FUNCTION__, strerror (errno)); goto done; } rc = 0; done: flux_msg_destroy (msg); return rc; }
static flux_msg_t *encode_event (const char *topic, int flags, uint32_t rolemask, uint32_t userid, uint32_t seq, const char *src) { flux_msg_t *msg; void *dst = NULL; int saved_errno; if (!(msg = flux_msg_create (FLUX_MSGTYPE_EVENT))) goto error; if (flux_msg_set_topic (msg, topic) < 0) goto error; if (flux_msg_set_userid (msg, userid) < 0) goto error; if (flux_msg_set_rolemask (msg, rolemask) < 0) goto error; if (flux_msg_set_seq (msg, seq) < 0) goto error; if ((flags & FLUX_MSGFLAG_PRIVATE)) { if (flux_msg_set_private (msg) < 0) goto error; } if (src) { // optional payload int srclen = strlen (src); size_t dstlen = BASE64_DECODE_SIZE (srclen); if (!(dst = malloc (dstlen))) goto error; if (sodium_base642bin ((unsigned char *)dst, dstlen, src, srclen, NULL, &dstlen, NULL, sodium_base64_VARIANT_ORIGINAL) < 0) { errno = EPROTO; goto error; } if (flux_msg_set_payload (msg, dst, dstlen) < 0) { if (errno == EINVAL) errno = EPROTO; goto error; } } free (dst); return msg; error: saved_errno = errno; free (dst); flux_msg_destroy (msg); errno = saved_errno; return NULL; }