forked from lei.chen/myxce
1008 lines
28 KiB
C
1008 lines
28 KiB
C
#include <errno.h>
|
|
#include <stdarg.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "cluster.h"
|
|
#include "objmgr.h"
|
|
#include "preason.h"
|
|
#include "utils.h"
|
|
#include "xce/cluster_def.h"
|
|
#include "xstring.h"
|
|
|
|
static void* xjob_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xjob_fini(void*);
|
|
static void xjob_type_fini(objtype_t*);
|
|
static void* xres_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xres_fini(void*);
|
|
static void xres_type_fini(objtype_t*);
|
|
static void* xworker_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xworker_fini(void*);
|
|
static void xworker_type_fini(objtype_t*);
|
|
static void* xqueue_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xqueue_fini(void*);
|
|
static void xqueue_type_fini(objtype_t*);
|
|
static void* xconfig_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xconfig_fini(void*);
|
|
static void xconfig_type_fini(objtype_t*);
|
|
static void* xresval_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xresval_fini(void*);
|
|
static void xresval_type_fini(objtype_t*);
|
|
static void* xgroup_create(objmgr_t*, objtype_t*, va_list);
|
|
static void xgroup_fini(void*);
|
|
static void xgroup_type_fini(objtype_t*);
|
|
|
|
/* clang-format off */
|
|
static objtype_t types[] = {
|
|
{
|
|
.type = "xjob",
|
|
.fn_create = (obj_create_fn_t)xjob_create,
|
|
.fn_fini = xjob_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xjob_type_fini,
|
|
.typedata = NULL
|
|
},
|
|
{
|
|
.type = "xresource",
|
|
.fn_create = (obj_create_fn_t)xres_create,
|
|
.fn_fini = xres_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xres_type_fini,
|
|
.typedata = NULL,
|
|
},
|
|
{
|
|
.type = "xworker",
|
|
.fn_create = (obj_create_fn_t)xworker_create,
|
|
.fn_fini = xworker_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xworker_type_fini,
|
|
.typedata = NULL
|
|
},
|
|
{
|
|
.type = "xqueue",
|
|
.fn_create = (obj_create_fn_t)xqueue_create,
|
|
.fn_fini = xqueue_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xqueue_type_fini,
|
|
.typedata = NULL
|
|
},
|
|
{
|
|
.type = "xconfig",
|
|
.fn_create = (obj_create_fn_t)xconfig_create,
|
|
.fn_fini = xconfig_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xconfig_type_fini,
|
|
.typedata = NULL
|
|
},
|
|
{
|
|
.type = "xresval",
|
|
.fn_create = (obj_create_fn_t)xresval_create,
|
|
.fn_fini = xresval_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xresval_type_fini,
|
|
.typedata = NULL
|
|
|
|
},
|
|
{
|
|
.type = "xgroup",
|
|
.fn_create = (obj_create_fn_t)xgroup_create,
|
|
.fn_fini = xgroup_fini,
|
|
.fn_type_fini = (objtype_fini_fn_t)xgroup_type_fini,
|
|
.typedata = NULL
|
|
}
|
|
};
|
|
/* clang-format on */
|
|
|
|
static void* xjob_create(objmgr_t* mgr, objtype_t* type, va_list ap)
|
|
{
|
|
jobmgr_t* jobmgr = &(((cluster_t*)type->typedata)->jobmgr);
|
|
xce_job_t* submit = va_arg(ap, xce_job_t*);
|
|
job_t* job = NULL;
|
|
myobj_t* obj;
|
|
int32_t idx;
|
|
|
|
if (submit == NULL) {
|
|
SET_ERROR(EINVAL);
|
|
return NULL;
|
|
}
|
|
|
|
job = jobmgr_lockjob(jobmgr, submit->jobid, OBJREF_READ);
|
|
if (job != NULL) {
|
|
SET_ERROR(EEXIST);
|
|
obj_deref(job);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
obj = obj_alloc(sizeof(*job));
|
|
if (obj == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
job = MYOBJ_TO_OBJ(job_t*, obj);
|
|
/* fill job data */
|
|
job->job.jobid = submit->jobid;
|
|
job->job.submit = (job_submit_data_t*)calloc(1, sizeof(*(job->job.submit)));
|
|
if (job->job.submit == NULL) {
|
|
return NULL;
|
|
}
|
|
job->job.submit->queue
|
|
= create_obj_by_typename(mgr, "xstring", submit->submit->queue);
|
|
/* FIXME: */
|
|
if (1) {
|
|
time_t now = time(NULL);
|
|
|
|
job->job.sub_time = now;
|
|
job->job.queue_time = now;
|
|
}
|
|
|
|
if (job->job.queue_time == 0) {
|
|
job->job.queue_time = job->job.sub_time;
|
|
}
|
|
job->job.state = submit->state;
|
|
job->job.submit->user
|
|
= create_obj_by_typename(mgr, "xstring", submit->submit->user);
|
|
job->job.start_time = submit->start_time;
|
|
job->job.finish_time = submit->finish_time;
|
|
job->job.submit->job_name
|
|
= create_obj_by_typename(mgr, "xstring", submit->submit->job_name);
|
|
job->job.submit->project_name
|
|
= create_obj_by_typename(mgr, "xstring", submit->submit->project_name);
|
|
job->job.submit->user_group
|
|
= create_obj_by_typename(mgr, "xstring", submit->submit->user_group);
|
|
job->job.submit->job_description = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->job_description);
|
|
job->job.submit->resreq
|
|
= create_obj_by_typename(mgr, "xstring", submit->submit->resreq);
|
|
job->job.run_time = submit->run_time;
|
|
job->job.submit->mintasks = submit->submit->mintasks;
|
|
job->job.submit->maxtasks = submit->submit->maxtasks;
|
|
job->job.pending_ctrl = submit->pending_ctrl;
|
|
|
|
job->job.pidinfo = NULL;
|
|
|
|
if (submit->pidinfo != NULL) {
|
|
job->job.pidinfo = (job_pidinfo_t*)calloc(1, sizeof(job_pidinfo_t));
|
|
if (job->job.pidinfo == NULL) {
|
|
SET_ERROR(ENOMEM);
|
|
goto clean_job;
|
|
}
|
|
job->job.pidinfo->npids = copy_int_list(
|
|
(int**)&(job->job.pidinfo->pids), (int*)submit->pidinfo->pids,
|
|
submit->pidinfo->npids);
|
|
job->job.pidinfo->npgids = copy_int_list(
|
|
(int**)&(job->job.pidinfo->pgids), (int*)submit->pidinfo->pgids,
|
|
submit->pidinfo->npgids);
|
|
if (submit->pidinfo->exdata) {
|
|
job->job.pidinfo->exdata = create_obj_by_typename(
|
|
mgr, "xstring", submit->pidinfo->exdata);
|
|
}
|
|
}
|
|
|
|
job->job.submit->start_info = NULL;
|
|
|
|
if (submit->submit->start_info != NULL) {
|
|
job->job.submit->start_info
|
|
= (job_startinfo_t*)calloc(1, sizeof(job_startinfo_t));
|
|
if (job->job.submit->start_info == NULL) {
|
|
SET_ERROR(ENOMEM);
|
|
goto clean_job;
|
|
}
|
|
job->job.submit->start_info->cmdline = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->cmdline);
|
|
job->job.submit->start_info->exdata = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->exdata);
|
|
job->job.submit->start_info->execcwd = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->execcwd);
|
|
job->job.submit->start_info->exechome = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->exechome);
|
|
job->job.submit->start_info->execuser = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->execuser);
|
|
job->job.submit->start_info->launch_type = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->launch_type);
|
|
if (submit->submit->start_info->job_pre_exec != NULL) {
|
|
job->job.submit->start_info->job_pre_exec = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->job_pre_exec);
|
|
}
|
|
|
|
if (submit->submit->start_info->job_post_exec != NULL) {
|
|
job->job.submit->start_info->job_post_exec = create_obj_by_typename(
|
|
mgr, "xstring", submit->submit->start_info->job_post_exec);
|
|
}
|
|
}
|
|
|
|
job->job.allocs = NULL;
|
|
|
|
if (submit->allocs) {
|
|
MOVE_PTR(job->job.allocs, submit->allocs);
|
|
}
|
|
|
|
job->job.run_usage = NULL;
|
|
|
|
if (submit->run_usage != NULL) {
|
|
MOVE_PTR(job->job.run_usage, submit->run_usage);
|
|
}
|
|
|
|
if ((job->job.submit->queue == NULL) || (job->job.submit->user == NULL)
|
|
|| (job->job.submit->job_name == NULL)
|
|
|| (job->job.submit->start_info->cmdline == NULL)
|
|
|| (job->job.submit->project_name == NULL)
|
|
|| (job->job.submit->job_description == NULL)
|
|
|| (job->job.submit->resreq == NULL)) {
|
|
|
|
FREEUP(job->job.submit->start_info);
|
|
|
|
job_obj_killer(job);
|
|
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
idx = jobmgr_add_job(jobmgr, job);
|
|
|
|
obj_init(mgr, type, idx, obj);
|
|
|
|
return job;
|
|
|
|
clean_job:
|
|
job_obj_killer(job);
|
|
return NULL;
|
|
}
|
|
|
|
void job_obj_killer(job_t* job)
|
|
{
|
|
myobj_t* obj;
|
|
|
|
if (job == NULL) {
|
|
return;
|
|
}
|
|
|
|
obj = TO_MYOBJ(job);
|
|
if (job->job.submit != NULL) {
|
|
DEREF_OBJ(job->job.submit->queue);
|
|
DEREF_OBJ(job->job.submit->user);
|
|
DEREF_OBJ(job->job.submit->job_name);
|
|
DEREF_OBJ(job->job.submit->project_name);
|
|
DEREF_OBJ(job->job.submit->job_description);
|
|
DEREF_OBJ(job->job.submit->resreq);
|
|
|
|
if (job->job.submit->start_info != NULL) {
|
|
DEREF_OBJ(job->job.submit->start_info->cmdline);
|
|
DEREF_OBJ(job->job.submit->start_info->exechome);
|
|
DEREF_OBJ(job->job.submit->start_info->execcwd);
|
|
DEREF_OBJ(job->job.submit->start_info->execuser);
|
|
DEREF_OBJ(job->job.submit->start_info->exdata);
|
|
DEREF_OBJ(job->job.submit->start_info->launch_type);
|
|
DEREF_OBJ(job->job.submit->start_info->job_pre_exec);
|
|
DEREF_OBJ(job->job.submit->start_info->job_post_exec);
|
|
FREEUP(job->job.submit->start_info);
|
|
}
|
|
|
|
FREEUP(job->job.submit);
|
|
}
|
|
|
|
if (job->job.pidinfo != NULL) {
|
|
FREEUP(job->job.pidinfo->pids);
|
|
FREEUP(job->job.pidinfo->pgids);
|
|
if (job->job.pidinfo->exdata != NULL) {
|
|
DEREF_OBJ(job->job.pidinfo->exdata);
|
|
}
|
|
|
|
FREEUP(job->job.pidinfo);
|
|
}
|
|
|
|
if (job->job.allocs != NULL) {
|
|
free_JobAlloc_ptr(&(job->job.allocs));
|
|
}
|
|
|
|
if (job->job.run_usage != NULL) {
|
|
for (int i = 0; i < job->job.run_usage->num_hosts; i++) {
|
|
DEREF_OBJ(job->job.run_usage->host_runusage[i]->host_name);
|
|
FREEUP(job->job.run_usage->host_runusage[i]);
|
|
}
|
|
FREEUP(job->job.run_usage->host_runusage);
|
|
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));
|
|
|
|
FREEUP(obj);
|
|
}
|
|
|
|
static void xjob_fini(void* j)
|
|
{
|
|
myobj_t* myobj;
|
|
objtype_t* typeval;
|
|
job_t* job;
|
|
jobmgr_t* jobmgr;
|
|
|
|
if (j == NULL) {
|
|
return;
|
|
}
|
|
|
|
job = (job_t*)j;
|
|
myobj = TO_MYOBJ(j);
|
|
typeval = myobj->type;
|
|
jobmgr = &(((cluster_t*)typeval->typedata)->jobmgr);
|
|
if (jobmgr == NULL) {
|
|
return;
|
|
}
|
|
|
|
jobmgr_del_job(jobmgr, job);
|
|
|
|
return;
|
|
}
|
|
|
|
static void xjob_type_fini(objtype_t* typeval) { return; }
|
|
|
|
int register_types(cluster_t* c)
|
|
{
|
|
int i;
|
|
|
|
for (i = 0; i < N_EL_ARRAY(types); i++) {
|
|
int rc;
|
|
|
|
types[i].typedata = c;
|
|
rc = objmgr_register(&(c->objmgr), &(types[i]));
|
|
if (rc < 0) {
|
|
return rc;
|
|
}
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void resval_obj_killer(xce_resval_t* v) { return; }
|
|
static void* xres_create(objmgr_t* mgr, objtype_t* type, va_list ap)
|
|
{
|
|
resmgr_t* resmgr = &(((cluster_t*)type->typedata)->resmgr);
|
|
xce_resource_t* r = va_arg(ap, xce_resource_t*);
|
|
xce_resource_t* r1 = NULL;
|
|
myobj_t* obj;
|
|
int32_t idx;
|
|
|
|
xce_use(resmgr);
|
|
|
|
if (r == NULL) {
|
|
SET_ERROR(EINVAL);
|
|
return NULL;
|
|
}
|
|
|
|
r1 = resmgr_lockres(resmgr, r->name, OBJREF_READ);
|
|
if (r1 != NULL) {
|
|
SET_ERROR(EEXIST);
|
|
obj_deref(r1);
|
|
return NULL;
|
|
}
|
|
|
|
obj = obj_alloc(sizeof(*r));
|
|
if (obj == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
r1 = MYOBJ_TO_OBJ(xce_resource_t*, obj);
|
|
|
|
r1->name = create_obj_by_typename(mgr, "xstring", r->name);
|
|
r1->desc = create_obj_by_typename(mgr, "xstring", r->desc);
|
|
if ((r1->name == NULL) || (r->desc != NULL && r1->desc == NULL)) {
|
|
res_obj_killer(r1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
r1->valtype = r->valtype;
|
|
r1->ordtype = r->ordtype;
|
|
r1->flags = r->flags;
|
|
r1->interval = r->interval;
|
|
r1->last_report = r->last_report;
|
|
|
|
r1->ndistributions = r->ndistributions;
|
|
if (r->distributions) {
|
|
MOVE_PTR(r1->distributions, r->distributions);
|
|
}
|
|
MOVE_PTR(r1->hbased_defined, r->hbased_defined);
|
|
idx = resmgr_add_res(resmgr, r1);
|
|
|
|
obj_init(mgr, type, idx, obj);
|
|
|
|
return r1;
|
|
}
|
|
|
|
void res_obj_killer(xce_resource_t* r)
|
|
{
|
|
myobj_t* obj;
|
|
|
|
if (r == NULL) {
|
|
return;
|
|
}
|
|
|
|
obj = TO_MYOBJ(r);
|
|
DEREF_OBJ(r->name);
|
|
DEREF_OBJ(r->desc);
|
|
if (r->hbased_defined) {
|
|
if (r->hbased_defined->which == Value_u_svalue) {
|
|
free(r->hbased_defined->u.svalue);
|
|
}
|
|
free(r->hbased_defined);
|
|
}
|
|
|
|
if (r->distributions != NULL) {
|
|
for (int i = 0; i < r->ndistributions; i++) {
|
|
if (r->distributions[i] != NULL) {
|
|
res_distribution_t* dist = r->distributions[i];
|
|
if (dist->hosts != NULL) {
|
|
for (int j = 0; j < dist->nhosts; j++) {
|
|
FREEUP(dist->hosts[j]);
|
|
}
|
|
FREEUP(dist->hosts);
|
|
}
|
|
if (dist->value != NULL) {
|
|
if (dist->value->which == Value_u_svalue) {
|
|
FREEUP(dist->value->u.svalue);
|
|
}
|
|
free(dist->value);
|
|
}
|
|
FREEUP(dist);
|
|
}
|
|
}
|
|
FREEUP(r->distributions);
|
|
}
|
|
memset(obj, 0x0, sizeof(*obj));
|
|
FREEUP(obj);
|
|
}
|
|
|
|
static void xres_fini(void* p)
|
|
{
|
|
myobj_t* myobj;
|
|
objtype_t* typeval;
|
|
xce_resource_t* r;
|
|
resmgr_t* resmgr;
|
|
|
|
if (p == NULL) {
|
|
return;
|
|
}
|
|
|
|
r = (xce_resource_t*)p;
|
|
myobj = TO_MYOBJ(p);
|
|
typeval = myobj->type;
|
|
resmgr = &(((cluster_t*)typeval->typedata)->resmgr);
|
|
if (resmgr == NULL) {
|
|
return;
|
|
}
|
|
|
|
resmgr_del_res(resmgr, r);
|
|
|
|
return;
|
|
}
|
|
|
|
static void xres_type_fini(objtype_t* typeval) { return; }
|
|
|
|
void worker_obj_killer(worker_t* w)
|
|
{
|
|
myobj_t* obj;
|
|
|
|
if (w == NULL) {
|
|
return;
|
|
}
|
|
|
|
obj = TO_MYOBJ(w);
|
|
|
|
DEREF_OBJ(w->host.name);
|
|
|
|
if ((w->host.thresholds != NULL) && (w->host.nthresholds > 0)) {
|
|
free_resource_thresholds(w->host.thresholds, w->host.nthresholds);
|
|
w->host.thresholds = NULL;
|
|
w->host.nthresholds = 0;
|
|
}
|
|
|
|
if (w->host.dispatch_window_config != NULL) {
|
|
free_timewindow_config(w->host.dispatch_window_config);
|
|
w->host.dispatch_window_config = NULL;
|
|
}
|
|
|
|
if (w->host.attrs != NULL) {
|
|
DEREF_OBJ(w->host.attrs->hosttype);
|
|
DEREF_OBJ(w->host.attrs->hostmodel);
|
|
FREEUP(w->host.attrs);
|
|
}
|
|
|
|
zarray_fini(&(w->host.resvals));
|
|
|
|
memset(obj, 0x0, sizeof(*obj));
|
|
FREEUP(obj);
|
|
}
|
|
|
|
static void kill_resval(void* p)
|
|
{
|
|
if (p == NULL) {
|
|
return;
|
|
}
|
|
|
|
/* FIXME: improve resval free */
|
|
free(p);
|
|
}
|
|
|
|
static void* xworker_create(objmgr_t* mgr, objtype_t* typeval, va_list ap)
|
|
{
|
|
workermgr_t* workermgr = &(((cluster_t*)typeval->typedata)->workermgr);
|
|
worker_t* w = va_arg(ap, worker_t*);
|
|
worker_t* w1 = NULL;
|
|
myobj_t* obj;
|
|
int32_t idx;
|
|
|
|
if (w == NULL) {
|
|
SET_ERROR(EINVAL);
|
|
return NULL;
|
|
}
|
|
|
|
w1 = workermgr_lock(workermgr, w->host.name, OBJREF_UPDATE);
|
|
if (w1 == NULL) {
|
|
obj = obj_alloc(sizeof(*w1));
|
|
if (obj == NULL) {
|
|
return NULL;
|
|
}
|
|
|
|
w1 = MYOBJ_TO_OBJ(worker_t*, obj);
|
|
memcpy(w1, w, sizeof(*w1));
|
|
w1->host.attrs = (hostattrs_t*)calloc(1, sizeof(hostattrs_t));
|
|
if (w1->host.attrs == NULL) {
|
|
free(obj);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
w1->host.name = create_obj_by_typename(mgr, "xstring", w->host.name);
|
|
|
|
idx = workermgr_add(workermgr, w1);
|
|
obj_init(mgr, typeval, idx, obj);
|
|
w1->idx = idx;
|
|
|
|
/* gain update lock */
|
|
w1 = obj_ref(w1, OBJREF_UPDATE);
|
|
w1->host.attrs->hosttype = NULL;
|
|
w1->host.attrs->hostmodel = NULL;
|
|
zarray_init(&(w1->host.resvals), 64, kill_resval);
|
|
}
|
|
|
|
DEREF_OBJ(w1->host.attrs->hosttype);
|
|
DEREF_OBJ(w1->host.attrs->hostmodel);
|
|
|
|
if (w->host.attrs) {
|
|
memcpy(w1->host.attrs, w->host.attrs, sizeof(*(w1->host.attrs)));
|
|
|
|
w1->host.attrs->hosttype
|
|
= create_obj_by_typename(mgr, "xstring", w->host.attrs->hosttype);
|
|
w1->host.attrs->hostmodel
|
|
= create_obj_by_typename(mgr, "xstring", w->host.attrs->hostmodel);
|
|
} else {
|
|
w1->host.attrs->hosttype
|
|
= create_obj_by_typename(mgr, "xstring", "Unknown");
|
|
w1->host.attrs->hostmodel
|
|
= create_obj_by_typename(mgr, "xstring", "Unknown");
|
|
}
|
|
|
|
/* clang-format off */
|
|
if ((w1->host.name == NULL) ||
|
|
(w1->host.attrs->hosttype == NULL) ||
|
|
(w1->host.attrs->hostmodel == NULL)) {
|
|
/* clang-format on */
|
|
|
|
worker_obj_killer(w1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
|
|
return w1;
|
|
}
|
|
static void xworker_fini(void* p)
|
|
{
|
|
myobj_t* myobj;
|
|
objtype_t* typeval;
|
|
worker_t* w;
|
|
workermgr_t* mgr;
|
|
|
|
if (p == NULL) {
|
|
return;
|
|
}
|
|
|
|
w = (worker_t*)p;
|
|
myobj = TO_MYOBJ(p);
|
|
typeval = myobj->type;
|
|
mgr = &(((cluster_t*)typeval->typedata)->workermgr);
|
|
|
|
if (mgr == NULL) {
|
|
return;
|
|
}
|
|
|
|
workermgr_del(mgr, w);
|
|
return;
|
|
}
|
|
|
|
static void xworker_type_fini(objtype_t* typeval) { return; }
|
|
|
|
void queue_obj_killer(queue_t* q)
|
|
{
|
|
myobj_t* obj;
|
|
|
|
if (q == NULL) {
|
|
return;
|
|
}
|
|
|
|
obj = TO_MYOBJ(q);
|
|
DEREF_OBJ(q->queue.queue);
|
|
if (q->queue.thresholds) {
|
|
for (int i = 0; i < q->queue.nthresholds; i++) {
|
|
if (q->queue.thresholds[i]) {
|
|
FREEUP(q->queue.thresholds[i]->name);
|
|
free(q->queue.thresholds[i]);
|
|
}
|
|
}
|
|
free(q->queue.thresholds);
|
|
}
|
|
q->queue.nthresholds = 0;
|
|
if (q->queue.runwindow) {
|
|
FREEUP(q->queue.runwindow->ranges);
|
|
q->queue.runwindow->nsegs = 0;
|
|
free(q->queue.runwindow);
|
|
}
|
|
|
|
if (q->queue.dispatchwindow) {
|
|
FREEUP(q->queue.dispatchwindow->ranges);
|
|
q->queue.dispatchwindow->nsegs = 0;
|
|
free(q->queue.dispatchwindow);
|
|
}
|
|
DEREF_OBJ(q->queue.pre_exec);
|
|
DEREF_OBJ(q->queue.post_exec);
|
|
if (q->queue.users) {
|
|
DEREF_OBJ(q->queue.users->name);
|
|
for (int i = 0; i < q->queue.users->members.count; i++) {
|
|
DEREF_OBJ(q->queue.users->members.data[i]);
|
|
}
|
|
|
|
FREEUP(q->queue.users->members.data);
|
|
|
|
for (int i = 0; i < q->queue.users->ex_members.count; i++) {
|
|
DEREF_OBJ(q->queue.users->ex_members.data[i]);
|
|
}
|
|
|
|
FREEUP(q->queue.users->ex_members.data);
|
|
|
|
free(q->queue.users);
|
|
}
|
|
if (q->queue.hosts) {
|
|
DEREF_OBJ(q->queue.hosts->name);
|
|
for (int i = 0; i < q->queue.hosts->members.count; i++) {
|
|
DEREF_OBJ(q->queue.hosts->members.data[i]);
|
|
}
|
|
|
|
FREEUP(q->queue.hosts->members.data);
|
|
|
|
for (int i = 0; i < q->queue.hosts->ex_members.count; i++) {
|
|
DEREF_OBJ(q->queue.hosts->ex_members.data[i]);
|
|
}
|
|
|
|
FREEUP(q->queue.hosts->ex_members.data);
|
|
|
|
free(q->queue.hosts);
|
|
}
|
|
|
|
if (q->queue.runwindow_config != NULL) {
|
|
free_timewindow_config(q->queue.runwindow_config);
|
|
q->queue.runwindow_config = NULL;
|
|
}
|
|
|
|
if (q->queue.dispatchwindow_config != NULL) {
|
|
free_timewindow_config(q->queue.dispatchwindow_config);
|
|
q->queue.dispatchwindow_config = NULL;
|
|
}
|
|
|
|
memset(obj, 0x0, sizeof(*obj));
|
|
FREEUP(obj);
|
|
}
|
|
|
|
static void* xqueue_create(objmgr_t* mgr, objtype_t* typeval, va_list ap)
|
|
{
|
|
qmgr_t* qmgr = &(((cluster_t*)typeval->typedata)->qmgr);
|
|
queue_t* q = va_arg(ap, queue_t*);
|
|
queue_t* q1 = NULL;
|
|
myobj_t* obj;
|
|
int32_t idx;
|
|
|
|
if (q == NULL) {
|
|
SET_ERROR(EINVAL);
|
|
return NULL;
|
|
}
|
|
|
|
q1 = qmgr_lockq(qmgr, q->queue.queue, OBJREF_READ);
|
|
if (q1 != NULL) {
|
|
SET_ERROR(EEXIST);
|
|
DEREF_OBJ(q1);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
obj = obj_alloc(sizeof(*q1));
|
|
if (obj == NULL) {
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
|
|
q1 = MYOBJ_TO_OBJ(queue_t*, obj);
|
|
q1->queue.queue = create_obj_by_typename(mgr, "xstring", q->queue.queue);
|
|
if (q1->queue.queue == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
q1->queue.attrs = q->queue.attrs;
|
|
q1->queue.status = q->queue.status;
|
|
q1->queue.priority = q->queue.priority;
|
|
q1->queue.accept_interval = q->queue.accept_interval;
|
|
q1->queue.sched_delay = q->queue.sched_delay;
|
|
q1->queue.resreq = NULL;
|
|
q1->queue.pre_exec = NULL;
|
|
q1->queue.post_exec = NULL;
|
|
|
|
if (q->queue.resreq != NULL) {
|
|
q1->queue.resreq
|
|
= create_obj_by_typename(mgr, "xstring", q->queue.resreq);
|
|
if (q1->queue.resreq == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (q->queue.pre_exec != NULL) {
|
|
q1->queue.pre_exec
|
|
= create_obj_by_typename(mgr, "xstring", q->queue.pre_exec);
|
|
if (q1->queue.pre_exec == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
if (q->queue.post_exec != NULL) {
|
|
q1->queue.post_exec
|
|
= create_obj_by_typename(mgr, "xstring", q->queue.post_exec);
|
|
if (q1->queue.post_exec == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
}
|
|
q1->queue.pending_ctrl = q->queue.pending_ctrl;
|
|
|
|
q1->queue.nthresholds = 0;
|
|
q1->queue.thresholds = NULL;
|
|
if ((q->queue.nthresholds > 0) && (q->queue.thresholds != NULL)) {
|
|
q1->queue.thresholds = dup_resource_thresholds(q->queue.thresholds,
|
|
q->queue.nthresholds);
|
|
if (q1->queue.thresholds != NULL) {
|
|
q1->queue.nthresholds = q->queue.nthresholds;
|
|
}
|
|
}
|
|
|
|
if (q->queue.users != NULL) {
|
|
q1->queue.users = (xce_group_t*)calloc(1, sizeof(xce_group_t));
|
|
if (q1->queue.users == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
if (q->queue.users->name) {
|
|
q1->queue.users->name
|
|
= create_obj_by_typename(mgr, "xstring", q->queue.users->name);
|
|
}
|
|
q1->queue.users->members.count = q->queue.users->members.count;
|
|
q1->queue.users->members.data
|
|
= (char**)calloc(q1->queue.users->members.count, sizeof(char*));
|
|
if (q1->queue.users->members.data == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
for (int i = 0; i < q->queue.users->members.count; i++) {
|
|
if (q->queue.users->members.data[i] == NULL) {
|
|
continue;
|
|
}
|
|
q1->queue.users->members.data[i] = create_obj_by_typename(
|
|
mgr, "xstring", q->queue.users->members.data[i]);
|
|
}
|
|
q1->queue.users->ex_members.count = q->queue.users->ex_members.count;
|
|
q1->queue.users->ex_members.data
|
|
= (char**)calloc(q1->queue.users->ex_members.count, sizeof(char*));
|
|
if (q1->queue.users->ex_members.data == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
for (int i = 0; i < q->queue.users->ex_members.count; i++) {
|
|
if (q->queue.users->ex_members.data[i] == NULL) {
|
|
continue;
|
|
}
|
|
q1->queue.users->ex_members.data[i] = create_obj_by_typename(
|
|
mgr, "xstring", q->queue.users->ex_members.data[i]);
|
|
}
|
|
}
|
|
if (q->queue.hosts != NULL) {
|
|
q1->queue.hosts = (xce_group_t*)calloc(1, sizeof(xce_group_t));
|
|
if (q1->queue.hosts == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
if (q->queue.hosts->name) {
|
|
q1->queue.hosts->name
|
|
= create_obj_by_typename(mgr, "xstring", q->queue.hosts->name);
|
|
}
|
|
q1->queue.hosts->members.count = q->queue.hosts->members.count;
|
|
q1->queue.hosts->members.data
|
|
= (char**)calloc(q1->queue.hosts->members.count, sizeof(char*));
|
|
if (q1->queue.hosts->members.data == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
for (int i = 0; i < q->queue.hosts->members.count; i++) {
|
|
if (q->queue.hosts->members.data[i] == NULL) {
|
|
continue;
|
|
}
|
|
q1->queue.hosts->members.data[i] = create_obj_by_typename(
|
|
mgr, "xstring", q->queue.hosts->members.data[i]);
|
|
}
|
|
q1->queue.hosts->ex_members.count = q->queue.hosts->ex_members.count;
|
|
q1->queue.hosts->ex_members.data
|
|
= (char**)calloc(q1->queue.hosts->ex_members.count, sizeof(char*));
|
|
if (q1->queue.hosts->ex_members.data == NULL) {
|
|
queue_obj_killer(q1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
for (int i = 0; i < q->queue.hosts->ex_members.count; i++) {
|
|
if (q->queue.hosts->ex_members.data[i] == NULL) {
|
|
continue;
|
|
}
|
|
q1->queue.hosts->ex_members.data[i] = create_obj_by_typename(
|
|
mgr, "xstring", q->queue.hosts->ex_members.data[i]);
|
|
}
|
|
}
|
|
|
|
q1->queue.runwindow_config = NULL;
|
|
if (q->queue.runwindow_config != NULL) {
|
|
q1->queue.runwindow_config
|
|
= dup_timewindow_config(q->queue.runwindow_config);
|
|
}
|
|
|
|
q1->queue.dispatchwindow_config = NULL;
|
|
if (q->queue.dispatchwindow_config != NULL) {
|
|
q1->queue.dispatchwindow_config
|
|
= dup_timewindow_config(q->queue.dispatchwindow_config);
|
|
}
|
|
|
|
/* leave run windows parse & dispatch parse later */
|
|
idx = qmgr_add(qmgr, q1);
|
|
obj_init(mgr, typeval, idx, obj);
|
|
|
|
return q1;
|
|
}
|
|
static void xqueue_fini(void* p)
|
|
{
|
|
myobj_t* myobj;
|
|
objtype_t* typeval;
|
|
queue_t* q;
|
|
qmgr_t* mgr;
|
|
|
|
if (p == NULL) {
|
|
return;
|
|
}
|
|
|
|
q = (queue_t*)p;
|
|
myobj = TO_MYOBJ(q);
|
|
typeval = myobj->type;
|
|
mgr = &(((cluster_t*)typeval->typedata)->qmgr);
|
|
|
|
if (mgr == NULL) {
|
|
return;
|
|
}
|
|
|
|
qmgr_delq(mgr, q);
|
|
|
|
return;
|
|
}
|
|
static void xqueue_type_fini(objtype_t* typeval) { return; }
|
|
|
|
static void* xresval_create(objmgr_t* mgr, objtype_t* typeval, va_list ap)
|
|
{
|
|
return NULL;
|
|
}
|
|
static void xresval_fini(void* r) { return; }
|
|
static void xresval_type_fini(objtype_t* typeval) { return; }
|
|
|
|
void config_obj_killer(xce_config_t* c)
|
|
{
|
|
myobj_t* obj;
|
|
|
|
if (c == NULL) {
|
|
return;
|
|
}
|
|
|
|
obj = TO_MYOBJ(c);
|
|
DEREF_OBJ(c->name);
|
|
DEREF_OBJ(c->value);
|
|
memset(obj, 0x0, sizeof(*obj));
|
|
FREEUP(obj);
|
|
}
|
|
|
|
static void* xconfig_create(objmgr_t* mgr, objtype_t* typeval, va_list ap)
|
|
{
|
|
cluster_t* c = (cluster_t*)typeval->typedata;
|
|
xce_config_t* kv = va_arg(ap, xce_config_t*);
|
|
myobj_t* obj;
|
|
xce_config_t* kv1 = NULL;
|
|
kvmgr_t* kvmgr = NULL;
|
|
uint32_t idx;
|
|
|
|
if (kv == NULL) {
|
|
SET_ERROR(EINVAL);
|
|
return NULL;
|
|
}
|
|
|
|
kvmgr = &(c->configmgr);
|
|
|
|
kv1 = kvmgr_lock(kvmgr, kv->name, OBJREF_READ);
|
|
if (kv1 != NULL) {
|
|
SET_ERROR(EEXIST);
|
|
DEREF_OBJ(kv1);
|
|
|
|
return NULL;
|
|
}
|
|
|
|
obj = obj_alloc(sizeof(*kv1));
|
|
if (obj == NULL) {
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
|
|
kv1 = MYOBJ_TO_OBJ(xce_config_t*, obj);
|
|
kv1->name = create_obj_by_typename(mgr, "xstring", kv->name);
|
|
kv1->value = create_obj_by_typename(mgr, "xstring", kv->value);
|
|
if ((kv1->name == NULL) || (kv1->value == NULL)) {
|
|
config_obj_killer(kv1);
|
|
SET_ERROR(ENOMEM);
|
|
return NULL;
|
|
}
|
|
|
|
idx = kvmgr_add(kvmgr, kv1->name, kv1);
|
|
obj_init(mgr, typeval, idx, obj);
|
|
|
|
return kv1;
|
|
}
|
|
static void xconfig_fini(void* p)
|
|
{
|
|
myobj_t* myobj;
|
|
objtype_t* typeval;
|
|
xce_config_t* config;
|
|
kvmgr_t* kvmgr;
|
|
|
|
if (p == NULL) {
|
|
return;
|
|
}
|
|
|
|
config = (xce_config_t*)p;
|
|
myobj = TO_MYOBJ(p);
|
|
typeval = myobj->type;
|
|
kvmgr = &(((cluster_t*)typeval->typedata)->configmgr);
|
|
|
|
kvmgr_del(kvmgr, config->name);
|
|
|
|
return;
|
|
}
|
|
static void xconfig_type_fini(objtype_t* typeval) { return; }
|
|
|
|
static void* xgroup_create(objmgr_t* mgr, objtype_t* typeval, va_list ap)
|
|
{
|
|
return NULL;
|
|
}
|
|
static void xgroup_fini(void* g) { return; }
|
|
static void xgroup_type_fini(objtype_t* typeval) { return; }
|