Ejemplo n.º 1
0
static void tftp_command(ctrl_t *ctrl)
{
	/* Default buffer and segment size */
	if (alloc_buf(ctrl, SEGSIZE)) {
		ERR(errno, "Failed allocating TFTP buffer memory");
		return;
	}

	uev_io_init(ctrl->ctx, &ctrl->io_watcher, read_client_command, ctrl, ctrl->sd, UEV_READ);
	uev_run(ctrl->ctx, 0);
}
Ejemplo n.º 2
0
int main(void)
{
	struct timeval tomorrow;
	uev_ctx_t ctx;

	gettimeofday(&tomorrow, NULL);
	tomorrow.tv_sec += 24 * 60 * 60;

	uev_init(&ctx);
	uev_timer_init(&ctx, &timer1, cb, NULL, TIMEOUT1 * 1000, 0);
	uev_timer_init(&ctx, &timer2, cb, NULL, TIMEOUT2 * 1000, 0);
	uev_timer_init(&ctx, &timer3, cb, NULL, TIMEOUT2 * 1000, 0);
	uev_timer_stop(&timer3);

	uev_cron_init(&ctx, &cron1, cb, NULL, tomorrow.tv_sec, 24 * 60 * 60);
	uev_cron_init(&ctx, &cron2, cb, NULL, tomorrow.tv_sec, 24 * 60 * 60);

	return uev_run(&ctx, 0);
}
Ejemplo n.º 3
0
/* This example implementation uses libuEv, so you need to
 * build that first and link to it using the Makefile. */
