service: initialize supplementary group ids
[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         ulog_open(ULOG_KMSG, LOG_DAEMON, "init");
76
77         sigaction(SIGTERM, &sa_shutdown, NULL);
78         sigaction(SIGUSR1, &sa_shutdown, NULL);
79         sigaction(SIGUSR2, &sa_shutdown, NULL);
80
81         early();
82         cmdline();
83         watchdog_init(1);
84
85         pid = fork();
86         if (!pid) {
87                 char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };
88
89                 if (debug < 3)
90                         patch_stdio("/dev/null");
91
92                 execvp(kmod[0], kmod);
93                 ERROR("Failed to start kmodloader: %m\n");
94                 exit(-1);
95         }
96         if (pid <= 0) {
97                 ERROR("Failed to start kmodloader instance: %m\n");
98         } else {
99                 int i;
100
101                 for (i = 0; i < 1200; i++) {
102                         if (waitpid(pid, NULL, WNOHANG) > 0)
103                                 break;
104                         usleep(10 * 1000);
105                         watchdog_ping();
106                 }
107         }
108         uloop_init();
109         preinit();
110         uloop_run();
111
112         return 0;
113 }