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