Пример #1
0
static int64_t next_jobid (flux_t h)
{
    int64_t ret = (int64_t) -1;
    const char *json_str;
    json_object *req, *resp;
    flux_rpc_t *rpc;

    req = Jnew ();
    Jadd_str (req, "name", "lwj");
    Jadd_int64 (req, "preincrement", 1);
    Jadd_int64 (req, "postincrement", 0);
    Jadd_bool (req, "create", true);
    rpc = flux_rpc (h, "cmb.seq.fetch",
                    json_object_to_json_string (req), 0, 0);
    json_object_put (req);

    if ((flux_rpc_get (rpc, NULL, &json_str) < 0)
        || !(resp = json_tokener_parse (json_str))) {
        flux_log_error (h, "rpc_get");
        goto out;
    }

    Jget_int64 (resp, "value", &ret);
    json_object_put (resp);
out:
    flux_rpc_destroy (rpc);
    return ret;
}
Пример #2
0
/*
 * Free parsed JSON object and RPC for hwloc toplogy
 */
static void hwloc_topo_destroy (struct hwloc_topo *t)
{
    json_object_put (t->o);
    flux_rpc_destroy (t->rpc);
    flux_close (t->h);
    free (t);
}
Пример #3
0
static int internal_content_store (optparse_t *p, int ac, char *av[])
{
    const uint32_t blob_size_limit = 1048576; /* RFC 10 */
    uint8_t *data;
    int size;
    flux_t *h;
    flux_rpc_t *rpc;
    const char *topic;

    if (optparse_optind (p)  != ac) {
        optparse_print_usage (p);
        exit (1);
    }
    if ((size = read_all (STDIN_FILENO, &data)) < 0)
        log_err_exit ("read");
    if (!(h = builtin_get_flux_handle (p)))
        log_err_exit ("flux_open");
    if (optparse_hasopt (p, "dry-run")) {
        int flags;
        const char *hashfun;

        if (size > blob_size_limit)
            log_errn_exit (EFBIG, "content-store");
        if (!(hashfun = flux_attr_get (h, "content-hash", &flags)))
            log_err_exit ("flux_attr_get content-hash");
        if (!strcmp (hashfun, "sha1")) {
            uint8_t hash[SHA1_DIGEST_SIZE];
            char hashstr[SHA1_STRING_SIZE];
            SHA1_CTX sha1_ctx;

            SHA1_Init (&sha1_ctx);
            SHA1_Update (&sha1_ctx, (uint8_t *)data, size);
            SHA1_Final (&sha1_ctx, hash);
            sha1_hashtostr (hash, hashstr);
            printf ("%s\n", hashstr);
        } else
            log_msg_exit ("content-store: unsupported hash function: %s", hashfun);
    } else {
        const char *blobref;
        int blobref_size;
        if (optparse_hasopt (p, "bypass-cache"))
            topic = "content-backing.store";
        else
            topic = "content.store";
        if (!(rpc = flux_rpc_raw (h, topic, data, size, 0, 0)))
            log_err_exit ("%s", topic);
        if (flux_rpc_get_raw (rpc, &blobref, &blobref_size) < 0)
            log_err_exit ("%s", topic);
        if (!blobref || blobref[blobref_size - 1] != '\0')
            log_msg_exit ("%s: protocol error", topic);
        printf ("%s\n", blobref);
        flux_rpc_destroy (rpc);
    }
    flux_close (h);
    free (data);
    return (0);
}
Пример #4
0
/* Handle responses
 */
