/* joblist_display.c -- xce-test-cli-ux task 2.5 remediation (bug-1711 fixes) * * See joblist_display.h for the full rationale. Verbatim extraction of * test.c's worker_status_str()/job_state_str()/format_job_time() -- no * behavior change from the pre-extraction versions. */ #include "joblist_display.h" #include /* snprintf */ #include /* strcmp */ #include "xce/ctrlstatus_fmt.h" /* ctrlstatus_format_time_ms */ #include "xce/types.h" /* XCE_WORKER_*, JOB_STAT_* bit definitions */ char* worker_status_str(uint32_t status) { /* Admin-set CLOSED takes priority over the dynamic UNAVAIL bit: the * config-upgrade-snapshot soak (task 8.6) needs to assert a host's * administratively-set status specifically, and a host closed via * hostctrl that later disconnects (e.g. its xce_test `worker`/`join` * connection exits after the script ends) would otherwise print only * "UNAVAIL", masking the admin bit this check exists to verify. */ if ((status & XCE_WORKER_CLOSED) != 0) { return "CLOSED"; } else if ((status & XCE_WORKER_UNAVAIL) != 0) { return "UNAVAIL"; } else if ((status & XCE_WORKER_LOCKEDU) != 0) { return "LOCKU"; } else if ((status & XCE_WORKER_LOCKEDW) != 0) { return "LOCKW"; } else if ((status & XCE_WORKER_BUSY) != 0) { return "BUSY"; } else if (status == 0) { return "OK"; } return "UNKNOWN"; } char* job_state_str(int state) { /* bug-1711 (Requirement 11.7): raw-state fallback mirroring * print_jobinfo's existing state_raw guard against the same ambiguity * (see print_jobinfo's comment above its "state_raw: 0x%x" print) -- a * job that is simultaneously RUN and EXIT (e.g. a worker-reported FAIL * received without a prior FINISH; apply_job_fail_transition ORs in * EXIT|PERR without clearing RUN) would otherwise silently print as * plain "RUN" via the if/else-if priority ordering below, hiding the * EXIT bit. Unlike print_jobinfo (which always has room for a separate * state_raw line), job_state_str's result is a single cmd_joblist table * cell, so the raw state is folded into the same string only for this * specific ambiguous case. */ static char ambiguous_buf[32]; if ((state & JOB_STAT_PEND) != 0) { if ((state & JOB_STAT_PSUSP) != 0) { return "PSUSP"; } return "PEND"; } else if ((state & JOB_STAT_RUN) != 0) { if ((state & JOB_STAT_USUSP) != 0) { return "USUSP"; } else if ((state & JOB_STAT_SSUSP) != 0) { return "SSUSP"; } else if ((state & JOB_STAT_EXIT) != 0) { snprintf(ambiguous_buf, sizeof(ambiguous_buf), "RUN(0x%x)", state); return ambiguous_buf; } return "RUN"; } else if ((state & JOB_STAT_EXIT) != 0) { return "EXIT"; } else if ((state & JOB_STAT_DONE) != 0) { return "DONE"; } else if ((state & JOB_STAT_ERR) != 0) { return "ERROR"; } return "UNKNOWN"; } /* bug-1711 (Requirement 11.5): format a job time_t field (epoch seconds) using * ctrlstatus_fmt.h's ctrlstatus_format_time_ms human-readable formatter * (which takes epoch milliseconds), instead of printing the raw epoch-seconds * value directly as cmd_joblist did before. A job time of 0 means the * corresponding event has not happened yet (e.g. an unstarted job's * start_time/finish_time) -- print "-" rather than a misleading 1970-01-01 * epoch date. */ const char* format_job_time(time_t t, char* buf, size_t bufsize) { if (t == 0) { return "-"; } if (ctrlstatus_format_time_ms((uint64_t)t * 1000u, buf, bufsize) == NULL) { return "-"; } return buf; } double worker_effective_attr(const xce_worker_t* w, const char* resname, double attr_value) { if (w == NULL) { return attr_value; } for (int i = 0; i < w->nresvals_to_sched; i++) { const xce_name_val_t* nv = w->resvals_to_sched[i]; if ((nv == NULL) || (nv->name == NULL) || (nv->val == NULL) || (strcmp(nv->name, resname) != 0)) { continue; } switch (nv->val->which) { case Value_u_fvalue: return nv->val->u.fvalue; case Value_u_ivalue32: return (double)nv->val->u.ivalue32; case Value_u_uvalue32: return (double)nv->val->u.uvalue32; case Value_u_ivalue64: return (double)nv->val->u.ivalue64; case Value_u_uvalue64: return (double)nv->val->u.uvalue64; default: return attr_value; /* not numeric */ } } return attr_value; }