Re: [RFC] rootmpfs

From: Byron Stanoszek
Date: Fri Apr 05 2013 - 15:59:34 EST


Rob,

FWIW I have a patch to do something like this. It even gives you a rdsize=xxx
tunable kernel parameter that lets you specify the size of the tmpfs, which
acts like the -osize= mount flag (so phrases like 100M or 20% works). So doing
things like 'cat /dev/zero > filename' will not run you out of all available
memory. (Note: If you don't specify rdsize= on the kernel command line, it will
not convert rootfs to tmpfs).

See attached.

-Byron

On Wed, 3 Apr 2013, Rob Landley wrote:

Attached is my quick and dirty hack to make rootfs be tmpfs when CONFIG_TMPFS is
enabled. It can't be this easy or somebody would have done it in the _eight_years_
since https://lkml.org/lkml/2006/7/31/145

Yes, it's got an #ifdef and out of place prototypes. Yes, it manually calls a module
init function and compensates by making it reentrant. But it works, and when I
"cat /dev/zero > filename" the filesystem fills _up_ instead of panicing the kernel.

So now that I've posted the error, would someone please tell me how I _should_ have done it?

Rob

P.S. If I actually change the filesystem type to a name other than "rootfs", it panics on the way up because various bits of the kernel are looking for that magic name. Sigh.

P.P.S. removing MS_NOUSER is actually intentional, there's a local cray patch that does the same thing because otherwise you can't --bind mount directories out of this filesystem, which is a thing they wanted to do.--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--- linux/init/initramfs.c.orig 2012-12-05 21:39:09.000000000 -0500
+++ linux/init/initramfs.c 2012-12-10 12:15:49.000000000 -0500
@@ -569,14 +569,56 @@
}
#endif

+static char * __initdata ramdisk_size;
+
+static int __init rdsize_setup(char *str)
+{
+ ramdisk_size = str;
+ return 1;
+}
+__setup("rdsize=", rdsize_setup);
+
+static int __init change_root_to_tmpfs(void)
+{
+ char size[38], *s;
+
+ sprintf(size, "size=%.20s,nr_inodes=0", ramdisk_size);
+ if ((s = strchr(size, ',')))
+ *s = '\0';
+
+ if (!sys_mkdir("/root", 0700) &&
+ !sys_mount("/dev/root", "/root", "tmpfs", 0, size) &&
+ !sys_chdir("/root") &&
+ !sys_mount(".", "/", NULL, MS_MOVE, NULL) &&
+ !sys_chroot("."))
+ return 0;
+
+ panic("Failed to mount tmpfs as root filesystem");
+}
+
+
static int __init populate_rootfs(void)
{
- char *err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
+ char *err;
+
+ if (ramdisk_size)
+ change_root_to_tmpfs();
+
+ err = unpack_to_rootfs(__initramfs_start, __initramfs_size);
if (err)
panic(err); /* Failed to decompress INTERNAL initramfs */
if (initrd_start) {
#ifdef CONFIG_BLK_DEV_RAM
int fd;
+ if (ramdisk_size) {
+ printk(KERN_INFO "Unpacking initramfs...\n");
+ err = unpack_to_rootfs((char *)initrd_start,
+ initrd_end - initrd_start);
+ if (err)
+ panic(err);
+ free_initrd();
+ return 0;
+ }
printk(KERN_INFO "Trying to unpack rootfs image as initramfs...\n");
err = unpack_to_rootfs((char *)initrd_start,
initrd_end - initrd_start);