#include "src/include/pmix_config.h"
#include <string.h>
#ifdef HAVE_UNISTD_H
# include <unistd.h>
#endif
#ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
#endif
#ifdef HAVE_SYS_STAT_H
# include <sys/stat.h>
#endif
#ifdef HAVE_FCNTL_H
# include <fcntl.h>
#endif
#ifdef HAVE_SYS_UTSNAME_H
# include <sys/utsname.h>
#endif
#include <time.h>
#include "pmix_common.h"
#include "src/include/pmix_globals.h"
#include "src/include/pmix_frameworks.h"
#include "src/class/pmix_list.h"
#include "src/mca/base/pmix_mca_base_vari.h"
#include "src/mca/preg/preg.h"
#include "src/server/pmix_server_ops.h"
#include "src/util/pmix_argv.h"
#include "src/util/pmix_error.h"
#include "src/util/pmix_environ.h"
#include "src/util/pmix_printf.h"
#include "src/mca/pmdl/base/base.h"
pmix_status_t pmix_pmdl_base_harvest_envars(char *nspace, const pmix_info_t info[], size_t ninfo,
pmix_list_t *ilist)
{
pmix_pmdl_base_active_module_t *active;
pmix_status_t rc;
pmix_namespace_t *nptr = NULL, *ns;
char *params[2] = {"PMIX_MCA_", NULL};
char **priors = NULL, *tmp;
pmix_kval_t *kv;
pmix_mca_base_var_file_value_t *fv;
if (!pmix_pmdl_globals.initialized) {
return PMIX_ERR_INIT;
}
pmix_output_verbose(2, pmix_pmdl_base_framework.framework_output,
"pmdl:harvest envars called");
if (NULL == ilist) {
return PMIX_ERR_BAD_PARAM;
}
PMIX_LIST_FOREACH(fv, &pmix_mca_base_var_file_values, pmix_mca_base_var_file_value_t) {
PMIX_KVAL_NEW(kv, PMIX_SET_ENVAR);
if (NULL == kv) {
return PMIX_ERR_NOMEM;
}
if (NULL == kv->value) {
PMIX_RELEASE(kv);
return PMIX_ERR_NOMEM;
}
kv->value->type = PMIX_ENVAR;
pmix_asprintf(&tmp, "PMIX_MCA_%s", fv->mbvfv_var);
PMIX_ENVAR_LOAD(&kv->value->data.envar, tmp, fv->mbvfv_value, ':');
free(tmp);
pmix_list_append(ilist, &kv->super);
}
PMIX_LIST_FOREACH(fv, &pmix_mca_base_var_override_values, pmix_mca_base_var_file_value_t) {
PMIX_KVAL_NEW(kv, PMIX_SET_ENVAR);
if (NULL == kv) {
return PMIX_ERR_NOMEM;
}
if (NULL == kv->value) {
PMIX_RELEASE(kv);
return PMIX_ERR_NOMEM;
}
kv->value->type = PMIX_ENVAR;
pmix_asprintf(&tmp, "PMIX_MCA_%s", fv->mbvfv_var);
PMIX_ENVAR_LOAD(&kv->value->data.envar, tmp, fv->mbvfv_value, ':');
free(tmp);
pmix_list_append(ilist, &kv->super);
}
if (NULL != nspace) {
nptr = NULL;
PMIX_LIST_FOREACH (ns, &pmix_globals.nspaces, pmix_namespace_t) {
if (0 == strcmp(ns->nspace, nspace)) {
nptr = ns;
break;
}
}
if (NULL == nptr) {
nptr = PMIX_NEW(pmix_namespace_t);
if (NULL == nptr) {
return PMIX_ERR_NOMEM;
}
nptr->nspace = strdup(nspace);
pmix_list_append(&pmix_globals.nspaces, &nptr->super);
}
}
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->harvest_envars) {
rc = active->module->harvest_envars(nptr, info, ninfo, ilist, &priors);
if (PMIX_SUCCESS != rc && PMIX_ERR_TAKE_NEXT_OPTION != rc) {
PMIx_Argv_free(priors);
return rc;
}
}
}
PMIx_Argv_free(priors);
rc = pmix_util_harvest_envars(params, NULL, ilist);
PMIX_KVAL_NEW(kv, PMIX_SET_ENVAR);
if (NULL == kv) {
return PMIX_ERR_NOMEM;
}
if (NULL == kv->value) {
PMIX_RELEASE(kv);
return PMIX_ERR_NOMEM;
}
kv->value->type = PMIX_ENVAR;
PMIX_ENVAR_LOAD(&kv->value->data.envar, "PMIX_PARAM_FILE_PASSED", "1", ':');
pmix_list_append(ilist, &kv->super);
return PMIX_SUCCESS;
}
static char *prte_frameworks_static_3_0_1[] = {
"errmgr",
"ess",
"filem",
"grpcomm",
"iof",
"odls",
"oob",
"plm",
"prtebacktrace",
"prtedl",
"prteinstalldirs",
"prtereachable",
"ras",
"rmaps",
"rml",
"routed",
"rtc",
"schizo",
"state",
"hwloc",
"if",
"reachable",
NULL,
};
static char **prte_frameworks = prte_frameworks_static_3_0_1;
static bool prte_frameworks_setup = false;
static void setup_prte_frameworks(void)
{
if (prte_frameworks_setup) {
return;
}
prte_frameworks_setup = true;
char *env = getenv("PRTE_MCA_PREFIXES");
if (NULL == env) {
return;
}
char **tmp = PMIx_Argv_split(env, ',');
if (NULL != tmp) {
prte_frameworks = tmp;
}
}
bool pmix_pmdl_base_check_prte_param(char *param)
{
char *p;
size_t n;
int len, len2;
setup_prte_frameworks();
p = strchr(param, '_');
if (NULL == p) {
len = strlen(param);
} else {
len = (int)(p - param);
}
if (0 == strncmp(param, "prte", len)) {
return true;
}
for (n=0; NULL != prte_frameworks[n]; n++) {
len2 = strlen(prte_frameworks[n]);
if (len != len2) {
continue;
}
if (0 == strncmp(param, prte_frameworks[n], len)) {
return true;
}
}
return false;
}
bool pmix_pmdl_base_check_pmix_param(char *param)
{
char *p;
size_t n;
int len, len2;
p = strchr(param, '_');
if (NULL == p) {
len = strlen(param);
} else {
len = (int)(p - param);
}
if (0 == strncmp(param, "pmix", len)) {
return true;
}
for (n=0; NULL != pmix_framework_names[n]; n++) {
len2 = strlen(pmix_framework_names[n]);
if (len != len2) {
continue;
}
if (0 == strncmp(param, pmix_framework_names[n], len)) {
return true;
}
}
return false;
}
void pmix_pmdl_base_parse_file_envars(pmix_list_t *ilist)
{
pmix_pmdl_base_active_module_t *active;
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->parse_file_envars) {
active->module->parse_file_envars(ilist);
}
}
}
pmix_status_t pmix_pmdl_base_setup_nspace(pmix_namespace_t *nptr, pmix_info_t *info)
{
pmix_pmdl_base_active_module_t *active;
pmix_status_t rc;
if (!pmix_pmdl_globals.initialized) {
return PMIX_ERR_INIT;
}
pmix_output_verbose(2, pmix_pmdl_base_framework.framework_output, "pmdl:setup_nspace called");
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->setup_nspace) {
rc = active->module->setup_nspace(nptr, info);
if (PMIX_SUCCESS != rc && PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pmdl_base_setup_nspace_kv(pmix_namespace_t *nptr, pmix_kval_t *kv)
{
pmix_pmdl_base_active_module_t *active;
pmix_status_t rc;
if (!pmix_pmdl_globals.initialized) {
return PMIX_ERR_INIT;
}
pmix_output_verbose(2, pmix_pmdl_base_framework.framework_output, "pmdl:setup_nspace called");
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->setup_nspace_kv) {
rc = active->module->setup_nspace_kv(nptr, kv);
if (PMIX_SUCCESS != rc && PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pmdl_base_register_nspace(pmix_namespace_t *nptr)
{
pmix_pmdl_base_active_module_t *active;
pmix_status_t rc;
if (!pmix_pmdl_globals.initialized) {
return PMIX_ERR_INIT;
}
pmix_output_verbose(2, pmix_pmdl_base_framework.framework_output,
"pmdl:register_nspace called");
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->register_nspace) {
rc = active->module->register_nspace(nptr);
if (PMIX_SUCCESS != rc && PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pmdl_base_setup_client(pmix_namespace_t *nptr, pmix_rank_t rank, uint32_t appnum)
{
pmix_pmdl_base_active_module_t *active;
pmix_status_t rc;
if (!pmix_pmdl_globals.initialized) {
return PMIX_ERR_INIT;
}
pmix_output_verbose(2, pmix_pmdl_base_framework.framework_output, "pmdl: setup_client called");
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->setup_client) {
rc = active->module->setup_client(nptr, rank, appnum);
if (PMIX_SUCCESS != rc && PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pmdl_base_setup_fork(const pmix_proc_t *proc, char ***env)
{
pmix_pmdl_base_active_module_t *active;
pmix_status_t rc;
char **priors = NULL;
if (!pmix_pmdl_globals.initialized) {
return PMIX_ERR_INIT;
}
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->setup_fork) {
rc = active->module->setup_fork(proc, env, &priors);
if (PMIX_SUCCESS != rc && PMIX_ERR_TAKE_NEXT_OPTION != rc) {
PMIx_Argv_free(priors);
return rc;
}
}
}
PMIx_Argv_free(priors);
return PMIX_SUCCESS;
}
void pmix_pmdl_base_deregister_nspace(const char *ns)
{
pmix_pmdl_base_active_module_t *active;
pmix_namespace_t *nptr, *n2;
if (!pmix_pmdl_globals.initialized) {
return;
}
nptr = NULL;
PMIX_LIST_FOREACH (n2, &pmix_globals.nspaces, pmix_namespace_t) {
if (0 == strncmp(ns, n2->nspace, PMIX_MAX_NSLEN)) {
nptr = n2;
break;
}
}
if (NULL == nptr) {
return;
}
PMIX_LIST_FOREACH (active, &pmix_pmdl_globals.actives, pmix_pmdl_base_active_module_t) {
if (NULL != active->module->deregister_nspace) {
active->module->deregister_nspace(nptr);
}
}
}