diff --git a/src/partition/repart.c b/src/partition/repart.c index 589acaa49d..75b92d0e9a 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -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;