spawn udevd & Co from 1st stage init
This commit is contained in:
parent
85b34d353b
commit
419b4c1201
271
init.c
271
init.c
@ -19,11 +19,18 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef INIT_HEADERS
|
#include <errno.h>
|
||||||
#include "init-libc-headers.h"
|
#include <string.h>
|
||||||
#else
|
#include <stdlib.h>
|
||||||
#include INIT_HEADERS
|
#include <stdio.h>
|
||||||
#endif
|
#include <unistd.h>
|
||||||
|
#include <dirent.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <sys/klog.h>
|
||||||
|
#include <sys/mount.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/vfs.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
#include "config-stage1.h"
|
#include "config-stage1.h"
|
||||||
|
|
||||||
@ -31,9 +38,13 @@
|
|||||||
#define TIOCSCTTY 0x540
|
#define TIOCSCTTY 0x540
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define MKDEV(ma,mi) ((ma)<<8 | (mi))
|
||||||
|
#define RAMFS_MAGIC 0x858458f6
|
||||||
|
#define TMPFS_MAGIC 0x01021994
|
||||||
|
|
||||||
char * env[] = {
|
char * env[] = {
|
||||||
"PATH=/usr/bin:/bin:/sbin:/usr/sbin:/usr/X11R6/bin",
|
"PATH=/usr/bin:/bin:/sbin:/usr/sbin",
|
||||||
"LD_LIBRARY_PATH=/lib:/usr/lib:/usr/X11R6/lib",
|
"LD_LIBRARY_PATH=/lib:/usr/lib",
|
||||||
"HOME=/",
|
"HOME=/",
|
||||||
"TERM=linux",
|
"TERM=linux",
|
||||||
"TERMINFO=/etc/terminfo",
|
"TERMINFO=/etc/terminfo",
|
||||||
@ -42,6 +53,11 @@ char * env[] = {
|
|||||||
|
|
||||||
char ** myenv = NULL;
|
char ** myenv = NULL;
|
||||||
|
|
||||||
|
char *stage[] = {"/sbin/stage1", NULL};
|
||||||
|
char *udevd[] = {"/sbin/udevd", NULL};
|
||||||
|
char *udevtrigger[] = {"/sbin/udevtrigger", NULL};
|
||||||
|
char *udevsettle[] = {"/sbin/udevsettle", NULL};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this needs to handle the following cases:
|
* this needs to handle the following cases:
|
||||||
*
|
*
|
||||||
@ -51,21 +67,14 @@ char ** myenv = NULL;
|
|||||||
* 4) run from a floppy that's been loaded into a ramdisk
|
* 4) run from a floppy that's been loaded into a ramdisk
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int klog_pid;
|
void fatal(const char *msg)
|
||||||
|
|
||||||
|
|
||||||
void fatal_error(const char *msg)
|
|
||||||
{
|
{
|
||||||
printf("FATAL ERROR IN INIT: %s : %s\n\nI can't recover from this, please reboot manually and send bugreport.\n", msg,strerror(errno));
|
printf("FATAL ERROR IN INIT: %s\nI can't recover from this,"
|
||||||
|
"please reboot manually and send bugreport.\n", msg);
|
||||||
while (1);
|
while (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void print_error(char *msg)
|
void warn(char *msg)
|
||||||
{
|
|
||||||
printf("E: %s\n", msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
void print_warning(char *msg)
|
|
||||||
{
|
{
|
||||||
printf("W: %s\n", msg);
|
printf("W: %s\n", msg);
|
||||||
}
|
}
|
||||||
@ -74,52 +83,50 @@ void print_warning(char *msg)
|
|||||||
* (1) watch /proc/kmsg and copy the stuff to /dev/tty4
|
* (1) watch /proc/kmsg and copy the stuff to /dev/tty4
|
||||||
* (2) listens to /dev/log and copy also this stuff (log from programs)
|
* (2) listens to /dev/log and copy also this stuff (log from programs)
|
||||||
*/
|
*/
|
||||||
void doklog()
|
pid_t doklog()
|
||||||
{
|
{
|
||||||
int in, out, i, ii;
|
int in, out, i, ii;
|
||||||
int log;
|
pid_t pid;
|
||||||
char buf[1024];
|
char buf[1024];
|
||||||
|
|
||||||
/* open kernel message logger */
|
/* open kernel message logger */
|
||||||
in = open("/proc/kmsg", O_RDONLY,0);
|
if ((in = open("/proc/kmsg", O_RDONLY, 0)) < 0)
|
||||||
if (in < 0) {
|
fatal("failed to open /proc/kmsg");
|
||||||
print_error("could not open /proc/kmsg");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((log = open("/tmp/syslog", O_WRONLY | O_CREAT, 0644)) < 0) {
|
if (mknod("/dev/tty4", S_IFCHR, MKDEV(4, 4)) < 0 ||
|
||||||
perror("/tmp/syslog");
|
(out = open("/dev/tty4", O_WRONLY, 0)) < 0)
|
||||||
print_error("error opening /tmp/syslog");
|
fatal("failed to open /dev/tty4");
|
||||||
sleep(5);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((klog_pid = fork())) {
|
if ((pid = fork())) {
|
||||||
|
if (pid < 0) fatal("doklog");
|
||||||
close(in);
|
close(in);
|
||||||
close(log);
|
close(out);
|
||||||
return;
|
return pid;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
|
/* child */
|
||||||
close(0);
|
close(0);
|
||||||
close(1);
|
close(1);
|
||||||
close(2);
|
close(2);
|
||||||
}
|
|
||||||
|
|
||||||
out = open("/dev/tty4", O_WRONLY, 0);
|
|
||||||
if (out < 0) {
|
|
||||||
perror("can't open /dev/tty4");
|
|
||||||
print_warning("couldn't open tty for syslog -- still using /tmp/syslog\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* disable on-console syslog output */
|
/* disable on-console syslog output */
|
||||||
syslog(8, NULL, 1);
|
klogctl(8, NULL, 1);
|
||||||
|
|
||||||
while (1) {
|
while (1)
|
||||||
i = read(in, buf, sizeof(buf));
|
if ((i = read(in, buf, sizeof(buf))) > 0)
|
||||||
if (i > 0) {
|
|
||||||
if (out >= 0)
|
|
||||||
ii = write(out, buf, i);
|
ii = write(out, buf, i);
|
||||||
ii = write(log, buf, i);
|
}
|
||||||
}
|
|
||||||
|
pid_t spawn(char *av[])
|
||||||
|
{
|
||||||
|
pid_t pid;
|
||||||
|
if ((pid = fork())) {
|
||||||
|
if (pid < 0) fatal(av[0]);
|
||||||
|
return pid;
|
||||||
|
} else {
|
||||||
|
execve(av[0], av, env);
|
||||||
|
perror(av[0]);
|
||||||
|
exit(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +138,7 @@ void grab_env(int fd)
|
|||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((i = read(fd, buf, sizeof(buf))) < 0) {
|
if ((i = read(fd, buf, sizeof(buf))) < 0) {
|
||||||
print_error("failed to read env from pipe");
|
warn("failed to read env from pipe");
|
||||||
myenv = env;
|
myenv = env;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -140,7 +147,7 @@ void grab_env(int fd)
|
|||||||
buf[i] = '\0';
|
buf[i] = '\0';
|
||||||
|
|
||||||
if ((ep = myenv = malloc(sizeof(char *) * 32)) == NULL) {
|
if ((ep = myenv = malloc(sizeof(char *) * 32)) == NULL) {
|
||||||
print_error("can't malloc env");
|
warn("can't malloc env");
|
||||||
myenv = env;
|
myenv = env;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -252,7 +259,7 @@ static int nuke(const char *what)
|
|||||||
|
|
||||||
if ( err ) {
|
if ( err ) {
|
||||||
errno = err;
|
errno = err;
|
||||||
fatal_error(what);
|
fatal(what);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -279,7 +286,7 @@ void unmount_filesystems(void)
|
|||||||
|
|
||||||
fd = open("/proc/mounts", O_RDONLY, 0);
|
fd = open("/proc/mounts", O_RDONLY, 0);
|
||||||
if (fd < 1) {
|
if (fd < 1) {
|
||||||
print_error("failed to open /proc/mounts");
|
warn("failed to open /proc/mounts");
|
||||||
sleep(2);
|
sleep(2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -332,66 +339,89 @@ void unmount_filesystems(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nb) {
|
if (nb) {
|
||||||
printf("failed to umount some filesystems\n");
|
fatal("failed to umount some filesystems\n");
|
||||||
while (1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MAJOR(dev) ((dev)>>8)
|
|
||||||
#define MINOR(dev) ((dev) & 0xff)
|
|
||||||
#define MKDEV(ma,mi) ((ma)<<8 | (mi))
|
|
||||||
|
|
||||||
#define DEV_PERM 00400|00200|00040|00020
|
|
||||||
#define CHR_DEV 0020000|DEV_PERM
|
|
||||||
#define BLK_DEV 0060000|DEV_PERM
|
|
||||||
|
|
||||||
#define RAMFS_MAGIC 0x858458f6
|
|
||||||
#define TMPFS_MAGIC 0x01021994
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
struct stat rst, cst, ist;
|
struct stat rst, cst, ist;
|
||||||
struct statfs sfs;
|
struct statfs sfs;
|
||||||
pid_t installpid, childpid;
|
pid_t pid, klogpid, udevpid;
|
||||||
int wait_status;
|
int wait_status;
|
||||||
int fd;
|
int fd = -1;
|
||||||
int fds[2];
|
int fds[2];
|
||||||
int end_stage1 = 0;
|
|
||||||
|
|
||||||
if (mount("/proc", "/proc", "proc", 0, NULL))
|
if (mount("/proc", "/proc", "proc", 0, NULL))
|
||||||
fatal_error("Unable to mount proc filesystem");
|
fatal("failed to mount proc filesystem");
|
||||||
if (mount("/sysfs", "/sys", "sysfs", 0, NULL))
|
if (mount("sysfs", "/sys", "sysfs", 0, NULL))
|
||||||
fatal_error("Unable to mount sysfs filesystem");
|
fatal("failed to mount sysfs filesystem");
|
||||||
|
if (mount("udev", "/dev", "tmpfs", 0, "size=10M,mode=0755"))
|
||||||
|
fatal("failed to mount tmpfs filesystem");
|
||||||
|
|
||||||
/* ignore Control-C and keyboard stop signals */
|
/* ignore Control-C and keyboard stop signals */
|
||||||
signal(SIGINT, SIG_IGN);
|
signal(SIGINT, SIG_IGN);
|
||||||
signal(SIGTSTP, SIG_IGN);
|
signal(SIGTSTP, SIG_IGN);
|
||||||
|
|
||||||
fd = open("/dev/console", O_RDWR, 0);
|
if (mknod("/dev/console", S_IFCHR, MKDEV(5, 1)) < 0 ||
|
||||||
if (fd < 0)
|
(fd = open("/dev/console", O_RDWR, 0)) < 0) {
|
||||||
fatal_error("failed to open /dev/console");
|
fatal("failed to open /dev/console");
|
||||||
|
}
|
||||||
|
|
||||||
dup2(fd, 0);
|
dup2(fd, 0);
|
||||||
dup2(fd, 1);
|
dup2(fd, 1);
|
||||||
dup2(fd, 2);
|
dup2(fd, 2);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
if (mknod("/dev/null", S_IFCHR, MKDEV(1, 3)) < 0)
|
||||||
|
fatal("failed to create /dev/null");
|
||||||
|
|
||||||
/* I set me up as session leader (probably not necessary?) */
|
/* I set me up as session leader (probably not necessary?) */
|
||||||
setsid();
|
setsid();
|
||||||
if (ioctl(0, TIOCSCTTY, NULL)) {
|
if (ioctl(0, TIOCSCTTY, NULL)) {
|
||||||
perror("TIOCSCTTY");
|
perror("TIOCSCTTY");
|
||||||
print_error("could not set new controlling tty");
|
warn("could not set new controlling tty");
|
||||||
}
|
}
|
||||||
|
|
||||||
char my_hostname[] = "localhost.localdomain";
|
if (sethostname("localhost.localdomain", sizeof("localhost.localdomain")) < 0)
|
||||||
if (sethostname(my_hostname, sizeof(my_hostname)) < 0)
|
warn("could not set hostname");
|
||||||
print_error("could not set hostname");
|
|
||||||
|
|
||||||
/* the default domainname (as of 2.0.35) is "(none)", which confuses glibc */
|
/* the default domainname (as of 2.0.35) is "(none)", which confuses glibc */
|
||||||
if (setdomainname("", 0) < 0)
|
if (setdomainname("", 0) < 0)
|
||||||
print_error("could not set domainname");
|
warn("could not set domainname");
|
||||||
|
|
||||||
doklog();
|
if (mkdir("/dev/.initramfs", 0755) < 0 ||
|
||||||
|
mkdir("/dev/pts", 0755) < 0 ||
|
||||||
|
mkdir("/dev/shm", 0755) < 0)
|
||||||
|
fatal("mkdir\n");
|
||||||
|
|
||||||
|
if ((fd = open("/proc/sys/kernel/hotplug", O_WRONLY, 0)) < 0 ||
|
||||||
|
write(fd, "\n", sizeof("\n")) < sizeof("\n"))
|
||||||
|
fatal("/proc/sys/kernel/hotplug\n");
|
||||||
|
close(fd);
|
||||||
|
|
||||||
|
klogpid = doklog();
|
||||||
|
|
||||||
|
if (mkdir("/dev/.udev", 0755) < 0 ||
|
||||||
|
mkdir("/dev/.udev/db", 0755) < 0)
|
||||||
|
fatal("/dev/.udev/db");
|
||||||
|
|
||||||
|
printf("Spawning udevd...");
|
||||||
|
|
||||||
|
udevpid = spawn(udevd);
|
||||||
|
|
||||||
|
if (mkdir("/dev/.udev/queue", 0755) < 0 && errno != EEXIST)
|
||||||
|
fatal("cannot create /dev/.udev/queue");
|
||||||
|
|
||||||
|
if (waitpid(spawn(udevtrigger), &wait_status, 0) < 0 ||
|
||||||
|
!(WIFEXITED(wait_status)))
|
||||||
|
warn("udevtrigger");
|
||||||
|
|
||||||
|
if (waitpid(spawn(udevsettle), &wait_status, 0) < 0 ||
|
||||||
|
!(WIFEXITED(wait_status)))
|
||||||
|
warn("udevsettle");
|
||||||
|
|
||||||
|
printf("done\n");
|
||||||
|
|
||||||
/* Go into normal init mode - keep going, and then do a orderly shutdown
|
/* Go into normal init mode - keep going, and then do a orderly shutdown
|
||||||
when:
|
when:
|
||||||
@ -404,33 +434,19 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
/* create a pipe for env passing */
|
/* create a pipe for env passing */
|
||||||
if (pipe(fds) < 0)
|
if (pipe(fds) < 0)
|
||||||
fatal_error("failed to create env pipe");
|
fatal("failed to create env pipe");
|
||||||
|
|
||||||
fcntl(fds[0], F_SETFD, 1);
|
fcntl(fds[0], F_SETFD, 1);
|
||||||
fcntl(fds[1], F_SETFD, 0);
|
fcntl(fds[1], F_SETFD, 0);
|
||||||
|
|
||||||
if (!(installpid = fork())) {
|
pid = spawn(stage);
|
||||||
/* child */
|
|
||||||
char * child_argv[2];
|
|
||||||
child_argv[0] = "/sbin/stage1";
|
|
||||||
child_argv[1] = NULL;
|
|
||||||
execve(child_argv[0], child_argv, env);
|
|
||||||
printf("error in exec of stage1 :-(\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
close(fds[1]);
|
close(fds[1]);
|
||||||
|
while (pid != wait(&wait_status));
|
||||||
while (!end_stage1) {
|
|
||||||
childpid = wait4(-1, &wait_status, 0, NULL);
|
|
||||||
if (childpid == installpid)
|
|
||||||
end_stage1 = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!(WIFEXITED(wait_status))) {
|
if (!(WIFEXITED(wait_status))) {
|
||||||
/* something went wrong */
|
/* something went wrong */
|
||||||
|
|
||||||
printf("wait_status: %i, install exited abnormally :-( ", wait_status);
|
printf("wait_status: %i, install exited abnormally ", wait_status);
|
||||||
if (WIFSIGNALED(wait_status))
|
if (WIFSIGNALED(wait_status))
|
||||||
printf("-- received signal %d", WTERMSIG(wait_status));
|
printf("-- received signal %d", WTERMSIG(wait_status));
|
||||||
printf("\n");
|
printf("\n");
|
||||||
@ -455,15 +471,23 @@ int main(int argc, char **argv)
|
|||||||
|
|
||||||
grab_env(fds[0]);
|
grab_env(fds[0]);
|
||||||
|
|
||||||
kill(klog_pid, 9);
|
if (waitpid(spawn(udevsettle), &wait_status, 0) < 0 ||
|
||||||
waitpid(klog_pid, &wait_status, 0);
|
!(WIFEXITED(wait_status)))
|
||||||
|
warn("udevsettle");
|
||||||
|
|
||||||
|
kill(udevpid, 9);
|
||||||
|
waitpid(udevpid, &wait_status, 0);
|
||||||
|
nuke_dir("/dev/.udev/queue");
|
||||||
|
|
||||||
|
kill(klogpid, 9);
|
||||||
|
waitpid(klogpid, &wait_status, 0);
|
||||||
|
|
||||||
printf("Spawning init ...");
|
printf("Spawning init ...");
|
||||||
|
|
||||||
/* rest was seamlessy stolen from klibc */
|
/* rest was seamlessy stolen from klibc */
|
||||||
/* First, change to the new root directory */
|
/* First, change to the new root directory */
|
||||||
if (chdir(STAGE2_LOCATION))
|
if (chdir(STAGE2_LOCATION))
|
||||||
fatal_error("chdir to new root");
|
fatal("chdir to new root");
|
||||||
|
|
||||||
/* This is a potentially highly destructive program. Take some
|
/* This is a potentially highly destructive program. Take some
|
||||||
extra precautions. */
|
extra precautions. */
|
||||||
@ -471,71 +495,66 @@ int main(int argc, char **argv)
|
|||||||
/* Make sure the current directory is not on the same filesystem
|
/* Make sure the current directory is not on the same filesystem
|
||||||
as the root directory */
|
as the root directory */
|
||||||
if ( stat("/", &rst) || stat(".", &cst) )
|
if ( stat("/", &rst) || stat(".", &cst) )
|
||||||
fatal_error("stat");
|
fatal("stat");
|
||||||
|
|
||||||
if ( rst.st_dev == cst.st_dev )
|
if ( rst.st_dev == cst.st_dev )
|
||||||
fatal_error("current directory on the same filesystem as the root");
|
fatal("current directory on the same filesystem as the root");
|
||||||
|
|
||||||
/* The initramfs should have /init */
|
/* The initramfs should have /init */
|
||||||
if ( stat("/init", &ist) || !S_ISREG(ist.st_mode) )
|
if ( stat("/init", &ist) || !S_ISREG(ist.st_mode) )
|
||||||
fatal_error("can't find /init on initramfs");
|
fatal("can't find /init on initramfs");
|
||||||
|
|
||||||
/* Make sure we're on a ramfs */
|
/* Make sure we're on a ramfs */
|
||||||
if ( statfs("/", &sfs) )
|
if ( statfs("/", &sfs) )
|
||||||
fatal_error("statfs /");
|
fatal("statfs /");
|
||||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
||||||
fatal_error("rootfs not a ramfs or tmpfs");
|
fatal("rootfs not a ramfs or tmpfs");
|
||||||
|
|
||||||
/* Okay, I think we should be safe... */
|
/* Okay, I think we should be safe... */
|
||||||
|
|
||||||
/* overmount image under new root if needed */
|
/* overmount image under new root if needed */
|
||||||
if ( statfs(IMAGE_LOCATION, &sfs) )
|
if ( statfs(IMAGE_LOCATION, &sfs) )
|
||||||
fatal_error("statfs "IMAGE_LOCATION);
|
fatal("statfs "IMAGE_LOCATION);
|
||||||
/* if something is mounted under IMAGE_LOCATION ? */
|
/* if something is mounted under IMAGE_LOCATION ? */
|
||||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC ) {
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC ) {
|
||||||
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION, NULL, MS_MOVE, NULL) )
|
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION, NULL, MS_MOVE, NULL) )
|
||||||
fatal_error("overmounting image location");
|
fatal("overmounting image location");
|
||||||
/* test for nested mount: disk or nfs with iso image */
|
/* test for nested mount: disk or nfs with iso image */
|
||||||
if ( statfs(IMAGE_LOCATION, &sfs) )
|
if ( statfs(IMAGE_LOCATION, &sfs) )
|
||||||
fatal_error("nested statfs "IMAGE_LOCATION);
|
fatal("nested statfs "IMAGE_LOCATION);
|
||||||
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
if ( sfs.f_type != RAMFS_MAGIC && sfs.f_type != TMPFS_MAGIC )
|
||||||
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION "/isolinux", NULL, MS_MOVE, NULL) )
|
if ( mount(IMAGE_LOCATION, "." IMAGE_LOCATION "/isolinux", NULL, MS_MOVE, NULL) )
|
||||||
fatal_error("overmounting nested image location");
|
fatal("overmounting nested image location");
|
||||||
}
|
}
|
||||||
|
|
||||||
umount("/sys");
|
umount("/sys");
|
||||||
umount("/proc/bus/usb");
|
umount("/proc/bus/usb");
|
||||||
umount("/proc");
|
umount("/proc");
|
||||||
|
|
||||||
|
if (mount("/dev", "./dev", NULL, MS_MOVE, NULL))
|
||||||
|
fatal("overmounting /dev");
|
||||||
|
|
||||||
/* Delete rootfs contents */
|
/* Delete rootfs contents */
|
||||||
if ( nuke_dir("/") )
|
if (nuke_dir("/"))
|
||||||
fatal_error("nuking initramfs contents");
|
fatal("nuking initramfs contents");
|
||||||
|
|
||||||
/* Overmount the root */
|
/* Overmount the root */
|
||||||
if ( mount(".", "/", NULL, MS_MOVE, NULL) )
|
if (mount(".", "/", NULL, MS_MOVE, NULL))
|
||||||
fatal_error("overmounting root");
|
fatal("overmounting root");
|
||||||
|
|
||||||
/* chroot, chdir */
|
/* chroot, chdir */
|
||||||
if (chroot(".") || chdir("/"))
|
if (chroot(".") || chdir("/"))
|
||||||
fatal_error("chroot");
|
fatal("chroot");
|
||||||
|
|
||||||
/* Open /dev/console */
|
|
||||||
if ((fd = open("/dev/console", O_RDWR)) != -1) {
|
|
||||||
dup2(fd, 0);
|
|
||||||
dup2(fd, 1);
|
|
||||||
dup2(fd, 2);
|
|
||||||
close(fd);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for given init */
|
/* Check for given init */
|
||||||
if (stat(STAGE2_BINNAME, &ist) || !S_ISREG(ist.st_mode))
|
if (stat(STAGE2_BINNAME, &ist) || !S_ISREG(ist.st_mode))
|
||||||
fatal_error("can't find init on root fs");
|
fatal("can't find init on root fs");
|
||||||
|
|
||||||
/* Spawn init */
|
/* Spawn init */
|
||||||
printf(" done.\n");
|
printf(" done.\n");
|
||||||
|
|
||||||
argv[0] = STAGE2_BINNAME;
|
argv[0] = STAGE2_BINNAME;
|
||||||
execve(argv[0], argv, myenv);
|
execve(argv[0], argv, myenv);
|
||||||
fatal_error("stage2"); /* Failed to spawn init */
|
fatal("stage2"); /* Failed to spawn init */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user