Bug 33952 - kernel unable to mount root оn BTRFS with multiple devices
Summary: kernel unable to mount root оn BTRFS with multiple devices
Status: RESOLVED DOCUMENTED
Alias: None
Product: File System
Classification: Unclassified
Component: btrfs (show other bugs)
Hardware: All Linux
: P1 normal
Assignee: fs_btrfs@kernel-bugs.osdl.org
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-04-26 05:40 UTC by Egor Y. Egorov
Modified: 2014-08-26 11:13 UTC (History)
3 users (show)

See Also:
Kernel Version: 2.6.38
Subsystem:
Regression: No
Bisected commit-id:


Attachments

Description Egor Y. Egorov 2011-04-26 05:40:08 UTC
I using Gentoo with gentoo-sources-2.6.38-r3 and can't start system on root on btrfs with multiple devices.

1. Create root оn btrfs-raid:
mkfs.btrfs /dev/sda3 /dev/sdb3 -d raid1 -m raid1
and host rootfs. 
2. Assemble kernel with BTRFS support (CONFIG_BTRFS_FS=y)
3. Boot kernel with command line:
root=/dev/sda3 rootfstype=btrfs rootflags=device=/dev/sdb3
(without initrd)

Actual result: kernel unable mount root
Expected result: kernel able mount root

PS:
1. With rootflags=degraded kernel able mount root
2. If boot on LiveCD, mounting able with command
mount /dev/sda3 -o device=/dev/sdb3 /mnt/gentoo
Comment 1 Josef Bacik 2013-04-30 16:39:09 UTC
Closing, if this is still affecting you on a newer kernel please reopen.
Comment 2 Egor Y. Egorov 2013-05-07 02:16:36 UTC
Reprodused on my system with kernel 3.9.0 and rootfs on btrfs-raid0:
egorov-ey ~ # btrfs filesystem show --all-devices /dev/sdd
Label: 'BTRFS-RAID0'  uuid: da81a15f-c4d7-4252-8673-6504aadd074e
        Total devices 2 FS bytes used 25.94GB
        devid    1 size 232.89GB used 19.03GB path /dev/sdc
        devid    2 size 232.89GB used 19.01GB path /dev/sdd

Btrfs v0.20-rc1-253-g7854c8b

kernel can not mount fs without initramfs and with commandline
rootfstype=btrfs root/dev/sdc rootflags=device=/dev/sdd,subvol=/ROOT
Comment 3 Egor Y. Egorov 2013-05-07 02:24:16 UTC
>root=/dev/sdc
fix typo
Comment 4 Josef Bacik 2013-05-14 20:50:45 UTC
Ok this is because you need to fix your initramfs to run btrfs device scan before it tries to mount the file system, then it will work fine.
Comment 5 Egor Y. Egorov 2014-08-13 05:20:19 UTC
(In reply to Josef Bacik from comment #4)
> Ok this is because you need to fix your initramfs to run btrfs device scan
> before it tries to mount the file system, then it will work fine.

Hello. What you think about patch from this thread?
https://forums.gentoo.org/viewtopic-t-923554-start-0.html
Comment 6 Egor Y. Egorov 2014-08-14 02:43:43 UTC
this patch solve the problem in my case

diff --git a/init/do_mounts.c b/init/do_mounts.c
index 82f2288..6d58f8d 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -484,7 +484,10 @@ void __init change_floppy(char *fmt, ...)
        va_start(args, fmt);
        vsprintf(buf, fmt, args);
        va_end(args);
-       fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
+       if (saved_root_name[0])
+               fd = sys_open(saved_root_name, O_RDWR | O_NDELAY, 0);
+       else
+               fd = sys_open("/dev/root", O_RDWR | O_NDELAY, 0);
        if (fd >= 0) {
                sys_ioctl(fd, FDEJECT, 0);
                sys_close(fd);
@@ -528,7 +531,14 @@ void __init mount_root(void)
 #endif
 #ifdef CONFIG_BLOCK
        create_dev("/dev/root", ROOT_DEV);
-       mount_block_root("/dev/root", root_mountflags);
+       if (saved_root_name[0]) {
+               create_dev(saved_root_name, ROOT_DEV);
+               devtmpfs_mount("dev");
+               mount_block_root(saved_root_name, root_mountflags);
+       } else {
+               create_dev("/dev/root", ROOT_DEV);
+               mount_block_root("/dev/root", root_mountflags);
+       }
 #endif
 }
Comment 7 Michał Górny 2014-08-25 18:41:00 UTC
Egor, thanks for the tips but I myself have serious doubts about your patch. Could you document a bit what you did and why was it necessary? I'm not a kernel expert but the following looks suspicious to me:

1. in the 'else' branch, create_dev("/dev/root", ROOT_DEV) is called second time with the same arguments as before the 'if'... is that intentional?

2. What purpose does using saved_root_name serve? I don't see how it is relevant here -- and AFAIU mounting devtmpfs will result in the device being created as well.

3. Can devtmpfs_mount() at this point have some side effects?


That said, I was able to get my multi-device btrfs mounted using a simpler patch:

diff --git a/init/do_mounts.c b/init/do_mounts.c
index e35fb52..434a54e 100644
--- a/init/do_mounts.c
+++ b/init/do_mounts.c
@@ -528,6 +528,7 @@ void __init mount_root(void)
        }
 #endif
 #ifdef CONFIG_BLOCK
