Beispiel #1
0
void *thread (void *arg)
{
    thd_t *t = arg;
    char *key, *fence_name = NULL;
    int i, flags = 0;
    struct timespec t0;
    uint32_t rank;
    flux_future_t *f;
    flux_kvs_txn_t *txn;

    if (!(t->h = flux_open (NULL, 0))) {
        log_err ("%d: flux_open", t->n);
        goto done;
    }
    if (flux_get_rank (t->h, &rank) < 0) {
        log_err ("%d: flux_get_rank", t->n);
        goto done;
    }
    for (i = 0; i < count; i++) {
        if (!(txn = flux_kvs_txn_create ()))
            log_err_exit ("flux_kvs_txn_create");
        key = xasprintf ("%s.%"PRIu32".%d.%d", prefix, rank, t->n, i);
        if (fopt)
            fence_name = xasprintf ("%s-%d", prefix, i);
        if (sopt)
            monotime (&t0);
        if (flux_kvs_txn_pack (txn, 0, key, "i", 42) < 0)
            log_err_exit ("%s", key);
        if (nopt && (i % nopt_divisor) == 0)
            flags |= FLUX_KVS_NO_MERGE;
        else
            flags = 0;
        if (fopt) {
            if (!(f = flux_kvs_fence (t->h, flags, fence_name,
                                                   fence_nprocs, txn))
                    || flux_future_get (f, NULL) < 0)
                log_err_exit ("flux_kvs_fence");
            flux_future_destroy (f);
        } else {
            if (!(f = flux_kvs_commit (t->h, flags, txn))
                    || flux_future_get (f, NULL) < 0)
                log_err_exit ("flux_kvs_commit");
            flux_future_destroy (f);
        }
        if (sopt && zlist_append (t->perf, ddup (monotime_since (t0))) < 0)
            oom ();
        free (key);
        free (fence_name);
        flux_kvs_txn_destroy (txn);
    }
done:
    if (t->h)
        flux_close (t->h);
    return NULL;
}
Beispiel #2
0
static int attr_list_rpc (attr_ctx_t *ctx)
{
    flux_future_t *f;
    json_t *array, *value;
    size_t index;
    int rc = -1;

    if (!(f = flux_rpc (ctx->h, "attr.list", NULL, FLUX_NODEID_ANY, 0)))
        goto done;
    if (flux_rpc_get_unpack (f, "{s:o}", "names", &array) < 0)
        goto done;
    zlist_destroy (&ctx->names);
    if (!(ctx->names = zlist_new ()))
        goto done;
    json_array_foreach (array, index, value) {
        const char *name = json_string_value (value);
        if (!name) {
            errno = EPROTO;
            goto done;
        }
        if (zlist_append (ctx->names, strdup (name)) < 0) {
            errno = ENOMEM;
            goto done;
        }
    }
    zlist_sort (ctx->names, (zlist_compare_fn *)attr_strcmp);
    rc = 0;
done:
    flux_future_destroy (f);
    return rc;
}
Beispiel #3
0
static int depthfirst_map_one (flux_t *h, const char *key, int dirskip,
                               restart_map_f cb, void *arg)
{
    flux_jobid_t id;
    flux_future_t *f;
    const char *eventlog;
    struct job *job = NULL;
    char path[64];
    int rc = -1;

    if (strlen (key) <= dirskip) {
        errno = EINVAL;
        return -1;
    }
    if (fluid_decode (key + dirskip + 1, &id, FLUID_STRING_DOTHEX) < 0)
        return -1;
    if (flux_job_kvs_key (path, sizeof (path), id, "eventlog") < 0) {
        errno = EINVAL;
        return -1;
    }
    if (!(f = flux_kvs_lookup (h, NULL, 0, path)))
        goto done;
    if (flux_kvs_lookup_get (f, &eventlog) < 0)
        goto done;
    if (!(job = job_create_from_eventlog (id, eventlog)))
        goto done;
    if (cb (job, arg) < 0)
        goto done;
    rc = 1;
done:
    flux_future_destroy (f);
    job_decref (job);
    return rc;
}
Beispiel #4
0
// builds the trigger request and sends it to "mod_name"
// converts sim_state to JSON, formats request tag based on "mod_name"
static int send_trigger (flux_t *h, const char *mod_name, sim_state_t *sim_state)
{
    int rc = 0;
    flux_future_t *future = NULL;
    json_t *o = NULL;
    char *topic = NULL;

    // Reset the next timer for "mod_name" to -1 before we trigger
    double *next_time = zhash_lookup (sim_state->timers, mod_name);
    *next_time = -1;

    o = sim_state_to_json (sim_state);

    topic = xasprintf ("%s.trigger", mod_name);
    future = flux_rpc (h, topic, Jtostr (o), FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE);
    if (!future) {
        flux_log (h, LOG_ERR, "failed to send trigger to %s", mod_name);
        rc = -1;
    }

    Jput (o);
    free (topic);
    flux_future_destroy (future);
    return rc;
}
Beispiel #5
0
void test_nsrc (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const int count = 10000;
    json_object *in = Jnew ();
    const char *json_str;
    json_object *out = NULL;
    int i, seq;

    Jadd_int (in, "count", count);
    if (!(f = flux_rpc (h, "req.nsrc", Jtostr (in), FLUX_NODEID_ANY,
                                                      FLUX_RPC_NORESPONSE)))
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
    for (i = 0; i < count; i++) {
        flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0);
        if (!msg)
            log_err_exit ("%s", __FUNCTION__);
        if (flux_response_decode (msg, NULL, &json_str) < 0)
            log_msg_exit ("%s: decode %d", __FUNCTION__, i);
        if (!json_str
            || !(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq))
            log_msg_exit ("%s: decode %d payload", __FUNCTION__, i);
        if (seq != i)
            log_msg_exit ("%s: decode %d - seq mismatch %d", __FUNCTION__, i, seq);
        Jput (out);
        flux_msg_destroy (msg);
    }
    Jput (in);
}
int main (int argc, char *argv[])
{
    flux_t *h;
    const char *key;
    flux_future_t *f;

    if (argc != 2) {
        fprintf (stderr, "Usage: waitcreate_cancel key\n");
        return (1);
    }
    key = argv[1];
    if (!(h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");

    if (!(f = flux_kvs_lookup (h, NULL, FLUX_KVS_WAITCREATE, key)))
        log_err_exit ("flux_kvs_lookup");

    if (flux_kvs_lookup_cancel (f) < 0)
        log_err_exit ("flux_kvs_lookup_cancel");

    if (flux_kvs_lookup_get (f, NULL) < 0) {
        if (errno != ENODATA)
            log_err_exit ("flux_kvs_lookup_get");
        flux_future_destroy (f);
    }
    else
        log_msg_exit ("flux_kvs_lookup_get returned success");

    flux_close (h);
    return (0);
}
Beispiel #7
0
static int extract_raw_rdl_alloc (flux_t *h, int64_t j, json_object *jcb)
{
    int i;
    json_object *ra = Jnew_ar ();
    bool processing = true;

    for (i=0; processing; ++i) {
        char *key = lwj_key (h, j, ".rank.%d.cores", i);
        flux_future_t *f = NULL;
        int64_t cores = 0;
        if (!key || !(f = flux_kvs_lookup (h, 0, key))
                 || flux_kvs_lookup_get_unpack (f, "I", &cores) < 0) {
            if (errno != EINVAL)
                flux_log_error (h, "extract %s", key);
            processing = false;
        } else {
            json_object *elem = Jnew ();
            json_object *o = Jnew ();
            Jadd_int64 (o, JSC_RDL_ALLOC_CONTAINED_NCORES, cores);
            json_object_object_add (elem, JSC_RDL_ALLOC_CONTAINED, o);
            json_object_array_add (ra, elem);
        }
        free (key);
        flux_future_destroy (f);
    }
    json_object_object_add (jcb, JSC_RDL_ALLOC, ra);
    return 0;
}
Beispiel #8
0
void test_nsrc (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const char *json_str;
    const int count = 10000;
    int i, seq = -1;
    json_t *o;

    if (!(f = flux_rpc_pack (h, "req.nsrc",
                             FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE,
                             "{s:i}", "count", count)))
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
    for (i = 0; i < count; i++) {
        flux_msg_t *msg;
        if (!(msg = flux_recv (h, FLUX_MATCH_ANY, 0)))
            log_err_exit ("%s", __FUNCTION__);
        if (flux_response_decode (msg, NULL, &json_str) < 0)
            log_msg_exit ("%s: decode %d", __FUNCTION__, i);
        if (!json_str || !(o = json_loads (json_str, 0, NULL))
                      || json_unpack (o, "{s:i}", "seq", &seq) < 0)
            log_msg_exit ("%s: decode %d payload", __FUNCTION__, i);
        if (seq != i)
            log_msg_exit ("%s: decode %d - seq mismatch %d", __FUNCTION__, i, seq);
        json_decref (o);
        flux_msg_destroy (msg);
    }
}
Beispiel #9
0
static int update_rdl (flux_t *h, int64_t j, const char *rs)
{
    int rc = -1;
    char *key = lwj_key (h, j, ".rdl");
    flux_kvs_txn_t *txn = NULL;
    flux_future_t *f = NULL;

    if (!(txn = flux_kvs_txn_create ())) {
        flux_log_error (h, "txn_create");
        goto done;
    }
    if (flux_kvs_txn_pack (txn, 0, key, "s", rs) < 0) {
        flux_log_error (h, "update %s", key);
        goto done;
    }
    if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) {
        flux_log_error (h, "commit failed");
        goto done;
    }
    flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new rdl.", j);
    rc = 0;

done:
    flux_kvs_txn_destroy (txn);
    flux_future_destroy (f);
    free (key);

    return rc;
}
Beispiel #10
0
static int attr_set_rpc (attr_ctx_t *ctx, const char *name, const char *val)
{
    flux_future_t *f;
    attr_t *attr;
    int rc = -1;

#if JANSSON_VERSION_HEX >= 0x020800
    /* $? format specifier was introduced in jansson 2.8 */
    f = flux_rpc_pack (ctx->h, "attr.set", FLUX_NODEID_ANY, 0,
                       "{s:s, s:s?}", "name", name, "value", val);
#else
    f = flux_rpc_pack (ctx->h, "attr.set", FLUX_NODEID_ANY, 0,
                       val ? "{s:s, s:s}" : "{s:s, s:n}",
                       "name", name, "value", val);
#endif
    if (!f)
        goto done;
    if (flux_future_get (f, NULL) < 0)
        goto done;
    if (val) {
        if (!(attr = attr_create (val, 0)))
            goto done;
        zhash_update (ctx->hash, name, attr);
        zhash_freefn (ctx->hash, name, attr_destroy);
    } else
        zhash_delete (ctx->hash, name);
    rc = 0;
done:
    flux_future_destroy (f);
    return rc;
}
Beispiel #11
0
void watch_continuation (flux_future_t *f, void *arg)
{
    int *last = arg;
    int i;

    if (flux_kvs_lookup_get_unpack (f, "i", &i) < 0) {
        if (errno == ENODATA) {
            flux_future_destroy (f); // ENODATA (like EOF on response stream)
            if (verbose)
                printf ("< ENODATA\n");
        }
        else
            log_err_exit ("flux_lookup_get_unpack");
        return;
    }
    if (verbose)
        printf ("< %s=%d\n", key, i);
    if (i != *last + 1)
        log_msg_exit ("%s: got %d, expected %d", __FUNCTION__, i, *last + 1);
    if (++wrxcount == totcount)
        flux_kvs_lookup_cancel (f);
    *last = i;

    flux_future_reset (f);
}
Beispiel #12
0
void commit_continuation (flux_future_t *f, void *arg)
{
    if (flux_future_get (f, NULL) < 0)
        log_err_exit ("flux_kvs_commit");
    rxcount++;

    flux_future_destroy (f);
}
Beispiel #13
0
void test_clog (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    if (!(f = flux_rpc (h, "req.clog", NULL, nodeid, 0))
             || flux_rpc_get (f, NULL) < 0)
        log_err_exit ("req.clog");
    flux_future_destroy (f);
}
Beispiel #14
0
void test_sink (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;

    if (!(f = flux_rpc_pack (h, "req.sink", nodeid, 0, "{s:f}", "pi", 3.14))
             || flux_future_get (f, NULL) < 0)
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
}
Beispiel #15
0
static int update_rdesc (flux_t *h, int64_t j, json_object *o)
{
    int rc = -1;
    int64_t nnodes = 0;
    int64_t ntasks = 0;
    int64_t walltime = 0;
    char *key1 = NULL;
    char *key2 = NULL;
    char *key3 = NULL;
    flux_kvs_txn_t *txn = NULL;
    flux_future_t *f = NULL;

    if (!Jget_int64 (o, JSC_RDESC_NNODES, &nnodes))
        goto done;
    if (!Jget_int64 (o, JSC_RDESC_NTASKS, &ntasks))
        goto done;
    if (!Jget_int64 (o, JSC_RDESC_WALLTIME, &walltime))
        goto done;
    if ((nnodes < 0) || (ntasks < 0) || (walltime < 0))
        goto done;
    key1 = lwj_key (h, j, ".nnodes");
    key2 = lwj_key (h, j, ".ntasks");
    key3 = lwj_key (h, j, ".walltime");
    if (!key1 || !key2 || !key3)
        goto done;
    if (!(txn = flux_kvs_txn_create ())) {
        flux_log_error (h, "txn_create");
        goto done;
    }
    if (flux_kvs_txn_pack (txn, 0, key1, "I", nnodes) < 0) {
        flux_log_error (h, "update %s", key1);
        goto done;
    }
    if (flux_kvs_txn_pack (txn, 0, key2, "I", ntasks) < 0) {
        flux_log_error (h, "update %s", key2);
        goto done;
    }
    if (flux_kvs_txn_pack (txn, 0, key3, "I", walltime) < 0) {
        flux_log_error (h, "update %s", key3);
        goto done;
    }
    if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) {
        flux_log_error (h, "commit failed");
        goto done;
    }
    flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new resources.", j);
    rc = 0;
done:
    flux_future_destroy (f);
    flux_kvs_txn_destroy (txn);
    free (key1);
    free (key2);
    free (key3);

    return rc;
}
Beispiel #16
0
void *watchthread (void *arg)
{
    thd_t *t = arg;
    watch_count_t wc;
    flux_kvs_txn_t *txn;
    flux_future_t *f;
    flux_reactor_t *r;
    flux_watcher_t *pw = NULL;
    flux_watcher_t *tw = NULL;

    if (!(t->h = flux_open (NULL, 0)))
        log_err_exit ("flux_open");

    /* Make sure key doesn't already exist, initial value may affect
     * test by chance (i.e. initial value = 0, commit 0 and thus no
     * change)
     */
    if (!(txn = flux_kvs_txn_create ()))
        log_err_exit ("flux_kvs_txn_create");
    if (flux_kvs_txn_unlink (txn, 0, key) < 0)
        log_err_exit ("flux_kvs_txn_unlink");
    if (!(f = flux_kvs_commit (t->h, 0, txn)) || flux_future_get (f, NULL) < 0)
        log_err_exit ("flux_kvs_commit");
    flux_future_destroy (f);
    flux_kvs_txn_destroy (txn);

    r = flux_get_reactor (t->h);

    if (flux_kvs_watch (t->h, key, watch_count_cb, t) < 0)
        log_err_exit ("flux_kvs_watch %s", key);

    pw = flux_prepare_watcher_create (r, watch_prepare_cb, NULL);

    wc.t = t;
    wc.lastcount = -1;

    /* So test won't hang if there's a bug */
    tw = flux_timer_watcher_create (r,
                                    WATCH_TIMEOUT,
                                    WATCH_TIMEOUT,
                                    watch_timeout_cb,
                                    &wc);

    flux_watcher_start (pw);
    flux_watcher_start (tw);

    if (flux_reactor_run (r, 0) < 0)
        log_err_exit ("flux_reactor_run");

    flux_watcher_destroy (pw);
    flux_watcher_destroy (tw);
    flux_close (t->h);
    return NULL;
}
Beispiel #17
0
/* This test is to make sure that deferred responses are handled in order.
 * Arrange for module to source 10K sequenced responses.  Messages 5000-5499
 * are "put back" on the handle using flux_putmsg().  We ensure that
 * the 10K messages are nonetheless received in order.
 */
