btrfs: if BTRFS_IOC_DEV_INFO returns /dev/root generate a friendly error message

On systems that boot without initrd on a btrfs root file systems the
BTRFS_IOC_DEV_INFO ioctl returns /dev/root as backing device. That
sucks, since that is not a real device visible to userspace.

Since this has been that way since forever, and it doesn't look like the
kernel will get fixed soon for this, let's at least generate a useful
error message in this case.

This is not a bug fix, just a tweak to make this more recognizable.

Once the kernel gets fixed to report the correct device nodes in this
case, in a way userspace can make sense of them things will magically
work for systemd, too.

(Note that this doesn't add a log message about this to really all cases
we call get_device() in, but just the main ones that are called in early
boot context, after all all there's no benefit in seeing this message
too many times.)

https://github.com/systemd/systemd/issues/16953
https://bugs.freedesktop.org/show_bug.cgi?id=84689
https://bugzilla.kernel.org/show_bug.cgi?id=89721
This commit is contained in:
Lennart Poettering
2020-09-08 18:10:26 +02:00
parent fc706b4816
commit 67f0ac8c79
5 changed files with 28 additions and 0 deletions
+9
View File
@@ -315,6 +315,15 @@ int btrfs_get_block_device_fd(int fd, dev_t *dev) {
return -errno;
}
/* For the root fs — when no initrd is involved — btrfs returns /dev/root on any kernels from
* the past few years. That sucks, as we have no API to determine the actual root then. let's
* return an recognizable error for this case, so that the caller can maybe print a nice
* message about this.
*
* https://bugzilla.kernel.org/show_bug.cgi?id=89721 */
if (path_equal((char*) di.path, "/dev/root"))
return -EUCLEAN;
if (stat((char*) di.path, &st) < 0)
return -errno;
+6
View File
@@ -121,3 +121,9 @@ int btrfs_qgroup_find_parents(int fd, uint64_t qgroupid, uint64_t **ret);
int btrfs_qgroup_get_quota_fd(int fd, uint64_t qgroupid, BtrfsQuotaInfo *quota);
int btrfs_qgroup_get_quota(const char *path, uint64_t qgroupid, BtrfsQuotaInfo *quota);
static inline int btrfs_log_dev_root(int level, int ret, const char *p) {
return log_full_errno(level, ret,
"File system behind %s is reported by btrfs to be backed by pseudo-device /dev/root, which is not a valid userspace accessible device node. "
"Cannot determine correct backing block device.", p);
}