diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-01-17 21:42:02 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-01-18 10:47:17 +0100 |
commit | 81dde3d85d57e1c91ac23208ce006f43502b54b2 (patch) | |
tree | 76312c4bbc3a42ec0763e9350ff92da739a641d6 /src | |
parent | 1d93c00386212bf3749e5657de9da99cdd429239 (diff) | |
download | systemd-81dde3d85d57e1c91ac23208ce006f43502b54b2.tar.gz |
homework: when creating/resizing GPT partitions, also set sector size explicitly
Diffstat (limited to 'src')
-rw-r--r-- | src/home/homework-luks.c | 19 | ||||
-rw-r--r-- | src/partition/repart.c | 15 | ||||
-rw-r--r-- | src/shared/dissect-image.c | 18 | ||||
-rw-r--r-- | src/shared/dissect-image.h | 1 | ||||
-rw-r--r-- | src/shared/fdisk-util.c | 20 | ||||
-rw-r--r-- | src/shared/fdisk-util.h | 2 |
6 files changed, 61 insertions, 14 deletions
diff --git a/src/home/homework-luks.c b/src/home/homework-luks.c index 5ad7706636..2ea9887853 100644 --- a/src/home/homework-luks.c +++ b/src/home/homework-luks.c @@ -1840,6 +1840,7 @@ static int luks_format( static int make_partition_table( int fd, + uint32_t sector_size, const char *label, sd_id128_t uuid, uint64_t *ret_offset, @@ -1867,7 +1868,7 @@ static int make_partition_table( if (r < 0) return log_error_errno(r, "Failed to initialize partition type: %m"); - r = fdisk_new_context_fd(fd, /* read_only= */ false, &c); + r = fdisk_new_context_fd(fd, /* read_only= */ false, sector_size, &c); if (r < 0) return log_error_errno(r, "Failed to open device: %m"); @@ -2317,6 +2318,7 @@ int home_create_luks( r = make_partition_table( setup->image_fd, + user_record_luks_sector_size(h), user_record_user_name_and_realm(h), partition_uuid, &partition_offset, @@ -2704,7 +2706,7 @@ static int prepare_resize_partition( return 0; } - r = fdisk_new_context_fd(fd, /* read_only= */ false, &c); + r = fdisk_new_context_fd(fd, /* read_only= */ false, UINT32_MAX, &c); if (r < 0) return log_error_errno(r, "Failed to open device: %m"); @@ -2788,6 +2790,7 @@ static int apply_resize_partition( _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; _cleanup_free_ void *two_zero_lbas = NULL; + uint32_t ssz; ssize_t n; int r; @@ -2808,18 +2811,22 @@ static int apply_resize_partition( if (r < 0) return log_error_errno(r, "Failed to change partition size: %m"); - two_zero_lbas = malloc0(1024U); + r = probe_sector_size(fd, &ssz); + if (r < 0) + return log_error_errno(r, "Failed to determine current sector size: %m"); + + two_zero_lbas = malloc0(ssz * 2); if (!two_zero_lbas) return log_oom(); /* libfdisk appears to get confused by the existing PMBR. Let's explicitly flush it out. */ - n = pwrite(fd, two_zero_lbas, 1024U, 0); + n = pwrite(fd, two_zero_lbas, ssz * 2, 0); if (n < 0) return log_error_errno(errno, "Failed to wipe partition table: %m"); - if (n != 1024) + if ((size_t) n != ssz * 2) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short write while wiping partition table."); - r = fdisk_new_context_fd(fd, /* read_only= */ false, &c); + r = fdisk_new_context_fd(fd, /* read_only= */ false, ssz, &c); if (r < 0) return log_error_errno(r, "Failed to open device: %m"); diff --git a/src/partition/repart.c b/src/partition/repart.c index 9698f1be07..1fe1c06a3c 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -6160,7 +6160,7 @@ static int find_root(Context *context) { return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device."); } -static int resize_pt(int fd) { +static int resize_pt(int fd, uint64_t sector_size) { _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; int r; @@ -6168,7 +6168,7 @@ static int resize_pt(int fd) { * possession of the enlarged backing file. For this it suffices to open the device with libfdisk and * immediately write it again, with no changes. */ - r = fdisk_new_context_fd(fd, /* read_only= */ false, &c); + r = fdisk_new_context_fd(fd, /* read_only= */ false, sector_size, &c); if (r < 0) return log_error_errno(r, "Failed to open device '%s': %m", FORMAT_PROC_FD_PATH(fd)); @@ -6192,7 +6192,8 @@ static int resize_backing_fd( const char *node, /* The primary way we access the disk image to operate on */ int *fd, /* An O_RDONLY fd referring to that inode */ const char *backing_file, /* If the above refers to a loopback device, the backing regular file for that, which we can grow */ - LoopDevice *loop_device) { + LoopDevice *loop_device, + uint64_t sector_size) { _cleanup_close_ int writable_fd = -EBADF; uint64_t current_size; @@ -6304,7 +6305,7 @@ static int resize_backing_fd( node, FORMAT_BYTES(current_size), FORMAT_BYTES(arg_size)); done: - r = resize_pt(writable_fd); + r = resize_pt(writable_fd, sector_size); if (r < 0) return r; @@ -6429,7 +6430,8 @@ static int run(int argc, char *argv[]) { context->node, &context->backing_fd, node_is_our_loop ? arg_image : NULL, - node_is_our_loop ? loop_device : NULL); + node_is_our_loop ? loop_device : NULL, + context->sector_size); if (r < 0) return r; } @@ -6503,7 +6505,8 @@ static int run(int argc, char *argv[]) { context->node, &context->backing_fd, node_is_our_loop ? arg_image : NULL, - node_is_our_loop ? loop_device : NULL); + node_is_our_loop ? loop_device : NULL, + context->sector_size); if (r < 0) return r; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index da8eba83de..c0d052e0ea 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -189,6 +189,24 @@ not_found: return 0; /* indicate we didn't find it */ } +int probe_sector_size_prefer_ioctl(int fd, uint32_t *ret) { + struct stat st; + + assert(fd >= 0); + assert(ret); + + /* Just like probe_sector_size(), but if we are looking at a block device, will use the already + * configured sector size rather than probing by contents */ + + if (fstat(fd, &st) < 0) + return -errno; + + if (S_ISBLK(st.st_mode)) + return blockdev_get_sector_size(fd, ret); + + return probe_sector_size(fd, ret); +} + int probe_filesystem_full( int fd, const char *path, diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index a69482d237..143d6ff501 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -190,3 +190,4 @@ int verity_dissect_and_mount(int src_fd, const char *src, const char *dest, cons int dissect_fstype_ok(const char *fstype); int probe_sector_size(int fd, uint32_t *ret); +int probe_sector_size_prefer_ioctl(int fd, uint32_t *ret); diff --git a/src/shared/fdisk-util.c b/src/shared/fdisk-util.c index eeed1840aa..e88adb2d43 100644 --- a/src/shared/fdisk-util.c +++ b/src/shared/fdisk-util.c @@ -1,11 +1,17 @@ /* SPDX-License-Identifier: LGPL-2.1-or-later */ +#include "dissect-image.h" #include "fd-util.h" #include "fdisk-util.h" #if HAVE_LIBFDISK -int fdisk_new_context_fd(int fd, bool read_only, struct fdisk_context **ret) { +int fdisk_new_context_fd( + int fd, + bool read_only, + uint32_t sector_size, + struct fdisk_context **ret) { + _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; int r; @@ -18,6 +24,18 @@ int fdisk_new_context_fd(int fd, bool read_only, struct fdisk_context **ret) { if (!c) return -ENOMEM; + if (sector_size == UINT32_MAX) { + r = probe_sector_size_prefer_ioctl(fd, §or_size); + if (r < 0) + return r; + } + + if (sector_size != 0) { + r = fdisk_save_user_sector_size(c, /* phy= */ 0, sector_size); + if (r < 0) + return r; + } + r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(fd), read_only); if (r < 0) return r; diff --git a/src/shared/fdisk-util.h b/src/shared/fdisk-util.h index 7f34a042ec..4845132927 100644 --- a/src/shared/fdisk-util.h +++ b/src/shared/fdisk-util.h @@ -14,7 +14,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct fdisk_partition*, fdisk_unref_partition, DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct fdisk_parttype*, fdisk_unref_parttype, NULL); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct fdisk_table*, fdisk_unref_table, NULL); -int fdisk_new_context_fd(int fd, bool read_only, struct fdisk_context **ret); +int fdisk_new_context_fd(int fd, bool read_only, uint32_t sector_size, struct fdisk_context **ret); int fdisk_partition_get_uuid_as_id128(struct fdisk_partition *p, sd_id128_t *ret); int fdisk_partition_get_type_as_id128(struct fdisk_partition *p, sd_id128_t *ret); |