summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHilko Bengen <bengen@hilluzination.de>2011-06-01 00:43:10 +0200
committerRichard W.M. Jones <rjones@redhat.com>2011-06-01 10:28:06 +0100
commitef6f7db3e1ed2e0d09e02ac77be70848c221f3df (patch)
treeb85e06a71a9061c13312aa5645d7fde86afcdef2
parentddbfd96c3d21d05170a0af7de427c3dcbd72f014 (diff)
downloadfebootstrap-ef6f7db3e1ed2e0d09e02ac77be70848c221f3df.tar.gz
febootstrap-ef6f7db3e1ed2e0d09e02ac77be70848c221f3df.tar.xz
febootstrap-ef6f7db3e1ed2e0d09e02ac77be70848c221f3df.zip
Don't require external insmod.static.
Add module loading functionality into init.c, thus making insmod.static unnecessary.
-rw-r--r--README5
-rw-r--r--configure.ac15
-rw-r--r--helper/ext2initrd.c9
-rw-r--r--helper/init.c67
4 files changed, 42 insertions, 54 deletions
diff --git a/README b/README
index 8092aaf..99c4d36 100644
--- a/README
+++ b/README
@@ -39,11 +39,6 @@ Requirements
/sbin/mke2fs
- These are part of e2fsprogs.
- /sbin/insmod.static
- - This is part of module-init-tools. Note that Debian does NOT
- package this, you have to build it yourself (or copy the file
- from a Fedora machine which also works ...)
-
For Fedora/RHEL:
rpm
diff --git a/configure.ac b/configure.ac
index 7606bca..ecd6b1e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -68,21 +68,6 @@ dnl For ArchLinux handler.
AC_CHECK_PROG(PACMAN,[pacman],[pacman],[no])
dnl Required programs, libraries.
-AC_PATH_PROG([INSMODSTATIC],[insmod.static],[no],
- [$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR])
-if test "x$INSMODSTATIC" = "xno" ; then
- AC_MSG_FAILURE([insmod.static program not found
-
-Is /sbin in your current path?
-
-Note that Debian/Ubuntu do not package this file from module-init-tools.
-Sorry, please fix your distribution. In the meantime you can copy
-/sbin/insmod.static from a Fedora machine.
-])
-fi
-AC_DEFINE_UNQUOTED([INSMODSTATIC],["$INSMODSTATIC"],
- [Full path to the insmod.static program.])
-
AC_PATH_PROG([MKE2FS],[mke2fs],[no],
[$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR])
if test "x$MKE2FS" = "xno" ; then
diff --git a/helper/ext2initrd.c b/helper/ext2initrd.c
index 3d765ca..17af3bd 100644
--- a/helper/ext2initrd.c
+++ b/helper/ext2initrd.c
@@ -155,15 +155,6 @@ ext2_make_initrd (const char *modpath, const char *initrd)
free (cmd);
free_module_deps ();
- /* Copy in insmod static binary. */
- cmd = xasprintf ("cp %s %s", INSMODSTATIC, dir);
- if (verbose >= 2) fprintf (stderr, "%s\n", cmd);
- r = system (cmd);
- if (r == -1 || WEXITSTATUS (r) != 0)
- error (EXIT_FAILURE, 0,
- "ext2_make_initrd: copy %s failed", INSMODSTATIC);
- free (cmd);
-
/* Copy in the init program, linked into this program as a data blob. */
char *init = xasprintf ("%s/init", dir);
int fd = open (init, O_WRONLY|O_TRUNC|O_CREAT|O_NOCTTY, 0755);
diff --git a/helper/init.c b/helper/init.c
index 7b6b94e..8690f22 100644
--- a/helper/init.c
+++ b/helper/init.c
@@ -19,8 +19,7 @@
/* This very minimal init "script" goes in the mini-initrd used to
* boot the ext2-based appliance. Note we have no shell, so we cannot
* use system(3) to run external commands. In fact, we don't have
- * very much at all, except this program, insmod.static, and some
- * kernel modules.
+ * very much at all, except this program, and some kernel modules.
*/
#include <config.h>
@@ -30,12 +29,17 @@
#include <string.h>
#include <unistd.h>
#include <errno.h>
+#include <fcntl.h>
#include <dirent.h>
#include <sys/types.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/wait.h>
+#include <asm/unistd.h>
+
+extern long init_module (void *, unsigned long, const char *);
+
/* Leave this enabled for now. When we get more confident in the boot
* process we can turn this off or make it configurable.
*/
@@ -66,12 +70,6 @@ main ()
exit (EXIT_FAILURE);
}
- /* A perennial problem is that /sbin/insmod.static is not
- * executable. Just make it executable. It's easier than fixing
- * everyone's distro.
- */
- chmod ("/sbin/insmod.static", 0755);
-
FILE *fp = fopen ("/modules", "r");
if (fp == NULL) {
perror ("fopen: /modules");
@@ -81,7 +79,16 @@ main ()
size_t n = strlen (line);
if (n > 0 && line[n-1] == '\n')
line[--n] = '\0';
- insmod (line);
+
+ /* XXX Because of the way we construct the module list, the
+ * "modules" file can contain non-existent modules. Ignore those
+ * for now. Really we should add them as missing dependencies.
+ * See ext2initrd.c:ext2_make_initrd().
+ */
+ if (access (line, R_OK) == 0)
+ insmod (line);
+ else
+ fprintf (stderr, "skipped %s, module is missing\n", line);
}
fclose (fp);
@@ -175,26 +182,36 @@ static void
insmod (const char *filename)
{
if (verbose)
- fprintf (stderr, "febootstrap: insmod %s\n", filename);
+ fprintf (stderr, "febootstrap: internal insmod %s\n", filename);
- pid_t pid = fork ();
- if (pid == -1) {
- perror ("insmod: fork");
+ int fd = open (filename, O_RDONLY);
+ if (fd == -1) {
+ fprintf (stderr, "insmod: open: %s: %m\n", filename);
exit (EXIT_FAILURE);
}
-
- if (pid == 0) { /* Child. */
- execl ("/insmod.static", "insmod.static", filename, NULL);
- perror ("insmod: execl");
- _exit (EXIT_FAILURE);
+ struct stat st;
+ if (fstat (fd, &st) == -1) {
+ perror ("insmod: fstat");
+ exit (EXIT_FAILURE);
+ }
+ char buf[st.st_size];
+ long offset = 0;
+ do {
+ long rc = read (fd, buf + offset, st.st_size - offset);
+ if (rc == -1) {
+ perror ("insmod: read");
+ exit (EXIT_FAILURE);
+ }
+ offset += rc;
+ } while (offset < st.st_size);
+ close (fd);
+
+ if (init_module (buf, st.st_size, "") != 0) {
+ fprintf (stderr, "insmod: init_module: %s: %m\n", filename);
+ /* However ignore the error because this can just happen because
+ * of a missing device.
+ */
}
-
- /* Parent. */
- int status;
- if (wait (&status) == -1 ||
- WEXITSTATUS (status) != 0)
- perror ("insmod: wait");
- /* but ignore the error, some will be because the device is not found */
}
/* Print contents of /proc/uptime. */