Beispiel #1
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);
}
Beispiel #2
0
static resrc_graph_req_t *resrc_graph_req_from_json (JSON ga)
{
    JSON go = NULL;     /* graph json object */
    const char *name = NULL;
    int i, ngraphs = 0;
    int64_t ssize;
    resrc_graph_req_t *resrc_graph_req = NULL;

    if (Jget_ar_len (ga, &ngraphs)) {
        resrc_graph_req = xzmalloc ((ngraphs + 1) * sizeof (resrc_graph_req_t));
        for (i=0; i < ngraphs; i++) {
            Jget_ar_obj (ga, i, &go);
            if (Jget_str (go, "name", &name))
                resrc_graph_req[i].name = xstrdup (name);
            else
                goto fail;
            if (Jget_int64 (go, "size", &ssize))
                resrc_graph_req[i].size = (size_t) ssize;
            else
                goto fail;
        }
        /* end of the line */
        resrc_graph_req[i].name = NULL;
    }

    return resrc_graph_req;
fail:
    free (resrc_graph_req);
    return NULL;
}
Beispiel #3
0
static void exit_event_cb (flux_t *h, flux_msg_handler_t *w,
                           const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    barrier_t *b;
    const char *json_str;
    json_object *o = NULL;
    const char *name;
    int errnum;

    if (flux_event_decode (msg, NULL, &json_str) < 0) {
        flux_log_error (h, "%s: decoding event", __FUNCTION__);
        goto done;
    }
    if (!(o = Jfromstr (json_str))
                || !Jget_str (o, "name", &name)
                || !Jget_int (o, "errnum", &errnum)) {
        errno = EPROTO;
        flux_log_error (h, "%s: decoding event", __FUNCTION__);
        goto done;
    }
    if ((b = zhash_lookup (ctx->barriers, name))) {
        b->errnum = errnum;
        zhash_foreach (b->clients, send_enter_response, b);
        zhash_delete (ctx->barriers, name);
    }
done:
    Jput (o);
}
Beispiel #4
0
/* Note: return value of this function is ignored by libsubprocess.
 * Also: zio_json_decode() returns -1 on error, 0 on eof, strlen(s) on
 * success; caller must free 's'.
 */
