namespace dmtcp { static unsigned int timeLeft = 0; static void checkpoint() { timeLeft = alarm(0); JTRACE("*** Alarm stopped. ***") (timeLeft); } static void resume() { /* Need to restart the timer on resume/restart. */ if (timeLeft > 0) { JTRACE("*** Resuming alarm. ***") (timeLeft); timeLeft = alarm(timeLeft); } } static DmtcpBarrier alarmBarriers[] = { { DMTCP_PRIVATE_BARRIER_PRE_CKPT, checkpoint, "checkpoint" }, { DMTCP_PRIVATE_BARRIER_RESUME, resume, "resume" }, { DMTCP_PRIVATE_BARRIER_RESTART, resume, "restart" } }; static DmtcpPluginDescriptor_t alarmPlugin = { DMTCP_PLUGIN_API_VERSION, PACKAGE_VERSION, "alarm", "DMTCP", "*****@*****.**", "Alarm plugin", DMTCP_DECL_BARRIERS(alarmBarriers), NULL }; DmtcpPluginDescriptor_t dmtcp_Alarm_PluginDescr() { return alarmPlugin; } }
static void checkpoint() { printf("\n*** The plugin %s is being called before checkpointing. ***\n", __FILE__); } static void resume() { printf("*** The plugin %s has now been checkpointed. ***\n", __FILE__); } static DmtcpBarrier barriers[] = { { DMTCP_GLOBAL_BARRIER_PRE_CKPT, checkpoint, "checkpoint" }, { DMTCP_GLOBAL_BARRIER_RESUME, resume, "resume" } }; DmtcpPluginDescriptor_t sleep1_plugin = { DMTCP_PLUGIN_API_VERSION, PACKAGE_VERSION, "sleep1", "DMTCP", "*****@*****.**", "Sleep1 plugin", DMTCP_DECL_BARRIERS(barriers), NULL }; DMTCP_DECL_PLUGIN(sleep1_plugin);
namespace dmtcp { static bool _isSuspended = false; static bool _syslogEnabled = false; static bool _identIsNotNULL = false; static int _option = -1; static int _facility = -1; static void SyslogCheckpointer_StopService(); static void SyslogCheckpointer_RestoreService(); static void SyslogCheckpointer_ResetOnFork(); static void syslog_event_hook(DmtcpEvent_t event, DmtcpEventData_t *data) { switch (event) { case DMTCP_EVENT_ATFORK_CHILD: SyslogCheckpointer_ResetOnFork(); break; default: break; } } static DmtcpBarrier syslogBarriers[] = { { DMTCP_PRIVATE_BARRIER_PRE_CKPT, SyslogCheckpointer_StopService, "checkpoint" }, { DMTCP_PRIVATE_BARRIER_RESUME, SyslogCheckpointer_RestoreService, "resume" }, { DMTCP_PRIVATE_BARRIER_RESTART, SyslogCheckpointer_RestoreService, "restart" } }; static DmtcpPluginDescriptor_t syslogPlugin = { DMTCP_PLUGIN_API_VERSION, PACKAGE_VERSION, "syslog", "DMTCP", "*****@*****.**", "Syslog plugin", DMTCP_DECL_BARRIERS(syslogBarriers), syslog_event_hook }; DmtcpPluginDescriptor_t dmtcp_Syslog_PluginDescr() { return syslogPlugin; } static string& _ident() { static string t; return t; } void SyslogCheckpointer_StopService() { JASSERT(!_isSuspended); if (_syslogEnabled) { closelog(); _isSuspended = true; } } void SyslogCheckpointer_RestoreService() { if (_isSuspended) { _isSuspended = false; JASSERT(_option >= 0 && _facility >= 0) (_option) (_facility); openlog((_identIsNotNULL ? _ident().c_str() : NULL), _option, _facility); } } void SyslogCheckpointer_ResetOnFork() { _syslogEnabled = false; } extern "C" void openlog(const char *ident, int option, int facility) { JASSERT(!_isSuspended); JTRACE("openlog") (ident); _real_openlog(ident, option, facility); _syslogEnabled = true; _identIsNotNULL = (ident != NULL); if (ident != NULL) { _ident() = ident; } _option = option; _facility = facility; } extern "C" void closelog(void) { JASSERT(!_isSuspended); JTRACE("closelog"); _real_closelog(); _syslogEnabled = false; } // FIXME: Need to add wrappers for vsyslog() and setlogmask() // NOTE: openlog() is optional. Its purpose is primarily to set default // parameters. If syslog() or vsyslog() is called without it, // it will still open the log. Hence, we need a wrapper for them // that will set _syslogEnabled = true. // NOTE: We also need to save and restore the mask of setlogmask() // NOTE: Need a test/syslog.c to test this code. How can we verify that // it continues to log on restart in an automatic fashion? }
{ DPRINTF("The plugin containing %s has been initialized.\n", __FILE__); break; } case DMTCP_EVENT_EXIT: DPRINTF("The plugin is being called before exiting.\n"); break; default: break; } } static DmtcpBarrier kvmBarriers[] = { { DMTCP_GLOBAL_BARRIER_PRE_CKPT, pre_ckpt, "checkpoint" }, { DMTCP_GLOBAL_BARRIER_RESTART, restart, "restart" } }; DmtcpPluginDescriptor_t kvm_plugin = { DMTCP_PLUGIN_API_VERSION, PACKAGE_VERSION, "kvm", "DMTCP", "*****@*****.**", "KVM plugin", DMTCP_DECL_BARRIERS(kvmBarriers), kvm_event_hook }; DMTCP_DECL_PLUGIN(kvm_plugin);
sigaddset(&mask, g_sig_num); doneInitialization = 1; } JTRACE("The plugin has been initialized."); break; } default: break; } } static DmtcpBarrier ckpttimerBarriers[] = { { DMTCP_GLOBAL_BARRIER_PRE_CKPT, pre_ckpt, "checkpoint" }, { DMTCP_GLOBAL_BARRIER_RESUME, resume, "resume" }, { DMTCP_GLOBAL_BARRIER_RESTART, restart, "restart" } }; DmtcpPluginDescriptor_t ckpttimer_plugin = { DMTCP_PLUGIN_API_VERSION, PACKAGE_VERSION, "ckpttimer", "DMTCP", "*****@*****.**", "Ckpttimer plugin", DMTCP_DECL_BARRIERS(ckpttimerBarriers), ckpttimer_event_hook }; DMTCP_DECL_PLUGIN(ckpttimer_plugin);
namespace dmtcp { static int saved_termios_exists = 0; static struct termios saved_termios; static struct winsize win; static void save_term_settings(); static void restore_term_settings(); static void save_term_settings() { /* Drain stdin and stdout before checkpoint */ tcdrain(STDOUT_FILENO); tcdrain(STDERR_FILENO); saved_termios_exists = (isatty(STDIN_FILENO) && tcgetattr(STDIN_FILENO, &saved_termios) >= 0); if (saved_termios_exists) { ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&win); } } static int safe_tcsetattr(int fd, int optional_actions, const struct termios *termios_p) { struct termios old_termios, new_termios; /* We will compare old and new, and we don't want uninitialized data */ memset(&new_termios, 0, sizeof(new_termios)); /* tcgetattr returns success as long as at least one of requested * changes was executed. So, repeat until no more changes. */ do { memcpy(&old_termios, &new_termios, sizeof(new_termios)); if (tcsetattr(fd, TCSANOW, termios_p) == -1) { return -1; } if (tcgetattr(fd, &new_termios) == -1) { return -1; } } while (memcmp(&new_termios, &old_termios, sizeof(new_termios)) != 0); return 0; } // FIXME: Handle Virtual Pids static void restore_term_settings() { if (saved_termios_exists) { /* First check if we are in foreground. If not, skip this and print * warning. If we try to call tcsetattr in background, we will hang up. */ int foreground = (tcgetpgrp(STDIN_FILENO) == getpgrp()); JTRACE("restore terminal attributes, check foreground status first") (foreground); if (foreground) { if ((!isatty(STDIN_FILENO) || safe_tcsetattr(STDIN_FILENO, TCSANOW, &saved_termios) == -1)) { JWARNING(false).Text("failed to restore terminal"); } else { struct winsize cur_win; JTRACE("restored terminal"); ioctl(STDIN_FILENO, TIOCGWINSZ, (char *)&cur_win); /* ws_row/ws_col was probably not 0/0 prior to checkpoint. We change * it back to last known row/col prior to checkpoint, and then send a * SIGWINCH (see below) to notify process that window might have changed */ if (cur_win.ws_row == 0 && cur_win.ws_col == 0) { ioctl(STDIN_FILENO, TIOCSWINSZ, (char *)&win); } } } else { JWARNING(false) .Text(":skip restore terminal step -- we are in BACKGROUND"); } } /* * NOTE: * Apache, when running in debug mode (-X), uses SIGWINCH * as a signal for stopping gracefully. Please comment out * the next line to prevent DMTCP from sending a SIGWINCH * on restart when testing with Apache. * * TODO: * This should be done automatically by wrapping it in an ifdef * or if condition that disables the SIGWINCH using configure or * a runtime option (--no-sigwinch). */ if (kill(getpid(), SIGWINCH) == -1) {} /* No remedy if error */ } static void checkpoint() { save_term_settings(); } static void restart() { restore_term_settings(); /* If DMTCP_RESTART_PAUSE2 set, sleep 15 seconds to allow gdb attach.*/ if (getenv("MTCP_RESTART_PAUSE2") || getenv("DMTCP_RESTART_PAUSE2")) { #ifdef HAS_PR_SET_PTRACER prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, 0, 0, 0); // For: gdb attach #endif // ifdef HAS_PR_SET_PTRACER struct timespec delay = { 15, 0 }; /* 15 seconds */ printf("Pausing 15 seconds. Do: gdb <PROGNAME> %d\n", dmtcp_virtual_to_real_pid(getpid())); nanosleep(&delay, NULL); #ifdef HAS_PR_SET_PTRACER prctl(PR_SET_PTRACER, 0, 0, 0, 0); // Revert permission to default. #endif // ifdef HAS_PR_SET_PTRACER } } static DmtcpBarrier terminalBarriers[] = { { DMTCP_PRIVATE_BARRIER_PRE_CKPT, checkpoint, "checkpoint" }, { DMTCP_PRIVATE_BARRIER_RESTART, restart, "restart" } }; static DmtcpPluginDescriptor_t terminalPlugin = { DMTCP_PLUGIN_API_VERSION, PACKAGE_VERSION, "terminal", "DMTCP", "*****@*****.**", "Terminal plugin", DMTCP_DECL_BARRIERS(terminalBarriers), NULL }; DmtcpPluginDescriptor_t dmtcp_Terminal_PluginDescr() { return terminalPlugin; } }