mirror of
https://github.com/systemd/systemd.git
synced 2026-08-03 22:50:29 +00:00
Merge pull request #24536 from yuwata/dissect-take-loop-device
dissect-image: introduce dissect_loop_device() which takes LoopDevice object
This commit is contained in:
@@ -2063,13 +2063,10 @@ int setup_namespace(
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create loop device for root image: %m");
|
||||
|
||||
r = dissect_image(
|
||||
loop_device->fd,
|
||||
r = dissect_loop_device(
|
||||
loop_device,
|
||||
&verity,
|
||||
root_image_options,
|
||||
loop_device->diskseq,
|
||||
loop_device->uevent_seqnum_not_before,
|
||||
loop_device->timestamp_not_before,
|
||||
dissect_image_flags,
|
||||
&dissected_image);
|
||||
if (r < 0)
|
||||
|
||||
@@ -304,7 +304,7 @@ static int swap_load_devnode(Swap *s) {
|
||||
if (stat(s->what, &st) < 0 || !S_ISBLK(st.st_mode))
|
||||
return 0;
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, st.st_rdev, &p);
|
||||
r = devname_from_stat_rdev(&st, &p);
|
||||
if (r < 0) {
|
||||
log_unit_full_errno(UNIT(s), r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Failed to get device node for swap %s: %m", s->what);
|
||||
|
||||
@@ -880,7 +880,7 @@ static int action_umount(const char *path) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to find backing block device for '%s': %m", canonical);
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devno, &devname);
|
||||
r = devname_from_devnum(S_IFBLK, devno, &devname);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get devname of block device " DEVNUM_FORMAT_STR ": %m",
|
||||
DEVNUM_FORMAT_VAL(devno));
|
||||
@@ -945,14 +945,11 @@ static int run(int argc, char *argv[]) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up loopback device for %s: %m", arg_image);
|
||||
|
||||
r = dissect_image_and_warn(
|
||||
d->fd,
|
||||
r = dissect_loop_device_and_warn(
|
||||
arg_image,
|
||||
d,
|
||||
&arg_verity_settings,
|
||||
NULL,
|
||||
d->diskseq,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
arg_flags,
|
||||
&m);
|
||||
if (r < 0)
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "fd-util.h"
|
||||
#include "string-util.h"
|
||||
|
||||
int devpath_from_devnum(mode_t mode, dev_t devnum, char **ret) {
|
||||
int devname_from_devnum(mode_t mode, dev_t devnum, char **ret) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
|
||||
_cleanup_free_ char *s = NULL;
|
||||
const char *devname;
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "sd-device.h"
|
||||
@@ -81,5 +82,9 @@
|
||||
#define log_device_warning_errno(device, error, ...) log_device_full_errno(device, LOG_WARNING, error, __VA_ARGS__)
|
||||
#define log_device_error_errno(device, error, ...) log_device_full_errno(device, LOG_ERR, error, __VA_ARGS__)
|
||||
|
||||
int devpath_from_devnum(mode_t mode, dev_t devnum, char **ret);
|
||||
int devname_from_devnum(mode_t mode, dev_t devnum, char **ret);
|
||||
static inline int devname_from_stat_rdev(const struct stat *st, char **ret) {
|
||||
assert(st);
|
||||
return devname_from_devnum(st->st_mode, st->st_rdev, ret);
|
||||
}
|
||||
int device_open_from_devnum(mode_t mode, dev_t devnum, int flags, char **ret);
|
||||
|
||||
@@ -500,7 +500,7 @@ TEST(sd_device_new_from_path) {
|
||||
}
|
||||
}
|
||||
|
||||
static void test_devpath_from_devnum_one(const char *path) {
|
||||
static void test_devname_from_devnum_one(const char *path) {
|
||||
_cleanup_free_ char *resolved = NULL;
|
||||
struct stat st;
|
||||
|
||||
@@ -512,21 +512,24 @@ static void test_devpath_from_devnum_one(const char *path) {
|
||||
return;
|
||||
}
|
||||
|
||||
assert_se(devpath_from_devnum(st.st_mode, st.st_rdev, &resolved) >= 0);
|
||||
assert_se(devname_from_devnum(st.st_mode, st.st_rdev, &resolved) >= 0);
|
||||
assert_se(path_equal(path, resolved));
|
||||
resolved = mfree(resolved);
|
||||
assert_se(devname_from_stat_rdev(&st, &resolved) >= 0);
|
||||
assert_se(path_equal(path, resolved));
|
||||
}
|
||||
|
||||
TEST(devpath_from_devnum) {
|
||||
test_devpath_from_devnum_one("/dev/null");
|
||||
test_devpath_from_devnum_one("/dev/zero");
|
||||
test_devpath_from_devnum_one("/dev/full");
|
||||
test_devpath_from_devnum_one("/dev/random");
|
||||
test_devpath_from_devnum_one("/dev/urandom");
|
||||
test_devpath_from_devnum_one("/dev/tty");
|
||||
TEST(devname_from_devnum) {
|
||||
test_devname_from_devnum_one("/dev/null");
|
||||
test_devname_from_devnum_one("/dev/zero");
|
||||
test_devname_from_devnum_one("/dev/full");
|
||||
test_devname_from_devnum_one("/dev/random");
|
||||
test_devname_from_devnum_one("/dev/urandom");
|
||||
test_devname_from_devnum_one("/dev/tty");
|
||||
|
||||
if (is_device_node("/run/systemd/inaccessible/blk") > 0) {
|
||||
test_devpath_from_devnum_one("/run/systemd/inaccessible/chr");
|
||||
test_devpath_from_devnum_one("/run/systemd/inaccessible/blk");
|
||||
test_devname_from_devnum_one("/run/systemd/inaccessible/chr");
|
||||
test_devname_from_devnum_one("/run/systemd/inaccessible/blk");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -900,7 +900,7 @@ static int oci_devices(const char *name, JsonVariant *v, JsonDispatchFlags flags
|
||||
}
|
||||
|
||||
/* Suppress a couple of implicit device nodes */
|
||||
r = devpath_from_devnum(node->mode, makedev(node->major, node->minor), &path);
|
||||
r = devname_from_devnum(node->mode, makedev(node->major, node->minor), &path);
|
||||
if (r < 0)
|
||||
json_log(e, flags|JSON_DEBUG, 0, "Failed to resolve device node %u:%u, ignoring: %m", node->major, node->minor);
|
||||
else {
|
||||
|
||||
@@ -5753,14 +5753,11 @@ static int run(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = dissect_image_and_warn(
|
||||
loop->fd,
|
||||
r = dissect_loop_device_and_warn(
|
||||
arg_image,
|
||||
loop,
|
||||
&arg_verity_settings,
|
||||
NULL,
|
||||
loop->diskseq,
|
||||
loop->uevent_seqnum_not_before,
|
||||
loop->timestamp_not_before,
|
||||
dissect_image_flags,
|
||||
&dissected_image);
|
||||
if (r == -ENOPKG) {
|
||||
|
||||
@@ -55,7 +55,7 @@ static int resize_crypt_luks_device(dev_t devno, const char *fstype, dev_t main_
|
||||
|
||||
log_debug("%s is %"PRIu64" bytes", main_devpath, size);
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devno, &devpath);
|
||||
r = devname_from_devnum(S_IFBLK, devno, &devpath);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get devpath of " DEVNUM_FORMAT_STR ": %m",
|
||||
DEVNUM_FORMAT_VAL(devno));
|
||||
@@ -117,7 +117,7 @@ static int maybe_resize_underlying_device(
|
||||
if (devno == main_devno)
|
||||
return 0;
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devno, &devpath);
|
||||
r = devname_from_devnum(S_IFBLK, devno, &devpath);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get devpath for block device " DEVNUM_FORMAT_STR ": %m",
|
||||
DEVNUM_FORMAT_VAL(devno));
|
||||
|
||||
@@ -4508,7 +4508,7 @@ static int acquire_root_devno(
|
||||
if (r < 0)
|
||||
log_debug_errno(r, "Failed to find whole disk block device for '%s', ignoring: %m", p);
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devno, ret);
|
||||
r = devname_from_devnum(S_IFBLK, devno, ret);
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to determine canonical path for '%s': %m", p);
|
||||
|
||||
|
||||
@@ -365,12 +365,9 @@ static int portable_extract_by_path(
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create temporary directory: %m");
|
||||
|
||||
r = dissect_image(
|
||||
d->fd,
|
||||
r = dissect_loop_device(
|
||||
d,
|
||||
NULL, NULL,
|
||||
d->diskseq,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
DISSECT_IMAGE_READ_ONLY |
|
||||
DISSECT_IMAGE_GENERIC_ROOT |
|
||||
DISSECT_IMAGE_REQUIRE_ROOT |
|
||||
|
||||
@@ -1196,12 +1196,9 @@ int image_read_metadata(Image *i) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = dissect_image(
|
||||
d->fd,
|
||||
r = dissect_loop_device(
|
||||
d,
|
||||
NULL, NULL,
|
||||
d->diskseq,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
DISSECT_IMAGE_GENERIC_ROOT |
|
||||
DISSECT_IMAGE_REQUIRE_ROOT |
|
||||
DISSECT_IMAGE_RELAX_VAR_CHECK |
|
||||
|
||||
@@ -2796,29 +2796,23 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dissect_image_and_warn(
|
||||
int fd,
|
||||
int dissect_loop_device_and_warn(
|
||||
const char *name,
|
||||
const LoopDevice *loop,
|
||||
const VeritySettings *verity,
|
||||
const MountOptions *mount_options,
|
||||
uint64_t diskseq,
|
||||
uint64_t uevent_seqnum_not_before,
|
||||
usec_t timestamp_not_before,
|
||||
DissectImageFlags flags,
|
||||
DissectedImage **ret) {
|
||||
|
||||
_cleanup_free_ char *buffer = NULL;
|
||||
int r;
|
||||
|
||||
if (!name) {
|
||||
r = fd_get_path(fd, &buffer);
|
||||
if (r < 0)
|
||||
return r;
|
||||
assert(loop);
|
||||
assert(loop->fd >= 0);
|
||||
|
||||
name = buffer;
|
||||
}
|
||||
if (!name)
|
||||
name = ASSERT_PTR(loop->node);
|
||||
|
||||
r = dissect_image(fd, verity, mount_options, diskseq, uevent_seqnum_not_before, timestamp_not_before, flags, ret);
|
||||
r = dissect_loop_device(loop, verity, mount_options, flags, ret);
|
||||
switch (r) {
|
||||
|
||||
case -EOPNOTSUPP:
|
||||
@@ -2971,7 +2965,7 @@ int mount_image_privately_interactively(
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up loopback device for %s: %m", image);
|
||||
|
||||
r = dissect_image_and_warn(d->fd, image, &verity, NULL, d->diskseq, d->uevent_seqnum_not_before, d->timestamp_not_before, flags, &dissected_image);
|
||||
r = dissect_loop_device_and_warn(image, d, &verity, NULL, flags, &dissected_image);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@@ -3082,24 +3076,18 @@ int verity_dissect_and_mount(
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to create loop device for image: %m");
|
||||
|
||||
r = dissect_image(
|
||||
loop_device->fd,
|
||||
r = dissect_loop_device(
|
||||
loop_device,
|
||||
&verity,
|
||||
options,
|
||||
loop_device->diskseq,
|
||||
loop_device->uevent_seqnum_not_before,
|
||||
loop_device->timestamp_not_before,
|
||||
dissect_image_flags,
|
||||
&dissected_image);
|
||||
/* No partition table? Might be a single-filesystem image, try again */
|
||||
if (!verity.data_path && r == -ENOPKG)
|
||||
r = dissect_image(
|
||||
loop_device->fd,
|
||||
r = dissect_loop_device(
|
||||
loop_device,
|
||||
&verity,
|
||||
options,
|
||||
loop_device->diskseq,
|
||||
loop_device->uevent_seqnum_not_before,
|
||||
loop_device->timestamp_not_before,
|
||||
dissect_image_flags | DISSECT_IMAGE_NO_PARTITION_TABLE,
|
||||
&dissected_image);
|
||||
if (r < 0)
|
||||
|
||||
@@ -254,7 +254,11 @@ const char* mount_options_from_designator(const MountOptions *options, Partition
|
||||
|
||||
int probe_filesystem(const char *node, char **ret_fstype);
|
||||
int dissect_image(int fd, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
int dissect_image_and_warn(int fd, const char *name, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
|
||||
static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) {
|
||||
assert(loop);
|
||||
return dissect_image(loop->fd, verity, mount_options, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, flags, ret);
|
||||
}
|
||||
int dissect_loop_device_and_warn(const char *name, const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
||||
|
||||
DissectedImage* dissected_image_unref(DissectedImage *m);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
|
||||
|
||||
@@ -45,7 +45,7 @@ static int verify_esp_blkid(
|
||||
const char *v;
|
||||
int r;
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devid, &node);
|
||||
r = devname_from_devnum(S_IFBLK, devid, &node);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get device path for " DEVNUM_FORMAT_STR ": %m", DEVNUM_FORMAT_VAL(devid));
|
||||
|
||||
@@ -508,7 +508,7 @@ static int verify_xbootldr_blkid(
|
||||
const char *type, *v;
|
||||
int r;
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devid, &node);
|
||||
r = devname_from_devnum(S_IFBLK, devid, &node);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get block device path for " DEVNUM_FORMAT_STR ": %m",
|
||||
DEVNUM_FORMAT_VAL(devid));
|
||||
|
||||
@@ -358,7 +358,7 @@ static int loop_device_make_internal(
|
||||
LoopDevice **ret) {
|
||||
|
||||
_cleanup_close_ int direct_io_fd = -1, lock_fd = -1;
|
||||
_cleanup_free_ char *loopdev = NULL;
|
||||
_cleanup_free_ char *node = NULL;
|
||||
bool try_loop_configure = true;
|
||||
struct loop_config config;
|
||||
LoopDevice *d = NULL;
|
||||
@@ -390,8 +390,13 @@ static int loop_device_make_internal(
|
||||
#endif
|
||||
nr = config.info.lo_number;
|
||||
|
||||
if (asprintf(&loopdev, "/dev/loop%i", nr) < 0)
|
||||
if (asprintf(&node, "/dev/loop%i", nr) < 0)
|
||||
return -ENOMEM;
|
||||
} else {
|
||||
/* This is a non-loopback block device. Let's get the path to the device node. */
|
||||
r = devname_from_stat_rdev(&st, &node);
|
||||
if (r < 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (offset == 0 && IN_SET(size, 0, UINT64_MAX)) {
|
||||
@@ -420,7 +425,7 @@ static int loop_device_make_internal(
|
||||
.fd = TAKE_FD(copy),
|
||||
.lock_fd = TAKE_FD(lock_fd),
|
||||
.nr = nr,
|
||||
.node = TAKE_PTR(loopdev),
|
||||
.node = TAKE_PTR(node),
|
||||
.relinquished = true, /* It's not allocated by us, don't destroy it when this object is freed */
|
||||
.devno = st.st_rdev,
|
||||
.diskseq = diskseq,
|
||||
@@ -501,10 +506,10 @@ static int loop_device_make_internal(
|
||||
if (nr < 0)
|
||||
return -errno;
|
||||
|
||||
if (asprintf(&loopdev, "/dev/loop%i", nr) < 0)
|
||||
if (asprintf(&node, "/dev/loop%i", nr) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
loop = open(loopdev, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
|
||||
loop = open(node, O_CLOEXEC|O_NONBLOCK|O_NOCTTY|open_flags);
|
||||
if (loop < 0) {
|
||||
/* Somebody might've gotten the same number from the kernel, used the device,
|
||||
* and called LOOP_CTL_REMOVE on it. Let's retry with a new number. */
|
||||
@@ -532,7 +537,7 @@ static int loop_device_make_internal(
|
||||
/* Now close the loop device explicitly. This will release any lock acquired by
|
||||
* attach_empty_file() or similar, while we sleep below. */
|
||||
loop = safe_close(loop);
|
||||
loopdev = mfree(loopdev);
|
||||
node = mfree(node);
|
||||
|
||||
/* Wait some random time, to make collision less likely. Let's pick a random time in the
|
||||
* range 0ms…250ms, linearly scaled by the number of failed attempts. */
|
||||
@@ -591,7 +596,7 @@ static int loop_device_make_internal(
|
||||
*d = (LoopDevice) {
|
||||
.fd = TAKE_FD(loop_with_fd),
|
||||
.lock_fd = TAKE_FD(lock_fd),
|
||||
.node = TAKE_PTR(loopdev),
|
||||
.node = TAKE_PTR(node),
|
||||
.nr = nr,
|
||||
.devno = st.st_rdev,
|
||||
.diskseq = diskseq,
|
||||
|
||||
@@ -15,7 +15,7 @@ int quotactl_devnum(int cmd, dev_t devnum, int id, void *addr) {
|
||||
/* Like quotactl() but takes a dev_t instead of a path to a device node, and fixes caddr_t → void*,
|
||||
* like we should, today */
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devnum, &devnode);
|
||||
r = devname_from_devnum(S_IFBLK, devnum, &devnode);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -539,14 +539,11 @@ static int merge_subprocess(Hashmap *images, const char *workspace) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to set up loopback device for %s: %m", img->path);
|
||||
|
||||
r = dissect_image_and_warn(
|
||||
d->fd,
|
||||
r = dissect_loop_device_and_warn(
|
||||
img->path,
|
||||
d,
|
||||
&verity_settings,
|
||||
NULL,
|
||||
d->diskseq,
|
||||
d->uevent_seqnum_not_before,
|
||||
d->timestamp_not_before,
|
||||
flags,
|
||||
&m);
|
||||
if (r < 0)
|
||||
|
||||
@@ -608,7 +608,7 @@ int resource_resolve_path(
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"File system is not placed on a partition block device, cannot determine whole block device backing root file system.");
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, d, &p);
|
||||
r = devname_from_devnum(S_IFBLK, d, &p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ static void* thread_func(void *ptr) {
|
||||
|
||||
log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted);
|
||||
|
||||
r = dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, DISSECT_IMAGE_READ_ONLY, &dissected);
|
||||
r = dissect_loop_device(loop, NULL, NULL, DISSECT_IMAGE_READ_ONLY, &dissected);
|
||||
if (r < 0)
|
||||
log_error_errno(r, "Failed dissect loopback device %s: %m", loop->node);
|
||||
assert_se(r >= 0);
|
||||
@@ -220,7 +220,7 @@ static int run(int argc, char *argv[]) {
|
||||
pthread_t threads[arg_n_threads];
|
||||
sd_id128_t id;
|
||||
|
||||
assert_se(dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
|
||||
assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0);
|
||||
|
||||
assert_se(dissected->partitions[PARTITION_ESP].found);
|
||||
assert_se(dissected->partitions[PARTITION_ESP].node);
|
||||
@@ -244,7 +244,7 @@ static int run(int argc, char *argv[]) {
|
||||
assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", id, true) >= 0);
|
||||
|
||||
dissected = dissected_image_unref(dissected);
|
||||
assert_se(dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
|
||||
assert_se(dissect_loop_device(loop, NULL, NULL, 0, &dissected) >= 0);
|
||||
|
||||
assert_se(mkdtemp_malloc(NULL, &mounted) >= 0);
|
||||
|
||||
|
||||
@@ -321,7 +321,7 @@ int lock_main(int argc, char *argv[], void *userdata) {
|
||||
for (size_t i = 0; i < n_devnos; i++) {
|
||||
_cleanup_free_ char *node = NULL;
|
||||
|
||||
r = devpath_from_devnum(S_IFBLK, devnos[i], &node);
|
||||
r = devname_from_devnum(S_IFBLK, devnos[i], &node);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to format block device path: %m");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user