pmix_status_t pmix_argv_append_unique_nosize(char ***argv, const char *arg, bool overwrite) { int i; /* if the provided array is NULL, then the arg cannot be present, * so just go ahead and append */ if (NULL == *argv) { return pmix_argv_append_nosize(argv, arg); } /* see if this arg is already present in the array */ for (i=0; NULL != (*argv)[i]; i++) { if (0 == strcmp(arg, (*argv)[i])) { /* already exists - are we authorized to overwrite? */ if (overwrite) { free((*argv)[i]); (*argv)[i] = strdup(arg); } return PMIX_SUCCESS; } } /* we get here if the arg is not in the array - so add it */ return pmix_argv_append_nosize(argv, arg); }
PMIX_EXPORT pmix_status_t PMIx_Lookup(pmix_pdata_t pdata[], size_t ndata, const pmix_info_t info[], size_t ninfo) { pmix_status_t rc; pmix_cb_t *cb; char **keys = NULL; size_t i; PMIX_ACQUIRE_THREAD(&pmix_global_lock); pmix_output_verbose(2, pmix_globals.debug_output, "pmix: lookup called"); if (pmix_globals.init_cntr <= 0) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_INIT; } /* if we aren't connected, don't attempt to send */ if (!pmix_globals.connected) { PMIX_RELEASE_THREAD(&pmix_global_lock); return PMIX_ERR_UNREACH; } PMIX_RELEASE_THREAD(&pmix_global_lock); /* bozo protection */ if (NULL == pdata) { return PMIX_ERR_BAD_PARAM; } /* transfer the pdata keys to the keys argv array */ for (i=0; i < ndata; i++) { if ('\0' != pdata[i].key[0]) { pmix_argv_append_nosize(&keys, pdata[i].key); } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->cbdata = (void*)pdata; cb->nvals = ndata; if (PMIX_SUCCESS != (rc = PMIx_Lookup_nb(keys, info, ninfo, lookup_cbfunc, cb))) { PMIX_RELEASE(cb); pmix_argv_free(keys); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_THREAD(&cb->lock); /* the data has been stored in the info array by lookup_cbfunc, so * nothing more for us to do */ rc = cb->status; PMIX_RELEASE(cb); return rc; }
int PMI2_Job_Spawn(int count, const char * cmds[], int argcs[], const char ** argvs[], const int maxprocs[], const int info_keyval_sizes[], const PMI_keyval_t *info_keyval_vectors[], int preput_keyval_size, const PMI_keyval_t *preput_keyval_vector[], char jobId[], int jobIdSize, int errors[]) { pmix_status_t rc = PMIX_SUCCESS; pmix_app_t *apps; int i, k; size_t j; char *evar; PMI2_CHECK(); if (NULL == cmds) { return PMI2_ERR_INVALID_ARGS; } /* setup the apps */ PMIX_APP_CREATE(apps, count); for (i=0; i < count; i++) { apps[i].cmd = strdup(cmds[i]); apps[i].maxprocs = maxprocs[i]; apps[i].argv = pmix_argv_copy((char**)argvs[i]); apps[i].argc = pmix_argv_count(apps[i].argv); apps[i].ninfo = info_keyval_sizes[i]; apps[i].info = (pmix_info_t*)malloc(apps[i].ninfo * sizeof(pmix_info_t)); /* copy the info objects */ for (j=0; j < apps[i].ninfo; j++) { (void)strncpy(apps[i].info[j].key, info_keyval_vectors[i][j].key, PMIX_MAX_KEYLEN); apps[i].info[j].value.type = PMIX_STRING; apps[i].info[j].value.data.string = strdup(info_keyval_vectors[i][j].val); } /* push the preput values into the apps environ */ for (k=0; k < preput_keyval_size; k++) { (void)asprintf(&evar, "%s=%s", preput_keyval_vector[j]->key, preput_keyval_vector[j]->val); pmix_argv_append_nosize(&apps[i].env, evar); free(evar); } } rc = PMIx_Spawn(NULL, 0, apps, count, NULL); /* tear down the apps array */ for (i=0; i < count; i++) { PMIX_APP_DESTRUCT(&apps[i]); } free(apps); if (NULL != errors) { for (i=0; i < count; i++) { errors[i] = convert_err(rc); } } return convert_err(rc); }
/* * Process a single MCA argument. */ static int process_arg(const char *param, const char *value, char ***params, char ***values) { int i; char *p1; /* check for quoted value */ if ('\"' == value[0] && '\"' == value[strlen(value)-1]) { p1 = strdup(&value[1]); p1[strlen(p1)-1] = '\0'; } else { p1 = strdup(value); } /* Look to see if we've already got an -mca argument for the same param. Check against the list of MCA param's that we've already saved arguments for - if found, return an error. */ for (i = 0; NULL != *params && NULL != (*params)[i]; ++i) { if (0 == strcmp(param, (*params)[i])) { /* cannot use show_help here as it may not get out prior * to the process exiting */ fprintf(stderr, "---------------------------------------------------------------------------\n" "The following MCA parameter has been listed multiple times on the\n" "command line:\n\n" " MCA param: %s\n\n" "MCA parameters can only be listed once on a command line to ensure there\n" "is no ambiguity as to its value. Please correct the situation and\n" "try again.\n" "---------------------------------------------------------------------------\n", param); free(p1); return PMIX_ERROR; } } /* If we didn't already have an value for the same param, save this one away */ pmix_argv_append_nosize(params, param); pmix_argv_append_nosize(values, p1); free(p1); return PMIX_SUCCESS; }
static pmix_status_t pmix_regex_extract_ppn(char *regexp, char ***procs) { char **rngs, **nds, *t, **ps=NULL; int i, j, k, start, end; /* split on semi-colons for nodes */ nds = pmix_argv_split(regexp, ';'); for (j=0; NULL != nds[j]; j++) { /* for each node, split it by comma */ rngs = pmix_argv_split(nds[j], ','); /* parse each element */ for (i=0; NULL != rngs[i]; i++) { /* look for a range */ if (NULL == (t = strchr(rngs[i], '-'))) { /* just one value */ pmix_argv_append_nosize(&ps, rngs[i]); } else { /* handle the range */ *t = '\0'; start = strtol(rngs[i], NULL, 10); ++t; end = strtol(t, NULL, 10); for (k=start; k <= end; k++) { asprintf(&t, "%d", k); pmix_argv_append_nosize(&ps, t); free(t); } } } pmix_argv_free(rngs); /* create the node entry */ t = pmix_argv_join(ps, ','); pmix_argv_append_nosize(procs, t); free(t); pmix_argv_free(ps); ps = NULL; } pmix_argv_free(nds); return PMIX_SUCCESS; }
/* * Append a string to the end of a new or existing argv array. */ pmix_status_t pmix_argv_append(int *argc, char ***argv, const char *arg) { pmix_status_t rc; /* add the new element */ if (PMIX_SUCCESS != (rc = pmix_argv_append_nosize(argv, arg))) { return rc; } *argc = pmix_argv_count(*argv); return PMIX_SUCCESS; }
int PMIx_Lookup(pmix_data_range_t scope, const pmix_info_t info[], size_t ninfo, pmix_pdata_t pdata[], size_t ndata) { int rc; pmix_cb_t *cb; char **keys = NULL; size_t i; pmix_output_verbose(2, pmix_globals.debug_output, "pmix: lookup called"); /* bozo protection */ if (NULL == pdata) { return PMIX_ERR_BAD_PARAM; } /* transfer the pdata keys to the keys argv array */ for (i=0; i < ndata; i++) { if ('\0' != pdata[i].key[0]) { pmix_argv_append_nosize(&keys, pdata[i].key); } } /* create a callback object as we need to pass it to the * recv routine so we know which callback to use when * the return message is recvd */ cb = PMIX_NEW(pmix_cb_t); cb->cbdata = (void*)pdata; cb->nvals = ndata; cb->active = true; if (PMIX_SUCCESS != (rc = PMIx_Lookup_nb(scope, keys, info, ninfo, lookup_cbfunc, cb))) { PMIX_RELEASE(cb); pmix_argv_free(keys); return rc; } /* wait for the server to ack our request */ PMIX_WAIT_FOR_COMPLETION(cb->active); /* the data has been stored in the info array by lookup_cbfunc, so * nothing more for us to do */ rc = cb->status; PMIX_RELEASE(cb); return rc; }
/* * Parse a single range in a set and add the full names of the values * found to the names argv * * @param base The base text of the value name * @param *ranges A pointer to a single range. (i.e. "1-3" or "5") * @param ***names An argv array to add the newly discovered values to */ static pmix_status_t regex_parse_value_range(char *base, char *range, int num_digits, char *suffix, char ***names) { char *str, tmp[132]; size_t i, k, start, end; size_t base_len, len; bool found; pmix_status_t ret; if (NULL == base || NULL == range) { return PMIX_ERROR; } len = strlen(range); base_len = strlen(base); /* Silence compiler warnings; start and end are always assigned properly, below */ start = end = 0; /* Look for the beginning of the first number */ for (found = false, i = 0; i < len; ++i) { if (isdigit((int) range[i])) { if (!found) { start = atoi(range + i); found = true; break; } } } if (!found) { PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); return PMIX_ERR_NOT_FOUND; } /* Look for the end of the first number */ for (found = false; i < len; ++i) { if (!isdigit(range[i])) { break; } } /* Was there no range, just a single number? */ if (i >= len) { end = start; found = true; } else { /* Nope, there was a range. Look for the beginning of the second * number */ for (; i < len; ++i) { if (isdigit(range[i])) { end = strtol(range + i, NULL, 10); found = true; break; } } } if (!found) { PMIX_ERROR_LOG(PMIX_ERR_NOT_FOUND); return PMIX_ERR_NOT_FOUND; } /* Make strings for all values in the range */ len = base_len + num_digits + 32; if (NULL != suffix) { len += strlen(suffix); } str = (char *) malloc(len); if (NULL == str) { PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); return PMIX_ERR_OUT_OF_RESOURCE; } for (i = start; i <= end; ++i) { memset(str, 0, len); strcpy(str, base); /* we need to zero-pad the digits */ for (k=0; k < (size_t)num_digits; k++) { str[k+base_len] = '0'; } memset(tmp, 0, 132); snprintf(tmp, 132, "%lu", (unsigned long)i); for (k=0; k < strlen(tmp); k++) { str[base_len + num_digits - k - 1] = tmp[strlen(tmp)-k-1]; } /* if there is a suffix, add it */ if (NULL != suffix) { strcat(str, suffix); } ret = pmix_argv_append_nosize(names, str); if(PMIX_SUCCESS != ret) { PMIX_ERROR_LOG(ret); free(str); return ret; } } free(str); /* All done */ return PMIX_SUCCESS; }
static pmix_status_t pmix_regex_extract_nodes(char *regexp, char ***names) { int i, j, k, len; pmix_status_t ret; char *base; char *orig, *suffix; bool found_range = false; bool more_to_come = false; int num_digits; /* set the default */ *names = NULL; if (NULL == regexp) { return PMIX_SUCCESS; } orig = base = strdup(regexp); if (NULL == base) { PMIX_ERROR_LOG(PMIX_ERR_OUT_OF_RESOURCE); return PMIX_ERR_OUT_OF_RESOURCE; } PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, "pmix:extract:nodes: checking list: %s", regexp)); do { /* Find the base */ len = strlen(base); for (i = 0; i <= len; ++i) { if (base[i] == '[') { /* we found a range. this gets dealt with below */ base[i] = '\0'; found_range = true; break; } if (base[i] == ',') { /* we found a singleton value, and there are more to come */ base[i] = '\0'; found_range = false; more_to_come = true; break; } if (base[i] == '\0') { /* we found a singleton value */ found_range = false; more_to_come = false; break; } } if (i == 0 && !found_range) { /* we found a special character at the beginning of the string */ free(orig); return PMIX_ERR_BAD_PARAM; } if (found_range) { /* If we found a range, get the number of digits in the numbers */ i++; /* step over the [ */ for (j=i; j < len; j++) { if (base[j] == ':') { base[j] = '\0'; break; } } if (j >= len) { /* we didn't find the number of digits */ free(orig); return PMIX_ERR_BAD_PARAM; } num_digits = strtol(&base[i], NULL, 10); i = j + 1; /* step over the : */ /* now find the end of the range */ for (j = i; j < len; ++j) { if (base[j] == ']') { base[j] = '\0'; break; } } if (j >= len) { /* we didn't find the end of the range */ free(orig); return PMIX_ERR_BAD_PARAM; } /* check for a suffix */ if (j+1 < len && base[j+1] != ',') { /* find the next comma, if present */ for (k=j+1; k < len && base[k] != ','; k++); if (k < len) { base[k] = '\0'; } suffix = strdup(&base[j+1]); if (k < len) { base[k] = ','; } j = k-1; } else { suffix = NULL; } PMIX_OUTPUT_VERBOSE((1, pmix_globals.debug_output, "regex:extract:nodes: parsing range %s %s %s", base, base + i, suffix)); ret = regex_parse_value_ranges(base, base + i, num_digits, suffix, names); if (NULL != suffix) { free(suffix); } if (PMIX_SUCCESS != ret) { free(orig); return ret; } if (j+1 < len && base[j + 1] == ',') { more_to_come = true; base = &base[j + 2]; } else { more_to_come = false; } } else { /* If we didn't find a range, just add the value */ if(PMIX_SUCCESS != (ret = pmix_argv_append_nosize(names, base))) { PMIX_ERROR_LOG(ret); free(orig); return ret; } /* step over the comma */ i++; /* set base equal to the (possible) next base to look at */ base = &base[i]; } } while(more_to_come); free(orig); /* All done */ return ret; }
int main(int argc, char **argv) { int rc; pmix_value_t value; pmix_value_t *val = &value; pmix_proc_t proc; uint32_t nprocs; char nsp2[PMIX_MAX_NSLEN+1]; pmix_app_t *app; char hostname[PMIX_MAXHOSTNAMELEN]; pmix_proc_t *peers; size_t npeers, ntmp=0; char *nodelist; gethostname(hostname, sizeof(hostname)); /* init us */ if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %d", myproc.nspace, myproc.rank, rc); exit(0); } pmix_output(0, "Client ns %s rank %d: Running", myproc.nspace, myproc.rank); /* get our universe size */ (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, &val))) { pmix_output(0, "Client ns %s rank %d: PMIx_Get universe size failed: %d", myproc.nspace, myproc.rank, rc); goto done; } nprocs = val->data.uint32; PMIX_VALUE_RELEASE(val); pmix_output(0, "Client %s:%d universe size %d", myproc.nspace, myproc.rank, nprocs); /* call fence to sync */ PMIX_PROC_CONSTRUCT(&proc); (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* rank=0 calls spawn */ if (0 == myproc.rank) { PMIX_APP_CREATE(app, 1); app->cmd = strdup("gumby"); app->maxprocs = 2; pmix_argv_append_nosize(&app->argv, "gumby"); pmix_argv_append_nosize(&app->argv, "-n"); pmix_argv_append_nosize(&app->argv, "2"); pmix_setenv("PMIX_ENV_VALUE", "3", true, &app->env); PMIX_INFO_CREATE(app->info, 2); (void)strncpy(app->info[0].key, "DARTH", PMIX_MAX_KEYLEN); app->info[0].value.type = PMIX_INT8; app->info[0].value.data.int8 = 12; (void)strncpy(app->info[1].key, "VADER", PMIX_MAX_KEYLEN); app->info[1].value.type = PMIX_DOUBLE; app->info[1].value.data.dval = 12.34; pmix_output(0, "Client ns %s rank %d: calling PMIx_Spawn", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Spawn(NULL, 0, app, 1, nsp2))) { pmix_output(0, "Client ns %s rank %d: PMIx_Spawn failed: %d", myproc.nspace, myproc.rank, rc); goto done; } PMIX_APP_FREE(app, 1); /* check to see if we got the expected info back */ if (0 != strncmp(nsp2, "DYNSPACE", PMIX_MAX_NSLEN)) { pmix_output(0, "Client ns %s rank %d: PMIx_Spawn returned incorrect nspace: %s", myproc.nspace, myproc.rank, nsp2); goto done; } else { pmix_output(0, "Client ns %s rank %d: PMIx_Spawn succeeded returning nspace: %s", myproc.nspace, myproc.rank, nsp2); } /* get their universe size */ (void)strncpy(proc.nspace, nsp2, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; val = NULL; if (PMIX_SUCCESS != (rc = PMIx_Get(&proc, PMIX_UNIV_SIZE, NULL, 0, &val)) || NULL == val) { pmix_output(0, "Client ns %s rank %d: PMIx_Get universe size failed: %d", myproc.nspace, myproc.rank, rc); goto done; } ntmp = val->data.uint32; PMIX_VALUE_RELEASE(val); pmix_output(0, "Client %s:%d universe %s size %d", myproc.nspace, myproc.rank, nsp2, (int)ntmp); } /* just cycle the connect/disconnect functions */ if (PMIX_SUCCESS != (rc = PMIx_Connect(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Connect failed: %d", myproc.nspace, myproc.rank, rc); goto done; } pmix_output(0, "Client ns %s rank %d: PMIx_Connect succeeded", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Disconnect(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Disonnect failed: %d", myproc.nspace, myproc.rank, rc); goto done; } pmix_output(0, "Client ns %s rank %d: PMIx_Disconnect succeeded", myproc.nspace, myproc.rank); /* finally, test the resolve functions */ if (0 == myproc.rank) { if (PMIX_SUCCESS != (rc = PMIx_Resolve_peers(hostname, NULL, &peers, &npeers))) { pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_peers failed for nspace %s: %d", myproc.nspace, myproc.rank, nsp2, rc); goto done; } if ((nprocs+ntmp) != npeers) { pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_peers returned incorrect npeers: %d vs %d", myproc.nspace, myproc.rank, (int)(nprocs+ntmp), (int)npeers); goto done; } pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_peers returned %d npeers", myproc.nspace, myproc.rank, (int)npeers); if (PMIX_SUCCESS != (rc = PMIx_Resolve_nodes(nsp2, &nodelist))) { pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_nodes failed for nspace %s: %d", myproc.nspace, myproc.rank, nsp2, rc); goto done; } pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_nodes %s", myproc.nspace, myproc.rank, nodelist); } else { if (PMIX_SUCCESS != (rc = PMIx_Resolve_peers(hostname, myproc.nspace, &peers, &npeers))) { pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_peers failed for nspace %s: %d", myproc.nspace, myproc.rank, myproc.nspace, rc); goto done; } if (nprocs != npeers) { pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_peers returned incorrect npeers: %d vs %d", myproc.nspace, myproc.rank, nprocs, (int)npeers); goto done; } pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_peers returned %d npeers", myproc.nspace, myproc.rank, (int)npeers); if (PMIX_SUCCESS != (rc = PMIx_Resolve_nodes(myproc.nspace, &nodelist))) { pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_nodes failed: %d", myproc.nspace, myproc.rank, rc); goto done; } pmix_output(0, "Client ns %s rank %d: PMIx_Resolve_nodes %s", myproc.nspace, myproc.rank, nodelist); } PMIX_PROC_FREE(peers, npeers); free(nodelist); done: /* call fence to sync */ PMIX_PROC_CONSTRUCT(&proc); (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* finalize us */ pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Finalize(NULL, 0))) { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc); } else { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank); } fflush(stderr); return(0); }
int main(int argc, char **argv) { int rc; pmix_value_t value; pmix_value_t *val = &value; pmix_proc_t proc; uint32_t nprocs; pmix_info_t *info; pmix_pdata_t *pdata; pmix_proc_t myproc; /* init us */ if (PMIX_SUCCESS != (rc = PMIx_Init(&myproc))) { pmix_output(0, "Client ns %s rank %d: PMIx_Init failed: %d", myproc.nspace, myproc.rank, rc); exit(0); } pmix_output(0, "Client ns %s rank %d: Running", myproc.nspace, myproc.rank); /* get our universe size */ if (PMIX_SUCCESS != (rc = PMIx_Get(&myproc, PMIX_UNIV_SIZE, NULL, 0, &val))) { pmix_output(0, "Client ns %s rank %d: PMIx_Get universe size failed: %d", myproc.nspace, myproc.rank, rc); goto done; } nprocs = val->data.uint32; PMIX_VALUE_RELEASE(val); pmix_output(0, "Client %s:%d universe size %d", myproc.nspace, myproc.rank, nprocs); /* call fence to ensure the data is received */ PMIX_PROC_CONSTRUCT(&proc); (void)strncpy(proc.nspace, myproc.nspace, PMIX_MAX_NSLEN); proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* publish something */ if (0 == myproc.rank) { PMIX_INFO_CREATE(info, 2); (void)strncpy(info[0].key, "FOOBAR", PMIX_MAX_KEYLEN); info[0].value.type = PMIX_UINT8; info[0].value.data.uint8 = 1; (void)strncpy(info[1].key, "PANDA", PMIX_MAX_KEYLEN); info[1].value.type = PMIX_SIZE; info[1].value.data.size = 123456; if (PMIX_SUCCESS != (rc = PMIx_Publish(info, 2))) { pmix_output(0, "Client ns %s rank %d: PMIx_Publish failed: %d", myproc.nspace, myproc.rank, rc); goto done; } PMIX_INFO_FREE(info, 2); } /* call fence again so all procs know the data * has been published */ if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* lookup something */ if (0 != myproc.rank) { PMIX_PDATA_CREATE(pdata, 1); (void)strncpy(pdata[0].key, "FOOBAR", PMIX_MAX_KEYLEN); if (PMIX_SUCCESS != (rc = PMIx_Lookup(pdata, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Lookup failed: %d", myproc.nspace, myproc.rank, rc); goto done; } /* check the return for value and source */ if (0 != strncmp(myproc.nspace, pdata[0].proc.nspace, PMIX_MAX_NSLEN)) { pmix_output(0, "Client ns %s rank %d: PMIx_Lookup returned wrong nspace: %s", myproc.nspace, myproc.rank, pdata[0].proc.nspace); goto done; } if (0 != pdata[0].proc.rank) { pmix_output(0, "Client ns %s rank %d: PMIx_Lookup returned wrong rank: %d", myproc.nspace, myproc.rank, pdata[0].proc.rank); goto done; } if (PMIX_UINT8 != pdata[0].value.type) { pmix_output(0, "Client ns %s rank %d: PMIx_Lookup returned wrong type: %d", myproc.nspace, myproc.rank, pdata[0].value.type); goto done; } if (1 != pdata[0].value.data.uint8) { pmix_output(0, "Client ns %s rank %d: PMIx_Lookup returned wrong value: %d", myproc.nspace, myproc.rank, (int)pdata[0].value.data.uint8); goto done; } PMIX_PDATA_FREE(pdata, 1); pmix_output(0, "PUBLISH-LOOKUP SUCCEEDED"); } /* call fence again so rank 0 waits before leaving */ if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } if (0 == myproc.rank) { char **keys = NULL; pmix_argv_append_nosize(&keys, "FOOBAR"); pmix_argv_append_nosize(&keys, "PANDA"); if (PMIX_SUCCESS != (rc = PMIx_Unpublish(keys, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Unpublish failed: %d", myproc.nspace, myproc.rank, rc); goto done; } pmix_output(0, "UNPUBLISH SUCCEEDED"); } /* call fence again so everyone waits for rank 0 before leaving */ proc.rank = PMIX_RANK_WILDCARD; if (PMIX_SUCCESS != (rc = PMIx_Fence(&proc, 1, NULL, 0))) { pmix_output(0, "Client ns %s rank %d: PMIx_Fence failed: %d", myproc.nspace, myproc.rank, rc); goto done; } done: /* finalize us */ pmix_output(0, "Client ns %s rank %d: Finalizing", myproc.nspace, myproc.rank); if (PMIX_SUCCESS != (rc = PMIx_Finalize())) { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize failed: %d\n", myproc.nspace, myproc.rank, rc); } else { fprintf(stderr, "Client ns %s rank %d:PMIx_Finalize successfully completed\n", myproc.nspace, myproc.rank); } fflush(stderr); return(0); }
/* * Scan all the files in a directory (or path) and invoke a callback * on each one. */ static int pdlopen_foreachfile(const char *search_path, int (*func)(const char *filename, void *data), void *data) { int ret; DIR *dp = NULL; char **dirs = NULL; char **good_files = NULL; dirs = pmix_argv_split(search_path, PMIX_ENV_SEP); for (int i = 0; NULL != dirs && NULL != dirs[i]; ++i) { dp = opendir(dirs[i]); if (NULL == dp) { ret = PMIX_ERR_IN_ERRNO; goto error; } struct dirent *de; while (NULL != (de = readdir(dp))) { /* Make the absolute path name */ char *abs_name = NULL; ret = asprintf(&abs_name, "%s/%s", dirs[i], de->d_name); if (0 > ret) { return PMIX_ERR_NOMEM; } if (NULL == abs_name) { ret = PMIX_ERR_IN_ERRNO; goto error; } /* Stat the file */ struct stat buf; if (stat(abs_name, &buf) < 0) { free(abs_name); ret = PMIX_ERR_IN_ERRNO; goto error; } /* Skip if not a file */ if (!S_ISREG(buf.st_mode)) { free(abs_name); continue; } /* Find the suffix */ char *ptr = strrchr(abs_name, '.'); if (NULL != ptr) { /* Skip libtool files */ if (strcmp(ptr, ".la") == 0 || strcmp(ptr, ".lo") == 0) { free (abs_name); continue; } *ptr = '\0'; } /* Have we already found this file? Or already found a file with the same basename (but different suffix)? */ bool found = false; for (int j = 0; NULL != good_files && NULL != good_files[j]; ++j) { if (strcmp(good_files[j], abs_name) == 0) { found = true; break; } } if (!found) { pmix_argv_append_nosize(&good_files, abs_name); } free(abs_name); } closedir(dp); } dp = NULL; /* Invoke the callback on all the found files */ if (NULL != good_files) { for (int i = 0; NULL != good_files[i]; ++i) { ret = func(good_files[i], data); if (PMIX_SUCCESS != ret) { goto error; } } } ret = PMIX_SUCCESS; error: if (NULL != dp) { closedir(dp); } if (NULL != dirs) { pmix_argv_free(dirs); } if (NULL != good_files) { pmix_argv_free(good_files); } return ret; }
pmix_status_t pmix_bfrop_unpack_app(pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_app_t *ptr; int32_t i, k, n, m; pmix_status_t ret; int32_t nval; char *tmp; pmix_output_verbose(20, pmix_globals.debug_output, "pmix_bfrop_unpack: %d apps", *num_vals); ptr = (pmix_app_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { /* initialize the fields */ PMIX_APP_CONSTRUCT(&ptr[i]); /* unpack cmd */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].cmd, &m, PMIX_STRING))) { return ret; } /* unpack argc */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int(buffer, &nval, &m, PMIX_INT32))) { return ret; } /* unpack argv */ for (k=0; k < nval; k++) { m=1; tmp = NULL; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { return ret; } if (NULL == tmp) { return PMIX_ERROR; } pmix_argv_append_nosize(&ptr[i].argv, tmp); free(tmp); } /* unpack env */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int32(buffer, &nval, &m, PMIX_INT32))) { return ret; } for (k=0; k < nval; k++) { m=1; tmp = NULL; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &tmp, &m, PMIX_STRING))) { return ret; } if (NULL == tmp) { return PMIX_ERROR; } pmix_argv_append_nosize(&ptr[i].env, tmp); free(tmp); } /* unpack cwd */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_string(buffer, &ptr[i].cwd, &m, PMIX_STRING))) { return ret; } /* unpack maxprocs */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_int(buffer, &ptr[i].maxprocs, &m, PMIX_INT))) { return ret; } /* unpack info array */ m=1; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_sizet(buffer, &ptr[i].ninfo, &m, PMIX_SIZE))) { return ret; } if (0 < ptr[i].ninfo) { PMIX_INFO_CREATE(ptr[i].info, ptr[i].ninfo); m = ptr[i].ninfo; if (PMIX_SUCCESS != (ret = pmix_bfrop_unpack_info(buffer, ptr[i].info, &m, PMIX_INFO))) { return ret; } } } return PMIX_SUCCESS; }
void set_client_argv(test_params *params, char ***argv) { pmix_argv_append_nosize(argv, params->binary); pmix_argv_append_nosize(argv, "-n"); if (NULL == params->np) { pmix_argv_append_nosize(argv, "1"); } else { pmix_argv_append_nosize(argv, params->np); } if( params->verbose ){ pmix_argv_append_nosize(argv, "-v"); } if (NULL != params->prefix) { pmix_argv_append_nosize(argv, "-o"); pmix_argv_append_nosize(argv, params->prefix); } if( params->early_fail ){ pmix_argv_append_nosize(argv, "--early-fail"); } if (NULL != params->fences) { pmix_argv_append_nosize(argv, "--fence"); pmix_argv_append_nosize(argv, params->fences); if (params->use_same_keys) { pmix_argv_append_nosize(argv, "--use-same-keys"); } } if (params->test_job_fence) { pmix_argv_append_nosize(argv, "--job-fence"); if (params->nonblocking) { pmix_argv_append_nosize(argv, "-nb"); } if (params->collect) { pmix_argv_append_nosize(argv, "-c"); } if (params->collect_bad) { pmix_argv_append_nosize(argv, "--collect-corrupt"); } } if (NULL != params->noise) { pmix_argv_append_nosize(argv, "--noise"); pmix_argv_append_nosize(argv, params->noise); } if (NULL != params->ns_dist) { pmix_argv_append_nosize(argv, "--ns-dist"); pmix_argv_append_nosize(argv, params->ns_dist); } if (params->test_publish) { pmix_argv_append_nosize(argv, "--test-publish"); } if (params->test_spawn) { pmix_argv_append_nosize(argv, "--test-spawn"); } if (params->test_connect) { pmix_argv_append_nosize(argv, "--test-connect"); } if (params->test_resolve_peers) { pmix_argv_append_nosize(argv, "--test-resolve-peers"); } if (params->test_error) { pmix_argv_append_nosize(argv, "--test-error"); } }
int launch_clients(int num_procs, char *binary, char *** client_env, char ***base_argv) { int n; uid_t myuid; gid_t mygid; char *ranks = NULL; char digit[MAX_DIGIT_LEN]; int rc; static int counter = 0; static int num_ns = 0; pmix_proc_t proc; TEST_VERBOSE(("Setting job info")); fill_seq_ranks_array(num_procs, counter, &ranks); if (NULL == ranks) { PMIx_server_finalize(); TEST_ERROR(("fill_seq_ranks_array failed")); return PMIX_ERROR; } (void)snprintf(proc.nspace, PMIX_MAX_NSLEN, "%s-%d", TEST_NAMESPACE, num_ns); set_namespace(num_procs, ranks, proc.nspace); if (NULL != ranks) { free(ranks); } myuid = getuid(); mygid = getgid(); /* fork/exec the test */ for (n = 0; n < num_procs; n++) { proc.rank = counter; if (PMIX_SUCCESS != (rc = PMIx_server_setup_fork(&proc, client_env))) {//n TEST_ERROR(("Server fork setup failed with error %d", rc)); PMIx_server_finalize(); cli_kill_all(); return rc; } if (PMIX_SUCCESS != (rc = PMIx_server_register_client(&proc, myuid, mygid, NULL, NULL, NULL))) {//n TEST_ERROR(("Server fork setup failed with error %d", rc)); PMIx_server_finalize(); cli_kill_all(); return rc; } cli_info[counter].pid = fork(); if (cli_info[counter].pid < 0) { TEST_ERROR(("Fork failed")); PMIx_server_finalize(); cli_kill_all(); return -1; } cli_info[counter].rank = counter;//n cli_info[counter].ns = strdup(proc.nspace); char **client_argv = pmix_argv_copy(*base_argv); /* add two last arguments: -r <rank> */ sprintf(digit, "%d", counter);//n pmix_argv_append_nosize(&client_argv, "-r"); pmix_argv_append_nosize(&client_argv, digit); pmix_argv_append_nosize(&client_argv, "-s"); pmix_argv_append_nosize(&client_argv, proc.nspace); sprintf(digit, "%d", num_procs); pmix_argv_append_nosize(&client_argv, "--ns-size"); pmix_argv_append_nosize(&client_argv, digit); sprintf(digit, "%d", num_ns); pmix_argv_append_nosize(&client_argv, "--ns-id"); pmix_argv_append_nosize(&client_argv, digit); sprintf(digit, "%d", (counter-n)); pmix_argv_append_nosize(&client_argv, "--base-rank"); pmix_argv_append_nosize(&client_argv, digit); if (cli_info[counter].pid == 0) { if( !TEST_VERBOSE_GET() ){ // Hide clients stdout // TODO: on some systems stdout is a constant, address this fclose(stdout); stdout = fopen("/dev/null","w"); } execve(binary, client_argv, *client_env); /* Does not return */ exit(0); } cli_info[counter].state = CLI_FORKED; pmix_argv_free(client_argv); counter++; } num_ns++; return PMIX_SUCCESS; }
pmix_status_t pmix_bfrops_base_unpack_app(pmix_pointer_array_t *regtypes, pmix_buffer_t *buffer, void *dest, int32_t *num_vals, pmix_data_type_t type) { pmix_app_t *ptr; int32_t i, k, n, m; pmix_status_t ret; int32_t nval; char *tmp; pmix_output_verbose(20, pmix_bfrops_base_framework.framework_output, "pmix_bfrop_unpack: %d apps", *num_vals); ptr = (pmix_app_t *) dest; n = *num_vals; for (i = 0; i < n; ++i) { /* initialize the fields */ PMIX_APP_CONSTRUCT(&ptr[i]); /* unpack cmd */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].cmd, &m, PMIX_STRING, regtypes); if (PMIX_SUCCESS != ret) { return ret; } /* unpack argc */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &nval, &m, PMIX_INT32, regtypes); if (PMIX_SUCCESS != ret) { return ret; } /* unpack argv */ for (k=0; k < nval; k++) { m=1; tmp = NULL; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &tmp, &m, PMIX_STRING, regtypes); if (PMIX_SUCCESS != ret) { return ret; } if (NULL == tmp) { return PMIX_ERROR; } pmix_argv_append_nosize(&ptr[i].argv, tmp); free(tmp); } /* unpack env */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &nval, &m, PMIX_INT32, regtypes); if (PMIX_SUCCESS != ret) { return ret; } for (k=0; k < nval; k++) { m=1; tmp = NULL; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &tmp, &m, PMIX_STRING, regtypes); if (PMIX_SUCCESS != ret) { return ret; } if (NULL == tmp) { return PMIX_ERROR; } pmix_argv_append_nosize(&ptr[i].env, tmp); free(tmp); } /* unpack cwd */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].cwd, &m, PMIX_STRING, regtypes); if (PMIX_SUCCESS != ret) { return ret; } /* unpack maxprocs */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].maxprocs, &m, PMIX_INT, regtypes); if (PMIX_SUCCESS != ret) { return ret; } /* unpack info array */ m=1; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].ninfo, &m, PMIX_SIZE, regtypes); if (PMIX_SUCCESS != ret) { return ret; } if (0 < ptr[i].ninfo) { PMIX_INFO_CREATE(ptr[i].info, ptr[i].ninfo); m = ptr[i].ninfo; PMIX_BFROPS_UNPACK_TYPE(ret, buffer, &ptr[i].info, &m, PMIX_INFO, regtypes); if (PMIX_SUCCESS != ret) { return ret; } } } return PMIX_SUCCESS; }