static int subprocess_io_cb (struct subprocess *p, const char *json_str)
{
    runlevel_t *r;
    json_object *o = NULL;
    const char *name;
    int len;
    bool eof;
    char *s = NULL, *argz = NULL, *line = NULL;
    size_t argz_len;

    r = subprocess_get_context (p, "runlevel_t");
    assert (r != NULL);

    if (!r->io_cb)
        goto done;
    if (!(o = Jfromstr (json_str)) || !Jget_str (o, "name", &name))
        goto done;
    len = zio_json_decode (json_str, (void **)&s, &eof);
    if (len <= 0 || !s || !*s || s[len] != '\0')
        goto done;
    if (argz_create_sep (s, '\n', &argz, &argz_len) != 0)
        goto done;
    while ((line = argz_next (argz, argz_len, line)) && *line)
        r->io_cb (r, name, line, r->io_cb_arg);
done:
    if (s)
        free (s);
    if (argz)
        free (argz);
    Jput (o);
    return 0;
}
Beispiel #5
0
static void rdl_update_cb (flux_t *h,
                           flux_msg_handler_t *w,
                           const flux_msg_t *msg,
                           void *arg)
{
    json_t *o = NULL;
    const char *json_str = NULL, *rdl_str = NULL;
    ctx_t *ctx = (ctx_t *)arg;

    if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL
        || !(o = Jfromstr (json_str))) {
        flux_log (h, LOG_ERR, "%s: bad message", __FUNCTION__);
        Jput (o);
        return;
    }

    Jget_str (o, "rdl_string", &rdl_str);
    if (rdl_str) {
        free (ctx->rdl_string);
        ctx->rdl_string = strdup (rdl_str);
        ctx->rdl_changed = true;
    }

    Jput (o);
}
Beispiel #6
0
static int handle_seq_fetch (seqhash_t *s, JSON in, JSON *outp)
{
    const char *name;
    bool create = false;
    bool created = false;
    int64_t v, pre, post, *valp;

    if (!Jget_str (in, "name", &name)
        || !Jget_bool (in, "create", &create)
        || !Jget_int64 (in, "preincrement", &pre)
        || !Jget_int64 (in, "postincrement", &post)) {
        errno = EPROTO;
        return (-1);
    }
    if (seq_fetch_and_add (s, name, pre, post, &v) < 0) {
        if (!create || (errno != ENOENT))
            return (-1);
        /*  Create and initialize
         */
        valp = seq_create (s, name);
        *valp += pre;
        v = *valp;
        *valp += post;
        created = true;
    }

    *outp = Jnew ();
    Jadd_str (*outp, "name", name);
    Jadd_int64 (*outp, "value", v);
    if (create && created)
        Jadd_bool (*outp, "created", true);
    return (0);
}
Beispiel #7
0
static int update_jcb_obj (flux_t *h, int64_t jobid, const char *key,
			json_object *jcb)
{
    int rc = -1;
    json_object *o = NULL;

    if (!jcb) return -1;
    if (jobid_exist (h, jobid) != 0) return -1;

    if (is_jobid (key)) {
        flux_log (h, LOG_ERR, "jobid attr cannot be updated");
    } else if (is_state_pair (key)) {
        if (Jget_obj (jcb, JSC_STATE_PAIR, &o))
            rc = update_state (h, jobid, o);
    } else if (is_rdesc (key)) {
        if (Jget_obj (jcb, JSC_RDESC, &o))
            rc = update_rdesc (h, jobid, o);
    } else if (is_rdl (key)) {
        const char *s = NULL;
        if (Jget_str (jcb, JSC_RDL, &s))
            rc = update_rdl (h, jobid, s);
    } else if (is_rdl_alloc (key)) {
        if (Jget_obj (jcb, JSC_RDL_ALLOC, &o))
            rc = update_rdl_alloc (h, jobid, o);
    } else if (is_pdesc (key)) {
        if (Jget_obj (jcb, JSC_PDESC, &o))
            rc = update_pdesc (h, jobid, o);
    }
    else
        flux_log (h, LOG_ERR, "key (%s) not understood", key);

    return rc;
}
Beispiel #8
0
static bool fetch_rank_pdesc (JSON src, int64_t *p, int64_t *n, const char **c)
{
    if (!src) return false;
    if (!Jget_str (src, "command", c)) return false;
    if (!Jget_int64 (src, "pid", p)) return false;
    if (!Jget_int64 (src, "nodeid", n)) return false;
    return true;
}
Beispiel #9
0
int kp_rcommit_dec (JSON o, int *rootseq, const char **rootdir,
                    const char **sender)
{
    int rc = -1;

    if (!rootseq || !rootdir || !sender) {
        errno = EINVAL;
        goto done;
    }
    if (!Jget_int (o, "rootseq", rootseq) || !Jget_str (o, "rootdir", rootdir)
                                          || !Jget_str (o, "sender", sender)) {
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    return rc;
}
Beispiel #10
0
static bool Jget_nodeset (JSON o, const char *name, nodeset_t *np)
{
    nodeset_t ns;
    const char *s;

    if (!Jget_str (o, name, &s) || !(ns = nodeset_new_str (s)))
        return false;
    *np = ns;
    return true;
}
Beispiel #11
0
void test_commit (void)
{
    JSON o;
    const char *sender = NULL, *fence = NULL;
    JSON dirents = NULL, dirs;
    int nprocs = 0;
    const char *s;
    const char *rootdir;
    int rootseq;

    ok ((o = kp_tcommit_enc (NULL, NULL, NULL, 0)) != NULL,
        "kp_tcommit_enc (external commit) works");
    ok (kp_tcommit_dec (o, &sender, &dirents, &fence, &nprocs) == 0
        && sender == NULL && dirents == NULL && fence == NULL && nprocs == 1,
        "kp_tcommit_dec (external commit) works");
    Jput (o);

    dirs = Jnew ();
    Jadd_str (dirs, "foo", "bar");
    Jadd_str (dirs, "bar", "baz");
    ok ((o = kp_tcommit_enc ("sender", dirs, "fence", 1024)) != NULL,
        "kp_tcommit_enc (internal commit) works");
    Jput (dirs);
    ok (kp_tcommit_dec (o, &sender, &dirents, &fence, &nprocs) == 0
        && sender != NULL && !strcmp (sender, "sender")
        && fence != NULL  && !strcmp (fence, "fence")
        && nprocs == 1024,
        "kp_tcommit_dec (internal commit) works");
    Jput (o);
    ok (Jget_str (dirents, "foo", &s) && !strcmp (s, "bar")
        && Jget_str (dirents, "bar", &s) && !strcmp (s, "baz"),
        "kp_tcommit_dec returned encoded dirents");
    Jput (dirents);

    ok ((o = kp_rcommit_enc (42, "abc", "def")) != NULL,
        "kp_rcommit_enc works");
    ok (kp_rcommit_dec (o, &rootseq, &rootdir, &sender) == 0
        && rootseq == 42
        && rootdir != NULL && !strcmp (rootdir, "abc")
        && sender != NULL && !strcmp (sender, "def"),
        "kp_rcommid_dec works");
    Jput (o);
}
Beispiel #12
0
int kp_tsetroot_dec (JSON o, int *rootseq, const char **rootdir,
                     JSON *root, const char **fence)
{
    int rc = -1;

    if (!o || !rootseq || !rootdir || !root || !fence) {
        errno = EINVAL;
        goto done;
    }
    if (!Jget_int (o, "rootseq", rootseq) || !Jget_str (o, "rootdir", rootdir)){
        errno = EPROTO;
        goto done;
    }
    *fence = NULL;
    (void)Jget_str (o, "fence", fence);
    *root = NULL;
    (void)Jget_obj (o, "rootdirval", root);
    rc = 0;
done:
    return rc;
}
Beispiel #13
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);
}
Beispiel #14
0
void test_watch (void)
{
    JSON o;
    bool dir = false;
    bool once = false;
    bool first = false;
    bool link = false;
    const char *key = NULL;
    const char *s = NULL;
    JSON val;

    val = Jnew ();
    Jadd_str (val, "s", "blatz");
    o = kp_twatch_enc ("foo", val, false, true, false, true);
    ok (o != NULL,
        "kp_twatch_enc works");
    val = NULL;
    ok (kp_twatch_dec (o, &key, &val, &once, &first, &dir, &link) == 0
        && once == false && first == true && dir == false && link == true,
        "kp_twatch_dec works");
    ok (key && !strcmp (key, "foo"),
        "kp_twatch_dec returned encoded key");
    ok (val && Jget_str (val, "s", &s) && !strcmp (s, "blatz"),
        "kp_twatch_dec returned encoded value");
    /* FIXME try encoding NULL value */
    Jput (o);

    val = Jnew ();
    Jadd_str (val, "str", "snerg");
    o = kp_rwatch_enc ("foo", val);
    ok (o != NULL,
        "kp_rwatch_enc works");
    val = NULL;
    ok (kp_rwatch_dec (o, &val) == 0,
        "kp_rewatch_dec works");
    ok (val && Jget_str (val, "str", &s) && !strcmp (s, "snerg"),
        "kp_twatch_dec returned encoded value");
    Jput (o);
}
Beispiel #15
0
static int handle_seq_destroy (seqhash_t *s, JSON in, JSON *outp)
{
    const char *name;
    if (!Jget_str (in, "name", &name)) {
        errno = EPROTO;
        return (-1);
    }
    if (seq_destroy (s, name) < 0)
        return (-1);
    *outp = Jnew ();
    Jadd_str (*outp, "name", name);
    Jadd_bool (*outp, "destroyed", true);
    return (0);
}
Beispiel #16
0
int kp_tcommit_dec (JSON o, const char **sender, JSON *ops,
                    const char **fence, int *nprocs)
{
    int rc = -1;

    if (!sender || !ops || !fence || !nprocs) {
        errno = EINVAL;
        goto done;
    }
    *ops = NULL;
    (void)Jget_obj (o, "ops", ops);
    if (*ops)
        Jget (*ops);
    *sender = NULL;
    (void)Jget_str (o, ".arg_sender", sender);
    *fence = NULL;
    (void)Jget_str (o, ".arg_fence", fence);
    *nprocs = 1;
    (void)Jget_int (o, ".arg_nprocs", nprocs);

    rc = 0;
done:
    return rc;
}
Beispiel #17
0
int kp_tunwatch_dec (JSON o, const char **key)
{
    int rc = -1;

    if (!o || !key) {
        errno = EINVAL;
        goto done;
    }
    if (!Jget_str (o, "key", key)) {
        errno = EPROTO;
        goto done;
    }
    rc = 0;
done:
    return rc;
}
Beispiel #18
0
/*
 * Gather concatenated hwloc xml topo file with resource-hwloc.topo RPC
 *  and save results until destroyed by hwloc_topo_destroy ().
 */
