1
0
mirror of https://github.com/systemd/systemd synced 2026-03-26 08:44:55 +01:00

Compare commits

..

No commits in common. "a3a5446b7675696f43c2d8a2a0b898d72228a53d" and "a9cd516f6c70ba3294ec5b24abbfbad9035bc099" have entirely different histories.

3 changed files with 19 additions and 54 deletions

2
TODO
View File

@ -1240,6 +1240,8 @@ Features:
* homed: keep an fd to the homedir open at all times, to keep the fs pinned * homed: keep an fd to the homedir open at all times, to keep the fs pinned
(autofs and such) while user is logged in. (autofs and such) while user is logged in.
* when we resize disks (homed?) always round up to 4K sectors, not 512K
* add a new switch --auto-definitions=yes/no or so to systemd-repart. If * add a new switch --auto-definitions=yes/no or so to systemd-repart. If
specified, synthesize a definition automatically if we can: enlarge last specified, synthesize a definition automatically if we can: enlarge last
partition on disk, but only if it is marked for growing and not read-only. partition on disk, but only if it is marked for growing and not read-only.

View File

@ -299,8 +299,6 @@ static int module_callback(Dwfl_Module *mod, void **userdata, const char *name,
program_header->p_offset, program_header->p_offset,
program_header->p_filesz, program_header->p_filesz,
ELF_T_NHDR); ELF_T_NHDR);
if (!data)
continue;
Elf *memelf = elf_memory(data->d_buf, data->d_size); Elf *memelf = elf_memory(data->d_buf, data->d_size);
if (!memelf) if (!memelf)

View File

