root/plugin/pid/pid.cpp

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

DEFINITIONS

This source file includes following definitions.
  1. dmtcp_real_to_virtual_pid
  2. dmtcp_virtual_to_real_pid
  3. dmtcp_get_real_pid
  4. dmtcp_get_real_tid
  5. dmtcp_real_tgkill
  6. pidVirt_AtForkParent
  7. pidVirt_ResetOnFork
  8. pidVirt_PrepareForExec
  9. pidVirt_PostExec
  10. openSharedFile
  11. openOriginalToCurrentMappingFiles
  12. pidVirt_PostRestart
  13. pidVirt_PostRestartRefill
  14. pidVirt_ThreadExit
  15. dmtcp_event_hook

   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 the dmtcp/src module of DMTCP (DMTCP:dmtcp/src).  *
   6  *                                                                          *
   7  *  DMTCP:dmtcp/src 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:dmtcp/src 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 <sys/types.h>
  23 #include "jalloc.h"
  24 #include "jassert.h"
  25 #include "jconvert.h"
  26 #include "jfilesystem.h"
  27 #include "pidwrappers.h"
  28 #include "virtualpidtable.h"
  29 #include "dmtcp.h"
  30 #include "protectedfds.h"
  31 
  32 using namespace dmtcp;
  33 
  34 extern "C" pid_t dmtcp_update_ppid();
  35 
  36 static string pidMapFile;
  37 
  38 extern "C"
  39 pid_t dmtcp_real_to_virtual_pid(pid_t realPid)
  40 {
  41   return REAL_TO_VIRTUAL_PID(realPid);
  42 }
  43 
  44 extern "C"
  45 pid_t dmtcp_virtual_to_real_pid(pid_t virtualPid)
  46 {
  47   return VIRTUAL_TO_REAL_PID(virtualPid);
  48 }
  49 
  50 extern "C"
  51 pid_t dmtcp_get_real_pid()
  52 {
  53   return _real_getpid();
  54 }
  55 
  56 extern "C"
  57 pid_t dmtcp_get_real_tid()
  58 {
  59   return _real_gettid();
  60 }
  61 
  62 extern "C"
  63 int dmtcp_real_tgkill(pid_t tgid, pid_t tid, int sig)
  64 {
  65   return _real_tgkill(tgid, tid, sig);
  66 }
  67 
  68 static void pidVirt_AtForkParent(DmtcpEventData_t *data)
  69 {
  70   pid_t virtPpid = getppid();
  71   pid_t realPpid = VIRTUAL_TO_REAL_PID(virtPpid);
  72   Util::setVirtualPidEnvVar(getpid(), virtPpid, realPpid);
  73 }
  74 
  75 static void pidVirt_ResetOnFork(DmtcpEventData_t *data)
  76 {
  77   VirtualPidTable::instance().resetOnFork();
  78 }
  79 
  80 static void pidVirt_PrepareForExec(DmtcpEventData_t *data)
  81 {
  82   pid_t virtPpid = getppid();
  83   pid_t realPpid = VIRTUAL_TO_REAL_PID(virtPpid);
  84   Util::setVirtualPidEnvVar(getpid(), virtPpid, realPpid);
  85 
  86   JASSERT(data != NULL);
  87   jalib::JBinarySerializeWriterRaw wr ("", data->serializerInfo.fd);
  88   VirtualPidTable::instance().serialize(wr);
  89 }
  90 
  91 static void pidVirt_PostExec(DmtcpEventData_t *data)
  92 {
  93   JASSERT(data != NULL);
  94   jalib::JBinarySerializeReaderRaw rd ("", data->serializerInfo.fd);
  95   VirtualPidTable::instance().serialize(rd);
  96   VirtualPidTable::instance().refresh();
  97 }
  98 
  99 static int openSharedFile(string name, int flags)
 100 {
 101   int fd;
 102   int errno_bkp;
 103   // try to create, truncate & open file
 104 
 105   jalib::string dir = jalib::Filesystem::DirName(name);
 106   JTRACE("shared file dir:")(dir);
 107   jalib::Filesystem::mkdir_r(dir, 0755);
 108 
 109   if ((fd = _real_open(name.c_str(), O_EXCL|O_CREAT|O_TRUNC | flags, 0600)) >= 0) {
 110     return fd;
 111   }
 112   errno_bkp = errno;
 113 
 114   JTRACE("_real_open: ")(strerror(errno))(fd)(flags);
 115 
 116   if ( (fd < 0) && (errno_bkp == EEXIST) ) {
 117     errno = 0;
 118     if ((fd = _real_open(name.c_str(), flags, 0600)) >= 0) {
 119       return fd;
 120     }
 121   }
 122   // unable to create & open OR open
 123   JASSERT(false)(name)(strerror(errno)).Text("Cannot open file");
 124   return -1;
 125 }
 126 
 127 static void openOriginalToCurrentMappingFiles()
 128 {
 129   int fd;
 130   ostringstream o;
 131   o << dmtcp_get_tmpdir() << "/dmtcpPidMap."
 132     << dmtcp_get_computation_id_str() << "."
 133     << std::hex << dmtcp_get_coordinator_timestamp();
 134   pidMapFile = o.str();
 135   // Open and create pidMapFile if it doesn't exist.
 136   JTRACE("Open dmtcpPidMapFile")(pidMapFile);
 137   if (!Util::isValidFd(PROTECTED_PIDMAP_FD)) {
 138     fd = openSharedFile(pidMapFile, O_RDWR);
 139     JASSERT (fd != -1);
 140     JASSERT (dup2 (fd, PROTECTED_PIDMAP_FD) == PROTECTED_PIDMAP_FD)
 141       (pidMapFile);
 142     close (fd);
 143   }
 144 }
 145 
 146 static void pidVirt_PostRestart(DmtcpEventData_t *data)
 147 {
 148   if ( jalib::Filesystem::GetProgramName() == "screen" )
 149     send_sigwinch = 1;
 150   // With hardstatus (bottom status line), screen process has diff. size window
 151   // Must send SIGWINCH to adjust it.
 152   // src/terminal.cpp:restore_term_settings() will send SIGWINCH to process
 153   // on restart.  This will force 'screen' to execute ioctl wrapper.
 154   // The wrapper will report a changed winsize,
 155   // so that 'screen' must re-initialize the screen (scrolling regions, etc.).
 156   // The wrapper will also send a second SIGWINCH.  Then 'screen' will
 157   // call ioctl and get the correct window size and resize again.
 158   // We can't just send two SIGWINCH's now, since window size has not
 159   // changed yet, and 'screen' will assume that there's nothing to do.
 160 
 161   dmtcp_update_ppid();
 162   openOriginalToCurrentMappingFiles();
 163   VirtualPidTable::instance().writeMapsToFile(PROTECTED_PIDMAP_FD);
 164 }
 165 
 166 static void pidVirt_PostRestartRefill(DmtcpEventData_t *data)
 167 {
 168   VirtualPidTable::instance().readMapsFromFile(PROTECTED_PIDMAP_FD);
 169   dmtcp_close_protected_fd(PROTECTED_PIDMAP_FD);
 170   unlink(pidMapFile.c_str());
 171 }
 172 
 173 static void pidVirt_ThreadExit(DmtcpEventData_t *data)
 174 {
 175   /* This thread has finished its execution, do some cleanup on our part.
 176    *  erasing the original_tid entry from virtualpidtable
 177    *  FIXME: What if the process gets checkpointed after erase() but before the
 178    *  thread actually exits?
 179    */
 180   pid_t tid = dmtcp_gettid();
 181   VirtualPidTable::instance().erase(tid);
 182 }
 183 
 184 extern "C" void dmtcp_event_hook(DmtcpEvent_t event, DmtcpEventData_t *data)
 185 {
 186   switch (event) {
 187     case DMTCP_EVENT_ATFORK_PARENT:
 188       pidVirt_AtForkParent(data);
 189       break;
 190 
 191     case DMTCP_EVENT_ATFORK_CHILD:
 192       pidVirt_ResetOnFork(data);
 193       break;
 194 
 195     case DMTCP_EVENT_PRE_EXEC:
 196       pidVirt_PrepareForExec(data);
 197       break;
 198 
 199     case DMTCP_EVENT_POST_EXEC:
 200       pidVirt_PostExec(data);
 201       break;
 202 
 203     case DMTCP_EVENT_RESTART:
 204       pidVirt_PostRestart(data);
 205       break;
 206 
 207     case DMTCP_EVENT_REFILL:
 208       if (data->refillInfo.isRestart) {
 209         pidVirt_PostRestartRefill(data);
 210       }
 211       break;
 212 
 213     case DMTCP_EVENT_PTHREAD_RETURN:
 214     case DMTCP_EVENT_PTHREAD_EXIT:
 215       pidVirt_ThreadExit(data);
 216       break;
 217 
 218     default:
 219       break;
 220   }
 221 
 222   DMTCP_NEXT_EVENT_HOOK(event, data);
 223   return;
 224 }

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