diff options
author | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-04-09 09:53:01 +0900 |
---|---|---|
committer | Yu Watanabe <watanabe.yu+github@gmail.com> | 2022-04-10 23:05:10 +0900 |
commit | 1a037ba238c626a6f37f18d2cfeeb79e025d2753 (patch) | |
tree | 7e57e4b9e2518001f3283313c8bf8796186005c8 /src/partition | |
parent | 41bc484906e973f6c91f8398a3ba309b7ee16f5a (diff) | |
download | systemd-1a037ba238c626a6f37f18d2cfeeb79e025d2753.tar.gz |
repart: use sd_device_open()
Then, we can safely open devices even if symlinks are not yet created by udevd.
Diffstat (limited to 'src/partition')
-rw-r--r-- | src/partition/repart.c | 85 |
1 files changed, 46 insertions, 39 deletions
diff --git a/src/partition/repart.c b/src/partition/repart.c index b6ac17c75e..34aa88198b 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -12,6 +12,7 @@ #include <sys/ioctl.h> #include <sys/stat.h> +#include "sd-device.h" #include "sd-id128.h" #include "alloc-util.h" @@ -3643,14 +3644,13 @@ static int resolve_copy_blocks_auto_candidate( sd_id128_t *ret_uuid) { _cleanup_(blkid_free_probep) blkid_probe b = NULL; - _cleanup_free_ char *p = NULL; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; _cleanup_close_ int fd = -1; - const char *pttype, *t; + const char *pttype, *t, *p; sd_id128_t pt_parsed, u; blkid_partition pp; dev_t whole_devno; blkid_partlist pl; - struct stat st; int r; /* Checks if the specified partition has the specified GPT type UUID, and is located on the specified @@ -3673,21 +3673,19 @@ static int resolve_copy_blocks_auto_candidate( major(partition_devno), minor(partition_devno), major(restrict_devno), minor(restrict_devno)); - r = device_path_make_major_minor(S_IFBLK, whole_devno, &p); + r = sd_device_new_from_devnum(&dev, 'b', whole_devno); if (r < 0) - return log_error_errno(r, "Failed to convert block device to device node path: %m"); - - fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK); - if (fd < 0) - return log_error_errno(r, "Failed to open '%s': %m", p); + return log_error_errno(r, "Failed to create sd-device for block device %u:%u: %m", + major(whole_devno), minor(whole_devno)); - if (fstat(fd, &st) < 0) - return log_error_errno(r, "Failed to stat '%s': %m", p); + r = sd_device_get_devname(dev, &p); + if (r < 0) + return log_error_errno(r, "Failed to get name of block device %u:%u: %m", + major(whole_devno), minor(whole_devno)); - if (!S_ISBLK(st.st_mode) || st.st_rdev != whole_devno) - return log_error_errno( - SYNTHETIC_ERRNO(EPERM), - "Opened and determined block device don't match, refusing."); + fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK); + if (fd < 0) + return log_error_errno(fd, "Failed to open block device %s: %m", p); b = blkid_new_probe(); if (!b) @@ -3805,7 +3803,7 @@ static int resolve_copy_blocks_auto( sd_id128_t type_uuid, const char *root, dev_t restrict_devno, - char **ret_path, + dev_t *ret_devno, sd_id128_t *ret_uuid) { const char *try1 = NULL, *try2 = NULL; @@ -3815,8 +3813,6 @@ static int resolve_copy_blocks_auto( dev_t devno, found = 0; int r; - assert(ret_path); - /* Enforce some security restrictions: CopyBlocks=auto should not be an avenue to get outside of the * --root=/--image= confinement. Specifically, refuse CopyBlocks= in combination with --root= at all, * and restrict block device references in the --image= case to loopback block device we set up. @@ -3926,9 +3922,8 @@ static int resolve_copy_blocks_auto( return log_error_errno(SYNTHETIC_ERRNO(ENXIO), "Unable to automatically discover suitable partition to copy blocks from."); - r = device_path_make_major_minor(S_IFBLK, found, ret_path); - if (r < 0) - return log_error_errno(r, "Failed to convert dev_t to device node path: %m"); + if (ret_devno) + *ret_devno = found; if (ret_uuid) *ret_uuid = found_uuid; @@ -3972,32 +3967,43 @@ static int context_open_copy_block_paths( "Copying from block device node is not permitted in --image=/--root= mode, refusing."); } else if (p->copy_blocks_auto) { + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + const char *devname; + dev_t devno; - r = resolve_copy_blocks_auto(p->type_uuid, root, restrict_devno, &opened, &uuid); + r = resolve_copy_blocks_auto(p->type_uuid, root, restrict_devno, &devno, &uuid); if (r < 0) return r; - source_fd = open(opened, O_RDONLY|O_CLOEXEC|O_NOCTTY); + r = sd_device_new_from_devnum(&dev, 'b', devno); + if (r < 0) + return log_error_errno(r, "Failed to create sd-device object for device %u:%u: %m", major(devno), minor(devno)); + + r = sd_device_get_devname(dev, &devname); + if (r < 0) + return log_error_errno(r, "Failed to get device name of %u:%u: %m", major(devno), minor(devno)); + + opened = strdup(devname); + if (!opened) + return log_oom(); + + source_fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK); if (source_fd < 0) - return log_error_errno(errno, "Failed to open automatically determined source block copy device '%s': %m", opened); + return log_error_errno(source_fd, "Failed to open automatically determined source block copy device '%s': %m", opened); if (fstat(source_fd, &st) < 0) return log_error_errno(errno, "Failed to stat block copy file '%s': %m", opened); - - /* If we found it automatically, it must be a block device, let's enforce that */ - if (!S_ISBLK(st.st_mode)) - return log_error_errno(SYNTHETIC_ERRNO(EBADF), - "Automatically detected source block copy device '%s' is not a block device, refusing: %m", opened); - } else + } else continue; if (S_ISDIR(st.st_mode)) { - _cleanup_free_ char *bdev = NULL; + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + const char *bdev; /* If the file is a directory, automatically find the backing block device */ if (major(st.st_dev) != 0) - r = device_path_make_major_minor(S_IFBLK, st.st_dev, &bdev); + r = sd_device_new_from_devnum(&dev, 'b', st.st_dev); else { dev_t devt; @@ -4009,22 +4015,23 @@ static int context_open_copy_block_paths( if (r < 0) return log_error_errno(r, "Unable to determine backing block device of '%s': %m", opened); - r = device_path_make_major_minor(S_IFBLK, devt, &bdev); + r = sd_device_new_from_devnum(&dev, 'b', devt); } if (r < 0) - return log_error_errno(r, "Failed to determine block device path for block device backing '%s': %m", opened); + return log_error_errno(r, "Failed to create sd-device object for block device backing '%s': %m", opened); + + r = sd_device_get_devpath(dev, &bdev); + if (r < 0) + return log_error_errno(r, "Failed to get device name for block device backing '%s': %m", opened); safe_close(source_fd); - source_fd = open(bdev, O_RDONLY|O_CLOEXEC|O_NOCTTY); + source_fd = sd_device_open(dev, O_RDONLY|O_CLOEXEC|O_NONBLOCK); if (source_fd < 0) - return log_error_errno(errno, "Failed to open block device '%s': %m", bdev); + return log_error_errno(source_fd, "Failed to open block device '%s': %m", bdev); if (fstat(source_fd, &st) < 0) return log_error_errno(errno, "Failed to stat block device '%s': %m", bdev); - - if (!S_ISBLK(st.st_mode)) - return log_error_errno(SYNTHETIC_ERRNO(ENOTBLK), "Block device '%s' is not actually a block device, refusing.", bdev); } if (S_ISREG(st.st_mode)) |