1
0
mirror of https://github.com/systemd/systemd.git synced 2024-10-31 07:51:21 +03:00

repart: when we can't fit the partitions in, report needed disk size current disk size

This improves error output in repart if we can't fit the defined
partitions into the disk image. With this change we'll now show not only
the disk size we need (as before), but also the current one, as well as
the largest free area on disk.

This should make it a bit easier to debug disk space issues that repart
runs into.
This commit is contained in:
Lennart Poettering 2021-07-02 15:33:35 +02:00
parent 8859b8f77a
commit 14a4c4edc7

View File

@ -538,14 +538,22 @@ static uint64_t charge_weight(uint64_t total, uint64_t amount) {
return total - amount;
}
static bool context_allocate_partitions(Context *context) {
static bool context_allocate_partitions(Context *context, uint64_t *ret_largest_free_area) {
Partition *p;
assert(context);
/* A simple first-fit algorithm, assuming the array of free areas is sorted by size in decreasing
* order. */
/* Sort free areas by size, putting smallest first */
typesafe_qsort(context->free_areas, context->n_free_areas, free_area_compare);
/* In any case return size of the largest free area (i.e. not the size of all free areas
* combined!) */
if (ret_largest_free_area)
*ret_largest_free_area =
context->n_free_areas == 0 ? 0 :
free_area_available_for_new_partitions(context->free_areas[context->n_free_areas-1]);
/* A simple first-fit algorithm. We return true if we can fit the partitions in, otherwise false. */
LIST_FOREACH(partitions, p, context->partitions) {
bool fits = false;
uint64_t required;
@ -555,9 +563,6 @@ static bool context_allocate_partitions(Context *context) {
if (p->dropped || PARTITION_EXISTS(p))
continue;
/* Sort by size */
typesafe_qsort(context->free_areas, context->n_free_areas, free_area_compare);
/* How much do we need to fit? */
required = partition_min_size_with_padding(p);
assert(required % 4096 == 0);
@ -4826,7 +4831,12 @@ static int determine_auto_size(Context *c) {
}
assert_se(format_bytes(buf, sizeof(buf), sum));
log_info("Automatically determined minimal disk image size as %s.", buf);
if (c->total != UINT64_MAX) { /* Image already allocated? Then show its size */
char buf2[FORMAT_BYTES_MAX];
assert_se(format_bytes(buf2, sizeof(buf2), c->total));
log_info("Automatically determined minimal disk image size as %s, current image size is %s.", buf, buf2);
} else /* If the image is being created right now, then it has no previous size, suppress any comment about it hence */
log_info("Automatically determined minimal disk image size as %s.", buf);
arg_size = sum;
return 0;
@ -4996,12 +5006,16 @@ static int run(int argc, char *argv[]) {
/* First try to fit new partitions in, dropping by priority until it fits */
for (;;) {
if (context_allocate_partitions(context))
uint64_t largest_free_area;
if (context_allocate_partitions(context, &largest_free_area))
break; /* Success! */
if (!context_drop_one_priority(context)) {
char buf[FORMAT_BYTES_MAX];
r = log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
"Can't fit requested partitions into free space, refusing.");
"Can't fit requested partitions into available free space (%s), refusing.",
format_bytes(buf, sizeof(buf), largest_free_area));
determine_auto_size(context);
return r;