* [PATCH] libfrog: obtain the actual available device when the root device is /dev/root
@ 2025-09-09 11:29 Wu Guanghao
2025-09-10 0:06 ` Dave Chinner
0 siblings, 1 reply; 3+ messages in thread
From: Wu Guanghao @ 2025-09-09 11:29 UTC (permalink / raw)
To: aalbersh, Darrick J. Wong; +Cc: linux-xfs, yangyun50
When starting a Fedora virtual machine using QEMU, if the device corresponding
to the root directory is the entire disk or a disk partition, the device
recorded in /proc/self/mounts will be /dev/root instead of the true device.
This can lead to the failure of executing commands such as xfs_growfs/xfs_info.
$ cat /proc/self/mounts
/dev/root / xfs rw,seclabel,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota 0 0
devtmpfs /dev devtmpfs rw,seclabel,relatime,size=4065432k,nr_inodes=1016358,mode=755 0 0
...
$ mount
/dev/sda3 on / type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
devtmpfs on /dev type devtmpfs (rw,relatime,seclabel,size=4065432k,nr_inodes=1016358,mode=755)
...
$ xfs_growfs /
xfs_growfs: / is not a mounted XFS filesystem
$ xfs_growfs /dev/sda3
xfs_growfs: /dev/sda3 is not a mounted XFS filesystem
$ xfs_info /
/: cannot find mount point.#
So, if the root device is found to be /dev/root, we need to obtain the
corresponding real device first.
Signed-off-by: Wu Guanghao <wuguanghao3@huawei.com>
---
libfrog/paths.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 48 insertions(+)
diff --git a/libfrog/paths.c b/libfrog/paths.c
index a5dfab48..6ff649b8 100644
--- a/libfrog/paths.c
+++ b/libfrog/paths.c
@@ -352,6 +352,38 @@ out_nomem:
return ENOMEM;
}
+static char *get_real_root_device(struct mntent *mnt)
+{
+ struct stat st;
+ char path[PATH_MAX], linkpath[PATH_MAX];
+ ssize_t len;
+ char *fake_root_device = "/dev/root";
+ /*
+ * The /dev/root does not point to a real root device, we need to obtain the
+ * real device.
+ */
+ if (strlen(mnt->mnt_fsname) != strlen(fake_root_device) ||
+ strcmp(mnt->mnt_fsname, fake_root_device))
+ return NULL;
+
+ if (stat(mnt->mnt_dir, &st) < 0)
+ return NULL;
+
+ snprintf(path, sizeof(path), "/sys/dev/block/%d:%d", major(st.st_dev), minor(st.st_dev));
+ len = readlink(path, linkpath, sizeof(linkpath) - 1);
+ if (len < 0 || len >= PATH_MAX)
+ return NULL;
+
+ linkpath[len] = '\0';
+
+ char *p = strrchr(linkpath, '/');
+ if (!p || strlen(p) <= 1)
+ return NULL;
+
+ snprintf(path, sizeof(path), "/dev/%s", p + 1);
+ return strdup(path);
+}
+
/*
* If *path is NULL, initialize the fs table with all xfs mount points in mtab
* If *path is specified, search for that path in mtab
@@ -359,6 +391,7 @@ out_nomem:
* Everything - path, devices, and mountpoints - are boiled down to realpath()
* for comparison, but fs_table is populated with what comes from getmntent.
*/
+
static int
fs_table_initialise_mounts(
char *path)
@@ -368,6 +401,8 @@ fs_table_initialise_mounts(
char *fslog, *fsrt;
int error, found;
char rpath[PATH_MAX], rmnt_fsname[PATH_MAX], rmnt_dir[PATH_MAX];
+ bool change_device = false;
+ char *fsname = NULL;
error = found = 0;
fslog = fsrt = NULL;
@@ -391,6 +426,13 @@ fs_table_initialise_mounts(
continue;
if (!realpath(mnt->mnt_dir, rmnt_dir))
continue;
+
+ fsname = get_real_root_device(mnt);
+ if (fsname) {
+ change_device = true;
+ mnt->mnt_fsname = fsname;
+ }
+
if (!realpath(mnt->mnt_fsname, rmnt_fsname))
continue;
@@ -402,6 +444,12 @@ fs_table_initialise_mounts(
continue;
(void) fs_table_insert(mnt->mnt_dir, 0, FS_MOUNT_POINT,
mnt->mnt_fsname, fslog, fsrt);
+
+ if (change_device) {
+ free(fsname);
+ change_device = false;
+ }
+
if (path) {
found = 1;
break;
--
2.51.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] libfrog: obtain the actual available device when the root device is /dev/root
2025-09-09 11:29 [PATCH] libfrog: obtain the actual available device when the root device is /dev/root Wu Guanghao
@ 2025-09-10 0:06 ` Dave Chinner
2025-09-10 1:42 ` Wu Guanghao
0 siblings, 1 reply; 3+ messages in thread
From: Dave Chinner @ 2025-09-10 0:06 UTC (permalink / raw)
To: Wu Guanghao; +Cc: aalbersh, Darrick J. Wong, linux-xfs, yangyun50
On Tue, Sep 09, 2025 at 07:29:02PM +0800, Wu Guanghao wrote:
> When starting a Fedora virtual machine using QEMU, if the device corresponding
> to the root directory is the entire disk or a disk partition, the device
> recorded in /proc/self/mounts will be /dev/root instead of the true device.
How does this /dev/root situation occur? My fedora VMs
show the real root device and not /dev/root in /proc/self/mounts,
so it's not clear to me why /dev/root is being reported here?
This smells of a custom boot sequence that is mounting the root
filesystem on a temporary initramfs /dev/root node (which then gets
removed once the initramfs is done) rather than using pivot_root to
move the real root fs into place once the real device nodes have
been initialised and the root fs mounted using them...
> This can lead to the failure of executing commands such as xfs_growfs/xfs_info.
>
> $ cat /proc/self/mounts
> /dev/root / xfs rw,seclabel,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota 0 0
> devtmpfs /dev devtmpfs rw,seclabel,relatime,size=4065432k,nr_inodes=1016358,mode=755 0 0
> ...
>
> $ mount
> /dev/sda3 on / type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
> devtmpfs on /dev type devtmpfs (rw,relatime,seclabel,size=4065432k,nr_inodes=1016358,mode=755)
> ...
>
> $ xfs_growfs /
> xfs_growfs: / is not a mounted XFS filesystem
>
> $ xfs_growfs /dev/sda3
> xfs_growfs: /dev/sda3 is not a mounted XFS filesystem
>
> $ xfs_info /
> /: cannot find mount point.#
>
> So, if the root device is found to be /dev/root, we need to obtain the
> corresponding real device first.
IMO, having a bogus device in /proc/self/mounts output is the
problem that needs to be fixed here. Working around a broken
/dev/root device in every userspace utility that reads
/proc/self/mounts does not feel like the right way to address this
problem.
-Dave.
--
Dave Chinner
david@fromorbit.com
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] libfrog: obtain the actual available device when the root device is /dev/root
2025-09-10 0:06 ` Dave Chinner
@ 2025-09-10 1:42 ` Wu Guanghao
0 siblings, 0 replies; 3+ messages in thread
From: Wu Guanghao @ 2025-09-10 1:42 UTC (permalink / raw)
To: Dave Chinner; +Cc: aalbersh, Darrick J. Wong, linux-xfs, yangyun50
在 2025/9/10 8:06, Dave Chinner 写道:
> On Tue, Sep 09, 2025 at 07:29:02PM +0800, Wu Guanghao wrote:
>> When starting a Fedora virtual machine using QEMU, if the device corresponding
>> to the root directory is the entire disk or a disk partition, the device
>> recorded in /proc/self/mounts will be /dev/root instead of the true device.
>
> How does this /dev/root situation occur? My fedora VMs
> show the real root device and not /dev/root in /proc/self/mounts,
> so it's not clear to me why /dev/root is being reported here?
>
I am using a Fedora 42 Server qcow2 image, and then I convert the image to partitions
and LVM devices using qemu-nbd. Afterwards, I pass through the partition devices and
LVM devices using qemu.
$ lsblk
...
nbd0 43:0 0 10G 0 disk
├─nbd0p1 43:1 0 500M 0 part
├─nbd0p2 43:2 0 1000M 0 part
└─nbd0p3 43:3 0 8.5G 0 part
└─systemVG-LVRoot 253:7 0 8.5G 0 lvm
qemu start scripts:
qemu-system-aarch64 \
... \
-drive id=root,if=virtio,media=disk,format=raw,file=/dev/systemVG/LVRoot \
-drive id=boot,if=virtio,media=disk,format=raw,file=/dev/nbd0p2 \
-drive id=efi,if=virtio,media=disk,format=raw,file=/dev/nbd0p1 \
> This smells of a custom boot sequence that is mounting the root
> filesystem on a temporary initramfs /dev/root node (which then gets
> removed once the initramfs is done) rather than using pivot_root to
> move the real root fs into place once the real device nodes have
> been initialised and the root fs mounted using them...
>
>> This can lead to the failure of executing commands such as xfs_growfs/xfs_info.
>>
>> $ cat /proc/self/mounts
>> /dev/root / xfs rw,seclabel,relatime,attr2,inode64,logbufs=8,logbsize=32k,noquota 0 0
>> devtmpfs /dev devtmpfs rw,seclabel,relatime,size=4065432k,nr_inodes=1016358,mode=755 0 0
>> ...
>
>>
>> $ mount
>> /dev/sda3 on / type xfs (rw,relatime,seclabel,attr2,inode64,logbufs=8,logbsize=32k,noquota)
>> devtmpfs on /dev type devtmpfs (rw,relatime,seclabel,size=4065432k,nr_inodes=1016358,mode=755)
>> ...
>>
>> $ xfs_growfs /
>> xfs_growfs: / is not a mounted XFS filesystem
>>
>> $ xfs_growfs /dev/sda3
>> xfs_growfs: /dev/sda3 is not a mounted XFS filesystem
>>
>> $ xfs_info /
>> /: cannot find mount point.#
>>
>> So, if the root device is found to be /dev/root, we need to obtain the
>> corresponding real device first.
>
> IMO, having a bogus device in /proc/self/mounts output is the
> problem that needs to be fixed here. Working around a broken
> /dev/root device in every userspace utility that reads
> /proc/self/mounts does not feel like the right way to address this
> problem.
>
I have reviewed the source code of the util-linux mount command and the e2fsprogs resize2fs command,
and both of these have logic for checking and handling /dev/root.
> -Dave.
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-09-10 1:42 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-09-09 11:29 [PATCH] libfrog: obtain the actual available device when the root device is /dev/root Wu Guanghao
2025-09-10 0:06 ` Dave Chinner
2025-09-10 1:42 ` Wu Guanghao
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox