Пример #1
0
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;
}
Пример #2
0
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;
}
Пример #3
0
/* 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));
}
Пример #4
0
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);
}
Пример #5
0
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;
}
Пример #6
0
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;
}
Пример #7
0
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;
}
Пример #8
0
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;
}
Пример #9
0
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;
}
Пример #10
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;
}
Пример #11
0
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;
}
Пример #12
0
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);
}
Пример #13
0
/* 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;
}
Пример #14
0
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);
}