diff --git a/src/partition/repart.c b/src/partition/repart.c index b241f9bc61..2fee79f33e 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -2908,12 +2908,13 @@ static int context_dump_partitions(Context *context) { return table_print_with_pager(t, arg_json_format_flags, arg_pager_flags, arg_legend); } -static void context_bar_char_process_partition( +static int context_bar_char_process_partition( Context *context, Partition *bar[], size_t n, Partition *p, - size_t *ret_start) { + size_t **start_array, + size_t *n_start_array) { uint64_t from, to, total; size_t x, y; @@ -2922,9 +2923,11 @@ static void context_bar_char_process_partition( assert(bar); assert(n > 0); assert(p); + assert(start_array); + assert(n_start_array); if (p->dropped) - return; + return 0; assert(p->offset != UINT64_MAX); assert(p->new_size != UINT64_MAX); @@ -2947,7 +2950,10 @@ static void context_bar_char_process_partition( for (size_t i = x; i < y; i++) bar[i] = p; - *ret_start = x; + if (!GREEDY_REALLOC_APPEND(*start_array, *n_start_array, &x, 1)) + return log_oom(); + + return 1; } static int partition_hint(const Partition *p, const char *node, char **ret) { @@ -2991,9 +2997,11 @@ done: static int context_dump_partition_bar(Context *context) { _cleanup_free_ Partition **bar = NULL; _cleanup_free_ size_t *start_array = NULL; + size_t n_start_array = 0; Partition *last = NULL; bool z = false; size_t c, j = 0; + int r; assert_se((c = columns()) >= 2); c -= 2; /* We do not use the leftmost and rightmost character cell */ @@ -3002,12 +3010,11 @@ static int context_dump_partition_bar(Context *context) { if (!bar) return log_oom(); - start_array = new(size_t, context->n_partitions); - if (!start_array) - return log_oom(); - - LIST_FOREACH(partitions, p, context->partitions) - context_bar_char_process_partition(context, bar, c, p, start_array + j++); + LIST_FOREACH(partitions, p, context->partitions) { + r = context_bar_char_process_partition(context, bar, c, p, &start_array, &n_start_array); + if (r < 0) + return r; + } putc(' ', stdout); @@ -3029,7 +3036,7 @@ static int context_dump_partition_bar(Context *context) { fputs(ansi_normal(), stdout); putc('\n', stdout); - for (size_t i = 0; i < context->n_partitions; i++) { + for (size_t i = 0; i < n_start_array; i++) { _cleanup_free_ char **line = NULL; line = new0(char*, c); @@ -3039,9 +3046,13 @@ static int context_dump_partition_bar(Context *context) { j = 0; LIST_FOREACH(partitions, p, context->partitions) { _cleanup_free_ char *d = NULL; + + if (p->dropped) + continue; + j++; - if (i < context->n_partitions - j) { + if (i < n_start_array - j) { if (line[start_array[j-1]]) { const char *e; @@ -3061,7 +3072,7 @@ static int context_dump_partition_bar(Context *context) { return log_oom(); } - } else if (i == context->n_partitions - j) { + } else if (i == n_start_array - j) { _cleanup_free_ char *hint = NULL; (void) partition_hint(p, context->node, &hint); diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 0c4e3205eb..c64b2039f3 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -1264,6 +1264,29 @@ EOF assert_in "${loop}p3 : start= *${start}, size= *${size}, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=DB081670-07AE-48CA-9F5E-813D5E40B976, name=\"linux-generic-2\"" "$output" } +testcase_dropped_partitions() { + local workdir image defs + + workdir="$(mktemp --directory "/tmp/test-repart.dropped-partitions.XXXXXXXXXX")" + # shellcheck disable=SC2064 + trap "rm -rf '${workdir:?}'" RETURN + + image="$workdir/image.img" + truncate -s 32M "$image" + + defs="$workdir/defs" + mkdir "$defs" + echo -ne "[Partition]\nType=root\n" >"$defs/10-part1.conf" + echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=1\n" >"$defs/11-dropped-first.conf" + echo -ne "[Partition]\nType=root\n" >"$defs/12-part2.conf" + echo -ne "[Partition]\nType=root\nSizeMinBytes=1T\nPriority=2\n" >"$defs/13-dropped-second.conf" + + systemd-repart --empty=allow --pretty=yes --dry-run=no --definitions="$defs" "$image" + + sfdisk -q -l "$image" + [[ "$(sfdisk -q -l "$image" | grep -c "$image")" -eq 2 ]] +} + OFFLINE="yes" run_testcases