New shell-script-based init system

This commit is contained in:
K. Lange 2018-08-12 16:36:56 +09:00
parent 4dbade5b5a
commit 4fbfafc442
6 changed files with 76 additions and 53 deletions

View File

@ -1,9 +1,14 @@
#include <stdio.h> #include <dirent.h>
#include <syscall.h>
#include <errno.h> #include <errno.h>
#include <wait.h> #include <stdio.h>
#include <stdlib.h>
#include <string.h> #include <string.h>
#include <syscall.h>
#include <unistd.h> #include <unistd.h>
#include <wait.h>
#include <sys/wait.h>
#define INITD_PATH "/etc/init.d"
void set_console(void) { void set_console(void) {
int _stdin = syscall_open("/dev/ttyS0", 0, 0); int _stdin = syscall_open("/dev/ttyS0", 0, 0);
@ -19,22 +24,6 @@ void set_console(void) {
(void)_stdin; (void)_stdin;
} }
void set_hostname(void) {
FILE * f = fopen("/etc/hostname", "r");
if (!f) {
/* set fallback hostname */
sethostname("localhost", 4);
} else {
char tmp[128];
fgets(tmp, 128, f);
char * nl = strchr(tmp, '\n');
if (nl) *nl = '\0';
sethostname(tmp, strlen(tmp));
}
}
int start_options(char * args[]) { int start_options(char * args[]) {
int cpid = syscall_fork(); int cpid = syscall_fork();
if (!cpid) { if (!cpid) {
@ -47,36 +36,65 @@ int start_options(char * args[]) {
}; };
syscall_execve(args[0], args, _envp); syscall_execve(args[0], args, _envp);
syscall_exit(0); syscall_exit(0);
} else {
int pid = 0;
do {
pid = wait(NULL);
if (pid == cpid) {
break;
}
} while ((pid > 0) || (pid == -1 && errno == EINTR));
} }
syscall_reboot(); int pid = 0;
do {
pid = waitpid(-1, NULL, WNOKERN);
if (pid == -1 && errno == ECHILD) {
break;
}
if (pid == cpid) {
break;
}
} while ((pid > 0) || (pid == -1 && errno == EINTR));
return 0; return cpid;
} }
int main(int argc, char * argv[]) { int main(int argc, char * argv[]) {
/* Initialize stdin/out/err */
set_console(); set_console();
set_hostname();
if (argc > 1) { /* Get directory listing for /etc/init.d */
if (!strcmp(argv[1], "--vga")) { int initd_dir = syscall_open(INITD_PATH, 0, 0);
return start_options((char *[]){"/bin/terminal-vga","-l",NULL}); if (initd_dir < 0) {
} else if (!strcmp(argv[1], "--migrate")) { /* No init scripts; try to start getty as a fallback */
return start_options((char *[]){"/bin/migrate",NULL}); start_options((char *[]){"/bin/getty",NULL});
} else if (!strcmp(argv[1], "--headless")) { } else {
return start_options((char *[]){"/bin/getty",NULL}); int count = 0, i = 0, ret = 0;
} else {
/* Pass it to the compositor... */ /* Figure out how many entries we have with a dry run */
return start_options((char *[]){"/bin/compositor","--",argv[1],NULL}); do {
struct dirent ent;
ret = syscall_readdir(initd_dir, ++count, &ent);
} while (ret > 0);
/* Read each directory entry */
struct dirent entries[count];
do {
syscall_readdir(initd_dir, i, &entries[i]);
i++;
} while (i < count);
/* Sort the directory entries */
int comparator(const void * c1, const void * c2) {
const struct dirent * d1 = c1;
const struct dirent * d2 = c2;
return strcmp(d1->d_name, d2->d_name);
}
qsort(entries, count, sizeof(struct dirent), comparator);
/* Run scripts */
for (int i = 0; i < count; ++i) {
if (entries[i].d_name[0] != '.') {
char path[256];
sprintf(path, "/etc/init.d/%s", entries[i].d_name);
start_options((char *[]){path, NULL});
}
} }
} }
return start_options((char *[]){"/bin/compositor",NULL});
syscall_reboot();
return 0;
} }

View File

@ -222,16 +222,5 @@ int main(int argc, char * argv[]) {
free(tmp); free(tmp);
} }
TRACE_("Launching intended startup app...");
if (!strcmp(start, "--vga")) {
execvp("/bin/terminal-vga", (char *[]){"terminal-vga","-l",NULL});
} else if (!strcmp(start, "--headless")) {
execvp("/bin/getty", (char *[]){"getty",NULL});
} else if (start) {
execvp("/bin/compositor", (char *[]){"compositor","--",start,NULL});
} else {
execvp("/bin/compositor", (char *[]){"compositor",NULL});
}
return 0; return 0;
} }

3
base/etc/init.d/00_migrate.sh Executable file
View File

@ -0,0 +1,3 @@
#!/bin/sh
if kcmdline -q migrate then /bin/migrate

5
base/etc/init.d/01_hostname.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/sh
export-cmd HOSTNAME cat /etc/hostname
if empty? "$HOSTNAME" then exec hostname "localhost" else exec hostname "$HOSTNAME"

8
base/etc/init.d/99_runstart.sh Executable file
View File

@ -0,0 +1,8 @@
#!/bin/sh
export-cmd START kcmdline -g start
if equals? $START "--vga" then exec /bin/terminal-vga -l
if equals? $START "--headless" then exec /bin/getty
if empty? "$START" then exec /bin/compositor else exec /bin/compositor $START

View File

@ -41,7 +41,7 @@ EFI_HANDLE ImageHandleIn;
#define DEFAULT_VID_CMDLINE "vid=auto,1440,900 " #define DEFAULT_VID_CMDLINE "vid=auto,1440,900 "
#define DEFAULT_PRESET_VID_CMDLINE "vid=preset " #define DEFAULT_PRESET_VID_CMDLINE "vid=preset "
#define DEFAULT_NETINIT_CMDLINE "init=/dev/ram0 _" #define DEFAULT_NETINIT_CMDLINE "init=/dev/ram0 _"
#define MIGRATE_CMDLINE "start=--migrate _" #define MIGRATE_CMDLINE "migrate "
#define DEBUG_LOG_CMDLINE "logtoserial=warning " #define DEBUG_LOG_CMDLINE "logtoserial=warning "
#define DEBUG_SERIAL_CMDLINE "kdebug " #define DEBUG_SERIAL_CMDLINE "kdebug "
#define DEFAULT_HEADLESS_CMDLINE "start=--headless " #define DEFAULT_HEADLESS_CMDLINE "start=--headless "