extern int spawn_req_unpack(spawn_req_t **req_ptr, Buf buf) { spawn_req_t *req = NULL; spawn_subcmd_t *subcmd = NULL; uint32_t temp32; int i, j; void *auth_cred; uid_t auth_uid, my_uid; auth_cred = g_slurm_auth_unpack(buf); if (auth_cred == NULL) { error("authentication: %s", g_slurm_auth_errstr(g_slurm_auth_errno(NULL)) ); return SLURM_ERROR; } auth_uid = g_slurm_auth_get_uid(auth_cred, NULL); (void) g_slurm_auth_destroy(auth_cred); my_uid = getuid(); if ((auth_uid != 0) && (auth_uid != my_uid)) { error("mpi/pmi2: spawn request apparently from uid %u", (uint32_t) auth_uid); return SLURM_ERROR; } req = xmalloc(sizeof(spawn_req_t)); safe_unpack32(&req->seq, buf); safe_unpackstr_xmalloc(&req->from_node, &temp32, buf); safe_unpack32(&req->subcmd_cnt, buf); /* subcmd_cnt must be greater than 0 */ req->subcmds = xmalloc(req->subcmd_cnt * sizeof(spawn_subcmd_t *)); safe_unpack32(&req->preput_cnt, buf); if (req->preput_cnt > 0) { req->pp_keys = xmalloc(req->preput_cnt * sizeof(char *)); req->pp_vals = xmalloc(req->preput_cnt * sizeof(char *)); for (i = 0; i < req->preput_cnt; i ++) { safe_unpackstr_xmalloc(&req->pp_keys[i], &temp32, buf); safe_unpackstr_xmalloc(&req->pp_vals[i], &temp32, buf); } } for (i = 0; i < req->subcmd_cnt; i ++) { req->subcmds[i] = spawn_subcmd_new(); subcmd = req->subcmds[i]; safe_unpackstr_xmalloc(&(subcmd->cmd), &temp32, buf); safe_unpack32(&(subcmd->max_procs), buf); safe_unpack32(&(subcmd->argc), buf); if (subcmd->argc > 0) { subcmd->argv = xmalloc(subcmd->argc * sizeof(char *)); for (j = 0; j < subcmd->argc; j ++) { safe_unpackstr_xmalloc(&(subcmd->argv[j]), &temp32, buf); } } safe_unpack32(&(subcmd->info_cnt), buf); if (subcmd->info_cnt > 0) { subcmd->info_keys = xmalloc(subcmd->info_cnt * sizeof(char *)); subcmd->info_vals = xmalloc(subcmd->info_cnt * sizeof(char *)); for (j = 0; j < subcmd->info_cnt; j ++) { safe_unpackstr_xmalloc(&(subcmd->info_keys[j]), &temp32, buf); safe_unpackstr_xmalloc(&(subcmd->info_vals[j]), &temp32, buf); } } } *req_ptr = req; return SLURM_SUCCESS; unpack_error: spawn_req_free(req); return SLURM_ERROR; }
static int _handle_mcmd(int fd, int lrank, client_req_t *req) { spawn_subcmd_t *subcmd = NULL; spawn_resp_t *spawn_resp = NULL; client_resp_t *task_resp = NULL; int spawnssofar = 0, rc = SLURM_SUCCESS, i; char buf[64]; debug3("mpi/pmi2: in _handle_mcmd"); client_req_parse_body(req); subcmd = client_req_parse_spawn_subcmd(req); debug3("mpi/pmi2: got subcmd"); client_req_get_int(req, SPAWNSSOFAR_KEY, &spawnssofar); if (spawnssofar == 1) { pmi1_spawn = spawn_req_new(); client_req_get_int(req, TOTSPAWNS_KEY, (int *)&pmi1_spawn->subcmd_cnt); pmi1_spawn->subcmds = xmalloc(pmi1_spawn->subcmd_cnt * sizeof(spawn_subcmd_t *)); client_req_get_int(req, PREPUTNUM_KEY, (int *)&pmi1_spawn->preput_cnt); pmi1_spawn->pp_keys = xmalloc(pmi1_spawn->preput_cnt * sizeof(char *)); pmi1_spawn->pp_vals = xmalloc(pmi1_spawn->preput_cnt * sizeof(char *)); for (i = 0; i < pmi1_spawn->preput_cnt; i ++) { snprintf(buf, 64, PREPUTKEY_KEY"%d", i); client_req_get_str(req, buf, &pmi1_spawn->pp_keys[i]); snprintf(buf, 64, PREPUTVAL_KEY"%d", i); client_req_get_str(req, buf, &pmi1_spawn->pp_vals[i]); } } pmi1_spawn->subcmds[spawnssofar - 1] = subcmd; if (spawnssofar == pmi1_spawn->subcmd_cnt) { debug3("mpi/pmi2: got whole spawn req"); /* a resp will be send back from srun. this will not be forwarded to the tasks */ rc = spawn_req_send_to_srun(pmi1_spawn, &spawn_resp); if (spawn_resp->rc != SLURM_SUCCESS) { task_resp = client_resp_new(); client_resp_append(task_resp, CMD_KEY"="SPAWNRESP_CMD";" RC_KEY"=%d;" ERRMSG_KEY"=spawn failed;", spawn_resp->rc); client_resp_send(task_resp, fd); client_resp_free(task_resp); spawn_resp_free(spawn_resp); spawn_req_free(pmi1_spawn); pmi1_spawn = NULL; error("mpi/pmi2: spawn failed"); rc = SLURM_ERROR; goto out; } debug("mpi/pmi2: spawn request sent to srun"); spawn_psr_enqueue(spawn_resp->seq, fd, lrank, NULL); spawn_resp_free(spawn_resp); spawn_req_free(pmi1_spawn); pmi1_spawn = NULL; } out: debug3("mpi/pmi2: out _handle_mcmd"); return rc; }
extern spawn_req_t * client_req_parse_spawn_req(client_req_t *req) { spawn_req_t *spawn_req = NULL; spawn_subcmd_t *subcmd = NULL; int i = 0, j = 0, pi = 0; /* req body already parsed */ pi = 0; if (req->pairs_cnt - pi < 5) { /* NCMDS, PREPUTCOUNT, SUBCMD, MAXPROCS, ARGC */ error("mpi/pmi2: wrong number of key-val pairs in spawn cmd"); return NULL; } spawn_req = spawn_req_new(); /* ncmds */ if (xstrcmp(MP_KEY(req, pi), NCMDS_KEY)) { error("mpi/pmi2: '" NCMDS_KEY "' expected in spawn cmd"); goto req_err; } spawn_req->subcmd_cnt = atoi(MP_VAL(req, pi)); spawn_req->subcmds = xmalloc(spawn_req->subcmd_cnt * sizeof(spawn_subcmd_t *)); pi ++; /* preputcount */ if (xstrcmp(MP_KEY(req, pi), PREPUTCOUNT_KEY)) { error("mpi/pmi2: '" PREPUTCOUNT_KEY "' expected in spawn cmd"); goto req_err; } spawn_req->preput_cnt = atoi(MP_VAL(req, pi)); pi ++; if (req->pairs_cnt - pi < ( (2 * spawn_req->preput_cnt) + (3 * spawn_req->subcmd_cnt) )) { /* <PPKEY, PPVAL>, <SUBCMD, MAXPROCS, ARGC> */ error("mpi/pmi2: wrong number of key-val pairs in spawn cmd"); goto req_err; } spawn_req->pp_keys = xmalloc(spawn_req->preput_cnt * sizeof(char *)); spawn_req->pp_vals = xmalloc(spawn_req->preput_cnt * sizeof(char *)); /* ppkey,ppval */ for (i = 0; i < spawn_req->preput_cnt; i ++) { /* ppkey */ if (xstrncmp(MP_KEY(req, pi), PPKEY_KEY, strlen(PPKEY_KEY)) || atoi((MP_KEY(req, pi) + strlen(PPKEY_KEY))) != i) { error("mpi/pmi2: '" PPKEY_KEY "%d' expected in spawn cmd", i); goto req_err; } spawn_req->pp_keys[i] = xstrdup(MP_VAL(req, pi)); pi ++; /* ppval */ if (xstrncmp(MP_KEY(req, pi), PPVAL_KEY, strlen(PPVAL_KEY)) || atoi((MP_KEY(req, pi) + strlen(PPVAL_KEY))) != i) { error("mpi/pmi2: '" PPVAL_KEY "%d' expected in spawn cmd", i); goto req_err; } spawn_req->pp_vals[i] = xstrdup(MP_VAL(req, pi)); pi ++; } /* subcmd */ for (i = 0; i < spawn_req->subcmd_cnt; i ++) { spawn_req->subcmds[i] = spawn_subcmd_new(); subcmd = spawn_req->subcmds[i]; /* subcmd */ if (xstrcmp(MP_KEY(req, pi), SUBCMD_KEY)) { error("mpi/pmi2: '" SUBCMD_KEY "' expected in spawn cmd"); goto req_err; } subcmd->cmd = xstrdup(MP_VAL(req, pi)); pi ++; /* maxprocs */ if (xstrcmp(MP_KEY(req, pi), MAXPROCS_KEY)) { error("mpi/pmi2: '" MAXPROCS_KEY "' expected in spawn cmd"); goto req_err; } subcmd->max_procs = atoi(MP_VAL(req, pi)); pi ++; /* argc */ if (xstrcmp(MP_KEY(req, pi), ARGC_KEY)) { error("mpi/pmi2: '" ARGC_KEY "' expected in spawn cmd"); goto req_err; } subcmd->argc = atoi(MP_VAL(req, pi)); pi ++; if (req->pairs_cnt - pi < ( subcmd->argc + (3 * (spawn_req->subcmd_cnt - i - 1))) ) { /* <ARGV>, <SUBCMD, MAXPROCS, ARGC> */ error("mpi/pmi2: wrong number of key-val pairs" " in spawn cmd"); goto req_err; } debug("mpi/pmi2: argc = %d", subcmd->argc); if (subcmd->argc > 0) { subcmd->argv = xmalloc(subcmd->argc * sizeof(char *)); } /* argv */ for (j = 0; j < subcmd->argc; j ++) { if (xstrncmp(MP_KEY(req, pi), ARGV_KEY, strlen(ARGV_KEY)) || atoi((MP_KEY(req, pi) + strlen(ARGV_KEY))) != j) { error("mpi/pmi2: '" ARGV_KEY "%d' expected in spawn cmd", j); goto req_err; } subcmd->argv[j] = xstrdup(MP_VAL(req, pi)); pi ++; } debug("mpi/pmi2: got argv"); /* infokeycount, optional */ if (pi == req->pairs_cnt) { if (i != spawn_req->subcmd_cnt - 1) { error("mpi/pmi2: wrong number of key-val pairs" "in spawn cmd"); goto req_err; } break; } else if (xstrcmp(MP_KEY(req, pi), INFOKEYCOUNT_KEY)) { subcmd->info_cnt = 0; continue; } subcmd->info_cnt = atoi(MP_VAL(req, pi)); pi ++; if (req->pairs_cnt - pi < ( (2 * subcmd->info_cnt) + (3 * (spawn_req->subcmd_cnt - i - 1)) )) { /* <INFOKEY, INFOVAL>, <SUBCMD, MAXPROCS, ARGC> */ error("mpi/pmi2: wrong number of key-val pairs" " in spawn cmd"); goto req_err; } if (subcmd->info_cnt > 0) { subcmd->info_keys = xmalloc(subcmd->info_cnt * sizeof(char *)); subcmd->info_vals = xmalloc(subcmd->info_cnt * sizeof(char *)); } /* infokey,infoval */ for (j = 0; j < subcmd->info_cnt; j ++) { /* infokey */ if (xstrncmp(MP_KEY(req, pi), INFOKEY_KEY, strlen(INFOKEY_KEY)) || atoi((MP_KEY(req, pi) + strlen(INFOKEY_KEY))) != j) { error("mpi/pmi2: '" INFOKEY_KEY "%d' expected in spawn cmd", j); goto req_err; } subcmd->info_keys[j] = xstrdup(MP_VAL(req, pi)); pi ++; /* infoval */ if (xstrncmp(MP_KEY(req, pi), INFOVAL_KEY, strlen(INFOVAL_KEY)) || atoi((MP_KEY(req, pi) + strlen(INFOVAL_KEY))) != j) { error("mpi/pmi2: '" INFOVAL_KEY "%d' expected in spawn cmd", j); goto req_err; } subcmd->info_vals[j] = xstrdup(MP_VAL(req, pi)); pi ++; } } debug("mpi/pmi2: out client_req_parse_spawn"); return spawn_req; req_err: spawn_req_free(spawn_req); return NULL; }