static void handlePSMsg(DDTypedBufferMsg_t *msg) { if (msg->header.dest == PSC_getMyTID()) { /* message for me, let's get infos and forward to all accounters */ mdbg(PSACC_LOG_ACC_MSG, "%s: got msg %s\n", __func__, getAccountMsgType(msg->type)); switch (msg->type) { case PSP_ACCOUNT_QUEUE: case PSP_ACCOUNT_DELETE: case PSP_ACCOUNT_SLOTS: case PSP_ACCOUNT_START: /* nothing to do here for me */ break; case PSP_ACCOUNT_LOG: handleAccountLog(msg); break; case PSP_ACCOUNT_CHILD: handleAccountChild(msg); break; case PSP_ACCOUNT_END: handleAccountEnd(msg); break; default: mlog("%s: invalid msg type %i sender %s\n", __func__, msg->type, PSC_printTID(msg->header.sender)); } mdbg(PSACC_LOG_VERBOSE, "%s: msg type %s sender %s\n", __func__, getAccountMsgType(msg->type), PSC_printTID(msg->header.sender)); } /* forward msg to accounting daemons */ if (origHandler) origHandler((DDBufferMsg_t *) msg); }
/** * @brief Handle signals * * Handle the signal @a sig received. For the time being only SIGTERM * is expected. * * @param sig Signal to handle * * @return No return value */ static void sighandler(int sig) { switch(sig) { case SIGTERM: if (sigVerbose) fprintf(stderr, "Got %s\n", strsignal(sig)); DDSignalMsg_t msg = { .header = { .type = PSP_CD_WHODIED, .dest = 0, .sender = PSC_getMyTID(), .len = sizeof(msg) }, .signal = sig }; if (PSI_sendMsg(&msg) < 0) { fprintf(stderr, "%s: PSI_sendMsg(): %m\n", __func__); } break; default: if (sigVerbose) fprintf(stderr, "Got signal %s\n", strsignal(sig)); }
* Send information on the environment variable @a key to task @a * dest. The information (i.e. name and value) is sent as a character * string. * * @param dest Task ID of the destination to send info to * * @param key Name of the environment variable to send * * @return No return value */ static void sendSingleEnv(PStask_ID_t dest, char *key) { DDTypedBufferMsg_t msg = { .header = { .type = PSP_CD_INFORESPONSE, .sender = PSC_getMyTID(), .dest = dest, .len = sizeof(msg.header) + sizeof(msg.type) }, .type = PSP_INFO_QUEUE_ENVS, .buf = {0}}; size_t strLen, bufLen = sizeof(msg.buf); char *envStr = getenv(key); if (envStr) { strLen = snprintf(msg.buf, bufLen, "%s=%s", key, envStr); } else { strLen = snprintf(msg.buf, bufLen, "%s=<NULL>", key); } if (strLen > bufLen) { msg.buf[bufLen-4] = '.'; msg.buf[bufLen-3] = '.';
int main(int argc, const char *argv[]) { int np, verbose; int rank, i, rc; int dup_argc; char **dup_argv; int waittime, killtime; unsigned int magic; /* * We can't use popt for argument parsing here. popt is not * capable to stop at the first unrecogniced option, i.e. at the * executable separation options to the mpirun command from * options to the application. */ poptContext optCon; /* context for parsing command-line options */ struct poptOption optionsTable[] = { { "np", '\0', POPT_ARG_INT | POPT_ARGFLAG_ONEDASH, &np, 0, "number of processes to start", "num"}, { "wait", 'w', POPT_ARG_INT, &waittime, 0, "Wait <n> seconds between each spawning step", "n"}, { "kill", 'k', POPT_ARG_INT, &killtime, 0, "Kill all processes <n> seconds after the first exits", "n"}, { NULL, 'v', POPT_ARG_NONE, &verbose, 0, "verbose mode", NULL}, { NULL, '\0', 0, NULL, 0, NULL, NULL} }; /* The duplicated argv will contain the apps commandline */ poptDupArgv(argc, argv, &dup_argc, (const char ***)&dup_argv); optCon = poptGetContext(NULL, dup_argc, (const char **)dup_argv, optionsTable, 0); poptSetOtherOptionHelp(optCon, OTHER_OPTIONS_STR); /* * Split the argv into two parts: * - first one containing the mpirun options * - second one containing the apps argv * The first one is already parsed while splitting */ while (1) { const char *unknownArg; np = -1; verbose = 0; waittime = 0; killtime = -1; rc = poptGetNextOpt(optCon); if ((unknownArg=poptGetArg(optCon))) { /* * Find the first unknown argument (which is the apps * name) within dup_argv. Start searching from dup_argv's end * since the apps name might be used within another * options argument. */ for (i=argc-1; i>0; i--) { if (strcmp(dup_argv[i], unknownArg)==0) { dup_argc = i; dup_argv[dup_argc] = NULL; poptFreeContext(optCon); optCon = poptGetContext(NULL, dup_argc, (const char **)dup_argv, optionsTable, 0); poptSetOtherOptionHelp(optCon, OTHER_OPTIONS_STR); break; } } if (i==0) { printf("unknownArg '%s' not found !?\n", unknownArg); exit(1); } } else { /* No unknownArg left, we are finished */ break; } } if (rc < -1) { /* an error occurred during option processing */ poptPrintUsage(optCon, stderr, 0); fprintf(stderr, "%s: %s\n", poptBadOption(optCon, POPT_BADOPTION_NOALIAS), poptStrerror(rc)); exit(1); } if (np == -1) { poptPrintUsage(optCon, stderr, 0); fprintf(stderr, "You have to give at least the -np argument.\n"); exit(1); } if (!argv[dup_argc]) { poptPrintUsage(optCon, stderr, 0); fprintf(stderr, "No <command> specified.\n"); exit(1); } free(dup_argv); if (verbose) { printf("The 'gmspawner' command-line is:\n"); for (i=0; i<dup_argc; i++) { printf("%s ", argv[i]); } printf("\b\n\n"); printf("The applications command-line is:\n"); for (i=dup_argc; i<argc; i++) { printf("%s ", argv[i]); } printf("\b\n\n"); } /* init PSI */ if (!PSI_initClient(TG_GMSPAWNER)) { fprintf(stderr, "Initialization of PSI failed."); exit(10); } PSI_infoInt(-1, PSP_INFO_TASKRANK, NULL, &rank, 0); if (rank != np) { fprintf(stderr, "%s: rank(%d) != np(%d).\n", argv[dup_argc], rank, np); exit(1); } /* Propagate some environment variables */ PSI_propEnv(); PSI_propEnvList("PSI_EXPORTS"); PSI_propEnvList("__PSI_EXPORTS"); srandom(time(NULL)); magic = random()%9999999; setIntEnv("GMPI_MAGIC", magic); setIntEnv("GMPI_NP", np); { char hostname[256]; gethostname(hostname, sizeof(hostname)); setPSIEnv("GMPI_MASTER", hostname, 1); } { int port = createListener(8000, np, magic, verbose); if (port>=0) setIntEnv("GMPI_PORT", port); } propagateEnv("GMPI_SHMEM", 1); propagateEnv("DISPLAY", 0); propagateEnv("GMPI_EAGER", 0); propagateEnv("GMPI_RECV", 1); PSC_setSigHandler(SIGALRM, sighandler); /* spawn all processes */ PSI_RemoteArgs(argc - dup_argc, (char **)&argv[dup_argc], &dup_argc, &dup_argv); for (rank=0; rank<np; rank++) { if (waittime && rank) sleep(waittime); setIntEnv("GMPI_ID", rank); setIntEnv("GMPI_BOARD", -1); char slavestring[20]; PSnodes_ID_t node; struct in_addr ip; int err; err = PSI_infoNodeID(-1, PSP_INFO_RANKID, &rank, &node, 1); if (err) { fprintf(stderr, "Could not determine rank %d's node.\n", rank); exit(1); } err = PSI_infoUInt(-1, PSP_INFO_NODE, &node, &ip.s_addr, 1); if (err) { fprintf(stderr, "Could not determine node %d's IP\n", node); exit(1); } snprintf(slavestring, sizeof(slavestring), "%s", inet_ntoa(ip)); setPSIEnv("GMPI_SLAVE", slavestring, 1); /* spawn the process */ int error; if (!PSI_spawnRank(rank, ".", dup_argc, dup_argv, &error)) { if (error) { char *errstr = strerror(error); fprintf(stderr, "Could not spawn process %d (%s) error = %s.\n", rank, dup_argv[0], errstr ? errstr : "UNKNOWN"); exit(1); } } } /* Wait for the spawned processes to complete */ while (np) { static int firstClient=1; DDErrorMsg_t msg; int ret; ret = PSI_recvMsg((DDMsg_t *)&msg, sizeof(msg)); if (msg.header.type != PSP_CD_SPAWNFINISH || ret != sizeof(msg)) { fprintf(stderr, "got strange message type %s\n", PSP_printMsg(msg.header.type)); } else { if (firstClient && killtime!=-1) { // printf("Alarm set to %d\n", killtime); if (killtime) { alarm(killtime); firstClient=0; } else { /* Stop immediately */ exit(0); } } np--; // printf("%d clients left\n", np); } } PSI_release(PSC_getMyTID()); PSI_exitClient(); return 0; }
int main(int argc, char **argv) { int rank = 0; command_name = argv[0]; parse_opt(argc, argv); if (arg_version) { printVersion(); return 0; } if (arg_cp) { unsigned int slen = strlen(copy_command_src) + strlen(arg_cp) + 1000; char *icmd = malloc(slen); snprintf(icmd, slen,"%s %s", copy_command_src, arg_cp); arg_icmd = icmd; arg_ocmd = copy_command_dest; fprintf(stderr, " input command: %s\n", arg_icmd); } if (arg_icmd && arg_ifile) { fprintf(stderr, "Warning: Ignoring -icmd %s, because -i is set\n", arg_icmd); arg_icmd = NULL; } if (arg_ocmd && arg_ofile) { fprintf(stderr, "Warning: Ignoring -ocmd %s, because -o is set\n", arg_ocmd); arg_ocmd = NULL; } if (PSP_Init() != PSP_OK) { fprintf(stderr, "PSP_Init() failed!\n"); exit(1); } if (!arg_manual) { /* HACK HACK HACK */ setenv("__PSI_MASTERNODE", "-1", 0); setenv("__PSI_MASTERPORT", "-1", 0); PSE_initialize(); rank = PSE_getRank(); } else if (arg_server) { rank = 1; } if (rank < 0) { /* original process, let's spawn rank 0 and become logger */ setenv("PSI_NOMSGLOGGERDONE", "", 1); PSE_spawnAdmin(-1, 0, argc, argv, 0); } else if (rank == 0) { /* server */ if (arg_progress) set_timer(1, 1 ,timer); doServer(); } else { /* client */ if (arg_progress && arg_manual) set_timer(1, 1 ,timer); doClient(); } if (!arg_manual) { PSI_release(PSC_getMyTID()); } if ((!rank || arg_manual) && arg_progress) { print_stat(1); } return 0; }