root/plugin/ipc/event/eventconnection.cpp

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

DEFINITIONS

This source file includes following definitions.
  1. drain
  2. refill
  3. postRestart
  4. serializeSubClass
  5. asEpoll
  6. onCTL
  7. drain
  8. refill
  9. postRestart
  10. serializeSubClass
  11. drain
  12. refill
  13. postRestart
  14. serializeSubClass
  15. drain
  16. refill
  17. postRestart
  18. serializeSubClass
  19. asInotify
  20. add_watch_descriptors
  21. remove_watch_descriptors

   1 /****************************************************************************
   2  *   Copyright (C) 2006-2010 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/ioctl.h>
  23 #include <sys/select.h>
  24 #include <sys/un.h>
  25 #include <unistd.h>
  26 #include <fcntl.h>
  27 #include <sys/file.h>
  28 #include <termios.h>
  29 #include <iostream>
  30 #include <ios>
  31 #include <fstream>
  32 #include <linux/limits.h>
  33 #include <arpa/inet.h>
  34 
  35 #include "dmtcp.h"
  36 #include "shareddata.h"
  37 #include "util.h"
  38 #include "jassert.h"
  39 #include "jfilesystem.h"
  40 #include "jconvert.h"
  41 
  42 #include "eventconnection.h"
  43 #include "eventwrappers.h"
  44 #include "util_descriptor.h"
  45 using namespace dmtcp;
  46 /*****************************************************************************
  47  * Epoll Connection
  48  *****************************************************************************/
  49 
  50 #ifdef HAVE_SYS_EPOLL_H
  51 void EpollConnection::drain()
  52 {
  53   JASSERT(_fds.size() > 0);
  54 }
  55 
  56 void EpollConnection::refill(bool isRestart)
  57 {
  58   JASSERT(_fds.size() > 0);
  59   if (isRestart) {
  60     typedef map< int, struct epoll_event >::iterator fdEventIterator;
  61     fdEventIterator fevt = _fdToEvent.begin();
  62     for (; fevt != _fdToEvent.end(); fevt++) {
  63       JTRACE("restore sfd options") (fevt->first);
  64       int ret = _real_epoll_ctl(_fds[0], EPOLL_CTL_ADD, fevt->first,
  65                                 &(fevt->second));
  66       JWARNING(ret == 0) (_fds[0]) (ret) (strerror(errno))
  67         .Text("Error in restoring options");
  68     }
  69   }
  70 }
  71 
  72 void EpollConnection::postRestart()
  73 {
  74   JASSERT(_fds.size()>0);
  75   JTRACE("Recreating epoll connection") (_fds[0]) (id());
  76   int tempFd =  _real_epoll_create(_size) ;
  77   JASSERT(tempFd >= 0);
  78   Util::dupFds(tempFd, _fds);
  79 }
  80 
  81 void EpollConnection::serializeSubClass(jalib::JBinarySerializer& o)
  82 {
  83   JSERIALIZE_ASSERT_POINT("EpollConnection");
  84   o & _type & _stat;
  85   o.serializeMap(_fdToEvent);
  86 }
  87 
  88 EpollConnection& EpollConnection::asEpoll()
  89 {
  90   return *this;
  91 }
  92 
  93 void EpollConnection::onCTL(int op, int fd, struct epoll_event *event)
  94 {
  95   JASSERT(((op==EPOLL_CTL_MOD || op==EPOLL_CTL_ADD) && event != NULL) ||
  96           op==EPOLL_CTL_DEL) (epollType())
  97    (id())
  98     .Text("Passing a NULL event! HUH!");
  99 
 100   struct epoll_event myEvent;
 101   _type = EPOLL_CTL;
 102   if (op == EPOLL_CTL_DEL) {
 103     _fdToEvent.erase(fd);
 104     return;
 105   }
 106   memcpy(&myEvent, event, sizeof myEvent);
 107   _fdToEvent[fd] = myEvent;
 108 }
 109 #endif
 110 
 111 /*****************************************************************************
 112  * Eventfd Connection
 113  *****************************************************************************/
 114 #ifdef HAVE_SYS_EVENTFD_H
 115 void EventFdConnection::drain()
 116 {
 117   JASSERT(_fds.size() > 0);
 118   JTRACE("Checkpoint eventfd.") (_fds[0]);
 119 
 120   int new_flags =(_fcntlFlags &(~(O_RDONLY|O_WRONLY))) | O_RDWR | O_NONBLOCK;
 121   int evtfd = _fds[0];
 122   JASSERT(evtfd >= 0) (evtfd) (JASSERT_ERRNO);
 123   // set the new flags
 124   JASSERT(fcntl(evtfd, F_SETFL, new_flags) == 0)
 125    (evtfd) (new_flags) (JASSERT_ERRNO);
 126   ssize_t size;
 127   uint64_t u;
 128   unsigned int counter = 1;
 129 
 130   // Read whatever is there on top of evtfd
 131   size = read(evtfd, &u, sizeof(uint64_t));
 132   if (-1 != size) {
 133     JTRACE("Read value u: ") (evtfd) (u);
 134     // EFD_SEMAPHORE flag not specified,
 135     // the counter value would have been reset to 0 upon read
 136     // Save the value, so that it can be restored in post-checkpoint
 137     if (!(_flags & EFD_SEMAPHORE)) {
 138       _initval = u;
 139     } else {
 140       // EFD_SEMAPHORE specified, so can't read the current counter value
 141       // Keep reading till "semaphore" becomes 0.
 142       while (-1 != read(evtfd, &u, sizeof(uint64_t)))
 143         counter++;
 144       _initval = counter;
 145     }
 146   } else {
 147     JTRACE("Nothing to be read from eventfd.")
 148       (evtfd) (errno) (strerror(errno));
 149     _initval = 0;
 150   }
 151   JTRACE("Checkpointing eventfd:  end.") (_fds[0]) (_initval);
 152 }
 153 
 154 void EventFdConnection::refill(bool isRestart)
 155 {
 156   JTRACE("Begin refill eventfd.") (_fds[0]);
 157   JASSERT(_fds.size() > 0);
 158   evtfd = _fds[0];
 159   if (!isRestart) {
 160     uint64_t u =(unsigned long long) _initval;
 161     JTRACE("Writing") (u);
 162     JWARNING(write(evtfd, &u, sizeof(uint64_t)) == sizeof(uint64_t))
 163       (evtfd) (errno) (strerror(errno))
 164       .Text("Write to eventfd failed during refill");
 165   }
 166   JTRACE("End refill eventfd.") (_fds[0]);
 167 }
 168 
 169 void EventFdConnection::postRestart()
 170 {
 171   JASSERT(_fds.size() > 0);
 172 
 173   JTRACE("Restoring EventFd Connection") (id());
 174   errno = 0;
 175   int tempfd = _real_eventfd(_initval, _flags);
 176   JASSERT(tempfd > 0) (tempfd) (JASSERT_ERRNO);
 177   Util::dupFds(tempfd, _fds);
 178 }
 179 
 180 void EventFdConnection::serializeSubClass(jalib::JBinarySerializer& o)
 181 {
 182   JSERIALIZE_ASSERT_POINT("EventFdConnection");
 183   o & _initval & _flags;
 184   JTRACE("Serializing EvenFdConn.") ;
 185 }
 186 #endif
 187 
 188 /*****************************************************************************
 189  * Signalfd Connection
 190  *****************************************************************************/
 191 #ifdef HAVE_SYS_SIGNALFD_H
 192 void SignalFdConnection::drain()
 193 {
 194   JASSERT(_fds.size() > 0);
 195 
 196   JTRACE("Checkpoint signalfd.") (_fds[0]);
 197 
 198   int new_flags =(_fcntlFlags &(~(O_RDONLY|O_WRONLY))) | O_RDWR | O_NONBLOCK;
 199   signlfd = _fds[0];
 200   JASSERT(signlfd >= 0) (signlfd) (JASSERT_ERRNO);
 201   // set the new flags
 202   JASSERT(fcntl(signlfd, F_SETFL, new_flags) == 0)
 203    (signlfd) (new_flags) (JASSERT_ERRNO);
 204   ssize_t size;
 205   struct signalfd_siginfo _fdsi;
 206 
 207   // Read whatever is there on top of signalfd
 208   size = read(signlfd, &_fdsi, sizeof(struct signalfd_siginfo));
 209   if (-1 != size) {
 210     // Save the value, so that it can be restored in post-checkpoint
 211     memcpy(&_fdsi, &_fdsi, sizeof(struct signalfd_siginfo));
 212 
 213   } else {
 214     JTRACE("Nothing to be read from signalfd.")
 215       (signlfd) (errno) (strerror(errno));
 216   }
 217   JTRACE("Checkpointing signlfd:  end.") (_fds[0]) ;
 218 }
 219 
 220 void SignalFdConnection::refill(bool isRestart)
 221 {
 222   JTRACE("Begin refill signalfd.") (_fds[0]);
 223   JASSERT(_fds.size() > 0);
 224   //raise the signals
 225   JTRACE("Raising the signal...") (_fdsi.ssi_signo);
 226   raise(_fdsi.ssi_signo);
 227   JTRACE("End refill signalfd.") (_fds[0]);
 228 }
 229 
 230 void SignalFdConnection::postRestart()
 231 {
 232   JASSERT(_fds.size() > 0);
 233 
 234   JTRACE("Restoring SignalFd Connection") (id());
 235   errno = 0;
 236   int tempfd = _real_signalfd(-1, &_mask, _flags);
 237   JASSERT(tempfd > 0) (tempfd) (JASSERT_ERRNO);
 238   Util::dupFds(tempfd, _fds);
 239 }
 240 
 241 void SignalFdConnection::serializeSubClass(jalib::JBinarySerializer& o)
 242 {
 243   JSERIALIZE_ASSERT_POINT("SignalFdConnection");
 244   o &  _flags & _mask & _fdsi;
 245   JTRACE("Serializing SignalFdConn.") ;
 246 }
 247 #endif
 248 
 249 #ifdef DMTCP_USE_INOTIFY
 250 /*****************************************************************************
 251  * Inotify Connection
 252  *****************************************************************************/
 253 void InotifyConnection::drain()
 254 {
 255   JASSERT(_fds.size() > 0);
 256 }
 257 
 258 void InotifyConnection::refill(bool isRestart)
 259 {
 260   JASSERT(_fds.size() > 0);
 261   if (isRestart) {
 262     int num_of_descriptors;
 263     Util::Descriptor descriptor;
 264     descriptor_types_u  watch_descriptor;
 265 
 266     //get the number of watch descriptors stored in dmtcp
 267     num_of_descriptors = descriptor.count_descriptors();
 268 
 269     JTRACE("inotify restoreOptions") (_fds[0]) (id()) (num_of_descriptors);
 270 
 271     for (int i = 0; i < num_of_descriptors; i++) {
 272       if (true == descriptor.get_descriptor(i, INOTIFY_ADD_WATCH_DESCRIPTOR,
 273                                             &watch_descriptor)) {
 274         int old_wd = watch_descriptor.add_watch.watch_descriptor;
 275 
 276         int new_wd =
 277           _real_inotify_add_watch(watch_descriptor.add_watch.file_descriptor,
 278                                   watch_descriptor.add_watch.pathname,
 279                                   watch_descriptor.add_watch.mask);
 280 
 281         JWARNING(_real_dup2(new_wd, old_wd) == old_wd)
 282           (new_wd) (old_wd) (JASSERT_ERRNO);
 283         JTRACE("restore watch descriptors")
 284           (old_wd) (new_wd) (watch_descriptor.add_watch.file_descriptor)
 285           (watch_descriptor.add_watch.pathname)
 286           (watch_descriptor.add_watch.mask);
 287       }
 288     }
 289   }
 290 }
 291 
 292 void InotifyConnection::postRestart()
 293 {
 294   //create a new inotify instance and clone it as the old one
 295   int tempfd =  _real_inotify_init1(_flags);
 296   JASSERT(tempfd >= 0);
 297   Util::dupFds(tempfd, _fds);
 298 }
 299 
 300 void InotifyConnection::serializeSubClass(jalib::JBinarySerializer& o)
 301 {
 302   JSERIALIZE_ASSERT_POINT("InotifyConnection");
 303   o & _type & _stat;
 304   //o.serializeMap(_inotify_fd_to_wd);
 305   //o.serializeMap(_wd_to_pathname);
 306   //o.serializeMap(_pathname_to_mask);
 307 }
 308 
 309 InotifyConnection& InotifyConnection::asInotify()
 310 {
 311   JTRACE("Return the connection as Inotify connection");
 312   return *this;
 313 }
 314 
 315 void InotifyConnection::add_watch_descriptors(int wd, int fd,
 316                                                      const char *pathname,
 317                                                      uint32_t mask)
 318 {
 319    int string_len;
 320 
 321    JTRACE("save inotify watch descriptor within dmtcp")
 322      (wd) (fd) (pathname) (mask);
 323    JASSERT(pathname != NULL) .Text("pathname is NULL");
 324    if (NULL != pathname) {
 325       Util::Descriptor descriptor;
 326       descriptor_types_u  watch_descriptor;
 327 
 328       //set watch_descriptor to zeros
 329       memset(&watch_descriptor, 0, sizeof(watch_descriptor));
 330 
 331       // get the string length
 332       string_len = strlen(pathname);
 333 
 334       // fill up the structure
 335       watch_descriptor.add_watch.file_descriptor = fd;
 336       watch_descriptor.add_watch.mask = mask;
 337       watch_descriptor.add_watch.watch_descriptor = wd;
 338       watch_descriptor.add_watch.type = INOTIFY_ADD_WATCH_DESCRIPTOR;
 339       strncpy(watch_descriptor.add_watch.pathname, pathname, string_len);
 340 
 341       // save the watch descriptor structure
 342       descriptor.add_descriptor(&watch_descriptor);
 343    }
 344 }
 345 
 346 void  InotifyConnection::remove_watch_descriptors(int wd)
 347 {
 348    Util::Descriptor descriptor;
 349    descriptor.remove_descriptor(INOTIFY_ADD_WATCH_DESCRIPTOR, (void *)&wd);
 350 }
 351 #endif

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