• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/procd/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 #if defined(WITH_SELINUX)
 33 #include <selinux/selinux.h>
 34 #include <selinux/restorecon.h>
 35 #include <selinux/avc.h>
 36 #endif
 37 
 38 #include "../utils/utils.h"
 39 #include "init.h"
 40 #include "../watchdog.h"
 41 
 42 unsigned int debug = 0;
 43 
 44 static void
 45 signal_shutdown(int signal, siginfo_t *siginfo, void *data)
 46 {
 47         fprintf(stderr, "reboot\n");
 48         fflush(stderr);
 49         sync();
 50         sleep(2);
 51         reboot(RB_AUTOBOOT);
 52         while (1)
 53                 ;
 54 }
 55 
 56 static struct sigaction sa_shutdown = {
 57         .sa_sigaction = signal_shutdown,
 58         .sa_flags = SA_SIGINFO
 59 };
 60 
 61 static void
 62 cmdline(void)
 63 {
 64         char line[20];
 65         char* res;
 66         long    r;
 67 
 68         res = get_cmdline_val("init_debug", line, sizeof(line));
 69         if (res != NULL) {
 70                 r = strtol(line, NULL, 10);
 71                 if ((r != LONG_MIN) && (r != LONG_MAX))
 72                         debug = (int) r;
 73         }
 74 }
 75 
 76 #if defined(WITH_SELINUX)
 77 static int
 78 selinux(char **argv)
 79 {
 80         int ret;
 81         int enforce = selinux_status_getenforce();
 82 
 83         /* is SELinux already initialized? */
 84         if (getenv("SELINUX_INIT")) {
 85                 /* have initramfs permissions already been restored? */
 86                 if (!getenv("INITRAMFS") || getenv("SELINUX_RESTORECON")) {
 87                         unsetenv("SELINUX_INIT");
 88                         unsetenv("SELINUX_RESTORECON");
 89                         return 0;
 90                 }
 91                 /* Second call (initramfs only): restore filesystem labels */
 92                 const char *exclude_list[] = { "/dev/console", "/proc", "/sys", 0 };
 93                 selinux_restorecon_set_exclude_list(exclude_list);
 94                 ret = selinux_restorecon("/", SELINUX_RESTORECON_RECURSE | SELINUX_RESTORECON_MASS_RELABEL);
 95                 putenv("SELINUX_RESTORECON=1");
 96         } else {
 97                 /* First call: load policy */
 98                 ret = selinux_init_load_policy(&enforce);
 99                 putenv("SELINUX_INIT=1");
100         }
101 
102         if (ret == 0)
103                 execv(argv[0], argv);
104 
105         if (enforce > 0) {
106                 fprintf(stderr, "Cannot load SELinux policy, but system in enforcing mode. Halting.\n");
107                 return 1;
108         }
109 
110         return 0;
111 }
112 #else
113 static int
114 selinux(char **argv)
115 {
116         return 0;
117 }
118 #endif
119 
120 int
121 main(int argc, char **argv)
122 {
123         pid_t pid;
124 
125         ulog_open(ULOG_KMSG, LOG_DAEMON, "init");
126 
127         sigaction(SIGTERM, &sa_shutdown, NULL);
128         sigaction(SIGUSR1, &sa_shutdown, NULL);
129         sigaction(SIGUSR2, &sa_shutdown, NULL);
130         sigaction(SIGPWR, &sa_shutdown, NULL);
131 
132         if (selinux(argv))
133                 exit(-1);
134         early();
135         cmdline();
136         watchdog_init(1);
137 
138         pid = fork();
139         if (!pid) {
140                 char *kmod[] = { "/sbin/kmodloader", "/etc/modules-boot.d/", NULL };
141 
142                 if (debug < 3)
143                         patch_stdio("/dev/null");
144 
145                 execvp(kmod[0], kmod);
146                 ERROR("Failed to start kmodloader: %m\n");
147                 exit(EXIT_FAILURE);
148         }
149         if (pid <= 0) {
150                 ERROR("Failed to start kmodloader instance: %m\n");
151         } else {
152                 const struct timespec req = {0, 10 * 1000 * 1000};
153                 int i;
154 
155                 for (i = 0; i < 1200; i++) {
156                         if (waitpid(pid, NULL, WNOHANG) > 0)
157                                 break;
158                         nanosleep(&req, NULL);
159                         watchdog_ping();
160                 }
161         }
162         uloop_init();
163         preinit();
164         uloop_run();
165 
166         return 0;
167 }
168 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt