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;
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);
}
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;
/* 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;