-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
homework: resize to maximum disk space if disk size is not specified #25066
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -2749,6 +2749,43 @@ static int prepare_resize_partition( | |||||||
return 1; | ||||||||
} | ||||||||
|
||||||||
static int get_maximum_partition_size( | ||||||||
int fd, | ||||||||
struct fdisk_partition *p, | ||||||||
uint64_t *ret_maximum_partition_size) { | ||||||||
|
||||||||
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; | ||||||||
uint64_t start_lba, start, last_lba, end; | ||||||||
int r; | ||||||||
|
||||||||
assert(fd >= 0); | ||||||||
assert(p); | ||||||||
assert(ret_maximum_partition_size); | ||||||||
|
||||||||
bluca marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||
c = fdisk_new_context(); | ||||||||
if (!c) | ||||||||
return log_oom(); | ||||||||
|
||||||||
r = fdisk_assign_device(c, FORMAT_PROC_FD_PATH(fd), 0); | ||||||||
if (r < 0) | ||||||||
return log_error_errno(r, "Failed to open device: %m"); | ||||||||
|
||||||||
start_lba = fdisk_partition_get_start(p); | ||||||||
assert(start_lba <= UINT64_MAX/512); | ||||||||
start = start_lba * 512; | ||||||||
|
||||||||
last_lba = fdisk_get_last_lba(c); /* One sector before boundary where usable space ends */ | ||||||||
assert(last_lba < UINT64_MAX/512); | ||||||||
end = DISK_SIZE_ROUND_DOWN((last_lba + 1) * 512); /* Round down to multiple of 4K */ | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. so, this is problematic if there are partitions behind this one. I guess to to be correct we'd have to iterate through all partitions on the disk, and look for the one whose start offset is smallest of those larger than our partition. And only if no such partition exist use the last LBA value. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. systemd/src/home/homework-luks.c Lines 2713 to 2715 in 4856f63
prepare_resize_partition() returns error if the partition is not the last. Therefore, this ensures that no more partitions exist.
|
||||||||
|
||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. before we subtract start from end we shuld really check for overflows, and generate some error There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i.e. if (start > end)
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Last LBA is before partition end."); or so |
||||||||
if (start > end) | ||||||||
return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), "Last LBA is before partition start."); | ||||||||
|
||||||||
*ret_maximum_partition_size = DISK_SIZE_ROUND_DOWN(end - start); | ||||||||
|
||||||||
return 1; | ||||||||
} | ||||||||
|
||||||||
static int ask_cb(struct fdisk_context *c, struct fdisk_ask *ask, void *userdata) { | ||||||||
char *result; | ||||||||
|
||||||||
|
@@ -3214,6 +3251,17 @@ int home_resize_luks( | |||||||
setup->partition_offset + setup->partition_size > old_image_size) | ||||||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Old partition doesn't fit in backing storage, refusing."); | ||||||||
|
||||||||
/* Get target partition information in here for new_partition_size calculation */ | ||||||||
r = prepare_resize_partition( | ||||||||
image_fd, | ||||||||
setup->partition_offset, | ||||||||
setup->partition_size, | ||||||||
&disk_uuid, | ||||||||
&table, | ||||||||
&partition); | ||||||||
if (r < 0) | ||||||||
return r; | ||||||||
|
||||||||
if (S_ISREG(st.st_mode)) { | ||||||||
uint64_t partition_table_extra, largest_size; | ||||||||
|
||||||||
|
@@ -3236,9 +3284,13 @@ int home_resize_luks( | |||||||
new_partition_size = 0; | ||||||||
intention = INTENTION_SHRINK; | ||||||||
} else { | ||||||||
uint64_t new_partition_size_rounded; | ||||||||
uint64_t new_partition_size_rounded = DISK_SIZE_ROUND_DOWN(h->disk_size); | ||||||||
|
||||||||
new_partition_size_rounded = DISK_SIZE_ROUND_DOWN(h->disk_size); | ||||||||
if (h->disk_size == UINT64_MAX && partition) { | ||||||||
r = get_maximum_partition_size(image_fd, partition, &new_partition_size_rounded); | ||||||||
if (r < 0) | ||||||||
return r; | ||||||||
} | ||||||||
|
||||||||
if (setup->partition_size >= new_partition_size_rounded && | ||||||||
setup->partition_size <= h->disk_size) { | ||||||||
|
@@ -3332,16 +3384,6 @@ int home_resize_luks( | |||||||
special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), | ||||||||
FORMAT_BYTES(new_fs_size)); | ||||||||
|
||||||||
r = prepare_resize_partition( | ||||||||
image_fd, | ||||||||
setup->partition_offset, | ||||||||
setup->partition_size, | ||||||||
&disk_uuid, | ||||||||
&table, | ||||||||
&partition); | ||||||||
if (r < 0) | ||||||||
return r; | ||||||||
|
||||||||
if (new_fs_size > old_fs_size) { /* → Grow */ | ||||||||
|
||||||||
if (S_ISREG(st.st_mode)) { | ||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
so this is actually not correct to assume. if a naked block device is used (i.e. no partition table) this will be NULL.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added
partition != NULL
condition. This will make it the same as before if it's a naked block device.