예제 #1
0
파일: jstatctl.c 프로젝트: trws/flux-core
static int send_state_event (flux_t *h, job_state_t st, int64_t j)
{
    flux_msg_t *msg;
    char *json = NULL;
    char *topic = NULL;
    int rc = -1;

    if (asprintf (&topic, "jsc.state.%s", jsc_job_num2state (st)) < 0) {
        errno = ENOMEM;
        flux_log_error (h, "create state change event: %s",
                        jsc_job_num2state (st));
        goto done;
    }
    if ((msg = flux_event_pack (topic, "{ s:I }", "lwj", j)) == NULL) {
        flux_log_error (h, "flux_event_pack");
        goto done;
    }
    if (flux_send (h, msg, 0) < 0)
        flux_log_error (h, "flux_send event");
    flux_msg_destroy (msg);
    rc = 0;
done:
    free (topic);
    free (json);
    return rc;
}
예제 #2
0
static void io_cb (flux_subprocess_t *p, const char *stream)
{
    runlevel_t *r;
    const char *ptr;
    int lenp;

    r = flux_subprocess_aux_get (p, "runlevel");

    assert (r);
    assert (r->level == 1 || r->level == 3);

    if (!(ptr = flux_subprocess_read_line (p, stream, &lenp))) {
        flux_log_error (r->h, "%s: flux_subprocess_read_line", __FUNCTION__);
        return;
    }

    if (!lenp) {
        if (!(ptr = flux_subprocess_read (p, stream, -1, &lenp))) {
            flux_log_error (r->h, "%s: flux_subprocess_read", __FUNCTION__);
            return;
        }
    }

    if (lenp && r->io_cb)
        r->io_cb (r, stream, ptr, r->io_cb_arg);
}
예제 #3
0
static ctx_t *getctx (flux_t *h)
{
    ctx_t *ctx = (ctx_t *)flux_aux_get (h, "flux::barrier");

    if (!ctx) {
        ctx = xzmalloc (sizeof (*ctx));
        if (!(ctx->barriers = zhash_new ())) {
            errno = ENOMEM;
            goto error;
        }
        if (flux_get_rank (h, &ctx->rank) < 0) {
            flux_log_error (h, "flux_get_rank");
            goto error;
        }
        if (!(ctx->timer = flux_timer_watcher_create (flux_get_reactor (h),
                       barrier_reduction_timeout_sec, 0., timeout_cb, ctx) )) {
            flux_log_error (h, "flux_timer_watacher_create");
            goto error;
        }
        ctx->h = h;
        flux_aux_set (h, "flux::barrier", ctx, freectx);
    }
    return ctx;
error:
    freectx (ctx);
    return NULL;
}
예제 #4
0
파일: job.c 프로젝트: cigolabs/flux-core
static void send_create_event (flux_t h, int64_t id, char *topic)
{
    flux_msg_t *msg;
    char *json = NULL;

    if (asprintf (&json, "{\"lwj\":%ld}", id) < 0) {
        errno = ENOMEM;
        flux_log_error (h, "failed to create state change event");
        goto out;
    }
    if ((msg = flux_event_encode (topic, json)) == NULL) {
        flux_log_error (h, "failed to create state change event");
        goto out;
    }
    if (flux_send (h, msg, 0) < 0)
        flux_log_error (h, "reserved event failed");
    flux_msg_destroy (msg);

    /* Workaround -- wait for our own event to be published with a
     *  blocking recv. XXX: Remove when publish is synchronous.
     */
    wait_for_event (h, id, topic);
out:
    free (json);
}
예제 #5
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);
}
예제 #6
0
int mod_main (flux_t *h, int argc, char **argv)
{
    int rc = -1;
    ctx_t *ctx = getctx (h);

    if (!ctx)
        goto done;
    if (flux_event_subscribe (h, "barrier.") < 0) {
        flux_log_error (h, "flux_event_subscribe");
        goto done;
    }
    if (flux_msg_handler_addvec (h, htab, ctx) < 0) {
        flux_log_error (h, "flux_msghandler_add");
        goto done;
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log_error (h, "flux_reactor_run");
        goto done_unreg;
    }
    rc = 0;
done_unreg:
    flux_msg_handler_delvec (htab);
done:
    return rc;
}
예제 #7
0
static int update_state (flux_t h, int64_t j, JSON o)
{
    int rc = -1;
    int64_t st = 0;
    char *key;

    if (!Jget_int64 (o, JSC_STATE_PAIR_NSTATE, &st)) return -1;
    if ((st >= J_FOR_RENT) || (st < J_NULL)) return -1;

    key = xasprintf ("lwj.%"PRId64".state", j);
    if (kvs_put_string (h, key, jsc_job_num2state ((job_state_t)st)) < 0)
        flux_log_error (h, "update %s", key);
    else if (kvs_commit (h) < 0)
        flux_log_error (h, "commit %s", key);
    else {
        flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new state: %s", j,
              jsc_job_num2state ((job_state_t)st));
        rc = 0;
    }
    free (key);

    if (send_state_event (h, st, j) < 0)
        flux_log_error (h, "send state event");

    return rc;
}
예제 #8
0
int mod_main (flux_t *h, int argc, char **argv)
{
    flux_msg_handler_t **handlers = NULL;
    sqlite_ctx_t *ctx = getctx (h);
    if (!ctx)
        goto done;
    if (flux_event_subscribe (h, "shutdown") < 0) {
        flux_log_error (h, "flux_event_subscribe");
        goto done;
    }
    if (flux_msg_handler_addvec (h, htab, ctx, &handlers) < 0) {
        flux_log_error (h, "flux_msg_handler_addvec");
        goto done;
    }
    if (register_backing_store (h, true, "content-sqlite") < 0) {
        flux_log_error (h, "registering backing store");
        goto done;
    }
    if (register_content_backing_service (h) < 0) {
        flux_log_error (h, "service.add: content-backing");
        goto done;
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log_error (h, "flux_reactor_run");
        goto done;
    }
done:
    flux_msg_handler_delvec (handlers);
    return 0;
}
예제 #9
0
파일: req.c 프로젝트: cigolabs/flux-core
/* Return 'n' sequenced responses.
 */
