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; }
int flux_event_decode (const flux_msg_t *msg, const char **topic, const char **json_str) { int type; const char *ts, *js; int rc = -1; if (msg == NULL) { errno = EINVAL; goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; if (type != FLUX_MSGTYPE_EVENT) { errno = EPROTO; goto done; } if (flux_msg_get_topic (msg, &ts) < 0) goto done; if (flux_msg_get_payload_json (msg, &js) < 0) goto done; if ((json_str && !js) || (!json_str && js)) { errno = EPROTO; goto done; } if (topic) *topic = ts; if (json_str) *json_str = js; rc = 0; done: return rc; }
/* Handle the simplest possible request. * Verify that everything is as expected; log it and stop the reactor if not. */ void null_request_cb (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg, void *arg) { ctx_t *ctx = arg; const char *topic; int type, size; void *buf; uint32_t nodeid; int flags; if (!msg) { flux_log (h, LOG_ERR, "%s: got NULL msg!", __FUNCTION__); goto error; } if (flux_msg_get_type (msg, &type) < 0) { flux_log_error (h, "%s: flux_msg_get_type", __FUNCTION__); goto error; } if (type != FLUX_MSGTYPE_REQUEST) { flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__, flux_msg_typestr (type)); goto error; } if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) { flux_log_error (h, "%s: flux_msg_get_nodeid", __FUNCTION__); goto error; } if (nodeid != ctx->rank && nodeid != FLUX_NODEID_ANY) { flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__, nodeid); goto error; } if (flux_msg_get_topic (msg, &topic) < 0) { flux_log_error (h, "%s: flux_msg_get_topic", __FUNCTION__); goto error; } if (strcmp (topic, "req.null") != 0) { flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__, topic); goto error; } if (flux_msg_get_payload (msg, &flags, &buf, &size) == 0) { flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__, size); goto error; } if (errno != EPROTO) { flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__, strerror (errno)); goto error; } if (flux_respond (h, msg, 0, NULL) < 0) { flux_log_error (h, "%s: flux_respond", __FUNCTION__); goto error; } return; error: flux_reactor_stop_error (flux_get_reactor (h)); }
static void profiling_msg_snapshot (flux_t *h, const flux_msg_t *msg, int flags, const char *msg_action) { h = lookup_clone_ancestor (h); cali_id_t attributes[3]; const void * data[3]; size_t size[3]; // This can get called before the handle is really ready if(! h->prof.initialized) return; int len = 0; if (msg_action) { attributes[len] = h->prof.msg_action; data[len] = msg_action; size[len] = strlen(msg_action); ++len; } int type; flux_msg_get_type (msg, &type); const char *msg_type = flux_msg_typestr (type); if (msg_type) { attributes[len] = h->prof.msg_type; data[len] = msg_type; size[len] = strlen(msg_type); ++len; } const char *msg_topic; if (type != FLUX_MSGTYPE_KEEPALIVE) flux_msg_get_topic (msg, &msg_topic); else msg_topic = "NONE"; /* attributes[len] = h->prof.msg_topic; */ /* data[len] = msg_topic; */ /* size[len] = strlen(msg_topic); */ /* ++len; */ if (type == FLUX_MSGTYPE_EVENT) { uint32_t seq; flux_msg_get_seq (msg, &seq); cali_begin_int (h->prof.msg_seq, seq); } cali_push_snapshot (CALI_SCOPE_PROCESS | CALI_SCOPE_THREAD, len /* n_entries */, attributes /* event_attributes */, data /* event_data */, size /* event_size */); if (type == FLUX_MSGTYPE_EVENT) cali_end (h->prof.msg_seq); }
flux_msg_t *module_recvmsg (module_t *p) { flux_msg_t *msg = NULL; int type; assert (p->magic == MODULE_MAGIC); if (!(msg = flux_msg_recvzsock (p->sock))) goto error; if (flux_msg_get_type (msg, &type) == 0 && type == FLUX_MSGTYPE_RESPONSE) { if (flux_msg_pop_route (msg, NULL) < 0) /* simulate DEALER socket */ goto error; } return msg; error: flux_msg_destroy (msg); return NULL; }
static int coproc_cb (coproc_t *c, void *arg) { flux_msg_handler_t *w = arg; flux_msg_t *msg; int type; int rc = -1; if (!(msg = flux_recv (w->d->h, FLUX_MATCH_ANY, FLUX_O_NONBLOCK))) { if (errno == EAGAIN || errno == EWOULDBLOCK) rc = 0; goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; w->fn (w->d->h, w, msg, w->arg); rc = 0; done: flux_msg_destroy (msg); return rc; }
int module_sendmsg (module_t *p, const flux_msg_t *msg) { flux_msg_t *cpy = NULL; int type; int rc = -1; if (!msg) return 0; if (flux_msg_get_type (msg, &type) < 0) goto done; switch (type) { case FLUX_MSGTYPE_REQUEST: { /* simulate DEALER socket */ char uuid[16]; snprintf (uuid, sizeof (uuid), "%u", p->rank); if (!(cpy = flux_msg_copy (msg, true))) goto done; if (flux_msg_push_route (cpy, uuid) < 0) goto done; if (flux_msg_sendzsock (p->sock, cpy) < 0) goto done; break; } case FLUX_MSGTYPE_RESPONSE: { /* simulate ROUTER socket */ if (!(cpy = flux_msg_copy (msg, true))) goto done; if (flux_msg_pop_route (cpy, NULL) < 0) goto done; if (flux_msg_sendzsock (p->sock, cpy) < 0) goto done; break; } default: if (flux_msg_sendzsock (p->sock, msg) < 0) goto done; break; } rc = 0; done: flux_msg_destroy (cpy); return rc; }
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; 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 void update_rx_stats (flux_t h, const flux_msg_t *msg) { int type; if (flux_msg_get_type (msg, &type) == 0) { switch (type) { case FLUX_MSGTYPE_REQUEST: h->msgcounters.request_rx++; break; case FLUX_MSGTYPE_RESPONSE: h->msgcounters.response_rx++; break; case FLUX_MSGTYPE_EVENT: h->msgcounters.event_rx++; break; case FLUX_MSGTYPE_KEEPALIVE: h->msgcounters.keepalive_rx++; break; } } else errno = 0; }
static int op_send (void *impl, const flux_msg_t *msg, int flags) { ctx_t *ctx = impl; assert (ctx->magic == MODHANDLE_MAGIC); flux_msg_t *cpy = NULL; int type; int rc = -1; if (connect_socket (ctx) < 0) goto done; if (flux_msg_get_type (msg, &type) < 0) goto done; switch (type) { case FLUX_MSGTYPE_REQUEST: case FLUX_MSGTYPE_EVENT: if (!(cpy = flux_msg_copy (msg, true))) goto done; if (flux_msg_enable_route (cpy) < 0) goto done; if (flux_msg_push_route (cpy, ctx->uuid) < 0) goto done; if (flux_msg_sendzsock (ctx->sock, cpy) < 0) goto done; break; case FLUX_MSGTYPE_RESPONSE: case FLUX_MSGTYPE_KEEPALIVE: if (flux_msg_sendzsock (ctx->sock, msg) < 0) goto done; break; default: errno = EINVAL; goto done; } rc = 0; done: flux_msg_destroy (cpy); return rc; }
static int event_decode (const flux_msg_t *msg, const char **topic) { int type; const char *ts; int rc = -1; if (msg == NULL) { errno = EINVAL; goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; if (type != FLUX_MSGTYPE_EVENT) { errno = EPROTO; goto done; } if (flux_msg_get_topic (msg, &ts) < 0) goto done; if (topic) *topic = ts; rc = 0; done: return rc; }
static void client_read_cb (flux_t h, flux_fd_watcher_t *w, int fd, int revents, void *arg) { client_t *c = arg; flux_msg_t *msg = NULL; int type; if (revents & FLUX_POLLERR) goto disconnect; if (!(revents & FLUX_POLLIN)) return; /* EPROTO, ECONNRESET are normal disconnect errors * EWOULDBLOCK, EAGAIN stores state in c->inbuf for continuation */ //flux_log (h, LOG_DEBUG, "recv: client ready"); if (!(msg = flux_msg_recvfd (c->fd, &c->inbuf))) { if (errno == EWOULDBLOCK || errno == EAGAIN) { //flux_log (h, LOG_DEBUG, "recv: client not ready"); return; } if (errno != ECONNRESET && errno != EPROTO) flux_log (h, LOG_ERR, "flux_msg_recvfd: %s", strerror (errno)); goto disconnect; } if (flux_msg_get_type (msg, &type) < 0) { flux_log (h, LOG_ERR, "flux_msg_get_type: %s", strerror (errno)); goto disconnect; } switch (type) { const char *name; subscription_t *sub; case FLUX_MSGTYPE_REQUEST: if (match_substr (msg, "api.event.subscribe.", &name)) { sub = subscription_create (h, FLUX_MSGTYPE_EVENT, name); if (zlist_append (c->subscriptions, sub) < 0) oom (); } else if (match_substr (msg, "api.event.unsubscribe.", &name)) { if ((sub = subscription_lookup (c, FLUX_MSGTYPE_EVENT, name))) zlist_remove (c->subscriptions, sub); } else { /* insert disconnect notifier before forwarding request */ if (c->disconnect_notify && disconnect_update (c, msg) < 0) { flux_log (h, LOG_ERR, "disconnect_update: %s", strerror (errno)); goto disconnect; } if (flux_msg_push_route (msg, zuuid_str (c->uuid)) < 0) oom (); /* FIXME */ if (flux_send (h, msg, 0) < 0) err ("%s: flux_send", __FUNCTION__); } break; case FLUX_MSGTYPE_EVENT: if (flux_send (h, msg, 0) < 0) err ("%s: flux_send", __FUNCTION__); break; default: flux_log (h, LOG_ERR, "drop unexpected %s", flux_msg_typestr (type)); break; } flux_msg_destroy (msg); return; disconnect: flux_msg_destroy (msg); zlist_remove (c->ctx->clients, c); client_destroy (c); }
/* Handle the simplest possible request. * Verify that everything is as expected; log it and stop the reactor if not. */ static int null_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg) { //ctx_t *ctx = arg; const char *topic; int type, size, flags; int rc = -1; void *buf; uint32_t nodeid; if (!zmsg || !*zmsg) { flux_log (h, LOG_ERR, "%s: got NULL zmsg!", __FUNCTION__); goto done; } if (flux_msg_get_type (*zmsg, &type) < 0) { flux_log (h, LOG_ERR, "%s: flux_msg_get_type: %s", __FUNCTION__, strerror (errno)); goto done; } if (type != FLUX_MSGTYPE_REQUEST) { flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__, flux_msg_typestr (type)); goto done; } if (flux_msg_get_nodeid (*zmsg, &nodeid, &flags) < 0) { flux_log (h, LOG_ERR, "%s: flux_msg_get_nodeid: %s", __FUNCTION__, strerror (errno)); goto done; } if (nodeid != FLUX_NODEID_ANY && nodeid != flux_rank (h)) { flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__, nodeid); goto done; } if (flux_msg_get_topic (*zmsg, &topic) < 0) { flux_log (h, LOG_ERR, "%s: flux_msg_get_topic: %s", __FUNCTION__, strerror (errno)); goto done; } if (strcmp (topic, "req.null") != 0) { flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__, topic); goto done; } if (flux_msg_get_payload (*zmsg, &flags, &buf, &size) == 0) { flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__, size); goto done; } if (errno != EPROTO) { flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__, strerror (errno)); goto done; } errno = 0; if (flux_err_respond (h, 0, zmsg) < 0) { flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__, strerror (errno)); goto done; } rc = 0; done: return rc; }
static void handle_cb (flux_reactor_t *r, flux_watcher_t *hw, int revents, void *arg) { struct dispatch *d = arg; flux_msg_handler_t *w; flux_msg_t *msg = NULL; int type; if (revents & FLUX_POLLERR) goto fatal; if (!(msg = flux_recv (d->h, FLUX_MATCH_ANY, FLUX_O_NONBLOCK))) { if (errno != EAGAIN && errno != EWOULDBLOCK) goto fatal; else goto done; } if (flux_msg_get_type (msg, &type) < 0) goto done; /* Message matches a coproc that yielded. * Resume, arranging for msg to be returned next by flux_recv(). */ if ((w = find_waiting_handler (d, msg))) { if (flux_requeue (d->h, msg, FLUX_RQ_HEAD) < 0) goto fatal; zlist_remove (d->waiters, w); if (resume_coproc (w) < 0) goto fatal; /* Message matches a handler. * If coproc already running, queue message as backlog. * Else if FLUX_O_COPROC, start coproc. * If coprocs not enabled, call handler directly. */ } else if ((w = find_handler (d, msg))) { if (w->coproc && coproc_started (w->coproc)) { if (backlog_append (w, &msg) < 0) /* msg now property of backlog */ goto fatal; } else if ((flux_flags_get (d->h) & FLUX_O_COPROC)) { if (flux_requeue (d->h, msg, FLUX_RQ_HEAD) < 0) goto fatal; if (start_coproc (w) < 0) goto fatal; } else { w->fn (d->h, w, msg, w->arg); } /* Message matched nothing. * Respond with ENOSYS if it was a request. * Else log it if FLUX_O_TRACE */ } else { if (type == FLUX_MSGTYPE_REQUEST) { if (flux_respond (d->h, msg, ENOSYS, NULL)) goto done; } else if (flux_flags_get (d->h) & FLUX_O_TRACE) { const char *topic = NULL; (void)flux_msg_get_topic (msg, &topic); fprintf (stderr, "nomatch: %s '%s'\n", flux_msg_typestr (type), topic ? topic : ""); } } done: flux_msg_destroy (msg); return; fatal: flux_msg_destroy (msg); flux_reactor_stop_error (r); FLUX_FATAL (d->h); }