예제 #1
0
파일: module.c 프로젝트: surajpkn/flux-core
int module_event_mcast (modhash_t *mh, const flux_msg_t *msg)
{
    const char *topic;
    zlist_t *uuids;
    char *uuid;
    int rc = -1;

    if (flux_msg_get_topic (msg, &topic) < 0)
        goto done;
    if (!(uuids = zhash_keys (mh->zh_byuuid)))
        oom ();
    uuid = zlist_first (uuids);
    while (uuid) {
        module_t *p = zhash_lookup (mh->zh_byuuid, uuid);
        assert (p != NULL);
        if (match_sub (p, topic)) {
            if (module_sendmsg (p, msg) < 0)
                goto done;
        }
        uuid = zlist_next (uuids);
    }
    rc = 0;
done:
    zlist_destroy (&uuids);
    return rc;
}
예제 #2
0
static int disconnect_update (client_t *c, const flux_msg_t *msg)
{
    char *p;
    char *key = NULL;
    char *svc = NULL;
    const char *topic;
    uint32_t nodeid;
    int flags;
    struct disconnect_notify *d;
    int rc = -1;

    if (flux_msg_get_topic (msg, &topic) < 0)
        goto done;
    if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0)
        goto done;
    svc = xstrdup (topic);
    if ((p = strchr (svc, '.')))
        *p = '\0';
    key = xasprintf ("%s:%u:%d", svc, nodeid, flags);
    if (!zhash_lookup (c->disconnect_notify, key)) {
        d = xzmalloc (sizeof (*d));
        d->nodeid = nodeid;
        d->flags = flags;
        d->topic = xasprintf ("%s.disconnect", svc);
        zhash_update (c->disconnect_notify, key, d);
    }
    rc = 0;
done:
    if (svc)
        free (svc);
    if (key)
        free (key);
    return rc;
}
예제 #3
0
static void job_state_cb (flux_t h, flux_msg_handler_t *w,
                          const flux_msg_t *msg, void *arg)
{
    int64_t jobid = -1;
    json_object *o = NULL;
    const char *topic = NULL;
    const char *json_str = NULL;
    const char *state = NULL;
    int len = 12;

    if (flux_msg_get_topic (msg, &topic) < 0)
        goto done;

    if (flux_event_decode (msg, NULL, &json_str) < 0
            || !(o = Jfromstr (json_str))
            || !Jget_int64 (o, "lwj", &jobid)) {
        flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__);
        goto done;
    }

    if (strncmp (topic, "jsc", 3) == 0)
       len = 10;

    state = topic + len;
    if (strcmp (state, jsc_job_num2state (J_RESERVED)) == 0)
        fixup_newjob_event (h, jobid);

    if (invoke_cbs (h, jobid, get_update_jcb (h, jobid, state), 0) < 0)
        flux_log (h, LOG_ERR, "job_state_cb: failed to invoke callbacks");

    if (job_is_finished (state))
        delete_jobinfo (h, jobid);
