#include "src/include/pmix_config.h"
#include "pmix_common.h"
#include "src/include/pmix_globals.h"
#include "src/class/pmix_list.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/mca/pnet/base/base.h"
pmix_status_t pmix_pnet_base_allocate(char *nspace, pmix_info_t info[], size_t ninfo,
pmix_list_t *ilist)
{
pmix_pnet_base_active_module_t *active;
pmix_status_t rc;
pmix_namespace_t *nptr, *ns;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output, "pnet:allocate called");
if (NULL == nspace || NULL == ilist) {
return PMIX_ERR_BAD_PARAM;
}
if (0 == pmix_list_get_size(&pmix_pnet_globals.actives)) {
return PMIX_SUCCESS;
}
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);
}
if (PMIX_PEER_IS_SERVER(pmix_globals.mypeer)) {
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->allocate) {
rc = active->module->allocate(nptr, info, ninfo, ilist);
if (PMIX_SUCCESS != rc && PMIX_ERR_NOT_AVAILABLE != rc
&& PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pnet_base_setup_local_network(char *nspace, pmix_info_t info[], size_t ninfo)
{
pmix_pnet_base_active_module_t *active;
pmix_status_t rc;
pmix_namespace_t *nsp, *nsp2;
pmix_nspace_env_cache_t *ns, *ns2;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: setup_local_network called");
if (NULL == nspace) {
return PMIX_ERR_BAD_PARAM;
}
if (0 == pmix_list_get_size(&pmix_pnet_globals.actives)) {
return PMIX_SUCCESS;
}
ns = NULL;
PMIX_LIST_FOREACH (ns2, &pmix_pnet_globals.nspaces, pmix_nspace_env_cache_t) {
if (PMIX_CHECK_NSPACE(ns2->ns->nspace, nspace)) {
ns = ns2;
break;
}
}
if (NULL == ns) {
nsp = NULL;
PMIX_LIST_FOREACH (nsp2, &pmix_globals.nspaces, pmix_namespace_t) {
if (0 == strcmp(nsp2->nspace, nspace)) {
nsp = nsp2;
break;
}
}
if (NULL == nsp) {
nsp = PMIX_NEW(pmix_namespace_t);
if (NULL == nsp) {
return PMIX_ERR_NOMEM;
}
nsp->nspace = strdup(nspace);
pmix_list_append(&pmix_globals.nspaces, &nsp->super);
}
ns = PMIX_NEW(pmix_nspace_env_cache_t);
PMIX_RETAIN(nsp);
ns->ns = nsp;
pmix_list_append(&pmix_pnet_globals.nspaces, &ns->super);
}
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->setup_local_network) {
rc = active->module->setup_local_network(ns, info, ninfo);
if (PMIX_SUCCESS != rc && PMIX_ERR_NOT_AVAILABLE != rc
&& PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pnet_base_setup_fork(const pmix_proc_t *proc, char ***env)
{
pmix_nspace_env_cache_t *ns, *ns2;
pmix_envar_list_item_t *ev;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output, "pnet: setup_fork called");
if (NULL == proc || NULL == env) {
return PMIX_ERR_BAD_PARAM;
}
ns = NULL;
PMIX_LIST_FOREACH (ns2, &pmix_pnet_globals.nspaces, pmix_nspace_env_cache_t) {
if (PMIX_CHECK_NSPACE(ns2->ns->nspace, proc->nspace)) {
ns = ns2;
break;
}
}
if (NULL != ns) {
PMIX_LIST_FOREACH (ev, &ns->envars, pmix_envar_list_item_t) {
PMIx_Setenv(ev->envar.envar, ev->envar.value, true, env);
}
}
return PMIX_SUCCESS;
}
void pmix_pnet_base_child_finalized(pmix_proc_t *peer)
{
pmix_pnet_base_active_module_t *active;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: child_finalized called");
if (NULL == peer) {
PMIX_ERROR_LOG(PMIX_ERR_BAD_PARAM);
return;
}
if (0 == pmix_list_get_size(&pmix_pnet_globals.actives)) {
return;
}
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->child_finalized) {
active->module->child_finalized(peer);
}
}
return;
}
void pmix_pnet_base_local_app_finalized(pmix_namespace_t *nptr)
{
pmix_pnet_base_active_module_t *active;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: local_app_finalized called");
if (NULL == nptr) {
return;
}
if (0 == pmix_list_get_size(&pmix_pnet_globals.actives)) {
return;
}
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->local_app_finalized) {
active->module->local_app_finalized(nptr);
}
}
return;
}
void pmix_pnet_base_deregister_nspace(char *nspace)
{
pmix_pnet_base_active_module_t *active;
pmix_nspace_env_cache_t *ns, *ns2;
pmix_output_verbose(2, pmix_pnet_base_framework.framework_output,
"pnet: deregister_nspace called");
if (NULL == nspace) {
return;
}
ns = NULL;
PMIX_LIST_FOREACH (ns2, &pmix_pnet_globals.nspaces, pmix_nspace_env_cache_t) {
if (PMIX_CHECK_NSPACE(ns2->ns->nspace, nspace)) {
ns = ns2;
pmix_list_remove_item(&pmix_pnet_globals.nspaces, &ns->super);
break;
}
}
if (NULL == ns) {
return;
}
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->deregister_nspace) {
active->module->deregister_nspace(ns->ns);
}
}
PMIX_RELEASE(ns);
}
pmix_status_t pmix_pnet_base_collect_inventory(pmix_info_t directives[], size_t ndirs,
pmix_list_t *inventory)
{
pmix_pnet_base_active_module_t *active;
pmix_status_t rc;
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->collect_inventory) {
pmix_output_verbose(5, pmix_pnet_base_framework.framework_output, "COLLECTING %s",
active->module->name);
rc = active->module->collect_inventory(directives, ndirs, inventory);
if (PMIX_SUCCESS != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pnet_base_deliver_inventory(pmix_info_t info[], size_t ninfo,
pmix_info_t directives[], size_t ndirs)
{
pmix_pnet_base_active_module_t *active;
pmix_status_t rc;
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->deliver_inventory) {
pmix_output_verbose(5, pmix_pnet_base_framework.framework_output, "DELIVERING TO %s",
active->module->name);
rc = active->module->deliver_inventory(info, ninfo, directives, ndirs);
if (PMIX_SUCCESS != rc) {
return rc;
}
}
}
return PMIX_SUCCESS;
}
pmix_status_t pmix_pnet_base_register_fabric(pmix_fabric_t *fabric, const pmix_info_t directives[],
size_t ndirs, pmix_op_cbfunc_t cbfunc, void *cbdata)
{
pmix_pnet_base_active_module_t *active;
pmix_status_t rc;
pmix_pnet_fabric_t *ft;
fabric->info = NULL;
fabric->ninfo = 0;
fabric->module = NULL;
if (0 == pmix_list_get_size(&pmix_pnet_globals.actives)) {
return PMIX_ERR_NOT_SUPPORTED;
}
PMIX_LIST_FOREACH (active, &pmix_pnet_globals.actives, pmix_pnet_base_active_module_t) {
if (NULL != active->module->register_fabric) {
rc = active->module->register_fabric(fabric, directives, ndirs, cbfunc, cbdata);
if (PMIX_OPERATION_SUCCEEDED == rc) {
ft = PMIX_NEW(pmix_pnet_fabric_t);
ft->index = fabric->index;
if (NULL != fabric->name) {
ft->name = strdup(fabric->name);
}
ft->module = active->module;
pmix_list_append(&pmix_pnet_globals.fabrics, &ft->super);
return rc;
} else if (PMIX_ERR_TAKE_NEXT_OPTION != rc) {
return rc;
}
}
}
return PMIX_ERR_NOT_FOUND;
}
pmix_status_t pmix_pnet_base_update_fabric(pmix_fabric_t *fabric)
{
pmix_status_t rc = PMIX_SUCCESS;
pmix_pnet_fabric_t *active;
pmix_pnet_module_t *module = NULL;
pmix_pnet_fabric_t *ft;
if (NULL == fabric) {
return PMIX_ERR_BAD_PARAM;
} else if (NULL == fabric->module) {
PMIX_LIST_FOREACH (ft, &pmix_pnet_globals.fabrics, pmix_pnet_fabric_t) {
if (fabric->index == ft->index) {
module = ft->module;
} else if (NULL != fabric->name && NULL != ft->name
&& 0 == strcmp(ft->name, fabric->name)) {
module = ft->module;
}
}
} else {
active = (pmix_pnet_fabric_t *) fabric->module;
module = (pmix_pnet_module_t *) active->module;
}
if (NULL == module) {
return PMIX_ERR_BAD_PARAM;
}
if (NULL != module->update_fabric) {
rc = module->update_fabric(fabric);
}
return rc;
}
pmix_status_t pmix_pnet_base_deregister_fabric(pmix_fabric_t *fabric)
{
pmix_status_t rc = PMIX_SUCCESS;
pmix_pnet_fabric_t *active;
pmix_pnet_module_t *module = NULL;
pmix_pnet_fabric_t *ft;
if (NULL == fabric) {
return PMIX_ERR_BAD_PARAM;
} else if (NULL == fabric->module) {
PMIX_LIST_FOREACH (ft, &pmix_pnet_globals.fabrics, pmix_pnet_fabric_t) {
if (fabric->index == ft->index) {
module = ft->module;
} else if (NULL != fabric->name && NULL != ft->name
&& 0 == strcmp(ft->name, fabric->name)) {
module = ft->module;
}
}
} else {
active = (pmix_pnet_fabric_t *) fabric->module;
module = (pmix_pnet_module_t *) active->module;
}
if (NULL == module) {
return PMIX_ERR_BAD_PARAM;
}
if (NULL != module->deregister_fabric) {
rc = module->deregister_fabric(fabric);
}
return rc;
}