int main(void)
{
	int sd;
	char buf[512];
	size_t len;
	struct mbus_arg arg;
        uev_t     stdio_watcher, socket_watcher;
        uev_ctx_t ctx;
	
	sd = socket_init(MC_GROUP_DEFAULT, MC_PORT_DEFAULT, MC_TTL_DEFAULT);
	if (sd < 0)
		return 1;

	fcntl(STDIN_FILENO, F_SETFL, O_NONBLOCK);
	arg.fp = stdin;
	arg.sd = sd;

	uev_init(&ctx);
        uev_io_init(&ctx, &stdio_watcher, read_stdin, &arg, STDIN_FILENO, UEV_READ);
        uev_io_init(&ctx, &socket_watcher, read_socket, &arg, sd, UEV_READ);

	return uev_run(&ctx, 0);
}
Ejemplo n.º 4
0
int main(int argc, char* argv[])
{
	char *path;
	char cmd[256];
	int udev = 0;
	uev_t timer;	       /* Bootstrap timer, on timeout call finalize() */
	uev_ctx_t loop;

	/*
	 * finit/init/telinit client tool uses /dev/initctl pipe
	 * for compatibility but initctl client tool uses socket
	 */
	if (getpid() != 1)
		return client(argc, argv);

	/*
	 * Initalize event context.
	 */
	uev_init(&loop);
	ctx = &loop;

	/*
	 * Set PATH and SHELL early to something sane
	 */
	setenv("PATH", _PATH_STDPATH, 1);
	setenv("SHELL", _PATH_BSHELL, 1);

	/*
	 * Mount base file system, kernel is assumed to run devtmpfs for /dev
	 */
	chdir("/");
	umask(0);
	mount("none", "/proc", "proc", 0, NULL);
	mount("none", "/sys", "sysfs", 0, NULL);
	if (fisdir("/proc/bus/usb"))
		mount("none", "/proc/bus/usb", "usbfs", 0, NULL);

	/*
	 * Parse kernel command line (debug, rescue, splash, etc.)
	 * Also calls log_init() to set correct log level
	 */
	conf_parse_cmdline();

	/* Set up canvas */
	if (!rescue && !log_is_debug())
		screen_init();

	/*
	 * In case of emergency.
	 */
	emergency_shell();

	/*
	 * Initial setup of signals, ignore all until we're up.
	 */
	sig_init();

	/*
	 * Load plugins early, finit.conf may contain references to
	 * features implemented by plugins.
	 */
	plugin_init(&loop);

	/*
	 * Hello world.
	 */
	banner();

	/*
	 * Check file filesystems in /etc/fstab
	 */
	for (int pass = 1; pass < 10 && !rescue; pass++) {
		if (fsck(pass))
			break;
	}

	/*
	 * Initialize .conf system and load static /etc/finit.conf
	 * Also initializes global_rlimit[] for udevd, below.
	 */
	conf_init();

	/*
	 * Some non-embedded systems without an initramfs may not have /dev mounted yet
	 * If they do, check if system has udevadm and perform cleanup from initramfs
	 */
	if (!fismnt("/dev"))
		mount("udev", "/dev", "devtmpfs", MS_RELATIME, "size=10%,nr_inodes=61156,mode=755");
	else if (whichp("udevadm"))
		run_interactive("udevadm info --cleanup-db", "Cleaning up udev db");

	/* Some systems use /dev/pts */
	makedir("/dev/pts", 0755);
	mount("devpts", "/dev/pts", "devpts", 0, "gid=5,mode=620");

	/*
	 * Some systems rely on us to both create /dev/shm and, to mount
	 * a tmpfs there.  Any system with dbus needs shared memory, so
	 * mount it, unless its already mounted, but not if listed in
	 * the /etc/fstab file already.
	 */
	makedir("/dev/shm", 0755);
	if (!fismnt("/dev/shm") && !ismnt("/etc/fstab", "/dev/shm"))
		mount("shm", "/dev/shm", "tmpfs", 0, NULL);

	/*
	 * New tmpfs based /run for volatile runtime data
	 * For details, see http://lwn.net/Articles/436012/
	 */
	if (fisdir("/run") && !fismnt("/run"))
		mount("tmpfs", "/run", "tmpfs", MS_NODEV, "mode=0755,size=10%");
	umask(022);

	/* Bootstrap conditions, needed for hooks */
	cond_init();

	/*
	 * Populate /dev and prepare for runtime events from kernel.
	 * Prefer udev if mdev is also available on the system.
	 */
	path = which("udevd");
	if (!path)
		path = which("/lib/systemd/systemd-udevd");
	if (path) {
		/* Desktop and server distros usually have a variant of udev */
		udev = 1;

		/* Register udevd as a monitored service */
		snprintf(cmd, sizeof(cmd), "[S12345789] pid:udevd %s -- Device event managing daemon", path);
		if (service_register(SVC_TYPE_SERVICE, cmd, global_rlimit, NULL)) {
			_pe("Failed registering %s", path);
			udev = 0;
		} else {
			snprintf(cmd, sizeof(cmd), ":1 [S] <svc%s> "
				 "udevadm trigger -c add -t devices "
				 "-- Requesting device events", path);
			service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);

			snprintf(cmd, sizeof(cmd), ":2 [S] <svc%s> "
				 "udevadm trigger -c add -t subsystems "
				 "-- Requesting subsystem events", path);
			service_register(SVC_TYPE_RUN, cmd, global_rlimit, NULL);
		}
		free(path);
	} else {
		path = which("mdev");
		if (path) {
			/* Embedded Linux systems usually have BusyBox mdev */
			if (log_is_debug())
				touch("/dev/mdev.log");

			snprintf(cmd, sizeof(cmd), "%s -s", path);
			free(path);

			run_interactive(cmd, "Populating device tree");
		}
	}

	/*
	 * Start built-in watchdog as soon as possible, if enabled
	 */
	wdogpid = watchdog(argv[0]);

	/*
	 * Mount filesystems
	 */
	if (!rescue) {
#ifdef REMOUNT_ROOTFS
		run("mount -n -o remount,rw /");
#endif
#ifdef SYSROOT
		mount(SYSROOT, "/", NULL, MS_MOVE, NULL);
#endif
	}

	if (!rescue) {
		_d("Root FS up, calling hooks ...");
		plugin_run_hooks(HOOK_ROOTFS_UP);

		umask(0);
		if (run_interactive("mount -na", "Mounting filesystems"))
			plugin_run_hooks(HOOK_MOUNT_ERROR);

		_d("Calling extra mount hook, after mount -a ...");
		plugin_run_hooks(HOOK_MOUNT_POST);

		run("swapon -ea");
		umask(0022);
	}

	/* Base FS up, enable standard SysV init signals */
	sig_setup(&loop);

	if (!rescue) {
		_d("Base FS up, calling hooks ...");
		plugin_run_hooks(HOOK_BASEFS_UP);
	}

	/*
	 * Set up inotify watcher for /etc/finit.d and read all .conf
	 * files to figure out how to bootstrap the system.
	 */
	conf_monitor(&loop);

	/*
	 * Initalize state machine and start all bootstrap tasks
	 * NOTE: no network available!
	 */
	sm_init(&sm);
	sm_step(&sm);

	/* Debian has this little script to copy generated rules while the system was read-only */
	if (udev && fexist("/lib/udev/udev-finish"))
		run_interactive("/lib/udev/udev-finish", "Finalizing udev");

	/* Start new initctl API responder */
	api_init(&loop);
	umask(022);

	/*
	 * Wait for all SVC_TYPE_RUNTASK to have completed their work in
	 * [S], or timeout, before calling finalize()
	 */
	_d("Starting bootstrap finalize timer ...");
	uev_timer_init(&loop, &timer, service_bootstrap_cb, finalize, 1000, 1000);

	/*
	 * Enter main loop to monior /dev/initctl and services
	 */
	_d("Entering main loop ...");
	return uev_run(&loop, 0);
}
Ejemplo n.º 5
0
int main(int argc, char *argv[])
{
	int timeout = WDT_TIMEOUT_DEFAULT;
	int real_timeout = 0;
	int T;
	int background = 1;
	int use_syslog = 1;
	int c, status;
	int log_opts = LOG_NDELAY | LOG_NOWAIT | LOG_PID;
	struct option long_options[] = {
		{"load-average",  1, 0, 'a'},
		{"foreground",    0, 0, 'n'},
		{"help",          0, 0, 'h'},
		{"interval",      1, 0, 't'},
		{"loglevel",      1, 0, 'l'},
		{"meminfo",       1, 0, 'm'},
		{"filenr",        1, 0, 'f'},
		{"pmon",          2, 0, 'p'},
		{"safe-exit",     0, 0, 'e'},
		{"syslog",        0, 0, 's'},
#ifndef TESTMODE_DISABLED
		{"test-mode",     0, 0, 'S'}, /* Hidden test mode, not for public use. */
#endif
		{"version",       0, 0, 'v'},
		{"timeout",       1, 0, 'T'},
		{NULL, 0, 0, 0}
	};
	uev_ctx_t ctx;

	while ((c = getopt_long(argc, argv, "a:f:Fhl:Lm:np::sSt:T:Vvx?", long_options, NULL)) != EOF) {
		switch (c) {
		case 'a':
			if (loadavg_set(optarg))
			    return usage(1);
			break;

		case 'f':
			if (filenr_set(optarg))
				return usage(1);
			break;

		case 'h':
			return usage(0);

		case 'l':
			loglevel = __wdog_loglevel(optarg);
			if (-1 == loglevel)
				return usage(1);
			break;

		case 'm':
			if (meminfo_set(optarg))
				return usage(1);
			break;

		case 'F':	/* BusyBox watchdogd compat. */
		case 'n':	/* Run in foreground */
			background = 0;
			use_syslog--;
			break;

		case 'p':
			if (pmon_set(optarg))
				return usage(1);
			break;

		case 's':
			use_syslog++;
			break;

#ifndef TESTMODE_DISABLED
		case 'S':	/* Simulate: no interaction with kernel, for testing pmon */
			__wdt_testmode = 1;
			break;
#endif

		case 't':	/* Watchdog kick interval */
			if (!optarg) {
				ERROR("Missing interval argument.");
				return usage(1);
			}
			period = atoi(optarg);
			break;

		case 'T':	/* Watchdog timeout */
			if (!optarg) {
				ERROR("Missing timeout argument.");
				return usage(1);
			}
			timeout = atoi(optarg);
			break;

		case 'v':
			printf("v%s\n", VERSION);
			return 0;

		case 'x':	/* Safe exit, i.e., don't reboot if we exit and close device */
			magic = 1;
			break;

		default:
			printf("Unrecognized option \"-%c\".\n", c);
			return usage(1);
		}
	}

	/* BusyBox watchdogd compat. */
	if (optind < argc) {
		char *dev = argv[optind];

		if (!strncmp(dev, "/dev", 4))
			strlcpy(devnode, dev, sizeof(devnode));
	}

	if (background) {
		DEBUG("Daemonizing ...");

		if (-1 == daemon(0, 0)) {
			PERROR("Failed daemonizing");
			return 1;
		}
	}

	if (!background && use_syslog < 1)
		log_opts |= LOG_PERROR;

	setlogmask(LOG_UPTO(loglevel));
	openlog(NULL, log_opts, LOG_DAEMON);

	INFO("watchdogd v%s %s ...", PACKAGE_VERSION, wdt_testmode() ? "test mode" : "starting");
	uev_init(&ctx);

	/* Setup callbacks for SIGUSR1 and, optionally, exit magic on SIGINT/SIGTERM */
	setup_signals(&ctx);

	if (wdt_init()) {
		PERROR("Failed connecting to kernel watchdog driver");
		return 1;
	}

	/* Set requested WDT timeout right before we enter the event loop. */
	if (wdt_set_timeout(timeout))
		PERROR("Failed setting HW watchdog timeout: %d", timeout);

	/* Sanity check with driver that setting actually took. */
	real_timeout = wdt_get_timeout();
	if (real_timeout < 0) {
		PERROR("Failed reading current watchdog timeout");
	} else {
		if (real_timeout <= period) {
			ERROR("Warning, watchdog timeout <= kick interval: %d <= %d",
			      real_timeout, period);
		}
	}

	/* If user did not provide '-k' argument, set to half actual timeout */
	if (-1 == period) {
		if (real_timeout < 0)
			period = WDT_KICK_DEFAULT;
		else
			period = real_timeout / 2;

		if (!period)
			period = 1;
	}

	/* Calculate period (T) in milliseconds for libuEv */
	T = period * 1000;
	DEBUG("Watchdog kick interval set to %d sec.", period);

	/* Read boot cause from watchdog and save in /var/run/watchdogd.status */
	create_bootstatus(real_timeout, period);

	/* Every period (T) seconds we kick the wdt */
	uev_timer_init(&ctx, &period_watcher, period_cb, NULL, T, T);

	/* Start all enabled plugins */
	wdt_plugins_init(&ctx, T);

	/* Only create pidfile when we're done with all set up. */
	if (pidfile(NULL) && !wdt_testmode())
		PERROR("Cannot create pidfile");

	status = uev_run(&ctx, 0);
	if (wdt_testmode())
		return status;

	while (wait_reboot) {
		int reboot_in = 3 * real_timeout;

		INFO("Waiting for HW WDT reboot ...");
		while (reboot_in > 0) {
			unsigned int rest = sleep(real_timeout);

			while (rest)
				rest = sleep(rest);

			reboot_in -= real_timeout;
		}

		INFO("HW WDT dit not reboot, forcing reboot now ...");
		reboot(RB_AUTOBOOT);
	}

	return status;
}