@ -38,18 +38,10 @@
#include "strv.h" #include "strv.h"
#include "tmpfile-util.h" #include "tmpfile-util.h"
/* Round down to the nearest 4K size. Given that newer hardware generally prefers 4K sectors, let's align our /* Round down to the nearest 1K size. Note that Linux generally handles block devices with 512 blocks only,
* partitions to that too. In the worst case we'll waste 3.5K per partition that way, but I think I can live * but actually doesn't accept uneven numbers in many cases. To avoid any confusion around this we'll
* with that. */ * strictly round disk sizes down to the next 1K boundary. */
#define DISK_SIZE_ROUND_DOWN(x) ((x) & ~UINT64_C(4095)) #define DISK_SIZE_ROUND_DOWN(x) ((x) & ~UINT64_C(1023))
/* Rounds up to the nearest 4K boundary. Returns UINT64_MAX on overflow */
#define DISK_SIZE_ROUND_UP(x) \
({ \
uint64_t _x = (x); \
_x > UINT64_MAX - 4095U ? UINT64_MAX : (_x + 4095U) & ~UINT64_C(4095); \
})
int run_mark_dirty(int fd, bool b) { int run_mark_dirty(int fd, bool b) {
char x = '1'; char x = '1';
@ -1628,7 +1620,7 @@ static int make_partition_table(
_cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL; _cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL;
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
_cleanup_free_ char *path = NULL, *disk_uuid_as_string = NULL; _cleanup_free_ char *path = NULL, *disk_uuid_as_string = NULL;
uint64_t offset, size, first_lba, start, last_lba, end; uint64_t offset, size;
sd_id128_t disk_uuid; sd_id128_t disk_uuid;
int r; int r;
@ -1668,31 +1660,17 @@ static int make_partition_table(
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to set partition type: %m"); return log_error_errno(r, "Failed to set partition type: %m");
r = fdisk_partition_start_follow_default(p, 1);
if (r < 0)
return log_error_errno(r, "Failed to place partition at beginning of space: %m");
r = fdisk_partition_partno_follow_default(p, 1); r = fdisk_partition_partno_follow_default(p, 1);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to place partition at first free partition index: %m"); return log_error_errno(r, "Failed to place partition at first free partition index: %m");
first_lba = fdisk_get_first_lba(c); /* Boundary where usable space starts */ r = fdisk_partition_end_follow_default(p, 1);
assert(first_lba <= UINT64_MAX/512);
start = DISK_SIZE_ROUND_UP(first_lba * 512); /* Round up to multiple of 4K */
if (start == UINT64_MAX)
return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Overflow while rounding up start LBA.");
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 */
if (end <= start)
return log_error_errno(SYNTHETIC_ERRNO(ERANGE), "Resulting partition size zero or negative.");
r = fdisk_partition_set_start(p, start / 512);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to place partition at offset %" PRIu64 ": %m", start); return log_error_errno(r, "Failed to make partition cover all free space: %m");
r = fdisk_partition_set_size(p, (end - start) / 512);
if (r < 0)
return log_error_errno(r, "Failed to end partition at offset %" PRIu64 ": %m", end);
r = fdisk_partition_set_name(p, label); r = fdisk_partition_set_name(p, label);
if (r < 0) if (r < 0)
@ -2714,8 +2692,6 @@ int home_resize_luks(
new_image_size = old_image_size; /* we can't resize physical block devices */ new_image_size = old_image_size; /* we can't resize physical block devices */
} else { } else {
uint64_t new_image_size_rounded;
r = stat_verify_regular(&st); r = stat_verify_regular(&st);
if (r < 0) if (r < 0)
return log_error_errno(r, "Image %s is not a block device nor regular file: %m", ip); return log_error_errno(r, "Image %s is not a block device nor regular file: %m", ip);
@ -2726,16 +2702,11 @@ int home_resize_luks(
* apply onto the loopback file as a whole. When we operate on block devices we instead apply * apply onto the loopback file as a whole. When we operate on block devices we instead apply
* to the partition itself only. */ * to the partition itself only. */
new_image_size_rounded = DISK_SIZE_ROUND_DOWN(h->disk_size); new_image_size = DISK_SIZE_ROUND_DOWN(h->disk_size);
if (new_image_size == old_image_size) {
if (old_image_size == h->disk_size ||
old_image_size == new_image_size_rounded) {
/* If exact match, or a match after we rounded down, don't do a thing */
log_info("Image size already matching, skipping operation."); log_info("Image size already matching, skipping operation.");
return 0; return 0;
} }
new_image_size = new_image_size_rounded;
} }
r = home_prepare_luks(h, already_activated, whole_disk, cache, setup, &header_home); r = home_prepare_luks(h, already_activated, whole_disk, cache, setup, &header_home);
@ -2759,21 +2730,15 @@ int home_resize_luks(
if (new_image_size <= partition_table_extra) if (new_image_size <= partition_table_extra)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "New size smaller than partition table metadata."); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "New size smaller than partition table metadata.");
new_partition_size = DISK_SIZE_ROUND_DOWN(new_image_size - partition_table_extra); new_partition_size = new_image_size - partition_table_extra;
} else { } else {
uint64_t new_partition_size_rounded;
assert(S_ISBLK(st.st_mode)); assert(S_ISBLK(st.st_mode));
new_partition_size_rounded = DISK_SIZE_ROUND_DOWN(h->disk_size); new_partition_size = DISK_SIZE_ROUND_DOWN(h->disk_size);
if (new_partition_size == setup->partition_size) {
if (h->disk_size == setup->partition_size ||
new_partition_size_rounded == setup->partition_size) {
log_info("Partition size already matching, skipping operation."); log_info("Partition size already matching, skipping operation.");
return 0; return 0;
} }
new_partition_size = new_partition_size_rounded;
} }
if ((UINT64_MAX - setup->partition_offset) < new_partition_size || if ((UINT64_MAX - setup->partition_offset) < new_partition_size ||
@ -2787,7 +2752,7 @@ int home_resize_luks(
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "New size smaller than crypto payload offset?"); return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "New size smaller than crypto payload offset?");
old_fs_size = (setup->partition_size / 512U - crypto_offset) * 512U; old_fs_size = (setup->partition_size / 512U - crypto_offset) * 512U;
new_fs_size = DISK_SIZE_ROUND_DOWN((new_partition_size / 512U - crypto_offset) * 512U); new_fs_size = (new_partition_size / 512U - crypto_offset) * 512U;
/* Before we start doing anything, let's figure out if we actually can */ /* Before we start doing anything, let's figure out if we actually can */
resize_type = can_resize_fs(setup->root_fd, old_fs_size, new_fs_size); resize_type = can_resize_fs(setup->root_fd, old_fs_size, new_fs_size);