From: Lennart Poettering Date: Thu, 28 Aug 2025 13:44:13 +0000 (+0200) Subject: repart: split out main function that ponders about placement of partitions X-Git-Tag: v259-rc1~193^2~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0eab6d2960d4ed4d64d5cc836da6749104f00e40;p=thirdparty%2Fsystemd.git repart: split out main function that ponders about placement of partitions Let's move the key code that places partitions into a function of its own. That will make it easier to call this via varlink. --- diff --git a/src/repart/repart.c b/src/repart/repart.c index 6d6d2228eae..4d3984f815d 100644 --- a/src/repart/repart.c +++ b/src/repart/repart.c @@ -9839,6 +9839,61 @@ static int determine_auto_size(Context *c) { return 0; } +static int context_ponder(Context *context) { + int r; + + assert(context); + + /* First try to fit new partitions in, dropping by priority until it fits */ + for (;;) { + uint64_t largest_free_area; + + if (context_allocate_partitions(context, &largest_free_area)) + break; /* Success! */ + + if (context_unmerge_and_allocate_partitions(context)) + break; /* We had to un-suppress a supplement or few, but still success! */ + + if (context_drop_or_foreignize_one_priority(context)) + continue; /* Still no luck. Let's drop a priority and try again. */ + + /* No more priorities left to drop. This configuration just doesn't fit on this disk... */ + r = log_error_errno(SYNTHETIC_ERRNO(ENOSPC), + "Can't fit requested partitions into available free space (%s), refusing.", + FORMAT_BYTES(largest_free_area)); + (void) determine_auto_size(context); + return r; + } + + LIST_FOREACH(partitions, p, context->partitions) { + if (!p->supplement_for) + continue; + + if (PARTITION_SUPPRESSED(p)) { + assert(!p->allocated_to_area); + p->dropped = true; + + log_debug("Partition %s can be merged into %s, suppressing supplement.", + p->definition_path, p->supplement_for->definition_path); + } else if (PARTITION_EXISTS(p)) + log_info("Partition %s already exists on disk, using supplement verbatim.", + p->definition_path); + else + log_info("Couldn't allocate partitions with %s merged into %s, using supplement verbatim.", + p->definition_path, p->supplement_for->definition_path); + } + + /* Now assign free space according to the weight logic */ + r = context_grow_partitions(context); + if (r < 0) + return r; + + /* Now calculate where each new partition gets placed */ + context_place_partitions(context); + + return 0; +} + static int vl_method_list_candidate_devices( sd_varlink *link, sd_json_variant *parameters, @@ -10162,53 +10217,10 @@ static int run(int argc, char *argv[]) { return r; } - /* First try to fit new partitions in, dropping by priority until it fits */ - for (;;) { - uint64_t largest_free_area; - - if (context_allocate_partitions(context, &largest_free_area)) - break; /* Success! */ - - if (context_unmerge_and_allocate_partitions(context)) - break; /* We had to un-suppress a supplement or few, but still success! */ - - if (context_drop_or_foreignize_one_priority(context)) - continue; /* Still no luck. Let's drop a priority and try again. */ - - /* No more priorities left to drop. This configuration just doesn't fit on this disk... */ - r = log_error_errno(SYNTHETIC_ERRNO(ENOSPC), - "Can't fit requested partitions into available free space (%s), refusing.", - FORMAT_BYTES(largest_free_area)); - determine_auto_size(context); - return r; - } - - LIST_FOREACH(partitions, p, context->partitions) { - if (!p->supplement_for) - continue; - - if (PARTITION_SUPPRESSED(p)) { - assert(!p->allocated_to_area); - p->dropped = true; - - log_debug("Partition %s can be merged into %s, suppressing supplement.", - p->definition_path, p->supplement_for->definition_path); - } else if (PARTITION_EXISTS(p)) - log_info("Partition %s already exists on disk, using supplement verbatim.", - p->definition_path); - else - log_info("Couldn't allocate partitions with %s merged into %s, using supplement verbatim.", - p->definition_path, p->supplement_for->definition_path); - } - - /* Now assign free space according to the weight logic */ - r = context_grow_partitions(context); + r = context_ponder(context); if (r < 0) return r; - /* Now calculate where each new partition gets placed */ - context_place_partitions(context); - (void) context_dump(context, /*late=*/ false); r = context_write_partition_table(context);