root/util_init.cpp

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. getCoordHostAndPort
  2. setCoordPort
  3. writeCoordPortToFile
  4. calcTmpDir
  5. initializeLogFile

   1 /****************************************************************************
   2  *   Copyright (C) 2006-2013 by Jason Ansel, Kapil Arya, and Gene Cooperman *
   3  *   jansel@csail.mit.edu, kapil@ccs.neu.edu, gene@ccs.neu.edu              *
   4  *                                                                          *
   5  *  This file is part of DMTCP.                                             *
   6  *                                                                          *
   7  *  DMTCP is free software: you can redistribute it and/or                  *
   8  *  modify it under the terms of the GNU Lesser General Public License as   *
   9  *  published by the Free Software Foundation, either version 3 of the      *
  10  *  License, or (at your option) any later version.                         *
  11  *                                                                          *
  12  *  DMTCP is distributed in the hope that it will be useful,                *
  13  *  but WITHOUT ANY WARRANTY; without even the implied warranty of          *
  14  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           *
  15  *  GNU Lesser General Public License for more details.                     *
  16  *                                                                          *
  17  *  You should have received a copy of the GNU Lesser General Public        *
  18  *  License along with DMTCP:dmtcp/src.  If not, see                        *
  19  *  <http://www.gnu.org/licenses/>.                                         *
  20  ****************************************************************************/
  21 
  22 #include <string.h>
  23 #include <pwd.h>
  24 #include <sys/fcntl.h>
  25 #include <sys/stat.h>
  26 #include <sys/types.h>
  27 #include "constants.h"
  28 #include "util.h"
  29 #include "protectedfds.h"
  30 #include "uniquepid.h"
  31 #include "coordinatorapi.h" // for COORD_JOIN, COORD_NEW, COORD_ANY
  32 #include "../jalib/jassert.h"
  33 #include "../jalib/jfilesystem.h"
  34 #include "../jalib/jsocket.h"
  35 #include  "../jalib/jconvert.h"
  36 
  37 using namespace dmtcp;
  38 
  39 void Util::getCoordHostAndPort(CoordinatorMode mode,
  40                                const char **host, int *port)
  41 {
  42   JASSERT(mode & COORD_JOIN || mode & COORD_NEW || mode & COORD_ANY);
  43 
  44   if (SharedData::initialized()) {
  45     *host = SharedData::coordHost().c_str();
  46     *port = SharedData::coordPort();
  47     return;
  48   }
  49 
  50   static bool _firstTime = true;
  51   static const char *_cachedHost;
  52   static int _cachedPort;
  53 
  54   if (_firstTime) {
  55     // Set host to cmd line (if --cord-host) or env var or DEFAULT_HOST
  56     if (*host == NULL) {
  57       if (getenv(ENV_VAR_NAME_HOST)) {
  58         *host = getenv(ENV_VAR_NAME_HOST);
  59       } else if (getenv("DMTCP_HOST")) { // deprecated
  60         *host = getenv("DMTCP_HOST");
  61       } else {
  62         *host = DEFAULT_HOST;
  63       }
  64     }
  65 
  66     // Set port to cmd line (if --coord-port) or env var
  67     //   or 0 (if --new-coordinator from cmd line) or DEFAULT_PORT
  68     if (*port == UNINITIALIZED_PORT) {
  69       if (getenv(ENV_VAR_NAME_PORT)) {
  70         *port = jalib::StringToInt(getenv(ENV_VAR_NAME_PORT));
  71       } else if (getenv("DMTCP_PORT")) { // deprecated
  72         *port = jalib::StringToInt(getenv("DMTCP_PORT"));
  73       } else if (mode & COORD_NEW) {
  74         *port = 0;
  75       } else {
  76         *port = DEFAULT_PORT;
  77       }
  78     }
  79 
  80     _cachedHost = *host;
  81     _cachedPort = *port;
  82     _firstTime = false;
  83 
  84   } else {
  85     // We might have gotten a user-requested port of 0 (random port) before,
  86     //   and now the user is passing in the actual coordinator port.
  87     if (*port > 0 && _cachedPort == 0) {
  88       _cachedPort = *port;
  89     }
  90     *host = _cachedHost;
  91     *port = _cachedPort;
  92   }
  93 }
  94 void Util::setCoordPort(int port)
  95 { 
  96   const char *host = NULL;
  97   // mode will be ignored, since this is not the first time we call this.
  98   Util::getCoordHostAndPort(COORD_ANY, &host, &port);
  99 }
 100 
 101 void Util::writeCoordPortToFile(int port, const char *portFile)
 102 {
 103   if (portFile != NULL && strlen(portFile) > 0) {
 104     int fd = open(portFile, O_CREAT|O_WRONLY|O_TRUNC, 0600);
 105     JWARNING(fd != -1) (JASSERT_ERRNO) (portFile)
 106       .Text("Failed to open port file.");
 107     char port_buf[30];
 108     memset(port_buf, '\0', sizeof(port_buf));
 109     sprintf(port_buf, "%d", port);
 110     writeAll(fd, port_buf, strlen(port_buf));
 111     fsync(fd);
 112     close(fd);
 113   }
 114 }
 115 
 116 /*
 117  * calcTmpDir() computes the TmpDir to be used by DMTCP. It does so by using
 118  * DMTCP_TMPDIR env, current username, and hostname. Once computed, we open the
 119  * directory on file descriptor PROTECTED_TMPDIR_FD.
 120  *
 121  * This mechanism was introduced to avoid calls to gethostname(), getpwuid()
 122  * etc. while DmtcpWorker was still initializing (in constructor) or the
 123  * process was restarting. gethostname(), getpwuid() will create a socket
 124  * connect to some DNS server to find out hostname and username. The socket is
 125  * closed only at next exec() and thus it leaves a dangling socket in the
 126  * worker process. To resolve this issue, we make sure to call calcTmpDir() only
 127  * from dmtcp_launch and dmtcp_restart process and once the user process
 128  * has been exec()ed, we use SharedData::getTmpDir() only.
 129  */
 130 string Util::calcTmpDir(const char *tmpdirenv)
 131 {
 132   char hostname[256];
 133   memset(hostname, 0, sizeof(hostname));
 134 
 135   JASSERT ( gethostname(hostname, sizeof(hostname)) == 0 ||
 136             errno == ENAMETOOLONG ).Text ( "gethostname() failed" );
 137 
 138   char *userName = const_cast<char *>("");
 139   if ( getpwuid ( getuid() ) != NULL ) {
 140     userName = getpwuid ( getuid() ) -> pw_name;
 141   } else if ( getenv("USER") != NULL ) {
 142     userName = getenv("USER");
 143   }
 144 
 145   if (tmpdirenv) {
 146     // tmpdirenv was set by --tmpdir
 147   } else if (getenv("DMTCP_TMPDIR")) {
 148     tmpdirenv = getenv("DMTCP_TMPDIR");
 149   } else if (getenv("TMPDIR")) {
 150     tmpdirenv = getenv("TMPDIR");
 151   } else {
 152     tmpdirenv = "/tmp";
 153   }
 154 
 155   JASSERT(mkdir(tmpdirenv, S_IRWXU) == 0 || errno == EEXIST)
 156           (JASSERT_ERRNO) (tmpdirenv)
 157     .Text("Error creating base directory (--tmpdir/DMTCP_TMPDIR/TMPDIR)");
 158 
 159   ostringstream o;
 160   o << tmpdirenv << "/dmtcp-" << userName << "@" << hostname;
 161   string tmpDir = o.str();
 162 
 163   JASSERT(mkdir(tmpDir.c_str(), S_IRWXU) == 0 || errno == EEXIST)
 164           (JASSERT_ERRNO) (tmpDir)
 165     .Text("Error creating tmp directory");
 166 
 167 
 168   JASSERT(0 == access(tmpDir.c_str(), X_OK|W_OK)) (tmpDir)
 169     .Text("ERROR: Missing execute- or write-access to tmp dir");
 170 
 171   return tmpDir;
 172 }
 173 
 174 void Util::initializeLogFile(string tmpDir, string procname, string prevLogPath)
 175 {
 176   UniquePid::ThisProcess(true);
 177 #ifdef DEBUG
 178   // Initialize JASSERT library here
 179   ostringstream o;
 180   o << tmpDir;
 181   o << "/jassertlog.";
 182   o << UniquePid::ThisProcess();
 183   o << "_";
 184   if (procname.empty()) {
 185     o << jalib::Filesystem::GetProgramName();
 186   } else {
 187     o << procname;
 188   }
 189 
 190   JASSERT_SET_LOG(o.str(), tmpDir, UniquePid::ThisProcess().toString());
 191 
 192   ostringstream a;
 193   a << "\n========================================";
 194   a << "\nProcess Information";
 195   a << "\n========================================";
 196   a << "\nThis Process: " << UniquePid::ThisProcess()
 197     << "\nParent Process: " << UniquePid::ParentProcess();
 198 
 199   if (!prevLogPath.empty()) {
 200     a << "\nPrev JAssertLog path: " << prevLogPath;
 201   }
 202 
 203   a << "\nArgv: ";
 204   vector<string> args = jalib::Filesystem::GetProgramArgs();
 205   size_t i;
 206   for (i = 0; i < args.size(); i++) {
 207     a << " " << args[i];
 208   }
 209 
 210   a << "\nEnvironment: ";
 211   for (i = 0; environ[i] != NULL; i++) {
 212     a << " " << environ[i] << ";";
 213   }
 214   a << "\n========================================\n";
 215 
 216   JLOG(a.str().c_str());
 217 #else
 218   JASSERT_SET_LOG("", tmpDir, UniquePid::ThisProcess().toString());
 219 #endif
 220   if (getenv(ENV_VAR_QUIET)) {
 221     jassert_quiet = *getenv(ENV_VAR_QUIET) - '0';
 222   } else {
 223     jassert_quiet = 0;
 224   }
 225 #ifdef QUIET
 226   jassert_quiet = 2;
 227 #endif
 228   unsetenv(ENV_VAR_STDERR_PATH);
 229 }

/* [<][>][^][v][top][bottom][index][help] */