aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--init/initramfs.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/init/initramfs.c b/init/initramfs.c
index d9c941c0c3ca..d3c56fcb30b8 100644
--- a/init/initramfs.c
+++ b/init/initramfs.c
@@ -5,6 +5,7 @@
5#include <linux/fcntl.h> 5#include <linux/fcntl.h>
6#include <linux/delay.h> 6#include <linux/delay.h>
7#include <linux/string.h> 7#include <linux/string.h>
8#include <linux/dirent.h>
8#include <linux/syscalls.h> 9#include <linux/syscalls.h>
9#include <linux/utime.h> 10#include <linux/utime.h>
10 11
@@ -166,8 +167,6 @@ static __initdata char *victim;
166static __initdata unsigned count; 167static __initdata unsigned count;
167static __initdata loff_t this_header, next_header; 168static __initdata loff_t this_header, next_header;
168 169
169static __initdata int dry_run;
170
171static inline void __init eat(unsigned n) 170static inline void __init eat(unsigned n)
172{ 171{
173 victim += n; 172 victim += n;
@@ -229,10 +228,6 @@ static int __init do_header(void)
229 parse_header(collected); 228 parse_header(collected);
230 next_header = this_header + N_ALIGN(name_len) + body_len; 229 next_header = this_header + N_ALIGN(name_len) + body_len;
231 next_header = (next_header + 3) & ~3; 230 next_header = (next_header + 3) & ~3;
232 if (dry_run) {
233 read_into(name_buf, N_ALIGN(name_len), GotName);
234 return 0;
235 }
236 state = SkipIt; 231 state = SkipIt;
237 if (name_len <= 0 || name_len > PATH_MAX) 232 if (name_len <= 0 || name_len > PATH_MAX)
238 return 0; 233 return 0;
@@ -303,8 +298,6 @@ static int __init do_name(void)
303 free_hash(); 298 free_hash();
304 return 0; 299 return 0;
305 } 300 }
306 if (dry_run)
307 return 0;
308 clean_path(collected, mode); 301 clean_path(collected, mode);
309 if (S_ISREG(mode)) { 302 if (S_ISREG(mode)) {
310 int ml = maybe_link(); 303 int ml = maybe_link();
@@ -476,10 +469,9 @@ static void __init flush_window(void)
476 outcnt = 0; 469 outcnt = 0;
477} 470}
478 471
479static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) 472static char * __init unpack_to_rootfs(char *buf, unsigned len)
480{ 473{
481 int written; 474 int written;
482 dry_run = check_only;
483 header_buf = kmalloc(110, GFP_KERNEL); 475 header_buf = kmalloc(110, GFP_KERNEL);
484 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); 476 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
485 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); 477 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
@@ -574,10 +566,57 @@ skip:
574 initrd_end = 0; 566 initrd_end = 0;
575} 567}
576 568
569#define BUF_SIZE 1024
570static void __init clean_rootfs(void)
571{
572 int fd;
573 void *buf;
574 struct linux_dirent64 *dirp;
575 int count;
576
577 fd = sys_open("/", O_RDONLY, 0);
578 WARN_ON(fd < 0);
579 if (fd < 0)
580 return;
581 buf = kzalloc(BUF_SIZE, GFP_KERNEL);
582 WARN_ON(!buf);
583 if (!buf) {
584 sys_close(fd);
585 return;
586 }
587
588 dirp = buf;
589 count = sys_getdents64(fd, dirp, BUF_SIZE);
590 while (count > 0) {
591 while (count > 0) {
592 struct stat st;
593 int ret;
594
595 ret = sys_newlstat(dirp->d_name, &st);
596 WARN_ON_ONCE(ret);
597 if (!ret) {
598 if (S_ISDIR(st.st_mode))
599 sys_rmdir(dirp->d_name);
600 else
601 sys_unlink(dirp->d_name);
602 }
603
604 count -= dirp->d_reclen;
605 dirp = (void *)dirp + dirp->d_reclen;
606 }
607 dirp = buf;
608 memset(buf, 0, BUF_SIZE);
609 count = sys_getdents64(fd, dirp, BUF_SIZE);
610 }
611
612 sys_close(fd);
613 kfree(buf);
614}
615
577static int __init populate_rootfs(void) 616static int __init populate_rootfs(void)
578{ 617{
579 char *err = unpack_to_rootfs(__initramfs_start, 618 char *err = unpack_to_rootfs(__initramfs_start,
580 __initramfs_end - __initramfs_start, 0); 619 __initramfs_end - __initramfs_start);
581 if (err) 620 if (err)
582 panic(err); 621 panic(err);
583 if (initrd_start) { 622 if (initrd_start) {
@@ -585,13 +624,15 @@ static int __init populate_rootfs(void)
585 int fd; 624 int fd;
586 printk(KERN_INFO "checking if image is initramfs..."); 625 printk(KERN_INFO "checking if image is initramfs...");
587 err = unpack_to_rootfs((char *)initrd_start, 626 err = unpack_to_rootfs((char *)initrd_start,
588 initrd_end - initrd_start, 1); 627 initrd_end - initrd_start);
589 if (!err) { 628 if (!err) {
590 printk(" it is\n"); 629 printk(" it is\n");
591 unpack_to_rootfs((char *)initrd_start,
592 initrd_end - initrd_start, 0);
593 free_initrd(); 630 free_initrd();
594 return 0; 631 return 0;
632 } else {
633 clean_rootfs();
634 unpack_to_rootfs(__initramfs_start,
635 __initramfs_end - __initramfs_start);
595 } 636 }
596 printk("it isn't (%s); looks like an initrd\n", err); 637 printk("it isn't (%s); looks like an initrd\n", err);
597 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700); 638 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
@@ -604,7 +645,7 @@ static int __init populate_rootfs(void)
604#else 645#else
605 printk(KERN_INFO "Unpacking initramfs..."); 646 printk(KERN_INFO "Unpacking initramfs...");
606 err = unpack_to_rootfs((char *)initrd_start, 647 err = unpack_to_rootfs((char *)initrd_start,
607 initrd_end - initrd_start, 0); 648 initrd_end - initrd_start);
608 if (err) 649 if (err)
609 panic(err); 650 panic(err);
610 printk(" done\n"); 651 printk(" done\n");