Don't require external insmod.static.
authorHilko Bengen <bengen@hilluzination.de>
Tue, 31 May 2011 22:43:10 +0000 (00:43 +0200)
committerRichard W.M. Jones <rjones@redhat.com>
Wed, 1 Jun 2011 09:28:06 +0000 (10:28 +0100)
Add module loading functionality into init.c, thus making
insmod.static unnecessary.

README
configure.ac
helper/ext2initrd.c
helper/init.c

diff --git a/README b/README
index 8092aaf..99c4d36 100644 (file)
--- 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
index 7606bca..ecd6b1e 100644 (file)
@@ -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
index 3d765ca..17af3bd 100644 (file)
@@ -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);
index 7b6b94e..8690f22 100644 (file)
@@ -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>
 #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. */