From d989dd763184f75133a9d44366799cbe1fb17400 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 22 Nov 2022 13:59:18 +0100 Subject: [PATCH 1/3] repart: Rename arg_filter_partitions_size to arg_n_filter_partitions --- src/partition/repart.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/partition/repart.c b/src/partition/repart.c index e23a0c3350..63c10cf3d5 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -143,7 +143,7 @@ static char *arg_tpm2_public_key = NULL; static uint32_t arg_tpm2_public_key_pcr_mask = UINT32_MAX; static bool arg_split = false; static sd_id128_t *arg_filter_partitions = NULL; -static size_t arg_filter_partitions_size = 0; +static size_t arg_n_filter_partitions = 0; static FilterPartitionsType arg_filter_partitions_type = FILTER_PARTITIONS_NONE; STATIC_DESTRUCTOR_REGISTER(arg_root, freep); @@ -391,7 +391,7 @@ static bool partition_skip(const Partition *p) { if (arg_filter_partitions_type == FILTER_PARTITIONS_NONE) return false; - for (size_t i = 0; i < arg_filter_partitions_size; i++) + for (size_t i = 0; i < arg_n_filter_partitions; i++) if (sd_id128_equal(p->type.uuid, arg_filter_partitions[i])) return arg_filter_partitions_type == FILTER_PARTITIONS_EXCLUDE; @@ -5350,10 +5350,10 @@ static int parse_filter_partitions(const char *p) { if (r < 0) return log_error_errno(r, "'%s' is not a valid partition type identifier or GUID", name); - if (!GREEDY_REALLOC(arg_filter_partitions, arg_filter_partitions_size + 1)) + if (!GREEDY_REALLOC(arg_filter_partitions, arg_n_filter_partitions + 1)) return log_oom(); - arg_filter_partitions[arg_filter_partitions_size++] = type.uuid; + arg_filter_partitions[arg_n_filter_partitions++] = type.uuid; } return 0; From 220780db86c0dabf1baef7781f9ad2921e93806b Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 22 Nov 2022 14:03:54 +0100 Subject: [PATCH 2/3] repart: Make parse_filter_partitions() more generic --- src/partition/repart.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/partition/repart.c b/src/partition/repart.c index 63c10cf3d5..855780f47f 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -5333,9 +5333,12 @@ static int context_minimize(Context *context) { return 0; } -static int parse_filter_partitions(const char *p) { +static int parse_partition_types(const char *p, sd_id128_t **partitions, size_t *n_partitions) { int r; + assert(partitions); + assert(n_partitions); + for (;;) { _cleanup_free_ char *name = NULL; GptPartitionType type; @@ -5350,10 +5353,10 @@ static int parse_filter_partitions(const char *p) { if (r < 0) return log_error_errno(r, "'%s' is not a valid partition type identifier or GUID", name); - if (!GREEDY_REALLOC(arg_filter_partitions, arg_n_filter_partitions + 1)) + if (!GREEDY_REALLOC(*partitions, *n_partitions + 1)) return log_oom(); - arg_filter_partitions[arg_n_filter_partitions++] = type.uuid; + (*partitions)[(*n_partitions)++] = type.uuid; } return 0; @@ -5730,7 +5733,7 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Combination of --include-partitions= and --exclude-partitions= is invalid."); - r = parse_filter_partitions(optarg); + r = parse_partition_types(optarg, &arg_filter_partitions, &arg_n_filter_partitions); if (r < 0) return r; @@ -5743,7 +5746,7 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Combination of --include-partitions= and --exclude-partitions= is invalid."); - r = parse_filter_partitions(optarg); + r = parse_partition_types(optarg, &arg_filter_partitions, &arg_n_filter_partitions); if (r < 0) return r; From 7d505753f1d75bb7ea806a4f7b0bd0fd906e7aed Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 22 Nov 2022 14:27:30 +0100 Subject: [PATCH 3/3] repart: Add --skip-partitions= --include-partitions and --exclude-partitions now fully exclude partitions from repart. Whenever a partition type is excluded, we don't take any partitions of that type into account at all when running systemd-repart. --skip-partitions= is introduced to do what --exclude-partitions did previously. Any skipped partitions are taken into acount when doing size calculations, but are not yet populated. Why do we need both concepts? Exclusion is needed so that we can use shared repart definitions to generate bootable and non-bootable images. When generating a non-bootable image, we use --exclude-partitions to exclude the ESP partition. Skipping is needed so that we can populate the root partition while skipping the ESP partition, get the roothash of the root partition, use that to generate a UKI, and finally populate the ESP partition with the UKI included. --- man/systemd-repart.xml | 17 ++++++++++++----- src/partition/repart.c | 37 +++++++++++++++++++++++++++++++++---- test/units/testsuite-58.sh | 8 ++++---- 3 files changed, 49 insertions(+), 13 deletions(-) diff --git a/man/systemd-repart.xml b/man/systemd-repart.xml index 6559fceedb..2c74afbe0f 100644 --- a/man/systemd-repart.xml +++ b/man/systemd-repart.xml @@ -372,11 +372,18 @@ are excluded. If is used, all partitions that are specified are excluded. Both options take a comma separated list of GPT partition type UUIDs or identifiers (see Type= in - repart.d5). All - partitions that are excluded using these options are still taken into account when calculating the - sizes and offsets of other partitions, but aren't actually written to the disk image. The net effect - of this option is that if you run systemd-repart again without these options, the - missing partitions will be added as if they had not been excluded the first time + repart.d5). + + + + + PARTITION + + This option specifies which partition types systemd-repart should + skip. All partitions that are skipped using this option are still taken into account when calculating + the sizes and offsets of other partitions, but aren't actually written to the disk image. The net + effect of this option is that if you run systemd-repart again without these + options, the missing partitions will be added as if they had not been skipped the first time systemd-repart was executed. diff --git a/src/partition/repart.c b/src/partition/repart.c index 855780f47f..7e56cc5155 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -145,6 +145,8 @@ static bool arg_split = false; static sd_id128_t *arg_filter_partitions = NULL; static size_t arg_n_filter_partitions = 0; static FilterPartitionsType arg_filter_partitions_type = FILTER_PARTITIONS_NONE; +static sd_id128_t *arg_skip_partitions = NULL; +static size_t arg_n_skip_partitions = 0; STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep); @@ -385,7 +387,7 @@ static void partition_foreignize(Partition *p) { p->verity = VERITY_OFF; } -static bool partition_skip(const Partition *p) { +static bool partition_exclude(const Partition *p) { assert(p); if (arg_filter_partitions_type == FILTER_PARTITIONS_NONE) @@ -398,6 +400,16 @@ static bool partition_skip(const Partition *p) { return arg_filter_partitions_type == FILTER_PARTITIONS_INCLUDE; } +static bool partition_skip(const Partition *p) { + assert(p); + + for (size_t i = 0; i < arg_n_skip_partitions; i++) + if (sd_id128_equal(p->type.uuid, arg_skip_partitions[i])) + return true; + + return false; +} + static Partition* partition_unlink_and_free(Context *context, Partition *p) { if (!p) return NULL; @@ -1559,6 +1571,9 @@ static int partition_read_definition(Partition *p, const char *path, const char if (r < 0) return r; + if (partition_exclude(p)) + return 0; + if (p->size_min != UINT64_MAX && p->size_max != UINT64_MAX && p->size_min > p->size_max) return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL), "SizeMinBytes= larger than SizeMaxBytes=, refusing."); @@ -1657,7 +1672,7 @@ static int partition_read_definition(Partition *p, const char *path, const char } else if (streq(p->split_name_format, "-")) p->split_name_format = mfree(p->split_name_format); - return 0; + return 1; } static int find_verity_sibling(Context *context, Partition *p, VerityMode mode, Partition **ret) { @@ -1732,6 +1747,8 @@ static int context_read_definitions( r = partition_read_definition(p, *f, dirs); if (r < 0) return r; + if (r == 0) + continue; LIST_INSERT_AFTER(partitions, context->partitions, last, p); last = TAKE_PTR(p); @@ -5405,9 +5422,12 @@ static int help(void) { " Generate JSON output\n" " --split=BOOL Whether to generate split artifacts\n" " --include-partitions=PARTITION1,PARTITION2,PARTITION3,…\n" - " Only operate on partitions of the specified types\n" + " Ignore partitions not of the specified types\n" " --exclude-partitions=PARTITION1,PARTITION2,PARTITION3,…\n" - " Don't operate on partitions of the specified types\n" + " Ignore partitions of the specified types\n" + " --skip-partitions=PARTITION1,PARTITION2,PARTITION3,…\n" + " Take partitions of the specified types into account\n" + " but don't populate them yet\n" "\nSee the %s for details.\n", program_invocation_short_name, ansi_highlight(), @@ -5445,6 +5465,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_SPLIT, ARG_INCLUDE_PARTITIONS, ARG_EXCLUDE_PARTITIONS, + ARG_SKIP_PARTITIONS, }; static const struct option options[] = { @@ -5474,6 +5495,7 @@ static int parse_argv(int argc, char *argv[]) { { "split", required_argument, NULL, ARG_SPLIT }, { "include-partitions", required_argument, NULL, ARG_INCLUDE_PARTITIONS }, { "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS }, + { "skip-partitions", required_argument, NULL, ARG_SKIP_PARTITIONS }, {} }; @@ -5754,6 +5776,13 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_SKIP_PARTITIONS: + r = parse_partition_types(optarg, &arg_skip_partitions, &arg_n_skip_partitions); + if (r < 0) + return r; + + break; + case '?': return -EINVAL; diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index a225ac8bee..01eec20745 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -154,13 +154,14 @@ device: $imgs/zzz unit: sectors first-lba: 2048 last-lba: 2097118 -$imgs/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\" -$imgs/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\"" +$imgs/zzz1 : start= 2048, size= 1775576, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\" +$imgs/zzz2 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\"" runas testuser systemd-repart --definitions="$defs" \ --dry-run=no \ --seed="$seed" \ - --exclude-partitions=root \ + --empty=force \ + --skip-partitions=home,root \ "$imgs/zzz" output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$') @@ -171,7 +172,6 @@ device: $imgs/zzz unit: sectors first-lba: 2048 last-lba: 2097118 -$imgs/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\" $imgs/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\"" runas testuser systemd-repart --definitions="$defs" \