#include #include "cluster.h" #include "request.h" #include "xce/cluster_def.h" #include "xce/types.h" typedef int (*check_fn_t)(void*); int check_controller(void* arg) { cluster_t* c = (cluster_t*)arg; if (!c->running) { return -EINVAL; } return 1; } struct intern_array_ { int count; int idx; void* data; check_fn_t checkfn; }; int not_null_check(void* arg) { if (arg == NULL) { return 0; } return 1; } static int collect_resval_with_idx_(zarray_t* array, int* nres, xce_val_with_idx_t*** resvals) { int nc; int i, j; xce_val_with_idx_t** vals; nc = 0; for (i = 0; i < array->caps; i++) { if (array->data[i] == NULL) { continue; } nc++; } if (nc == 0) { *nres = 0; *resvals = NULL; return 0; } vals = (xce_val_with_idx_t**)calloc(nc, sizeof(xce_val_with_idx_t*)); if (vals == NULL) { return -ENOMEM; } j = 0; for (i = 0; i < array->caps; i++) { xce_val_with_idx_t* val; xce_val_t* src = array->data[i]; if (array->data[i] == NULL) { continue; } val = (xce_val_with_idx_t*)calloc(1, sizeof(*val)); if (val == NULL) { free_resval_with_idx_list(&vals, j); return -ENOMEM; } vals[j] = val; j++; val->idx = i; val->val = (xce_val_t*)calloc(1, sizeof(xce_val_t)); if (val->val == NULL) { free_resval_with_idx_list(&vals, j); return -ENOMEM; } if (src->which == Value_u_svalue) { val->val->which = Value_u_svalue; if (src->u.svalue != NULL) { val->val->u.svalue = strdup(src->u.svalue); } else { val->val->u.svalue = strdup("-"); } } else { memcpy(val->val, array->data[i], sizeof(xce_val_t)); } } *nres = j; *resvals = vals; return j; } int collect_resval_with_idx(zarray_t* array, int* nres, xce_val_with_idx_t*** resvals) { int rc = 0; mylock_lock(&(array->lock)); rc = collect_resval_with_idx_(array, nres, resvals); mylock_unlock(&(array->lock)); return rc; } static int count_(void* arg1, void* arg2) { struct intern_array_* arg = (struct intern_array_*)arg1; if ((arg == NULL) || (arg->checkfn == NULL)) { return -EINVAL; } if (!(arg->checkfn(arg2))) { return 0; } arg->count++; return 0; } static int add_confvar_(void* arg1, void* arg2) { struct intern_array_* arg = (struct intern_array_*)arg1; xce_config_t** p = NULL; if ((arg == NULL) || (arg->count < 0)) { return -EINVAL; } if (arg->count == 0) { return 0; } if (!(arg->checkfn(arg2))) { return 0; } p = (xce_config_t**)arg->data; if (p == NULL) { p = (xce_config_t**)calloc(arg->count, sizeof(xce_config_t*)); if (p == NULL) { return -ENOMEM; } arg->data = p; } p[arg->idx] = (xce_config_t*)obj_ref(arg2, OBJREF_READ); arg->idx++; return 1; } void collect_confvars(cluster_t* c, collect_check_fn_t fn, int* nconfig, xce_config_t*** configs) { xlist_t lst; struct intern_array_ args = { .count = 0, .idx = 0, .data = NULL, .checkfn = (fn == NULL) ? not_null_check : fn }; int rc; *nconfig = 0; *configs = NULL; xlist_init(&lst, 3); xlist_store(&lst, count_); xlist_store(&lst, add_confvar_); rc = kvmgr_iter(&(c->configmgr), &lst, &args); xlist_fini(&lst); if (rc >= 0) { *nconfig = args.count; *configs = args.data; } } static int add_queue_(void* arg1, void* arg2) { struct intern_array_* arg = (struct intern_array_*)arg1; xce_queue_t** p = NULL; if (arg == NULL) { return -EINVAL; } if (arg->count < 0) { return -EINVAL; } if (arg->count == 0) { return 0; } if (!(arg->checkfn(arg2))) { return 0; } p = (xce_queue_t**)arg->data; if (p == NULL) { p = (xce_queue_t**)calloc(arg->count, sizeof(xce_queue_t*)); if (p == NULL) { return -ENOMEM; } arg->data = p; } p[arg->idx] = (xce_queue_t*)obj_ref(arg2, OBJREF_READ); arg->idx++; return 1; } void collect_queues(cluster_t* c, collect_check_fn_t fn, int* nqueues, xce_queue_t*** queues) { xlist_t lst; struct intern_array_ args = { .count = 0, .idx = 0, .data = NULL, .checkfn = (fn == NULL) ? not_null_check : fn }; int rc; *nqueues = 0; *queues = NULL; xlist_init(&lst, 3); xlist_store(&lst, count_); xlist_store(&lst, add_queue_); rc = qmgr_iter(&(c->qmgr), &lst, &args); xlist_fini(&lst); if (rc >= 0) { *nqueues = args.count; *queues = args.data; } } static int add_resource_(void* arg1, void* arg2) { struct intern_array_* arg = (struct intern_array_*)arg1; xce_resource_t** p = NULL; if (arg == NULL) { return -EINVAL; } if (arg->count < 0) { return -EINVAL; } if (arg->count == 0) { return 0; } if (!(arg->checkfn(arg2))) { return 0; } p = (xce_resource_t**)arg->data; if (p == NULL) { p = (xce_resource_t**)calloc(arg->count, sizeof(xce_resource_t*)); if (p == NULL) { return -ENOMEM; } arg->data = p; } p[arg->idx] = (xce_resource_t*)obj_ref(arg2, OBJREF_READ); arg->idx++; return 1; } void collect_resources(cluster_t* c, collect_check_fn_t fn, int* nresources, xce_resource_t*** resources) { xlist_t lst; struct intern_array_ args = { .count = 0, .idx = 0, .data = NULL, .checkfn = (fn == NULL) ? not_null_check : fn }; int rc; *nresources = 0; *resources = NULL; xlist_init(&lst, 3); xlist_store(&lst, count_); xlist_store(&lst, add_resource_); rc = resmgr_iter(&(c->resmgr), &lst, &args); xlist_fini(&lst); if (rc >= 0) { *nresources = args.count; *resources = args.data; } } static int add_job_(void* arg1, void* arg2) { struct intern_array_* arg = (struct intern_array_*)arg1; xce_job_t** p = NULL; if (arg == NULL) { return -EINVAL; } if (arg->count < 0) { return -EINVAL; } if (arg->count == 0) { return 0; } if (!(arg->checkfn(arg2))) { return 0; } p = (xce_job_t**)arg->data; if (p == NULL) { p = (xce_job_t**)calloc(arg->count, sizeof(xce_job_t*)); if (p == NULL) { return -ENOMEM; } arg->data = p; } p[arg->idx] = (xce_job_t*)obj_ref(arg2, OBJREF_READ); arg->idx++; return 1; } void collect_jobs(cluster_t* c, collect_check_fn_t fn, int* njobs, xce_job_t*** jobs) { xlist_t lst; struct intern_array_ args = { .count = 0, .idx = 0, .data = NULL, .checkfn = (check_fn_t)fn }; int rc = 0; *njobs = 0; *jobs = NULL; xlist_init(&lst, 3); xlist_store(&lst, count_); xlist_store(&lst, add_job_); rc = jobmgr_iter(&(c->jobmgr), &lst, &args); xlist_fini(&lst); if (rc >= 0) { *njobs = args.count; *jobs = args.data; } return; } static int add_worker_(void* arg1, void* arg2) { struct intern_array_* arg = (struct intern_array_*)arg1; xce_worker_t** p = NULL; xce_worker_t* w; if (arg == NULL) { return -EINVAL; } if (arg->count < 0) { return -EINVAL; } if (arg->count == 0) { return 0; } if (!(arg->checkfn(arg2))) { return 0; } p = (xce_worker_t**)arg->data; if (p == NULL) { p = (xce_worker_t**)calloc(arg->count, sizeof(xce_worker_t*)); if (p == NULL) { return -ENOMEM; } arg->data = p; } w = (xce_worker_t*)obj_ref(arg2, OBJREF_READ); collect_resval_with_idx(&(w->resvals), &(w->nresvals_to_sched), &(w->resvals_to_sched)); p[arg->idx] = w; arg->idx++; return 1; } void collect_workers(cluster_t* c, collect_check_fn_t fn, int* nworkers, xce_worker_t*** workers) { xlist_t lst; struct intern_array_ args = { .count = 0, .idx = 0, .data = NULL, .checkfn = (check_fn_t)fn }; int rc = 0; *nworkers = 0; *workers = NULL; xlist_init(&lst, 3); xlist_store(&lst, count_); xlist_store(&lst, add_worker_); rc = workermgr_iter(&(c->workermgr), &lst, &args); xlist_fini(&lst); if (rc >= 0) { *nworkers = args.count; *workers = args.data; } return; } void collect_shared_resvals(cluster_t* c, collect_check_fn_t fn, int* nres, xce_val_with_idx_t*** resvals) { collect_resval_with_idx(&(c->resmgr.sharedinst), nres, resvals); return; } void deref_objs(int count, void** objs) { int i; for (i = 0; i < count; i++) { void* obj = objs[i]; if (obj == NULL) { continue; } DEREF_OBJ(obj); } } int notify(cluster_t* c, endpoint_t* ep, xce_notify_data_t* data) { ioctx_t* ctx = NULL; ctx = ioctx_alloc(ep, c->myhost); if (ctx == NULL) { return -ENOMEM; } return xce_notify_req(ctx, data); }