Exemplo n.º 1
0
int PMIU_writeline( int fd, char *buf )	
{
    ssize_t size, n;

    size = strlen( buf );
    if ( size > PMIU_MAXLINE ) {
	buf[PMIU_MAXLINE-1] = '\0';
	PMIU_printf( 1, "write_line: message string too big: :%s:\n", buf );
    }
    else if ( buf[strlen( buf ) - 1] != '\n' )  /* error:  no newline at end */
	    PMIU_printf( 1, "write_line: message string doesn't end in newline: :%s:\n",
		       buf );
    else {
	do {
	    n = write( fd, buf, size );
	} while (n == -1 && errno == EINTR);

	if ( n < 0 ) {
	    PMIU_printf( 1, "write_line error; fd=%d buf=:%s:\n", fd, buf );
	    perror("system msg for write_line failure ");
	    return PMI_FAIL;
	}
	if ( n < size)
	    PMIU_printf( 1, "write_line failed to write entire message\n" );
    }
    return PMI_SUCCESS;
}
Exemplo n.º 2
0
/*
 * Given an input string st, parse it into internal storage that can be
 * queried by routines such as PMIU_getval.
 */
int PMIU_parse_keyvals( char *st )
{
    char *p, *keystart, *valstart;
    int  offset;

    if ( !st )
	return PMI_FAIL;

    PMIU_keyval_tab_idx = 0;
    p = st;
    while ( 1 ) {
	while ( *p == ' ' )
	    p++;
	/* got non-blank */
	if ( *p == '=' ) {
	    PMIU_printf( 1, "PMIU_parse_keyvals:  unexpected = at character %d in %s\n",
		       p - st, st );
	    return PMI_FAIL;
	}
	if ( *p == '\n' || *p == '\0' )
	    return PMI_SUCCESS;	/* normal exit */
	/* got normal character */
	keystart = p;		/* remember where key started */
	while ( *p != ' ' && *p != '=' && *p != '\n' && *p != '\0' )
	    p++;
	if ( *p == ' ' || *p == '\n' || *p == '\0' ) {
	    PMIU_printf( 1,
       "PMIU_parse_keyvals: unexpected key delimiter at character %d in %s\n",
		       p - st, st );
	    return PMI_FAIL;
	}
	/* Null terminate the key */
	*p = 0;
	/* store key */
        MPL_strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].key, keystart, 
		      MAXKEYLEN );

	valstart = ++p;			/* start of value */
	while ( *p != ' ' && *p != '\n' && *p != '\0' )
	    p++;
	/* store value */
        MPL_strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].value, valstart, 
		      MAXVALLEN );
	offset = (int)(p - valstart);
	/* When compiled with -fPIC, the pgcc compiler generates incorrect
	   code if "p - valstart" is used instead of using the 
	   intermediate offset */
	PMIU_keyval_tab[PMIU_keyval_tab_idx].value[offset] = '\0';  
	PMIU_keyval_tab_idx++;
	if ( *p == ' ' )
	    continue;
	if ( *p == '\n' || *p == '\0' )
	    return PMI_SUCCESS;	/* value has been set to empty */
    }
}
Exemplo n.º 3
0
/*
 * Process input from the socket connecting the mpiexec process to the
 * child process.
 *
 * The return status is interpreted by the IOLoop code in ioloop.c ;
 * a zero is a normal exit.
 */
int PMIServHandleInput(int fd, int rdwr, void *extra)
{
    PMIProcess *pentry = (PMIProcess *) extra;
    int rc;
    int returnCode = 0;
    char inbuf[PMIU_MAXLINE], cmd[MAXPMICMD];
    PMICmdMap *p;
    int cmdtype;

    DBG_PRINTFCOND(pmidebug, ("Handling PMI input\n"));
    if ((rc = PMIUBufferedReadLine(pentry, inbuf, PMIU_MAXLINE)) > 0) {
        DBG_PRINTFCOND(pmidebug, ("Entering PMIServHandleInputFd %s\n", inbuf));

        PMIU_parse_keyvals(inbuf);
        cmdtype = PMIGetCommand(cmd, sizeof(cmd));
        DBG_PRINTFCOND(pmidebug, ("cmd = %s\n", cmd));
        /* Look for the command and execute the related function */
        p = pmiCommands;
        while (p->handler) {
            if (strncmp(cmd, p->cmdName, MAXPMICMD) == 0) {
                rc = (p->handler) (pentry);
                break;
            }
            p++;
        }
        if (!p->handler) {
            PMIU_printf(1, "unknown cmd %s\n", cmd);
        }
    } else {    /* lost contact with client */
        DBG_PRINTFCOND(pmidebug, ("EOF on PMI input\n"));
        /* returning a 1 causes the IO loop code to close the socket */
        returnCode = 1;
    }
    return returnCode;
}
Exemplo n.º 4
0
/* Implement the singleton init handshake.  See the discussion in
   simplepmi.c for the protocol */