void nsrc_request_cb (flux_t h, flux_msg_handler_t *w,
                      const flux_msg_t *msg, void *arg)
{
    const char *json_str;
    int saved_errno;
    JSON o = Jnew ();
    int i, count;
    int rc = -1;

    if (flux_request_decode (msg, NULL, &json_str) < 0) {
        saved_errno = errno;
        goto done;
    }
    if (!(o = Jfromstr (json_str)) || !Jget_int (o, "count", &count)) {
        saved_errno = errno = EPROTO;
        goto done;
    }
    for (i = 0; i < count; i++) {
        Jadd_int (o, "seq", i);
        if (flux_respond (h, msg, 0, Jtostr (o)) < 0) {
            saved_errno = errno;
            flux_log_error (h, "%s: flux_respond", __FUNCTION__);
            goto done;
        }
    }
    rc = 0;
done:
    if (rc < 0) {
        if (flux_respond (h, msg, saved_errno, NULL) < 0)
            flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    }
    Jput (o);
}
예제 #10
0
/* sched-ready:
 * Scheduler indicates what style of alloc concurrency is requires,
 * and tells job-manager to start allocations.  job-manager tells
 * scheduler how many jobs are in the queue.
 */
static void ready_cb (flux_t *h, flux_msg_handler_t *mh,
                      const flux_msg_t *msg, void *arg)
{
    struct alloc_ctx *ctx = arg;
    const char *mode;
    int count;

    if (flux_request_unpack (msg, NULL, "{s:s}", "mode", &mode) < 0)
        goto error;
    if (!strcmp (mode, "single"))
        ctx->mode = SCHED_SINGLE;
    else if (!strcmp (mode, "unlimited"))
        ctx->mode = SCHED_UNLIMITED;
    else {
        errno = EPROTO;
        goto error;
    }
    ctx->ready = true;
    flux_log (h, LOG_DEBUG, "scheduler: ready %s", mode);
    count = queue_size (ctx->inqueue);
    if (flux_respond_pack (h, msg, "{s:i}", "count", count) < 0)
        flux_log_error (h, "%s: flux_respond_pack", __FUNCTION__);
    return;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
}
예제 #11
0
파일: jstatctl.c 프로젝트: trws/flux-core
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;
}
예제 #12
0
파일: req.c 프로젝트: cigolabs/flux-core
int mod_main (flux_t h, int argc, char **argv)
{
    int saved_errno;
    ctx_t *ctx = getctx (h);

    if (!ctx) {
        saved_errno = errno;
        flux_log_error (h, "error allocating context");
        goto error;
    }
    if (flux_msg_handler_addvec (h, htab, ctx) < 0) {
        saved_errno = errno;
        flux_log_error (h, "flux_msg_handler_addvec");
        goto error;
    }
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        saved_errno = errno;
        flux_log_error (h, "flux_reactor_run");
        flux_msg_handler_delvec (htab);
        goto error;
    }
    flux_msg_handler_delvec (htab);
    return 0;
