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;
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);
+}
int r;
r = get_block_device_harder("/", &devno);
+ if (r == -EUCLEAN)
+ return btrfs_log_dev_root(LOG_ERR, r, "root file system");
if (r < 0)
return log_error_errno(r, "Failed to determine block device of root file system: %m");
if (r == 0) {
r = get_block_device_harder("/usr", &devno);
+ if (r == -EUCLEAN)
+ return btrfs_log_dev_root(LOG_ERR, r, "/usr");
if (r < 0)
return log_error_errno(r, "Failed to determine block device of /usr file system: %m");
if (r == 0) {
#include <sys/vfs.h>
#include "blockdev-util.h"
+#include "btrfs-util.h"
#include "cryptsetup-util.h"
#include "device-nodes.h"
#include "dissect-image.h"
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "\"%s\" is not a mount point: %m", arg_target);
r = get_block_device(arg_target, &devno);
+ if (r == -EUCLEAN)
+ return btrfs_log_dev_root(LOG_ERR, r, arg_target);
if (r < 0)
return log_error_errno(r, "Failed to determine block device of \"%s\": %m", arg_target);
/* Special support for btrfs */
r = btrfs_get_block_device_fd(source_fd, &devt);
+ if (r == -EUCLEAN)
+ return btrfs_log_dev_root(LOG_ERR, r, p->copy_blocks_path);
if (r < 0)
return log_error_errno(r, "Unable to determine backing block device of '%s': %m", p->copy_blocks_path);
}
r = acquire_root_devno(arg_node, O_RDONLY|O_CLOEXEC, ret, ret_fd);
+ if (r == -EUCLEAN)
+ return btrfs_log_dev_root(LOG_ERR, r, arg_node);
if (r < 0)
return log_error_errno(r, "Failed to open file or determine backing device of %s: %m", arg_node);
r = acquire_root_devno(p, O_RDONLY|O_DIRECTORY|O_CLOEXEC, ret, ret_fd);
if (r < 0) {
+ if (r == -EUCLEAN)
+ return btrfs_log_dev_root(LOG_ERR, r, p);
if (r != -ENODEV)
return log_error_errno(r, "Failed to determine backing device of %s: %m", p);
} else