int PMI_InitSingletonConnection(int fd, PMIProcess * pmiprocess)
{
    char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
    int rc;
    char version[PMIU_MAXLINE], subversion[PMIU_MAXLINE];

    /* We start with the singinit command, wait for the singinit from
     * the client, and then send the singinit_info */
    MPL_snprintf(buf, PMIU_MAXLINE,
                 "cmd=singinit pmi_version=%d pmi_subversion=%d stdio=no authtype=none\n",
                 PMI_VERSION, PMI_SUBVERSION);
    PMIWriteLine(fd, buf);
    PMIReadLine(fd, buf, PMIU_MAXLINE);
    PMIU_parse_keyvals(buf);
    PMIU_getval("cmd", cmd, MAXPMICMD);
    if (strcmp(cmd, "singinit")) {
        PMIU_printf(1, "Unexpected cmd %s\n", cmd);
        return -1;
    }
    /* Could look at authtype */
    /* check version compatibility with PMI client library */
    PMIU_getval("pmi_version", version, PMIU_MAXLINE);
    PMIU_getval("pmi_subversion", subversion, PMIU_MAXLINE);
    if (PMI_VERSION == atoi(version) && PMI_SUBVERSION >= atoi(subversion))
        rc = 0;
    else
        rc = -1;

    MPL_snprintf(buf, PMIU_MAXLINE,
                 "cmd=singinit_info versionok=%s stdio=no kvsname=%s\n",
                 (rc == 0) ? "yes" : "no", (char *) (pmiprocess->group->kvs->kvsname));
    PMIWriteLine(fd, buf);

    return 0;
}
Exemplo n.º 5
0
int PMI_Abort(int exit_code, const char error_msg[])
{
    char buf[PMIU_MAXLINE];

    /* include exit_code in the abort command */
    MPL_snprintf( buf, PMIU_MAXLINE, "cmd=abort exitcode=%d\n", exit_code);

    PMIU_printf(PMI_debug, "aborting job:\n%s\n", error_msg);
    GetResponse( buf, "", 0 );

    /* the above command should not return */
    return PMI_FAIL;
}
Exemplo n.º 6
0
char *PMIU_getval( const char *keystr, char *valstr, int vallen )
{
    int i, rc;
    
    for (i = 0; i < PMIU_keyval_tab_idx; i++) {
	if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) { 
	    rc = MPL_strncpy( valstr, PMIU_keyval_tab[i].value, vallen );
	    if (rc != 0) {
		PMIU_printf( 1, "MPL_strncpy failed in PMIU_getval\n" );
		return NULL;
	    }
	    return valstr;
       } 
    }
    valstr[0] = '\0';
    return NULL;
}
Exemplo n.º 7
0
/*
 * This is a special routine.  It accepts the first input from the
 * remote process, and returns the PMI_ID value.  -1 is returned on error
 */
