summaryrefslogtreecommitdiff
path: root/src/partition
diff options
context:
space:
mode:
authorYu Watanabe <watanabe.yu+github@gmail.com>2022-04-09 09:53:01 +0900
committerYu Watanabe <watanabe.yu+github@gmail.com>2022-04-10 23:05:10 +0900
commit1a037ba238c626a6f37f18d2cfeeb79e025d2753 (patch)
tree7e57e4b9e2518001f3283313c8bf8796186005c8 /src/partition
parent41bc484906e973f6c91f8398a3ba309b7ee16f5a (diff)
downloadsystemd-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.c85
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))