void ping_continuation (flux_rpc_t *rpc, void *arg)
{
    struct ping_ctx *ctx = arg;
    const char *json_str, *route, *pad;
    int64_t sec, nsec;
    struct timespec t0;
    int seq;
    json_object *out = NULL;
    struct ping_data *pdata = flux_rpc_aux_get (rpc);
    tstat_t *tstat = pdata->tstat;

    if (flux_rpc_get (rpc, &json_str) < 0) {
        log_err ("flux_rpc_get");
        goto done;
    }
    if (!(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq)
            || !Jget_int64 (out, "time.tv_sec", &sec)
            || !Jget_int64 (out, "time.tv_nsec", &nsec)
            || !Jget_str (out, "pad", &pad)
            || !Jget_str (out, "route", &route)
            || strcmp (ctx->pad, pad) != 0) {
        log_err ("error decoding ping response");
        goto done;
    }
    t0.tv_sec = sec;
    t0.tv_nsec = nsec;
    tstat_push (tstat, monotime_since (t0));

    pdata->seq = seq;
    if (pdata->route)
        free (pdata->route);
    pdata->route = xstrdup (route);
    pdata->rpc_count++;

done:
    if (flux_rpc_next (rpc) < 0 && pdata->rpc_count) {
        if (ctx->rank != NULL) {
            printf ("%s!%s pad=%lu seq=%d time=(%0.3f:%0.3f:%0.3f) ms stddev %0.3f\n",
                    ctx->rank,
                    ctx->topic, strlen (ctx->pad), pdata->seq,
                    tstat_min (tstat), tstat_mean (tstat), tstat_max (tstat),
                    tstat_stddev (tstat));
        } else {
            char s[16];
            snprintf (s, sizeof (s), "%u", ctx->nodeid);
            printf ("%s%s%s pad=%lu seq=%d time=%0.3f ms (%s)\n",
                    ctx->nodeid == FLUX_NODEID_ANY ? "" : s,
                    ctx->nodeid == FLUX_NODEID_ANY ? "" : "!",
                    ctx->topic, strlen (ctx->pad), pdata->seq,
                    tstat_mean (tstat),
                    pdata->route);
        }
        flux_rpc_destroy (rpc);
    }
    Jput (out);
}
Пример #5
0
/* Proxy ping.
 */
void xping_request_cb (flux_t h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    const char *json_str;
    int saved_errno;
    int rank, seq = ctx->ping_seq++;
    const char *service;
    char *hashkey = NULL;
    JSON in = Jnew ();
    JSON o = NULL;
    flux_msg_t *cpy;

    if (flux_request_decode (msg, NULL, &json_str) < 0) {
        saved_errno = errno;
        goto error;
    }
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "rank", &rank)
                                   || !Jget_str (o, "service", &service)) {
        saved_errno = errno = EPROTO;
        goto error;
    }
    flux_log (h, LOG_DEBUG, "Rxping rank=%d service=%s", rank, service);

    Jadd_int (in, "seq", seq);
    flux_log (h, LOG_DEBUG, "Tping seq=%d %d!%s", seq, rank, service);

    flux_rpc_t *rpc;
    if (!(rpc = flux_rpc (h, service, Jtostr (in), rank,
                                            FLUX_RPC_NORESPONSE))) {
        saved_errno = errno;
        goto error;
    }
    flux_rpc_destroy (rpc);
    if (!(cpy = flux_msg_copy (msg, true))) {
        saved_errno = errno;
        goto error;
    }
    hashkey = xasprintf ("%d", seq);
    zhash_update (ctx->ping_requests, hashkey, cpy);
    zhash_freefn (ctx->ping_requests, hashkey, (zhash_free_fn *)flux_msg_destroy);
    Jput (o);
    Jput (in);
    if (hashkey)
        free (hashkey);
    return;
