Esempio n. 1
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__);
}
Esempio n. 2
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__);
}
Esempio n. 3
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__);
}
Esempio n. 4
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);
}
Esempio n. 5
0
/* sched-hello:
 * Scheduler obtains a list of jobs that have resources allocated.
 */
static void hello_cb (flux_t *h, flux_msg_handler_t *mh,
                      const flux_msg_t *msg, void *arg)
{
    struct alloc_ctx *ctx = arg;
    struct job *job;
    json_t *o = NULL;
    json_t *jobid;

    if (flux_request_decode (msg, NULL, NULL) < 0)
        goto error;
    flux_log (h, LOG_DEBUG, "scheduler: hello");
    if (!(o = json_array ()))
        goto nomem;
    job = queue_first (ctx->queue);
    while (job) {
        if (job->has_resources) {
            if (!(jobid = json_integer (job->id)))
                goto nomem;
            if (json_array_append_new (o, jobid) < 0) {
                json_decref (jobid);
                goto nomem;
            }
        }
        job = queue_next (ctx->queue);
    }
    if (flux_respond_pack (h, msg, "{s:O}", "alloc", o) < 0)
        flux_log_error (h, "%s: flux_respond_pack", __FUNCTION__);
    /* Restart any free requests that might have been interrupted
     * when scheduler was last unloaded.
     */
    job = queue_first (ctx->queue);
    while (job) {
        if (event_job_action (ctx->event_ctx, job) < 0)
            flux_log_error (h, "%s: event_job_action", __FUNCTION__);
        job = queue_next (ctx->queue);
    }
    json_decref (o);
    return;
nomem:
    errno = ENOMEM;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
    json_decref (o);
}
Esempio n. 6
0
static void rmmod_request_cb (flux_t *h, flux_msg_handler_t *mh,
                              const flux_msg_t *msg, void *arg)
{
    const char *name;

    if (flux_request_unpack (msg, NULL, "{s:s}", "name", &name) < 0)
        goto error;
    if (!zhash_lookup (modules, name)) {
        errno = ENOENT;
        goto error;
    }
    zhash_delete (modules, name);
    flux_log (h, LOG_DEBUG, "rmmod %s", name);
    if (flux_respond (h, msg, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    return;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
}
Esempio n. 7
0
void list_handle_request (flux_t *h, struct queue *queue,
                          const flux_msg_t *msg)
{
    int max_entries;
    json_t *jobs;
    json_t *attrs;

    if (flux_request_unpack (msg, NULL, "{s:i s:o}",
                                        "max_entries", &max_entries,
                                        "attrs", &attrs) < 0)
        goto error;
    if (!(jobs = list_job_array (queue, max_entries, attrs)))
        goto error;
    if (flux_respond_pack (h, msg, "{s:O}", "jobs", jobs) < 0)
        flux_log_error (h, "%s: flux_respond_pack", __FUNCTION__);
    json_decref (jobs);
    return;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
}
Esempio n. 8
0
static void ping_request_cb (flux_t *h, flux_msg_handler_t *mh,
                             const flux_msg_t *msg, void *arg)
{
    const char *json_str;
    char *route_str = NULL;
    char *full_route_str = NULL;
    char *resp_str = NULL;
    uint32_t rank, userid, rolemask;

    if (flux_request_decode (msg, NULL, &json_str) < 0)
        goto error;
    if (flux_msg_get_rolemask (msg, &rolemask) < 0)
        goto error;
    if (flux_msg_get_userid (msg, &userid) < 0)
        goto error;
    if (!(route_str = flux_msg_get_route_string (msg)))
        goto error;
    if (flux_get_rank (h, &rank) < 0)
        goto error;
    if (asprintf (&full_route_str, "%s!%u", route_str, rank) < 0) {
        errno = ENOMEM;
        goto error;
    }
    if (!(resp_str = make_json_response_payload (json_str, full_route_str,
                                                 userid, rolemask))) {
        goto error;
    }
    if (flux_respond (h, msg, resp_str) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    free (route_str);
    free (full_route_str);
    free (resp_str);
    return;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
    free (route_str);
    free (full_route_str);
    free (resp_str);
}
Esempio n. 9
0
static void insmod_request_cb (flux_t *h, flux_msg_handler_t *mh,
                               const flux_msg_t *msg, void *arg)
{
    const char *path;
    json_t *args;
    size_t index;
    json_t *value;
    char *argz = NULL;
    size_t argz_len = 0;
    module_t *m = NULL;
    error_t e;

    if (flux_request_unpack (msg, NULL, "{s:s s:o}", "path", &path,
                                                     "args", &args) < 0)
        goto error;
    if (!json_is_array (args))
        goto proto;
    json_array_foreach (args, index, value) {
        if (!json_is_string (value))
            goto proto;
        if ((e = argz_add (&argz, &argz_len, json_string_value (value)))) {
            errno = e;
            goto error;
        }
    }
    if (!(m = module_create (path, argz, argz_len)))
        goto error;
    flux_log (h, LOG_DEBUG, "insmod %s", m->name);
    if (flux_respond (h, msg, NULL) < 0)
        flux_log_error (h, "%s: flux_respond", __FUNCTION__);
    free (argz);
    return;
proto:
    errno = EPROTO;
error:
    if (flux_respond_error (h, msg, errno, NULL) < 0)
        flux_log_error (h, "%s: flux_respond_error", __FUNCTION__);
    free (argz);
}
Esempio n. 10
0
void store_cb (flux_t *h, flux_msg_handler_t *mh,
               const flux_msg_t *msg, void *arg)
{
    sqlite_ctx_t *ctx = arg;
    const void *data;
    int size, hash_len;
    uint8_t hash[BLOBREF_MAX_DIGEST_SIZE];
    char blobref[BLOBREF_MAX_STRING_SIZE] = "-";
    int uncompressed_size = -1;
    int rc = -1;
    int old_state;
    //delay cancellation to ensure lock-correctness in sqlite
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);

    if (flux_request_decode_raw (msg, NULL, &data, &size) < 0) {
        flux_log_error (h, "store: request decode failed");
        goto done;
    }
    if (size > ctx->blob_size_limit) {
        errno = EFBIG;
        goto done;
    }
    if (blobref_hash (ctx->hashfun, (uint8_t *)data, size, blobref,
                      sizeof (blobref)) < 0)
        goto done;
    if ((hash_len = blobref_strtohash (blobref, hash, sizeof (hash))) < 0)
        goto done;
    if (size >= compression_threshold) {
        int r;
        int out_len = LZ4_compressBound(size);
        if (ctx->lzo_bufsize < out_len && grow_lzo_buf (ctx, out_len) < 0)
            goto done;
        r = LZ4_compress_default (data, ctx->lzo_buf, size, out_len);
        if (r == 0) {
            errno = EINVAL;
            goto done;
        }
        uncompressed_size = size;
        size = r;
        data = ctx->lzo_buf;
    }
    if (sqlite3_bind_text (ctx->store_stmt, 1, (char *)hash, hash_len,
                           SQLITE_STATIC) != SQLITE_OK) {
        log_sqlite_error (ctx, "store: binding key");
        set_errno_from_sqlite_error (ctx);
        goto done;
    }
    if (sqlite3_bind_int (ctx->store_stmt, 2, uncompressed_size) != SQLITE_OK) {
        log_sqlite_error (ctx, "store: binding size");
        set_errno_from_sqlite_error (ctx);
        goto done;
    }
    if (sqlite3_bind_blob (ctx->store_stmt, 3,
                           data, size, SQLITE_STATIC) != SQLITE_OK) {
        log_sqlite_error (ctx, "store: binding data");
        set_errno_from_sqlite_error (ctx);
        goto done;
    }
    if (sqlite3_step (ctx->store_stmt) != SQLITE_DONE
                    && sqlite3_errcode (ctx->db) != SQLITE_CONSTRAINT) {
        log_sqlite_error (ctx, "store: executing stmt");
        set_errno_from_sqlite_error (ctx);
        goto done;
    }
    rc = 0;
done:
    if (rc < 0) {
        if (flux_respond_error (h, msg, errno, NULL) < 0)
            flux_log_error (h, "store: flux_respond_error");
    }
    else {
        if (flux_respond_raw (h, msg, blobref, strlen (blobref) + 1) < 0)
            flux_log_error (h, "store: flux_respond_raw");
    }
    (void) sqlite3_reset (ctx->store_stmt);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
}
Esempio n. 11
0
void load_cb (flux_t *h, flux_msg_handler_t *mh,
              const flux_msg_t *msg, void *arg)
{
    sqlite_ctx_t *ctx = arg;
    const char *blobref = "-";
    int blobref_size;
    uint8_t hash[BLOBREF_MAX_DIGEST_SIZE];
    int hash_len;
    const void *data = NULL;
    int size = 0;
    int uncompressed_size;
    int rc = -1;
    int old_state;
    //delay cancellation to ensure lock-correctness in sqlite
    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);

    if (flux_request_decode_raw (msg, NULL, (const void **)&blobref,
                                 &blobref_size) < 0) {
        flux_log_error (h, "load: request decode failed");
        goto done;
    }
    if (!blobref || blobref[blobref_size - 1] != '\0') {
        errno = EPROTO;
        flux_log_error (h, "load: malformed blobref");
        goto done;
    }
    if ((hash_len = blobref_strtohash (blobref, hash, sizeof (hash))) < 0) {
        errno = ENOENT;
        flux_log_error (h, "load: unexpected foreign blobref");
        goto done;
    }
    if (sqlite3_bind_text (ctx->load_stmt, 1, (char *)hash, hash_len,
                                              SQLITE_STATIC) != SQLITE_OK) {
        log_sqlite_error (ctx, "load: binding key");
        set_errno_from_sqlite_error (ctx);
        goto done;
    }
    if (sqlite3_step (ctx->load_stmt) != SQLITE_ROW) {
        //log_sqlite_error (ctx, "load: executing stmt");
        errno = ENOENT;
        goto done;
    }
    size = sqlite3_column_bytes (ctx->load_stmt, 0);
    if (sqlite3_column_type (ctx->load_stmt, 0) != SQLITE_BLOB && size > 0) {
        flux_log (h, LOG_ERR, "load: selected value is not a blob");
        errno = EINVAL;
        goto done;
    }
    data = sqlite3_column_blob (ctx->load_stmt, 0);
    if (sqlite3_column_type (ctx->load_stmt, 1) != SQLITE_INTEGER) {
        flux_log (h, LOG_ERR, "load: selected value is not an integer");
        errno = EINVAL;
        goto done;
    }
    uncompressed_size = sqlite3_column_int (ctx->load_stmt, 1);
    if (uncompressed_size != -1) {
        if (ctx->lzo_bufsize < uncompressed_size
                                && grow_lzo_buf (ctx, uncompressed_size) < 0)
            goto done;
        int r = LZ4_decompress_safe (data, ctx->lzo_buf, size, uncompressed_size);
        if (r < 0) {
            errno = EINVAL;
            goto done;
        }
        if (r != uncompressed_size) {
            flux_log (h, LOG_ERR, "load: blob size mismatch");
            errno = EINVAL;
            goto done;
        }
        data = ctx->lzo_buf;
        size = uncompressed_size;
    }
    rc = 0;
done:
    if (rc < 0) {
        if (flux_respond_error (h, msg, errno, NULL) < 0)
            flux_log_error (h, "load: flux_respond_error");
    }
    else {
        if (flux_respond_raw (h, msg, data, size) < 0)
            flux_log_error (h, "load: flux_respond_raw");
    }
    (void )sqlite3_reset (ctx->load_stmt);
    pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);
}