/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */ /* * Copyright (c) 2015-2020 Intel, Inc. All rights reserved. * Copyright (c) 2016 Mellanox Technologies, Inc. * All rights reserved. * Copyright (c) 2018 Research Organization for Information Science * and Technology (RIST). All rights reserved. * * Copyright (c) 2021-2023 Nanook Consulting. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "src/include/pmix_config.h" #include #ifdef HAVE_UNISTD_H # include #endif #ifdef HAVE_SYS_TYPES_H # include #endif #ifdef HAVE_SYS_STAT_H # include #endif #ifdef HAVE_FCNTL_H # include #endif #ifdef HAVE_SYS_UTSNAME_H # include #endif #include #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"); /* protect against bozo inputs */ if (NULL == ilist) { return PMIX_ERR_BAD_PARAM; } /* start by adding in the vars found in the default param * files, if any - this will allow the model-specific * components to override those values, if necessary */ 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; /* find this nspace - note that it may not have * been registered yet */ PMIX_LIST_FOREACH (ns, &pmix_globals.nspaces, pmix_namespace_t) { if (0 == strcmp(ns->nspace, nspace)) { nptr = ns; break; } } if (NULL == nptr) { /* add it */ 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); } } /* process the request */ 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) { /* true error */ PMIx_Argv_free(priors); return rc; } } } PMIx_Argv_free(priors); /* add any local PMIx MCA params */ rc = pmix_util_harvest_envars(params, NULL, ilist); // mark that we are passing the PMIx envars 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", // inherited from OPAL "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; } // If we found the env variable, it will be a comma-delimited list // of values. Split it into an argv-style array. 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; setup_prte_frameworks(); p = strchr(param, '_'); len = (int)(p - param); if (0 == strncmp(param, "prte", len)) { return true; } for (n=0; NULL != prte_frameworks[n]; n++) { 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; p = strchr(param, '_'); len = (int)(p - param); if (0 == strncmp(param, "pmix", len)) { return true; } for (n=0; NULL != pmix_framework_names[n]; n++) { 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; /* process the request */ 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"); /* process the request */ 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) { /* true error */ 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"); /* process the request */ 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) { /* true error */ 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"); /* process the request */ 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) { /* true error */ return rc; } } } return PMIX_SUCCESS; } /* can only be called by a server */ 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) { /* true error */ return rc; } } } return PMIX_SUCCESS; } /* can only be called by a server */ 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) { /* true error */ 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; } /* search for the namespace */ 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); } } }