diff --git a/src/partition/repart.c b/src/partition/repart.c index be16f5a067..7b6201efa8 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -3977,6 +3977,40 @@ static int find_root(char **ret, int *ret_fd) { return log_error_errno(SYNTHETIC_ERRNO(ENODEV), "Failed to discover root block device."); } +static int resize_pt(int fd) { + char procfs_path[STRLEN("/proc/self/fd/") + DECIMAL_STR_MAX(int)]; + _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; + int r; + + /* After resizing the backing file we need to resize the partition table itself too, so that it takes + * possession of the enlarged backing file. For this it suffices to open the device with libfdisk and + * immediately write it again, with no changes. */ + + c = fdisk_new_context(); + if (!c) + return log_oom(); + + xsprintf(procfs_path, "/proc/self/fd/%i", fd); + r = fdisk_assign_device(c, procfs_path, 0); + if (r < 0) + return log_error_errno(r, "Failed to open device '%s': %m", procfs_path); + + r = fdisk_has_label(c); + if (r < 0) + return log_error_errno(r, "Failed to determine whether disk '%s' has a disk label: %m", procfs_path); + if (r == 0) { + log_debug("Not resizing partition table, as there currently is none."); + return 0; + } + + r = fdisk_write_disklabel(c); + if (r < 0) + return log_error_errno(r, "Failed to write resized partition table: %m"); + + log_info("Resized partition table."); + return 1; +} + static int resize_backing_fd(const char *node, int *fd) { char buf1[FORMAT_BYTES_MAX], buf2[FORMAT_BYTES_MAX]; _cleanup_close_ int writable_fd = -1; @@ -4029,6 +4063,10 @@ static int resize_backing_fd(const char *node, int *fd) { /* Fallback to truncation, if fallocate() is not supported. */ log_debug("Backing file system does not support fallocate(), falling back to ftruncate()."); } else { + r = resize_pt(writable_fd); + if (r < 0) + return r; + if (st.st_size == 0) /* Likely regular file just created by us */ log_info("Allocated %s for '%s'.", buf2, node); else @@ -4042,6 +4080,10 @@ static int resize_backing_fd(const char *node, int *fd) { return log_error_errno(errno, "Failed to grow '%s' from %s to %s by truncation: %m", node, buf1, buf2); + r = resize_pt(writable_fd); + if (r < 0) + return r; + if (st.st_size == 0) /* Likely regular file just created by us */ log_info("Sized '%s' to %s.", node, buf2); else