From ef6f7db3e1ed2e0d09e02ac77be70848c221f3df Mon Sep 17 00:00:00 2001 From: Hilko Bengen Date: Wed, 1 Jun 2011 00:43:10 +0200 Subject: [PATCH] Don't require external insmod.static. Add module loading functionality into init.c, thus making insmod.static unnecessary. --- README | 5 ---- configure.ac | 15 ------------ helper/ext2initrd.c | 9 ------- helper/init.c | 67 +++++++++++++++++++++++++++++++++-------------------- 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 @@ -30,12 +29,17 @@ #include #include #include +#include #include #include #include #include #include +#include + +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. */ -- 1.8.3.1