/* * This function forks a child process and drops the realtime * scheduler for the child process. */ pid_t ctdb_fork(struct ctdb_context *ctdb) { pid_t pid; pid = fork(); if (pid == -1) { return -1; } if (pid == 0) { ctdb_set_child_info(ctdb, NULL); /* Close the Unix Domain socket and the TCP socket. * This ensures that none of the child processes will * look like the main daemon when it is not running. * tevent needs to be stopped before closing sockets. */ if (ctdb->ev != NULL) { talloc_free(ctdb->ev); ctdb->ev = NULL; } if (ctdb->daemon.sd != -1) { close(ctdb->daemon.sd); ctdb->daemon.sd = -1; } if (ctdb->methods != NULL) { ctdb->methods->shutdown(ctdb); } /* The child does not need to be realtime */ if (ctdb->do_setsched) { reset_scheduler(); } ctdb->can_send_controls = false; return 0; } ctdb_track_child(ctdb, pid); return pid; }
int main(int argc, char *argv[]) { int log_fd, write_fd; pid_t pid; int status, output, ret; progname = argv[0]; if (argc < 5) { usage(); exit(1); } reset_scheduler(); log_fd = atoi(argv[1]); write_fd = atoi(argv[2]); set_close_on_exec(write_fd); close(STDOUT_FILENO); close(STDERR_FILENO); dup2(log_fd, STDOUT_FILENO); dup2(log_fd, STDERR_FILENO); close(log_fd); if (setpgid(0, 0) != 0) { fprintf(stderr, "Failed to create process group for event script - %s\n", strerror(errno)); exit(1); } signal(SIGTERM, sigterm); pid = fork(); if (pid < 0) { int save_errno = errno; fprintf(stderr, "Failed to fork - %s\n", strerror(errno)); sys_write(write_fd, &save_errno, sizeof(save_errno)); exit(1); } if (pid == 0) { ret = check_executable(argv[3]); if (ret != 0) { _exit(ret); } ret = execv(argv[3], &argv[3]); if (ret != 0) { int save_errno = errno; fprintf(stderr, "Error executing '%s' - %s\n", argv[3], strerror(save_errno)); } /* This should never happen */ _exit(ENOEXEC); } ret = waitpid(pid, &status, 0); if (ret == -1) { output = -errno; fprintf(stderr, "waitpid() failed - %s\n", strerror(errno)); sys_write(write_fd, &output, sizeof(output)); exit(1); } if (WIFEXITED(status)) { output = WEXITSTATUS(status); /* Only errors should be returned as -ve values */ if (output == ENOENT || output == ENOEXEC) { output = -output; } sys_write(write_fd, &output, sizeof(output)); exit(0); } if (WIFSIGNALED(status)) { output = -EINTR; fprintf(stderr, "Process terminated with signal - %d\n", WTERMSIG(status)); sys_write(write_fd, &output, sizeof(output)); exit(0); } fprintf(stderr, "waitpid() status=%d\n", status); exit(1); }
static void reset_priority(void) { if (realtime) { reset_scheduler(); } }