/* 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__); }
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__); }
int main (int argc, char *argv[]) { flux_t *h; flux_msg_t *msg; const char *topic; const char *reason; int flags; plan (NO_PLAN); if (!(h = loopback_create (0))) BAIL_OUT ("loopback_create failed"); /* Send request */ ok (flux_panic (h, 0, 0, "fubar") == 0, "flux_panic works"); /* Receive request on the loopback */ msg = flux_recv (h, FLUX_MATCH_ANY, 0); ok (msg != NULL, "flux_recv received message on loop"); ok (flux_request_unpack (msg, &topic, "{s:s s:i}", "reason", &reason, "flags", &flags) == 0, "flux_request_unpack worked on panic request"); ok (topic != NULL && !strcmp (topic, "cmb.panic"), "topic string is correct"); ok (!strcmp (reason, "fubar"), "reason is correct"); ok (flags == 0, "flags is correct"); flux_msg_destroy (msg); /* invalid arguments */ errno = 0; ok (flux_panic (NULL, 0, 0, "foo") < 0 && errno == EINVAL, "flux_panic h=NULL fails with EINVAL"); errno = 0; ok (flux_panic (h, 0, 1, "foo") < 0 && errno == EINVAL, "flux_panic flags=1 fails with EINVAL"); errno = 0; ok (flux_panic (h, 0, 0, NULL) < 0 && errno == EINVAL, "flux_panic reason=NULL fails with EINVAL"); flux_close (h); done_testing(); return (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__); }
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__); }
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); }
void pub_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { struct publisher *pub = arg; const char *topic; const char *payload = NULL; // optional int flags; uint32_t rolemask, userid; flux_msg_t *event = NULL; if (flux_request_unpack (msg, NULL, "{s:s s:i s?:s}", "topic", &topic, "flags", &flags, "payload", &payload) < 0) goto error; if ((flags & ~(FLUX_MSGFLAG_PRIVATE)) != 0) { errno = EPROTO; goto error; } if (flux_msg_get_rolemask (msg, &rolemask) < 0) goto error; if (flux_msg_get_userid (msg, &userid) < 0) goto error; if (!(event = encode_event (topic, flags, rolemask, userid, ++pub->seq, payload))) goto error_restore_seq; send_event (pub, event); if (flux_respond_pack (h, msg, "{s:i}", "seq", pub->seq) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); flux_msg_destroy (event); return; error_restore_seq: pub->seq--; error: if (flux_respond (h, msg, errno, NULL) < 0) flux_log_error (h, "%s: flux_respond", __FUNCTION__); flux_msg_destroy (event); }
static void dump_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *reason; if (flux_request_unpack (msg, NULL, "{s:s}", "reason", &reason) < 0) goto error; #if WITH_TCMALLOC if (!IsHeapProfilerRunning ()) { errno = EINVAL; goto error; } HeapProfilerDump (reason); #else errno = ENOSYS; goto error; #endif if (flux_respond (h, msg, 0, NULL) < 0) FLUX_LOG_ERROR (h); return; error: if (flux_respond (h, msg, errno, NULL) < 0) FLUX_LOG_ERROR (h); }
static void start_cb (flux_t *h, flux_msg_handler_t *mh, const flux_msg_t *msg, void *arg) { const char *filename; if (flux_request_unpack (msg, NULL, "{s:s}", "filename", &filename) < 0) goto error; #if WITH_TCMALLOC if (IsHeapProfilerRunning ()) { errno = EINVAL; goto error; } HeapProfilerStart (filename); #else errno = ENOSYS; goto error; #endif if (flux_respond (h, msg, 0, NULL) < 0) FLUX_LOG_ERROR (h); return; error: if (flux_respond (h, msg, errno, NULL) < 0) FLUX_LOG_ERROR (h); }
int main (int argc, char *argv[]) { flux_msg_t *msg; const char *topic, *s; const char *json_str = "{\"a\":42}"; const void *d; const char data[] = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"; int i, l, len = strlen (data); plan (NO_PLAN); /* no topic is an error */ errno = 0; ok ((msg = flux_request_encode (NULL, json_str)) == NULL && errno == EINVAL, "flux_request_encode returns EINVAL with no topic string"); ok ((msg = flux_request_encode_raw (NULL, data, strlen (data))) == NULL && errno == EINVAL, "flux_request_encode_raw returns EINVAL with no topic string"); /* without payload */ ok ((msg = flux_request_encode ("foo.bar", NULL)) != NULL, "flux_request_encode works with NULL payload"); topic = NULL; ok (flux_request_decode (msg, &topic, NULL) == 0 && topic != NULL && !strcmp (topic, "foo.bar"), "flux_request_decode returns encoded topic"); ok (flux_request_decode (msg, NULL, NULL) == 0, "flux_request_decode topic is optional"); errno = 0; ok (flux_request_decode (msg, NULL, &s) == 0 && s == NULL, "flux_request_decode returns s = NULL when expected payload is missing"); flux_msg_destroy(msg); /* with JSON payload */ ok ((msg = flux_request_encode ("foo.bar", json_str)) != NULL, "flux_request_encode works with payload"); s = NULL; ok (flux_request_decode (msg, NULL, &s) == 0 && s != NULL && !strcmp (s, json_str), "flux_request_decode returns encoded payload"); topic = NULL; i = 0; ok (flux_request_unpack (msg, &topic, "{s:i}", "a", &i) == 0 && i == 42 && topic != NULL && !strcmp (topic, "foo.bar"), "flux_request_unpack returns encoded payload"); errno = 0; ok (flux_request_decode (msg, NULL, NULL) == 0, "flux_request_decode works with payload but don't want the payload"); flux_msg_destroy(msg); /* without payload (raw) */ ok ((msg = flux_request_encode_raw ("foo.bar", NULL, 0)) != NULL, "flux_request_encode_raw works with NULL payload"); topic = NULL; ok (flux_request_decode_raw (msg, &topic, &d, &l) == 0 && topic != NULL && !strcmp (topic, "foo.bar"), "flux_request_decode_raw returns encoded topic"); ok (flux_request_decode_raw (msg, NULL, &d, &l) == 0, "flux_request_decode_raw topic is optional"); d = (char *)&d; l = 1; ok (flux_request_decode_raw (msg, NULL, &d, &l) == 0 && l == 0 && d == NULL, "flux_request_decode_raw returned NULL payload"); flux_msg_destroy(msg); /* with raw payload */ ok ((msg = flux_request_encode_raw ("foo.bar", data, len)) != NULL, "flux_request_encode_raw works with payload"); d = NULL; l = 0; ok (flux_request_decode_raw (msg, NULL, &d, &l) == 0 && d != NULL && l == len && memcmp (d, data, len) == 0, "flux_request_decode_raw returns encoded payload"); flux_msg_destroy(msg); done_testing(); return (0); }