summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--README2
-rw-r--r--configure.ac3
-rw-r--r--helper/ext2initrd.c30
-rw-r--r--helper/init.c51
4 files changed, 66 insertions, 20 deletions
diff --git a/README b/README
index 99c4d36..2c42b2e 100644
--- a/README
+++ b/README
@@ -59,6 +59,8 @@ are building:
qemu >= 0.13
kernel >= 2.6.36
+ zlib - if your kernel uses gzipped modules
+
Building and installing
-----------------------
diff --git a/configure.ac b/configure.ac
index 23c876b..dca5032 100644
--- a/configure.ac
+++ b/configure.ac
@@ -86,6 +86,9 @@ AC_SUBST([APT_CACHE_DEPENDS_RECURSE_BROKEN])
dnl For ArchLinux handler.
AC_CHECK_PROG(PACMAN,[pacman],[pacman],[no])
+dnl Support for gzipped kernel modules.
+AC_CHECK_LIB([z],[gzopen])
+
dnl Required programs, libraries.
AC_PATH_PROG([MKE2FS],[mke2fs],[no],
[$PATH$PATH_SEPARATOR/sbin$PATH_SEPARATOR])
diff --git a/helper/ext2initrd.c b/helper/ext2initrd.c
index c4fc353..bb00c72 100644
--- a/helper/ext2initrd.c
+++ b/helper/ext2initrd.c
@@ -52,21 +52,21 @@ extern char _binary_init_start, _binary_init_end, _binary_init_size;
* ext2 filesystem on it.
*/
static const char *kmods[] = {
- "ext2.ko",
- "ext4.ko", /* CONFIG_EXT4_USE_FOR_EXT23=y option might be set */
- "virtio*.ko",
- "ide*.ko",
- "libata*.ko",
- "piix*.ko",
- "scsi_transport_spi.ko",
- "scsi_mod.ko",
- "sd_mod.ko",
- "sym53c8xx.ko",
- "ata_piix.ko",
- "sr_mod.ko",
- "mbcache.ko",
- "crc*.ko",
- "libcrc*.ko",
+ "ext2.ko*",
+ "ext4.ko*", /* CONFIG_EXT4_USE_FOR_EXT23=y option might be set */
+ "virtio*.ko*",
+ "ide*.ko*",
+ "libata*.ko*",
+ "piix*.ko*",
+ "scsi_transport_spi.ko*",
+ "scsi_mod.ko*",
+ "sd_mod.ko*",
+ "sym53c8xx.ko*",
+ "ata_piix.ko*",
+ "sr_mod.ko*",
+ "mbcache.ko*",
+ "crc*.ko*",
+ "libcrc*.ko*",
NULL
};
diff --git a/helper/init.c b/helper/init.c
index 34a8450..447df8e 100644
--- a/helper/init.c
+++ b/helper/init.c
@@ -38,6 +38,10 @@
#include <asm/unistd.h>
+#ifdef HAVE_LIBZ
+#include <zlib.h>
+#endif
+
extern long init_module (void *, unsigned long, const char *);
/* translation taken from module-init-tools/insmod.c */
@@ -201,9 +205,40 @@ main ()
static void
insmod (const char *filename)
{
+ size_t size;
+
if (verbose)
fprintf (stderr, "febootstrap: internal insmod %s\n", filename);
+#ifdef HAVE_LIBZ
+ gzFile gzfp = gzopen (filename, "rb");
+ int capacity = 64*1024;
+ char *buf = (char *) malloc (capacity);
+ int tmpsize = 8 * 1024;
+ char tmp[tmpsize];
+ int num;
+
+ size = 0;
+
+ if (gzfp == NULL) {
+ fprintf (stderr, "insmod: gzopen failed: %s", filename);
+ exit (EXIT_FAILURE);
+ }
+ while ((num = gzread (gzfp, tmp, tmpsize)) > 0) {
+ if (num > capacity) {
+ buf = (char*) realloc (buf, size*2);
+ capacity = size;
+ }
+ memcpy (buf+size, tmp, num);
+ capacity -= num;
+ size += num;
+ }
+ if (num == -1) {
+ perror ("insmod: gzread");
+ exit (EXIT_FAILURE);
+ }
+ gzclose (gzfp);
+#else
int fd = open (filename, O_RDONLY);
if (fd == -1) {
fprintf (stderr, "insmod: open: %s: %m\n", filename);
@@ -214,24 +249,30 @@ insmod (const char *filename)
perror ("insmod: fstat");
exit (EXIT_FAILURE);
}
- char buf[st.st_size];
- long offset = 0;
+ size = st.st_size;
+ char buf[size];
+ size_t offset = 0;
do {
- long rc = read (fd, buf + offset, st.st_size - offset);
+ ssize_t rc = read (fd, buf + offset, size - offset);
if (rc == -1) {
perror ("insmod: read");
exit (EXIT_FAILURE);
}
offset += rc;
- } while (offset < st.st_size);
+ } while (offset < size);
close (fd);
+#endif
- if (init_module (buf, st.st_size, "") != 0) {
+ if (init_module (buf, size, "") != 0) {
fprintf (stderr, "insmod: init_module: %s: %s\n", filename, moderror (errno));
/* However ignore the error because this can just happen because
* of a missing device.
*/
}
+
+#ifdef HAVE_LIBZ
+ free (buf);
+#endif
}
/* Mount /proc unless it's mounted already. */