root/plugin/pid/pidwrappers.cpp

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

DEFINITIONS

This source file includes following definitions.
  1. getPidFromEnvVar
  2. dmtcpResetPidPpid
  3. dmtcpResetTid
  4. dmtcp_update_ppid
  5. dmtcp_gettid
  6. getpid
  7. getppid
  8. tcsetpgrp
  9. tcgetpgrp
  10. tcgetsid
  11. getpgrp
  12. setpgrp
  13. getpgid
  14. setpgid
  15. getsid
  16. setsid
  17. kill
  18. dmtcp_tkill
  19. dmtcp_tgkill
  20. wait
  21. waitpid
  22. waitid
  23. wait3
  24. wait4
  25. ptrace
  26. fcntl

   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 <stdarg.h>
  23 #include <vector>
  24 #include <list>
  25 #include <string>
  26 #include <fcntl.h>
  27 #include <sys/ioctl.h>
  28 #include <sys/syscall.h>
  29 #include <sys/procfs.h>
  30 
  31 #include "jassert.h"
  32 #include "jconvert.h"
  33 #include "pidwrappers.h"
  34 #include "virtualpidtable.h"
  35 #include "dmtcp.h"
  36 #include "pid.h"
  37 #include "util.h"
  38 
  39 using namespace dmtcp;
  40 
  41 static __thread pid_t _dmtcp_thread_tid = -1;
  42 
  43 static pid_t _dmtcp_pid = -1;
  44 static pid_t _dmtcp_ppid = -1;
  45 
  46 LIB_PRIVATE pid_t getPidFromEnvVar()
  47 {
  48   const char *pidstr = getenv(ENV_VAR_VIRTUAL_PID);
  49   if (pidstr == NULL) {
  50     fprintf(stderr, "ERROR at %s:%d: env var DMTCP_VIRTUAL_PID not set\n\n",
  51             __FILE__, __LINE__);
  52     sleep(5);
  53     _exit(0);
  54   }
  55   return strtol(pidstr, NULL, 10);
  56 }
  57 
  58 extern "C" LIB_PRIVATE
  59 void dmtcpResetPidPpid()
  60 {
  61   const char *pidstr = getenv(ENV_VAR_VIRTUAL_PID);
  62   char *virtPpidstr = NULL;
  63   char *realPpidstr = NULL;
  64   pid_t virtPpid;
  65   pid_t realPpid;
  66 
  67   if (pidstr == NULL) {
  68     fprintf(stderr, "ERROR at %s:%d: env var DMTCP_VIRTUAL_PID not set\n\n",
  69             __FILE__, __LINE__);
  70     sleep(5);
  71     _exit(0);
  72   }
  73   _dmtcp_pid = strtol(pidstr, &virtPpidstr, 10);
  74   VirtualPidTable::instance().updateMapping(_dmtcp_pid, _real_getpid());
  75 
  76   if (virtPpidstr[0] != ':' && !isdigit(virtPpidstr[1])) {
  77     fprintf(stderr, "ERROR at %s:%d: env var DMTCP_VIRTUAL_PID invalid\n\n",
  78             __FILE__, __LINE__);
  79     sleep(5);
  80     _exit(0);
  81   }
  82   virtPpid = strtol(virtPpidstr + 1, &realPpidstr, 10);
  83 
  84   if (realPpidstr[0] != ':' && !isdigit(realPpidstr[1])) {
  85     fprintf(stderr, "ERROR at %s:%d: env var DMTCP_VIRTUAL_PID invalid\n\n",
  86             __FILE__, __LINE__);
  87     sleep(5);
  88     _exit(0);
  89   }
  90   realPpid = strtol(realPpidstr + 1, NULL, 10);
  91 
  92   pid_t curRealPpid = _real_getppid();
  93   if (realPpid != curRealPpid) {
  94     // Parent is dead; we have a new parent (init).
  95     _dmtcp_ppid = curRealPpid;
  96   } else {
  97     // Parent is alive.
  98     // We shouldn't need to update mapping for virtual->real ppid. If we are
  99     // the same process as dmtcp_launch, then the parent would not be under
 100     // DMTCP anyways. Instead, if we were created after a fork, we inherited
 101     // the memory maps. However, if we did an exec after a fork, we might not
 102     // have had a chance to serialize the maps yet, so we better insert the
 103     // mapping here.
 104     _dmtcp_ppid = virtPpid;
 105     VirtualPidTable::instance().updateMapping(_dmtcp_ppid, curRealPpid);
 106   }
 107 }
 108 
 109 
 110 extern "C" LIB_PRIVATE
 111 void dmtcpResetTid(pid_t tid)
 112 {
 113   _dmtcp_thread_tid = tid;
 114 }
 115 
 116 /* FIXME: Once we have implemented the plugin calling mechanism in which the
 117  * plugins are called in the reverse order during restart/resume phase, we can
 118  * call this function while processing RESTART event.
 119  */
 120 extern "C"
 121 void dmtcp_update_ppid()
 122 {
 123   if (_dmtcp_ppid != 1) {
 124     VirtualPidTable::instance().updateMapping(_dmtcp_ppid,
 125                                                      _real_getppid());
 126   }
 127 }
 128 
 129 LIB_PRIVATE pid_t dmtcp_gettid()
 130 {
 131   /* dmtcp::ThreadList::updateTid calls gettid() before calling
 132    *  ThreadSync::decrementUninitializedThreadCount() and so the value is
 133    * cached before it is accessed by some other DMTCP code.
 134    */
 135   if (_dmtcp_thread_tid == -1) {
 136     _dmtcp_thread_tid = getpid();
 137     // Make sure this is the motherofall thread.
 138     JASSERT(_real_gettid() == _real_getpid()) (_real_gettid()) (_real_getpid());
 139   }
 140   return _dmtcp_thread_tid;
 141 }
 142 
 143 extern "C" pid_t getpid()
 144 {
 145   if (_dmtcp_pid == -1) {
 146     dmtcpResetPidPpid();
 147   }
 148   return _dmtcp_pid;
 149 }
 150 
 151 extern "C" pid_t getppid()
 152 {
 153   if (_dmtcp_ppid == -1) {
 154     dmtcpResetPidPpid();
 155   }
 156   if (_real_getppid() != VIRTUAL_TO_REAL_PID(_dmtcp_ppid)) {
 157     // The original parent died; reset our ppid.
 158     //
 159     // On older systems, a process is inherited by init (pid = 1) after its
 160     // parent dies. However, with the new per-user init process, the parent
 161     // pid is no longer "1"; it's the pid of the user-specific init process.
 162     _dmtcp_ppid = _real_getppid();
 163   }
 164   return _dmtcp_ppid;
 165 }
 166 
 167 extern "C" pid_t tcsetpgrp(int fd, pid_t pgrp)
 168 {
 169   DMTCP_PLUGIN_DISABLE_CKPT();
 170 
 171   pid_t currPgrp = VIRTUAL_TO_REAL_PID(pgrp);
 172 //  JTRACE("Inside tcsetpgrp wrapper") (fd) (pgrp) (currPgrp);
 173   pid_t realPid = _real_tcsetpgrp(fd, currPgrp);
 174   pid_t virtualPid = REAL_TO_VIRTUAL_PID(realPid);
 175 
 176   //JTRACE("tcsetpgrp return value") (fd) (pgrp) (currPgrp) (retval);
 177   DMTCP_PLUGIN_ENABLE_CKPT();
 178 
 179   return virtualPid;
 180 }
 181 
 182 extern "C" pid_t tcgetpgrp(int fd)
 183 {
 184   DMTCP_PLUGIN_DISABLE_CKPT();
 185 
 186   pid_t retval = REAL_TO_VIRTUAL_PID(_real_tcgetpgrp(fd));
 187 
 188   JTRACE("tcgetpgrp return value") (fd) (retval);
 189   DMTCP_PLUGIN_ENABLE_CKPT();
 190 
 191   return retval;
 192 }
 193 
 194 extern "C" pid_t tcgetsid(int fd)
 195 {
 196   DMTCP_PLUGIN_DISABLE_CKPT();
 197 
 198   pid_t retval = REAL_TO_VIRTUAL_PID(_real_tcgetsid(fd));
 199 
 200   JTRACE("tcgetsid return value") (fd) (retval);
 201   DMTCP_PLUGIN_ENABLE_CKPT();
 202 
 203   return retval;
 204 }
 205 
 206 extern "C" pid_t getpgrp(void)
 207 {
 208   DMTCP_PLUGIN_DISABLE_CKPT();
 209 
 210   pid_t pgrp = _real_getpgrp();
 211   pid_t origPgrp =  REAL_TO_VIRTUAL_PID(pgrp);
 212 
 213   DMTCP_PLUGIN_ENABLE_CKPT();
 214 
 215   return origPgrp;
 216 }
 217 
 218 extern "C" int setpgrp(void)
 219 {
 220   DMTCP_PLUGIN_DISABLE_CKPT();
 221 
 222   pid_t realPid = _real_setpgrp();
 223   pid_t virtualPid = REAL_TO_VIRTUAL_PID(realPid);
 224 
 225   DMTCP_PLUGIN_ENABLE_CKPT();
 226 
 227   return virtualPid;
 228 }
 229 
 230 extern "C" pid_t getpgid(pid_t pid)
 231 {
 232   DMTCP_PLUGIN_DISABLE_CKPT();
 233 
 234   pid_t realPid = VIRTUAL_TO_REAL_PID (pid);
 235   pid_t res = _real_getpgid (realPid);
 236   pid_t origPgid = REAL_TO_VIRTUAL_PID (res);
 237 
 238   DMTCP_PLUGIN_ENABLE_CKPT();
 239 
 240   return origPgid;
 241 }
 242 
 243 extern "C" int   setpgid(pid_t pid, pid_t pgid)
 244 {
 245   DMTCP_PLUGIN_DISABLE_CKPT();
 246 
 247   pid_t currPid = VIRTUAL_TO_REAL_PID (pid);
 248   pid_t currPgid = VIRTUAL_TO_REAL_PID (pgid);
 249 
 250   int retVal = _real_setpgid (currPid, currPgid);
 251 
 252   DMTCP_PLUGIN_ENABLE_CKPT();
 253 
 254   return retVal;
 255 }
 256 
 257 extern "C" pid_t getsid(pid_t pid)
 258 {
 259   DMTCP_PLUGIN_DISABLE_CKPT();
 260 
 261   pid_t currPid;
 262 
 263   // If !pid then we ask SID of this process
 264   if (pid)
 265     currPid = VIRTUAL_TO_REAL_PID (pid);
 266   else
 267     currPid = _real_getpid();
 268 
 269   pid_t res = _real_getsid (currPid);
 270 
 271   pid_t origSid = REAL_TO_VIRTUAL_PID (res);
 272 
 273   DMTCP_PLUGIN_ENABLE_CKPT();
 274 
 275   return origSid;
 276 }
 277 
 278 extern "C" pid_t setsid(void)
 279 {
 280   DMTCP_PLUGIN_DISABLE_CKPT();
 281 
 282   pid_t pid = _real_setsid();
 283   pid_t origPid = REAL_TO_VIRTUAL_PID (pid);
 284 
 285   DMTCP_PLUGIN_ENABLE_CKPT();
 286 
 287   return origPid;
 288 }
 289 
 290 extern "C" int   kill(pid_t pid, int sig)
 291 {
 292   /* FIXME: When bash receives a SIGINT signal, the signal handler is
 293    * called to process the signal. Once the processing is done, bash
 294    * performs a longjmp to a much higher call frame. As a result, this
 295    * call frame never gets a chance to return and hence we fail to
 296    * perform DMTCP_PLUGIN_ENABLE_CKPT() WHICH RESULTS in the lock
 297    * being held but never released. Thus later on, when the ckpt-thread
 298    * tries to acquire this lock, it results in a deadlock.
 299    *
 300    *  To avoid the deadlock, FOR NOW, we shouldn't call WRAPPER_...()
 301    *  calls in this function or any kill() family of wrappers.
 302    *
 303    * Potential Solution: If the signal sending process is among the
 304    * potential signal receivers, it should MASK/BLOCK signal delivery
 305    * right before sending the signal (before calling _real_kill()). Once
 306    * the system call returns, it should then call
 307    * DMTCP_PLUGIN_ENABLE_CKPT() AND THEN RESTore the signal mask to
 308    * as it was prior to calling this wrapper. So this function will as
 309    * follows:
 310    *     DMTCP_PLUGIN_DISABLE_CKPT();
 311    *     // if this process is a potential receiver of this signal
 312    *     if (pid == getpid() || pid == 0 || pid == -1 ||
 313    *         getpgrp() == abs(pid)) {
 314    *       <SAVE_SIGNAL_MASK>;
 315    *       <BLOCK SIGNAL 'sig'>;
 316    *       sigmaskAltered = true;
 317    *     }
 318    *     pid_t currPid = VIRTUAL_TO_REAL_PID(pid);
 319    *     int retVal = _real_kill(currPid, sig);
 320    *     DMTCP_PLUGIN_ENABLE_CKPT();
 321    *     if (sigmaskAltered) {
 322    *       <RESTORE_SIGNAL_MASK>
 323    *     }
 324    *     return retVal;
 325    *
 326    *
 327    * This longjmp trouble can happen with any wrapper, whose execution my
 328    * end up in a call to user-code i.e. if the call frame looks sth like:
 329    *        ...
 330    *        user_func1(...)
 331    *        ...
 332    *        DMTCP_WRAPPER(...)
 333    *        ...
 334    *        user_func2(...)
 335    *        ...
 336    *
 337    * Another potential way would be to put a wrapper around longjmp() in
 338    * which the calling thread should release all the DMTCP-locks being
 339    * held at the moment. This would require us to keep a count of lock()
 340    * calls without a corresponding unlock() call. After the longjmp()
 341    * call, one need to make sure that an unlock() call is requested only
 342    * if there is a corresponding lock, because it might happen that
 343    * longjmp() was harmless in the sense that, it didn't cause a
 344    * callframe like the one mentioned above.
 345    *
 346    */
 347 //  DMTCP_PLUGIN_DISABLE_CKPT();
 348 
 349   pid_t currPid = VIRTUAL_TO_REAL_PID (pid);
 350 
 351   int retVal = _real_kill (currPid, sig);
 352 
 353 //  DMTCP_PLUGIN_ENABLE_CKPT();
 354 
 355   return retVal;
 356 }
 357 
 358 LIB_PRIVATE
 359 int dmtcp_tkill(int tid, int sig)
 360 {
 361   // FIXME: Check the comments in kill()
 362 //  DMTCP_PLUGIN_DISABLE_CKPT();
 363 
 364   int realTid = VIRTUAL_TO_REAL_PID (tid);
 365 
 366   int retVal = _real_tkill (realTid, sig);
 367 
 368 //  DMTCP_PLUGIN_ENABLE_CKPT();
 369 
 370   return retVal;
 371 }
 372 
 373 LIB_PRIVATE
 374 int dmtcp_tgkill(int tgid, int tid, int sig)
 375 {
 376   // FIXME: Check the comments in kill()
 377 //  DMTCP_PLUGIN_DISABLE_CKPT();
 378 
 379   int realTgid = VIRTUAL_TO_REAL_PID (tgid);
 380   int realTid = VIRTUAL_TO_REAL_PID (tid);
 381 
 382   int retVal = _real_tgkill (realTgid, realTid, sig);
 383 
 384 //  DMTCP_PLUGIN_ENABLE_CKPT();
 385 
 386   return retVal;
 387 }
 388 
 389 
 390 //long sys_tgkill (int tgid, int pid, int sig)
 391 
 392 /*
 393  * TODO: Add the wrapper protection for wait() family of system calls.
 394  *       It wouldn't be a straight forward process, we need to take care of the
 395  *         _BLOCKING_ property of these system calls.
 396  *                                                      --KAPIL
 397  */
 398 
 399 extern "C" pid_t wait (__WAIT_STATUS stat_loc)
 400 {
 401   return waitpid(-1, (int*)stat_loc, 0);
 402 }
 403 
 404 extern "C" pid_t waitpid(pid_t pid, int *stat_loc, int options)
 405 {
 406   return wait4(pid, stat_loc, options, NULL);
 407 }
 408 
 409 extern "C" int waitid(idtype_t idtype, id_t id, siginfo_t *infop, int options)
 410 {
 411   int retval = 0;
 412   struct timespec ts = {0, 1000};
 413   const struct timespec maxts = {1, 0};
 414   siginfo_t siginfop;
 415   memset(&siginfop, 0, sizeof(siginfop));
 416 
 417   /* waitid returns 0 in case of success as well as when WNOHANG is specified
 418    * and we need to distinguish those two cases.man page for waitid says:
 419    *   If WNOHANG was specified in options and there were no children in a
 420    *   waitable  state, then waitid() returns 0 immediately and the state of
 421    *   the siginfo_t structure pointed to by infop is unspecified.  To
 422    *   distinguish this case from that where a child was in a  waitable state,
 423    *   zero out the si_pid field before the call and check for a nonzero value
 424    *   in this field after the call returns.
 425    *
 426    * See comments above wait4()
 427    */
 428   while (retval == 0) {
 429     DMTCP_PLUGIN_DISABLE_CKPT();
 430     pid_t currPid = VIRTUAL_TO_REAL_PID (id);
 431     retval = _real_waitid (idtype, currPid, &siginfop, options | WNOHANG);
 432 
 433     if (retval != -1) {
 434       pid_t virtualPid = REAL_TO_VIRTUAL_PID (siginfop.si_pid);
 435       siginfop.si_pid = virtualPid;
 436 
 437       if (siginfop.si_code == CLD_EXITED || siginfop.si_code == CLD_KILLED)
 438         VirtualPidTable::instance().erase(virtualPid);
 439     }
 440     DMTCP_PLUGIN_ENABLE_CKPT();
 441 
 442     if ((options & WNOHANG) ||
 443         retval == -1 ||
 444         siginfop.si_pid != 0) {
 445       break;
 446     } else {
 447       nanosleep(&ts, NULL);
 448       if (TIMESPEC_CMP(&ts, &maxts, <)) {
 449         TIMESPEC_ADD(&ts, &ts, &ts);
 450       }
 451     }
 452   }
 453 
 454   if (retval == 0 && infop != NULL) {
 455     *infop = siginfop;
 456   }
 457 
 458   return retval;
 459 }
 460 
 461 extern "C" pid_t wait3(__WAIT_STATUS status, int options, struct rusage *rusage)
 462 {
 463   return wait4(-1, status, options, rusage);
 464 }
 465 
 466 /*
 467  * wait() family and checkpoint/restart.
 468  *
 469  * wait() returns the _real_ pid of the child process. The
 470  * pid-virtualization layer then converts it to virtualPid pid and return it to
 471  * the caller.
 472  *
 473  * To guarantee the correctness of the real to virtualPid conversion, we need
 474  * to make sure that there is no ckpt/restart in between (A) returning from
 475  * wait(), and (B) performing conversion. If a ckpt happens in between, then on
 476  * restart, the real pid won't be valid anymore and the conversion would be
 477  * a false one.
 478  *
 479  * One way to avoid ckpt/restart in between state A and B is to disable ckpt
 480  * before A and enable it only after performing B. The problem in doing this is
 481  * the fact that wait is a blocking system call, unless WNOHANG is specified.
 482  * Thus we force the WNOHANG flag even though the caller didn't want to.
 483  *
 484  * When WNOHANG is specified, a return value of '0' indicates that there is no
 485  * child process to be waited for, in which case we sleep for a small amount of
 486  * time and retry.
 487  *
 488  * The last bit of logic is the amount of time to sleep for. Too little, and we
 489  * end up wasting CPU time; too large, and some application (for eg: strace)
 490  * might not like. We try to avoid this problem by starting with a tiny sleep
 491  * interval and on every failed wait(), we double the interval until we reach a
 492  * max. Once it reaches a max time, we don't double it, we just use it as is.
 493  *
 494  * The initial sleep interval is set to 10 micro seconds and the max is set to
 495  * 1 second. We hope that it would cover all the cases.
 496  *
 497  */
 498 extern "C"
 499 pid_t wait4(pid_t pid, __WAIT_STATUS status, int options, struct rusage *rusage)
 500 {
 501   int stat;
 502   int saved_errno = errno;
 503   pid_t currPid;
 504   pid_t virtualPid;
 505   pid_t retval = 0;
 506   struct timespec ts = {0, 1000};
 507   const struct timespec maxts = {1, 0};
 508 
 509   if (status == NULL)
 510     status = (__WAIT_STATUS) &stat;
 511 
 512   while (retval == 0) {
 513     DMTCP_PLUGIN_DISABLE_CKPT();
 514     currPid = VIRTUAL_TO_REAL_PID(pid);
 515     retval = _real_wait4(currPid, status, options | WNOHANG, rusage);
 516     saved_errno = errno;
 517     virtualPid = REAL_TO_VIRTUAL_PID(retval);
 518 
 519     if (retval > 0 &&
 520         (WIFEXITED(*(int*)status) || WIFSIGNALED(*(int*)status))) {
 521       VirtualPidTable::instance().erase(virtualPid);
 522     }
 523     DMTCP_PLUGIN_ENABLE_CKPT();
 524 
 525     if ((options & WNOHANG) || retval != 0) {
 526       break;
 527     } else {
 528       nanosleep(&ts, NULL);
 529       if (TIMESPEC_CMP(&ts, &maxts, <)) {
 530         TIMESPEC_ADD(&ts, &ts, &ts);
 531       }
 532     }
 533   }
 534   errno = saved_errno;
 535   return virtualPid;
 536 }
 537 
 538 extern "C" long ptrace (enum __ptrace_request request, ...)
 539 {
 540   va_list ap;
 541   pid_t virtualPid;
 542   pid_t realPid;
 543   void *addr;
 544   void *data;
 545 
 546   va_start(ap, request);
 547   virtualPid = va_arg(ap, pid_t);
 548   addr = va_arg(ap, void *);
 549   data = va_arg(ap, void *);
 550   va_end(ap);
 551 
 552   realPid = VIRTUAL_TO_REAL_PID(virtualPid);
 553   long ptrace_ret =  _real_ptrace(request, realPid, addr, data);
 554 
 555   /*
 556    * PTRACE_GETEVENTMSG (since Linux 2.5.46)
 557    *          Retrieve  a message (as an unsigned long) about the ptrace event
 558    *          that just happened, placing it in the location data in the
 559    *          parent.  For PTRACE_EVENT_EXIT this is the child's exit status.
 560    *          For PTRACE_EVENT_FORK, PTRACE_EVENT_VFORK and PTRACE_EVENT_CLONE
 561    *          this is the PID  of the new process.  Since Linux 2.6.18, the PID
 562    *          of the new process is also available for PTRACE_EVENT_VFORK_DONE.
 563    *          (addr is ignored.)
 564    */
 565 
 566 #ifdef PT_GETEVENTMSG
 567   if (ptrace_ret == 0 && request == PTRACE_GETEVENTMSG) {
 568     unsigned long *ldata = (unsigned long*) data;
 569     pid_t newRealPid =  (pid_t) *ldata;
 570     *ldata = (unsigned long) REAL_TO_VIRTUAL_PID(newRealPid);
 571   }
 572 #endif
 573 
 574   return ptrace_ret;
 575 }
 576 
 577 extern "C" int fcntl(int fd, int cmd, ...)
 578 {
 579   va_list ap;
 580   // Handling the variable number of arguments
 581   void *arg_in = NULL;
 582   void *arg = NULL;
 583   va_start(ap, cmd);
 584   arg_in = va_arg(ap, void *);
 585   va_end(ap);
 586 
 587   arg = arg_in;
 588 
 589   DMTCP_PLUGIN_DISABLE_CKPT();
 590 
 591   if (cmd == F_SETOWN) {
 592     pid_t virtualPid = VIRTUAL_TO_REAL_PID((pid_t) (unsigned long) arg_in);
 593     arg = (void*) (unsigned long) virtualPid;
 594   }
 595 
 596   int result = _real_fcntl(fd, cmd, arg);
 597   int retval = result;
 598 
 599   if (cmd == F_GETOWN) {
 600     retval = REAL_TO_VIRTUAL_PID(result);
 601   }
 602 
 603   DMTCP_PLUGIN_ENABLE_CKPT();
 604   return retval;
 605 }
 606 
 607 /*
 608 extern "C" int setgid(gid_t gid)
 609 {
 610   return _real_setgid(gid);
 611 }
 612 
 613 extern "C" int setuid(uid_t uid)
 614 {
 615   return _real_setuid(uid);
 616 }
 617 */
 618 
 619 // long sys_set_tid_address(int __user *tidptr);
 620 // extern "C" int   sigqueue(pid_t pid, int signo, const union sigval value)
 621 
 622 
 623 // long sys_getuid(void);
 624 // long sys_geteuid(void);
 625 // long sys_getgid(void);
 626 // long sys_getegid(void);
 627 // long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid);
 628 // long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid);
 629 // long sys_getpgrp(void);
 630 // long sys_getgroups(int gidsetsize, gid_t __user *grouplist);
 631 //
 632 // long sys_setregid(gid_t rgid, gid_t egid);
 633 // long sys_setgid(gid_t gid);
 634 // long sys_setreuid(uid_t ruid, uid_t euid);
 635 // long sys_setuid(uid_t uid);
 636 // long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid);
 637 // long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid);
 638 // long sys_setfsuid(uid_t uid);
 639 // long sys_setfsgid(gid_t gid);
 640 // long sys_setsid(void);
 641 // long sys_setgroups(int gidsetsize, gid_t __user *grouplist);
 642 //
 643 //
 644 // long sys_sched_setscheduler(pid_t pid, int policy,
 645 //                                      struct sched_param __user *param);
 646 // long sys_sched_setparam(pid_t pid,
 647 //                                      struct sched_param __user *param);
 648 // long sys_sched_getscheduler(pid_t pid);
 649 // long sys_sched_getparam(pid_t pid,
 650 //                                      struct sched_param __user *param);
 651 // long sys_sched_setaffinity(pid_t pid, unsigned int len,
 652 //                                      unsigned long __user *user_mask_ptr);
 653 // long sys_sched_getaffinity(pid_t pid, unsigned int len,
 654 //                                      unsigned long __user *user_mask_ptr);
 655 // long sys_sched_yield(void);
 656 // long sys_sched_rr_get_interval(pid_t pid,
 657 //
 658 //
 659 // long sys_rt_sigqueueinfo(int pid, int sig, siginfo_t __user *uinfo);
 660 //
 661 //
 662 //
 663 //
 664 // long sys_chown(const char __user *filename,
 665 //                              uid_t user, gid_t group);
 666 // long sys_lchown(const char __user *filename,
 667 //                              uid_t user, gid_t group);
 668 // long sys_fchown(unsigned int fd, uid_t user, gid_t group);
 669 // #ifdef CONFIG_UID16
 670 // long sys_chown16(const char __user *filename,
 671 //                              old_uid_t user, old_gid_t group);
 672 // long sys_lchown16(const char __user *filename,
 673 //                              old_uid_t user, old_gid_t group);
 674 // long sys_fchown16(unsigned int fd, old_uid_t user, old_gid_t group);
 675 // long sys_setregid16(old_gid_t rgid, old_gid_t egid);
 676 // long sys_setgid16(old_gid_t gid);
 677 // long sys_setreuid16(old_uid_t ruid, old_uid_t euid);
 678 // long sys_setuid16(old_uid_t uid);
 679 // long sys_setresuid16(old_uid_t ruid, old_uid_t euid, old_uid_t suid);
 680 // long sys_getresuid16(old_uid_t __user *ruid,
 681 //                              old_uid_t __user *euid, old_uid_t __user *suid);
 682 // long sys_setresgid16(old_gid_t rgid, old_gid_t egid, old_gid_t sgid);
 683 // long sys_getresgid16(old_gid_t __user *rgid,
 684 //                              old_gid_t __user *egid, old_gid_t __user *sgid);
 685 // long sys_setfsuid16(old_uid_t uid);
 686 // long sys_setfsgid16(old_gid_t gid);
 687 // long sys_getgroups16(int gidsetsize, old_gid_t __user *grouplist);
 688 // long sys_setgroups16(int gidsetsize, old_gid_t __user *grouplist);
 689 // long sys_getuid16(void);
 690 // long sys_geteuid16(void);
 691 // long sys_getgid16(void);
 692 // long sys_getegid16(void);
 693 //
 694 //
 695 //
 696 //
 697 // long sys_add_key(const char __user *_type,
 698 //                          const char __user *_description,
 699 //                          const void __user *_payload,
 700 //                          size_t plen,
 701 //                          key_serial_t destringid);
 702 //
 703 // long sys_request_key(const char __user *_type,
 704 //                              const char __user *_description,
 705 //                              const char __user *_callout_info,
 706 //                              key_serial_t destringid);
 707 //
 708 //
 709 // long sys_migrate_pages(pid_t pid, unsigned long maxnode,
 710 //                              const unsigned long __user *from,
 711 //                              const unsigned long __user *to);
 712 // long sys_move_pages(pid_t pid, unsigned long nr_pages,
 713 //                              const void __user * __user *pages,
 714 //                              const int __user *nodes,
 715 //                              int __user *status,
 716 //                              int flags);
 717 // long compat_sys_move_pages(pid_t pid, unsigned long nr_page,
 718 //                              __u32 __user *pages,
 719 //                              const int __user *nodes,
 720 //                              int __user *status,
 721 //                              int flags);
 722 //
 723 // long sys_fchownat(int dfd, const char __user *filename, uid_t user,
 724 //                           gid_t group, int flag);
 725 //
 726 // long sys_get_robust_list(int pid,
 727 //                                  struct robust_list_head __user * __user *head_ptr,
 728 //                                  size_t __user *len_ptr);
 729 //
 730 

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