forked from lei.chen/myxce
merge job rusage and pending reason support
This commit is contained in:
parent
30824ae5ea
commit
cb0c7fe9e7
82 changed files with 4280 additions and 2561 deletions
|
|
@ -5,6 +5,7 @@
|
|||
#include <unistd.h>
|
||||
|
||||
#include "cluster.h"
|
||||
#include "dataq.h"
|
||||
#include "htab.h"
|
||||
#include "mylock.h"
|
||||
#include "request.h"
|
||||
|
|
@ -188,6 +189,12 @@ static int myreq_handler(vtask_t* task)
|
|||
case OPCode_runtasks:
|
||||
rc = do_runtasks(c, ep, &request);
|
||||
break;
|
||||
case OPCode_setpreason:
|
||||
rc = do_set_preason(c, ep, &request);
|
||||
break;
|
||||
case OPCode_clrpreason:
|
||||
rc = do_clr_preason(c, ep, &request);
|
||||
break;
|
||||
default:
|
||||
rc = -E_XCE_BAD_OPCODE;
|
||||
ERROR("Unknown opcode: %d", request.opcode);
|
||||
|
|
@ -447,6 +454,11 @@ static int xce_install_hooks(cluster_t* c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int run_delay_tasks(delay_task_entry_fn_t entry, void* arg)
|
||||
{
|
||||
return entry(arg);
|
||||
}
|
||||
|
||||
int cluster_init(cluster_t* c)
|
||||
{
|
||||
int i, rc;
|
||||
|
|
@ -524,12 +536,90 @@ int cluster_init(cluster_t* c)
|
|||
|
||||
vtaskmgr_init(&(c->vtaskmgr), c->myconf->cluster_config->vcpus);
|
||||
|
||||
delaymgr_init(&(c->delaymgr), 2, run_delay_tasks);
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_CLUSTER, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_CLUSTER_INIT, c);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_heartbeat(cluster_t* c, endpoint_t* ep)
|
||||
{
|
||||
return xce_nop_req(ep);
|
||||
}
|
||||
|
||||
static int check_worker_timeout_(void* arg1, void* arg2)
|
||||
{
|
||||
cluster_t* c = (cluster_t*)arg1;
|
||||
worker_t* w = (worker_t*)arg2;
|
||||
endpoint_t* ep;
|
||||
time_t now = time(NULL);
|
||||
int timeout;
|
||||
cluster_config_t* config;
|
||||
|
||||
if (w == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (c == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ep = w->ep;
|
||||
if (ep == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
config = c->myconf->cluster_config;
|
||||
timeout = config->heartbeat_interval * config->inactive_heartbeat_count;
|
||||
|
||||
if (now - ep->ts_last_in > timeout) {
|
||||
TRACE("%s worker %s becomes UNAVAIL as heartbeat timeout", __func__,
|
||||
w->host.name);
|
||||
|
||||
mark_worker_unavail(c, w);
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
if (IS_WORKER_UNAVAIL(w->host.status)) {
|
||||
mark_worker_back(c, w);
|
||||
}
|
||||
}
|
||||
|
||||
if (now - ep->ts_last_out >= config->heartbeat_interval) {
|
||||
if (DATAQ_EMPTY(&(ep->outq))) {
|
||||
int rc = 0;
|
||||
|
||||
TRACE("%s send heartbeat to %s", __func__, w->host.name);
|
||||
|
||||
rc = make_heartbeat(c, ep);
|
||||
|
||||
if (rc < 0) {
|
||||
ERROR("%s make_heartbeat to %s failed", __func__, w->host.name);
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check_workers_timeout(void* args)
|
||||
{
|
||||
xlist_t lst;
|
||||
int rc;
|
||||
cluster_t* c = (cluster_t*)args;
|
||||
|
||||
xlist_init(&lst, 3);
|
||||
xlist_store(&lst, check_worker_timeout_);
|
||||
rc = workermgr_iter(&(c->workermgr), &lst, c);
|
||||
|
||||
xlist_fini(&lst);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
int cluster_start(cluster_t* c)
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -546,6 +636,10 @@ int cluster_start(cluster_t* c)
|
|||
|
||||
iomgr_start(&(c->iomgr));
|
||||
vtaskmgr_start(&(c->vtaskmgr));
|
||||
delaymgr_start(&(c->delaymgr));
|
||||
|
||||
delay_task(&(c->delaymgr), c->myconf->cluster_config->heartbeat_interval,
|
||||
-1, (delay_task_entry_fn_t)check_workers_timeout, (void*)c);
|
||||
|
||||
c->running = 1;
|
||||
return 0;
|
||||
|
|
@ -565,6 +659,9 @@ int cluster_run(cluster_t* c)
|
|||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_CLUSTER, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_CLUSTER_SHUTDOWN, c);
|
||||
c->running = 0;
|
||||
|
||||
delaymgr_stop(&(c->delaymgr));
|
||||
|
||||
iomgr_unmonitor(&(c->iomgr), &(c->ep));
|
||||
iomgr_stop(&(c->iomgr));
|
||||
|
||||
|
|
@ -573,6 +670,7 @@ int cluster_run(cluster_t* c)
|
|||
|
||||
void cluster_fini(cluster_t* c)
|
||||
{
|
||||
delaymgr_fini(&(c->delaymgr));
|
||||
vtaskmgr_fini(&(c->vtaskmgr));
|
||||
endpoint_fini(&(c->ep));
|
||||
|
||||
|
|
|
|||
|
|
@ -98,6 +98,8 @@ extern int handle_reply(endpoint_t*, struct Request*, cluster_t*);
|
|||
extern int handle_jobdispatch(cluster_t*, endpoint_t*, xce_request_t*);
|
||||
extern int handle_jobsubmit(cluster_t*, endpoint_t*, xce_request_t*);
|
||||
extern int handle_worker_leave(cluster_t*, int);
|
||||
extern int mark_worker_unavail(cluster_t*, worker_t*);
|
||||
extern int mark_worker_back(cluster_t*, worker_t*);
|
||||
extern int handle_scheduler_leave(cluster_t*);
|
||||
extern int handle_clusterconf(cluster_t*, endpoint_t*, xce_request_t*);
|
||||
|
||||
|
|
@ -151,5 +153,7 @@ extern int xce_controller_res_init(cluster_t*);
|
|||
extern int map_resource_to_host(char*, cluster_t*);
|
||||
extern int release_resource_from_worker(char*, cluster_t*);
|
||||
extern int collect_resval_with_idx(zarray_t*, int*, xce_val_with_idx_t***);
|
||||
extern int do_set_preason(cluster_t*, endpoint_t*, xce_request_t*);
|
||||
extern int do_clr_preason(cluster_t*, endpoint_t*, xce_request_t*);
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <time.h>
|
||||
|
||||
#include "cluster.h"
|
||||
#include "preason.h"
|
||||
#include "xce/cluster_def.h"
|
||||
#include "xce/errnox.h"
|
||||
#include "xce/types.h"
|
||||
|
|
@ -457,7 +458,10 @@ int handle_jobsubmit(cluster_t* c, endpoint_t* ep, xce_request_t* request)
|
|||
/* Run hooks to tell scheduler */
|
||||
j = jobmgr_lockjob(&(c->jobmgr), jobid, OBJREF_READ);
|
||||
if (j == NULL) {
|
||||
ERROR("%s fail to lock job %lu", __func__, jobid);
|
||||
char idstring[128];
|
||||
|
||||
fmt_jobid(idstring, sizeof(idstring) - 1, jobid);
|
||||
ERROR("%s fail to lock job %s (%lu)", __func__, idstring, jobid);
|
||||
} else {
|
||||
xlist_init(&jlist, 2);
|
||||
if (xlist_store(&jlist, j) >= 0) {
|
||||
|
|
@ -777,6 +781,9 @@ int update_job_rusages(cluster_t* c, endpoint_t* ep, xce_request_t* request)
|
|||
|
||||
TRACE("%s trying to update job(%ld) rusage", __func__, rusages->jobid);
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_JOB, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_JOB_RUSAGE_UPDATE, c, rusages);
|
||||
|
||||
j = jobmgr_lockjob(&(c->jobmgr), rusages->jobid, OBJREF_UPDATE);
|
||||
if (j == NULL) {
|
||||
PERROR("jobmgr_lockjob");
|
||||
|
|
@ -815,5 +822,106 @@ int update_job_rusages(cluster_t* c, endpoint_t* ep, xce_request_t* request)
|
|||
HOOK_DETAIL_JOB_UPDATE, c, j);
|
||||
|
||||
obj_deref(j);
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_JOB, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_JOB_RUSAGE_UPDATE, c, rusages);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int set_preason(cluster_t* c, xce_pendreason_t* reasons)
|
||||
{
|
||||
job_t* j;
|
||||
xce_job_t* job;
|
||||
|
||||
TRACE("%s jobid %ld", __func__, reasons->jobid);
|
||||
|
||||
j = jobmgr_lockjob(&(c->jobmgr), reasons->jobid, OBJREF_UPDATE);
|
||||
if (j == NULL) {
|
||||
PERROR("jobmgr_lockjob");
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_JOB, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_SETPREASON, c, j);
|
||||
job = &(j->job);
|
||||
if (job->pend_reasons != NULL) {
|
||||
erase_job_preason(job->pend_reasons);
|
||||
FREEUP(job->pend_reasons);
|
||||
}
|
||||
|
||||
MOVE_PTR(job->pend_reasons, reasons->reasons);
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_JOB, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_SETPREASON, c, j);
|
||||
obj_deref(j);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_set_preason(cluster_t* c, endpoint_t* ep, xce_request_t* request)
|
||||
{
|
||||
int i;
|
||||
xce_preason_set_t* reasons = request->body.preasonmsg;
|
||||
xce_reply_t reply;
|
||||
|
||||
init_reply_by_req(&reply, request);
|
||||
reply.status = 0;
|
||||
reply.data_which = RequestReply_data_nodata;
|
||||
|
||||
xce_reply(ep, c->myhost, &reply);
|
||||
|
||||
for (i = 0; i < reasons->nreasons; i++) {
|
||||
int rc = 0;
|
||||
|
||||
if (reasons->reasons[i] == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rc = set_preason(c, reasons->reasons[i]);
|
||||
if (rc < 0) {
|
||||
PERROR("set_preason");
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_clr_preason(cluster_t* c, endpoint_t* ep, xce_request_t* request)
|
||||
{
|
||||
int i;
|
||||
xce_reply_t reply;
|
||||
xce_clear_reason_t* clreason = request->body.clrpreasonmsg;
|
||||
|
||||
init_reply_by_req(&reply, request);
|
||||
reply.status = 0;
|
||||
reply.data_which = RequestReply_data_nodata;
|
||||
|
||||
xce_reply(ep, c->myhost, &reply);
|
||||
|
||||
for (i = 0; i < clreason->njobs; i++) {
|
||||
uint64_t jobid = clreason->jobs[i];
|
||||
job_t* j;
|
||||
xce_job_t* job;
|
||||
|
||||
j = jobmgr_lockjob(&(c->jobmgr), jobid, OBJREF_UPDATE);
|
||||
if (j == NULL) {
|
||||
PERROR("jobmgr_lockjob");
|
||||
continue;
|
||||
}
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_JOB, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_CLRPREASON, c, j);
|
||||
|
||||
job = &(j->job);
|
||||
if (job->pend_reasons != NULL) {
|
||||
erase_job_preason(job->pend_reasons);
|
||||
FREEUP(job->pend_reasons);
|
||||
}
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_JOB, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_CLRPREASON, c, j);
|
||||
|
||||
obj_deref(j);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -143,10 +143,28 @@ static int do_reply_joblist(cluster_t* c, endpoint_t* ep,
|
|||
xce_data_t getdata = { .table = request->body.getmsg->table,
|
||||
.data = { .jobs = &jobdata } };
|
||||
int rc = 0;
|
||||
xce_match_t* match = request->body.getmsg->condition;
|
||||
|
||||
init_reply_by_req(&reply, request);
|
||||
collect_jobs(c, (collect_check_fn_t)check_job_, &(jobdata.n_total),
|
||||
&(jobdata.jobs));
|
||||
|
||||
if (match->type == MatchCondition_condition_matchjid) {
|
||||
job_t* j;
|
||||
|
||||
jobdata.n_total = 0;
|
||||
jobdata.jobs = NULL;
|
||||
|
||||
j = jobmgr_lockjob(&(c->jobmgr), match->condition.jobid, OBJREF_READ);
|
||||
if (j != NULL) {
|
||||
jobdata.jobs = (xce_job_t**)calloc(1, sizeof(xce_job_t*));
|
||||
if (jobdata.jobs != NULL) {
|
||||
jobdata.jobs[0] = &(j->job);
|
||||
jobdata.n_total = 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
collect_jobs(c, (collect_check_fn_t)check_job_, &(jobdata.n_total),
|
||||
&(jobdata.jobs));
|
||||
}
|
||||
|
||||
reply.status = 0;
|
||||
reply.data_which = RequestReply_data_getdata;
|
||||
|
|
|
|||
|
|
@ -314,6 +314,37 @@ static int sched_job_update_fun(int type, int situation, void* data, va_list ap)
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int sched_job_rusage_update_fun(int type, int situation, void* data,
|
||||
va_list ap)
|
||||
{
|
||||
cluster_t* c = va_arg(ap, cluster_t*);
|
||||
xce_job_rusages_t* rusages = va_arg(ap, xce_job_rusages_t*);
|
||||
int rc = 0;
|
||||
/* clang-format off */
|
||||
xce_notify_data_t xdata = {
|
||||
.event = NotifyData_data_schedJobRusages,
|
||||
.data = {
|
||||
.sched_job_rusages = rusages
|
||||
}
|
||||
};
|
||||
/* clang-format on */
|
||||
|
||||
mylock_lock(&(c->sched.lock));
|
||||
if (c->sched.ep != NULL) {
|
||||
switch (situation) {
|
||||
case HOOK_AFTER_EVENT:
|
||||
rc = notify(c, c->sched.ep, &xdata);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
mylock_unlock(&(c->sched.lock));
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int sched_job_hook_fun(int type, int situation, int detail, void* data,
|
||||
va_list ap)
|
||||
{
|
||||
|
|
@ -328,6 +359,8 @@ static int sched_job_hook_fun(int type, int situation, int detail, void* data,
|
|||
return sched_job_update_fun(type, situation, data, ap);
|
||||
case HOOK_DETAIL_JOB_FAIL:
|
||||
return sched_job_fail_fun(type, situation, data, ap);
|
||||
case HOOK_DETAIL_JOB_RUSAGE_UPDATE:
|
||||
return sched_job_rusage_update_fun(type, situation, data, ap);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -51,6 +51,8 @@ static int check_task_hosts(cluster_t* c, xce_taskrun_t* runmsg)
|
|||
obj_deref(w);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
obj_deref(w);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,9 @@
|
|||
|
||||
#include "client.h"
|
||||
#include "controller.capnp.h"
|
||||
#include "delay.h"
|
||||
#include "idgen.h"
|
||||
#include "preason.h"
|
||||
#include "xce/types.h"
|
||||
|
||||
typedef int (*cmd_func_t)(int, char*[]);
|
||||
|
|
@ -73,6 +75,7 @@ typedef struct {
|
|||
#define MAX_TASK_HOSTS (5)
|
||||
#define MAX_RUN_TASKS (50)
|
||||
#define RUSAGE_UPDATE_INTERVAL (60)
|
||||
#define MAX_LINE_LEN (40960)
|
||||
|
||||
#define S2J_JSON_SET_var_string_ELEMENT(to_json, from_struct, _element) \
|
||||
if (((from_struct) != NULL) && (((from_struct)->_element) != NULL)) { \
|
||||
|
|
@ -109,14 +112,12 @@ extern int cmd_jobkill(int, char*[]);
|
|||
extern int cmd_jobckpt(int, char*[]);
|
||||
extern int cmd_qctrl(int, char*[]);
|
||||
extern int cmd_runtasks(int, char*[]);
|
||||
extern int cmd_setpend(int, char*[]);
|
||||
extern int cmd_jobinfo(int, char*[]);
|
||||
static int worker_house_keeping(void*);
|
||||
|
||||
static void handler(int, siginfo_t*, void*);
|
||||
|
||||
#define CLOCKID CLOCK_REALTIME
|
||||
#define SIG SIGRTMIN
|
||||
|
||||
static timer_t timerid;
|
||||
static idgen_ctx_t idctx;
|
||||
delaymgr_t delaymgr;
|
||||
|
||||
static setting_t settings[] = {
|
||||
{ (char*)"host", (char*)NULL, (char*)"localhost" },
|
||||
|
|
@ -168,6 +169,7 @@ static command_t client_commands[] = {
|
|||
{ "jobsub", cmd_jobsub, "submit a job" },
|
||||
{ "jobkill", cmd_jobkill, "signal a job" },
|
||||
{ "jobckpt", cmd_jobckpt, "checkpoint a job" },
|
||||
{ "jobinfo", cmd_jobinfo, "job information" },
|
||||
{ "resval", cmd_resval, "get value of res" },
|
||||
{ "taskrun", cmd_runtasks, "run tasks" },
|
||||
{ "help", cmd_help, "Display this text" },
|
||||
|
|
@ -186,6 +188,7 @@ static command_t scheduler_commands[] = {
|
|||
{ "quit", cmd_quit, "Quit xce test" },
|
||||
{ "join", cmd_join_sched, "Join the cluster" },
|
||||
{ "getconf", cmd_getconf, "Get conf of cluster" },
|
||||
{ "setpend", cmd_setpend, "set job pend reason" },
|
||||
{ (char*)NULL, (cmd_func_t)NULL, (char*)NULL }
|
||||
};
|
||||
|
||||
|
|
@ -278,7 +281,7 @@ int leave_ctx(command_ctx_t* ctx)
|
|||
}
|
||||
|
||||
if (ctx == &workerctx) {
|
||||
timer_delete(timerid);
|
||||
delaymgr_fini(&delaymgr);
|
||||
}
|
||||
|
||||
xcecli_wakeup(active_ctx->ctx, (int)-EINTR);
|
||||
|
|
@ -392,10 +395,7 @@ int cmd_up(int argc, char* argv[])
|
|||
|
||||
int cmd_worker(int argc, char* argv[])
|
||||
{
|
||||
int rc;
|
||||
struct sigevent sev;
|
||||
struct sigaction sa;
|
||||
struct itimerspec its;
|
||||
int rc;
|
||||
|
||||
if ((rc = enter_ctx(&workerctx)) < 0) {
|
||||
return rc;
|
||||
|
|
@ -403,22 +403,10 @@ int cmd_worker(int argc, char* argv[])
|
|||
|
||||
active_ctx = &workerctx;
|
||||
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sa.sa_sigaction = handler;
|
||||
sigemptyset(&(sa.sa_mask));
|
||||
sigaction(SIG, &sa, NULL);
|
||||
|
||||
sev.sigev_notify = SIGEV_SIGNAL;
|
||||
sev.sigev_signo = SIG;
|
||||
sev.sigev_value.sival_ptr = &timerid;
|
||||
|
||||
timer_create(CLOCKID, &sev, &timerid);
|
||||
|
||||
memset(&its, 0x0, sizeof(its));
|
||||
its.it_value.tv_sec = 1;
|
||||
|
||||
timer_settime(timerid, 0, &its, NULL);
|
||||
|
||||
delaymgr_init(&delaymgr, 2, NULL);
|
||||
delaymgr_start(&delaymgr);
|
||||
delay_task(&delaymgr, 5, -1, (delay_task_entry_fn_t)worker_house_keeping,
|
||||
&workerctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -631,11 +619,94 @@ int cmd_joblist(int argc, char* argv[])
|
|||
jobs[i]->submit->start_info->cmdline);
|
||||
}
|
||||
|
||||
for (i = 0; i < rc; i++) {
|
||||
free_Job_ptr(&(jobs[i]));
|
||||
}
|
||||
|
||||
free(jobs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_jobinfo(xce_job_t* job)
|
||||
{
|
||||
char idstring[128];
|
||||
|
||||
if (job == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
fmt_jobid(idstring, sizeof(idstring) - 1, job->jobid);
|
||||
printf("JobID: %s\n", idstring);
|
||||
printf("state: %s\n", job_state_str(job->state));
|
||||
printf("Queue: %s\n", job->submit->queue);
|
||||
printf("User: %s\n", job->submit->user);
|
||||
printf("Slots: %d,%d\n", job->submit->mintasks, job->submit->maxtasks);
|
||||
printf("Command: %s\n", job->submit->start_info->cmdline);
|
||||
|
||||
if (job->pend_reasons != NULL) {
|
||||
printf("Pend Reason:\n");
|
||||
if (job->pend_reasons->main_reason != 0) {
|
||||
printf("\tmain Reason: %d\n", job->pend_reasons->main_reason);
|
||||
} else {
|
||||
if (job->pend_reasons->nhost_reasons > 0) {
|
||||
int i;
|
||||
|
||||
printf("\tHost Reasons:\n");
|
||||
for (i = 0; i < job->pend_reasons->nhost_reasons; i++) {
|
||||
printf("\t\t(%s, %d)\n",
|
||||
job->pend_reasons->host_based_reasons[i]->host,
|
||||
job->pend_reasons->host_based_reasons[i]->reason);
|
||||
}
|
||||
}
|
||||
|
||||
if (job->pend_reasons->nres_reasons > 0) {
|
||||
int i;
|
||||
|
||||
printf("\tResource Reasons:\n");
|
||||
for (i = 0; i < job->pend_reasons->nres_reasons; i++) {
|
||||
printf("\t\t(%s, %s, %d)\n",
|
||||
job->pend_reasons->res_based_reasons[i]->resource,
|
||||
job->pend_reasons->res_based_reasons[i]->host,
|
||||
job->pend_reasons->res_based_reasons[i]->reason);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int cmd_jobinfo(int argc, char* argv[])
|
||||
{
|
||||
int opt;
|
||||
|
||||
optind = 1;
|
||||
|
||||
while ((opt = getopt(argc, argv, "j:")) != -1) {
|
||||
uint64_t jobid;
|
||||
xce_job_t* job;
|
||||
int rc = 0;
|
||||
|
||||
switch (opt) {
|
||||
case 'j':
|
||||
parse_jobid(&jobid, optarg);
|
||||
|
||||
if (jobid > 0) {
|
||||
rc = xcecli_jobinfo(active_ctx->ctx, jobid, &job);
|
||||
if (rc < 0) {
|
||||
perror("xcecli_jobinfo");
|
||||
continue;
|
||||
}
|
||||
|
||||
print_jobinfo(job);
|
||||
free_Job_ptr(&job);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int fill_job_alloc(xce_job_alloc_t* jalloc, int nhosts,
|
||||
host_task_t* hosts)
|
||||
{
|
||||
|
|
@ -1256,6 +1327,91 @@ int cmd_runtasks(int argc, char* argv[])
|
|||
return rc;
|
||||
}
|
||||
|
||||
static int add_pendreason(xce_job_preason_t* preason, char* s)
|
||||
{
|
||||
char s1[MAX_LINE_LEN];
|
||||
char* pcode = NULL;
|
||||
char* phost = NULL;
|
||||
char* pres = NULL;
|
||||
char* p;
|
||||
int code;
|
||||
|
||||
if ((preason == NULL) || (s == NULL)) {
|
||||
fprintf(stderr, "bad parameter\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((p = strrchr(s, (int)':')) == NULL) {
|
||||
pcode = s;
|
||||
} else {
|
||||
pcode = p + 1;
|
||||
memset(s1, 0x0, sizeof(s1));
|
||||
strncpy(s1, s, p - s);
|
||||
|
||||
if ((p = strrchr(s1, (int)':')) == NULL) {
|
||||
phost = s1;
|
||||
} else {
|
||||
*p = 0x0;
|
||||
phost = p + 1;
|
||||
pres = s1;
|
||||
}
|
||||
}
|
||||
|
||||
code = atoi(pcode);
|
||||
|
||||
return add_job_preason(preason, code, phost, pres);
|
||||
}
|
||||
|
||||
int cmd_setpend(int argc, char* argv[])
|
||||
{
|
||||
int opt;
|
||||
xce_job_preason_t jreasons;
|
||||
xce_pendreason_t preason = { .reasons = &jreasons };
|
||||
xce_preason_set_t reasons
|
||||
= { .nreasons = 1, .reasons = (xce_pendreason_t*[]) { &preason } };
|
||||
int rc = 0;
|
||||
|
||||
optind = 1;
|
||||
|
||||
while ((opt = getopt(argc, argv, "j:p:")) != -1) {
|
||||
int rc = 0;
|
||||
switch (opt) {
|
||||
case 'j':
|
||||
parse_jobid(&(preason.jobid), optarg);
|
||||
break;
|
||||
case 'p':
|
||||
rc = add_pendreason(&jreasons, optarg);
|
||||
if (rc < 0) {
|
||||
perror("add_pendreason");
|
||||
return rc;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (preason.jobid == 0) {
|
||||
fprintf(stderr, "no or incorrect jobid specified\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((jreasons.main_reason == 0) && (jreasons.nhost_reasons == 0)
|
||||
&& (jreasons.nres_reasons == 0)) {
|
||||
fprintf(stderr, "no or incorrect pend reason set\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = xcecli_set_pend_reason(active_ctx->ctx, &reasons);
|
||||
if (rc < 0) {
|
||||
perror("xcecli_set_pend_reason");
|
||||
erase_job_preason(&jreasons);
|
||||
return rc;
|
||||
}
|
||||
|
||||
printf("ok\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cmd_join_worker(int argc, char* argv[])
|
||||
{
|
||||
int rc;
|
||||
|
|
@ -2263,18 +2419,24 @@ static void check_run_tasks()
|
|||
}
|
||||
}
|
||||
|
||||
static void handler(int sig, siginfo_t* si, void* uc)
|
||||
#define HEARTBEAT_INTERVAL (60)
|
||||
|
||||
static int worker_house_keeping(void* arg)
|
||||
{
|
||||
struct itimerspec its;
|
||||
command_ctx_t* ctx = (command_ctx_t*)arg;
|
||||
int rc = 0;
|
||||
|
||||
xce_use(ctx);
|
||||
|
||||
check_run_jobs();
|
||||
check_run_tasks();
|
||||
|
||||
memset(&its, 0x0, sizeof(its));
|
||||
rc = xcecli_heartbeat(ctx->ctx, HEARTBEAT_INTERVAL);
|
||||
if (rc < 0) {
|
||||
perror("xcecli_heartbeat");
|
||||
}
|
||||
|
||||
its.it_value.tv_sec = 1;
|
||||
|
||||
timer_settime(timerid, 0, &its, NULL);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
|
|
|
|||
|
|
@ -476,6 +476,28 @@ int get_resval(cluster_t* c, char* resname, char* host, xce_val_t* val)
|
|||
return 1;
|
||||
}
|
||||
|
||||
int mark_worker_unavail(cluster_t* c, worker_t* w)
|
||||
{
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_WORKER, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_WORKER_DEAD, c, w);
|
||||
w->host.status |= XCE_WORKER_UNAVAIL;
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_WORKER, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_WORKER_DEAD, c, w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mark_worker_back(cluster_t* c, worker_t* w)
|
||||
{
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_WORKER, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_WORKER_UPDATE, c, w);
|
||||
w->host.status &= ~XCE_WORKER_UNAVAIL;
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_WORKER, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_WORKER_UPDATE, c, w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int handle_worker_leave(cluster_t* c, int idx)
|
||||
{
|
||||
worker_t* w = NULL;
|
||||
|
|
@ -499,13 +521,8 @@ int handle_worker_leave(cluster_t* c, int idx)
|
|||
return -errno;
|
||||
}
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_WORKER, HOOK_BEFORE_EVENT,
|
||||
HOOK_DETAIL_WORKER_DEAD, c, w);
|
||||
w->host.status |= XCE_WORKER_UNAVAIL;
|
||||
w->ep = NULL;
|
||||
mark_worker_unavail(c, w);
|
||||
|
||||
xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_WORKER, HOOK_AFTER_EVENT,
|
||||
HOOK_DETAIL_WORKER_DEAD, c, w);
|
||||
obj_deref(w);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -539,7 +556,6 @@ int worker_ctrl(cluster_t* c, xce_hostctrl_t* ctrl)
|
|||
}
|
||||
w->host.status |= XCE_WORKER_CLOSED;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
rc = -1;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
#include "cluster.h"
|
||||
#include "objmgr.h"
|
||||
#include "preason.h"
|
||||
#include "utils.h"
|
||||
#include "xce/cluster_def.h"
|
||||
#include "xstring.h"
|
||||
|
|
@ -296,6 +297,11 @@ void job_obj_killer(job_t* job)
|
|||
FREEUP(job->job.run_usage);
|
||||
}
|
||||
|
||||
if (job->job.pend_reasons != NULL) {
|
||||
erase_job_preason(job->job.pend_reasons);
|
||||
FREEUP(job->job.pend_reasons);
|
||||
}
|
||||
|
||||
FREEUP(job->job.exit_info);
|
||||
|
||||
memset(obj, 0x0, sizeof(*obj));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue