Example #1
0
/*
 * 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;
}
Example #2
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;
}
Example #3
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;
}
Example #4
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;
}
Example #5
0
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;
}
Example #6
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;
}