Merge pull request #16973 from poettering/btrfs-dev-root
print friendly error message if btrfs tells us /dev/root was backing block device of root fs
This commit is contained in:
commit
a1447e77a7
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ int quotactl_path(int cmd, const char *path, int id, void *addr) {
|
|||
r = get_block_device(path, &devno);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (devno == 0)
|
||||
if (devno == 0) /* Doesn't have a block device */
|
||||
return -ENODEV;
|
||||
|
||||
return quotactl_devno(cmd, devno, id, addr);
|
||||
|
|
|
@ -729,10 +729,14 @@ static int add_mounts(void) {
|
|||
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) {
|
||||
if (r == 0) { /* Not backed by block device */
|
||||
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) {
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <sys/vfs.h>
|
||||
|
||||
#include "blockdev-util.h"
|
||||
#include "btrfs-util.h"
|
||||
#include "cryptsetup-util.h"
|
||||
#include "device-nodes.h"
|
||||
#include "dissect-image.h"
|
||||
|
@ -96,6 +97,8 @@ static int maybe_resize_underlying_device(const char *mountpath, dev_t main_devn
|
|||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine underlying block device of \"%s\": %m",
|
||||
mountpath);
|
||||
if (devno == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" not backed by block device.", arg_target);
|
||||
|
||||
log_debug("Underlying device %d:%d, main dev %d:%d, %s",
|
||||
major(devno), minor(devno),
|
||||
|
@ -212,8 +215,12 @@ static int run(int argc, char *argv[]) {
|
|||
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);
|
||||
if (devno == 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "File system \"%s\" not backed by block device.", arg_target);
|
||||
|
||||
r = maybe_resize_underlying_device(arg_target, devno);
|
||||
if (r < 0)
|
||||
|
|
|
@ -3369,6 +3369,8 @@ static int context_open_copy_block_paths(Context *context) {
|
|||
/* 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);
|
||||
|
||||
|
@ -3833,6 +3835,8 @@ static int find_root(char **ret, int *ret_fd) {
|
|||
}
|
||||
|
||||
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);
|
||||
|
||||
|
@ -3860,6 +3864,8 @@ static int find_root(char **ret, int *ret_fd) {
|
|||
|
||||
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
|
||||
|
|
|
@ -403,6 +403,8 @@ int find_hibernate_location(HibernateLocation **ret_hibernate_location) {
|
|||
r = swap_device_to_device_id(swap, &swap_device);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "%s: failed to query device number: %m", swap->device);
|
||||
if (swap_device == 0)
|
||||
return log_debug_errno(SYNTHETIC_ERRNO(ENODEV), "%s: not backed by block device.", swap->device);
|
||||
|
||||
hibernate_location = hibernate_location_free(hibernate_location);
|
||||
hibernate_location = new(HibernateLocation, 1);
|
||||
|
|
|
@ -175,7 +175,7 @@ static int run(int argc, char *argv[]) {
|
|||
r = get_block_device_harder(path, &devt);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to determine device major/minor of %s: %m", path);
|
||||
else if (r > 0) {
|
||||
else if (r > 0) { /* backed by block device */
|
||||
_cleanup_free_ char *dn = NULL;
|
||||
|
||||
r = device_path_make_major_minor(S_IFBLK, devt, &dn);
|
||||
|
|
Loading…
Reference in New Issue