|
Packit Service |
c5cf8c |
/* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil ; -*- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* (C) 2001 by Argonne National Laboratory.
|
|
Packit Service |
c5cf8c |
* See COPYRIGHT in top-level directory.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*********************** PMI implementation ********************************/
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* This file implements the client-side of the PMI interface.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* Note that the PMI client code must not print error messages (except
|
|
Packit Service |
c5cf8c |
* when an abort is required) because MPI error handling is based on
|
|
Packit Service |
c5cf8c |
* reporting error codes to which messages are attached.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* In v2, we should require a PMI client interface to use MPI error codes
|
|
Packit Service |
c5cf8c |
* to provide better integration with MPICH.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/***************************************************************************/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpichconf.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#define PMI_VERSION 1
|
|
Packit Service |
c5cf8c |
#define PMI_SUBVERSION 1
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include <stdio.h>
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_UNISTD_H
|
|
Packit Service |
c5cf8c |
#include <unistd.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_STDLIB_H
|
|
Packit Service |
c5cf8c |
#include <stdlib.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_STRING_H
|
|
Packit Service |
c5cf8c |
#include <string.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#ifdef HAVE_STRINGS_H
|
|
Packit Service |
c5cf8c |
#include <strings.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#ifdef USE_PMI_PORT
|
|
Packit Service |
c5cf8c |
#ifndef MAXHOSTNAME
|
|
Packit Service |
c5cf8c |
#define MAXHOSTNAME 256
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/* This should be moved to pmiu for shutdown */
|
|
Packit Service |
c5cf8c |
#if defined(HAVE_SYS_SOCKET_H)
|
|
Packit Service |
c5cf8c |
#include <sys/socket.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "mpl.h" /* Get ATTRIBUTE, some base functions */
|
|
Packit Service |
c5cf8c |
/* mpimem includes the definitions for MPL_malloc and MPL_free */
|
|
Packit Service |
c5cf8c |
#include "mpir_mem.h"
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Temporary debug definitions */
|
|
Packit Service |
c5cf8c |
/* #define DBG_PRINTF(args) printf args ; fflush(stdout) */
|
|
Packit Service |
c5cf8c |
#define DBG_PRINTF(args)
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#include "pmi.h"
|
|
Packit Service |
c5cf8c |
#include "simple_pmiutil.h"
|
|
Packit Service |
c5cf8c |
#include "mpi.h" /* to get MPI_MAX_PORT_NAME */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
These are global variable used *ONLY* in this file, and are hence
|
|
Packit Service |
c5cf8c |
declared static.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int PMI_fd = -1;
|
|
Packit Service |
c5cf8c |
static int PMI_size = 1;
|
|
Packit Service |
c5cf8c |
static int PMI_rank = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Set PMI_initialized to 1 for singleton init but no process manager
|
|
Packit Service |
c5cf8c |
to help. Initialized to 2 for normal initialization. Initialized
|
|
Packit Service |
c5cf8c |
to values higher than 2 when singleton_init by a process manager.
|
|
Packit Service |
c5cf8c |
All values higher than 1 invlove a PM in some way.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
typedef enum { PMI_UNINITIALIZED = 0,
|
|
Packit Service |
c5cf8c |
SINGLETON_INIT_BUT_NO_PM = 1,
|
|
Packit Service |
c5cf8c |
NORMAL_INIT_WITH_PM,
|
|
Packit Service |
c5cf8c |
SINGLETON_INIT_WITH_PM
|
|
Packit Service |
c5cf8c |
} PMIState;
|
|
Packit Service |
c5cf8c |
static PMIState PMI_initialized = PMI_UNINITIALIZED;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ALL GLOBAL VARIABLES MUST BE INITIALIZED TO AVOID POLLUTING THE
|
|
Packit Service |
c5cf8c |
LIBRARY WITH COMMON SYMBOLS */
|
|
Packit Service |
c5cf8c |
static int PMI_kvsname_max = 0;
|
|
Packit Service |
c5cf8c |
static int PMI_keylen_max = 0;
|
|
Packit Service |
c5cf8c |
static int PMI_vallen_max = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int PMI_debug = 0;
|
|
Packit Service |
c5cf8c |
static int PMI_debug_init = 0; /* Set this to true to debug the init
|
|
Packit Service |
c5cf8c |
* handshakes */
|
|
Packit Service |
c5cf8c |
static int PMI_spawned = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Function prototypes for internal routines */
|
|
Packit Service |
c5cf8c |
static int PMII_getmaxes(int *kvsname_max, int *keylen_max, int *vallen_max);
|
|
Packit Service |
c5cf8c |
static int PMII_Set_from_port(int, int);
|
|
Packit Service |
c5cf8c |
static int PMII_Connect_to_pm(char *, int);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int GetResponse(const char[], const char[], int);
|
|
Packit Service |
c5cf8c |
static int getPMIFD(int *);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef USE_PMI_PORT
|
|
Packit Service |
c5cf8c |
static int PMII_singinit(void);
|
|
Packit Service |
c5cf8c |
static int PMI_totalview = 0;
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
static int PMIi_InitIfSingleton(void);
|
|
Packit Service |
c5cf8c |
static int accept_one_connection(int);
|
|
Packit Service |
c5cf8c |
static int cached_singinit_inuse = 0;
|
|
Packit Service |
c5cf8c |
static char cached_singinit_key[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
static char cached_singinit_val[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
static char singinit_kvsname[256];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/******************************** Group functions *************************/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Init(int *spawned)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *p;
|
|
Packit Service |
c5cf8c |
int notset = 1;
|
|
Packit Service |
c5cf8c |
int rc;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMI_initialized = PMI_UNINITIALIZED;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: Why is setvbuf commented out? */
|
|
Packit Service |
c5cf8c |
/* FIXME: What if the output should be fully buffered (directed to file)?
|
|
Packit Service |
c5cf8c |
* unbuffered (user explicitly set?) */
|
|
Packit Service |
c5cf8c |
/* setvbuf(stdout,0,_IONBF,0); */
|
|
Packit Service |
c5cf8c |
setbuf(stdout, NULL);
|
|
Packit Service |
c5cf8c |
/* PMIU_printf(1, "PMI_INIT\n"); */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the value of PMI_DEBUG from the environment if possible, since
|
|
Packit Service |
c5cf8c |
* we may have set it to help debug the setup process */
|
|
Packit Service |
c5cf8c |
p = getenv("PMI_DEBUG");
|
|
Packit Service |
c5cf8c |
if (p)
|
|
Packit Service |
c5cf8c |
PMI_debug = atoi(p);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the fd for PMI commands; if none, we're a singleton */
|
|
Packit Service |
c5cf8c |
rc = getPMIFD(¬set);
|
|
Packit Service |
c5cf8c |
if (rc) {
|
|
Packit Service |
c5cf8c |
return rc;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_fd == -1) {
|
|
Packit Service |
c5cf8c |
/* Singleton init: Process not started with mpiexec,
|
|
Packit Service |
c5cf8c |
* so set size to 1, rank to 0 */
|
|
Packit Service |
c5cf8c |
PMI_size = 1;
|
|
Packit Service |
c5cf8c |
PMI_rank = 0;
|
|
Packit Service |
c5cf8c |
*spawned = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMI_initialized = SINGLETON_INIT_BUT_NO_PM;
|
|
Packit Service |
c5cf8c |
/* 256 is picked as the minimum allowed length by the PMI servers */
|
|
Packit Service |
c5cf8c |
PMI_kvsname_max = 256;
|
|
Packit Service |
c5cf8c |
PMI_keylen_max = 256;
|
|
Packit Service |
c5cf8c |
PMI_vallen_max = 256;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* If size, rank, and debug are not set from a communication port,
|
|
Packit Service |
c5cf8c |
* use the environment */
|
|
Packit Service |
c5cf8c |
if (notset) {
|
|
Packit Service |
c5cf8c |
if ((p = getenv("PMI_SIZE")))
|
|
Packit Service |
c5cf8c |
PMI_size = atoi(p);
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
PMI_size = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if ((p = getenv("PMI_RANK"))) {
|
|
Packit Service |
c5cf8c |
PMI_rank = atoi(p);
|
|
Packit Service |
c5cf8c |
/* Let the util routine know the rank of this process for
|
|
Packit Service |
c5cf8c |
* any messages (usually debugging or error) */
|
|
Packit Service |
c5cf8c |
PMIU_Set_rank(PMI_rank);
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
PMI_rank = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if ((p = getenv("PMI_DEBUG")))
|
|
Packit Service |
c5cf8c |
PMI_debug = atoi(p);
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
PMI_debug = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Leave unchanged otherwise, which indicates that no value
|
|
Packit Service |
c5cf8c |
* was set */
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: Why does this depend on their being a port??? */
|
|
Packit Service |
c5cf8c |
/* FIXME: What is this for? */
|
|
Packit Service |
c5cf8c |
#ifdef USE_PMI_PORT
|
|
Packit Service |
c5cf8c |
if ((p = getenv("PMI_TOTALVIEW")))
|
|
Packit Service |
c5cf8c |
PMI_totalview = atoi(p);
|
|
Packit Service |
c5cf8c |
if (PMI_totalview) {
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
/* FIXME: This should use a cmd/response rather than a expecting the
|
|
Packit Service |
c5cf8c |
* server to set a value in this and only this case */
|
|
Packit Service |
c5cf8c |
/* FIXME: And it most ceratainly should not happen *before* the
|
|
Packit Service |
c5cf8c |
* initialization handshake */
|
|
Packit Service |
c5cf8c |
PMIU_readline(PMI_fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strncmp(cmd, "tv_ready", PMIU_MAXLINE) != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "expecting cmd=tv_ready, got %s\n", buf);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMII_getmaxes(&PMI_kvsname_max, &PMI_keylen_max, &PMI_vallen_max);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: This is something that the PM should tell the process,
|
|
Packit Service |
c5cf8c |
* rather than deliver it through the environment */
|
|
Packit Service |
c5cf8c |
if ((p = getenv("PMI_SPAWNED")))
|
|
Packit Service |
c5cf8c |
PMI_spawned = atoi(p);
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
PMI_spawned = 0;
|
|
Packit Service |
c5cf8c |
if (PMI_spawned)
|
|
Packit Service |
c5cf8c |
*spawned = 1;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
*spawned = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (!PMI_initialized)
|
|
Packit Service |
c5cf8c |
PMI_initialized = NORMAL_INIT_WITH_PM;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Initialized(int *initialized)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* Turn this into a logical value (1 or 0) . This allows us
|
|
Packit Service |
c5cf8c |
* to use PMI_initialized to distinguish between initialized with
|
|
Packit Service |
c5cf8c |
* an PMI service (e.g., via mpiexec) and the singleton init,
|
|
Packit Service |
c5cf8c |
* which has no PMI service */
|
|
Packit Service |
c5cf8c |
*initialized = (PMI_initialized != 0);
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Get_size(int *size)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (PMI_initialized)
|
|
Packit Service |
c5cf8c |
*size = PMI_size;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
*size = 1;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Get_rank(int *rank)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (PMI_initialized)
|
|
Packit Service |
c5cf8c |
*rank = PMI_rank;
|
|
Packit Service |
c5cf8c |
else
|
|
Packit Service |
c5cf8c |
*rank = 0;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Get_universe_size is one of the routines that needs to communicate
|
|
Packit Service |
c5cf8c |
* with the process manager. If we started as a singleton init, then
|
|
Packit Service |
c5cf8c |
* we first need to connect to the process manager and acquire the
|
|
Packit Service |
c5cf8c |
* needed information.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
int PMI_Get_universe_size(int *size)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err;
|
|
Packit Service |
c5cf8c |
char size_c[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Connect to the PM if we haven't already */
|
|
Packit Service |
c5cf8c |
if (PMIi_InitIfSingleton() != 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
err = GetResponse("cmd=get_universe_size\n", "universe_size", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("size", size_c, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
*size = atoi(size_c);
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
*size = 1;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Get_appnum(int *appnum)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err;
|
|
Packit Service |
c5cf8c |
char appnum_c[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
err = GetResponse("cmd=get_appnum\n", "appnum", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("appnum", appnum_c, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
*appnum = atoi(appnum_c);
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
*appnum = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Barrier(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err = PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
err = GetResponse("cmd=barrier_in\n", "barrier_out", 0);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Inform the process manager that we're in finalize */
|
|
Packit Service |
c5cf8c |
int PMI_Finalize(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err = PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
err = GetResponse("cmd=finalize\n", "finalize_ack", 0);
|
|
Packit Service |
c5cf8c |
shutdown(PMI_fd, SHUT_RDWR);
|
|
Packit Service |
c5cf8c |
close(PMI_fd);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Abort(int exit_code, const char error_msg[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* include exit_code in the abort command */
|
|
Packit Service |
c5cf8c |
MPL_snprintf(buf, PMIU_MAXLINE, "cmd=abort exitcode=%d\n", exit_code);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "aborting job:\n%s\n", error_msg);
|
|
Packit Service |
c5cf8c |
GetResponse(buf, "", 0);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* the above command should not return */
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/************************************* Keymap functions **********************/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*FIXME: need to return an error if the value of the kvs name returned is
|
|
Packit Service |
c5cf8c |
truncated because it is larger than length */
|
|
Packit Service |
c5cf8c |
/* FIXME: My name should be cached rather than re-acquired, as it is
|
|
Packit Service |
c5cf8c |
unchanging (after singleton init) */
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Get_my_name(char kvsname[], int length)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized == SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
/* Return a dummy name */
|
|
Packit Service |
c5cf8c |
/* FIXME: We need to support a distinct kvsname for each
|
|
Packit Service |
c5cf8c |
* process group */
|
|
Packit Service |
c5cf8c |
MPL_snprintf(kvsname, length, "singinit_kvs_%d_0", (int) getpid());
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
err = GetResponse("cmd=get_my_kvsname\n", "my_kvsname", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("kvsname", kvsname, length);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Get_name_length_max(int *maxlen)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (maxlen == NULL)
|
|
Packit Service |
c5cf8c |
return PMI_ERR_INVALID_ARG;
|
|
Packit Service |
c5cf8c |
*maxlen = PMI_kvsname_max;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Get_key_length_max(int *maxlen)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (maxlen == NULL)
|
|
Packit Service |
c5cf8c |
return PMI_ERR_INVALID_ARG;
|
|
Packit Service |
c5cf8c |
*maxlen = PMI_keylen_max;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Get_value_length_max(int *maxlen)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
if (maxlen == NULL)
|
|
Packit Service |
c5cf8c |
return PMI_ERR_INVALID_ARG;
|
|
Packit Service |
c5cf8c |
*maxlen = PMI_vallen_max;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Put(const char kvsname[], const char key[], const char value[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err = PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int rc;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This is a special hack to support singleton initialization */
|
|
Packit Service |
c5cf8c |
if (PMI_initialized == SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
if (cached_singinit_inuse)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
rc = MPL_strncpy(cached_singinit_key, key, PMI_keylen_max);
|
|
Packit Service |
c5cf8c |
if (rc != 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
rc = MPL_strncpy(cached_singinit_val, value, PMI_vallen_max);
|
|
Packit Service |
c5cf8c |
if (rc != 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
cached_singinit_inuse = 1;
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(buf, PMIU_MAXLINE,
|
|
Packit Service |
c5cf8c |
"cmd=put kvsname=%s key=%s value=%s\n", kvsname, key, value);
|
|
Packit Service |
c5cf8c |
if (rc < 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
err = GetResponse(buf, "put_result", 1);
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Commit(const char kvsname[]ATTRIBUTE((unused)))
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
/* no-op in this implementation */
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*FIXME: need to return an error if the value returned is truncated
|
|
Packit Service |
c5cf8c |
because it is larger than length */
|
|
Packit Service |
c5cf8c |
int PMI_KVS_Get(const char kvsname[], const char key[], char value[], int length)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err = PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
int rc;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Connect to the PM if we haven't already. This is needed in case
|
|
Packit Service |
c5cf8c |
* we're doing an MPI_Comm_join or MPI_Comm_connect/accept from
|
|
Packit Service |
c5cf8c |
* the singleton init case. This test is here because, in the way in
|
|
Packit Service |
c5cf8c |
* which MPICH uses PMI, this is where the test needs to be. */
|
|
Packit Service |
c5cf8c |
if (PMIi_InitIfSingleton() != 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(buf, PMIU_MAXLINE, "cmd=get kvsname=%s key=%s\n", kvsname, key);
|
|
Packit Service |
c5cf8c |
if (rc < 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
err = GetResponse(buf, "get_result", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("rc", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
rc = atoi(buf);
|
|
Packit Service |
c5cf8c |
if (rc == 0) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("value", value, length);
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/*************************** Name Publishing functions **********************/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Publish_name(const char service_name[], const char port[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
MPL_snprintf(cmd, PMIU_MAXLINE,
|
|
Packit Service |
c5cf8c |
"cmd=publish_name service=%s port=%s\n", service_name, port);
|
|
Packit Service |
c5cf8c |
err = GetResponse(cmd, "publish_result", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("rc", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(buf, "0") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("msg", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "publish failed; reason = %s\n", buf);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "PMI_Publish_name called before init\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Unpublish_name(const char service_name[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err = PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
MPL_snprintf(cmd, PMIU_MAXLINE, "cmd=unpublish_name service=%s\n", service_name);
|
|
Packit Service |
c5cf8c |
err = GetResponse(cmd, "unpublish_result", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("rc", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(buf, "0") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("msg", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "unpublish failed; reason = %s\n", buf);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "PMI_Unpublish_name called before init\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Lookup_name(const char service_name[], char port[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized > SINGLETON_INIT_BUT_NO_PM) {
|
|
Packit Service |
c5cf8c |
MPL_snprintf(cmd, PMIU_MAXLINE, "cmd=lookup_name service=%s\n", service_name);
|
|
Packit Service |
c5cf8c |
err = GetResponse(cmd, "lookup_result", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("rc", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(buf, "0") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("msg", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "lookup failed; reason = %s\n", buf);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_getval("port", port, MPI_MAX_PORT_NAME);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "PMI_Lookup_name called before init\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/************************** Process Creation functions **********************/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
int PMI_Spawn_multiple(int count,
|
|
Packit Service |
c5cf8c |
const char *cmds[],
|
|
Packit Service |
c5cf8c |
const char **argvs[],
|
|
Packit Service |
c5cf8c |
const int maxprocs[],
|
|
Packit Service |
c5cf8c |
const int info_keyval_sizes[],
|
|
Packit Service |
c5cf8c |
const PMI_keyval_t * info_keyval_vectors[],
|
|
Packit Service |
c5cf8c |
int preput_keyval_size,
|
|
Packit Service |
c5cf8c |
const PMI_keyval_t preput_keyval_vector[], int errors[])
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int i, rc, argcnt, spawncnt, total_num_processes, num_errcodes_found;
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], tempbuf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
char *lead, *lag;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Connect to the PM if we haven't already */
|
|
Packit Service |
c5cf8c |
if (PMIi_InitIfSingleton() != 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
total_num_processes = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
for (spawncnt = 0; spawncnt < count; spawncnt++) {
|
|
Packit Service |
c5cf8c |
total_num_processes += maxprocs[spawncnt];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(buf, PMIU_MAXLINE,
|
|
Packit Service |
c5cf8c |
"mcmd=spawn\nnprocs=%d\nexecname=%s\n",
|
|
Packit Service |
c5cf8c |
maxprocs[spawncnt], cmds[spawncnt]);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE,
|
|
Packit Service |
c5cf8c |
"totspawns=%d\nspawnssofar=%d\n", count, spawncnt + 1);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
argcnt = 0;
|
|
Packit Service |
c5cf8c |
if ((argvs != NULL) && (argvs[spawncnt] != NULL)) {
|
|
Packit Service |
c5cf8c |
for (i = 0; argvs[spawncnt][i] != NULL; i++) {
|
|
Packit Service |
c5cf8c |
/* FIXME (protocol design flaw): command line arguments
|
|
Packit Service |
c5cf8c |
* may contain both = and <space> (and even tab!).
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/* Note that part of this fixme was really a design error -
|
|
Packit Service |
c5cf8c |
* because this uses the mcmd form, the data can be
|
|
Packit Service |
c5cf8c |
* sent in multiple writelines. This code now takes
|
|
Packit Service |
c5cf8c |
* advantage of that. Note also that a correct parser
|
|
Packit Service |
c5cf8c |
* of the commands will permit any character other than a
|
|
Packit Service |
c5cf8c |
* new line in the argument, since the form is
|
|
Packit Service |
c5cf8c |
* argn=<any nonnewline><newline> */
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "arg%d=%s\n", i + 1, argvs[spawncnt][i]);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
argcnt++;
|
|
Packit Service |
c5cf8c |
rc = PMIU_writeline(PMI_fd, buf);
|
|
Packit Service |
c5cf8c |
if (rc)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
buf[0] = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "argcnt=%d\n", argcnt);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "preput_num=%d\n", preput_keyval_size);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (i = 0; i < preput_keyval_size; i++) {
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "preput_key_%d=%s\n",
|
|
Packit Service |
c5cf8c |
i, preput_keyval_vector[i].key);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "preput_val_%d=%s\n",
|
|
Packit Service |
c5cf8c |
i, preput_keyval_vector[i].val);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "info_num=%d\n", info_keyval_sizes[spawncnt]);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
for (i = 0; i < info_keyval_sizes[spawncnt]; i++) {
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "info_key_%d=%s\n",
|
|
Packit Service |
c5cf8c |
i, info_keyval_vectors[spawncnt][i].key);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(tempbuf, PMIU_MAXLINE, "info_val_%d=%s\n",
|
|
Packit Service |
c5cf8c |
i, info_keyval_vectors[spawncnt][i].val);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, tempbuf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_strnapp(buf, "endcmd\n", PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
rc = PMIU_writeline(PMI_fd, buf);
|
|
Packit Service |
c5cf8c |
if (rc) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMIU_readline(PMI_fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strncmp(cmd, "spawn_result", PMIU_MAXLINE) != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "got unexpected response to spawn :%s:\n", buf);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
PMIU_getval("rc", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
rc = atoi(buf);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
/* PMIU_getval("status", tempbuf, PMIU_MAXLINE); */
|
|
Packit Service |
c5cf8c |
/* PMIU_printf(1, "pmi_spawn_mult failed; status: %s\n",tempbuf); */
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMIU_Assert(errors != NULL);
|
|
Packit Service |
c5cf8c |
if (PMIU_getval("errcodes", tempbuf, PMIU_MAXLINE)) {
|
|
Packit Service |
c5cf8c |
num_errcodes_found = 0;
|
|
Packit Service |
c5cf8c |
lag = &tempbuf[0];
|
|
Packit Service |
c5cf8c |
do {
|
|
Packit Service |
c5cf8c |
lead = strchr(lag, ',');
|
|
Packit Service |
c5cf8c |
if (lead)
|
|
Packit Service |
c5cf8c |
*lead = '\0';
|
|
Packit Service |
c5cf8c |
errors[num_errcodes_found++] = atoi(lag);
|
|
Packit Service |
c5cf8c |
lag = lead + 1; /* move past the null char */
|
|
Packit Service |
c5cf8c |
PMIU_Assert(num_errcodes_found <= total_num_processes);
|
|
Packit Service |
c5cf8c |
} while (lead != NULL);
|
|
Packit Service |
c5cf8c |
PMIU_Assert(num_errcodes_found == total_num_processes);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
/* gforker doesn't return errcodes, so we'll just pretend that means
|
|
Packit Service |
c5cf8c |
* that it was going to send all `0's. */
|
|
Packit Service |
c5cf8c |
for (i = 0; i < total_num_processes; ++i) {
|
|
Packit Service |
c5cf8c |
errors[i] = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/***************** Internal routines not part of PMI interface ***************/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* to get all maxes in one message */
|
|
Packit Service |
c5cf8c |
/* FIXME: This mixes init with get maxes */
|
|
Packit Service |
c5cf8c |
static int PMII_getmaxes(int *kvsname_max, int *keylen_max, int *vallen_max)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err, rc;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(buf, PMIU_MAXLINE,
|
|
Packit Service |
c5cf8c |
"cmd=init pmi_version=%d pmi_subversion=%d\n", PMI_VERSION, PMI_SUBVERSION);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = PMIU_writeline(PMI_fd, buf);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Unable to write to PMI_fd\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
buf[0] = 0; /* Ensure buffer is empty if read fails */
|
|
Packit Service |
c5cf8c |
err = PMIU_readline(PMI_fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (err < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Error reading initack on %d\n", PMI_fd);
|
|
Packit Service |
c5cf8c |
perror("Error on readline:");
|
|
Packit Service |
c5cf8c |
PMI_Abort(-1, "Above error when reading after init");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
cmd[0] = 0;
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (strncmp(cmd, "response_to_init", PMIU_MAXLINE) != 0) {
|
|
Packit Service |
c5cf8c |
char errmsg[PMIU_MAXLINE * 2 + 100];
|
|
Packit Service |
c5cf8c |
MPL_snprintf(errmsg, sizeof(errmsg),
|
|
Packit Service |
c5cf8c |
"got unexpected response to init :%s: (full line = %s)", cmd, buf);
|
|
Packit Service |
c5cf8c |
PMI_Abort(-1, errmsg);
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
char buf1[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
PMIU_getval("rc", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strncmp(buf, "0", PMIU_MAXLINE) != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("pmi_version", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_getval("pmi_subversion", buf1, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
char errmsg[PMIU_MAXLINE * 2 + 100];
|
|
Packit Service |
c5cf8c |
MPL_snprintf(errmsg, sizeof(errmsg),
|
|
Packit Service |
c5cf8c |
"pmi_version mismatch; client=%d.%d mgr=%s.%s",
|
|
Packit Service |
c5cf8c |
PMI_VERSION, PMI_SUBVERSION, buf, buf1);
|
|
Packit Service |
c5cf8c |
PMI_Abort(-1, errmsg);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
err = GetResponse("cmd=get_maxes\n", "maxes", 0);
|
|
Packit Service |
c5cf8c |
if (err == PMI_SUCCESS) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("kvsname_max", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
*kvsname_max = atoi(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("keylen_max", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
*keylen_max = atoi(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("vallen_max", buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
*vallen_max = atoi(buf);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ----------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* This function is used to request information from the server and check
|
|
Packit Service |
c5cf8c |
* that the response uses the expected command name. On a successful
|
|
Packit Service |
c5cf8c |
* return from this routine, additional PMIU_getval calls may be used
|
|
Packit Service |
c5cf8c |
* to access information about the returned value.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* If checkRc is true, this routine also checks that the rc value returned
|
|
Packit Service |
c5cf8c |
* was 0. If not, it uses the "msg" value to report on the reason for
|
|
Packit Service |
c5cf8c |
* the failure.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
static int GetResponse(const char request[], const char expectedCmd[], int checkRc)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int err, n;
|
|
Packit Service |
c5cf8c |
char *p;
|
|
Packit Service |
c5cf8c |
char recvbuf[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
char cmdName[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: This is an example of an incorrect fix - writeline can change
|
|
Packit Service |
c5cf8c |
* the second argument in some cases, and that will break the const'ness
|
|
Packit Service |
c5cf8c |
* of request. Instead, writeline should take a const item and return
|
|
Packit Service |
c5cf8c |
* an error in the case in which it currently truncates the data. */
|
|
Packit Service |
c5cf8c |
err = PMIU_writeline(PMI_fd, (char *) request);
|
|
Packit Service |
c5cf8c |
if (err) {
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
n = PMIU_readline(PMI_fd, recvbuf, sizeof(recvbuf));
|
|
Packit Service |
c5cf8c |
if (n <= 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "readline failed\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
err = PMIU_parse_keyvals(recvbuf);
|
|
Packit Service |
c5cf8c |
if (err) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "parse_kevals failed %d\n", err);
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
p = PMIU_getval("cmd", cmdName, sizeof(cmdName));
|
|
Packit Service |
c5cf8c |
if (!p) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "getval cmd failed\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (strcmp(expectedCmd, cmdName) != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "expecting cmd=%s, got %s\n", expectedCmd, cmdName);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (checkRc) {
|
|
Packit Service |
c5cf8c |
p = PMIU_getval("rc", cmdName, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (p && strcmp(cmdName, "0") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_getval("msg", cmdName, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Command %s failed, reason='%s'\n", request, cmdName);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return err;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ----------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#ifdef USE_PMI_PORT
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* This code allows a program to contact a host/port for the PMI socket.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
#include <errno.h>
|
|
Packit Service |
c5cf8c |
#if defined(HAVE_SYS_TYPES_H)
|
|
Packit Service |
c5cf8c |
#include <sys/types.h>
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
#include <sys/param.h>
|
|
Packit Service |
c5cf8c |
#include <sys/socket.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* sockaddr_in (Internet) */
|
|
Packit Service |
c5cf8c |
#include <netinet/in.h>
|
|
Packit Service |
c5cf8c |
/* TCP_NODELAY */
|
|
Packit Service |
c5cf8c |
#include <netinet/tcp.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* sockaddr_un (Unix) */
|
|
Packit Service |
c5cf8c |
#include <sys/un.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* defs of gethostbyname */
|
|
Packit Service |
c5cf8c |
#include <netdb.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* fcntl, F_GET/SETFL */
|
|
Packit Service |
c5cf8c |
#include <fcntl.h>
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* This is really IP!? */
|
|
Packit Service |
c5cf8c |
#ifndef TCP
|
|
Packit Service |
c5cf8c |
#define TCP 0
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* stub for connecting to a specified host/port instead of using a
|
|
Packit Service |
c5cf8c |
specified fd inherited from a parent process */
|
|
Packit Service |
c5cf8c |
static int PMII_Connect_to_pm(char *hostname, int portnum)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
MPL_sockaddr_t addr;
|
|
Packit Service |
c5cf8c |
int ret;
|
|
Packit Service |
c5cf8c |
int fd;
|
|
Packit Service |
c5cf8c |
int optval = 1;
|
|
Packit Service |
c5cf8c |
int q_wait = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
ret = MPL_get_sockaddr(hostname, &addr);
|
|
Packit Service |
a56745 |
if (ret) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Unable to get host entry for %s\n", hostname);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
fd = MPL_socket();
|
|
Packit Service |
c5cf8c |
if (fd < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Unable to get AF_INET socket\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &optval, sizeof(optval))) {
|
|
Packit Service |
c5cf8c |
perror("Error calling setsockopt:");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We wait here for the connection to succeed */
|
|
Packit Service |
c5cf8c |
ret = MPL_connect(fd, &addr, portnum);
|
|
Packit Service |
c5cf8c |
if (ret < 0) {
|
|
Packit Service |
c5cf8c |
switch (errno) {
|
|
Packit Service |
c5cf8c |
case ECONNREFUSED:
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "connect failed with connection refused\n");
|
|
Packit Service |
c5cf8c |
/* (close socket, get new socket, try again) */
|
|
Packit Service |
c5cf8c |
if (q_wait)
|
|
Packit Service |
c5cf8c |
close(fd);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
case EINPROGRESS: /* (nonblocking) - select for writing. */
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
case EISCONN: /* (already connected) */
|
|
Packit Service |
c5cf8c |
break;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
case ETIMEDOUT: /* timed out */
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "connect failed with timeout\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
default:
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "connect failed with errno %d\n", errno);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return fd;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int PMII_Set_from_port(int fd, int id)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
int err, rc;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We start by sending a startup message to the server */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_debug) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Writing initack to destination fd %d\n", fd);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* Handshake and initialize from a port */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(buf, PMIU_MAXLINE, "cmd=initack pmiid=%d\n", id);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "writing on fd %d line :%s:\n", fd, buf);
|
|
Packit Service |
c5cf8c |
err = PMIU_writeline(fd, buf);
|
|
Packit Service |
c5cf8c |
if (err) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Error in writeline initack\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* cmd=initack */
|
|
Packit Service |
c5cf8c |
buf[0] = 0;
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "reading initack\n");
|
|
Packit Service |
c5cf8c |
err = PMIU_readline(fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (err < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Error reading initack on %d\n", fd);
|
|
Packit Service |
c5cf8c |
perror("Error on readline:");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(cmd, "initack")) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "got unexpected input %s\n", buf);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Read, in order, size, rank, and debug. Eventually, we'll want
|
|
Packit Service |
c5cf8c |
* the handshake to include a version number */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* size */
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "reading size\n");
|
|
Packit Service |
c5cf8c |
err = PMIU_readline(fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (err < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Error reading size on %d\n", fd);
|
|
Packit Service |
c5cf8c |
perror("Error on readline:");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(cmd, "set")) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "got unexpected command %s in %s\n", cmd, buf);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* cmd=set size=n */
|
|
Packit Service |
c5cf8c |
PMIU_getval("size", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMI_size = atoi(cmd);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* rank */
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug, "reading rank\n");
|
|
Packit Service |
c5cf8c |
err = PMIU_readline(fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (err < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Error reading rank on %d\n", fd);
|
|
Packit Service |
c5cf8c |
perror("Error on readline:");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(cmd, "set")) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "got unexpected command %s in %s\n", cmd, buf);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* cmd=set rank=n */
|
|
Packit Service |
c5cf8c |
PMIU_getval("rank", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMI_rank = atoi(cmd);
|
|
Packit Service |
c5cf8c |
PMIU_Set_rank(PMI_rank);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* debug flag */
|
|
Packit Service |
c5cf8c |
err = PMIU_readline(fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (err < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Error reading debug on %d\n", fd);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(cmd, "set")) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "got unexpected command %s in %s\n", cmd, buf);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* cmd=set debug=n */
|
|
Packit Service |
c5cf8c |
PMIU_getval("debug", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMI_debug = atoi(cmd);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_debug) {
|
|
Packit Service |
c5cf8c |
DBG_PRINTF(("end of handshake, rank = %d, size = %d\n", PMI_rank, PMI_size));
|
|
Packit Service |
c5cf8c |
DBG_PRINTF(("Completed init\n"));
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
/*
|
|
Packit Service |
c5cf8c |
* Singleton Init.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* MPI-2 allows processes to become MPI processes and then make MPI calls,
|
|
Packit Service |
c5cf8c |
* such as MPI_Comm_spawn, that require a process manager (this is different
|
|
Packit Service |
c5cf8c |
* than the much simpler case of allowing MPI programs to run with an
|
|
Packit Service |
c5cf8c |
* MPI_COMM_WORLD of size 1 without an mpiexec or process manager).
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* The process starts when either the client or the process manager contacts
|
|
Packit Service |
c5cf8c |
* the other. If the client starts, it sends a singinit command and
|
|
Packit Service |
c5cf8c |
* waits for the server to respond with its own singinit command.
|
|
Packit Service |
c5cf8c |
* If the server start, it send a singinit command and waits for the
|
|
Packit Service |
c5cf8c |
* client to respond with its own singinit command
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* client sends singinit with these required values
|
|
Packit Service |
c5cf8c |
* pmi_version=<value of PMI_VERSION>
|
|
Packit Service |
c5cf8c |
* pmi_subversion=<value of PMI_SUBVERSION>
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* and these optional values
|
|
Packit Service |
c5cf8c |
* stdio=[yes|no]
|
|
Packit Service |
c5cf8c |
* authtype=[none|shared|<other-to-be-defined>]
|
|
Packit Service |
c5cf8c |
* authstring=<string>
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* server sends singinit with the same required and optional values as
|
|
Packit Service |
c5cf8c |
* above.
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* At this point, the protocol is now the same in both cases, and has the
|
|
Packit Service |
c5cf8c |
* following components:
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* server sends singinit_info with these required fields
|
|
Packit Service |
c5cf8c |
* versionok=[yes|no]
|
|
Packit Service |
c5cf8c |
* stdio=[yes|no]
|
|
Packit Service |
c5cf8c |
* kvsname=<string>
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* The client then issues the init command (see PMII_getmaxes)
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* cmd=init pmi_version=<val> pmi_subversion=<val>
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* and expects to receive a
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* cmd=response_to_init rc=0 pmi_version=<val> pmi_subversion=<val>
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
* (This is the usual init sequence).
|
|
Packit Service |
c5cf8c |
*
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
/* ------------------------------------------------------------------------- */
|
|
Packit Service |
c5cf8c |
/* This is a special routine used to re-initialize PMI when it is in
|
|
Packit Service |
c5cf8c |
the singleton init case. That is, the executable was started without
|
|
Packit Service |
c5cf8c |
mpiexec, and PMI_Init returned as if there was only one process.
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
Note that PMI routines should not call PMII_singinit; they should
|
|
Packit Service |
c5cf8c |
call PMIi_InitIfSingleton(), which both connects to the process mangager
|
|
Packit Service |
c5cf8c |
and sets up the initial KVS connection entry.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int PMII_singinit(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int pid, rc;
|
|
Packit Service |
c5cf8c |
int singinit_listen_sock, stdin_sock, stdout_sock, stderr_sock;
|
|
Packit Service |
c5cf8c |
const char *newargv[8];
|
|
Packit Service |
c5cf8c |
char charpid[8], port_c[8];
|
|
Packit Service |
c5cf8c |
unsigned short port;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Create a socket on which to allow an mpiexec to connect back to
|
|
Packit Service |
c5cf8c |
* us */
|
|
Packit Service |
c5cf8c |
singinit_listen_sock = MPL_socket();
|
|
Packit Service |
c5cf8c |
if (singinit_listen_sock == -1) {
|
|
Packit Service |
c5cf8c |
perror("PMII_singinit: socket creation failed");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
MPL_LISTEN_PUSH(0, 5);
|
|
Packit Service |
c5cf8c |
rc = MPL_listen_anyport(singinit_listen_sock, &port);
|
|
Packit Service |
c5cf8c |
MPL_LISTEN_POP;
|
|
Packit Service |
c5cf8c |
if (rc) {
|
|
Packit Service |
c5cf8c |
perror("PMII_singinit: listen failed");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
MPL_snprintf(port_c, sizeof(port_c), "%d", port);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "Starting mpiexec with %s\n", port_c);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Launch the mpiexec process with the name of this port */
|
|
Packit Service |
c5cf8c |
pid = fork();
|
|
Packit Service |
c5cf8c |
if (pid < 0) {
|
|
Packit Service |
c5cf8c |
perror("PMII_singinit: fork failed");
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
} else if (pid == 0) {
|
|
Packit Service |
c5cf8c |
newargv[0] = "mpiexec";
|
|
Packit Service |
c5cf8c |
newargv[1] = "-pmi_args";
|
|
Packit Service |
c5cf8c |
newargv[2] = port_c;
|
|
Packit Service |
c5cf8c |
/* FIXME: Use a valid hostname */
|
|
Packit Service |
c5cf8c |
newargv[3] = "default_interface"; /* default interface name, for now */
|
|
Packit Service |
c5cf8c |
newargv[4] = "default_key"; /* default authentication key, for now */
|
|
Packit Service |
c5cf8c |
MPL_snprintf(charpid, sizeof(charpid), "%d", getpid());
|
|
Packit Service |
c5cf8c |
newargv[5] = charpid;
|
|
Packit Service |
c5cf8c |
newargv[6] = NULL;
|
|
Packit Service |
c5cf8c |
rc = execvp(newargv[0], (char **) newargv);
|
|
Packit Service |
c5cf8c |
perror("PMII_singinit: execv failed");
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, " This singleton init program attempted to access some feature\n");
|
|
Packit Service |
c5cf8c |
PMIU_printf(1,
|
|
Packit Service |
c5cf8c |
" for which process manager support was required, e.g. spawn or universe_size.\n");
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, " But the necessary mpiexec is not in your path.\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
|
|
Packit Service |
c5cf8c |
char *p;
|
|
Packit Service |
c5cf8c |
int connectStdio = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Allow one connection back from the created mpiexec program */
|
|
Packit Service |
c5cf8c |
PMI_fd = accept_one_connection(singinit_listen_sock);
|
|
Packit Service |
c5cf8c |
if (PMI_fd < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Failed to establish singleton init connection\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* Execute the singleton init protocol */
|
|
Packit Service |
c5cf8c |
rc = PMIU_readline(PMI_fd, buf, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "Singinit: read %s\n", buf);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMIU_parse_keyvals(buf);
|
|
Packit Service |
c5cf8c |
PMIU_getval("cmd", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (strcmp(cmd, "singinit") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "unexpected command from PM: %s\n", cmd);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
p = PMIU_getval("authtype", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (p && strcmp(cmd, "none") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "unsupported authentication method %s\n", cmd);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
/* p = PMIU_getval("authstring", cmd, PMIU_MAXLINE); */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* If we're successful, send back our own singinit */
|
|
Packit Service |
c5cf8c |
rc = MPL_snprintf(buf, PMIU_MAXLINE,
|
|
Packit Service |
c5cf8c |
"cmd=singinit pmi_version=%d pmi_subversion=%d stdio=yes authtype=none\n",
|
|
Packit Service |
c5cf8c |
PMI_VERSION, PMI_SUBVERSION);
|
|
Packit Service |
c5cf8c |
if (rc < 0) {
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "GetResponse with %s\n", buf);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
rc = GetResponse(buf, "singinit_info", 0);
|
|
Packit Service |
c5cf8c |
if (rc != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "GetResponse failed\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
p = PMIU_getval("versionok", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (p && strcmp(cmd, "yes") != 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Process manager needs a different PMI version\n");
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
p = PMIU_getval("stdio", cmd, PMIU_MAXLINE);
|
|
Packit Service |
c5cf8c |
if (p && strcmp(cmd, "yes") == 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "PM agreed to connect stdio\n");
|
|
Packit Service |
c5cf8c |
connectStdio = 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
p = PMIU_getval("kvsname", singinit_kvsname, sizeof(singinit_kvsname));
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "kvsname to use is %s\n", singinit_kvsname);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (connectStdio) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "Accepting three connections for stdin, out, err\n");
|
|
Packit Service |
c5cf8c |
stdin_sock = accept_one_connection(singinit_listen_sock);
|
|
Packit Service |
c5cf8c |
dup2(stdin_sock, 0);
|
|
Packit Service |
c5cf8c |
stdout_sock = accept_one_connection(singinit_listen_sock);
|
|
Packit Service |
c5cf8c |
dup2(stdout_sock, 1);
|
|
Packit Service |
c5cf8c |
stderr_sock = accept_one_connection(singinit_listen_sock);
|
|
Packit Service |
c5cf8c |
dup2(stderr_sock, 2);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
PMIU_printf(PMI_debug_init, "Done with singinit handshake\n");
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Promote PMI to a fully initialized version if it was started as
|
|
Packit Service |
c5cf8c |
a singleton init */
|
|
Packit Service |
c5cf8c |
static int PMIi_InitIfSingleton(void)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int rc;
|
|
Packit Service |
c5cf8c |
static int firstcall = 1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_initialized != SINGLETON_INIT_BUT_NO_PM || !firstcall)
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We only try to init as a singleton the first time */
|
|
Packit Service |
c5cf8c |
firstcall = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* First, start (if necessary) an mpiexec, connect to it,
|
|
Packit Service |
c5cf8c |
* and start the singleton init handshake */
|
|
Packit Service |
c5cf8c |
rc = PMII_singinit();
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (rc < 0)
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
PMI_initialized = SINGLETON_INIT_WITH_PM; /* do this right away */
|
|
Packit Service |
c5cf8c |
PMI_size = 1;
|
|
Packit Service |
c5cf8c |
PMI_rank = 0;
|
|
Packit Service |
c5cf8c |
PMI_debug = 0;
|
|
Packit Service |
c5cf8c |
PMI_spawned = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
PMII_getmaxes(&PMI_kvsname_max, &PMI_keylen_max, &PMI_vallen_max);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* FIXME: We need to support a distinct kvsname for each
|
|
Packit Service |
c5cf8c |
* process group */
|
|
Packit Service |
c5cf8c |
PMI_KVS_Put(singinit_kvsname, cached_singinit_key, cached_singinit_val);
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
static int accept_one_connection(int list_sock)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
int gotit, new_sock;
|
|
Packit Service |
c5cf8c |
MPL_sockaddr_t addr;
|
|
Packit Service |
c5cf8c |
socklen_t len;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
len = sizeof(addr);
|
|
Packit Service |
c5cf8c |
gotit = 0;
|
|
Packit Service |
c5cf8c |
while (!gotit) {
|
|
Packit Service |
c5cf8c |
new_sock = accept(list_sock, (struct sockaddr *) &addr, &len;;
|
|
Packit Service |
c5cf8c |
if (new_sock == -1) {
|
|
Packit Service |
c5cf8c |
if (errno == EINTR) /* interrupted? If so, try again */
|
|
Packit Service |
c5cf8c |
continue;
|
|
Packit Service |
c5cf8c |
else {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "accept failed in accept_one_connection\n");
|
|
Packit Service |
c5cf8c |
exit(-1);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else
|
|
Packit Service |
c5cf8c |
gotit = 1;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return (new_sock);
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
/* end USE_PMI_PORT */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Get the FD to use for PMI operations. If a port is used, rather than
|
|
Packit Service |
c5cf8c |
a pre-established FD (i.e., via pipe), this routine will handle the
|
|
Packit Service |
c5cf8c |
initial handshake.
|
|
Packit Service |
c5cf8c |
*/
|
|
Packit Service |
c5cf8c |
static int getPMIFD(int *notset)
|
|
Packit Service |
c5cf8c |
{
|
|
Packit Service |
c5cf8c |
char *p;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Set the default */
|
|
Packit Service |
c5cf8c |
PMI_fd = -1;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
p = getenv("PMI_FD");
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (p) {
|
|
Packit Service |
c5cf8c |
PMI_fd = atoi(p);
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#ifdef USE_PMI_PORT
|
|
Packit Service |
c5cf8c |
p = getenv("PMI_PORT");
|
|
Packit Service |
c5cf8c |
if (p) {
|
|
Packit Service |
c5cf8c |
int portnum;
|
|
Packit Service |
c5cf8c |
char hostname[MAXHOSTNAME + 1];
|
|
Packit Service |
c5cf8c |
char *pn, *ph;
|
|
Packit Service |
c5cf8c |
int id = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Connect to the indicated port (in format hostname:portnumber)
|
|
Packit Service |
c5cf8c |
* and get the fd for the socket */
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Split p into host and port */
|
|
Packit Service |
c5cf8c |
pn = p;
|
|
Packit Service |
c5cf8c |
ph = hostname;
|
|
Packit Service |
c5cf8c |
while (*pn && *pn != ':' && (ph - hostname) < MAXHOSTNAME) {
|
|
Packit Service |
c5cf8c |
*ph++ = *pn++;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
*ph = 0;
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
if (PMI_debug) {
|
|
Packit Service |
c5cf8c |
DBG_PRINTF(("Connecting to %s\n", p));
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
if (*pn == ':') {
|
|
Packit Service |
c5cf8c |
portnum = atoi(pn + 1);
|
|
Packit Service |
c5cf8c |
/* FIXME: Check for valid integer after : */
|
|
Packit Service |
c5cf8c |
/* This routine only gets the fd to use to talk to
|
|
Packit Service |
c5cf8c |
* the process manager. The handshake below is used
|
|
Packit Service |
c5cf8c |
* to setup the initial values */
|
|
Packit Service |
c5cf8c |
PMI_fd = PMII_Connect_to_pm(hostname, portnum);
|
|
Packit Service |
c5cf8c |
if (PMI_fd < 0) {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "Unable to connect to %s on %d\n", hostname, portnum);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
} else {
|
|
Packit Service |
c5cf8c |
PMIU_printf(1, "unable to decode hostport from %s\n", p);
|
|
Packit Service |
c5cf8c |
return PMI_FAIL;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* We should first handshake to get size, rank, debug. */
|
|
Packit Service |
c5cf8c |
p = getenv("PMI_ID");
|
|
Packit Service |
c5cf8c |
if (p) {
|
|
Packit Service |
c5cf8c |
id = atoi(p);
|
|
Packit Service |
c5cf8c |
/* PMII_Set_from_port sets up the values that are delivered
|
|
Packit Service |
c5cf8c |
* by enviroment variables when a separate port is not used */
|
|
Packit Service |
c5cf8c |
PMII_Set_from_port(PMI_fd, id);
|
|
Packit Service |
c5cf8c |
*notset = 0;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|
|
Packit Service |
c5cf8c |
#endif
|
|
Packit Service |
c5cf8c |
|
|
Packit Service |
c5cf8c |
/* Singleton init case - its ok to return success with no fd set */
|
|
Packit Service |
c5cf8c |
return PMI_SUCCESS;
|
|
Packit Service |
c5cf8c |
}
|