summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-01-17 21:42:02 +0100
committerLennart Poettering <lennart@poettering.net>2023-01-18 10:47:17 +0100
commit81dde3d85d57e1c91ac23208ce006f43502b54b2 (patch)
tree76312c4bbc3a42ec0763e9350ff92da739a641d6 /src
parent1d93c00386212bf3749e5657de9da99cdd429239 (diff)
downloadsystemd-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.c19
-rw-r--r--src/partition/repart.c15
-rw-r--r--src/shared/dissect-image.c18
-rw-r--r--src/shared/dissect-image.h1
-rw-r--r--src/shared/fdisk-util.c20
-rw-r--r--src/shared/fdisk-util.h2
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, &sector_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);