1 /* febootstrap-supermin-helper reimplementation in C.
2 * Copyright (C) 2009-2010 Red Hat Inc.
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
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.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 /* This very minimal init "script" goes in the mini-initrd used to
20 * boot the ext2-based appliance. Note we have no shell, so we cannot
21 * use system(3) to run external commands. In fact, we don't have
22 * very much at all, except this program, insmod.static, and some
33 #include <sys/types.h>
34 #include <sys/mount.h>
38 /* Leave this enabled for now. When we get more confident in the boot
39 * process we can turn this off or make it configurable.
43 static void print_uptime (void);
44 static void insmod (const char *filename);
46 static char line[1024];
52 fprintf (stderr, "febootstrap: ext2 mini initrd starting up\n");
54 /* Create some fixed directories. */
56 mkdir ("/root", 0755);
61 fprintf (stderr, "febootstrap: mounting /sys\n");
62 if (mount ("sysfs", "/sys", "sysfs", 0, "") == -1) {
63 perror ("mount: /sys");
67 FILE *fp = fopen ("/modules", "r");
69 perror ("fopen: /modules");
72 while (fgets (line, sizeof line, fp)) {
73 size_t n = strlen (line);
74 if (n > 0 && line[n-1] == '\n')
80 /* Look for the ext2 filesystem device. It's always the last
82 * XXX More than 25 devices?
84 char path[] = "/sys/block/xdx/dev";
85 char class[3] = { 'v', 's', 'h' };
88 for (i = 0; i < sizeof class; ++i) {
89 for (j = 'z'; j >= 'a'; --j) {
92 fp = fopen (path, "r");
98 "febootstrap: no ext2 root device found\n"
99 "Please include FULL verbose output in your bug report.\n");
104 fprintf (stderr, "febootstrap: picked %s as root device\n", path);
106 fgets (line, sizeof line, fp);
107 int major = atoi (line);
108 char *p = line + strcspn (line, ":") + 1;
109 int minor = atoi (p);
112 if (umount ("/sys") == -1) {
113 perror ("umount: /sys");
118 fprintf (stderr, "febootstrap: creating /dev/root as block special %d:%d\n",
121 if (mknod ("/dev/root", S_IFBLK|0700, makedev (major, minor)) == -1) {
122 perror ("mknod: /dev/root");
126 /* Mount new root and chroot to it. */
128 fprintf (stderr, "febootstrap: mounting new root on /root\n");
129 if (mount ("/dev/root", "/root", "ext2", MS_NOATIME, "") == -1) {
130 perror ("mount: /root");
134 /* Note that pivot_root won't work. See the note in
135 * Documentation/filesystems/ramfs-rootfs-initramfs.txt
136 * We could remove the old initramfs files, but let's not bother.
139 fprintf (stderr, "febootstrap: chroot\n");
141 if (chroot ("/root") == -1) {
142 perror ("chroot: /root");
148 /* Run /init from ext2 filesystem. */
150 execl ("/init", "init", NULL);
151 perror ("execl: /init");
156 insmod (const char *filename)
159 fprintf (stderr, "febootstrap: insmod %s\n", filename);
163 perror ("insmod: fork");
167 if (pid == 0) { /* Child. */
168 execl ("/insmod.static", "insmod.static", filename, NULL);
169 perror ("insmod: execl");
170 _exit (EXIT_FAILURE);
175 if (wait (&status) == -1 ||
176 WEXITSTATUS (status) != 0)
177 perror ("insmod: wait");
178 /* but ignore the error, some will be because the device is not found */
181 /* Print contents of /proc/uptime. */
185 FILE *fp = fopen ("/proc/uptime", "r");
187 perror ("/proc/uptime");
191 fgets (line, sizeof line, fp);
194 fprintf (stderr, "febootstrap: uptime: %s", line);