/* * daemonize * * Performs the steps necessary to become a daemon. */ static void daemonize(void) { int pid; int status; signal(SIGTERM, &parent_exit_handler); pid = fork(); if (pid < 0) { LOG_ERROR("Unable to fork()"); exit(EXIT_FAILURE); } if (pid) { /* Parent waits here for child to get going */ while (!waitpid(pid, &status, WNOHANG) && !exit_now); if (exit_now) exit(EXIT_SUCCESS); switch (WEXITSTATUS(status)) { case EXIT_LOCKFILE: LOG_ERROR("Failed to create lockfile"); LOG_ERROR("Process already running?"); break; case EXIT_KERNEL_SOCKET: LOG_ERROR("Unable to create netlink socket"); break; case EXIT_KERNEL_BIND: LOG_ERROR("Unable to bind to netlink socket"); break; case EXIT_KERNEL_SETSOCKOPT: LOG_ERROR("Unable to setsockopt on netlink socket"); break; case EXIT_CLUSTER_CKPT_INIT: LOG_ERROR("Unable to initialize checkpoint service"); LOG_ERROR("Has the cluster infrastructure been started?"); break; case EXIT_FAILURE: LOG_ERROR("Failed to start: Generic error"); break; default: LOG_ERROR("Failed to start: Unknown error"); break; } exit(EXIT_FAILURE); } setsid(); chdir("/"); umask(0); close(0); close(1); close(2); open("/dev/null", O_RDONLY); /* reopen stdin */ open("/dev/null", O_WRONLY); /* reopen stdout */ open("/dev/null", O_WRONLY); /* reopen stderr */ LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON); if (create_lockfile(CMIRRORD_PIDFILE)) exit(EXIT_LOCKFILE); signal(SIGINT, &sig_handler); signal(SIGQUIT, &sig_handler); signal(SIGTERM, &sig_handler); signal(SIGHUP, &sig_handler); signal(SIGPIPE, SIG_IGN); signal(SIGUSR1, &sig_handler); signal(SIGUSR2, &sig_handler); sigemptyset(&signal_mask); signal_received = 0; }
WL_EXPORT int weston_xserver_init(struct weston_compositor *compositor) { struct wl_display *display = compositor->wl_display; struct weston_xserver *mxs; char lockfile[256], display_name[8]; mxs = malloc(sizeof *mxs); memset(mxs, 0, sizeof *mxs); mxs->process.cleanup = weston_xserver_cleanup; mxs->wl_display = display; mxs->compositor = compositor; mxs->display = 0; retry: if (create_lockfile(mxs->display, lockfile, sizeof lockfile) < 0) { if (errno == EAGAIN) { goto retry; } else if (errno == EEXIST) { mxs->display++; goto retry; } else { free(mxs); return -1; } } mxs->abstract_fd = bind_to_abstract_socket(mxs->display); if (mxs->abstract_fd < 0 && errno == EADDRINUSE) { mxs->display++; unlink(lockfile); goto retry; } mxs->unix_fd = bind_to_unix_socket(mxs->display); if (mxs->unix_fd < 0) { unlink(lockfile); close(mxs->abstract_fd); free(mxs); return -1; } snprintf(display_name, sizeof display_name, ":%d", mxs->display); weston_log("xserver listening on display %s\n", display_name); setenv("DISPLAY", display_name, 1); mxs->loop = wl_display_get_event_loop(display); mxs->abstract_source = wl_event_loop_add_fd(mxs->loop, mxs->abstract_fd, WL_EVENT_READABLE, weston_xserver_handle_event, mxs); mxs->unix_source = wl_event_loop_add_fd(mxs->loop, mxs->unix_fd, WL_EVENT_READABLE, weston_xserver_handle_event, mxs); wl_display_add_global(display, &xserver_interface, mxs, bind_xserver); mxs->destroy_listener.notify = weston_xserver_destroy; wl_signal_add(&compositor->destroy_signal, &mxs->destroy_listener); return 0; }
int main(int argc, char **argv) { /* I18n */ setlocale(LC_ALL, ""); #if ENABLE_NLS bindtextdomain(PACKAGE, LOCALEDIR); textdomain(PACKAGE); #endif abrt_init(argv); const char *program_usage_string = _( "& [-v -i] -e|--event EVENT DIR..." ); char *event_name = NULL; int interactive = 0; /* must be _int_, OPT_BOOL expects that! */ struct options program_options[] = { OPT__VERBOSE(&g_verbose), OPT_STRING('e', "event" , &event_name, "EVENT", _("Run EVENT on DIR")), OPT_BOOL('i', "interactive" , &interactive, _("Communicate directly to the user")), OPT_END() }; parse_opts(argc, argv, program_options, program_usage_string); argv += optind; if (!*argv || !event_name) show_usage_and_die(program_usage_string, program_options); load_abrt_conf(); bool post_create = (strcmp(event_name, "post-create") == 0); char *dump_dir_name = NULL; while (*argv) { dump_dir_name = xstrdup(*argv++); int i = strlen(dump_dir_name); while (--i >= 0) if (dump_dir_name[i] != '/') break; dump_dir_name[++i] = '\0'; struct dump_dir *dd = dd_opendir(dump_dir_name, /*flags:*/ DD_OPEN_READONLY); if (!dd) return 1; uid = dd_load_text_ext(dd, FILENAME_UID, DD_FAIL_QUIETLY_ENOENT); dd_close(dd); struct run_event_state *run_state = new_run_event_state(); if (!interactive) make_run_event_state_forwarding(run_state); run_state->logging_callback = do_log; if (post_create) { run_state->post_run_callback = is_crash_a_dup; /* * The post-create event cannot be run concurrently for more problem * directories. The problem is in searching for duplicates process * in case when two concurrently processed directories are duplicates * of each other. Both of the directories are marked as duplicates * of each other and are deleted. */ create_lockfile(); } int r = run_event_on_dir_name(run_state, dump_dir_name, event_name); if (post_create) delete_lockfile(); const bool no_action_for_event = (r == 0 && run_state->children_count == 0); free_run_event_state(run_state); /* Needed only if is_crash_a_dup() was called, but harmless * even if it wasn't: */ dup_uuid_fini(); dup_corebt_fini(); if (no_action_for_event) error_msg_and_die("No actions are found for event '%s'", event_name); //TODO: consider this case: // new dump is created, post-create detects that it is a dup, // but then load_crash_info(dup_name) *FAILS*. // In this case, we later delete damaged dup_name (right?) // but new dump never gets its FILENAME_COUNT set! /* Is crash a dup? (In this case, is_crash_a_dup() should have * aborted "post-create" event processing as soon as it saw uuid * and determined that there is another crash with same uuid. * In this case it sets crash_dump_dup_name) */ if (crash_dump_dup_name) error_msg_and_die("DUP_OF_DIR: %s", crash_dump_dup_name); /* Was there error on one of processing steps in run_event? */ if (r != 0) return r; /* yes */ free(dump_dir_name); dump_dir_name = NULL; } /* exit 0 means, that there is no duplicate of dump-dir */ return 0; }
static int do_server(int type) { int rv = -1; static char log_ent[128] = DAEMON_NAME "-"; rv = setup_config(type); if (rv < 0) return rv; if (!local) { log_error("Cannot find myself in the configuration."); exit(EXIT_FAILURE); } if (daemonize) { if (daemon(0, 0) < 0) { perror("daemon error"); exit(EXIT_FAILURE); } } /* The lockfile must be written to _after_ the call to daemon(), so * that the lockfile contains the pid of the daemon, not the parent. */ lock_fd = create_lockfile(); if (lock_fd < 0) return lock_fd; atexit(server_exit); strcat(log_ent, type_to_string(local->type)); cl_log_set_entity(log_ent); cl_log_enable_stderr(enable_stderr ? TRUE : FALSE); cl_log_set_facility(HA_LOG_FACILITY); cl_inherit_logging_environment(0); log_info("BOOTH %s %s daemon is starting", type_to_string(local->type), RELEASE_STR); signal(SIGUSR1, (__sighandler_t)tickets_log_info); signal(SIGTERM, (__sighandler_t)sig_exit_handler); signal(SIGINT, (__sighandler_t)sig_exit_handler); /* we'll handle errors there and then */ signal(SIGPIPE, SIG_IGN); set_scheduler(); /* we don't want to be killed by the OOM-killer */ if (set_procfs_val("/proc/self/oom_score_adj", "-999")) (void)set_procfs_val("/proc/self/oom_adj", "-16"); set_proc_title("%s %s %s for [%s]:%d", DAEMON_NAME, cl.configfile, type_to_string(local->type), local->addr_string, booth_conf->port); rv = limit_this_process(); if (rv) return rv; #ifdef COREDUMP_NURSING if (cl_enable_coredumps(TRUE) < 0){ log_error("enabling core dump failed"); } cl_cdtocoredir(); prctl(PR_SET_DUMPABLE, (unsigned long)TRUE, 0UL, 0UL, 0UL); #else if (chdir(BOOTH_CORE_DIR) < 0) { log_error("cannot change working directory to %s", BOOTH_CORE_DIR); } #endif signal(SIGCHLD, (__sighandler_t)wait_child); rv = loop(lock_fd); return rv; }
WL_EXPORT int module_init(struct weston_compositor *compositor, int *argc, char *argv[]) { struct wl_display *display = compositor->wl_display; struct weston_xserver *wxs; char lockfile[256], display_name[8]; wxs = zalloc(sizeof *wxs); if (wxs == NULL) return -1; wxs->process.cleanup = weston_xserver_cleanup; wxs->wl_display = display; wxs->compositor = compositor; wxs->display = 0; retry: if (create_lockfile(wxs->display, lockfile, sizeof lockfile) < 0) { if (errno == EAGAIN) { goto retry; } else if (errno == EEXIST) { wxs->display++; goto retry; } else { free(wxs); return -1; } } wxs->abstract_fd = bind_to_abstract_socket(wxs->display); if (wxs->abstract_fd < 0 && errno == EADDRINUSE) { wxs->display++; unlink(lockfile); goto retry; } wxs->unix_fd = bind_to_unix_socket(wxs->display); if (wxs->unix_fd < 0) { unlink(lockfile); close(wxs->abstract_fd); free(wxs); return -1; } snprintf(display_name, sizeof display_name, ":%d", wxs->display); weston_log("xserver listening on display %s\n", display_name); setenv("DISPLAY", display_name, 1); wxs->loop = wl_display_get_event_loop(display); wxs->abstract_source = wl_event_loop_add_fd(wxs->loop, wxs->abstract_fd, WL_EVENT_READABLE, weston_xserver_handle_event, wxs); wxs->unix_source = wl_event_loop_add_fd(wxs->loop, wxs->unix_fd, WL_EVENT_READABLE, weston_xserver_handle_event, wxs); wxs->sigusr1_source = wl_event_loop_add_signal(wxs->loop, SIGUSR1, handle_sigusr1, wxs); wxs->destroy_listener.notify = weston_xserver_destroy; wl_signal_add(&compositor->destroy_signal, &wxs->destroy_listener); return 0; }
static int do_server(int type) { int rv = -1; static char log_ent[128] = DAEMON_NAME "-"; rv = setup_config(type); if (rv < 0) return rv; if (!local) { log_error("Cannot find myself in the configuration."); exit(EXIT_FAILURE); } if (!daemonize) { if (daemon(0, 0) < 0) { perror("daemon error"); exit(EXIT_FAILURE); } } /* The lockfile must be written to _after_ the call to daemon(), so * that the lockfile contains the pid of the daemon, not the parent. */ lock_fd = create_lockfile(); if (lock_fd < 0) return lock_fd; atexit(server_exit); strcat(log_ent, type_to_string(local->type)); cl_log_set_entity(log_ent); cl_log_enable_stderr(enable_stderr ? TRUE : FALSE); cl_log_set_facility(HA_LOG_FACILITY); cl_inherit_logging_environment(0); log_info("BOOTH %s %s daemon is starting", type_to_string(local->type), RELEASE_STR); signal(SIGUSR1, (__sighandler_t)tickets_log_info); signal(SIGTERM, (__sighandler_t)sig_exit_handler); signal(SIGINT, (__sighandler_t)sig_exit_handler); set_scheduler(); set_oom_adj(-16); set_proc_title("%s %s %s for [%s]:%d", DAEMON_NAME, cl.configfile, type_to_string(local->type), local->addr_string, booth_conf->port); rv = limit_this_process(); if (rv) return rv; if (cl_enable_coredumps(TRUE) < 0){ cl_log(LOG_ERR, "enabling core dump failed"); } cl_cdtocoredir(); prctl(PR_SET_DUMPABLE, (unsigned long)TRUE, 0UL, 0UL, 0UL); rv = loop(lock_fd); return rv; }