diff options
-rw-r--r-- | README | 2 | ||||
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | helper/ext2initrd.c | 30 | ||||
-rw-r--r-- | helper/init.c | 51 |
4 files changed, 66 insertions, 20 deletions
@@ -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. */ |