done:
    return;
}
예제 #4
0
파일: event.c 프로젝트: surajpkn/flux-core
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;
}
예제 #5
0
파일: req.c 프로젝트: cigolabs/flux-core
/* 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));
}
예제 #6
0
static void multmatch2 (flux_t h, flux_msg_handler_t *w, const flux_msg_t *msg,
                        void *arg)
{
    const char *topic;
    if (flux_msg_get_topic (msg, &topic) < 0 || strcmp (topic, "foo.bar"))
        flux_reactor_stop_error (flux_get_reactor (h));
    flux_msg_handler_stop (w);
    multmatch_count++;
}
예제 #7
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);
}
예제 #8
0
static bool match_substr (zmsg_t *zmsg, const char *topic, const char **rest)
{
    const char *s;
    if (flux_msg_get_topic (zmsg, &s) < 0)
        return false;
    if (strncmp(topic, s, strlen (topic)) != 0)
        return false;
    if (rest)
        *rest = s + strlen (topic);
    return true;
}
예제 #9
0
static bool subscription_match (client_t *c, const flux_msg_t *msg)
{
    subscription_t *sub;
    const char *topic;

    if (flux_msg_get_topic (msg, &topic) < 0)
        return false;
    sub = zlist_first (c->subscriptions);
    while (sub) {
        if (!strncmp (topic, sub->topic, strlen (sub->topic)))
            return true;
        sub = zlist_next (c->subscriptions);
    }
    return false;
}
예제 #10
0
int main (int argc, char **argv)
{
    flux_t *h;
    flux_msg_t *msg;
    const char *topic;

    if (!(h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");
    if (flux_event_subscribe (h, "hb") < 0)
        log_err_exit ("flux_event_subscribe");
    if (!(msg = flux_recv (h, FLUX_MATCH_EVENT, 0)))
        log_err_exit ("flux_recv");
    if (flux_msg_get_topic (msg, &topic) < 0)
        log_err_exit ("flux_msg_get_topic");
    printf ("Event: %s\n", topic);
    if (flux_event_unsubscribe (h, "hb") < 0)
        log_err_exit ("flux_event_unsubscribe");
    flux_msg_destroy (msg);
    flux_close (h);
    return (0);
}
예제 #11
0
파일: jstatctl.c 프로젝트: trws/flux-core
static void job_state_cb (flux_t *h, flux_msg_handler_t *mh,
                          const flux_msg_t *msg, void *arg)
{
    json_object *jcb = NULL;
    int64_t jobid = -1;
    const char *topic = NULL;
    const char *state = NULL;
    const char *kvs_path = NULL;
    int len = 12;

    if (flux_msg_get_topic (msg, &topic) < 0)
        goto done;

    if (flux_event_unpack (msg, NULL, "{ s:I }", "lwj", &jobid) < 0) {
        flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__);
        goto done;
    }

    if (!flux_event_unpack (msg, NULL, "{ s:s }", "kvs_path", &kvs_path)) {
        if (jscctx_add_jobid_path (getctx (h), jobid, kvs_path) < 0)
            flux_log_error (h, "jscctx_add_jobid_path");
    }

    if (strncmp (topic, "jsc", 3) == 0)
       len = 10;

    state = topic + len;
    if (strcmp (state, jsc_job_num2state (J_RESERVED)) == 0)
        fixup_newjob_event (h, jobid);

    if (invoke_cbs (h, jobid, jcb = get_update_jcb (h, jobid, state), 0) < 0)
        flux_log (h, LOG_ERR, "job_state_cb: failed to invoke callbacks");

    if (job_is_finished (state))
        delete_jobinfo (h, jobid);
done:
    Jput (jcb);
    return;
}
예제 #12
0
static void run_cb (flux_t *h,
                    flux_msg_handler_t *w,
                    const flux_msg_t *msg,
                    void *arg)
{
    const char *topic;
    ctx_t *ctx = (ctx_t *)arg;
    int *jobid = (int *)malloc (sizeof (int));

    if (flux_msg_get_topic (msg, &topic) < 0) {
        flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__);
        free (jobid);
        return;
    }

    // Logging
    flux_log (h, LOG_DEBUG, "received a request (%s)", topic);

    // Handle Request
    sscanf (topic, "sim_exec.run.%d", jobid);
    zlist_append (ctx->queued_events, jobid);
    flux_log (h, LOG_DEBUG, "queued the running of jobid %d", *jobid);
}
예제 #13
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;
}
예제 #14
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;
}
예제 #15
0
static int job_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    const char *json_str;
    json_object *o = NULL;
    const char *topic;

    if (flux_msg_get_topic (*zmsg, &topic) < 0)
        goto out;
    if (flux_msg_get_payload_json (*zmsg, &json_str) < 0)
        goto out;
    if (json_str && !(o = json_tokener_parse (json_str)))
        goto out;
    if (strcmp (topic, "job.shutdown") == 0) {
        flux_reactor_stop (h);
    }
    if (strcmp (topic, "job.next-id") == 0) {
        if (flux_rank (h) == 0) {
            unsigned long id = lwj_next_id (h);
            json_object *ox = json_id (id);
            flux_json_respond (h, ox, zmsg);
            json_object_put (o);
        }
        else {
            fprintf (stderr, "%s: forwarding request\n", topic);
            flux_json_request (h, FLUX_NODEID_ANY,
                                  FLUX_MATCHTAG_NONE, topic, o);
        }
    }
    if (strcmp (topic, "job.create") == 0) {
        json_object *jobinfo = NULL;
        unsigned long id = lwj_next_id (h);
        bool should_workaround = false;

        //"Fix" for Race Condition
        if (util_json_object_get_boolean (o, "race_workaround",
                                           &should_workaround) < 0) {
            should_workaround = false;
        } else if (should_workaround) {
            if (wait_for_lwj_watch_init (h, id) < 0) {
              flux_err_respond (h, errno, zmsg);
              goto out;
            }
        }

        int rc = kvs_job_new (h, id);
        if (rc < 0) {
            flux_err_respond (h, errno, zmsg);
            goto out;
        }
        add_jobinfo (h, id, o);

        kvs_commit (h);

        /* Generate reply with new jobid */
        jobinfo = util_json_object_new_object ();
        util_json_object_add_int64 (jobinfo, "jobid", id);
        flux_json_respond (h, jobinfo, zmsg);
        json_object_put (jobinfo);
    }

out:
    if (o)
        json_object_put (o);
    zmsg_destroy (zmsg);
    return 0;
}
예제 #16
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);
}