void test_putmsg (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const char *json_str;
    const int count = 10000;
    const int defer_start = 5000;
    const int defer_count = 500;
    json_object *in = Jnew ();
    json_object *out = NULL;
    int seq, myseq = 0;
    zlist_t *defer = zlist_new ();
    bool popped = false;
    flux_msg_t *z;

    if (!defer)
        oom ();

    Jadd_int (in, "count", count);
    if (!(f = flux_rpc (h, "req.nsrc", Jtostr (in), FLUX_NODEID_ANY,
                                                      FLUX_RPC_NORESPONSE)))
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
    do {
        flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0);
        if (!msg)
            log_err_exit ("%s", __FUNCTION__);
        if (flux_response_decode (msg, NULL, &json_str) < 0)
            log_msg_exit ("%s: decode", __FUNCTION__);
        if (!json_str
            || !(out = Jfromstr (json_str))
            || !Jget_int (out, "seq", &seq))
            log_msg_exit ("%s: decode - payload", __FUNCTION__);
        Jput (out);
        if (seq >= defer_start && seq < defer_start + defer_count && !popped) {
            if (zlist_append (defer, msg) < 0)
                oom ();
            if (seq == defer_start + defer_count - 1) {
                while ((z = zlist_pop (defer))) {
                    if (flux_requeue (h, z, FLUX_RQ_TAIL) < 0)
                        log_err_exit ("%s: flux_requeue", __FUNCTION__);
                    flux_msg_destroy (z);
                }
                popped = true;
            }
            continue;
        }
        if (seq != myseq)
            log_msg_exit ("%s: expected %d got %d", __FUNCTION__, myseq, seq);
        myseq++;
        flux_msg_destroy (msg);
    } while (myseq < count);
    zlist_destroy (&defer);
    Jput (in);
}
Beispiel #18
0
static void runlevel_timeout (flux_reactor_t *reactor, flux_watcher_t *w,
                              int revents, void *arg)
{
    runlevel_t *r = arg;
    flux_future_t *f;
    flux_log (r->h, LOG_ERR, "runlevel %d timeout, sending SIGTERM", r->level);
    if (!(f = flux_subprocess_kill (r->rc[r->level].p, SIGTERM)))
        flux_log_error (r->h, "flux_subprocess_kill");
    /* don't care about response */
    flux_future_destroy (f);
}
int register_content_backing_service (flux_t *h)
{
    int rc, saved_errno;
    flux_future_t *f;
    if (!(f = flux_service_register (h, "content-backing")))
        return -1;
    rc = flux_future_get (f, NULL);
    saved_errno = errno;
    flux_future_destroy (f);
    errno = saved_errno;
    return rc;
}
Beispiel #20
0
void test_err (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;

    if (!(f = flux_rpc (h, "req.err", NULL, nodeid, 0)))
        log_err_exit ("error sending request");
    if (flux_future_get (f, NULL) == 0)
        log_msg_exit ("%s: succeeded when should've failed", __FUNCTION__);
    if (errno != 42)
        log_msg_exit ("%s: got errno %d instead of 42", __FUNCTION__, errno);
    flux_future_destroy (f);
}
Beispiel #21
0
void test_sink (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    json_object *in = Jnew();

    Jadd_double (in, "pi", 3.14);
    if (!(f = flux_rpc (h, "req.sink", Jtostr (in), nodeid, 0))
             || flux_future_get (f, NULL) < 0)
        log_err_exit ("%s", __FUNCTION__);
    Jput (in);
    flux_future_destroy (f);
}
Beispiel #22
0
void test_src (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    int i;

    if (!(f = flux_rpc (h, "req.src", NULL, nodeid, 0))
             || flux_rpc_get_unpack (f, "{s:i}", "wormz", &i) < 0)
        log_err_exit ("%s", __FUNCTION__);
    if (i != 42)
        log_msg_exit ("%s: didn't get expected payload", __FUNCTION__);
    flux_future_destroy (f);
}
Beispiel #23
0
static void xping (flux_t *h, uint32_t nodeid, uint32_t xnodeid, const char *svc)
{
    flux_future_t *f;
    const char *route;

    if (!(f = flux_rpc_pack (h, "req.xping", nodeid, 0,
                             "{s:i s:s}", "rank", xnodeid, "service", svc))
            || flux_rpc_get_unpack (f, "{s:s}", "route", &route) < 0)
        log_err_exit ("req.xping");
    printf ("hops=%d\n", count_hops (route));
    flux_future_destroy (f);
}
Beispiel #24
0
void test_echo (flux_t *h, uint32_t nodeid)
{
    const char *s;
    flux_future_t *f;

    if (!(f = flux_rpc_pack (h, "req.echo", nodeid, 0,
                             "{s:s}", "mumble", "burble"))
             || flux_rpc_get_unpack (f, "{s:s}", "mumble", &s) < 0)
        log_err_exit ("%s", __FUNCTION__);
    if (strcmp (s, "burble") != 0)
        log_msg_exit ("%s: returned payload wasn't an echo", __FUNCTION__);
    flux_future_destroy (f);
}
Beispiel #25
0
// Send an event to all modules that the simulation has completed
int send_complete_event (flux_t *h)
{
    int rc = 0;
    flux_future_t *future = NULL;

    future = flux_rpc (h, "sim.complete", NULL, FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE);
    if (!future) {
        rc = -1;
    }

    flux_future_destroy (future);
    return rc;
}
Beispiel #26
0
static int update_rdl_alloc (flux_t *h, int64_t j, json_object *o)
{
    int i = 0;
    int rc = -1;
    int size = 0;
    json_object *ra_e = NULL;
    const char *key = NULL;
    zhash_t *rtab = NULL;
    int64_t *ncores = NULL;
    flux_kvs_txn_t *txn = NULL;
    flux_future_t *f = NULL;

    if (!(rtab = zhash_new ()))
        oom ();
    if (!Jget_ar_len (o, &size))
        goto done;

    for (i=0; i < (int) size; ++i) {
        if (!Jget_ar_obj (o, i, &ra_e))
            goto done;
        /* 'o' represents an array of per-node core count to use.
         * However, becasue the same rank can appear multiple times
         * in this array in emulation mode, update_hash_1ra is
         * used to determine the total core count per rank.
         */
        if ( (rc = update_hash_1ra (h, j, ra_e, rtab)) < 0)
            goto done;
    }

    if (!(txn = flux_kvs_txn_create ())) {
        flux_log_error (h, "txn_create");
        goto done;
    }
    FOREACH_ZHASH (rtab, key, ncores) {
        if ( (rc = flux_kvs_txn_pack (txn, 0, key, "I", *ncores)) < 0) {
            flux_log_error (h, "put %s", key);
            goto done;
        }
    }
    if (!(f = flux_kvs_commit (h, 0, txn)) || flux_future_get (f, NULL) < 0) {
        flux_log (h, LOG_ERR, "update_pdesc commit failed");
        goto done;
    }
    rc = 0;

done:
    flux_future_destroy (f);
    flux_kvs_txn_destroy (txn);
    zhash_destroy (&rtab);
    return rc;
}
Beispiel #27
0
/* This test is to make sure that deferred responses are handled in order.
 * Arrange for module to source 10K sequenced responses.  Messages 5000-5499
 * are "put back" on the handle using flux_putmsg().  We ensure that
 * the 10K messages are nonetheless received in order.
 */
