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