/* 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); }
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); }