"Fossies" - the Fresh Open Source Software Archive

Member "berkeley_upc-2019.4.2/gasnet/other/amudp/amudprun.c" (27 May 2019, 8664 Bytes) of package /linux/misc/berkeley_upc-2019.4.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "amudprun.c" see the Fossies "Dox" file reference documentation.

    1 /*   $Source: bitbucket.org:berkeleylab/gasnet.git/other/amudp/amudprun.c $
    2  * Description: Stand-alone AMUDP job launcher
    3  * Copyright 2006, Dan Bonachea <bonachea@cs.berkeley.edu>
    4  */
    5 
    6 #include <stdio.h>
    7 #include <stdlib.h>
    8 #include <string.h>
    9 
   10 #include <sys/types.h>
   11 #include <sys/stat.h>
   12 #include <fcntl.h>
   13 #ifdef AMUDP_BLCR_ENABLED /* bug 3328: avoid broken clang/Cygwin header */
   14 #include <dirent.h>
   15 #endif
   16 
   17 #ifdef HAVE_GASNET_TOOLS
   18 #define GASNETT_LITE_MODE /* preserves AMUDP's threading neutrality */
   19 #include <gasnet_tools.h> /* for ctype.h wrappers */
   20 #else
   21 #include <ctype.h>
   22 #endif
   23 
   24 #include <amudp.h>
   25 #include <amudp_spmd.h>
   26 
   27 static const char *argvzero;
   28 static void Usage(const char *msg) {
   29   int i;
   30   if (msg) fprintf(stderr, "ERROR: %s\n\n", msg);
   31   fprintf(stderr, 
   32     "%s, version %s\n"
   33     "Usage: %s [<options>] <program_name> [<program arguments>...]\n\n"
   34     "  -np N     Spawn N processes (may also be spelled -N or -n)\n"
   35     "  -spawn F  Use spawning function F\n"
   36     "  -depth D  Use network depth D\n"
   37     "  -v        Enable verbose mode spawn\n"
   38     "  -h        Show this help\n\n"
   39     , argvzero, AMUDP_LIBRARY_VERSION_STR, argvzero);
   40 #ifdef AMUDP_BLCR_ENABLED
   41   fprintf(stderr, 
   42     "Usage: %s -restart <checkpoint_directory>\n\n"
   43     , argvzero);
   44 #endif
   45   fprintf (stderr, "Available spawn functions:\n");
   46   for (i=0; AMUDP_Spawnfn_Desc[i].abbrev; i++) {
   47     fprintf(stderr, "    '%c'  %s\n",  
   48           toupper(AMUDP_Spawnfn_Desc[i].abbrev), AMUDP_Spawnfn_Desc[i].desc);
   49   }
   50   fprintf(stderr, "\n");
   51   exit(1);
   52 }
   53 
   54 static amudp_spawnfn_t spawnfn = NULL;
   55 static char spawnfn_abbr = '-';
   56 static const char *spawnfn_str = "<default>";
   57 static void set_spawnfn(const char *str) {
   58   int i;
   59   spawnfn_abbr = toupper(str[0]);
   60   if (str[1]) Usage("Invalid spawn function");
   61   for (i=0; AMUDP_Spawnfn_Desc[i].abbrev; i++) {
   62     if (spawnfn_abbr == toupper(AMUDP_Spawnfn_Desc[i].abbrev)) {
   63       spawnfn = AMUDP_Spawnfn_Desc[i].fnptr;
   64       spawnfn_str = AMUDP_Spawnfn_Desc[i].desc;
   65       break;
   66     }
   67   }
   68   if (!spawnfn) Usage("Unknown spawn value for -spawn");
   69 }
   70 
   71 int main(int argc, char **argv) {
   72   int verbose = 0;
   73   int nproc = 0;
   74   int networkdepth = 0;
   75 
   76 #ifdef AMUDP_BLCR_ENABLED
   77   int procid = AMUDP_SPMDRestartProcId(&argc, &argv);
   78   if (procid >= 0) {
   79     char filename[32];
   80     int magic_fd = -1;
   81     int context_fd = -1;
   82 
   83     /* Save opaque "magic" (argv[2]) in a temporary file */
   84     { size_t len;
   85       char *tempname;
   86       const char *tmpdir;
   87       const char *magic = argv[2];
   88       int rc;
   89 
   90       tmpdir = getenv("TMPDIR");
   91       if (!tmpdir) tmpdir = (const char *)"/tmp";
   92       tempname = (char *)malloc(13 + strlen(tmpdir));
   93       strcpy(tempname, tmpdir);
   94       strcat(tempname, "/amudpXXXXXX");
   95       magic_fd = mkstemp(tempname);
   96       if (magic_fd < 0) {
   97         perror("Failed to mkstemp()");
   98         exit(1);
   99       }
  100       (void)unlink(tempname);
  101       len = 1 + strlen(magic);
  102       rc = (int)write(magic_fd, magic, len);
  103       if (rc < (ssize_t)len) {
  104         perror("Failed to write() restart magic file");
  105         exit(1);
  106       }
  107       if ((off_t)0 != lseek(magic_fd, 0, SEEK_SET)) {
  108         perror("Failed to rewind restart magic file");
  109         exit(1);
  110       }
  111     }
  112 
  113     /* Open context file and dup() magic_fd to its reserved fd */
  114     snprintf(filename, sizeof(filename), "context.%d", (int)procid);
  115     { int special_fd;
  116       ssize_t bytesread;
  117 
  118       if (0 != chdir(argv[1])) {
  119         fprintf(stderr, "ERROR: failed to change to restart directory '%s'\n", argv[1]);
  120         return 1;
  121       }
  122 
  123       context_fd = open(filename, O_RDONLY);
  124       if (context_fd < 0) {
  125         perror("Failed to open() context file");
  126         exit(1);
  127       }
  128       bytesread = read(context_fd, &special_fd, sizeof(int));
  129       if (bytesread != (ssize_t)sizeof(int)) {
  130         perror("Failed to read() context file");
  131         exit(1);
  132       }
  133 
  134       if (context_fd == special_fd) {
  135         int tmp = dup(context_fd);
  136         if (0 > tmp) {
  137           perror("Failed to dup() context file");
  138           exit(1);
  139         }
  140         close(context_fd);
  141         context_fd = tmp;
  142       }
  143       if (magic_fd != special_fd) {
  144         if (0 > dup2(magic_fd, special_fd)) {
  145           perror("Failed to dup2() magic file");
  146           exit(1);
  147         }
  148         (void)close(magic_fd);
  149       }
  150     }
  151 
  152     /* BLCR-TODO: close any "stray" files or mark them close-on-exec */
  153 
  154     /* Append BLCR's bindir to PATH */
  155     {
  156       const char *bindir = BLCR_BINDIR;
  157       const char *path = getenv("PATH");
  158       const size_t len = strlen(path) + strlen(bindir) + 2; /* 2 = ':' and '\0' */
  159       char *new_path = malloc(len);
  160       strcpy(new_path, path);
  161       strcat(new_path, ":" BLCR_BINDIR);
  162       setenv("PATH", new_path, 1);
  163     }
  164 
  165     /* Now the actual restart */
  166     /* BLCR-TODO: use cr_request_restart()? */
  167     {
  168       char fd_arg[10];
  169       snprintf(fd_arg, sizeof(fd_arg), "%d", context_fd);
  170       execlp("cr_restart", "cr_restart", "-F", fd_arg, (char*)NULL);
  171     }
  172     perror("Failed execlp() restart command");
  173     exit(1);
  174   }
  175 #endif /* AMUDP_BLCR_ENABLED */
  176 
  177   if (AMUDP_SPMDIsWorker(argv)) Usage("launcher cannot be invoked as target program");
  178 
  179   argvzero = argv[0];
  180   argv++; argc--; /* strip launcher name */
  181 
  182   while (argc && argv[0][0] == '-') {
  183     const char *arg = argv[0];
  184     if (arg[1] == '-') arg++;
  185     if (!strcmp(arg,"-v")) {
  186       verbose = 1;
  187     } else if (!strcmp(arg,"-np") || 
  188                !strcmp(arg,"-n") || 
  189                !strcmp(arg,"-N")) {
  190       if (argc < 2) Usage("Missing process count for -np");
  191       argv++; argc--;
  192       nproc = atoi(argv[0]);
  193       if (nproc < 1) Usage("Bad process count for -np");
  194     } else if (!strcmp(arg,"-depth")) {
  195       if (argc < 2) Usage("Missing depth value for -depth");
  196       argv++; argc--;
  197       networkdepth = atoi(argv[0]);
  198       if (networkdepth < 1) Usage("Bad depth value for -depth");
  199     } else if (!strcmp(arg,"-spawn")) {
  200       if (argc < 2) Usage("Missing spawn value for -spawn");
  201       argv++; argc--;
  202       set_spawnfn(argv[0]);
  203     } else if (!strcmp(arg,"-h") || 
  204                !strcmp(arg,"-H") || 
  205                !strcmp(arg,"-help")) {
  206       Usage(NULL);
  207 #ifdef AMUDP_BLCR_ENABLED
  208     } else if (!strcmp(arg,"-restart")) {
  209       if (argc < 2) Usage("Missing directory name for -restart");
  210       { /* determine nproc by counting context files, and check for gaps */
  211         int rc, maxN = -1;
  212         DIR *dir;
  213         struct dirent *d;
  214 
  215         dir = opendir(argv[1]);
  216         if (NULL == dir) {
  217           fprintf(stderr, "ERROR: failed to open restart directory '%s'\n", argv[1]);
  218           return 1;
  219         }
  220         nproc = 0;
  221         while (NULL != (d = readdir(dir))) {
  222           static char pattern[] = "context.";
  223           const size_t len = sizeof(pattern) - 1;
  224           if (0 == strncmp(d->d_name, pattern, len)) {
  225             int id = atoi(d->d_name + len);
  226             char tmpname[32];
  227             snprintf(tmpname, sizeof(tmpname)-1, "context.%d", id);
  228             if (0 == strcmp(d->d_name, tmpname)) {
  229               ++nproc;
  230               maxN = (id>maxN) ? id : maxN;
  231             }
  232           }
  233         }
  234         closedir(dir);
  235         if (nproc == 0) {
  236           fprintf(stderr, "ERROR: failed to find context files in restart directory '%s'\n", argv[1]);
  237           return 1;
  238         } else if (nproc != maxN+1) {
  239           fprintf(stderr, "ERROR: missing one or more context files in restart directory '%s'\n", argv[1]);
  240           return 1;
  241         }
  242       }
  243       /* BLCR-TODO: need an absolute path (or should we *require* one?) */
  244       AMUDP_SPMDRunRestart(strdup(argvzero), argv[1], nproc);
  245       /* should never return */
  246       fprintf(stderr, "ERROR: AMUDP_SPMDRunRestart failed\n");
  247       return 1;
  248 #endif /* AMUDP_BLCR_ENABLED */
  249     } else Usage("unknown option");
  250     argv++; argc--;
  251   }
  252   if (argc < 1) Usage("missing program name");
  253 
  254   AMX_VerboseErrors = 1;
  255 
  256   if (verbose) {
  257     int i;
  258     if (!getenv("AMUDP_VERBOSEENV")) putenv((char *)"AMUDP_VERBOSEENV=1");
  259     fprintf(stderr,"%s: Launching: ",argvzero);
  260     for (i = 0; i < argc; i++) {
  261       fprintf(stderr,"%s ", argv[i]);
  262     }
  263     fprintf(stderr,"\n");
  264     fprintf(stderr,"%s: nprocs=%i depth=%i spawnfn=%c(%s)\n",
  265       argvzero,nproc,networkdepth,spawnfn_abbr,spawnfn_str);
  266   }
  267 
  268   { /* call startup */
  269     eb_t eb;
  270     ep_t ep;
  271     uint64_t networkpid;
  272     int retval =
  273       AMUDP_SPMDStartup(&argc, &argv, 
  274                         nproc, networkdepth, 
  275                         spawnfn, &networkpid, &eb, &ep);
  276     /* should never return */
  277     fprintf(stderr, "ERROR: AMUDP_SPMDStartup failed: %i\n", retval);
  278   }
  279   return 1;
  280 }