aboutsummaryrefslogtreecommitdiffstats
path: root/init/initramfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'init/initramfs.c')
-rw-r--r--init/initramfs.c71
1 files changed, 56 insertions, 15 deletions
diff --git a/init/initramfs.c b/init/initramfs.c
index 7dcde7ea6603..619c1baf7701 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();
@@ -417,14 +410,13 @@ static unsigned my_inptr; /* index of next byte to be processed in inbuf */
417 410
418#include <linux/decompress/generic.h> 411#include <linux/decompress/generic.h>
419 412
420static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only) 413static char * __init unpack_to_rootfs(char *buf, unsigned len)
421{ 414{
422 int written; 415 int written;
423 decompress_fn decompress; 416 decompress_fn decompress;
424 const char *compress_name; 417 const char *compress_name;
425 static __initdata char msg_buf[64]; 418 static __initdata char msg_buf[64];
426 419
427 dry_run = check_only;
428 header_buf = kmalloc(110, GFP_KERNEL); 420 header_buf = kmalloc(110, GFP_KERNEL);
429 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL); 421 symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
430 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL); 422 name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
@@ -523,10 +515,57 @@ skip:
523 initrd_end = 0; 515 initrd_end = 0;
524} 516}
525 517
518#define BUF_SIZE 1024
519static void __init clean_rootfs(void)
520{
521 int fd;
522 void *buf;
523 struct linux_dirent64 *dirp;
524 int count;
525
526 fd = sys_open("/", O_RDONLY, 0);
527 WARN_ON(fd < 0);
528 if (fd < 0)
529 return;
530 buf = kzalloc(BUF_SIZE, GFP_KERNEL);
531 WARN_ON(!buf);
532 if (!buf) {
533 sys_close(fd);
534 return;
535 }
536
537 dirp = buf;
538 count = sys_getdents64(fd, dirp, BUF_SIZE);
539 while (count > 0) {
540 while (count > 0) {
541 struct stat st;
542 int ret;
543
544 ret = sys_newlstat(dirp->d_name, &st);
545 WARN_ON_ONCE(ret);
546 if (!ret) {
547 if (S_ISDIR(st.st_mode))
548 sys_rmdir(dirp->d_name);
549 else
550 sys_unlink(dirp->d_name);
551 }
552
553 count -= dirp->d_reclen;
554 dirp = (void *)dirp + dirp->d_reclen;
555 }
556 dirp = buf;
557 memset(buf, 0, BUF_SIZE);
558 count = sys_getdents64(fd, dirp, BUF_SIZE);
559 }
560
561 sys_close(fd);
562 kfree(buf);
563}
564
526static int __init populate_rootfs(void) 565static int __init populate_rootfs(void)
527{ 566{
528 char *err = unpack_to_rootfs(__initramfs_start, 567 char *err = unpack_to_rootfs(__initramfs_start,
529 __initramfs_end - __initramfs_start, 0); 568 __initramfs_end - __initramfs_start);
530 if (err) 569 if (err)
531 panic(err); /* Failed to decompress INTERNAL initramfs */ 570 panic(err); /* Failed to decompress INTERNAL initramfs */
532 if (initrd_start) { 571 if (initrd_start) {
@@ -534,13 +573,15 @@ static int __init populate_rootfs(void)
534 int fd; 573 int fd;
535 printk(KERN_INFO "checking if image is initramfs..."); 574 printk(KERN_INFO "checking if image is initramfs...");
536 err = unpack_to_rootfs((char *)initrd_start, 575 err = unpack_to_rootfs((char *)initrd_start,
537 initrd_end - initrd_start, 1); 576 initrd_end - initrd_start);
538 if (!err) { 577 if (!err) {
539 printk(" it is\n"); 578 printk(" it is\n");
540 unpack_to_rootfs((char *)initrd_start,
541 initrd_end - initrd_start, 0);
542 free_initrd(); 579 free_initrd();
543 return 0; 580 return 0;
581 } else {
582 clean_rootfs();
583 unpack_to_rootfs(__initramfs_start,
584 __initramfs_end - __initramfs_start);
544 } 585 }
545 printk("it isn't (%s); looks like an initrd\n", err); 586 printk("it isn't (%s); looks like an initrd\n", err);
546 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700); 587 fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
@@ -553,7 +594,7 @@ static int __init populate_rootfs(void)
553#else 594#else
554 printk(KERN_INFO "Unpacking initramfs..."); 595 printk(KERN_INFO "Unpacking initramfs...");
555 err = unpack_to_rootfs((char *)initrd_start, 596 err = unpack_to_rootfs((char *)initrd_start,
556 initrd_end - initrd_start, 0); 597 initrd_end - initrd_start);
557 if (err) { 598 if (err) {
558 printk(" failed!\n"); 599 printk(" failed!\n");
559 printk(KERN_EMERG "%s\n", err); 600 printk(KERN_EMERG "%s\n", err);