From 5249e953852d352fa18649420a2dcae83608e087 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 30 May 2023 13:30:08 +0200 Subject: [PATCH 1/4] gpt: Fix copy paste error --- src/shared/gpt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/shared/gpt.c b/src/shared/gpt.c index adf7325704..569c914be2 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -168,12 +168,12 @@ const GptPartitionType gpt_partition_type_table[] = { { SD_GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_architecture(), .designator = PARTITION_USR_VERITY_SIG }, #endif #ifdef SD_GPT_ROOT_SECONDARY - { SD_GPT_ROOT_NATIVE, "root-secondary", native_architecture(), .designator = PARTITION_ROOT }, - { SD_GPT_ROOT_NATIVE_VERITY, "root-secondary-verity", native_architecture(), .designator = PARTITION_ROOT_VERITY }, - { SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-secondary-verity-sig", native_architecture(), .designator = PARTITION_ROOT_VERITY_SIG }, - { SD_GPT_USR_NATIVE, "usr-secondary", native_architecture(), .designator = PARTITION_USR }, - { SD_GPT_USR_NATIVE_VERITY, "usr-secondary-verity", native_architecture(), .designator = PARTITION_USR_VERITY }, - { SD_GPT_USR_NATIVE_VERITY_SIG, "usr-secondary-verity-sig", native_architecture(), .designator = PARTITION_USR_VERITY_SIG }, + { SD_GPT_ROOT_SECONDARY, "root-secondary", ARCHITECTURE_SECONDARY, .designator = PARTITION_ROOT }, + { SD_GPT_ROOT_SECONDARY_VERITY, "root-secondary-verity", ARCHITECTURE_SECONDARY, .designator = PARTITION_ROOT_VERITY }, + { SD_GPT_ROOT_SECONDARY_VERITY_SIG, "root-secondary-verity-sig", ARCHITECTURE_SECONDARY, .designator = PARTITION_ROOT_VERITY_SIG }, + { SD_GPT_USR_SECONDARY, "usr-secondary", ARCHITECTURE_SECONDARY, .designator = PARTITION_USR }, + { SD_GPT_USR_SECONDARY_VERITY, "usr-secondary-verity", ARCHITECTURE_SECONDARY, .designator = PARTITION_USR_VERITY }, + { SD_GPT_USR_SECONDARY_VERITY_SIG, "usr-secondary-verity-sig", ARCHITECTURE_SECONDARY, .designator = PARTITION_USR_VERITY_SIG }, #endif { SD_GPT_ESP, "esp", _ARCHITECTURE_INVALID, .designator = PARTITION_ESP }, From 716a413a7dab79a5003a4acd15220fc1526c4415 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 31 May 2023 13:32:23 +0200 Subject: [PATCH 2/4] gpt: Use FOREACH_ARRAY --- src/shared/gpt.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/shared/gpt.c b/src/shared/gpt.c index 569c914be2..4df8724f41 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -190,9 +190,9 @@ const GptPartitionType gpt_partition_type_table[] = { static const GptPartitionType *gpt_partition_type_find_by_uuid(sd_id128_t id) { - for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++) - if (sd_id128_equal(id, gpt_partition_type_table[i].uuid)) - return gpt_partition_type_table + i; + FOREACH_ARRAY(t, gpt_partition_type_table, ELEMENTSOF(gpt_partition_type_table) - 1) + if (sd_id128_equal(id, t->uuid)) + return t; return NULL; } @@ -228,11 +228,11 @@ int gpt_partition_type_from_string(const char *s, GptPartitionType *ret) { assert(s); - for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++) - if (streq(s, gpt_partition_type_table[i].name)) { + FOREACH_ARRAY(t, gpt_partition_type_table, ELEMENTSOF(gpt_partition_type_table) - 1) + if (streq(s, t->name)) { /* Don't return immediately, instead re-resolve by UUID so that we can support * aliases like aarch64 -> arm64 transparently. */ - id = gpt_partition_type_table[i].uuid; + id = t->uuid; break; } From 7767b83f4a98a59b6d023f1296a5e2742c50453e Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Wed, 31 May 2023 13:44:00 +0200 Subject: [PATCH 3/4] gpt: Add gpt_partition_type_override_architecture() Let's add a function that allows changing the architecture of a given partition type. --- src/shared/gpt.c | 12 ++++++++++++ src/shared/gpt.h | 2 ++ src/test/test-gpt.c | 27 +++++++++++++++++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/shared/gpt.c b/src/shared/gpt.c index 4df8724f41..dd96261888 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -248,6 +248,18 @@ int gpt_partition_type_from_string(const char *s, GptPartitionType *ret) { return 0; } +GptPartitionType gpt_partition_type_override_architecture(GptPartitionType type, Architecture arch) { + assert(arch >= 0); + + FOREACH_ARRAY(t, gpt_partition_type_table, ELEMENTSOF(gpt_partition_type_table) - 1) + if (t->designator == type.designator && t->arch == arch) + return *t; + + /* If we can't find an entry with the same designator and the requested architecture, just return the + * original partition type. */ + return type; +} + Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id) { const GptPartitionType *pt; diff --git a/src/shared/gpt.h b/src/shared/gpt.h index bebfbc6116..8623a8664e 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -62,6 +62,8 @@ int gpt_partition_label_valid(const char *s); GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id); int gpt_partition_type_from_string(const char *s, GptPartitionType *ret); +GptPartitionType gpt_partition_type_override_architecture(GptPartitionType type, Architecture arch); + const char *gpt_partition_type_mountpoint_nulstr(GptPartitionType type); bool gpt_partition_type_knows_read_only(GptPartitionType type); diff --git a/src/test/test-gpt.c b/src/test/test-gpt.c index 5ad30fab44..fa5923eb27 100644 --- a/src/test/test-gpt.c +++ b/src/test/test-gpt.c @@ -81,4 +81,31 @@ TEST(type_alias_same) { } } +TEST(override_architecture) { + GptPartitionType x, y; + + assert_se(gpt_partition_type_from_string("root-x86-64", &x) >= 0); + assert_se(x.arch == ARCHITECTURE_X86_64); + + assert_se(gpt_partition_type_from_string("root-arm64", &y) >= 0); + assert(y.arch == ARCHITECTURE_ARM64); + + x = gpt_partition_type_override_architecture(x, ARCHITECTURE_ARM64); + assert_se(x.arch == y.arch); + assert_se(x.designator == y.designator); + assert_se(sd_id128_equal(x.uuid, y.uuid)); + assert_se(streq(x.name, y.name)); + + /* If the partition type does not have an architecture, nothing should change. */ + + assert_se(gpt_partition_type_from_string("esp", &x) >= 0); + y = x; + + x = gpt_partition_type_override_architecture(x, ARCHITECTURE_ARM64); + assert_se(x.arch == y.arch); + assert_se(x.designator == y.designator); + assert_se(sd_id128_equal(x.uuid, y.uuid)); + assert_se(streq(x.name, y.name)); +} + DEFINE_TEST_MAIN(LOG_INFO); From 9786dfe60fc59ed9e39ec2305372b4da809219bd Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 30 May 2023 10:11:23 +0200 Subject: [PATCH 4/4] repart: Add --architecture option This option allows overriding the architecture that's used for the architecture specific partition types. This is useful to allow reusing the same repart configuration to produce the same image for different architectures. --- man/systemd-repart.xml | 28 ++++++++++++++++++++++++++++ src/partition/repart.c | 35 +++++++++++++++++++++++++++++------ 2 files changed, 57 insertions(+), 6 deletions(-) diff --git a/man/systemd-repart.xml b/man/systemd-repart.xml index cd5d4631db..08c116ee05 100644 --- a/man/systemd-repart.xml +++ b/man/systemd-repart.xml @@ -398,6 +398,34 @@ disks that use a different sector size as the disk on which the image is produced. + + ARCH + + This option allows overriding the architecture used for architecture specific + partition types. For example, if set to arm64 a partition type of + root-x86-64 referenced in repart.d/ drop-ins will be patched + dynamically to refer to root-arm64 instead. Takes one of + alpha, + arc, + arm, + arm64, + ia64, + loongarch64, + mips-le, + mips64-le, + parisc, + ppc, + ppc64, + ppc64-le, + riscv32, + riscv64, + s390, + s390x, + tilegx, + x86 or + x86-64. + + diff --git a/src/partition/repart.c b/src/partition/repart.c index 4fde0a58a5..2e9badfd31 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -144,13 +144,14 @@ static uint32_t arg_tpm2_pcr_mask = UINT32_MAX; 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 GptPartitionType *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_defer_partitions = NULL; +static GptPartitionType *arg_defer_partitions = NULL; static size_t arg_n_defer_partitions = 0; static uint64_t arg_sector_size = 0; static ImagePolicy *arg_image_policy = NULL; +static Architecture arg_architecture = _ARCHITECTURE_INVALID; STATIC_DESTRUCTOR_REGISTER(arg_root, freep); STATIC_DESTRUCTOR_REGISTER(arg_image, freep); @@ -428,7 +429,7 @@ static bool partition_exclude(const Partition *p) { return false; for (size_t i = 0; i < arg_n_filter_partitions; i++) - if (sd_id128_equal(p->type.uuid, arg_filter_partitions[i])) + if (sd_id128_equal(p->type.uuid, arg_filter_partitions[i].uuid)) return arg_filter_partitions_type == FILTER_PARTITIONS_EXCLUDE; return arg_filter_partitions_type == FILTER_PARTITIONS_INCLUDE; @@ -438,7 +439,7 @@ static bool partition_defer(const Partition *p) { assert(p); for (size_t i = 0; i < arg_n_defer_partitions; i++) - if (sd_id128_equal(p->type.uuid, arg_defer_partitions[i])) + if (sd_id128_equal(p->type.uuid, arg_defer_partitions[i].uuid)) return true; return false; @@ -1180,6 +1181,9 @@ static int config_parse_type( if (r < 0) return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition type: %s", rvalue); + if (arg_architecture >= 0) + *type = gpt_partition_type_override_architecture(*type, arg_architecture); + return 0; } @@ -5766,7 +5770,7 @@ static int context_minimize(Context *context) { return 0; } -static int parse_partition_types(const char *p, sd_id128_t **partitions, size_t *n_partitions) { +static int parse_partition_types(const char *p, GptPartitionType **partitions, size_t *n_partitions) { int r; assert(partitions); @@ -5789,7 +5793,7 @@ static int parse_partition_types(const char *p, sd_id128_t **partitions, size_t if (!GREEDY_REALLOC(*partitions, *n_partitions + 1)) return log_oom(); - (*partitions)[(*n_partitions)++] = type.uuid; + (*partitions)[(*n_partitions)++] = type; } return 0; @@ -5847,6 +5851,7 @@ static int help(void) { " Take partitions of the specified types into account\n" " but don't populate them yet\n" " --sector-size=SIZE Set the logical sector size for the image\n" + " --architecture=ARCH Set the generic architecture for the image\n" "\nSee the %s for details.\n", program_invocation_short_name, ansi_highlight(), @@ -5888,6 +5893,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_DEFER_PARTITIONS, ARG_SECTOR_SIZE, ARG_SKIP_PARTITIONS, + ARG_ARCHITECTURE, }; static const struct option options[] = { @@ -5920,6 +5926,7 @@ static int parse_argv(int argc, char *argv[]) { { "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS }, { "defer-partitions", required_argument, NULL, ARG_DEFER_PARTITIONS }, { "sector-size", required_argument, NULL, ARG_SECTOR_SIZE }, + { "architecture", required_argument, NULL, ARG_ARCHITECTURE }, {} }; @@ -6220,6 +6227,14 @@ static int parse_argv(int argc, char *argv[]) { break; + case ARG_ARCHITECTURE: + r = architecture_from_string(optarg); + if (r < 0) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid architecture '%s'", optarg); + + arg_architecture = r; + break; + case '?': return -EINVAL; @@ -6283,6 +6298,14 @@ static int parse_argv(int argc, char *argv[]) { if (arg_pretty < 0 && isatty(STDOUT_FILENO)) arg_pretty = true; + if (arg_architecture >= 0) { + FOREACH_ARRAY(p, arg_filter_partitions, arg_n_filter_partitions) + *p = gpt_partition_type_override_architecture(*p, arg_architecture); + + FOREACH_ARRAY(p, arg_defer_partitions, arg_n_defer_partitions) + *p = gpt_partition_type_override_architecture(*p, arg_architecture); + } + return 1; }