static struct hwloc_topo * hwloc_topo_create (optparse_t *p)
{
    const char *json_str;
    struct hwloc_topo *t = xzmalloc (sizeof (*t));

    if (!(t->h = builtin_get_flux_handle (p)))
        log_err_exit ("flux_open");

    t->rpc = flux_rpc (t->h, "resource-hwloc.topo", NULL, 0, 0);
    if (!t->rpc || (flux_rpc_get (t->rpc, NULL, &json_str) < 0))
        log_err_exit ("flux_rpc");

    if (!(t->o = Jfromstr (json_str)) || !Jget_str (t->o, "topology", &t->topo))
        log_msg_exit ("failed to parse json topology");

    return (t);
}
Beispiel #19
0
/* Handle ping response for proxy ping.
 */
static int ping_response_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = arg;
    JSON o = NULL;
    JSON out = Jnew ();;
    int seq;
    const char *route;
    zmsg_t *zreq = NULL;
    char *hashkey = NULL;

    if (flux_json_response_decode (*zmsg, &o) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_json_response_decode: %s",
                  __FUNCTION__, strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "seq", &seq) || !Jget_str (o, "route", &route)) {
        flux_log (h, LOG_ERR, "%s: protocol error", __FUNCTION__);
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Rping seq=%d %s", seq, route);
    hashkey = xasprintf ("%d", seq);
    if (!(zreq = zhash_lookup (ctx->ping_requests, hashkey))) {
        flux_log (h, LOG_ERR, "%s: unsolicited ping response: %s",
                  __FUNCTION__, hashkey);
        goto done;
    }
    zhash_delete (ctx->ping_requests, hashkey);
    flux_log (h, LOG_DEBUG, "Txping seq=%d %s", seq, route);
    Jadd_str (out, "route", route);
    if (flux_json_respond (h, out, &zreq) < 0) {
        flux_log (h, LOG_ERR, "%s: flux_json_respond: %s",
                  __FUNCTION__, strerror (errno));
        goto done;
    }
done:
    if (hashkey)
        free (hashkey);
    Jput (o);
    Jput (out);
    //zmsg_destroy (zmsg);
    zmsg_destroy (&zreq);
    return 0;
}
Beispiel #20
0
static int handle_seq_set (seqhash_t *s, JSON in, JSON *outp)
{
    const char *name;
    int64_t old, v;
    if (!Jget_str (in, "name", &name)
        || !Jget_int64 (in, "value", &v)) {
        errno = EPROTO;
        return (-1);
    }
    if ((Jget_int64 (in, "oldvalue", &old)
        && (seq_cmp_and_set (s, name, old, v) < 0))
        || (seq_set (s, name, v) < 0))
            return (-1);

    *outp = Jnew ();
    Jadd_str (*outp, "name", name);
    Jadd_bool (*outp, "set", true);
    Jadd_int64 (*outp, "value", v);
    return (0);
}
Beispiel #21
0
static int dmesg_rpc_get (flux_rpc_t *rpc, int *seq, flux_log_f fun, void *arg)
{
    const char *json_str;
    const char *buf;
    JSON o = NULL;
    int rc = -1;

    if (flux_rpc_get (rpc, NULL, &json_str) < 0)
        goto done;
    if (!(o = Jfromstr (json_str)) || !Jget_str (o, "buf", &buf)
                                   || !Jget_int (o, "seq", seq)) {
        errno = EPROTO;
        goto done;
    }
    fun (buf, strlen (buf), arg);
    rc = 0;
done:
    Jput (o);
    return rc;
}
Beispiel #22
0
/* Proxy ping.
 */
