/dev/null | 100 ---------------------------------------------- drivers/block/Makefile | 1 init/do_mounts_initrd.c | 28 +++++++------ init/initramfs.c | 103 ++++++++++++++++++++++++++++++++++-------------- 4 files changed, 90 insertions(+), 142 deletions(-) diff -puN -L drivers/block/initrd.c drivers/block/initrd.c~RD0-initrd-B6 /dev/null --- 25/drivers/block/initrd.c +++ /dev/null 2002-08-30 16:31:37.000000000 -0700 @@ -1,100 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include - - -unsigned long initrd_start, initrd_end; -int initrd_below_start_ok; - -static int initrd_users; -static spinlock_t initrd_users_lock = SPIN_LOCK_UNLOCKED; - -static struct gendisk *initrd_disk; - -static ssize_t initrd_read(struct file *file, char *buf, - size_t count, loff_t *ppos) -{ - int left = initrd_end - initrd_start - *ppos; - - if (count > left) - count = left; - if (count == 0) - return 0; - if (copy_to_user(buf, (char *)initrd_start + *ppos, count)) - return -EFAULT; - - *ppos += count; - return count; -} - -static int initrd_release(struct inode *inode,struct file *file) -{ - - blkdev_put(inode->i_bdev, BDEV_FILE); - - spin_lock(&initrd_users_lock); - if (!--initrd_users) { - spin_unlock(&initrd_users_lock); - del_gendisk(initrd_disk); - free_initrd_mem(initrd_start, initrd_end); - initrd_start = 0; - } else - spin_unlock(&initrd_users_lock); - - return 0; -} - -static struct file_operations initrd_fops = { - .read = initrd_read, - .release = initrd_release, -}; - -static int initrd_open(struct inode *inode, struct file *filp) -{ - if (!initrd_start) - return -ENODEV; - - spin_lock(&initrd_users_lock); - initrd_users++; - spin_unlock(&initrd_users_lock); - - filp->f_op = &initrd_fops; - return 0; -} - -static struct block_device_operations initrd_bdops = { - .owner = THIS_MODULE, - .open = initrd_open, -}; - -static int __init initrd_init(void) -{ - initrd_disk = alloc_disk(1); - if (!initrd_disk) - return -ENOMEM; - - initrd_disk->major = RAMDISK_MAJOR; - initrd_disk->first_minor = INITRD_MINOR; - initrd_disk->fops = &initrd_bdops; - - sprintf(initrd_disk->disk_name, "initrd"); - sprintf(initrd_disk->devfs_name, "rd/initrd"); - - set_capacity(initrd_disk, (initrd_end-initrd_start+511) >> 9); - add_disk(initrd_disk); - return 0; -} - -static void __exit initrd_exit(void) -{ - put_disk(initrd_disk); -} - -module_init(initrd_init); -module_exit(initrd_exit); diff -puN drivers/block/Makefile~RD0-initrd-B6 drivers/block/Makefile --- 25/drivers/block/Makefile~RD0-initrd-B6 2003-10-02 01:35:43.000000000 -0700 +++ 25-akpm/drivers/block/Makefile 2003-10-02 01:35:43.000000000 -0700 @@ -28,7 +28,6 @@ obj-$(CONFIG_ATARI_ACSI) += acsi.o obj-$(CONFIG_ATARI_SLM) += acsi_slm.o obj-$(CONFIG_AMIGA_Z2RAM) += z2ram.o obj-$(CONFIG_BLK_DEV_RAM) += rd.o -obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o obj-$(CONFIG_BLK_DEV_LOOP) += loop.o obj-$(CONFIG_BLK_DEV_PS2) += ps2esdi.o obj-$(CONFIG_BLK_DEV_XD) += xd.o diff -puN init/do_mounts_initrd.c~RD0-initrd-B6 init/do_mounts_initrd.c --- 25/init/do_mounts_initrd.c~RD0-initrd-B6 2003-10-02 01:35:43.000000000 -0700 +++ 25-akpm/init/do_mounts_initrd.c 2003-10-02 01:35:43.000000000 -0700 @@ -9,6 +9,8 @@ #include "do_mounts.h" +unsigned long initrd_start, initrd_end; +int initrd_below_start_ok; unsigned int real_root_dev; /* do_proc_dointvec cannot handle kdev_t */ static int __initdata old_fd, root_fd; static int __initdata mount_initrd = 1; @@ -99,18 +101,20 @@ static void __init handle_initrd(void) int __init initrd_load(void) { - if (!mount_initrd) - return 0; - - create_dev("/dev/ram", MKDEV(RAMDISK_MAJOR, 0), NULL); - create_dev("/dev/initrd", MKDEV(RAMDISK_MAJOR, INITRD_MINOR), NULL); - /* Load the initrd data into /dev/ram0. Execute it as initrd unless - * /dev/ram0 is supposed to be our actual root device, in - * that case the ram disk is just set up here, and gets - * mounted in the normal path. */ - if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) { - handle_initrd(); - return 1; + if (mount_initrd) { + create_dev("/dev/ram", Root_RAM0, NULL); + /* + * Load the initrd data into /dev/ram0. Execute it as initrd + * unless /dev/ram0 is supposed to be our actual root device, + * in that case the ram disk is just set up here, and gets + * mounted in the normal path. + */ + if (rd_load_image("/dev/initrd") && ROOT_DEV != Root_RAM0) { + sys_unlink("/dev/initrd"); + handle_initrd(); + return 1; + } } + sys_unlink("/dev/initrd"); return 0; } diff -puN init/initramfs.c~RD0-initrd-B6 init/initramfs.c --- 25/init/initramfs.c~RD0-initrd-B6 2003-10-02 01:35:43.000000000 -0700 +++ 25-akpm/init/initramfs.c 2003-10-02 01:35:43.000000000 -0700 @@ -8,9 +8,11 @@ #include #include +static __initdata char *message; static void __init error(char *x) { - panic("populate_root: %s\n", x); + if (!message) + message = x; } static void __init *malloc(int size) @@ -63,7 +65,7 @@ static char __init *find_link(int major, } q = (struct hash *)malloc(sizeof(struct hash)); if (!q) - error("can't allocate link hash entry"); + panic("can't allocate link hash entry"); q->ino = ino; q->minor = minor; q->major = major; @@ -119,7 +121,7 @@ static void __init parse_header(char *s) /* FSM */ -enum state { +static __initdata enum state { Start, Collect, GotHeader, @@ -130,9 +132,11 @@ enum state { Reset } state, next_state; -char *victim; -unsigned count; -loff_t this_header, next_header; +static __initdata char *victim; +static __initdata unsigned count; +static __initdata loff_t this_header, next_header; + +static __initdata int dry_run; static inline void eat(unsigned n) { @@ -185,23 +189,30 @@ static int __init do_collect(void) static int __init do_header(void) { + if (memcmp(collected, "070701", 6)) { + error("no cpio magic"); + return 1; + } parse_header(collected); next_header = this_header + N_ALIGN(name_len) + body_len; next_header = (next_header + 3) & ~3; + if (dry_run) { + read_into(name_buf, N_ALIGN(name_len), GotName); + return 0; + } + state = SkipIt; if (name_len <= 0 || name_len > PATH_MAX) - state = SkipIt; - else if (S_ISLNK(mode)) { + return 0; + if (S_ISLNK(mode)) { if (body_len > PATH_MAX) - state = SkipIt; - else { - collect = collected = symlink_buf; - remains = N_ALIGN(name_len) + body_len; - next_state = GotSymlink; - state = Collect; - } - } else if (body_len && !S_ISREG(mode)) - state = SkipIt; - else + return 0; + collect = collected = symlink_buf; + remains = N_ALIGN(name_len) + body_len; + next_state = GotSymlink; + state = Collect; + return 0; + } + if (S_ISREG(mode) || !body_len) read_into(name_buf, N_ALIGN(name_len), GotName); return 0; } @@ -248,6 +259,8 @@ static int __init do_name(void) next_state = Reset; return 0; } + if (dry_run) + return 0; if (S_ISREG(mode)) { if (maybe_link() >= 0) { wfd = sys_open(collected, O_WRONLY|O_CREAT, mode); @@ -268,8 +281,7 @@ static int __init do_name(void) sys_chown(collected, uid, gid); sys_chmod(collected, mode); } - } else - panic("populate_root: bogus mode: %o\n", mode); + } return 0; } @@ -323,13 +335,14 @@ static int __init write_buffer(char *buf static void __init flush_buffer(char *buf, unsigned len) { int written; - while ((written = write_buffer(buf, len)) < len) { + if (message) + return; + while ((written = write_buffer(buf, len)) < len && !message) { char c = buf[written]; if (c == '0') { buf += written; len -= written; state = Start; - continue; } else error("junk in compressed archive"); } @@ -408,18 +421,20 @@ static void __init flush_window(void) outcnt = 0; } -static void __init unpack_to_rootfs(char *buf, unsigned len) +char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) { int written; + dry_run = check_only; header_buf = malloc(110); symlink_buf = malloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1); name_buf = malloc(N_ALIGN(PATH_MAX)); window = malloc(WSIZE); if (!window || !header_buf || !symlink_buf || !name_buf) - error("can't allocate buffers"); + panic("can't allocate buffers"); state = Start; this_header = 0; - while (len) { + message = NULL; + while (!message && len) { loff_t saved_offset = this_header; if (*buf == '0' && !(this_header & 3)) { state = Start; @@ -427,7 +442,8 @@ static void __init unpack_to_rootfs(char buf += written; len -= written; continue; - } else if (!*buf) { + } + if (!*buf) { buf++; len--; this_header++; @@ -442,7 +458,7 @@ static void __init unpack_to_rootfs(char crc = (ulg)0xffffffffL; /* shift register contents */ makecrc(); if (gunzip()) - error("ungzip failed"); + message = "ungzip failed"; if (state != Reset) error("junk in gzipped archive"); this_header = saved_offset + inptr; @@ -453,12 +469,41 @@ static void __init unpack_to_rootfs(char free(name_buf); free(symlink_buf); free(header_buf); + return message; } extern char __initramfs_start, __initramfs_end; +#ifdef CONFIG_BLK_DEV_INITRD +#include +#endif void __init populate_rootfs(void) { - unpack_to_rootfs(&__initramfs_start, - &__initramfs_end - &__initramfs_start); + char *err = unpack_to_rootfs(&__initramfs_start, + &__initramfs_end - &__initramfs_start, 0); + if (err) + panic(err); +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start) { + int fd; + printk(KERN_INFO "checking if image is initramfs..."); + err = unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 1); + if (!err) { + printk(" it is\n"); + unpack_to_rootfs((char *)initrd_start, + initrd_end - initrd_start, 0); + free_initrd_mem(initrd_start, initrd_end); + return; + } + printk("it isn't (%s); looks like an initrd\n", err); + fd = sys_open("/dev/initrd", O_WRONLY|O_CREAT, 700); + if (fd >= 0) { + sys_write(fd, (char *)initrd_start, + initrd_end - initrd_start); + sys_close(fd); + free_initrd_mem(initrd_start, initrd_end); + } + } +#endif } _