#include "config.h" #include #include #include #include #include "cluster.h" #include "xce/cluster_def.h" static int do_update_resvals(cluster_t* c, endpoint_t* ep, xce_request_t* request) { ep_private_t* priv = NULL; int rc = -EPERM; xce_reply_t reply; priv = (ep_private_t*)ep->data; TRACE("endpoint %p priv data %p", ep, priv); init_reply_by_req(&reply, request); if (priv != NULL) { int idx = priv->u.idx; if ((priv->role == HostRole_worker) && (idx >= 0)) { worker_t* w = NULL; rc = vget(c->workermgr, idx, (void**)&w); if (w == NULL) { rc = -E_XCE_BAD_WORKER; } else { xce_update_data_t* updatemsg = request->body.updatemsg; xce_resval_list_t* resvals = updatemsg->data.resvals; xce_resval_list_t applied = { .count = 0, .vals = NULL }; /* bug-1583: the AFTER_EVENT listeners (scheduler push, * apiserver store) must only hear about the values this * controller actually accepted -- not the raw client list, * which may name resources it rejected. `applied` borrows * pointers into `resvals`; nothing changes ownership. */ if ((resvals != NULL) && (resvals->count > 0)) { applied.vals = (xce_resval_t**)calloc( (size_t)resvals->count, sizeof(xce_resval_t*)); } xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_RESOURCE, HOOK_BEFORE_EVENT, HOOK_DETAIL_RESOURCE_UPDATE, c, resvals); rc = update_resval_list(c, w, resvals, (applied.vals != NULL) ? &applied : NULL); if (applied.count > 0) { xce_run_hooks(&(c->hooksys), XCE_CONTROLLER_HOOK_RESOURCE, HOOK_AFTER_EVENT, HOOK_DETAIL_RESOURCE_UPDATE, c, &applied); } free(applied.vals); } } } reply.status = rc; reply.data_which = RequestReply_data_nodata; xce_reply(ep, c->myhost, &reply); return 0; } static int do_update_jobrusage(cluster_t* c, endpoint_t* ep, xce_request_t* request) { int rc = 0; xce_reply_t reply; init_reply_by_req(&reply, request); rc = update_job_rusages(c, ep, request); reply.status = rc; reply.data_which = RequestReply_data_nodata; xce_reply(ep, c->myhost, &reply); return rc; } int do_update_op(cluster_t* c, endpoint_t* ep, xce_request_t* request) { int rc = 0; xce_reply_t reply; init_reply_by_req(&reply, request); switch (request->body.updatemsg->table) { case Update_data_resvals: rc = do_update_resvals(c, ep, request); break; case Update_data_jobrusages: rc = do_update_jobrusage(c, ep, request); break; default: rc = -ENOENT; reply.status = rc; reply.data_which = RequestReply_data_nodata; xce_reply(ep, c->myhost, &reply); break; } return rc; }