/* * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana * University Research and Technology * Corporation. All rights reserved. * Copyright (c) 2004-2006 The University of Tennessee and The University * of Tennessee Research Foundation. All rights * reserved. * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart, * University of Stuttgart. All rights reserved. * Copyright (c) 2004-2005 The Regents of the University of California. * All rights reserved. * Copyright (c) 2007 Cisco Systems, Inc. All rights reserved. * $COPYRIGHT$ * * Additional copyrights may follow * * $HEADER$ */ #include "orte_config.h" #include "orte/orte_constants.h" #include #include #include "orte/runtime/runtime.h" #include "opal/util/output.h" #include "orte/util/proc_info.h" #include "opal/util/argv.h" #include "opal/mca/mca.h" #include "opal/mca/base/base.h" #include "orte/mca/errmgr/errmgr.h" #include "orte/mca/ns/ns.h" #include "orte/mca/oob/oob.h" #include "orte/mca/oob/base/base.h" OBJ_CLASS_INSTANCE( mca_oob_t, opal_list_item_t, NULL, NULL ); OBJ_CLASS_INSTANCE( mca_oob_base_info_t, opal_list_item_t, NULL, NULL ); /** * Parse contact info string into process name and list of uri strings. */ int mca_oob_parse_contact_info( const char* contact_info, orte_process_name_t* name, char*** uri) { orte_process_name_t* proc_name; int rc; /* parse the process name */ char* cinfo = strdup(contact_info); char* ptr = strchr(cinfo, ';'); if(NULL == ptr) { ORTE_ERROR_LOG(ORTE_ERR_BAD_PARAM); free(cinfo); return ORTE_ERR_BAD_PARAM; } *ptr = '\0'; ptr++; if (ORTE_SUCCESS != (rc = orte_ns.convert_string_to_process_name(&proc_name, cinfo))) { ORTE_ERROR_LOG(rc); free(cinfo); return rc; } *name = *proc_name; free(proc_name); if (NULL != uri) { /* parse the remainder of the string into an array of uris */ *uri = opal_argv_split(ptr, ';'); } free(cinfo); return ORTE_SUCCESS; } /** * Function for selecting one module from all those that are * available. * * Call the init function on all available modules. */ int mca_oob_base_init(void) { opal_list_item_t *item; mca_base_component_list_item_t *cli; mca_oob_base_component_t *component; mca_oob_t *module; mca_oob_t *s_module = NULL; int s_priority = -1; /* Traverse the list of available modules; call their init functions. */ for (item = opal_list_get_first(&mca_oob_base_components); item != opal_list_get_end(&mca_oob_base_components); item = opal_list_get_next(item)) { mca_oob_base_info_t *inited; cli = (mca_base_component_list_item_t *) item; component = (mca_oob_base_component_t *) cli->cli_component; if (NULL == component->oob_init) { opal_output_verbose(10, mca_oob_base_output, "mca_oob_base_init: no init function; ignoring component"); } else { int priority = -1; module = component->oob_init(&priority); if (NULL != module) { inited = OBJ_NEW(mca_oob_base_info_t); inited->oob_component = component; inited->oob_module = module; opal_list_append(&mca_oob_base_modules, &inited->super); /* setup highest priority oob channel */ if(priority > s_priority) { s_priority = priority; s_module = module; } } } } /* set the global variable to point to the first initialize module */ if(s_module == NULL) { opal_output_verbose(10, mca_oob_base_output, "mca_oob_base_init: no OOB modules available\n"); return ORTE_ERROR; } mca_oob = *s_module; return ORTE_SUCCESS; } /** * Obtains the contact info (oob implementation specific) URI strings through * which this process can be contacted on an OOB channel. * * @return A null terminated string. * * The caller is responsible for freeing the returned string. */ char* mca_oob_get_my_contact_info() { char *proc_name=NULL; char *proc_addr = mca_oob.oob_get_addr(); char *contact_info=NULL; int rc; if (ORTE_SUCCESS != (rc = orte_ns.get_proc_name_string(&proc_name, orte_process_info.my_name))) { ORTE_ERROR_LOG(rc); return NULL; } if (0 > asprintf(&contact_info, "%s;%s", proc_name, proc_addr)) { ORTE_ERROR_LOG(ORTE_ERR_OUT_OF_RESOURCE); } free(proc_name); free(proc_addr); return contact_info; } /** * Setup the contact information for the seed daemon - which * is passed as an MCA parameter. * * @param seed */ int mca_oob_set_contact_info(const char* contact_info) { orte_process_name_t name; char** uri; char** ptr; int rc = mca_oob_parse_contact_info(contact_info, &name, &uri); if(rc != ORTE_SUCCESS) return rc; for(ptr = uri; ptr != NULL && *ptr != NULL; ptr++) { opal_list_item_t* item; for (item = opal_list_get_first(&mca_oob_base_modules); item != opal_list_get_end(&mca_oob_base_modules); item = opal_list_get_next(item)) { mca_oob_base_info_t* base = (mca_oob_base_info_t *) item; if (strncmp(base->oob_component->oob_base.mca_component_name, *ptr, strlen(base->oob_component->oob_base.mca_component_name)) == 0) base->oob_module->oob_set_addr(&name, *ptr); } } if(uri != NULL) { opal_argv_free(uri); } return ORTE_SUCCESS; } /** * Called to request the selected oob components to * initialize their connections to the HNP (if not an HNP), or * to setup a listener for incoming connections (if an HNP) */ int mca_oob_base_module_init(void) { opal_list_item_t* item; for (item = opal_list_get_first(&mca_oob_base_modules); item != opal_list_get_end(&mca_oob_base_modules); item = opal_list_get_next(item)) { mca_oob_base_info_t* base = (mca_oob_base_info_t *) item; if (NULL != base->oob_module->oob_init) base->oob_module->oob_init(); } return ORTE_SUCCESS; } /** * Called to have all selected oob components register their * contact info on the GPR */ int mca_oob_register_contact_info(void) { opal_list_item_t* item; int rc; for (item = opal_list_get_first(&mca_oob_base_modules); item != opal_list_get_end(&mca_oob_base_modules); item = opal_list_get_next(item)) { mca_oob_base_info_t* base = (mca_oob_base_info_t *) item; if (NULL != base->oob_module->oob_register_contact_info) { if (ORTE_SUCCESS != (rc = base->oob_module->oob_register_contact_info())) { ORTE_ERROR_LOG(rc); return rc; } } } return ORTE_SUCCESS; } /** * Called to have all selected oob components register a subscription * to receive their required contact info from all processes in the * specified job when the provided trigger fires */ int mca_oob_register_subscription(orte_jobid_t job, char *trigger) { opal_list_item_t* item; int rc; for (item = opal_list_get_first(&mca_oob_base_modules); item != opal_list_get_end(&mca_oob_base_modules); item = opal_list_get_next(item)) { mca_oob_base_info_t* base = (mca_oob_base_info_t *) item; if (NULL != base->oob_module->oob_register_subscription) { if (ORTE_SUCCESS != (rc = base->oob_module->oob_register_subscription(job, trigger))) { ORTE_ERROR_LOG(rc); return rc; } } } return ORTE_SUCCESS; } /* * Called to get contact info for a process or job from all selected * oob components */ int mca_oob_get_contact_info(orte_process_name_t *name, orte_gpr_notify_data_t **data) { opal_list_item_t* item; int rc; for (item = opal_list_get_first(&mca_oob_base_modules); item != opal_list_get_end(&mca_oob_base_modules); item = opal_list_get_next(item)) { mca_oob_base_info_t* base = (mca_oob_base_info_t *) item; if (NULL != base->oob_module->oob_get_contact_info) { if (ORTE_SUCCESS != (rc = base->oob_module->oob_get_contact_info(name, data))) { ORTE_ERROR_LOG(rc); return rc; } } } return ORTE_SUCCESS; } /* * Called to update contact info tables in all selected oob components */ void mca_oob_update_contact_info(orte_gpr_notify_data_t* data, void* cbdata) { opal_list_item_t* item; for (item = opal_list_get_first(&mca_oob_base_modules); item != opal_list_get_end(&mca_oob_base_modules); item = opal_list_get_next(item)) { mca_oob_base_info_t* base = (mca_oob_base_info_t *) item; if (NULL != base->oob_module->oob_update_contact_info) { base->oob_module->oob_update_contact_info(data, cbdata); } } }