[Libguestfs] [PATCH 2/4] febootstrap: Cope with non-existing insmod.static

Hilko Bengen bengen at hilluzination.de
Tue May 31 22:43:10 UTC 2011


Add module loading functionality into init.c, make copying insmod.static to initrd optional.
---
 configure.ac        |   14 +++++---------
 helper/ext2initrd.c |    2 ++
 helper/init.c       |   37 +++++++++++++++++++++++++++++++++++++
 3 files changed, 44 insertions(+), 9 deletions(-)

diff --git a/configure.ac b/configure.ac
index 7606bca..382e270 100644
--- a/configure.ac
+++ b/configure.ac
@@ -71,17 +71,13 @@ 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.
+  AC_MSG_WARN([insmod.static program not found
+Compiling insmod functionality directly into init program.
 ])
+else
+  AC_DEFINE_UNQUOTED([INSMODSTATIC],["$INSMODSTATIC"],
+    [Full path to the insmod.static program.])
 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])
diff --git a/helper/ext2initrd.c b/helper/ext2initrd.c
index 3d765ca..c65ecf8 100644
--- a/helper/ext2initrd.c
+++ b/helper/ext2initrd.c
@@ -155,6 +155,7 @@ ext2_make_initrd (const char *modpath, const char *initrd)
   free (cmd);
   free_module_deps ();
 
+#ifdef INSMODSTATIC
   /* Copy in insmod static binary. */
   cmd = xasprintf ("cp %s %s", INSMODSTATIC, dir);
   if (verbose >= 2) fprintf (stderr, "%s\n", cmd);
@@ -163,6 +164,7 @@ ext2_make_initrd (const char *modpath, const char *initrd)
     error (EXIT_FAILURE, 0,
            "ext2_make_initrd: copy %s failed", INSMODSTATIC);
   free (cmd);
+#endif
 
   /* Copy in the init program, linked into this program as a data blob. */
   char *init = xasprintf ("%s/init", dir);
diff --git a/helper/init.c b/helper/init.c
index 7b6b94e..ac71018 100644
--- a/helper/init.c
+++ b/helper/init.c
@@ -36,6 +36,12 @@
 #include <sys/stat.h>
 #include <sys/wait.h>
 
+#ifndef INSMODSTATIC
+#include <fcntl.h>
+#include <asm/unistd.h>
+extern long init_module(void *, unsigned long, const char *);
+#endif
+
 /* Leave this enabled for now.  When we get more confident in the boot
  * process we can turn this off or make it configurable.
  */
@@ -70,7 +76,9 @@ main ()
    * executable.  Just make it executable.  It's easier than fixing
    * everyone's distro.
    */
+#ifdef INSMODSTATIC
   chmod ("/sbin/insmod.static", 0755);
+#endif
 
   FILE *fp = fopen ("/modules", "r");
   if (fp == NULL) {
@@ -184,9 +192,38 @@ insmod (const char *filename)
   }
 
   if (pid == 0) { /* Child. */
+#ifdef INSMODSTATIC
     execl ("/insmod.static", "insmod.static", filename, NULL);
     perror ("insmod: execl");
     _exit (EXIT_FAILURE);
+#else
+    int fd = open (filename, O_RDONLY);
+    if (fd == -1) {
+      fprintf (stderr, "insmod: open: %s: %s\n", filename, strerror(errno));
+      _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);
+    if (init_module (buf, st.st_size, "") != 0) {
+      fprintf (stderr, "insmod: init_module: %s: %s\n", filename, strerror(errno));
+      _exit (EXIT_FAILURE);
+    }
+    close (fd);
+    _exit (EXIT_SUCCESS);
+#endif
   }
 
   /* Parent. */
-- 
1.7.5.3




More information about the Libguestfs mailing list