/*ARGSUSED*/ static void alarm_handler(int sig) { time_t now; hrtime_t hr_now; now = time(NULL); hr_now = gethrtime(); if (checkidle_time <= now && checkidle_time != 0) check_idleness(&now, &hr_now); if (shutdown_time <= now && shutdown_time != 0) check_shutdown(&now, &hr_now); set_alarm(now); }
/* suspend through xenstore if suspend event channel is unavailable */ static int compat_suspend(checkpoint_state* s) { char path[128]; sprintf(path, "/local/domain/%u/control/shutdown", s->domid); if (!xs_write(s->xsh, XBT_NULL, path, "suspend", 7)) { s->errstr = "error signalling qemu logdirty"; return -1; } if (check_shutdown(s) != 1) return -1; return 0; }
static int setup_shutdown_watch(checkpoint_state* s) { char buf[16]; /* write domain ID to watch so we can ignore other domain shutdowns */ snprintf(buf, sizeof(buf), "%u", s->domid); if ( !xs_watch(s->xsh, "@releaseDomain", buf) ) { fprintf(stderr, "Could not bind to shutdown watch\n"); return -1; } /* watch fires once on registration */ s->watching_shutdown = 1; check_shutdown(s); return 0; }
static int suspend_hvm(checkpoint_state *s) { int rc = -1; fprintf(stderr, "issuing HVM suspend hypercall\n"); rc = xc_domain_shutdown(s->xch, s->domid, SHUTDOWN_suspend); if (rc < 0) { s->errstr = "shutdown hypercall failed"; return -1; } fprintf(stderr, "suspend hypercall returned %d\n", rc); if (check_shutdown(s) != 1) return -1; rc = suspend_qemu(s); return rc; }
/*ARGSUSED*/ static void work_handler(int sig) { time_t now; hrtime_t hr_now; struct stat stat_buf; do_idlecheck = 0; info->pd_flags = PD_AC; /* * Parse the config file for autoshutdown and idleness entries. */ if (read_cpr_config() < 0) return; /* * Since Oct. 1, 1995, any new system shipped had root * property "energystar-v2" defined in its prom. Systems * shipped after July 1, 1999, will have "energystar-v3" * property. */ estar_v2_prop = asinfo.is_cpr_default; info->pd_flags |= asinfo.is_autowakeup_capable; if (strlen(asinfo.idlecheck_path) > 0) { if (stat(asinfo.idlecheck_path, &stat_buf) != 0) { logerror("unable to access idlecheck program \"%s\".", asinfo.idlecheck_path); } else if (!(stat_buf.st_mode & S_IXUSR)) { logerror("idlecheck program \"%s\" is not executable.", asinfo.idlecheck_path); } else { do_idlecheck = 1; } } if (strlen(asinfo.as_behavior) == 0 || strcmp(asinfo.as_behavior, "noshutdown") == 0 || strcmp(asinfo.as_behavior, "unconfigured") == 0) { info->pd_autoshutdown = 0; } else if (strcmp(asinfo.as_behavior, "default") == 0) { info->pd_autoshutdown = estar_v2_prop; } else if (strcmp(asinfo.as_behavior, "shutdown") == 0 || strcmp(asinfo.as_behavior, "autowakeup") == 0) { info->pd_autoshutdown = asinfo.is_cpr_capable; } else { logerror("autoshutdown behavior \"%s\" unrecognized.", asinfo.as_behavior); info->pd_autoshutdown = 0; } if (info->pd_autoshutdown) { info->pd_idle_time = asinfo.as_idle; info->pd_start_time = (asinfo.as_sh * 60 + asinfo.as_sm) % DAYS_TO_MINS; info->pd_finish_time = (asinfo.as_fh * 60 + asinfo.as_fm) % DAYS_TO_MINS; info->pd_autoresume = (strcmp(asinfo.as_behavior, "autowakeup") == 0) ? 1 : 0; } autoshutdown_en = (asinfo.as_idle >= 0 && info->pd_autoshutdown) ? 1 : 0; #ifdef DEBUG (void) fprintf(stderr, "autoshutdown_en = %d, as_idle = %d, " "pd_autoresume = %d\n", autoshutdown_en, asinfo.as_idle, info->pd_autoresume); (void) fprintf(stderr, " pd_start_time=%d, pd_finish_time=%d\n", info->pd_start_time, info->pd_finish_time); #endif got_sighup = 1; now = last_resume = time(NULL); hr_now = gethrtime(); check_idleness(&now, &hr_now); check_shutdown(&now, &hr_now); set_alarm(now); }
/*----------------------------------------------------------------------------- main -----------------------------------------------------------------------------*/ int main(int argc, char** argv) { if (argc < 2) { fprintf(stderr, "Syntax: %s <tracee> [<tracee args>]\n", argv[0]); return -1; } main_child = fork(); if (main_child == 0) { int argv_len = 0; for (int i = 1; i < argc; ++i) if (argv[i]) argv_len += strlen(argv[i]) + 1; char* new_argv = new char[argv_len + 1]; for (int i = 1; i < argc; ++i) { if (i > 1) strcat(new_argv, " "); strcat(new_argv, argv[i]); } char* execve_args[] = {(char*)"sh", (char*)"-c", new_argv, NULL}; ptrace(PTRACE_TRACEME, 0, 0, 0); execv("/bin/sh", execve_args); } else { unsigned char first_fork = 1; int status; pid_t pid; std::map<pid_t, struct minimal_childstate*>::iterator it; struct minimal_childstate* child = init_child(main_child); childs.insert(std::pair<pid_t, struct minimal_childstate*>(main_child, child)); // wait for the main child first to set the ptrace options if ((waitpid(-1, &status, 0) == main_child) && WIFSTOPPED(status)) { child_set_options(child); ptrace(PTRACE_SYSCALL, main_child, NULL, 0); } else { fprintf(stderr, "ERROR: Main child initialization failed\n"); force_shutdown(); } while ((pid = waitpid(-1, &status, __WALL | WUNTRACED)) != -1) { it = childs.find(pid); if (it == childs.end()) { if (childs.find(pid) == childs.end()) childs.insert(std::pair<pid_t, struct minimal_childstate*>(pid, init_child(pid))); } else { child = it->second; } if (WIFEXITED(status)) { child->child_exited = 1; check_shutdown(); ptrace(PTRACE_SYSCALL, pid, NULL, 0); } else if (WIFSTOPPED(status)) { if (WSTOPSIG(status) == (SIGTRAP|0x80)) { if (!child->child_in_syscall) { long syscall_no = ptrace(PTRACE_PEEKUSER, pid, 8 * ORIG_RAX, NULL); if (is_whitelisted_syscall(syscall_no)) child->child_syscalls_whitelisted++; child->child_syscalls++; } child->child_in_syscall = !child->child_in_syscall; ptrace(PTRACE_SYSCALL, pid, NULL, 0); } else if (WSTOPSIG(status) == SIGTRAP) { int event = ((status & 0x000F0000) >> 16); if (event == PTRACE_EVENT_FORK || event == PTRACE_EVENT_VFORK || event == PTRACE_EVENT_CLONE) { long newpid; ptrace(PTRACE_GETEVENTMSG, pid, 0, &newpid); if (childs.find(newpid) == childs.end()) childs.insert(std::pair<pid_t, struct minimal_childstate*>(newpid, init_child(newpid))); //printf("fork event from child: %d [== FORK ==>] %d\n", pid, (pid_t)newpid); if (first_fork) { first_fork = 0; gettimeofday(&start_time, NULL); } } else { //fprintf(stderr, "ERROR: Unexpected SIGTRAP from child %d - event: %d\n", pid, event); //force_shutdown(); } ptrace(PTRACE_SYSCALL, pid, NULL, 0); } else if (WSTOPSIG(status) == SIGSTOP) { if (!child->child_resumed) child->child_resumed = 1; else child->child_signals++; ptrace(PTRACE_SYSCALL, pid, NULL, 0); } else { child->child_signals++; ptrace(PTRACE_SYSCALL, pid, NULL, (void*)WSTOPSIG(status)); } } else {
static void _teardown(void) { efl_unref(object); check_shutdown(); }