error:
    if (flux_respond (h, msg, saved_errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    Jput (o);
    Jput (in);
}
Пример #6
0
int main (int argc, char **argv)
{
    flux_t h;
    flux_rpc_t *rpc;

    if (!(h = flux_open (NULL, 0)))
        err_exit ("flux_open");
    if (!(rpc = flux_rpc (h, "cmb.info", NULL, FLUX_NODEID_ANY, 0)))
        err_exit ("flux_rpc");
    get_rank (rpc);
    flux_rpc_destroy (rpc);
    flux_close (h);
    return (0);
}
Пример #7
0
flux_rpc_t *flux_rpc (flux_t h, const char *topic, const char *json_str,
                      uint32_t nodeid, int flags)
{
    flux_rpc_t *rpc = rpc_create (h, flags, 1);

    if (rpc_request_send (rpc, 0, topic, json_str, nodeid) < 0)
        goto error;
    if (!rpc->oneway)
        rpc->nodemap[0] = nodeid;
    return rpc;
error:
    flux_rpc_destroy (rpc);
    return NULL;
}
Пример #8
0
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);
}
Пример #9
0
void mod_insmod (flux_t h, opt_t opt)
{
    char *modpath = NULL;
    char *modname = NULL;

    if (opt.argc < 1)
        usage ();
    if (strchr (opt.argv[0], '/')) {
        if (!(modpath = realpath (opt.argv[0], NULL)))
            oom ();
        if (!(modname = flux_modname (modpath)))
            msg_exit ("%s", dlerror ());
    } else {
        char *searchpath = getenv ("FLUX_MODULE_PATH");
        if (!searchpath)
            searchpath = MODULE_PATH;
        modname = xstrdup (opt.argv[0]);
        if (!(modpath = flux_modfind (searchpath, modname)))
            msg_exit ("%s: not found in module search path", modname);
    }
    opt.argv++;
    opt.argc--;
    if (opt.direct) {
        char *service = getservice (modname);
        char *topic = xasprintf ("%s.insmod", service);
        char *json_str = flux_insmod_json_encode (modpath, opt.argc, opt.argv);
        assert (json_str != NULL);
        flux_rpc_t *r = flux_rpc_multi (h, topic, json_str, opt.nodeset, 0);
        if (!r)
            err_exit ("%s", topic);
        while (!flux_rpc_completed (r)) {
            uint32_t nodeid = FLUX_NODEID_ANY;
            if (flux_rpc_get (r, NULL, NULL) < 0)
                err_exit ("%s[%d]", topic,
                          nodeid == FLUX_NODEID_ANY ? -1 : nodeid);
        }
        flux_rpc_destroy (r);
        free (topic);
        free (service);
        free (json_str);
    } else {
        if (flux_modctl_load (h, opt.nodeset, modpath, opt.argc, opt.argv) < 0)
            err_exit ("%s", modname);
    }
    if (modpath)
        free (modpath);
    if (modname)
        free (modname);
}
Пример #10
0
static void store_completion (flux_rpc_t *rpc, void *arg)
{
    flux_reactor_t *r = arg;
    const char *blobref;
    int blobref_size;

    if (flux_rpc_get_raw (rpc, &blobref, &blobref_size) < 0)
        log_err_exit ("store");
    if (!blobref || blobref[blobref_size - 1] != '\0')
        log_msg_exit ("store: protocol error");
    //printf ("%s\n", blobref);
    flux_rpc_destroy (rpc);
    if (--spam_cur_inflight < spam_max_inflight/2)
        flux_reactor_stop (r);
}
Пример #11
0
static int dmesg_clear (flux_t *h, int seq)
{
    flux_rpc_t *rpc;
    int rc = -1;

    if (!(rpc = flux_rpcf (h, "cmb.dmesg.clear", FLUX_NODEID_ANY, 0,
                           "{s:i}", "seq", seq)))
        goto done;
    if (flux_rpc_get (rpc, NULL) < 0)
        goto done;
    rc = 0;
done:
    flux_rpc_destroy (rpc);
    return rc;
}
Пример #12
0
flux_rpc_t *flux_rpc_multi (flux_t h, const char *topic, const char *json_str,
                            const char *nodeset, int flags)
{
    nodeset_t *ns = NULL;
    nodeset_iterator_t *itr = NULL;
    flux_rpc_t *rpc = NULL;
    int i;
    uint32_t count;

    if (!topic || !nodeset) {
        errno = EINVAL;
        goto error;
    }
    if (!strcmp (nodeset, "all")) {
        if (flux_get_size (h, &count) < 0)
            goto error;
        ns = nodeset_create_range (0, count - 1);
    } else {
        if ((ns = nodeset_create_string (nodeset)))
            count = nodeset_count (ns);
    }
    if (!ns) {
        errno = EINVAL;
        goto error;
    }
    if (!(rpc = rpc_create (h, flags, count)))
        goto error;
    if (!(itr = nodeset_iterator_create (ns)))
        goto error;
    for (i = 0; i < count; i++) {
        uint32_t nodeid = nodeset_next (itr);
        assert (nodeid != NODESET_EOF);
        if (rpc_request_send (rpc, i, topic, json_str, nodeid) < 0)
            goto error;
        if (!rpc->oneway)
            rpc->nodemap[i] = nodeid;
    }
    nodeset_iterator_destroy (itr);
    return rpc;
error:
    if (rpc)
        flux_rpc_destroy (rpc);
    if (itr)
        nodeset_iterator_destroy (itr);
    if (ns)
        nodeset_destroy (ns);
    return NULL;
}
Пример #13
0
static int internal_heaptrace_stop (optparse_t *p, int ac, char *av[])
{
    flux_t *h;
    flux_rpc_t *rpc;

    if (optparse_optind (p) != ac) {
        optparse_print_usage (p);
        exit (1);
    }
    if (!(h = builtin_get_flux_handle (p)))
        log_err_exit ("flux_open");
    if (!(rpc = flux_rpc (h, "cmb.heaptrace.stop", NULL, FLUX_NODEID_ANY, 0))
            || flux_rpc_get (rpc, NULL) < 0)
        log_err_exit ("cmb.heaptrace.stop");
    flux_rpc_destroy (rpc);
    flux_close (h);
    return (0);
}
Пример #14
0
static int op_event_unsubscribe (void *impl, const char *topic)
{
    ctx_t *c = impl;
    assert (c->magic == CTX_MAGIC);
    flux_rpc_t *rpc = NULL;
    JSON in = Jnew ();
    int rc = 0;

    Jadd_str (in, "topic", topic);
    if (!(rpc = flux_rpc (c->h, "local.unsub", Jtostr (in), FLUX_NODEID_ANY, 0))
                || flux_rpc_get (rpc, NULL, NULL) < 0)
        goto done;
    rc = 0;
done:
    flux_rpc_destroy (rpc);
    Jput (in);
    return rc;
}
Пример #15
0
static int dmesg_clear (flux_t h, int seq)
{
    flux_rpc_t *rpc;
    JSON o = Jnew ();
    int rc = -1;

    Jadd_int (o, "seq", seq);
    if (!(rpc = flux_rpc (h, "cmb.dmesg.clear", Jtostr (o),
                          FLUX_NODEID_ANY, 0)))
        goto done;
    if (flux_rpc_get (rpc, NULL, NULL) < 0)
        goto done;
    rc = 0;
done:
    flux_rpc_destroy (rpc);
    Jput (o);
    return rc;
}
Пример #16
0
static void request_hwloc_reload (flux_t h, const char *nodeset)
{
    flux_rpc_t *rpc;

    if (!(rpc = flux_rpc_multi (h, "resource-hwloc.reload", NULL,
                                                        nodeset, 0)))
        err_exit ("flux_rpc_multi");
    while (!flux_rpc_completed (rpc)) {
        const char *json_str;
        uint32_t nodeid = FLUX_NODEID_ANY;
        if (flux_rpc_get (rpc, &nodeid, &json_str) < 0) {
            if (nodeid == FLUX_NODEID_ANY)
                err ("flux_rpc_get");
            else
                err ("rpc(%"PRIu32")", nodeid);
        }
    }
    flux_rpc_destroy (rpc);
}
Пример #17
0
void flux_vlog (flux_t *h, int level, const char *fmt, va_list ap)
{
    logctx_t *ctx = getctx (h);
    int saved_errno = errno;
    uint32_t rank;
    flux_rpc_t *rpc = NULL;
    int n, len;
    char timestamp[WALLCLOCK_MAXLEN];
    char hostname[STDLOG_MAX_HOSTNAME + 1];
    struct stdlog_header hdr;

    stdlog_init (&hdr);
    hdr.pri = STDLOG_PRI (level, LOG_USER);
    if (wallclock_get_zulu (timestamp, sizeof (timestamp)) >= 0)
        hdr.timestamp = timestamp;
    if (flux_get_rank (h, &rank) == 0) {
        snprintf (hostname, sizeof (hostname), "%" PRIu32, rank);
        hdr.hostname = hostname;
    }
    hdr.appname = ctx->appname;
    hdr.procid = ctx->procid;

    len = stdlog_encode (ctx->buf, sizeof (ctx->buf), &hdr,
                         STDLOG_NILVALUE, "");
    assert (len < sizeof (ctx->buf));

    n = vsnprintf (ctx->buf + len, sizeof (ctx->buf) - len, fmt, ap);
    if (n > sizeof (ctx->buf) - len) /* ignore truncation of message */
        n = sizeof (ctx->buf) - len;
    len += n;

    if (ctx->cb) {
        ctx->cb (ctx->buf, len, ctx->cb_arg);
    } else {
        if (!(rpc = flux_rpc_raw (h, "cmb.log", ctx->buf, len,
                                  FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE)))
            goto done;
    }
done:
    flux_rpc_destroy (rpc);
    errno = saved_errno;
}
Пример #18
0
static int internal_content_dropcache (optparse_t *p, int ac, char *av[])
{
    flux_t *h;
    flux_rpc_t *rpc = NULL;
    const char *topic = "content.dropcache";

    if (optparse_optind (p) != ac) {
        optparse_print_usage (p);
        exit (1);
    }
    if (!(h = builtin_get_flux_handle (p)))
        log_err_exit ("flux_open");
    if (!(rpc = flux_rpc (h, topic, NULL, FLUX_NODEID_ANY, 0)))
        log_err_exit ("%s", topic);
    if (flux_rpc_get (rpc, NULL) < 0)
        log_err_exit ("%s", topic);
    flux_rpc_destroy (rpc);
    flux_close (h);
    return (0);
}
Пример #19
0
static void send_enter_request (ctx_t *ctx, barrier_t *b)
{
    json_object *o = Jnew ();
    flux_rpc_t *rpc;

    Jadd_str (o, "name", b->name);
    Jadd_int (o, "count", b->count);
    Jadd_int (o, "nprocs", b->nprocs);
    Jadd_int (o, "hopcount", 1);

    if (!(rpc = flux_rpc (ctx->h, "barrier.enter", Jtostr (o),
                          FLUX_NODEID_UPSTREAM, FLUX_RPC_NORESPONSE))) {
        flux_log_error (ctx->h, "sending barrier.enter request");
        goto done;
    }
done:
    if (rpc)
        flux_rpc_destroy (rpc);
    json_object_put (o);
}
Пример #20
0
static int op_event_unsubscribe (void *impl, const char *topic)
{
    ctx_t *ctx = impl;
    assert (ctx->magic == MODHANDLE_MAGIC);
    JSON in = Jnew ();
    flux_rpc_t *rpc = NULL;
    int rc = -1;

    if (connect_socket (ctx) < 0)
        goto done;
    Jadd_str (in, "topic", topic);
    if (!(rpc = flux_rpc (ctx->h, "cmb.unsub", Jtostr (in), FLUX_NODEID_ANY, 0))
                || flux_rpc_get (rpc, NULL, NULL) < 0)
        goto done;
    rc = 0;
done:
    Jput (in);
    flux_rpc_destroy (rpc);
    return rc;
}
Пример #21
0
static flux_rpc_t *rpc_create (flux_t h, int flags, int count)
{
    flux_rpc_t *rpc = xzmalloc (sizeof (*rpc));
    if ((flags & FLUX_RPC_NORESPONSE)) {
        rpc->oneway = true;
        rpc->m.matchtag = FLUX_MATCHTAG_NONE;
    } else {
        rpc->nodemap = xzmalloc (sizeof (rpc->nodemap[0]) * count);
        rpc->m.matchtag = flux_matchtag_alloc (h, count);
        if (rpc->m.matchtag == FLUX_MATCHTAG_NONE) {
            flux_rpc_destroy (rpc);
            return NULL;
        }
    }
    rpc->m.bsize = count;
    rpc->m.typemask = FLUX_MSGTYPE_RESPONSE;
    rpc->h = h;
    rpc->usecount = 1;
    return rpc;
}
Пример #22
0
static int internal_heaptrace_dump (optparse_t *p, int ac, char *av[])
{
    flux_t *h;
    flux_rpc_t *rpc;
    json_object *in = Jnew ();

    if (optparse_optind (p) != ac - 1) {
        optparse_print_usage (p);
        exit (1);
    }
    Jadd_str (in, "reason", av[ac - 1]);
    if (!(h = builtin_get_flux_handle (p)))
        log_err_exit ("flux_open");
    if (!(rpc = flux_rpc (h, "cmb.heaptrace.dump", Jtostr (in),
                          FLUX_NODEID_ANY, 0))
            || flux_rpc_get (rpc, NULL) < 0)
        log_err_exit ("cmb.heaptrace.dump");
    flux_rpc_destroy (rpc);
    flux_close (h);
    return (0);
}
Пример #23
0
int get_watch_stats (flux_t *h, int *count)
{
    flux_rpc_t *rpc;
    const char *json_str;
    json_object *o = NULL;
    int rc = -1;

    if (!(rpc = flux_rpc (h, "kvs.stats.get", NULL, FLUX_NODEID_ANY, 0)))
        goto done;
    if (flux_rpc_get (rpc, &json_str) < 0)
        goto done;
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "#watchers", count)) {
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    flux_rpc_destroy (rpc);
    Jput (o);
    return rc;
}
Пример #24
0
int rpctest_begin_cb (flux_t h, int type, zmsg_t **zmsg, void *arg)
{
    uint32_t nodeid;
    int i, errors;
    int old_count;
    flux_rpc_t *r;
    const char *json_str;

    errno = 0;
    ok (!(r = flux_rpc_multi (h, NULL, "foo", "all", 0)) && errno == EINVAL,
        "flux_rpc_multi [0] with NULL topic fails with EINVAL");
    errno = 0;
    ok (!(r = flux_rpc_multi (h, "bar", "foo", NULL, 0)) && errno == EINVAL,
        "flux_rpc_multi [0] with NULL nodeset fails with EINVAL");
    errno = 0;
    ok (!(r = flux_rpc_multi (h, "bar", "foo", "xyz", 0)) && errno == EINVAL,
        "flux_rpc_multi [0] with bad nodeset fails with EINVAL");

    /* working no-payload RPC */
    old_count = hello_count;
    ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "all", 0)) != NULL,
        "flux_rpc_multi [0] with no payload when none is expected works");
    if (!r)
        BAIL_OUT ("can't continue without successful rpc call");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    ok (flux_rpc_get (r, NULL, NULL) == 0,
        "flux_rpc_get works");
    ok (hello_count == old_count + 1,
        "rpc was called once");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (unexpected payload) - picked up in _get() */
    ok ((r = flux_rpc_multi (h, "rpctest.hello", "foo", "all", 0)) != NULL,
        "flux_rpc_multi [0] with unexpected payload works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* fake that we have a larger session */
    fake_size = 128;
    char s[16];
    uint32_t size = 0;
    snprintf (s, sizeof (s), "%u", fake_size);
    flux_attr_fake (h, "size", s, FLUX_ATTRFLAG_IMMUTABLE);
    flux_get_size (h, &size);
    cmp_ok (size, "==", fake_size,
        "successfully faked flux_get_size() of %d", fake_size);

    /* repeat working no-payload RPC test (now with 128 nodes) */
    old_count = hello_count;
    ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "all", 0)) != NULL,
        "flux_rpc_multi [0-%d] with no payload when none is expected works",
        fake_size - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errors = 0;
    for (i = 0; i < fake_size; i++)
        if (flux_rpc_get (r, NULL, NULL) < 0)
            errors++;
    ok (errors == 0,
        "flux_rpc_get succeded %d times", fake_size);

    cmp_ok (hello_count - old_count, "==", fake_size,
        "rpc was called %d times", fake_size);
    flux_rpc_destroy (r);

    /* same with a subset */
    old_count = hello_count;
    ok ((r = flux_rpc_multi (h, "rpctest.hello", NULL, "[0-63]", 0)) != NULL,
        "flux_rpc_multi [0-%d] with no payload when none is expected works",
        64 - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errors = 0;
    for (i = 0; i < 64; i++)
        if (flux_rpc_get (r, &nodeid, NULL) < 0 || nodeid != i)
            errors++;
    ok (errors == 0,
        "flux_rpc_get succeded %d times, with correct nodeid map", 64);

    cmp_ok (hello_count - old_count, "==", 64,
        "rpc was called %d times", 64);
    flux_rpc_destroy (r);

    /* same with echo payload */
    ok ((r = flux_rpc_multi (h, "rpctest.echo", "foo", "[0-63]", 0)) != NULL,
        "flux_rpc_multi [0-%d] ok",
        64 - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errors = 0;
    for (i = 0; i < 64; i++) {
        if (flux_rpc_get (r, NULL, &json_str) < 0
                || !json_str || strcmp (json_str, "foo") != 0)
            errors++;
    }
    ok (errors == 0,
        "flux_rpc_get succeded %d times, with correct return payload", 64);
    flux_rpc_destroy (r);

    /* detect partial failure without mresponse */
    nodeid_fake_error = 20;
    ok ((r = flux_rpc_multi (h, "rpctest.nodeid", NULL, "[0-63]", 0)) != NULL,
        "flux_rpc_multi [0-%d] ok",
        64 - 1);
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    for (i = 0; i < 64; i++) {
        if (flux_rpc_get (r, &nodeid, &json_str) < 0)
            break;
    }
    ok (i == 20 && errno == EPERM,
        "flux_rpc_get correctly reports single error");
    flux_rpc_destroy (r);

    /* test _then (still at fake session size of 128) */
    ok ((then_r = flux_rpc_multi (h, "rpctest.hello", NULL, "[0-127]", 0)) != NULL,
        "flux_rpc_multi [0-127] ok");
    ok (flux_rpc_then (then_r, then_cb, h) == 0,
        "flux_rpc_then works");
    /* then_cb stops reactor; results reported, then_r destroyed in main() */

    return 0;
}
Пример #25
0
flux_rpc_t *flux_rpc_multi (flux_t *h,
                            const char *topic,
                            const char *json_str,
                            const char *nodeset,
                            int flags)
{
    nodeset_t *ns = NULL;
    nodeset_iterator_t *itr = NULL;
    flux_rpc_t *rpc = NULL;
    int i;
    uint32_t count;
    int rx_expected;

    if (!topic || !nodeset) {
        errno = EINVAL;
        goto error;
    }
    if (!strcmp (nodeset, "all")) {
        if (flux_get_size (h, &count) < 0)
            goto error;
        ns = nodeset_create_range (0, count - 1);
    } else {
        if ((ns = nodeset_create_string (nodeset)))
            count = nodeset_count (ns);
    }
    if (!ns) {
        errno = EINVAL;
        goto error;
    }
    rx_expected = count;
    if ((flags & FLUX_RPC_NORESPONSE))
        rx_expected = 0;
    if (!(rpc = rpc_create (h, rx_expected)))
        goto error;
    if (!(itr = nodeset_iterator_create (ns)))
        goto error;
#if HAVE_CALIPER
    cali_begin_string_byname ("flux.message.rpc", "multi");
    cali_begin_int_byname ("flux.message.response_expected",
                           !(flags & FLUX_RPC_NORESPONSE));
#endif
    for (i = 0; i < count; i++) {
        uint32_t nodeid = nodeset_next (itr);
        assert (nodeid != NODESET_EOF);
#if HAVE_CALIPER
        cali_begin_int_byname ("flux.message.rpc.nodeid", nodeid);
#endif
        if (rpc_request_send (rpc, topic, nodeid, json_str) < 0)
            goto error;
#if HAVE_CALIPER
        cali_end_byname ("flux.message.rpc.nodeid");
#endif
    }
#if HAVE_CALIPER
    cali_end_byname ("flux.message.response_expected");
    cali_end_byname ("flux.message.rpc");
#endif
    nodeset_iterator_destroy (itr);
    return rpc;
error:
    if (rpc)
        flux_rpc_destroy (rpc);
    if (itr)
        nodeset_iterator_destroy (itr);
    if (ns)
        nodeset_destroy (ns);
    return NULL;
}
Пример #26
0
int main (int argc, char *argv[])
{
    flux_msg_t *msg;
    flux_t h;

    plan (33);

    (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");
    flux_fatal_set (h, fatal_err, NULL);

    ok (flux_msg_watcher_addvec (h, htab, 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,
        "encoded rpctest.begin request OK");
    ok (flux_send (h, msg, 0) == 0,
        "sent rpctest.begin request");
    ok (flux_reactor_start (h) == 0,
        "reactor completed normally");
    flux_msg_destroy (msg);

    /* test _then:  Slightly tricky.
     * Send request.  We're not in a coproc ctx here in main(), so there
     * will be no response, therefore, check will be false.  Register
     * continuation, start reactor.  Response will be received, continuation
     * will be invoked. Continuation stops the reactor.
    */
    flux_rpc_t *r;
    ok ((r = flux_rpc (h, "rpctest.echo", "xxx", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    /* reg/unreg _then a couple times for fun */
    ok (flux_rpc_then (r, NULL, 0) == 0,
        "flux_rpc_then with NULL cb works");
    ok (flux_rpc_then (r, then_cb, h) == 0,
        "flux_rpc_then works after NULL");
    ok (flux_rpc_then (r, NULL, 0) == 0,
        "flux_rpc_then with NULL cb after non-NULL works");
    ok (flux_rpc_then (r, then_cb, h) == 0,
        "flux_rpc_then works");
    /* enough of that */
    ok (flux_reactor_start (h) == 0,
        "reactor completed normally");
    flux_rpc_destroy (r);

    /* Test a _then corner case:
     * If _check() is called before _then(), a message may have been cached
     * in the flux_rpc_t.  rpctest_thenbug_cb creates this condition.
     * Next, _then continuation is installed, but will reactor call it?
     * This will hang if rpc implementation doesn't return a cached message
     * back to the handle in _then().  Else, continuation will stop reactor.
     */
    ok ((thenbug_r = flux_rpc (h, "rpctest.echo", "xxx",
        FLUX_NODEID_ANY, 0)) != NULL,
        "thenbug: sent echo request");
    do {
        if (!(msg = flux_request_encode ("rpctest.thenbug", NULL))
                  || flux_send (h, msg, 0) < 0
                  || flux_reactor_start (h) < 0) {
            flux_msg_destroy (msg);
            break;
        }
        flux_msg_destroy (msg);
    } while (!flux_rpc_check (thenbug_r));
    ok (true,
        "thenbug: check says message ready");
    ok (flux_rpc_then (thenbug_r, then_cb, h) == 0,
        "thenbug: registered then - hangs on failure");
    ok (flux_reactor_start (h) == 0,
        "reactor completed normally");
    flux_rpc_destroy (thenbug_r);

    flux_msg_watcher_delvec (h, htab);
    flux_close (h);
    done_testing();
    return (0);
}
Пример #27
0
void rpctest_begin_cb (flux_t *h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    const char *json_str;
    flux_rpc_t *r;

    errno = 0;
    ok (!(r = flux_rpc (h, NULL, NULL, FLUX_NODEID_ANY, 0))
        && errno == EINVAL,
        "flux_rpc with NULL topic fails with EINVAL");

    /* working no-payload RPC */
    ok ((r = flux_rpc (h, "rpctest.hello", NULL, FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with no payload when none is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    ok (flux_rpc_get (r, NULL) == 0,
        "flux_rpc_get works");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (unexpected payload) - will be picked up in _get() */
    ok ((r = flux_rpc (h, "rpctest.hello", "{}", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when none is expected works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* cause remote EPROTO (missing payload) - will be picked up in _get() */
    errno = 0;
    ok ((r = flux_rpc (h, "rpctest.echo", NULL, FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with no payload when payload is expected works, at first");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    errno = 0;
    ok (flux_rpc_get (r, NULL) < 0
        && errno == EPROTO,
        "flux_rpc_get fails with EPROTO");
    flux_rpc_destroy (r);

    /* working with-payload RPC */
    ok ((r = flux_rpc (h, "rpctest.echo", "{}", FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    json_str = NULL;
    ok (flux_rpc_get (r, &json_str) == 0
        && json_str && !strcmp (json_str, "{}"),
        "flux_rpc_get works and returned expected payload");
    flux_rpc_destroy (r);

    /* working with-payload RPC (raw) */
    char *d, data[] = "aaaaaaaaaaaaaaaaaaaa";
    int l, len = strlen (data);
    ok ((r = flux_rpc_raw (h, "rpctest.rawecho", data, len,
                          FLUX_NODEID_ANY, 0)) != NULL,
        "flux_rpc_raw with payload when payload is expected works");
    ok (flux_rpc_check (r) == false,
        "flux_rpc_check says get would block");
    json_str = NULL;
    ok (flux_rpc_get_raw (r, &d, &l) == 0
        && d != NULL && l == len && memcmp (data, d, len) == 0,
        "flux_rpc_get_raw works and returned expected payload");
    flux_rpc_destroy (r);

    /* use newish pack/unpack payload interfaces */
    int i = 0;
    ok ((r = flux_rpcf (h, "rpctest.incr", FLUX_NODEID_ANY, 0,
                        "{s:i}", "n", 107)) != NULL,
        "flux_rpcf works");
    ok (flux_rpc_getf (r, "{s:i}", "n", &i) == 0,
        "flux_rpc_getf works");
    ok (i == 108,
        "and service returned incremented value");
    flux_rpc_destroy (r);

    flux_reactor_stop (flux_get_reactor (h));
}
Пример #28
-1
static flux_msg_t *op_recv (void *impl, int flags)
{
    ctx_t *ctx = impl;
    assert (ctx->magic == MODHANDLE_MAGIC);
    zmq_pollitem_t zp = {
        .events = ZMQ_POLLIN, .socket = ctx->sock, .revents = 0, .fd = -1,
    };
    flux_msg_t *msg = NULL;

    if (connect_socket (ctx) < 0)
        goto done;
    if ((flags & FLUX_O_NONBLOCK)) {
        int n;
        if ((n = zmq_poll (&zp, 1, 0L)) <= 0) {
            if (n == 0)
                errno = EWOULDBLOCK;
            goto done;
        }
    }
    msg = flux_msg_recvzsock (ctx->sock);
done:
    return msg;
}

static int op_event_subscribe (void *impl, const char *topic)
{
    ctx_t *ctx = impl;
    assert (ctx->magic == MODHANDLE_MAGIC);
    json_object *in = Jnew ();
    flux_rpc_t *rpc = NULL;
    int rc = -1;

    if (connect_socket (ctx) < 0)
        goto done;
    Jadd_str (in, "topic", topic);
    if (!(rpc = flux_rpc (ctx->h, "cmb.sub", Jtostr (in), FLUX_NODEID_ANY, 0))
            || flux_rpc_get (rpc, NULL) < 0)
        goto done;
    rc = 0;
done:
    Jput (in);
    flux_rpc_destroy (rpc);
    return rc;
}