Пример #1
0
/*
 * Prepare for a clean shutdown
 */
void
daemon_shutdown()
{
    pidfile_remove(pfh);
    if (!use_syslog)
        log_close(lfh);
}
Пример #2
0
/*
 * Log an error message, then exit.
 */
void
error(char *fmt, ...)
{
	va_list list;

	do_percentm(fbuf, sizeof(fbuf), fmt);

	va_start(list, fmt);
	vsnprintf(mbuf, sizeof(mbuf), fbuf, list);
	va_end(list);

#ifndef DEBUG
	syslog(log_priority | LOG_ERR, "%s", mbuf);
#endif

	/* Also log it to stderr? */
	if (log_perror) {
		write(2, mbuf, strlen(mbuf));
		write(2, "\n", 1);
	}

	syslog(LOG_CRIT, "exiting.");
	if (log_perror) {
		fprintf(stderr, "exiting.\n");
		fflush(stderr);
	}
	if (pidfile != NULL)
		pidfile_remove(pidfile);
	exit(1);
}
void handle_signal(int signo)
{
    if (SIGINT == signo || SIGTERM == signo) {
        utlog(LOG_NOTICE, "Received SIGINT/TERM signal, shuting down..");
        pidfile_remove(pidfile);
        exit(EXIT_SUCCESS);
    }
}
Пример #4
0
void server() {
    // load Config File and Settings
    fprintf(stdout, "Starting fidistat Server...\n");
    openlog("fidistat-server", LOG_PID, LOG_DAEMON);
    syslog(LOG_INFO, "Started Fidistat Server");

    struct pidfh *pfh = daemon_start('s');

    // Handle Signals
    signal(SIGTERM, handleSigterm_S);
    signal(SIGCHLD, handleChild);

    // Open Socket
    initConf();
    tls_init();
    struct tls* ctx = tls_server();
    int sock = initTLS_S(ctx);
    sckt = sock;

    int connfd, pid;
    listen(sock, 10);

    // Destroy Config
    destroyConf(); 

    while(!term) {
        connfd = accept(sock, (struct sockaddr*) NULL, NULL); 

        if (term) {
            break;
        }
        pid = fork();
        if (pid < 0) {
            syslog(LOG_ERR, "forking new Worker failed");
        } else if (pid == 0) {
            close(sock);
            syslog(LOG_INFO, "New incoming connection");
            worker(connfd, ctx);
            syslog(LOG_INFO, "Closing connection");
            exit(0);
        } else {
            close(connfd);
        }
    }
    syslog(LOG_INFO, "Shutting down Server");
    close(sock);
    tls_close(ctx);
    tls_free(ctx);
    tls_config_free(tlsServer_conf);

    pidfile_remove(pfh);
    syslog(LOG_INFO, "Stopped Fidistat Server");
    closelog();
    exit(0);
}
Пример #5
0
static void v_daemon(struct pidfh **pfh) 
{
	int ret;
#ifdef __APPLE__
	logger(-1, "Daemonizing is not guaranteed to not kill kittens on Mac OS X.\n");
	logger(-1, "Consider using -d to run in foreground instead.\n");
#endif
	ret = daemon(0,0);
	if (ret == -1) {
		warn("Cannot daemonize");
		if (*pfh)
			pidfile_remove(*pfh);
		exit(EXIT_FAILURE);
	}
	assert(ret == 0);
}
Пример #6
0
int main(int argc, char **argv)
{
	int pid_fd = -1, r = 0;
	pid_t old_pid;
	struct pfiled pfiled;

	init_perr("pfiled");
	parse_cmdline(argc, argv);

	perr(PI, 0, "p = %ld, nr_ops = %lu\n", cmdline_portno, cmdline_nr_ops);
	
	if (cmdline_pidfile){
		pid_fd = pidfile_open(cmdline_pidfile, &old_pid);
		if (pid_fd < 0) {
			if (old_pid) {
				perr(PFE, 0, "Daemon already running, pid: %d.", old_pid);
			} else {
				perr(PFE, 0, "Cannot open or create pidfile");
			}
			return -1;
		}
	}

	if (cmdline_daemon){
		if (daemon(0, 1) < 0){
			perr(PFE, 0, "Cannot daemonize");
			r = -1;
			goto out;
		}
	}
	setup_signals();
	if (pid_fd > 0)
		pidfile_write(pid_fd);


	if (pfiled_init(&pfiled) < 0){
		r = -1;
		goto out;
	}

	r = pfiled_loop(&pfiled);
out:
	if (pid_fd > 0)
		pidfile_remove(cmdline_pidfile, pid_fd);
	return r;

}
Пример #7
0
int
main(int argc, char **argv)
{
	struct agent_core_t core;
	struct agent_plugin_t *plug;
	struct pidfh *pfh = NULL;

	core.config = calloc(1,sizeof(struct agent_config_t));
	assert(core.config);
	core.plugins = NULL;
	core_alloc_plugins(&core);
	core_opt(&core, argc, argv);
	base64_init();
	core_plugins(&core);
	
	if (core.config->P_arg)
		p_open(&pfh, core.config->P_arg);

	sandbox(&core);
	if (core.config->d_arg)
		logger(-1, "Plugins initialized. -d argument given, so not forking.");
	else
		v_daemon(&pfh);
		
	if (pfh)
		pidfile_write(pfh);
	ipc_sanity(&core);
	threads_started = 1;
	for (plug = core.plugins; plug != NULL; plug = plug->next) {
		if (plug->start != NULL)
			plug->thread = plug->start(&core, plug->name);
	}
	threads_started = 2;
	for (plug = core.plugins; plug; plug = plug->next) {
		if (plug->thread) {
			pthread_join(*(pthread_t *)plug->thread, NULL);
			free(plug->thread);
		}
	}
	/*
	 * XXX: Might want to do this on SIGTERM too I suppose.
	 */
	if (pfh)
		pidfile_remove(pfh);
	return 0;
}
Пример #8
0
void
process_error(int ret_code, char *fmt,...)
{
	va_list ap;
	char buf[1024];

	va_start(ap, fmt);

	if (pfh)
		pidfile_remove(pfh);

	vsprintf(buf, fmt, ap);
	logd(LOG_ERR, buf);
	errx(ret_code, buf);

	/* does not reach */
	va_end(ap);
}
Пример #9
0
static void
restart_mountd(void)
{
	struct pidfh *pfh;
	pid_t mountdpid;

	pfh = pidfile_open(_PATH_MOUNTDPID, 0600, &mountdpid);
	if (pfh != NULL) {
		/* Mountd is not running. */
		pidfile_remove(pfh);
		return;
	}
	if (errno != EEXIST) {
		/* Cannot open pidfile for some reason. */
		return;
	}
	/* We have mountd(8) PID in mountdpid varible. */
	kill(mountdpid, SIGHUP);
}
Пример #10
0
void
hastd_secondary(struct hast_resource *res, struct nv *nvin)
{
	sigset_t mask;
	pthread_t td;
	pid_t pid;
	int error, mode, debuglevel;

	/*
	 * Create communication channel between parent and child.
	 */
	if (proto_client(NULL, "socketpair://", &res->hr_ctrl) < 0) {
		KEEP_ERRNO((void)pidfile_remove(pfh));
		pjdlog_exit(EX_OSERR,
		    "Unable to create control sockets between parent and child");
	}
	/*
	 * Create communication channel between child and parent.
	 */
	if (proto_client(NULL, "socketpair://", &res->hr_event) < 0) {
		KEEP_ERRNO((void)pidfile_remove(pfh));
		pjdlog_exit(EX_OSERR,
		    "Unable to create event sockets between child and parent");
	}

	pid = fork();
	if (pid < 0) {
		KEEP_ERRNO((void)pidfile_remove(pfh));
		pjdlog_exit(EX_OSERR, "Unable to fork");
	}

	if (pid > 0) {
		/* This is parent. */
		proto_close(res->hr_remotein);
		res->hr_remotein = NULL;
		proto_close(res->hr_remoteout);
		res->hr_remoteout = NULL;
		/* Declare that we are receiver. */
		proto_recv(res->hr_event, NULL, 0);
		/* Declare that we are sender. */
		proto_send(res->hr_ctrl, NULL, 0);
		res->hr_workerpid = pid;
		return;
	}

	gres = res;
	mode = pjdlog_mode_get();
	debuglevel = pjdlog_debug_get();

	/* Declare that we are sender. */
	proto_send(res->hr_event, NULL, 0);
	/* Declare that we are receiver. */
	proto_recv(res->hr_ctrl, NULL, 0);
	descriptors_cleanup(res);

	descriptors_assert(res, mode);

	pjdlog_init(mode);
	pjdlog_debug_set(debuglevel);
	pjdlog_prefix_set("[%s] (%s) ", res->hr_name, role2str(res->hr_role));
	setproctitle("%s (%s)", res->hr_name, role2str(res->hr_role));

	PJDLOG_VERIFY(sigemptyset(&mask) == 0);
	PJDLOG_VERIFY(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);

	/* Error in setting timeout is not critical, but why should it fail? */
	if (proto_timeout(res->hr_remotein, 2 * HAST_KEEPALIVE) < 0)
		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");
	if (proto_timeout(res->hr_remoteout, res->hr_timeout) < 0)
		pjdlog_errno(LOG_WARNING, "Unable to set connection timeout");

	init_local(res);
	init_environment();

	if (drop_privs(res) != 0)
		exit(EX_CONFIG);
	pjdlog_info("Privileges successfully dropped.");

	/*
	 * Create the control thread before sending any event to the parent,
	 * as we can deadlock when parent sends control request to worker,
	 * but worker has no control thread started yet, so parent waits.
	 * In the meantime worker sends an event to the parent, but parent
	 * is unable to handle the event, because it waits for control
	 * request response.
	 */
	error = pthread_create(&td, NULL, ctrl_thread, res);
	PJDLOG_ASSERT(error == 0);

	init_remote(res, nvin);
	event_send(res, EVENT_CONNECT);

	error = pthread_create(&td, NULL, recv_thread, res);
	PJDLOG_ASSERT(error == 0);
	error = pthread_create(&td, NULL, disk_thread, res);
	PJDLOG_ASSERT(error == 0);
	(void)send_thread(res);
}
Пример #11
0
int
main(int argc, char * argv[])
{
	struct timeval timeout;
	fd_set fdset;
	int nfds;
	struct pidfh *pfh = NULL;
	const char *pidfile = NULL;
	int freq, curfreq, initfreq, *freqs, i, j, *mwatts, numfreqs, load;
	int minfreq = -1, maxfreq = -1;
	int ch, mode, mode_ac, mode_battery, mode_none, idle, to;
	uint64_t mjoules_used;
	size_t len;

	/* Default mode for all AC states is adaptive. */
	mode_ac = mode_none = MODE_HIADAPTIVE;
	mode_battery = MODE_ADAPTIVE;
	cpu_running_mark = DEFAULT_ACTIVE_PERCENT;
	cpu_idle_mark = DEFAULT_IDLE_PERCENT;
	poll_ival = DEFAULT_POLL_INTERVAL;
	mjoules_used = 0;
	vflag = 0;

	/* User must be root to control frequencies. */
	if (geteuid() != 0)
		errx(1, "must be root to run");

	while ((ch = getopt(argc, argv, "a:b:i:m:M:n:p:P:r:v")) != -1)
		switch (ch) {
		case 'a':
			parse_mode(optarg, &mode_ac, ch);
			break;
		case 'b':
			parse_mode(optarg, &mode_battery, ch);
			break;
		case 'i':
			cpu_idle_mark = atoi(optarg);
			if (cpu_idle_mark < 0 || cpu_idle_mark > 100) {
				warnx("%d is not a valid percent",
				    cpu_idle_mark);
				usage();
			}
			break;
		case 'm':
			minfreq = atoi(optarg);
			if (minfreq < 0) {
				warnx("%d is not a valid CPU frequency",
				    minfreq);
				usage();
			}
			break;
		case 'M':
			maxfreq = atoi(optarg);
			if (maxfreq < 0) {
				warnx("%d is not a valid CPU frequency",
				    maxfreq);
				usage();
			}
			break;
		case 'n':
			parse_mode(optarg, &mode_none, ch);
			break;
		case 'p':
			poll_ival = atoi(optarg);
			if (poll_ival < 5) {
				warnx("poll interval is in units of ms");
				usage();
			}
			break;
		case 'P':
			pidfile = optarg;
			break;
		case 'r':
			cpu_running_mark = atoi(optarg);
			if (cpu_running_mark <= 0 || cpu_running_mark > 100) {
				warnx("%d is not a valid percent",
				    cpu_running_mark);
				usage();
			}
			break;
		case 'v':
			vflag = 1;
			break;
		default:
			usage();
		}

	mode = mode_none;

	/* Poll interval is in units of ms. */
	poll_ival *= 1000;

	/* Look up various sysctl MIBs. */
	len = 2;
	if (sysctlnametomib("kern.cp_times", cp_times_mib, &len))
		err(1, "lookup kern.cp_times");
	len = 4;
	if (sysctlnametomib("dev.cpu.0.freq", freq_mib, &len))
		err(EX_UNAVAILABLE, "no cpufreq(4) support -- aborting");
	len = 4;
	if (sysctlnametomib("dev.cpu.0.freq_levels", levels_mib, &len))
		err(1, "lookup freq_levels");

	/* Check if we can read the load and supported freqs. */
	if (read_usage_times(NULL))
		err(1, "read_usage_times");
	if (read_freqs(&numfreqs, &freqs, &mwatts, minfreq, maxfreq))
		err(1, "error reading supported CPU frequencies");
	if (numfreqs == 0)
		errx(1, "no CPU frequencies in user-specified range");

	/* Run in the background unless in verbose mode. */
	if (!vflag) {
		pid_t otherpid;

		pfh = pidfile_open(pidfile, 0600, &otherpid);
		if (pfh == NULL) {
			if (errno == EEXIST) {
				errx(1, "powerd already running, pid: %d",
				    otherpid);
			}
			warn("cannot open pid file");
		}
		if (daemon(0, 0) != 0) {
			warn("cannot enter daemon mode, exiting");
			pidfile_remove(pfh);
			exit(EXIT_FAILURE);

		}
		pidfile_write(pfh);
	}

	/* Decide whether to use ACPI or APM to read the AC line status. */
	acline_init();

	/*
	 * Exit cleanly on signals.
	 */
	signal(SIGINT, handle_sigs);
	signal(SIGTERM, handle_sigs);

	freq = initfreq = curfreq = get_freq();
	i = get_freq_id(curfreq, freqs, numfreqs);
	if (freq < 1)
		freq = 1;

	/*
	 * If we are in adaptive mode and the current frequency is outside the
	 * user-defined range, adjust it to be within the user-defined range.
	 */
	acline_read();
	if (acline_status > SRC_UNKNOWN)
		errx(1, "invalid AC line status %d", acline_status);
	if ((acline_status == SRC_AC &&
	    (mode_ac == MODE_ADAPTIVE || mode_ac == MODE_HIADAPTIVE)) ||
	    (acline_status == SRC_BATTERY &&
	    (mode_battery == MODE_ADAPTIVE || mode_battery == MODE_HIADAPTIVE)) ||
	    (acline_status == SRC_UNKNOWN &&
	    (mode_none == MODE_ADAPTIVE || mode_none == MODE_HIADAPTIVE))) {
		/* Read the current frequency. */
		len = sizeof(curfreq);
		if (sysctl(freq_mib, 4, &curfreq, &len, NULL, 0) != 0) {
			if (vflag)
				warn("error reading current CPU frequency");
		}
		if (curfreq < freqs[numfreqs - 1]) {
			if (vflag) {
				printf("CPU frequency is below user-defined "
				    "minimum; changing frequency to %d "
				    "MHz\n", freqs[numfreqs - 1]);
			}
			if (set_freq(freqs[numfreqs - 1]) != 0) {
				warn("error setting CPU freq %d",
				    freqs[numfreqs - 1]);
			}
		} else if (curfreq > freqs[0]) {
			if (vflag) {
				printf("CPU frequency is above user-defined "
				    "maximum; changing frequency to %d "
				    "MHz\n", freqs[0]);
			}
			if (set_freq(freqs[0]) != 0) {
				warn("error setting CPU freq %d",
				    freqs[0]);
			}
		}
	}

	idle = 0;
	/* Main loop. */
	for (;;) {
		FD_ZERO(&fdset);
		if (devd_pipe >= 0) {
			FD_SET(devd_pipe, &fdset);
			nfds = devd_pipe + 1;
		} else {
			nfds = 0;
		}
		if (mode == MODE_HIADAPTIVE || idle < 120)
			to = poll_ival;
		else if (idle < 360)
			to = poll_ival * 2;
		else
			to = poll_ival * 4;
		timeout.tv_sec = to / 1000000;
		timeout.tv_usec = to % 1000000;
		select(nfds, &fdset, NULL, &fdset, &timeout);

		/* If the user requested we quit, print some statistics. */
		if (exit_requested) {
			if (vflag && mjoules_used != 0)
				printf("total joules used: %u.%03u\n",
				    (u_int)(mjoules_used / 1000),
				    (int)mjoules_used % 1000);
			break;
		}

		/* Read the current AC status and record the mode. */
		acline_read();
		switch (acline_status) {
		case SRC_AC:
			mode = mode_ac;
			break;
		case SRC_BATTERY:
			mode = mode_battery;
			break;
		case SRC_UNKNOWN:
			mode = mode_none;
			break;
		default:
			errx(1, "invalid AC line status %d", acline_status);
		}

		/* Read the current frequency. */
		if (idle % 32 == 0) {
			if ((curfreq = get_freq()) == 0)
				continue;
			i = get_freq_id(curfreq, freqs, numfreqs);
		}
		idle++;
		if (vflag) {
			/* Keep a sum of all power actually used. */
			if (mwatts[i] != -1)
				mjoules_used +=
				    (mwatts[i] * (poll_ival / 1000)) / 1000;
		}

		/* Always switch to the lowest frequency in min mode. */
		if (mode == MODE_MIN) {
			freq = freqs[numfreqs - 1];
			if (curfreq != freq) {
				if (vflag) {
					printf("now operating on %s power; "
					    "changing frequency to %d MHz\n",
					    modes[acline_status], freq);
				}
				idle = 0;
				if (set_freq(freq) != 0) {
					warn("error setting CPU freq %d",
					    freq);
					continue;
				}
			}
			continue;
		}

		/* Always switch to the highest frequency in max mode. */
		if (mode == MODE_MAX) {
			freq = freqs[0];
			if (curfreq != freq) {
				if (vflag) {
					printf("now operating on %s power; "
					    "changing frequency to %d MHz\n",
					    modes[acline_status], freq);
				}
				idle = 0;
				if (set_freq(freq) != 0) {
					warn("error setting CPU freq %d",
					    freq);
					continue;
				}
			}
			continue;
		}

		/* Adaptive mode; get the current CPU usage times. */
		if (read_usage_times(&load)) {
			if (vflag)
				warn("read_usage_times() failed");
			continue;
		}

		if (mode == MODE_ADAPTIVE) {
			if (load > cpu_running_mark) {
				if (load > 95 || load > cpu_running_mark * 2)
					freq *= 2;
				else
					freq = freq * load / cpu_running_mark;
				if (freq > freqs[0])
					freq = freqs[0];
			} else if (load < cpu_idle_mark &&
			    curfreq * load < freqs[get_freq_id(
			    freq * 7 / 8, freqs, numfreqs)] *
			    cpu_running_mark) {
				freq = freq * 7 / 8;
				if (freq < freqs[numfreqs - 1])
					freq = freqs[numfreqs - 1];
			}
		} else { /* MODE_HIADAPTIVE */
			if (load > cpu_running_mark / 2) {
				if (load > 95 || load > cpu_running_mark)
					freq *= 4;
				else
					freq = freq * load * 2 / cpu_running_mark;
				if (freq > freqs[0] * 2)
					freq = freqs[0] * 2;
			} else if (load < cpu_idle_mark / 2 &&
			    curfreq * load < freqs[get_freq_id(
			    freq * 31 / 32, freqs, numfreqs)] *
			    cpu_running_mark / 2) {
				freq = freq * 31 / 32;
				if (freq < freqs[numfreqs - 1])
					freq = freqs[numfreqs - 1];
			}
		}
		if (vflag) {
		    printf("load %3d%%, current freq %4d MHz (%2d), wanted freq %4d MHz\n",
			load, curfreq, i, freq);
		}
		j = get_freq_id(freq, freqs, numfreqs);
		if (i != j) {
			if (vflag) {
				printf("changing clock"
				    " speed from %d MHz to %d MHz\n",
				    freqs[i], freqs[j]);
			}
			idle = 0;
			if (set_freq(freqs[j]))
				warn("error setting CPU frequency %d",
				    freqs[j]);
		}
	}
	if (set_freq(initfreq))
		warn("error setting CPU frequency %d", initfreq);
	free(freqs);
	free(mwatts);
	devd_close();
	if (!vflag)
		pidfile_remove(pfh);

	exit(0);
}
Пример #12
0
int main(int argc, char const* argv[])
{
    ir::IRXDaemon* instance;
    OperationEnum operation;
    ModeEnum mode;
    struct pidfh* pfh;
    pid_t pid;
    bool daemonize;
    int i;
    int result(EXIT_SUCCESS);
    
    if ((instance = ir::IRXDaemon::_new()) != NULL) {
        operation = OPERATION_UNKNOWN;
        mode = MODE_UNKNOWN;
        if (argc > 1) {
            if ((result = instance->usage(argc, argv)) == EXIT_SUCCESS) {
                for (i = 1; i < argc; ++i) {
                    if (strcmp(argv[i], "start") == 0) {
                        operation = OPERATION_START;
                    }
                    else if (strcmp(argv[i], "restart") == 0) {
                        operation = OPERATION_RESTART;
                    }
                    else if (strcmp(argv[i], "stop") == 0) {
                        operation = OPERATION_STOP;
                    }
                    else if (strcmp(argv[i], "--daemon") == 0) {
                        mode = MODE_DAEMON;
                    }
                    else if (strcmp(argv[i], "--application") == 0) {
                        mode = MODE_APPLICATION;
                    }
                }
            }
        }
        if (result == EXIT_SUCCESS) {
            if (operation == OPERATION_UNKNOWN) {
                operation = OPERATION_START;
            }
            if (mode == MODE_UNKNOWN) {
                mode = MODE_DAEMON;
            }
            g_quit = false;
            signal(SIGHUP, onSigHUP);
            signal(SIGINT, onSigINT);
            signal(SIGTERM, onSigTERM);
            signal(SIGCHLD, SIG_IGN);
            switch (operation) {
                case OPERATION_RESTART:
                case OPERATION_STOP:
                    if ((pfh = pidfile_open(NULL, 0600, &pid)) != NULL) {
                        instance->log(LOG_NOTICE, "already stopped");
                        pidfile_remove(pfh);
                    }
                    else {
                        switch (errno) {
                            case EEXIST:
                                if (kill(pid, SIGTERM) == 0) {
                                    instance->log(LOG_NOTICE, "stopping pid = %d...", pid);
                                    while (true) {
                                        if (g_quit) {
                                            result = EXIT_FAILURE;
                                            break;
                                        }
                                        if (kill(pid, 0) != 0) {
                                            instance->log(LOG_NOTICE, "stopping done");
                                            break;
                                        }
                                        sleep(1);
                                    }
                                }
                                else {
                                    instance->log(LOG_ERR, "can't stop pid = %d [%m]", pid);
                                    result = EX_OSERR;
                                }
                                break;
                            case EACCES:
                                instance->log(LOG_ERR, "run as super user");
                                result = EX_OSERR;
                                break;
                            default:
                                instance->log(LOG_ERR, "can't stop [%m]");
                                result = EX_OSERR;
                                break;
                        }
                    }
                    break;
                default:
                    // nop
                    break;
            }
            if (result == EXIT_SUCCESS) {
                switch (operation) {
                    case OPERATION_START:
                    case OPERATION_RESTART:
                        if ((pfh = pidfile_open(NULL, 0600, &pid)) != NULL) {
                            instance->log(LOG_NOTICE, "starting pid = %d...", getpid());
                            daemonize = true;
                            if (mode == MODE_APPLICATION) {
                                daemonize = false;
                            }
                            #ifdef __APPLE__
                            if (getppid() == 1) {
                                daemonize = false;
                            }
                            #endif
                            if (daemonize) {
                                if (daemon(0, 0) != 0) {
                                    instance->log(LOG_ERR, "can't daemonize pid = %d [%m]", getpid());
                                    result = EX_OSERR;
                                }
                            }
                            if (result == EXIT_SUCCESS) {
                                instance->log(LOG_NOTICE, "changing pid = %d...", getpid());
                                pidfile_write(pfh);
                                if ((result = instance->initialize()) == EXIT_SUCCESS) {
                                    instance->log(LOG_NOTICE, "starting done");
                                    while (true) {
                                        if (g_quit) {
                                            result = EXIT_FAILURE;
                                            break;
                                        }
                                        instance->loop();
                                    }
                                }
                                else {
                                    instance->log(LOG_ERR, "can't start pid = %d [%d]", getpid(), result);
                                }
                                instance->terminate();
                            }
                            pidfile_remove(pfh);
                        }
                        else {
                            switch (errno) {
                                case EEXIST:
                                    instance->log(LOG_ERR, "already started pid = %d", pid);
                                    result = EX_OSERR;
                                    break;
                                case EACCES:
                                    instance->log(LOG_ERR, "run as super user");
                                    result = EX_OSERR;
                                    break;
                                default:
                                    instance->log(LOG_ERR, "can't start [%m]");
                                    result = EX_OSERR;
                                    break;
                            }
                        }
                        break;
                    default:
                        // nop
                        break;
                }
            }
        }
        ir::IRXDaemon::_delete(instance);
    }
    else {
        result = EXIT_FAILURE;
    }
    return result;
}
Пример #13
0
int
main(int argc, char *argv[])
{
	struct pidfh *pfh = NULL;
	int ch, nochdir, noclose, errcode;
	const char *pidfile, *user;
	pid_t otherpid;

	nochdir = noclose = 1;
	pidfile = user = NULL;
	while ((ch = getopt(argc, argv, "-cfp:u:")) != -1) {
		switch (ch) {
		case 'c':
			nochdir = 0;
			break;
		case 'f':
			noclose = 0;
			break;
		case 'p':
			pidfile = optarg;
			break;
		case 'u':
			user = optarg;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0)
		usage();

	if (user != NULL)
		restrict_process(user);

	/*
	 * Try to open the pidfile before calling daemon(3),
	 * to be able to report the error intelligently
	 */
	if (pidfile) {
		pfh = pidfile_open(pidfile, 0600, &otherpid);
		if (pfh == NULL) {
			if (errno == EEXIST) {
				errx(3, "process already running, pid: %d",
				    otherpid);
			}
			err(2, "pidfile ``%s''", pidfile);
		}
	}

	if (daemon(nochdir, noclose) == -1)
		err(1, NULL);

	/* Now that we are the child, write out the pid */
	if (pidfile)
		pidfile_write(pfh);

	execvp(argv[0], argv);

	/*
	 * execvp() failed -- unlink pidfile if any, and
	 * report the error
	 */
	errcode = errno; /* Preserve errcode -- unlink may reset it */
	if (pidfile)
		pidfile_remove(pfh);

	/* The child is now running, so the exit status doesn't matter. */
	errc(1, errcode, "%s", argv[0]);
}
Пример #14
0
int
main(int argc, char *argv[])
{
	struct pidfh *pfh = NULL;
	sigset_t mask, oldmask;
	int ch, nochdir, noclose, restart;
	const char *pidfile, *user;
	pid_t otherpid, pid;

	nochdir = noclose = 1;
	restart = 0;
	pidfile = user = NULL;
	while ((ch = getopt(argc, argv, "-cfp:ru:")) != -1) {
		switch (ch) {
		case 'c':
			nochdir = 0;
			break;
		case 'f':
			noclose = 0;
			break;
		case 'p':
			pidfile = optarg;
			break;
		case 'r':
			restart = 1;
			break;
		case 'u':
			user = optarg;
			break;
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	if (argc == 0)
		usage();

	pfh = NULL;
	/*
	 * Try to open the pidfile before calling daemon(3),
	 * to be able to report the error intelligently
	 */
	if (pidfile != NULL) {
		pfh = pidfile_open(pidfile, 0600, &otherpid);
		if (pfh == NULL) {
			if (errno == EEXIST) {
				errx(3, "process already running, pid: %d",
				    otherpid);
			}
			err(2, "pidfile ``%s''", pidfile);
		}
	}

	if (daemon(nochdir, noclose) == -1)
		err(1, NULL);

	/*
	 * If the pidfile or restart option is specified the daemon
	 * executes the command in a forked process and wait on child
	 * exit to remove the pidfile or restart the command. Normally
	 * we don't want the monitoring daemon to be terminated
	 * leaving the running process and the stale pidfile, so we
	 * catch SIGTERM and forward it to the children expecting to
	 * get SIGCHLD eventually.
	 */
	pid = -1;
	if (pidfile != NULL || restart) {
		/*
		 * Restore default action for SIGTERM in case the
		 * parent process decided to ignore it.
		 */
		if (signal(SIGTERM, SIG_DFL) == SIG_ERR)
			err(1, "signal");
		/*
		 * Because SIGCHLD is ignored by default, setup dummy handler
		 * for it, so we can mask it.
		 */
		if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR)
			err(1, "signal");
		/*
		 * Block interesting signals.
		 */
		sigemptyset(&mask);
		sigaddset(&mask, SIGTERM);
		sigaddset(&mask, SIGCHLD);
		if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1)
			err(1, "sigprocmask");
		/*
		 * Try to protect against pageout kill. Ignore the
		 * error, madvise(2) will fail only if a process does
		 * not have superuser privileges.
		 */
		(void)madvise(NULL, 0, MADV_PROTECT);
restart:
		/*
		 * Spawn a child to exec the command, so in the parent
		 * we could wait for it to exit and remove pidfile.
		 */
		pid = fork();
		if (pid == -1) {
			pidfile_remove(pfh);
			err(1, "fork");
		}
	}
	if (pid <= 0) {
		if (pid == 0) {
			/* Restore old sigmask in the child. */
			if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1)
				err(1, "sigprocmask");
		}
		/* Now that we are the child, write out the pid. */
		pidfile_write(pfh);

		if (user != NULL)
			restrict_process(user);

		execvp(argv[0], argv);

		/*
		 * execvp() failed -- report the error. The child is
		 * now running, so the exit status doesn't matter.
		 */
		err(1, "%s", argv[0]);
	}
	setproctitle("%s[%d]", argv[0], pid);
	if (wait_child(pid, &mask) == 0 && restart) {
		sleep(1);
		goto restart;
	}
	pidfile_remove(pfh);
	exit(0); /* Exit status does not matter. */
}
Пример #15
0
/*
 * Periodically pat the watchdog, preventing it from firing.
 */