void test_putmsg (flux_t *h, uint32_t nodeid)
{
    flux_future_t *f;
    const char *json_str;
    const int count = 10000;
    const int defer_start = 5000;
    const int defer_count = 500;
    int seq, myseq = 0;
    zlist_t *defer = zlist_new ();
    bool popped = false;
    flux_msg_t *z;
    json_t *o;

    if (!defer)
        oom ();

    if (!(f = flux_rpc_pack (h, "req.nsrc",
                             FLUX_NODEID_ANY, FLUX_RPC_NORESPONSE,
                             "{s:i}", "count", count)))
        log_err_exit ("%s", __FUNCTION__);
    flux_future_destroy (f);
    do {
        flux_msg_t *msg = flux_recv (h, FLUX_MATCH_ANY, 0);
        if (!msg)
            log_err_exit ("%s", __FUNCTION__);
        if (flux_response_decode (msg, NULL, &json_str) < 0)
            log_msg_exit ("%s: decode", __FUNCTION__);
        if (!json_str || !(o = json_loads (json_str, 0, NULL))
                      || json_unpack (o, "{s:i}", "seq", &seq) < 0)
            log_msg_exit ("%s: decode - payload", __FUNCTION__);
        json_decref (o);
        if (seq >= defer_start && seq < defer_start + defer_count && !popped) {
            if (zlist_append (defer, msg) < 0)
                oom ();
            if (seq == defer_start + defer_count - 1) {
                while ((z = zlist_pop (defer))) {
                    if (flux_requeue (h, z, FLUX_RQ_TAIL) < 0)
                        log_err_exit ("%s: flux_requeue", __FUNCTION__);
                    flux_msg_destroy (z);
                }
                popped = true;
            }
            continue;
        }
        if (seq != myseq)
            log_msg_exit ("%s: expected %d got %d", __FUNCTION__, myseq, seq);
        myseq++;
        flux_msg_destroy (msg);
    } while (myseq < count);
    zlist_destroy (&defer);
}
Beispiel #28
0
static int depthfirst_map (flux_t *h, const char *key,
                           int dirskip, restart_map_f cb, void *arg)
{
    flux_future_t *f;
    const flux_kvsdir_t *dir;
    flux_kvsitr_t *itr;
    const char *name;
    int path_level;
    int count = 0;
    int rc = -1;

    path_level = restart_count_char (key + dirskip, '.');
    if (!(f = flux_kvs_lookup (h, NULL, FLUX_KVS_READDIR, key)))
        return -1;
    if (flux_kvs_lookup_get_dir (f, &dir) < 0) {
        if (errno == ENOENT && path_level == 0)
            rc = 0;
        goto done;
    }
    if (!(itr = flux_kvsitr_create (dir)))
        goto done;
    while ((name = flux_kvsitr_next (itr))) {
        char *nkey;
        int n;
        if (!flux_kvsdir_isdir (dir, name))
            continue;
        if (!(nkey = flux_kvsdir_key_at (dir, name)))
            goto done_destroyitr;
        if (path_level == 3) // orig 'key' = .A.B.C, thus 'nkey' is complete
            n = depthfirst_map_one (h, nkey, dirskip, cb, arg);
        else
            n = depthfirst_map (h, nkey, dirskip, cb, arg);
        if (n < 0) {
            int saved_errno = errno;
            free (nkey);
            errno = saved_errno;
            goto done_destroyitr;
        }
        count += n;
        free (nkey);
    }
    rc = count;
done_destroyitr:
    flux_kvsitr_destroy (itr);
done:
    flux_future_destroy (f);
    return rc;
}
Beispiel #29
0
static int update_1pdesc (flux_t *h, flux_kvs_txn_t *txn,
              int r, int64_t j, json_object *o,
			  json_object *ha, json_object *ea)
{
    flux_future_t *f = NULL;
    int rc = -1;
    json_object *d = NULL;
    char *key;
    const char *json_str;
    const char *hn = NULL, *en = NULL;
    int64_t pid = 0, hindx = 0, eindx = 0, hrank = 0;

    if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_PID, &pid)) return -1;
    if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_HINDX, &hindx)) return -1;
    if (!Jget_int64 (o, JSC_PDESC_RANK_PDARRAY_EINDX, &eindx)) return -1;
    if (!Jget_ar_str (ha, (int)hindx, &hn)) return -1;
    if (!Jget_ar_str (ea, (int)eindx, &en)) return -1;

    key = lwj_key (h, j, ".%d.procdesc", r);

    if (!key || !(f = flux_kvs_lookup (h, 0, key))
             || flux_kvs_lookup_get (f, &json_str) < 0
            || !(d = Jfromstr (json_str))) {
        flux_log_error (h, "extract %s", key);
        goto done;
    }

    Jadd_str (d, "command", en);
    Jadd_int64 (d, "pid", pid);
    errno = 0;
    if ( (hrank = strtoul (hn, NULL, 10)) && errno != 0) {
        flux_log (h, LOG_ERR, "invalid hostname %s", hn);
        goto done;
    }
    Jadd_int64 (d, "nodeid", (int64_t)hrank);
    if (flux_kvs_txn_put (txn, 0, key, Jtostr (d)) < 0) {
        flux_log_error (h, "put %s", key);
        goto done;
    }
    rc = 0;

done:
    flux_future_destroy (f);
    free (key);
    if (d)
        Jput (d);
    return rc;
}
Beispiel #30
0
/* KVS commit completed.
 * Respond to original request which was copied and passed as 'arg'.
 */
static void commit_continuation (flux_future_t *f, void *arg)
{
    flux_t *h = flux_future_get_flux (f);
    flux_msg_t *msg = arg;

    if (flux_future_get (f, NULL) < 0) {
        if (flux_respond_error (h, msg, errno, NULL) < 0)
            flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
    }
    else {
        if (flux_respond (h, msg, 0, NULL) < 0)
            flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    }
    flux_msg_destroy (msg);
    flux_future_destroy (f);
}