0d201bc33ffa46d1fad1488e7cc27082ae64869d
[project/procd.git] / initd / init.c
1 /*
2 * Copyright (C) 2013 Felix Fietkau <nbd@openwrt.org>
3 * Copyright (C) 2013 John Crispin <blogic@openwrt.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU Lesser General Public License version 2.1
7 * as published by the Free Software Foundation
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 */
14
15 #include <sys/wait.h>
16 #include <sys/types.h>
17 #include <sys/stat.h>
18 #include <sys/reboot.h>
19
20 #include <libubox/uloop.h>
21 #include <libubus.h>
22
23 #include <limits.h>
24 #include <stdlib.h>
25 #include <fcntl.h>
26 #include <getopt.h>
27 #include <libgen.h>
28 #include <regex.h>
29 #include <unistd.h>
30 #include <stdio.h>
31
32 #include "../utils/utils.h"
33 #include "init.h"
34 #include "../watchdog.h"
35
36 unsigned int debug = 0;
37
38 static void
39 signal_shutdown(int signal, siginfo_t *siginfo, void *data)
40 {
41 fprintf(stderr, "reboot\n");
42 fflush(stderr);
43 sync();
44 sleep(2);
45 reboot(RB_AUTOBOOT);
46 while (1)
47 ;
48 }
49
50 static struct sigaction sa_shutdown = {
51 .sa_sigaction = signal_shutdown,
52 .sa_flags = SA_SIGINFO
53 };
54
55 static void
56 cmdline(void)
57 {
58 char line[20];
59 char* res;
60 long r;
61
62 res = get_cmdline_val("init_debug", line, sizeof(line));
63 if (res != NULL) {
64 r = strtol(line, NULL, 10);
65 if ((r != LONG_MIN) && (r != LONG_MAX))
66 debug = (int) r;
67 }
68 }
69
70 int
71 main(int argc, char **argv)
72 {
73 pid_t pid;
74
75 sigaction(SIGTERM, &sa_shutdown, NULL);
76 sigaction(SIGUSR1, &sa_shutdown, NULL);
77 sigaction(SIGUSR2, &sa_shutdown, NULL);
78
79 early();
80 cmdline();
81 watchdog_init(1);
82
83 pid = fork();
84 if (!pid) {
85 char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };
86
87 if (debug < 3) {
88 int fd = open("/dev/null", O_RDWR);
89
90 if (fd > -1) {
91 dup2(fd, STDIN_FILENO);
92 dup2(fd, STDOUT_FILENO);
93 dup2(fd, STDERR_FILENO);
94 if (fd > STDERR_FILENO)
95 close(fd);
96 }
97 }
98 execvp(kmod[0], kmod);
99 ERROR("Failed to start kmodloader\n");
100 exit(-1);
101 }
102 if (pid <= 0) {
103 ERROR("Failed to start kmodloader instance\n");
104 } else {
105 int i;
106
107 for (i = 0; i < 120; i++) {
108 if (waitpid(pid, NULL, WNOHANG) > 0)
109 break;
110 sleep(1);
111 watchdog_ping();
112 }
113 }
114 uloop_init();
115 preinit();
116 uloop_run();
117
118 return 0;
119 }