error:
    errno = saved_errno;
    return -1;
}
예제 #13
0
파일: req.c 프로젝트: cigolabs/flux-core
/* Handle the simplest possible request.
 * Verify that everything is as expected; log it and stop the reactor if not.
 */
void null_request_cb (flux_t h, flux_msg_handler_t *w,
                      const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = arg;
    const char *topic;
    int type, size;
    void *buf;
    uint32_t nodeid;
    int flags;

    if (!msg) {
        flux_log (h, LOG_ERR, "%s: got NULL msg!", __FUNCTION__);
        goto error;
    }
    if (flux_msg_get_type (msg, &type) < 0) {
        flux_log_error (h, "%s: flux_msg_get_type", __FUNCTION__);
        goto error;
    }
    if (type != FLUX_MSGTYPE_REQUEST) {
        flux_log (h, LOG_ERR, "%s: unexpected type %s", __FUNCTION__,
                  flux_msg_typestr (type));
        goto error;
    }
    if (flux_msg_get_nodeid (msg, &nodeid, &flags) < 0) {
        flux_log_error (h, "%s: flux_msg_get_nodeid", __FUNCTION__);
        goto error;
    }
    if (nodeid != ctx->rank && nodeid != FLUX_NODEID_ANY) {
        flux_log (h, LOG_ERR, "%s: unexpected nodeid: %"PRIu32"", __FUNCTION__,
                  nodeid);
        goto error;
    }
    if (flux_msg_get_topic (msg, &topic) < 0) {
        flux_log_error (h, "%s: flux_msg_get_topic", __FUNCTION__);
        goto error;
    }
    if (strcmp (topic, "req.null") != 0) {
        flux_log (h, LOG_ERR, "%s: unexpected topic: %s", __FUNCTION__,
                  topic);
        goto error;
    }
    if (flux_msg_get_payload (msg, &flags, &buf, &size) == 0) {
        flux_log (h, LOG_ERR, "%s: unexpected payload size %d", __FUNCTION__,
                  size);
        goto error;
    }
    if (errno != EPROTO) {
        flux_log (h, LOG_ERR, "%s: get nonexistent payload: %s", __FUNCTION__,
                  strerror (errno));
        goto error;
    }
    if (flux_respond (h, msg, 0, NULL) < 0) {
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
        goto error;
    }
    return;
error:
    flux_reactor_stop_error (flux_get_reactor (h));
}
예제 #14
0
void priority_handle_request (flux_t *h, struct queue *queue,
                              struct event_ctx *event_ctx,
                              const flux_msg_t *msg)
{
    uint32_t userid;
    uint32_t rolemask;
    flux_jobid_t id;
    struct job *job;
    int priority;
    const char *errstr = NULL;

    if (flux_request_unpack (msg, NULL, "{s:I s:i}",
                                        "id", &id,
                                        "priority", &priority) < 0
                    || flux_msg_get_userid (msg, &userid) < 0
                    || flux_msg_get_rolemask (msg, &rolemask) < 0)
        goto error;
    if (priority < FLUX_JOB_PRIORITY_MIN || priority > FLUX_JOB_PRIORITY_MAX) {
        errstr = "priority value is out of range";
        errno = EINVAL;
        goto error;
    }
    if (!(job = queue_lookup_by_id (queue, id))) {
        errstr = "unknown job";
        goto error;
    }
    /* Security: guests can only adjust jobs that they submitted.
     */
    if (!(rolemask & FLUX_ROLE_OWNER) && userid != job->userid) {
        errstr = "guests can only reprioritize their own jobs";
        errno = EPERM;
        goto error;
    }
    /* Security: guests can only reduce priority, or increase up to default.
     */
    if (!(rolemask & FLUX_ROLE_OWNER)
            && priority > MAXOF (FLUX_JOB_PRIORITY_DEFAULT, job->priority)) {
        errstr = "guests can only adjust priority <= default";
        errno = EPERM;
        goto error;
    }
    /* Post event, change job's queue position, and respond.
     */
    if (event_job_post_pack (event_ctx, job,
                             "priority",
                             "{ s:i s:i }",
                             "userid", userid,
                             "priority", priority) < 0)
        goto error;
    queue_reorder (queue, job, job->queue_handle);
    if (flux_respond (h, msg, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    return;
error:
    if (flux_respond_error (h, msg, errno, errstr) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
}
예제 #15
0
파일: jstatctl.c 프로젝트: trws/flux-core
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;
}
예제 #16
0
파일: event.c 프로젝트: trws/flux-core
static void *cron_event_create (flux_t *h, cron_entry_t *e, json_t *arg)
{
    struct cron_event *ev;
    int nth = 0;
    int after = 0;
    double min_interval = 0.;
    const char *event;
    struct flux_match match = FLUX_MATCH_EVENT;

    if (json_unpack (arg, "{ s:s, s?i, s?i, s?F }",
                          "topic", &event,
                          "nth",   &nth,
                          "after", &after,
                          "min_interval", &min_interval) < 0) {
        flux_log_error (h, "cron event: json_unpack");
        errno = EPROTO;
        return NULL;
    }

    if ((ev = calloc (1, sizeof (*ev))) == NULL) {
        flux_log_error (h, "cron event: calloc");
        return NULL;
    }

    /* Call subscribe per cron entry. Multiple event subscriptions are
     *  allowed and each cron_event entry will have a corresponding
     *  unsubscribe
     */
    if (flux_event_subscribe (h, event) < 0) {
        flux_log_error (h, "cron_event: subscribe");
        goto fail;
    }
    /* Save a copy of this handle for event unsubscribe at destroy */
    ev->h = h;
    ev->nth = nth;
    ev->after = after;
    ev->min_interval = min_interval;
    ev->counter = 0;

    if ((ev->event = strdup (event)) == NULL) {
        flux_log_error (h, "cron event: strdup");
        goto fail;
    }

    match.topic_glob = ev->event;
    ev->mh = flux_msg_handler_create (h, match, event_handler, (void *)e);
    if (!ev->mh) {
        flux_log_error (h, "cron_event: flux_msg_handler_create");
        goto fail;
    }

    return (ev);
fail:
    cron_event_destroy (ev);
    return (NULL);
}
예제 #17
0
파일: jstatctl.c 프로젝트: trws/flux-core
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;
}
예제 #18
0
파일: req.c 프로젝트: cigolabs/flux-core
/* Reply to all queued requests.
 */
void flush_request_cb (flux_t h, flux_msg_handler_t *w,
                       const flux_msg_t *msg, void *arg)
{
    ctx_t *ctx = getctx (h);
    flux_msg_t *req;

    while ((req = zlist_pop (ctx->clog_requests))) {
        /* send clog response */
        if (flux_respond (h, req, 0, NULL) < 0)
            flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    }
    /* send flush response */
    if (flux_respond (h, msg, 0, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
}
예제 #19
0
파일: jstatctl.c 프로젝트: trws/flux-core
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;
}
예제 #20
0
/* check:
 * Runs right after reactor calls poll(2).
 * Stop idle watcher, and send next alloc request, if available.
 */
static void check_cb (flux_reactor_t *r, flux_watcher_t *w,
                      int revents, void *arg)
{
    struct alloc_ctx *ctx = arg;
    struct job *job;

    flux_watcher_stop (ctx->idle);
    if (!ctx->ready)
        return;
    if (ctx->mode == SCHED_SINGLE && ctx->active_alloc_count > 0)
        return;
    if ((job = queue_first (ctx->inqueue))) {
        if (alloc_request (ctx, job) < 0) {
            flux_log_error (ctx->h, "alloc_request fatal error");
            flux_reactor_stop_error (flux_get_reactor (ctx->h));
            return;
        }
        queue_delete (ctx->inqueue, job, job->aux_queue_handle);
        job->aux_queue_handle = NULL;
        job->alloc_pending = 1;
        job->alloc_queued = 0;
        ctx->active_alloc_count++;
        if ((job->flags & FLUX_JOB_DEBUG))
            (void)event_job_post_pack (ctx->event_ctx, job,
                                       "debug.alloc-request", NULL);

    }
}
예제 #21
0
static int extract_raw_rdl_alloc (flux_t h, int64_t j, JSON jcb)
{
    int i = 0;
    char *key;
    int64_t cores = 0;
    JSON ra = Jnew_ar ();
    bool processing = true;

    for (i=0; processing; ++i) {
        key = xasprintf ("lwj.%"PRId64".rank.%"PRId32".cores", j, i);
        if (kvs_get_int64 (h, key, &cores) < 0) {
            if (errno != EINVAL)
                flux_log_error (h, "extract %s", key);
            processing = false;
        } else {
            JSON elem = Jnew ();
            JSON 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);
    }
    json_object_object_add (jcb, JSC_RDL_ALLOC, ra);
    return 0;
}
예제 #22
0
static int update_rdl (flux_t h, int64_t j, const char *rs)
{
    int rc = -1;
    char *key = xasprintf ("lwj.%"PRId64".rdl", j);
    if (kvs_put_string (h, key, rs) < 0)
        flux_log_error (h, "update %s", key);
    else if (kvs_commit (h) < 0)
        flux_log_error (h, "commit failed");
    else {
        flux_log (h, LOG_DEBUG, "job (%"PRId64") assigned new rdl.", j);
        rc = 0;
    }
    free (key);

    return rc;
}
예제 #23
0
파일: plugin.c 프로젝트: tpatki/flux-sched
static void rmmod_cb (flux_t *h, flux_msg_handler_t *w,
                      const flux_msg_t *msg, void *arg)
{
    struct sched_plugin_loader *sploader = arg;
    struct sched_plugin *plugin = sched_plugin_get (sploader);
    const char *json_str;
    char *name = NULL;
    int rc = -1;

    if (flux_request_decode (msg, NULL, &json_str) < 0)
        goto done;
    if (flux_rmmod_json_decode (json_str, &name) < 0)
        goto done;
    if (!plugin || strcmp (name, plugin->name) != 0) {
        errno = ENOENT;
        goto done;
    }
    sched_plugin_unload (sploader);
    flux_log (h, LOG_INFO, "%s unloaded", name);
    rc = 0;
done:
    if (flux_respond (h, msg, rc < 0 ? errno : 0, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    if (name)
        free (name);
}
예제 #24
0
int mod_main (flux_t *h, int argc, char **argv)
{
    int saved_errno;
    flux_msg_handler_t **handlers = NULL;

    if (argc == 1 && !strcmp (argv[0], "--init-failure")) {
        flux_log (h, LOG_INFO, "aborting during init per test request");
        errno = EIO;
        goto error;
    }
    if (!(modules = zhash_new ())) {
        errno = ENOMEM;
        goto error;
    }
    if (flux_get_rank (h, &rank) < 0)
        goto error;
    if (flux_msg_handler_addvec (h, htab, NULL, &handlers) < 0)
        goto error;
    if (flux_reactor_run (flux_get_reactor (h), 0) < 0) {
        flux_log_error (h, "flux_reactor_run");
        goto error;
    }
    zhash_destroy (&modules);
    return 0;
error:
    saved_errno = errno;
    flux_msg_handler_delvec (handlers);
    zhash_destroy (&modules);
    errno = saved_errno;
    return -1;
}
예제 #25
0
static void lsmod_request_cb (flux_t *h, flux_msg_handler_t *mh,
                              const flux_msg_t *msg, void *arg)
{
    json_t *mods = NULL;

    if (flux_request_decode (msg, NULL, NULL) < 0)
        goto error;
    mods = module_list ();
    if (flux_respond_pack (h, msg, "{s:O}", "mods", mods) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    json_decref (mods);
    return;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
}
예제 #26
0
파일: job.c 프로젝트: cigolabs/flux-core
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;
}
예제 #27
0
/* Handle a sched.free response.
 */
static void free_response_cb (flux_t *h, flux_msg_handler_t *mh,
                              const flux_msg_t *msg, void *arg)
{
    struct alloc_ctx *ctx = arg;
    flux_jobid_t id = 0;
    struct job *job;

    if (flux_response_decode (msg, NULL, NULL) < 0)
        goto teardown;
    if (flux_msg_unpack (msg, "{s:I}", "id", &id) < 0)
        goto teardown;
    if (!(job = queue_lookup_by_id (ctx->queue, id))) {
        flux_log_error (h, "sched.free-response: id=%llu not active",
                        (unsigned long long)id);
        goto teardown;
    }
    if (!job->has_resources) {
        flux_log (h, LOG_ERR, "sched.free-response: id=%lld not allocated",
                  (unsigned long long)id);
        errno = EINVAL;
        goto teardown;
    }
    job->free_pending = 0;
    if (event_job_post_pack (ctx->event_ctx, job, "free", NULL) < 0)
        goto teardown;
    return;
teardown:
    interface_teardown (ctx, "free response error", errno);
}
예제 #28
0
파일: jstatctl.c 프로젝트: trws/flux-core
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;
}
예제 #29
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);
}
예제 #30
0
/* Initiate teardown.  Clear any alloc/free requests, and clear
 * the alloc->ready flag to stop prep/check from allocating.
 */
static void interface_teardown (struct alloc_ctx *ctx, char *s, int errnum)
{
    if (ctx->ready) {
        struct job *job;

        flux_log (ctx->h, LOG_DEBUG, "alloc: stop due to %s: %s",
                  s, flux_strerror (errnum));

        job = queue_first (ctx->queue);
        while (job) {
            /* jobs with alloc pending need to go back in the queue
             * so they will automatically send alloc again.
             */
            if (job->alloc_pending) {
                assert (job->aux_queue_handle == NULL);
                if (queue_insert (ctx->inqueue, job,
                                                &job->aux_queue_handle) < 0)
                    flux_log_error (ctx->h, "%s: queue_insert", __FUNCTION__);
                job->alloc_pending = 0;
                job->alloc_queued = 1;
            }
            /* jobs with free pending (much smaller window for this to be true)
             * need to be picked up again after 'hello'.
             */
            job->free_pending = 0;
            job = queue_next (ctx->queue);
        }
        ctx->ready = false;
        ctx->active_alloc_count = 0;
    }
}