repart: don't crash when looping over dropped partitions

Properly skip over dropped partitions and make sure they don't affect
the final graphical output (for example by leaving empty "spaces" where
their definition file name would otherwise be).

Resolves: #30742
This commit is contained in:
Frantisek Sumsal
2024-01-07 05:26:38 +09:00
committed by Yu Watanabe
parent 0417d1d0e8
commit f569dc6af2
2 changed files with 47 additions and 13 deletions
+24 -13
View File
@@ -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);
+23
View File
@@ -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