+       devtmpfs_mount("dev");
        create_dev("/dev/root", ROOT_DEV);
        mount_block_root("/dev/root", root_mountflags);
 #endif
Comment 8 Egor Y. Egorov 2014-08-26 02:48:04 UTC
(In reply to Michał Górny from comment #7)
> Egor, thanks for the tips but I myself have serious doubts about your patch.
> Could you document a bit what you did and why was it necessary? I'm not a
> kernel expert but the following looks suspicious to me:
> 
> 1. in the 'else' branch, create_dev("/dev/root", ROOT_DEV) is called second
> time with the same arguments as before the 'if'... is that intentional?
> 2. What purpose does using saved_root_name serve? I don't see how it is
> relevant here -- and AFAIU mounting devtmpfs will result in the device being
> created as well.

I'm not a kernel expert too :) This is part of genpatches included in gentoo-sources. 
http://sources.gentoo.org/cgi-bin/viewvc.cgi/linux-patches/genpatches-2.6/trunk/3.15/2900_dev-root-proc-mount-fix.patch?revision=2771&view=markup

You can ask about this mpagano. 
And here: https://bugs.gentoo.org/show_bug.cgi?id=438380

> 3. Can devtmpfs_mount() at this point have some side effects?
> That said, I was able to get my multi-device btrfs mounted using a simpler
> patch:
> 
> diff --git a/init/do_mounts.c b/init/do_mounts.c
> index e35fb52..434a54e 100644
> --- a/init/do_mounts.c
> +++ b/init/do_mounts.c
> @@ -528,6 +528,7 @@ void __init mount_root(void)
>         }
>  #endif
>  #ifdef CONFIG_BLOCK
> +       devtmpfs_mount("dev");
>         create_dev("/dev/root", ROOT_DEV);
>         mount_block_root("/dev/root", root_mountflags);
>  #endif
Yes, this path is working as well.

The very fact of the mount I think it is unlikely to have a negative effect. But in some cases this can cause twice mounted devtmpfs: before mount root and after. So this patch is not ideal. May be should introduce new kernel-option: CONFIG_DEVTMPFS_PREMOUNT by analogy with CONFIG_DEVTMPFS_MOUNT and rework logic of mounting.

> i'm looking for Egor Y. Egorov - any chance you know where to find him? :)
Do not hesitate to write me email or xmmp: eegorov@jabber.ru ;)
Comment 9 Michał Górny 2014-08-26 07:30:33 UTC
Well, you definitely don't want to be mixing two patches together here. As far as I understand, the goal of genpatches patch is to not have /dev/root and use the root directly.

On top of that patch, I think it's enough to replace create_dev(saved_root_name, ROOT_DEV) with the mount -- devtmpfs will have the proper device anyway.

Note You need to log in before you can comment on or make changes to this bug.