static void fixup_newjob_event (flux_t *h, int64_t nj) { json_object *ss = NULL; json_object *jcb = NULL; int64_t js = J_NULL; char *key = xasprintf ("%"PRId64, nj); jscctx_t *ctx = getctx (h); /* We fix up ordering problem only when new job event hasn't been reported through a kvs watch */ jcb = Jnew (); ss = Jnew (); Jadd_int64 (jcb, JSC_JOBID, nj); Jadd_int64 (ss, JSC_STATE_PAIR_OSTATE , (int64_t) js); Jadd_int64 (ss, JSC_STATE_PAIR_NSTATE, (int64_t) js); json_object_object_add (jcb, JSC_STATE_PAIR, ss); if (zhash_insert (ctx->active_jobs, key, (void *)(intptr_t)js) < 0) { flux_log (h, LOG_ERR, "new_job_cb: inserting a job to hash failed"); goto done; } if (invoke_cbs (h, nj, jcb, 0) < 0) { flux_log (h, LOG_ERR, "makeup_newjob_event: failed to invoke callbacks"); goto done; } done: Jput (jcb); free (key); return; }
void send_ping (struct ping_ctx *ctx) { struct timespec t0; json_object *in = Jnew (); flux_rpc_t *rpc; struct ping_data *pdata = xzmalloc (sizeof (*pdata)); pdata->tstat = xzmalloc (sizeof (*(pdata->tstat))); pdata->seq = 0; pdata->route = NULL; pdata->rpc_count = 0; Jadd_int (in, "seq", ctx->send_count); monotime (&t0); Jadd_int64 (in, "time.tv_sec", t0.tv_sec); Jadd_int64 (in, "time.tv_nsec", t0.tv_nsec); Jadd_str (in, "pad", ctx->pad); if (ctx->rank) rpc = flux_rpc_multi (ctx->h, ctx->topic, Jtostr (in), ctx->rank, 0); else rpc = flux_rpc (ctx->h, ctx->topic, Jtostr (in), ctx->nodeid, 0); if (!rpc) log_err_exit ("flux_rpc"); flux_rpc_aux_set (rpc, pdata, ping_data_free); if (flux_rpc_then (rpc, ping_continuation, ctx) < 0) log_err_exit ("flux_rpc_then"); Jput (in); ctx->send_count++; }
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; }
static json_object *build_parray_elem (int64_t pid, int64_t eix, int64_t hix) { json_object *po = Jnew (); Jadd_int64 (po, JSC_PDESC_RANK_PDARRAY_PID, pid); Jadd_int64 (po, JSC_PDESC_RANK_PDARRAY_EINDX, eix); Jadd_int64 (po, JSC_PDESC_RANK_PDARRAY_HINDX, hix); return po; }
static int new_job_cb (const char *key, int64_t val, void *arg, int errnum) { int64_t nj = 0; int64_t js = 0; JSON ss = NULL; JSON jcb = NULL; char k[20] = {'\0'}; char path[20] = {'\0'}; flux_t h = (flux_t) arg; jscctx_t *ctx = getctx (h); if (ctx->first_time == 1) { /* watch is invoked immediately and we shouldn't * rely on that event at all. */ ctx->first_time = 0; return 0; } if (chk_errnum (h, errnum) < 0) return 0; flux_log (h, LOG_DEBUG, "new_job_cb invoked: key(%s), val(%ld)", key, val); js = J_NULL; nj = val-1; snprintf (k, 20, "%ld", nj); snprintf (path, 20, "lwj.%ld", nj); if (zhash_insert (ctx->active_jobs, k, (void *)(intptr_t)js) < 0) { flux_log (h, LOG_ERR, "new_job_cb: inserting a job to hash failed"); goto done; } flux_log (h, LOG_DEBUG, "jobstate_hdlr registered"); jcb = Jnew (); ss = Jnew (); Jadd_int64 (jcb, JSC_JOBID, nj); Jadd_int64 (ss, JSC_STATE_PAIR_OSTATE , (int64_t) js); Jadd_int64 (ss, JSC_STATE_PAIR_NSTATE, (int64_t) js); json_object_object_add (jcb, JSC_STATE_PAIR, ss); if (invoke_cbs (h, nj, jcb, errnum) < 0) { flux_log (h, LOG_ERR, "new_job_cb: failed to invoke callbacks"); } if (reg_jobstate_hdlr (h, path, job_state_cb) == -1) { flux_log (h, LOG_ERR, "new_job_cb: reg_jobstate_hdlr: %s", strerror (errno)); } done: /* always return 0 so that reactor won't return */ return 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; }
static int query_rdesc (flux_t h, int64_t j, JSON *jcb) { JSON o = NULL; int64_t nnodes = -1; int64_t ntasks = -1; if (extract_raw_nnodes (h, j, &nnodes) < 0) return -1; if (extract_raw_ntasks (h, j, &ntasks) < 0) return -1; *jcb = Jnew (); o = Jnew (); Jadd_int64 (o, JSC_RDESC_NNODES, nnodes); Jadd_int64 (o, JSC_RDESC_NTASKS, ntasks); json_object_object_add (*jcb, JSC_RDESC, o); return 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; }
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; }
static int extract_raw_rdl_alloc (flux_t h, int64_t j, JSON jcb) { int i = 0; char k[20]; int64_t cores = 0; JSON ra = Jnew_ar (); bool processing = true; for (i=0; processing; ++i) { snprintf (k, 20, "lwj.%ld.rank.%d.cores", j, i); if (kvs_get_int64 (h, k, &cores) < 0) { if (errno != EINVAL) flux_log (h, LOG_ERR, "extract %s: %s", k, strerror (errno)); 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); } } json_object_object_add (jcb, JSC_RDL_ALLOC, ra); return 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); }
static int query_pdesc (flux_t *h, int64_t j, json_object **jcb) { int64_t ntasks = 0; if (extract_raw_ntasks (h, j, &ntasks) < 0) return -1; *jcb = Jnew (); Jadd_int64 (*jcb, JSC_PDESC_SIZE, ntasks); return extract_raw_pdescs (h, j, ntasks, *jcb); }
static int query_state_pair (flux_t *h, int64_t j, json_object **jcb) { json_object *o = NULL; int64_t st = (int64_t)J_FOR_RENT;; if (extract_raw_state (h, j, &st) < 0) return -1; *jcb = Jnew (); o = Jnew (); /* Old state is unavailable through the query. * One should use notification service instead. */ Jadd_int64 (o, JSC_STATE_PAIR_OSTATE, st); Jadd_int64 (o, JSC_STATE_PAIR_NSTATE, st); json_object_object_add (*jcb, JSC_STATE_PAIR, o); return 0; }
static int update_1pdesc (flux_t h, int r, int64_t j, JSON o, JSON ha, JSON ea) { int rc = -1; JSON d = NULL; char *key; char *json_str = NULL; 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 = xasprintf ("lwj.%"PRId64".%"PRId32".procdesc", j, r); if (kvs_get (h, key, &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 (kvs_put (h, key, Jtostr (d)) < 0) { flux_log_error (h, "put %s", key); goto done; } rc = 0; done: free (key); if (d) Jput (d); if (json_str) free (json_str); return rc; }
static int query_rdesc (flux_t *h, int64_t j, json_object **jcb) { json_object *o = NULL; int64_t nnodes = -1; int64_t ntasks = -1; int64_t walltime = -1; if (extract_raw_nnodes (h, j, &nnodes) < 0) return -1; if (extract_raw_ntasks (h, j, &ntasks) < 0) return -1; if (extract_raw_walltime (h, j, &walltime) < 0) return -1; *jcb = Jnew (); o = Jnew (); Jadd_int64 (o, JSC_RDESC_NNODES, nnodes); Jadd_int64 (o, JSC_RDESC_NTASKS, ntasks); Jadd_int64 (o, JSC_RDESC_WALLTIME, walltime); json_object_object_add (*jcb, JSC_RDESC, o); return 0; }
static int query_jobid (flux_t *h, int64_t j, json_object **jcb) { int rc = 0; if ( ( rc = jobid_exist (h, j)) != 0) *jcb = NULL; else { *jcb = Jnew (); Jadd_int64 (*jcb, JSC_JOBID, j); } return rc; }
static json_object *get_update_jcb (flux_t *h, int64_t j, const char *val) { json_object *o = NULL; json_object *ss = NULL; jscctx_t *ctx = getctx (h); int64_t ostate = (int64_t) J_FOR_RENT; int64_t nstate = (int64_t) J_FOR_RENT; nstate = jsc_job_state2num (val); if ( (ostate = fetch_and_update_state (ctx->active_jobs, j, nstate)) < 0) { flux_log (h, LOG_INFO, "%"PRId64"'s old state unavailable", j); ostate = nstate; } o = Jnew (); ss = Jnew (); Jadd_int64 (o, JSC_JOBID, j); Jadd_int64 (ss, JSC_STATE_PAIR_OSTATE , (int64_t) ostate); Jadd_int64 (ss, JSC_STATE_PAIR_NSTATE, (int64_t) nstate); json_object_object_add (o, JSC_STATE_PAIR, ss); return o; }
static int update_1pdesc (flux_t h, int r, int64_t j, JSON o, JSON ha, JSON ea) { int rc = -1; JSON d = NULL; char key[20] = {'\0'};; 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; snprintf (key, 20, "lwj.%ld.%d.procdesc", j, r); if (kvs_get_obj (h, key, &d) < 0) { flux_log (h, LOG_ERR, "extract %s: %s", key, strerror (errno)); 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 (kvs_put_obj (h, key, d) < 0) { flux_log (h, LOG_ERR, "put %s: %s", key, strerror (errno)); goto done; } rc = 0; done: if (d) Jput (d); return rc; }
// Given the kvs dir of a job, change the state of the job and // timestamp the change static int update_job_state (ctx_t *ctx, int64_t jobid, flux_kvsdir_t *kvs_dir, job_state_t new_state, double update_time) { int rc; double t_starting = SIM_TIME_NONE; double t_running = SIM_TIME_NONE; double t_completing = SIM_TIME_NONE; double t_complete = SIM_TIME_NONE; switch (new_state) { case J_STARTING: t_starting = update_time; break; case J_RUNNING: t_running = update_time; break; case J_COMPLETING: t_completing = update_time; break; case J_COMPLETE: t_complete = update_time; break; default: flux_log (ctx->h, LOG_ERR, "Unknown state %d", (int) new_state); return -1; } json_t *jcb = Jnew (); json_t *o = Jnew (); Jadd_int64 (o, JSC_STATE_PAIR_NSTATE, (int64_t) new_state); Jadd_obj (jcb, JSC_STATE_PAIR, o); jsc_update_jcb(ctx->h, jobid, JSC_STATE_PAIR, Jtostr (jcb)); rc = set_job_timestamps (kvs_dir, t_starting, t_running, t_completing, t_complete, SIM_TIME_NONE); // io if (rc < 0) flux_log_error (ctx->h, "%s: set_job_timestamps", __FUNCTION__); Jput (jcb); Jput (o); return rc; }
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); }
static int test_a_resrc (resrc_t *resrc, bool rdl) { int found = 0; int rc = 0; int64_t nowtime = epochtime (); JSON o = NULL; JSON req_res = NULL; resrc_reqst_t *resrc_reqst = NULL; resrc_tree_t *deserialized_tree = NULL; resrc_tree_t *found_tree = NULL; resrc_tree_t *resrc_tree = NULL; resrc_tree_t *selected_tree = NULL; resrc_tree = resrc_phys_tree (resrc); ok ((resrc_tree != NULL), "resource tree valid"); if (!resrc_tree) goto ret; if (verbose) { printf ("Listing resource tree\n"); resrc_tree_print (resrc_tree); printf ("End of resource tree\n"); } /* * Build a resource composite to search for. Two variants are * constructed depending on whether the loaded resources came * from the sample RDL file or from the hwloc. The hwloc request * does not span multiple nodes or contain the localid property. */ req_res = Jnew (); if (rdl) { JSON bandwidth = Jnew (); JSON child_core = Jnew (); JSON child_sock = Jnew (); JSON graph_array = Jnew_ar (); JSON ja = Jnew_ar (); JSON jpropo = Jnew (); /* json property object */ JSON memory = Jnew (); JSON power = Jnew (); /* JSON jtago = Jnew (); /\* json tag object *\/ */ /* Jadd_bool (jtago, "maytag", true); */ /* Jadd_bool (jtago, "yourtag", true); */ Jadd_str (memory, "type", "memory"); Jadd_int (memory, "req_qty", 1); Jadd_int (memory, "size", 100); json_object_array_add (ja, memory); Jadd_str (child_core, "type", "core"); Jadd_int (child_core, "req_qty", 6); Jadd_bool (child_core, "exclusive", true); Jadd_int (jpropo, "localid", 1); json_object_object_add (child_core, "properties", jpropo); json_object_array_add (ja, child_core); Jadd_str (child_sock, "type", "socket"); Jadd_int (child_sock, "req_qty", 2); json_object_object_add (child_sock, "req_children", ja); Jadd_str (bandwidth, "type", "bandwidth"); Jadd_int (bandwidth, "size", 100); json_object_array_add (graph_array, bandwidth); Jadd_str (power, "type", "power"); Jadd_int (power, "size", 10); json_object_array_add (graph_array, power); Jadd_str (req_res, "type", "node"); Jadd_int (req_res, "req_qty", 2); Jadd_int64 (req_res, "starttime", nowtime); /* json_object_object_add (req_res, "tags", jtago); */ json_object_object_add (req_res, "req_child", child_sock); json_object_object_add (req_res, "graphs", graph_array); } else { Jadd_str (req_res, "type", "core"); Jadd_int (req_res, "req_qty", 2); Jadd_bool (req_res, "exclusive", true); } resrc_reqst = resrc_reqst_from_json (req_res, NULL); Jput (req_res); ok ((resrc_reqst != NULL), "resource request valid"); if (!resrc_reqst) goto ret; if (verbose) { printf ("Listing resource request tree\n"); resrc_reqst_print (resrc_reqst); printf ("End of resource request tree\n"); } init_time (); found = resrc_tree_search (resrc, resrc_reqst, &found_tree, true); ok (found, "found %d requested resources in %lf", found, ((double)get_time ())/1000000); if (!found) goto ret; if (verbose) { printf ("Listing found tree\n"); resrc_tree_print (found_tree); printf ("End of found tree\n"); } o = Jnew (); init_time (); rc = resrc_tree_serialize (o, found_tree); ok (!rc, "found resource serialization took: %lf", ((double)get_time ())/1000000); if (verbose) { printf ("The found resources serialized: %s\n", Jtostr (o)); } deserialized_tree = resrc_tree_deserialize (o, NULL); if (verbose) { printf ("Listing deserialized tree\n"); resrc_tree_print (deserialized_tree); printf ("End of deserialized tree\n"); } Jput (o); init_time (); /* * Exercise time-based allocations for the rdl case and * now-based allocations for the hwloc case */ selected_tree = test_select_resources (found_tree, NULL, 1); if (rdl) rc = resrc_tree_allocate (selected_tree, 1, nowtime, nowtime + 3600); else rc = resrc_tree_allocate (selected_tree, 1, 0, 0); ok (!rc, "successfully allocated resources for job 1"); resrc_tree_destroy (selected_tree, false); resrc_tree_unstage_resources (found_tree); selected_tree = test_select_resources (found_tree, NULL, 2); if (rdl) rc = resrc_tree_allocate (selected_tree, 2, nowtime, nowtime + 3600); else rc = resrc_tree_allocate (selected_tree, 2, 0, 0); ok (!rc, "successfully allocated resources for job 2"); resrc_tree_destroy (selected_tree, false); resrc_tree_unstage_resources (found_tree); selected_tree = test_select_resources (found_tree, NULL, 3); if (rdl) rc = resrc_tree_allocate (selected_tree, 3, nowtime, nowtime + 3600); else rc = resrc_tree_allocate (selected_tree, 3, 0, 0); ok (!rc, "successfully allocated resources for job 3"); resrc_tree_destroy (selected_tree, false); resrc_tree_unstage_resources (found_tree); selected_tree = test_select_resources (found_tree, NULL, 4); if (rdl) rc = resrc_tree_reserve (selected_tree, 4, nowtime, nowtime + 3600); else rc = resrc_tree_reserve (selected_tree, 4, 0, 0); ok (!rc, "successfully reserved resources for job 4"); resrc_tree_destroy (selected_tree, false); resrc_tree_unstage_resources (found_tree); printf (" allocate and reserve took: %lf\n", ((double)get_time ())/1000000); if (verbose) { printf ("Allocated and reserved resources\n"); resrc_tree_print (resrc_tree); } init_time (); rc = resrc_tree_release (found_tree, 1); ok (!rc, "resource release of job 1 took: %lf", ((double)get_time ())/1000000); if (verbose) { printf ("Same resources without job 1\n"); resrc_tree_print (resrc_tree); } init_time (); resrc_reqst_destroy (resrc_reqst); resrc_tree_destroy (deserialized_tree, true); resrc_tree_destroy (found_tree, false); printf (" destroy took: %lf\n", ((double)get_time ())/1000000); ret: return rc; }
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; }
int getrusage_json (int who, json_object **op) { struct rusage ru; json_object *o; if (getrusage (who, &ru) < 0) return -1; o = Jnew (); Jadd_double (o, "utime", (double)ru.ru_utime.tv_sec + 1E-6 * ru.ru_utime.tv_usec); Jadd_double (o, "stime", (double)ru.ru_stime.tv_sec + 1E-6 * ru.ru_stime.tv_usec); Jadd_int64 (o, "maxrss", ru.ru_maxrss); Jadd_int64 (o, "ixrss", ru.ru_ixrss); Jadd_int64 (o, "idrss", ru.ru_idrss); Jadd_int64 (o, "isrss", ru.ru_isrss); Jadd_int64 (o, "minflt", ru.ru_minflt); Jadd_int64 (o, "majflt", ru.ru_majflt); Jadd_int64 (o, "nswap", ru.ru_nswap); Jadd_int64 (o, "inblock", ru.ru_inblock); Jadd_int64 (o, "oublock", ru.ru_oublock); Jadd_int64 (o, "msgsnd", ru.ru_msgsnd); Jadd_int64 (o, "msgrcv", ru.ru_msgrcv); Jadd_int64 (o, "nsignals", ru.ru_nsignals); Jadd_int64 (o, "nvcsw", ru.ru_nvcsw); Jadd_int64 (o, "nivcsw", ru.ru_nivcsw); *op = o; return 0; }