int
main(int argc, char *argv[])
{
	struct rtprio rtp;
	struct pidfh *pfh;
	pid_t otherpid;

	if (getuid() != 0)
		errx(EX_SOFTWARE, "not super user");
		
	parseargs(argc, argv);

	if (do_syslog)
		openlog("watchdogd", LOG_CONS|LOG_NDELAY|LOG_PERROR,
		    LOG_DAEMON);

	rtp.type = RTP_PRIO_REALTIME;
	rtp.prio = 0;
	if (rtprio(RTP_SET, 0, &rtp) == -1)
		err(EX_OSERR, "rtprio");

	if (!is_dry_run && watchdog_init() == -1)
		errx(EX_SOFTWARE, "unable to initialize watchdog");

	if (is_daemon) {
		if (watchdog_onoff(1) == -1)
			err(EX_OSERR, "patting the dog");

		pfh = pidfile_open(pidfile, 0600, &otherpid);
		if (pfh == NULL) {
			if (errno == EEXIST) {
				watchdog_onoff(0);
				errx(EX_SOFTWARE, "%s already running, pid: %d",
				    getprogname(), otherpid);
			}
			warn("Cannot open or create pidfile");
		}

		if (debugging == 0 && daemon(0, 0) == -1) {
			watchdog_onoff(0);
			pidfile_remove(pfh);
			err(EX_OSERR, "daemon");
		}

		signal(SIGHUP, SIG_IGN);
		signal(SIGINT, sighandler);
		signal(SIGTERM, sighandler);

		pidfile_write(pfh);
		if (madvise(0, 0, MADV_PROTECT) != 0)
			warn("madvise failed");
		if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0)
			warn("mlockall failed");

		watchdog_loop();

		/* exiting */
		pidfile_remove(pfh);
		return (EX_OK);
	} else {
		if (passive)
			timeout |= WD_PASSIVE;
		else
			timeout |= WD_ACTIVE;
		if (watchdog_patpat(timeout) < 0)
			err(EX_OSERR, "patting the dog");
		return (EX_OK);
	}
}
Пример #16
0
heartbeat_daemon_tool(int argc, char *argv[])
{
    struct pidfh *ppfh, *pfh;
    sigset_t mask, oldmask;
    int ch, nochdir, noclose, restart, serrno;
    const char *pidfile, *ppidfile, *user;
    pid_t otherpid, pid;

    nochdir = noclose = 1;
    restart = 0;
    ppidfile = pidfile = user = NULL;
    while ((ch = getopt(argc, argv, "cfp:P:ru:")) != -1) {
        switch (ch) {
            case 'c':
                nochdir = 0;
                break;
            case 'f':
                noclose = 0;
                break;
            case 'p':
                pidfile = optarg;
                break;
            case 'P':
                ppidfile = optarg;
                break;
            case 'r':
                restart = 1;
                break;
            case 'u':
                user = optarg;
                break;
            default:
                daemon_tool_usage();
        }
    }
    argc -= optind;
    argv += optind;

    if (argc == 0)
        daemon_tool_usage();

    if (pidfile != NULL) {
        pfh = pidfile_open(pidfile, 0600, &otherpid);
        if (pfh == NULL) {
            if (errno == EEXIST) {
                errx(3, "process already running, pid: %d", otherpid);
            }
            err(2, "pidfile ``%s''", pidfile);
        }
    }

    if (ppidfile != NULL) {
        ppfh = pidfile_open(ppidfile, 0600, &otherpid);
        if (ppfh == NULL) {
            serrno = errno;
            pidfile_remove(pfh);
            errno = serrno;
            if (errno = EEXIST) {
                errx(3, "process already running, pid: %d", otherpid);
            }
            err(2, "ppidfile ``%s''", ppidfile);
        }
    }

    if (daemon(nochdir, noclose) == -1) {
        warn("daemon");
        goto exit;
    }

    pidfile_write(ppfh);

    pid = -1;

    if (pidfile != NULL || ppidfile != NULL || restart) {
        if (signal(SIGTERM, SIG_DFL) == SIG_ERR) {
            warn("signal");
            goto exit;
        }
        if (signal(SIGCHLD, dummy_sighandler) == SIG_ERR) {
            warn("signal");
            goto exit;
        }

        sigemptyset(&mask);
        sigaddset(&mask, SIGTERM);
        sigaddset(&mask, SIGCHLD);
        if (sigprocmask(SIG_SETMASK, &mask, &oldmask) == -1) {
            warn("sigprocmask");
            goto exit;
        }
        (void)madvise(NULL, 0, MADV_PROTECT);

restart:
            pid = fork();
            if (pid == -1) {
                warn("fork");
                goto exit;
            }
    }
    if (pid <= 0) {
        if (pid == 0) {
            if (sigprocmask(SIG_SETMASK, &oldmask, NULL) == -1)
                err(1, "sigprocmask");
        }

        pidfile_write(pfh);

        if (user != NULL)
            restrict_process(user);

        execvp(argv[0], argv);
        err(1, "%s", argv[0]);
    }
    setproctitle("%s[%d", argv[0], pid);
    if (wait_child(pid, &mask) == 0 && restart) {
        sleep(1);
        goto restart;
    }

exit:
        pidfile_remove(pfh);
        pidfile_remove(ppfh);
        exit(1);
}
Пример #17
0
int main(int argc, char *argv[])
{
	char optstring[] = "i:p:dfs:vh";
	struct option longopts[] = {
		{"isns-server",		1, NULL, 'i'},
		{"isns-port",		1, NULL, 'p'},
		{"debug",		0, NULL, 'd'},
		{"foreground",		0, NULL, 'f'},
		{"configfs-iscsi-path",	1, NULL, 's'},
		{"version",		0, NULL, 'v'},
		{"help",		0, NULL, 'h'},
		{NULL,			0, NULL, 0}
        };
	int option;
	int longindex = 0;
	int ifd = -1, sfd = -1, tfd = -1;
	struct epoll_event events[EPOLL_MAX_FD];
	ssize_t nr_events;
	bool daemon = true;
	int ret = EXIT_FAILURE;
	size_t configsz;

	conffile_read();

	while ((option = getopt_long(argc, argv, optstring, longopts,
				     &longindex)) != -1) {
		switch (option) {
		case 'i':
			configsz = sizeof(config.isns_server);
			strncpy(config.isns_server, optarg, configsz);
			config.isns_server[configsz - 1] = '\0';
			break;
		case 'p':
			sscanf(optarg, "%hu", &config.isns_port);
			break;
		case 'd':
			config.log_level = LOG_DEBUG;
			daemon = false;
			break;
		case 'f':
			daemon = false;
			break;
		case 's':
			configsz = sizeof(config.configfs_iscsi_path);
			strncpy(config.configfs_iscsi_path, optarg, configsz);
			config.configfs_iscsi_path[configsz - 1] = '\0';
			break;
		case 'v':
			printf(PROGNAME " version " TARGET_ISNS_VERSION "\n");
			exit(EXIT_SUCCESS);
			break;
		case 'h':
			print_usage();
			exit(EXIT_SUCCESS);
			break;
		case ':':
		case '?':
			exit(EXIT_FAILURE);
			break;
		}
	}

	if (!configfs_iscsi_path_exists()) {
		fprintf(stderr,
			"Error: configfs is not mounted or the "
			"target and iSCSI modules are not loaded.\n");
		fprintf(stderr,
			"Error: %s missing.\n",
			config.configfs_iscsi_path);
		exit(EXIT_FAILURE);
	}

	if (daemon) {
		daemonize();
		pidfile_create();
	}

	log_init(PROGNAME, daemon, config.log_level);
	log_print(LOG_INFO, PROGNAME " version " TARGET_ISNS_VERSION " started");

	epoll_init_fds();
	if (isns_init(config.isns_server, config.isns_port) == -1) {
		log_print(LOG_ERR, "failed to initialize iSNS client");
		goto err_init;
	}

	if ((epoll_fd = epoll_create1(0)) == -1) {
		log_print(LOG_ERR, "failed to create epoll instance");
		goto err_epoll_fd;
	}

	if ((tfd = isns_registration_timer_init()) == -1) {
		log_print(LOG_ERR, "failed to create timerfd instance");
		goto err_tfd;
	}
	epoll_set_fd(EPOLL_REGISTRATION_TIMER, tfd);

	if ((ifd = configfs_inotify_init()) == -1) {
		log_print(LOG_ERR, "failed to create inotify instance");
		goto err_ifd;
	}
	epoll_set_fd(EPOLL_INOTIFY, ifd);

	if ((sfd = signal_init()) == -1) {
		log_print(LOG_ERR, "failed to create signalfd instance");
		goto err_sfd;
	}
	epoll_set_fd(EPOLL_SIGNAL, sfd);

	isns_start();
	while (true) {
		nr_events = epoll_wait(epoll_fd, events, ARRAY_SIZE(events), -1);

		for (int i = 0; i < nr_events; i++) {
			int fd = events[i].data.fd;

			if (fd == epoll_set[EPOLL_SIGNAL]) {
				if (signal_is_quit(fd))
					goto quit;
			} else if (fd == epoll_set[EPOLL_INOTIFY])
				configfs_inotify_events_handle();
			else if (fd == epoll_set[EPOLL_REGISTRATION_TIMER])
				isns_registration_refresh();
			else if (fd == epoll_set[EPOLL_ISNS])
				isns_handle();
			else if (fd == epoll_set[EPOLL_SCN_LISTEN])
				isns_scn_handle(true);
			else if (fd == epoll_set[EPOLL_SCN])
				isns_scn_handle(false);
		}
	}

quit:
	ret = EXIT_SUCCESS;
	isns_stop();
	sleep(1);
	close(sfd);
err_sfd:
	configfs_inotify_cleanup(); /* closes ifd */
err_ifd:
	close(tfd);
err_tfd:
	close(epoll_fd);
err_epoll_fd:
	isns_exit();
err_init:
	log_print(LOG_INFO, PROGNAME " stopped");
	log_close();
	if (daemon)
		pidfile_remove();

	return ret;
}
Пример #18
0
int
main(
    int argc,
    char *argv[])
{
    const char *program = basename(argv[0]);

    int fps = DEFAULT_FPS;
    suseconds_t frameDuration =  1000000 / fps;
    bool isDaemon =  false;
    uint32_t sourceDisplayNumber = DEFAULT_SOURCE_DISPLAY_NUMBER;
    uint32_t destDisplayNumber = DEFAULT_DESTINATION_DISPLAY_NUMBER;
	int32_t layerNumber = DEFAULT_LAYER_NUMBER;
    const char *pidfile = NULL;

    //---------------------------------------------------------------------

    static const char *sopts = "d:f:hl:p:s:D";
    static struct option lopts[] = 
    {
        { "destination", required_argument, NULL, 'd' },
        { "fps", required_argument, NULL, 'f' },
        { "help", no_argument, NULL, 'h' },
        { "layer", required_argument, NULL, 'l' },
        { "pidfile", required_argument, NULL, 'p' },
        { "source", required_argument, NULL, 's' },
        { "daemon", no_argument, NULL, 'D' },
        { NULL, no_argument, NULL, 0 }
    };

    int opt = 0;

    while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1)
    {
        switch (opt)
        {
        case 'd':

            destDisplayNumber = atoi(optarg);
            break;

        case 'f':

            fps = atoi(optarg);

            if (fps > 0)
            {
                frameDuration = 1000000 / fps;
            }
            else
            {
                fps = 1000000 / frameDuration;
            }

            break;

        case 'h':

            printUsage(stdout, program);
            exit(EXIT_SUCCESS);

            break;

        case 'l':

            layerNumber = atoi(optarg);
            break;

        case 'p':

            pidfile = optarg;

            break;

        case 's':

            sourceDisplayNumber = atoi(optarg);
            break;

        case 'D':

            isDaemon = true;
            break;

        default:

            printUsage(stderr, program);
            exit(EXIT_FAILURE);

            break;
        }
    }

    //---------------------------------------------------------------------

    struct pidfh *pfh = NULL;

    if (isDaemon)
    {
        if (pidfile != NULL)
        {
            pid_t otherpid;
            pfh = pidfile_open(pidfile, 0600, &otherpid);

            if (pfh == NULL)
            {
                fprintf(stderr,
                        "%s is already running %jd\n",
                        program,
                        (intmax_t)otherpid);
                exit(EXIT_FAILURE);
            }
        }
        
        if (daemon(0, 0) == -1)
        {
            fprintf(stderr, "daemonize failed\n");

            exitAndRemovePidFile(EXIT_FAILURE, pfh);
        }

        if (pfh)
        {
            pidfile_write(pfh);
        }

        openlog(program, LOG_PID, LOG_USER);
    }

    //---------------------------------------------------------------------

    if (signal(SIGINT, signalHandler) == SIG_ERR)
    {
        perrorLog(isDaemon, program, "installing SIGINT signal handler");

        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    //---------------------------------------------------------------------

    if (signal(SIGTERM, signalHandler) == SIG_ERR)
    {
        perrorLog(isDaemon, program, "installing SIGTERM signal handler");

        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    //---------------------------------------------------------------------

    bcm_host_init();

    //---------------------------------------------------------------------

    int result = 0;

    //---------------------------------------------------------------------
    // Make sure the VC_DISPLAY variable isn't set. 

    unsetenv("VC_DISPLAY");

    //---------------------------------------------------------------------

    DISPMANX_DISPLAY_HANDLE_T sourceDisplay
        = vc_dispmanx_display_open(sourceDisplayNumber);

    if (sourceDisplay == 0)
    {
        messageLog(isDaemon,
                   program,
                   LOG_ERR,
                   "open source display failed");
        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    DISPMANX_MODEINFO_T sourceInfo;

    result = vc_dispmanx_display_get_info(sourceDisplay, &sourceInfo);

    if (result != 0)
    {
        messageLog(isDaemon,
                   program,
                   LOG_ERR,
                   "getting source display dimensions failed");

        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    //---------------------------------------------------------------------

    DISPMANX_DISPLAY_HANDLE_T destDisplay
        = vc_dispmanx_display_open(destDisplayNumber);

    if (destDisplay == 0)
    {
        messageLog(isDaemon,
                   program,
                   LOG_ERR,
                   "open destination display failed");
        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    DISPMANX_MODEINFO_T destInfo;

    result = vc_dispmanx_display_get_info(destDisplay, &destInfo);

    if (result != 0)
    {
        messageLog(isDaemon,
                   program,
                   LOG_ERR,
                   "getting destination display dimensions failed");
        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    //---------------------------------------------------------------------

    messageLog(isDaemon,
               program,
               LOG_INFO,
               "copying from [%d] %dx%d to [%d] %dx%d",
               sourceDisplayNumber,
               sourceInfo.width,
               sourceInfo.height,
               destDisplayNumber,
               destInfo.width,
               destInfo.height);

    //---------------------------------------------------------------------

    uint32_t image_ptr;

    DISPMANX_RESOURCE_HANDLE_T resource = 
        vc_dispmanx_resource_create(VC_IMAGE_RGBA32,
                                    destInfo.width,
                                    destInfo.height,
                                    &image_ptr);

    //---------------------------------------------------------------------

    VC_RECT_T sourceRect;
    vc_dispmanx_rect_set(&sourceRect,
                         0,
                         0,
                         destInfo.width << 16,
                         destInfo.height << 16);
    
    VC_RECT_T destRect;
    vc_dispmanx_rect_set(&destRect, 0, 0, 0, 0);

    //---------------------------------------------------------------------

    VC_DISPMANX_ALPHA_T alpha =
    {
        DISPMANX_FLAGS_ALPHA_FIXED_ALL_PIXELS,
        255,
        0
    };

    DISPMANX_UPDATE_HANDLE_T update = vc_dispmanx_update_start(0);

    if (update == 0)
    {
        messageLog(isDaemon,
                   program,
                   LOG_ERR,
                   "display update failed");
        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    DISPMANX_ELEMENT_HANDLE_T element;
    element = vc_dispmanx_element_add(update,
                                      destDisplay,
                                      layerNumber,
                                      &destRect,
                                      resource,
                                      &sourceRect,
                                      DISPMANX_PROTECTION_NONE,
                                      &alpha,
                                      NULL,
                                      DISPMANX_NO_ROTATE);
    if (element == 0)
    {
        messageLog(isDaemon,
                   program,
                   LOG_ERR,
                   "failed to create DispmanX element");
        exitAndRemovePidFile(EXIT_FAILURE, pfh);
    }

    vc_dispmanx_update_submit_sync(update);

    //---------------------------------------------------------------------

    struct timeval start_time;
    struct timeval end_time;
    struct timeval elapsed_time;

    //---------------------------------------------------------------------

    while (run)
    {
        gettimeofday(&start_time, NULL);

        //-----------------------------------------------------------------

        result = vc_dispmanx_snapshot(sourceDisplay,
                                      resource,
                                      DISPMANX_NO_ROTATE);

        if (result != 0)
        {
            messageLog(isDaemon,
                       program,
                       LOG_ERR,
                       "DispmanX snapshot failed");
            exitAndRemovePidFile(EXIT_FAILURE, pfh);
        }

        //-----------------------------------------------------------------

        update = vc_dispmanx_update_start(0);

        if (update == 0)
        {
            messageLog(isDaemon,
                       program,
                       LOG_ERR,
                       "display update failed");
            exitAndRemovePidFile(EXIT_FAILURE, pfh);
        }

        vc_dispmanx_element_change_source(update, element, resource);
        vc_dispmanx_update_submit_sync(update);

        //-----------------------------------------------------------------

        gettimeofday(&end_time, NULL);
        timersub(&end_time, &start_time, &elapsed_time);

        if (elapsed_time.tv_sec == 0)
        {
            if (elapsed_time.tv_usec < frameDuration)
            {
                usleep(frameDuration -  elapsed_time.tv_usec);
            }
        }
    }

    //---------------------------------------------------------------------

    update = vc_dispmanx_update_start(0);
    vc_dispmanx_element_remove(update, element);
    vc_dispmanx_update_submit_sync(update);

    vc_dispmanx_resource_delete(resource);

    vc_dispmanx_display_close(sourceDisplay);
    vc_dispmanx_display_close(destDisplay);

    //---------------------------------------------------------------------

    messageLog(isDaemon, program, LOG_INFO, "exiting");

    if (isDaemon)
    {
        closelog();
    }

    if (pfh)
    {
        pidfile_remove(pfh);
    }

    //---------------------------------------------------------------------

    return 0 ;
}
Пример #19
0
int
main(int argc, char **argv)
{
    int ch, debug = 0, error, iscsi_fd, maxproc = 30, retval, saved_errno,
            timeout = 60;
    bool dont_daemonize = false;
    struct pidfh *pidfh;
    pid_t pid, otherpid;
    const char *pidfile_path = DEFAULT_PIDFILE;
    struct iscsi_daemon_request request;

    while ((ch = getopt(argc, argv, "P:dl:m:t:")) != -1) {
        switch (ch) {
        case 'P':
            pidfile_path = optarg;
            break;
        case 'd':
            dont_daemonize = true;
            debug++;
            break;
        case 'l':
            debug = atoi(optarg);
            break;
        case 'm':
            maxproc = atoi(optarg);
            break;
        case 't':
            timeout = atoi(optarg);
            break;
        case '?':
        default:
            usage();
        }
    }
    argc -= optind;
    if (argc != 0)
        usage();

    log_init(debug);

    pidfh = pidfile_open(pidfile_path, 0600, &otherpid);
    if (pidfh == NULL) {
        if (errno == EEXIST)
            log_errx(1, "daemon already running, pid: %jd.",
                     (intmax_t)otherpid);
        log_err(1, "cannot open or create pidfile \"%s\"",
                pidfile_path);
    }

    iscsi_fd = open(ISCSI_PATH, O_RDWR);
    if (iscsi_fd < 0 && errno == ENOENT) {
        saved_errno = errno;
        retval = kldload("iscsi");
        if (retval != -1)
            iscsi_fd = open(ISCSI_PATH, O_RDWR);
        else
            errno = saved_errno;
    }
    if (iscsi_fd < 0)
        log_err(1, "failed to open %s", ISCSI_PATH);

    if (dont_daemonize == false) {
        if (daemon(0, 0) == -1) {
            log_warn("cannot daemonize");
            pidfile_remove(pidfh);
            exit(1);
        }
    }

    pidfile_write(pidfh);

    register_sigchld();

    for (;;) {
        log_debugx("waiting for request from the kernel");

        memset(&request, 0, sizeof(request));
        error = ioctl(iscsi_fd, ISCSIDWAIT, &request);
        if (error != 0) {
            if (errno == EINTR) {
                nchildren -= wait_for_children(false);
                assert(nchildren >= 0);
                continue;
            }

            log_err(1, "ISCSIDWAIT");
        }

        if (dont_daemonize) {
            log_debugx("not forking due to -d flag; "
                       "will exit after servicing a single request");
        } else {
            nchildren -= wait_for_children(false);
            assert(nchildren >= 0);

            while (maxproc > 0 && nchildren >= maxproc) {
                log_debugx("maxproc limit of %d child processes hit; "
                           "waiting for child process to exit", maxproc);
                nchildren -= wait_for_children(true);
                assert(nchildren >= 0);
            }
            log_debugx("incoming connection; forking child process #%d",
                       nchildren);
            nchildren++;

            pid = fork();
            if (pid < 0)
                log_err(1, "fork");
            if (pid > 0)
                continue;
        }

        pidfile_close(pidfh);
        handle_request(iscsi_fd, &request, timeout);
    }

    return (0);
}
Пример #20
0
int main(int argc, char *argv[], char *envp[]) {
    log_open(LOG_FILE);
    FM_LOG_TRACE("---");
    check_pid();

    int sockfd;
    socklen_t clilen;
    struct sockaddr_in serv_addr{};
    struct sockaddr_in cli_addr{};
    const char *cfg_file;

    if (argc > 1) {
        cfg_file = argv[1];
    } else {
        cfg_file = DEFAULT_CFG_FILE;
    }
    read_config(cfg_file);
    FM_LOG_TRACE("read_config");

    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0) {
        fatal_error("ERROR opening socket");
    }
    FM_LOG_TRACE("socket");

    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    if (inet_aton(oj_config.ip, &serv_addr.sin_addr) == 0) {
        serv_addr.sin_addr.s_addr = INADDR_ANY;
    }
    serv_addr.sin_port = htons(oj_config.port);
    FM_LOG_NOTICE("IP address: %s %s", oj_config.ip, inet_ntoa(serv_addr.sin_addr));
    FM_LOG_NOTICE("port: %d %d", oj_config.port, ntohs(serv_addr.sin_port));

    int yes = 1;
    if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int)) == -1) {
        fatal_error("setsockopt SO_REUSEADDR failed");
    }

    if (bind(sockfd, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
        fatal_error("ERROR on binding");
    }
    FM_LOG_TRACE("bind");

    clilen = sizeof(cli_addr);

    if (listen(sockfd, oj_config.backlog) < 0) {
        fatal_error("ERROR on listening");
    }
    FM_LOG_NOTICE("listen  backlog: %d", oj_config.backlog);

    if (daemon(0, 0) == -1) {
        FM_LOG_FATAL("Cannot daemonize");
        pidfile_remove(pfh);

        exit(EXIT_FAILURE);
    }

    print_word_dir();
    print_user_group();

    pidfile_write(pfh);

    struct sigaction sa{};
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    if (sigaction(SIGTERM, &sa, nullptr) == -1) {   // install signal hander for timeout
        FM_LOG_FATAL("cannot handle SIGTERM");
        exit(EXIT_FAILURE);
    } else {
        FM_LOG_DEBUG("set signal_handler");
    }
    for (int i = 0; i < oj_config.thread_num; i++) {
        std::thread t(ThreadWork);
        t.detach();
    }
    FM_LOG_NOTICE("thread count: %d", oj_config.thread_num);

    std::thread(SendWork).detach();

    while (isRunning) {
        int newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
        if (newsockfd != -1) {
            work(newsockfd, cli_addr);
        }
    }

    pidfile_remove(pfh);
    close(sockfd);
    return 0;
}
Пример #21
0
void
tap_init(void)
{
	channel_t *chan;
	struct ifreq ifr;
	int fd, s;
	char pidfile[PATH_MAX];

	fd = open(interface_name, O_RDWR);
	if (fd == -1) {
		log_err("Could not open \"%s\": %m", interface_name);
		exit(EXIT_FAILURE);
	}

	memset(&ifr, 0, sizeof(ifr));
	if (ioctl(fd, TAPGIFNAME, &ifr) == -1) {
		log_err("Could not get interface name: %m");
		exit(EXIT_FAILURE);
	}

	s = socket(AF_INET, SOCK_DGRAM, 0);
	if (s == -1) {
		log_err("Could not open PF_LINK socket: %m");
		exit(EXIT_FAILURE);
	}

	ifr.ifr_addr.sa_family = AF_LINK;
	ifr.ifr_addr.sa_len = ETHER_ADDR_LEN;
	b2eaddr(ifr.ifr_addr.sa_data, &local_bdaddr);

	if (ioctl(s, SIOCSIFLLADDR, &ifr) == -1) {
		log_err("Could not set %s physical address: %m", ifr.ifr_name);
		exit(EXIT_FAILURE);
	}

	if (ioctl(s, SIOCGIFFLAGS, &ifr) == -1) {
		log_err("Could not get interface flags: %m");
		exit(EXIT_FAILURE);
	}

	if ((ifr.ifr_flags & IFF_UP) == 0) {
		ifr.ifr_flags |= IFF_UP;

		if (ioctl(s, SIOCSIFFLAGS, &ifr) == -1) {
			log_err("Could not set IFF_UP: %m");
			exit(EXIT_FAILURE);
		}
	}

	close(s);

	log_info("Using interface %s with addr %s", ifr.ifr_name,
		ether_ntoa((struct ether_addr *)&ifr.ifr_addr.sa_data));

	chan = channel_alloc();
	if (chan == NULL)
		exit(EXIT_FAILURE);

	chan->send = tap_send;
	chan->recv = tap_recv;
	chan->mru = ETHER_HDR_LEN + ETHER_MAX_LEN;
	memcpy(chan->raddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
	memcpy(chan->laddr, ifr.ifr_addr.sa_data, ETHER_ADDR_LEN);
	chan->state = CHANNEL_OPEN;
	if (!channel_open(chan, fd))
		exit(EXIT_FAILURE);

	snprintf(pidfile, sizeof(pidfile), "%s/%s.pid",
		_PATH_VARRUN, ifr.ifr_name);
	chan->pfh = pidfile_open(pidfile, 0600, NULL);
	if (chan->pfh == NULL)
		log_err("can't create pidfile");
	else if (pidfile_write(chan->pfh) < 0) {
		log_err("can't write pidfile");
		pidfile_remove(chan->pfh);
		chan->pfh = NULL;
	}
}
Пример #22
0
/*
 * Prepare for a clean shutdown
 */
void
daemon_shutdown()
{
	pidfile_remove(pfh);
}