int PMI_Init_port_connection(int fd)
{
    char message[PMIU_MAXLINE], cmd[MAXPMICMD];
    int pmiid = -1;

    DBG_PRINTFCOND(pmidebug, ("Beginning initial handshake read\n"));
    PMIReadLine(fd, message, PMIU_MAXLINE);
    DBG_PRINTFCOND(pmidebug, ("received message %s\n", message));

    PMIU_parse_keyvals(message);
    PMIU_getval("cmd", cmd, MAXPMICMD);
    if (strcmp(cmd, "initack")) {
        PMIU_printf(1, "Unexpected cmd %s, expected initack\n", cmd);
        return -1;
    }
    PMIU_getval("pmiid", cmd, MAXPMICMD);
    pmiid = atoi(cmd);

    return pmiid;
}
Exemplo n.º 8
0
void PMIU_dump_keyvals( void )
{
    int i;
    for (i=0; i < PMIU_keyval_tab_idx; i++) 
	PMIU_printf(1, "  %s=%s\n",PMIU_keyval_tab[i].key, PMIU_keyval_tab[i].value);
}
Exemplo n.º 9
0
int PMI_Abort(int exit_code, const char error_msg[])
{
    PMIU_printf(1, "aborting job:\n%s\n", error_msg);
    MPIU_Exit(exit_code);
    return -1;
}
Exemplo n.º 10
0
int PMI_Init( int *spawned )
{
    char *p;
    int notset = 1;
    int rc;
    
    PMI_initialized = PMI_UNINITIALIZED;
    
    /* FIXME: Why is setvbuf commented out? */
    /* FIXME: What if the output should be fully buffered (directed to file)?
       unbuffered (user explicitly set?) */
    /* setvbuf(stdout,0,_IONBF,0); */
    setbuf(stdout,NULL);
    /* PMIU_printf( 1, "PMI_INIT\n" ); */

    /* Get the value of PMI_DEBUG from the environment if possible, since
       we may have set it to help debug the setup process */
    p = getenv( "PMI_DEBUG" );
    if (p) PMI_debug = atoi( p );

    /* Get the fd for PMI commands; if none, we're a singleton */
    rc = getPMIFD(&notset);
    if (rc) {
	return rc;
    }

    if ( PMI_fd == -1 ) {
	/* Singleton init: Process not started with mpiexec, 
	   so set size to 1, rank to 0 */
	PMI_size = 1;
	PMI_rank = 0;
	*spawned = 0;
	
	PMI_initialized = SINGLETON_INIT_BUT_NO_PM;
	/* 256 is picked as the minimum allowed length by the PMI servers */
	PMI_kvsname_max = 256;
	PMI_keylen_max  = 256;
	PMI_vallen_max  = 256;
	
	return( 0 );
    }

    /* If size, rank, and debug are not set from a communication port,
       use the environment */
    if (notset) {
	if ( ( p = getenv( "PMI_SIZE" ) ) )
	    PMI_size = atoi( p );
	else 
	    PMI_size = 1;
	
	if ( ( p = getenv( "PMI_RANK" ) ) ) {
	    PMI_rank = atoi( p );
	    /* Let the util routine know the rank of this process for 
	       any messages (usually debugging or error) */
	    PMIU_Set_rank( PMI_rank );
	}
	else 
	    PMI_rank = 0;
	
	if ( ( p = getenv( "PMI_DEBUG" ) ) )
	    PMI_debug = atoi( p );
	else 
	    PMI_debug = 0;

	/* Leave unchanged otherwise, which indicates that no value
	   was set */
    }

/* FIXME: Why does this depend on their being a port??? */
/* FIXME: What is this for? */
#ifdef USE_PMI_PORT
    if ( ( p = getenv( "PMI_TOTALVIEW" ) ) )
	PMI_totalview = atoi( p );
    if ( PMI_totalview ) {
	char buf[PMIU_MAXLINE], cmd[PMIU_MAXLINE];
	/* FIXME: This should use a cmd/response rather than a expecting the
	   server to set a value in this and only this case */
	/* FIXME: And it most ceratainly should not happen *before* the
	   initialization handshake */
	PMIU_readline( PMI_fd, buf, PMIU_MAXLINE );
	PMIU_parse_keyvals( buf );
	PMIU_getval( "cmd", cmd, PMIU_MAXLINE );
	if ( strncmp( cmd, "tv_ready", PMIU_MAXLINE ) != 0 ) {
	    PMIU_printf( 1, "expecting cmd=tv_ready, got %s\n", buf );
	    return( PMI_FAIL );
	}
    }
#endif

    PMII_getmaxes( &PMI_kvsname_max, &PMI_keylen_max, &PMI_vallen_max );

    /* FIXME: This is something that the PM should tell the process,
       rather than deliver it through the environment */
    if ( ( p = getenv( "PMI_SPAWNED" ) ) )
	PMI_spawned = atoi( p );
    else
	PMI_spawned = 0;
    if (PMI_spawned)
	*spawned = 1;
    else
	*spawned = 0;

    if ( ! PMI_initialized )
	PMI_initialized = NORMAL_INIT_WITH_PM;

    return( 0 );
}