#include <linux/fcntl.h>
#include <linux/delay.h>
#include <linux/string.h>
+#include <linux/dirent.h>
#include <linux/syscalls.h>
#include <linux/utime.h>
static __initdata unsigned count;
static __initdata loff_t this_header, next_header;
-static __initdata int dry_run;
-
static inline void __init eat(unsigned n)
{
victim += n;
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)
return 0;
free_hash();
return 0;
}
- if (dry_run)
- return 0;
clean_path(collected, mode);
if (S_ISREG(mode)) {
int ml = maybe_link();
return len - count;
}
-#if defined CONFIG_RD_GZIP || defined CONFIG_RD_BZIP2 || defined CONFIG_RD_LZMA
static int __init flush_buffer(void *bufv, unsigned len)
{
char *buf = (char *) bufv;
}
return origLen;
}
-#endif
static unsigned my_inptr; /* index of next byte to be processed in inbuf */
#include <linux/decompress/generic.h>
-static char * __init unpack_to_rootfs(char *buf, unsigned len, int check_only)
+static char * __init unpack_to_rootfs(char *buf, unsigned len)
{
int written;
decompress_fn decompress;
+ const char *compress_name;
+ static __initdata char msg_buf[64];
- dry_run = check_only;
header_buf = kmalloc(110, GFP_KERNEL);
symlink_buf = kmalloc(PATH_MAX + N_ALIGN(PATH_MAX) + 1, GFP_KERNEL);
name_buf = kmalloc(N_ALIGN(PATH_MAX), GFP_KERNEL);
continue;
}
this_header = 0;
- decompress = decompress_method(buf, len, NULL);
+ decompress = decompress_method(buf, len, &compress_name);
if (decompress)
decompress(buf, len, NULL, flush_buffer, NULL,
&my_inptr, error);
+ else if (compress_name) {
+ if (!message) {
+ snprintf(msg_buf, sizeof msg_buf,
+ "compression method %s not configured",
+ compress_name);
+ message = msg_buf;
+ }
+ }
if (state != Reset)
error("junk in compressed archive");
this_header = saved_offset + my_inptr;
initrd_end = 0;
}
+#define BUF_SIZE 1024
+static void __init clean_rootfs(void)
+{
+ int fd;
+ void *buf;
+ struct linux_dirent64 *dirp;
+ int count;
+
+ fd = sys_open("/", O_RDONLY, 0);
+ WARN_ON(fd < 0);
+ if (fd < 0)
+ return;
+ buf = kzalloc(BUF_SIZE, GFP_KERNEL);
+ WARN_ON(!buf);
+ if (!buf) {
+ sys_close(fd);
+ return;
+ }
+
+ dirp = buf;
+ count = sys_getdents64(fd, dirp, BUF_SIZE);
+ while (count > 0) {
+ while (count > 0) {
+ struct stat st;
+ int ret;
+
+ ret = sys_newlstat(dirp->d_name, &st);
+ WARN_ON_ONCE(ret);
+ if (!ret) {
+ if (S_ISDIR(st.st_mode))
+ sys_rmdir(dirp->d_name);
+ else
+ sys_unlink(dirp->d_name);
+ }
+
+ count -= dirp->d_reclen;
+ dirp = (void *)dirp + dirp->d_reclen;
+ }
+ dirp = buf;
+ memset(buf, 0, BUF_SIZE);
+ count = sys_getdents64(fd, dirp, BUF_SIZE);
+ }
+
+ sys_close(fd);
+ kfree(buf);
+}
+
static int __init populate_rootfs(void)
{
char *err = unpack_to_rootfs(__initramfs_start,
- __initramfs_end - __initramfs_start, 0);
+ __initramfs_end - __initramfs_start);
if (err)
- panic(err);
+ panic(err); /* Failed to decompress INTERNAL initramfs */
if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
int fd;
printk(KERN_INFO "checking if image is initramfs...");
err = unpack_to_rootfs((char *)initrd_start,
- initrd_end - initrd_start, 1);
+ initrd_end - initrd_start);
if (!err) {
printk(" it is\n");
- unpack_to_rootfs((char *)initrd_start,
- initrd_end - initrd_start, 0);
free_initrd();
return 0;
+ } else {
+ clean_rootfs();
+ unpack_to_rootfs(__initramfs_start,
+ __initramfs_end - __initramfs_start);
}
printk("it isn't (%s); looks like an initrd\n", err);
fd = sys_open("/initrd.image", O_WRONLY|O_CREAT, 0700);
#else
printk(KERN_INFO "Unpacking initramfs...");
err = unpack_to_rootfs((char *)initrd_start,
- initrd_end - initrd_start, 0);
- if (err)
- panic(err);
- printk(" done\n");
+ initrd_end - initrd_start);
+ if (err) {
+ printk(" failed!\n");
+ printk(KERN_EMERG "%s\n", err);
+ } else {
+ printk(" done\n");
+ }
free_initrd();
#endif
}