Linux XFS filesystem development
 help / color / mirror / Atom feed
* [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