static int xping_request_cb (flux_t h, int typemask, zmsg_t **zmsg, void *arg)
{
    ctx_t *ctx = arg;
    int rank, seq = ctx->ping_seq++;
    const char *service;
    char *hashkey = NULL;
    JSON in = Jnew ();
    JSON o = NULL;

    if (flux_json_request_decode (*zmsg, &o) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    if (!Jget_int (o, "rank", &rank) || !Jget_str (o, "service", &service)) {
        if (flux_err_respond (h, EPROTO, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    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);
    if (flux_json_request (h, rank, 0, service, in) < 0) {
        if (flux_err_respond (h, errno, zmsg) < 0)
            flux_log (h, LOG_ERR, "%s: flux_err_respond: %s", __FUNCTION__,
                      strerror (errno));
        goto done;
    }
    hashkey = xasprintf ("%d", seq);
    zhash_update (ctx->ping_requests, hashkey, *zmsg);
    *zmsg = NULL;
done:
    Jput (o);
    Jput (in);
    if (hashkey)
        free (hashkey);
    return 0;
}
Beispiel #23
0
void test_echo (flux_t *h, uint32_t nodeid)
{
    json_object *in = Jnew ();
    json_object *out = NULL;
    const char *json_str;
    const char *s;
    flux_future_t *f;

    Jadd_str (in, "mumble", "burble");
    if (!(f = flux_rpc (h, "req.echo", Jtostr (in), nodeid, 0))
             || flux_rpc_get (f, &json_str) < 0)
        log_err_exit ("%s", __FUNCTION__);
    if (!json_str
        || !(out = Jfromstr (json_str))
        || !Jget_str (out, "mumble", &s)
        || strcmp (s, "burble") != 0)
        log_msg_exit ("%s: returned payload wasn't an echo", __FUNCTION__);
    Jput (in);
    Jput (out);
    flux_future_destroy (f);
}
Beispiel #24
0
int shutdown_decode (const flux_msg_t *msg, double *grace, int *exitcode,
                     int *rank, char *reason, int reason_len)
{
    const char *json_str, *s;
    JSON in = NULL;
    int rc = -1;

    if (flux_event_decode (msg, NULL, &json_str) < 0
                || !(in = Jfromstr (json_str))
                || !Jget_str (in, "reason", &s)
                || !Jget_double (in, "grace", grace)
                || !Jget_int (in, "rank", rank)
                || !Jget_int (in, "exitcode", exitcode)) {
        errno = EPROTO;
        goto done;
    }
    snprintf (reason, reason_len, "%s", s);
    rc = 0;
done:
    Jput (in);
    return rc;
}
Beispiel #25
0
static void xping (flux_t *h, uint32_t nodeid, uint32_t xnodeid, const char *svc)
{
    flux_future_t *f;
    const char *json_str;
    json_object *in = Jnew ();
    json_object *out = NULL;
    const char *route;

    Jadd_int (in, "rank", xnodeid);
    Jadd_str (in, "service", svc);
    if (!(f = flux_rpc (h, "req.xping", Jtostr (in), nodeid, 0))
            || flux_rpc_get (f, &json_str) < 0)
        log_err_exit ("req.xping");
    if (!json_str
        || !(out = Jfromstr (json_str))
        || !Jget_str (out, "route", &route))
        log_errn_exit (EPROTO, "req.xping");
    printf ("hops=%d\n", count_hops (route));
    Jput (out);
    Jput (in);
    flux_future_destroy (f);
}
Beispiel #26
0
/* Handle ping response for proxy ping.
 * Match it with a request and respond to that request.
 */
void ping_response_cb (flux_t h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    const char *json_str;
    JSON o = NULL;
    JSON out = Jnew ();;
    int seq;
    const char *route;
    flux_msg_t *req = NULL;
    char *hashkey = NULL;

    if (flux_response_decode (msg, NULL, &json_str) < 0) {
        flux_log_error (h, "%s: flux_response_decode", __FUNCTION__);
        goto done;
    }
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "seq", &seq)
                                   || !Jget_str (o, "route", &route)) {
        errno = EPROTO;
        flux_log_error (h, "%s: payload", __FUNCTION__);
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Rping seq=%d %s", seq, route);
    hashkey = xasprintf ("%d", seq);
    if (!(req = zhash_lookup (ctx->ping_requests, hashkey))) {
        flux_log_error (h, "%s: unsolicited ping response", __FUNCTION__);
        goto done;
    }
    flux_log (h, LOG_DEBUG, "Txping seq=%d %s", seq, route);
    Jadd_str (out, "route", route);
    if (flux_respond (h, req, 0, Jtostr (out)) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    zhash_delete (ctx->ping_requests, hashkey);
done:
    if (hashkey)
        free (hashkey);
    Jput (o);
    Jput (out);
}
Beispiel #27
0
resrc_flow_t *resrc_flow_new_from_json (json_t *o, resrc_flow_t *parent)
{
    json_t *jhierarchyo = NULL; /* json hierarchy object */
    const char *basename = NULL;
    const char *name = NULL;
    const char *hierarchy = NULL;
    const char *path = NULL;
    const char *hierarchy_path = NULL;
    const char *tmp = NULL;
    const char *type = NULL;
    int64_t id;
    int64_t ssize;
    resrc_flow_t *resrc_flow = NULL;
    resrc_t *flow_resrc;
    resrc_t *resrc = NULL;
    size_t size = 1;
    uuid_t uuid;

    if (!Jget_str (o, "type", &type))
        goto ret;
    Jget_str (o, "basename", &basename);
    Jget_str (o, "name", &name);
    if (!(Jget_int64 (o, "id", &id)))
        id = -1;
    if (Jget_str (o, "uuid", &tmp))
        uuid_parse (tmp, uuid);
    else
        uuid_clear(uuid);
    if (Jget_int64 (o, "size", &ssize))
        size = (size_t) ssize;
    if ((jhierarchyo = Jobj_get (o, "hierarchy"))) {
        /* Get first key and value from hierarchy object */
        const char *key = json_object_iter_key (json_object_iter (jhierarchyo));
        if (key) {
            hierarchy = key;
            Jget_str (jhierarchyo, key, &hierarchy_path);
        }
    }
    if (!Jget_str (o, "path", &path)) {
        if (hierarchy_path)
            path = xstrdup (hierarchy_path);
    }
    if (!path) {
        if (parent)
            path = xasprintf ("%s/%s", resrc_path (parent->flow_resrc), name);
        else
            path = xasprintf ("/%s", name);
    }

    if (!(flow_resrc = resrc_new_resource (type, path, basename, name, NULL, id,
                                           uuid, size)))
        goto ret;

    if (!strncmp (type, "node", 5)) {
        resrc = resrc_lookup (name);
    }
    if ((resrc_flow = resrc_flow_new (parent, flow_resrc, resrc))) {
        /* add time window if we are given a start time */
        int64_t starttime;
        if (Jget_int64 (o, "starttime", &starttime)) {
            json_t *   w = Jnew ();
            char    *json_str;
            int64_t endtime;
            int64_t wall_time;

            Jadd_int64 (w, "starttime", starttime);

            if (!Jget_int64 (o, "endtime", &endtime)) {
                if (Jget_int64 (o, "walltime", &wall_time))
                    endtime = starttime + wall_time;
                else
                    endtime = TIME_MAX;
            }
            Jadd_int64 (w, "endtime", endtime);

            json_str = xstrdup (Jtostr (w));
            resrc_twindow_insert (resrc_flow->flow_resrc, "0",
                                  (void *) json_str);
            Jput (w);
        }
    }
    if (resrc)
        resrc_graph_insert (resrc, hierarchy, resrc_flow);
ret:
    return resrc_flow;
}
Beispiel #28
0
static void enter_request_cb (flux_t *h, flux_msg_handler_t *w,
                              const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    barrier_t *b;
    json_object *o = NULL;
    char *sender = NULL;
    const char *name;
    int count, nprocs, hopcount;
    const char *json_str;

    if (flux_request_decode (msg, NULL, &json_str) < 0
     		|| flux_msg_get_route_first (msg, &sender) < 0) {
        flux_log_error (ctx->h, "%s: decoding request", __FUNCTION__);
        goto done;
    }
    if (!(o = Jfromstr (json_str))
     	        || !Jget_str (o, "name", &name)
     	        || !Jget_int (o, "count", &count)
     	        || !Jget_int (o, "nprocs", &nprocs)) {
        errno = EPROTO;
        flux_log_error (ctx->h, "%s: decoding request", __FUNCTION__);
        goto done;
    }

    if (!(b = zhash_lookup (ctx->barriers, name)))
        b = barrier_create (ctx, name, nprocs);

    /* Distinguish client (tracked) vs downstream barrier plugin (untracked).
     * A client, distinguished by hopcount > 0, can only enter barrier once.
     */
    if (!Jget_int (o, "hopcount", &hopcount)) {
        if (barrier_add_client (b, sender, msg) < 0) {
            flux_respond (ctx->h, msg, EEXIST, NULL);
            flux_log (ctx->h, LOG_ERR,
                        "abort %s due to double entry by client %s",
                        name, sender);
            if (exit_event_send (ctx->h, b->name, ECONNABORTED) < 0)
                flux_log_error (ctx->h, "exit_event_send");
            goto done;
        }
    }

    /* If the count has been reached, terminate the barrier;
     * o/w set timer to pass count upstream and zero it here.
     */
    b->count += count;
    if (b->count == b->nprocs) {
        if (exit_event_send (ctx->h, b->name, 0) < 0)
            flux_log_error (ctx->h, "exit_event_send");
    } else if (ctx->rank > 0 && !ctx->timer_armed) {
        flux_timer_watcher_reset (ctx->timer, barrier_reduction_timeout_sec, 0.);
        flux_watcher_start (ctx->timer);
        ctx->timer_armed = true;
    }
done:
    if (o)
        json_object_put (o);
    if (sender)
        free (sender);
}
Beispiel #29
0
// Recevied a request to join the simulation ("sim.join")
static void join_cb (flux_t *h,
                     flux_msg_handler_t *w,
                     const flux_msg_t *msg,
                     void *arg)
{
    int mod_rank;
    json_t *request = NULL;
    const char *mod_name = NULL, *json_str = NULL;
    double *next_event = (double *)malloc (sizeof (double));
    ctx_t *ctx = arg;
    sim_state_t *sim_state = ctx->sim_state;
    uint32_t size;

    if (flux_msg_get_json (msg, &json_str) < 0 || json_str == NULL
        || !(request = Jfromstr (json_str))
        || !Jget_str (request, "mod_name", &mod_name)
        || !Jget_int (request, "rank", &mod_rank)
        || !Jget_double (request, "next_event", next_event)) {
        flux_log (h, LOG_ERR, "%s: bad join message", __FUNCTION__);
        goto out;
    }
    if (flux_get_size (h, &size) < 0)
        goto out;
    if (mod_rank < 0 || mod_rank >= size) {
        flux_log (h, LOG_ERR, "%s: bad rank in join message", __FUNCTION__);
        goto out;
    }

    flux_log (h,
              LOG_DEBUG,
              "join rcvd from module %s on rank %d, next event at %f",
              mod_name,
              mod_rank,
              *next_event);

    zhash_t *timers = sim_state->timers;
    if (zhash_insert (timers, mod_name, next_event) < 0) {  // key already
                                                            // exists
        flux_log (h,
                  LOG_ERR,
                  "duplicate join request from %s, module already exists in "
                  "sim_state",
                  mod_name);
        goto out;
    }
    // clear next event so it is not freed below
    next_event = NULL;

    // TODO: this is horribly hackish, improve the handshake to avoid
    // this hardcoded # of modules. maybe use a timeout?  ZMQ provides
    // support for polling etc with timeouts, should try that
    static int num_modules = 3;
    num_modules--;
    if (num_modules <= 0) {
        if (handle_next_event (ctx) < 0) {
            flux_log (h, LOG_ERR, "failure while handling next event");
            return;
        }
    }

out:
    Jput (request);
    free (next_event);
}
Beispiel #30
0
static void determine_all_min_bandwidth_helper (struct resource *r,
                                                double curr_min_bandwidth,
                                                zhash_t *job_hash)
{
    struct resource *curr_child;
    int64_t job_id;
    double total_requested_bandwidth, curr_average_bandwidth,
        child_alloc_bandwidth, total_used_bandwidth, this_max_bandwidth,
        num_children, this_alloc_bandwidth;
    json_t *o;
    zlist_t *child_list;
    const char *type = NULL;

    // Check if leaf node in hierarchy (base case)
    rdl_resource_iterator_reset (r);
    curr_child = rdl_resource_next_child (r);
    if (curr_child == NULL) {
        // Check if allocated to a job
        if (rdl_resource_get_int (r, "lwj", &job_id) == 0) {
            // Determine which is less, the bandwidth currently available to
            // this resource, or the bandwidth allocated to it by the job
            // This assumes that jobs cannot share leaf nodes in the hierarchy
            this_alloc_bandwidth = get_alloc_bandwidth (r);
            curr_min_bandwidth = (curr_min_bandwidth < this_alloc_bandwidth)
                                     ? curr_min_bandwidth
                                     : this_alloc_bandwidth;
            double *job_min_bw = get_job_min_from_hash (job_hash, job_id);
            if (job_min_bw != NULL && curr_min_bandwidth < *job_min_bw) {
                *job_min_bw = curr_min_bandwidth;
            }  // if job_min_bw is NULL, the tag still exists in the RDL, but
               // the job completed
        }
        return;
    }  // else

    // Sum the bandwidths of the parent's children
    total_requested_bandwidth = 0;
    child_list = zlist_new ();
    while (curr_child != NULL) {
        o = rdl_resource_json (curr_child);
        Jget_str (o, "type", &type);
        // TODO: clean up this hardcoded value, should go away once we switch to
        // the real
        // rdl implementation (storing a bandwidth resource at every level)
        if (strcmp (type, "memory") != 0) {
            total_requested_bandwidth += get_alloc_bandwidth (curr_child);
            zlist_append (child_list, curr_child);
        }
        Jput (o);
        curr_child = rdl_resource_next_child (r);
    }
    rdl_resource_iterator_reset (r);

    // Sort child list based on alloc bw
    zlist_sort (child_list, compare_resource_alloc_bw);

    // const char *resource_string = Jtostr(o);
    // Loop over all of the children
    this_max_bandwidth = get_max_bandwidth (r);
    total_used_bandwidth = (total_requested_bandwidth > this_max_bandwidth)
                               ? this_max_bandwidth
                               : total_requested_bandwidth;
    total_used_bandwidth = (total_used_bandwidth > curr_min_bandwidth)
                               ? curr_min_bandwidth
                               : total_used_bandwidth;
    while (zlist_size (child_list) > 0) {
        // Determine the amount of bandwidth to allocate to each child
        num_children = zlist_size (child_list);
        curr_average_bandwidth = (total_used_bandwidth / num_children);
        curr_child = (struct resource *)zlist_pop (child_list);
        child_alloc_bandwidth = get_alloc_bandwidth (curr_child);
        if (child_alloc_bandwidth > 0) {
            if (child_alloc_bandwidth > curr_average_bandwidth)
                child_alloc_bandwidth = curr_average_bandwidth;

            // Subtract the allocated bandwidth from the parent's total
            total_used_bandwidth -= child_alloc_bandwidth;
            // Recurse on the child
            determine_all_min_bandwidth_helper (curr_child,
                                                child_alloc_bandwidth,
                                                job_hash);
        }
        rdl_resource_destroy (curr_child);
    }

    // Cleanup
    zlist_destroy (
        &child_list);  // no need to rdl_resource_destroy, done in above loop

    return;
}