From: Daan De Meyer Date: Thu, 13 Oct 2022 19:26:16 +0000 (+0200) Subject: gpt: Expose GptPartitionType and get rid of SECONDARY/OTHER X-Git-Tag: v253-rc1~525^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=22e932f4d15f59ae773370a41a1c01ec93f8915a;p=thirdparty%2Fsystemd.git gpt: Expose GptPartitionType and get rid of SECONDARY/OTHER Instead of exposing just the partition type UUID, let's expose the GptPartitionType struct, which has a lot more information available in a much more accessible way. Also, let's get rid of SECONDARY/OTHER in PartitionDesignator. These were only there to support preferred architectures in dissect-image.c, but we can easily handle that by comparing architectures when we decide whether to override a partition. This is done in a new function compare_arch(). --- diff --git a/src/id128/id128.c b/src/id128/id128.c index af88e315bbc..53a24348d5c 100644 --- a/src/id128/id128.c +++ b/src/id128/id128.c @@ -123,10 +123,13 @@ static int verb_show(int argc, char **argv, void *userdata) { if (have_uuid) id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ"; else { - r = gpt_partition_type_uuid_from_string(*p, &uuid); + GptPartitionType type; + + r = gpt_partition_type_from_string(*p, &type); if (r < 0) return log_error_errno(r, "Unknown identifier \"%s\".", *p); + uuid = type.uuid; id = *p; } diff --git a/src/partition/repart.c b/src/partition/repart.c index 4cdbeadf711..20f764ee1ca 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -164,7 +164,7 @@ struct Partition { char *definition_path; char **drop_in_files; - sd_id128_t type_uuid; + GptPartitionType type; sd_id128_t current_uuid, new_uuid; bool new_uuid_is_set; char *current_label, *new_label; @@ -1087,12 +1087,12 @@ static int config_parse_type( void *data, void *userdata) { - sd_id128_t *type_uuid = ASSERT_PTR(data); + GptPartitionType *type = ASSERT_PTR(data); int r; assert(rvalue); - r = gpt_partition_type_uuid_from_string(rvalue, type_uuid); + r = gpt_partition_type_from_string(rvalue, type); if (r < 0) return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition type: %s", rvalue); @@ -1478,7 +1478,7 @@ static DEFINE_CONFIG_PARSE_ENUM_WITH_DEFAULT(config_parse_verity, verity_mode, V static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) { ConfigTableItem table[] = { - { "Partition", "Type", config_parse_type, 0, &p->type_uuid }, + { "Partition", "Type", config_parse_type, 0, &p->type }, { "Partition", "Label", config_parse_label, 0, &p->new_label }, { "Partition", "UUID", config_parse_uuid, 0, p }, { "Partition", "Priority", config_parse_int32, 0, &p->priority }, @@ -1535,7 +1535,7 @@ static int partition_read_definition(Partition *p, const char *path, const char return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL), "PaddingMinBytes= larger than PaddingMaxBytes=, refusing."); - if (sd_id128_is_null(p->type_uuid)) + if (sd_id128_is_null(p->type.uuid)) return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL), "Type= not defined, refusing."); @@ -1599,13 +1599,13 @@ static int partition_read_definition(Partition *p, const char *path, const char verity_mode_to_string(p->verity)); /* Verity partitions are read only, let's imply the RO flag hence, unless explicitly configured otherwise. */ - if ((gpt_partition_type_is_root_verity(p->type_uuid) || - gpt_partition_type_is_usr_verity(p->type_uuid)) && + if ((p->type.designator == PARTITION_ROOT_VERITY || + p->type.designator == PARTITION_USR_VERITY) && p->read_only < 0) p->read_only = true; /* Default to "growfs" on, unless read-only */ - if (gpt_partition_type_knows_growfs(p->type_uuid) && + if (gpt_partition_type_knows_growfs(p->type) && p->read_only <= 0) p->growfs = true; @@ -2099,7 +2099,7 @@ static int context_load_partition_table( LIST_FOREACH(partitions, pp, context->partitions) { last = pp; - if (!sd_id128_equal(pp->type_uuid, ptid)) + if (!sd_id128_equal(pp->type.uuid, ptid)) continue; if (!pp->current_partition) { @@ -2136,7 +2136,7 @@ static int context_load_partition_table( return log_oom(); np->current_uuid = id; - np->type_uuid = ptid; + np->type = gpt_partition_type_from_uuid(ptid); np->current_size = sz; np->offset = start; np->partno = partno; @@ -2295,7 +2295,7 @@ static const char *partition_label(const Partition *p) { if (p->current_label) return p->current_label; - return gpt_partition_type_uuid_to_string(p->type_uuid); + return gpt_partition_type_uuid_to_string(p->type.uuid); } static int context_dump_partitions(Context *context, const char *node) { @@ -2369,7 +2369,7 @@ static int context_dump_partitions(Context *context, const char *node) { r = table_add_many( t, - TABLE_STRING, gpt_partition_type_uuid_to_string_harder(p->type_uuid, uuid_buffer), + TABLE_STRING, gpt_partition_type_uuid_to_string_harder(p->type.uuid, uuid_buffer), TABLE_STRING, empty_to_null(label) ?: "-", TABLE_SET_COLOR, empty_to_null(label) ? NULL : ansi_grey(), TABLE_UUID, p->new_uuid_is_set ? p->new_uuid : p->current_uuid, TABLE_STRING, p->definition_path ? basename(p->definition_path) : "-", TABLE_SET_COLOR, p->definition_path ? NULL : ansi_grey(), @@ -2503,7 +2503,7 @@ static int partition_hint(const Partition *p, const char *node, char **ret) { else if (!sd_id128_is_null(p->current_uuid)) id = p->current_uuid; else - id = p->type_uuid; + id = p->type.uuid; buf = strdup(SD_ID128_TO_UUID_STRING(id)); @@ -3463,7 +3463,7 @@ static int make_copy_files_denylist(Context *context, Set **ret) { assert(ret); LIST_FOREACH(partitions, p, context->partitions) { - const char *sources = gpt_partition_type_mountpoint_nulstr(p->type_uuid); + const char *sources = gpt_partition_type_mountpoint_nulstr(p->type); if (!sources) continue; @@ -3955,13 +3955,13 @@ static int partition_acquire_uuid(Context *context, Partition *p, sd_id128_t *re if (p == q) break; - if (!sd_id128_equal(p->type_uuid, q->type_uuid)) + if (!sd_id128_equal(p->type.uuid, q->type.uuid)) continue; k++; } - plaintext.type_uuid = p->type_uuid; + plaintext.type_uuid = p->type.uuid; plaintext.counter = htole64(k); hmac_sha256(context->seed.bytes, sizeof(context->seed.bytes), @@ -4002,7 +4002,7 @@ static int partition_acquire_label(Context *context, Partition *p, char **ret) { assert(p); assert(ret); - prefix = gpt_partition_type_uuid_to_string(p->type_uuid); + prefix = gpt_partition_type_uuid_to_string(p->type.uuid); if (!prefix) prefix = "linux"; @@ -4118,35 +4118,35 @@ static uint64_t partition_merge_flags(Partition *p) { f = p->gpt_flags; if (p->no_auto >= 0) { - if (gpt_partition_type_knows_no_auto(p->type_uuid)) + if (gpt_partition_type_knows_no_auto(p->type)) SET_FLAG(f, SD_GPT_FLAG_NO_AUTO, p->no_auto); else { char buffer[SD_ID128_UUID_STRING_MAX]; log_warning("Configured NoAuto=%s for partition type '%s' that doesn't support it, ignoring.", yes_no(p->no_auto), - gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer)); + gpt_partition_type_uuid_to_string_harder(p->type.uuid, buffer)); } } if (p->read_only >= 0) { - if (gpt_partition_type_knows_read_only(p->type_uuid)) + if (gpt_partition_type_knows_read_only(p->type)) SET_FLAG(f, SD_GPT_FLAG_READ_ONLY, p->read_only); else { char buffer[SD_ID128_UUID_STRING_MAX]; log_warning("Configured ReadOnly=%s for partition type '%s' that doesn't support it, ignoring.", yes_no(p->read_only), - gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer)); + gpt_partition_type_uuid_to_string_harder(p->type.uuid, buffer)); } } if (p->growfs >= 0) { - if (gpt_partition_type_knows_growfs(p->type_uuid)) + if (gpt_partition_type_knows_growfs(p->type)) SET_FLAG(f, SD_GPT_FLAG_GROWFS, p->growfs); else { char buffer[SD_ID128_UUID_STRING_MAX]; log_warning("Configured GrowFileSystem=%s for partition type '%s' that doesn't support it, ignoring.", yes_no(p->growfs), - gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer)); + gpt_partition_type_uuid_to_string_harder(p->type.uuid, buffer)); } } @@ -4225,7 +4225,7 @@ static int context_mangle_partitions(Context *context) { if (!t) return log_oom(); - r = fdisk_parttype_set_typestr(t, SD_ID128_TO_UUID_STRING(p->type_uuid)); + r = fdisk_parttype_set_typestr(t, SD_ID128_TO_UUID_STRING(p->type.uuid)); if (r < 0) return log_error_errno(r, "Failed to initialize partition type: %m"); @@ -4284,8 +4284,8 @@ static int split_name_printf(Partition *p) { assert(p); const Specifier table[] = { - { 't', specifier_string, GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(p->type_uuid) }, - { 'T', specifier_id128, &p->type_uuid }, + { 't', specifier_string, GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(p->type.uuid) }, + { 'T', specifier_id128, &p->type.uuid }, { 'U', specifier_id128, &p->new_uuid }, { 'n', specifier_uint64, &p->partno }, @@ -4614,7 +4614,7 @@ static int context_can_factory_reset(Context *context) { static int resolve_copy_blocks_auto_candidate( dev_t partition_devno, - sd_id128_t partition_type_uuid, + GptPartitionType partition_type, dev_t restrict_devno, sd_id128_t *ret_uuid) { @@ -4706,10 +4706,10 @@ static int resolve_copy_blocks_auto_candidate( return false; } - if (!sd_id128_equal(pt_parsed, partition_type_uuid)) { + if (!sd_id128_equal(pt_parsed, partition_type.uuid)) { log_debug("Partition %u:%u has non-matching partition type " SD_ID128_FORMAT_STR " (needed: " SD_ID128_FORMAT_STR "), ignoring.", major(partition_devno), minor(partition_devno), - SD_ID128_FORMAT_VAL(pt_parsed), SD_ID128_FORMAT_VAL(partition_type_uuid)); + SD_ID128_FORMAT_VAL(pt_parsed), SD_ID128_FORMAT_VAL(partition_type.uuid)); return false; } @@ -4766,7 +4766,7 @@ static int find_backing_devno( } static int resolve_copy_blocks_auto( - sd_id128_t type_uuid, + GptPartitionType type, const char *root, dev_t restrict_devno, dev_t *ret_devno, @@ -4796,30 +4796,30 @@ static int resolve_copy_blocks_auto( * partitions in the host, using the appropriate directory as key and ensuring that the partition * type matches. */ - if (gpt_partition_type_is_root(type_uuid)) + if (type.designator == PARTITION_ROOT) try1 = "/"; - else if (gpt_partition_type_is_usr(type_uuid)) + else if (type.designator == PARTITION_USR) try1 = "/usr/"; - else if (gpt_partition_type_is_root_verity(type_uuid)) + else if (type.designator == PARTITION_ROOT_VERITY) try1 = "/"; - else if (gpt_partition_type_is_usr_verity(type_uuid)) + else if (type.designator == PARTITION_USR_VERITY) try1 = "/usr/"; - else if (sd_id128_equal(type_uuid, SD_GPT_ESP)) { + else if (type.designator == PARTITION_ESP) { try1 = "/efi/"; try2 = "/boot/"; - } else if (sd_id128_equal(type_uuid, SD_GPT_XBOOTLDR)) + } else if (type.designator == PARTITION_XBOOTLDR) try1 = "/boot/"; else return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Partition type " SD_ID128_FORMAT_STR " not supported from automatic source block device discovery.", - SD_ID128_FORMAT_VAL(type_uuid)); + SD_ID128_FORMAT_VAL(type.uuid)); r = find_backing_devno(try1, root, &devno); if (r == -ENOENT && try2) r = find_backing_devno(try2, root, &devno); if (r < 0) return log_error_errno(r, "Failed to resolve automatic CopyBlocks= path for partition type " SD_ID128_FORMAT_STR ", sorry: %m", - SD_ID128_FORMAT_VAL(type_uuid)); + SD_ID128_FORMAT_VAL(type.uuid)); xsprintf_sys_block_path(p, "/slaves", devno); d = opendir(p); @@ -4861,7 +4861,7 @@ static int resolve_copy_blocks_auto( continue; } - r = resolve_copy_blocks_auto_candidate(sl, type_uuid, restrict_devno, &u); + r = resolve_copy_blocks_auto_candidate(sl, type, restrict_devno, &u); if (r < 0) return r; if (r > 0) { @@ -4877,7 +4877,7 @@ static int resolve_copy_blocks_auto( } else if (errno != ENOENT) return log_error_errno(errno, "Failed open %s: %m", p); else { - r = resolve_copy_blocks_auto_candidate(devno, type_uuid, restrict_devno, &found_uuid); + r = resolve_copy_blocks_auto_candidate(devno, type, restrict_devno, &found_uuid); if (r < 0) return r; if (r > 0) @@ -4934,7 +4934,7 @@ static int context_open_copy_block_paths( } else if (p->copy_blocks_auto) { dev_t devno; - r = resolve_copy_blocks_auto(p->type_uuid, p->copy_blocks_root, restrict_devno, &devno, &uuid); + r = resolve_copy_blocks_auto(p->type, p->copy_blocks_root, restrict_devno, &devno, &uuid); if (r < 0) return r; diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index 8418ed6dc37..d67bdd501bc 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -333,6 +333,27 @@ static int open_partition(const char *node, bool is_partition, const LoopDevice return TAKE_FD(fd); } +static int compare_arch(Architecture a, Architecture b) { + if (a == b) + return 0; + + if (a == native_architecture()) + return 1; + + if (b == native_architecture()) + return -1; + +#ifdef ARCHITECTURE_SECONDARY + if (a == ARCHITECTURE_SECONDARY) + return 1; + + if (b == ARCHITECTURE_SECONDARY) + return -1; +#endif + + return 0; +} + static int dissect_image( DissectedImage *m, int fd, @@ -606,10 +627,9 @@ static int dissect_image( } if (is_gpt) { - PartitionDesignator designator = _PARTITION_DESIGNATOR_INVALID; - Architecture architecture = _ARCHITECTURE_INVALID; const char *stype, *sid, *fstype = NULL, *label; sd_id128_t type_id, id; + GptPartitionType type; bool rw = true, growfs = false; sid = blkid_partition_get_uuid(pp); @@ -624,9 +644,11 @@ static int dissect_image( if (sd_id128_from_string(stype, &type_id) < 0) continue; + type = gpt_partition_type_from_uuid(type_id); + label = blkid_partition_get_name(pp); /* libblkid returns NULL here if empty */ - if (sd_id128_equal(type_id, SD_GPT_HOME)) { + if (type.designator == PARTITION_HOME) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -634,11 +656,10 @@ static int dissect_image( if (pflags & SD_GPT_FLAG_NO_AUTO) continue; - designator = PARTITION_HOME; rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); - } else if (sd_id128_equal(type_id, SD_GPT_SRV)) { + } else if (type.designator == PARTITION_SRV) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -646,11 +667,10 @@ static int dissect_image( if (pflags & SD_GPT_FLAG_NO_AUTO) continue; - designator = PARTITION_SRV; rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); - } else if (sd_id128_equal(type_id, SD_GPT_ESP)) { + } else if (type.designator == PARTITION_ESP) { /* Note that we don't check the SD_GPT_FLAG_NO_AUTO flag for the ESP, as it is * not defined there. We instead check the SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL, as @@ -660,10 +680,9 @@ static int dissect_image( if (pflags & SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL) continue; - designator = PARTITION_ESP; fstype = "vfat"; - } else if (sd_id128_equal(type_id, SD_GPT_XBOOTLDR)) { + } else if (type.designator == PARTITION_XBOOTLDR) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -671,11 +690,10 @@ static int dissect_image( if (pflags & SD_GPT_FLAG_NO_AUTO) continue; - designator = PARTITION_XBOOTLDR; rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); - } else if (gpt_partition_type_is_root(type_id)) { + } else if (type.designator == PARTITION_ROOT) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -687,12 +705,10 @@ static int dissect_image( if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id)) continue; - assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0); - designator = partition_root_of_arch(architecture); rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); - } else if (gpt_partition_type_is_root_verity(type_id)) { + } else if (type.designator == PARTITION_ROOT_VERITY) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY); @@ -712,12 +728,10 @@ static int dissect_image( if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id)) continue; - assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0); - designator = partition_verity_of(partition_root_of_arch(architecture)); fstype = "DM_verity_hash"; rw = false; - } else if (gpt_partition_type_is_root_verity_sig(type_id)) { + } else if (type.designator == PARTITION_ROOT_VERITY_SIG) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY); @@ -732,12 +746,10 @@ static int dissect_image( if (verity->designator >= 0 && verity->designator != PARTITION_ROOT) continue; - assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0); - designator = partition_verity_sig_of(partition_root_of_arch(architecture)); fstype = "verity_hash_signature"; rw = false; - } else if (gpt_partition_type_is_usr(type_id)) { + } else if (type.designator == PARTITION_USR) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -749,12 +761,10 @@ static int dissect_image( if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id)) continue; - assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0); - designator = partition_usr_of_arch(architecture); rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); - } else if (gpt_partition_type_is_usr_verity(type_id)) { + } else if (type.designator == PARTITION_USR_VERITY) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY); @@ -773,12 +783,10 @@ static int dissect_image( if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id)) continue; - assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0); - designator = partition_verity_of(partition_usr_of_arch(architecture)); fstype = "DM_verity_hash"; rw = false; - } else if (gpt_partition_type_is_usr_verity_sig(type_id)) { + } else if (type.designator == PARTITION_USR_VERITY_SIG) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY); @@ -793,21 +801,17 @@ static int dissect_image( if (verity->designator >= 0 && verity->designator != PARTITION_USR) continue; - assert_se((architecture = gpt_partition_type_uuid_to_arch(type_id)) >= 0); - designator = partition_verity_sig_of(partition_usr_of_arch(architecture)); fstype = "verity_hash_signature"; rw = false; - } else if (sd_id128_equal(type_id, SD_GPT_SWAP)) { + } else if (type.designator == PARTITION_SWAP) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO); if (pflags & SD_GPT_FLAG_NO_AUTO) continue; - designator = PARTITION_SWAP; - - } else if (sd_id128_equal(type_id, SD_GPT_LINUX_GENERIC)) { + } else if (type.designator == PARTITION_LINUX_GENERIC) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -827,7 +831,7 @@ static int dissect_image( return -ENOMEM; } - } else if (sd_id128_equal(type_id, SD_GPT_TMP)) { + } else if (type.designator == PARTITION_TMP) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -835,11 +839,10 @@ static int dissect_image( if (pflags & SD_GPT_FLAG_NO_AUTO) continue; - designator = PARTITION_TMP; rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); - } else if (sd_id128_equal(type_id, SD_GPT_VAR)) { + } else if (type.designator == PARTITION_VAR) { check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS); @@ -868,27 +871,29 @@ static int dissect_image( } } - designator = PARTITION_VAR; rw = !(pflags & SD_GPT_FLAG_READ_ONLY); growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS); } - if (designator != _PARTITION_DESIGNATOR_INVALID) { + if (type.designator != _PARTITION_DESIGNATOR_INVALID) { _cleanup_free_ char *t = NULL, *o = NULL, *l = NULL; _cleanup_close_ int mount_node_fd = -1; const char *options = NULL; - if (m->partitions[designator].found) { + if (m->partitions[type.designator].found) { /* For most partition types the first one we see wins. Except for the * rootfs and /usr, where we do a version compare of the label, and * let the newest version win. This permits a simple A/B versioning * scheme in OS images. */ - if (!partition_designator_is_versioned(designator) || - strverscmp_improved(m->partitions[designator].label, label) >= 0) + if (compare_arch(type.arch, m->partitions[type.designator].architecture) <= 0) + continue; + + if (!partition_designator_is_versioned(type.designator) || + strverscmp_improved(m->partitions[type.designator].label, label) >= 0) continue; - dissected_partition_done(m->partitions + designator); + dissected_partition_done(m->partitions + type.designator); } if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) { @@ -909,19 +914,19 @@ static int dissect_image( return -ENOMEM; } - options = mount_options_from_designator(mount_options, designator); + options = mount_options_from_designator(mount_options, type.designator); if (options) { o = strdup(options); if (!o) return -ENOMEM; } - m->partitions[designator] = (DissectedPartition) { + m->partitions[type.designator] = (DissectedPartition) { .found = true, .partno = nr, .rw = rw, .growfs = growfs, - .architecture = architecture, + .architecture = type.arch, .node = TAKE_PTR(node), .fstype = TAKE_PTR(t), .label = TAKE_PTR(l), @@ -1001,121 +1006,21 @@ static int dissect_image( } } - if (m->partitions[PARTITION_ROOT].found) { - /* If we found the primary arch, then invalidate the secondary and other arch to avoid any - * ambiguities, since we never want to mount the secondary or other arch in this case. */ - m->partitions[PARTITION_ROOT_SECONDARY].found = false; - m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found = false; - m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found = false; - m->partitions[PARTITION_USR_SECONDARY].found = false; - m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false; - m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false; - - m->partitions[PARTITION_ROOT_OTHER].found = false; - m->partitions[PARTITION_ROOT_OTHER_VERITY].found = false; - m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG].found = false; - m->partitions[PARTITION_USR_OTHER].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false; - - } else if (m->partitions[PARTITION_ROOT_VERITY].found || - m->partitions[PARTITION_ROOT_VERITY_SIG].found) - return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */ - - else if (m->partitions[PARTITION_ROOT_SECONDARY].found) { - - /* No root partition found but there's one for the secondary architecture? Then upgrade - * secondary arch to first and invalidate the other arch. */ - - log_debug("No root partition found of the native architecture, falling back to a root " - "partition of the secondary architecture."); - - m->partitions[PARTITION_ROOT] = TAKE_PARTITION(m->partitions[PARTITION_ROOT_SECONDARY]); - m->partitions[PARTITION_ROOT_VERITY] = TAKE_PARTITION(m->partitions[PARTITION_ROOT_SECONDARY_VERITY]); - m->partitions[PARTITION_ROOT_VERITY_SIG] = TAKE_PARTITION(m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG]); - - m->partitions[PARTITION_USR] = TAKE_PARTITION(m->partitions[PARTITION_USR_SECONDARY]); - m->partitions[PARTITION_USR_VERITY] = TAKE_PARTITION(m->partitions[PARTITION_USR_SECONDARY_VERITY]); - m->partitions[PARTITION_USR_VERITY_SIG] = TAKE_PARTITION(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]); - - m->partitions[PARTITION_ROOT_OTHER].found = false; - m->partitions[PARTITION_ROOT_OTHER_VERITY].found = false; - m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG].found = false; - m->partitions[PARTITION_USR_OTHER].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false; - - } else if (m->partitions[PARTITION_ROOT_SECONDARY_VERITY].found || - m->partitions[PARTITION_ROOT_SECONDARY_VERITY_SIG].found) - return -EADDRNOTAVAIL; /* as above */ - - else if (m->partitions[PARTITION_ROOT_OTHER].found) { - - /* No root or secondary partition found but there's one for another architecture? Then - * upgrade the other architecture to first. */ - - log_debug("No root partition found of the native architecture or the secondary architecture, " - "falling back to a root partition of a non-native architecture (%s).", - architecture_to_string(m->partitions[PARTITION_ROOT_OTHER].architecture)); - - m->partitions[PARTITION_ROOT] = TAKE_PARTITION(m->partitions[PARTITION_ROOT_OTHER]); - m->partitions[PARTITION_ROOT_VERITY] = TAKE_PARTITION(m->partitions[PARTITION_ROOT_OTHER_VERITY]); - m->partitions[PARTITION_ROOT_VERITY_SIG] = TAKE_PARTITION(m->partitions[PARTITION_ROOT_OTHER_VERITY_SIG]); - - m->partitions[PARTITION_USR] = TAKE_PARTITION(m->partitions[PARTITION_USR_OTHER]); - m->partitions[PARTITION_USR_VERITY] = TAKE_PARTITION(m->partitions[PARTITION_USR_OTHER_VERITY]); - m->partitions[PARTITION_USR_VERITY_SIG] = TAKE_PARTITION(m->partitions[PARTITION_USR_OTHER_VERITY_SIG]); - } + if (!m->partitions[PARTITION_ROOT].found && + (m->partitions[PARTITION_ROOT_VERITY].found || + m->partitions[PARTITION_ROOT_VERITY_SIG].found)) + return -EADDRNOTAVAIL; /* Verity found but no matching rootfs? Something is off, refuse. */ /* Hmm, we found a signature partition but no Verity data? Something is off. */ if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found) return -EADDRNOTAVAIL; - if (m->partitions[PARTITION_USR].found) { - /* Invalidate secondary and other arch /usr/ if we found the primary arch */ - m->partitions[PARTITION_USR_SECONDARY].found = false; - m->partitions[PARTITION_USR_SECONDARY_VERITY].found = false; - m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found = false; - - m->partitions[PARTITION_USR_OTHER].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false; - - } else if (m->partitions[PARTITION_USR_VERITY].found || - m->partitions[PARTITION_USR_VERITY_SIG].found) - return -EADDRNOTAVAIL; /* as above */ - - else if (m->partitions[PARTITION_USR_SECONDARY].found) { - - log_debug("No usr partition found of the native architecture, falling back to a usr " - "partition of the secondary architecture."); - - /* Upgrade secondary arch to primary */ - m->partitions[PARTITION_USR] = TAKE_PARTITION(m->partitions[PARTITION_USR_SECONDARY]); - m->partitions[PARTITION_USR_VERITY] = TAKE_PARTITION(m->partitions[PARTITION_USR_SECONDARY_VERITY]); - m->partitions[PARTITION_USR_VERITY_SIG] = TAKE_PARTITION(m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG]); + if (!m->partitions[PARTITION_USR].found && + (m->partitions[PARTITION_USR_VERITY].found || + m->partitions[PARTITION_USR_VERITY_SIG].found)) + return -EADDRNOTAVAIL; /* as above */ - m->partitions[PARTITION_USR_OTHER].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY].found = false; - m->partitions[PARTITION_USR_OTHER_VERITY_SIG].found = false; - - } else if (m->partitions[PARTITION_USR_SECONDARY_VERITY].found || - m->partitions[PARTITION_USR_SECONDARY_VERITY_SIG].found) - return -EADDRNOTAVAIL; /* as above */ - - else if (m->partitions[PARTITION_USR_OTHER].found) { - - log_debug("No usr partition found of the native architecture or the secondary architecture, " - "falling back to a usr partition of a non-native architecture (%s).", - architecture_to_string(m->partitions[PARTITION_ROOT_OTHER].architecture)); - - /* Upgrade other arch to primary */ - m->partitions[PARTITION_USR] = TAKE_PARTITION(m->partitions[PARTITION_USR_OTHER]); - m->partitions[PARTITION_USR_VERITY] = TAKE_PARTITION(m->partitions[PARTITION_USR_OTHER_VERITY]); - m->partitions[PARTITION_USR_VERITY_SIG] = TAKE_PARTITION(m->partitions[PARTITION_USR_OTHER_VERITY_SIG]); - } - - /* Hmm, we found a signature partition but no Verity data? Something is off. */ + /* as above */ if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found) return -EADDRNOTAVAIL; diff --git a/src/shared/gpt.c b/src/shared/gpt.c index af969ff9d57..ce73d7f7819 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -23,23 +23,11 @@ bool partition_designator_is_versioned(PartitionDesignator d) { return IN_SET(d, PARTITION_ROOT, - PARTITION_ROOT_SECONDARY, - PARTITION_ROOT_OTHER, PARTITION_USR, - PARTITION_USR_SECONDARY, - PARTITION_USR_OTHER, PARTITION_ROOT_VERITY, - PARTITION_ROOT_SECONDARY_VERITY, - PARTITION_ROOT_OTHER_VERITY, PARTITION_USR_VERITY, - PARTITION_USR_SECONDARY_VERITY, - PARTITION_USR_OTHER_VERITY, PARTITION_ROOT_VERITY_SIG, - PARTITION_ROOT_SECONDARY_VERITY_SIG, - PARTITION_ROOT_OTHER_VERITY_SIG, - PARTITION_USR_VERITY_SIG, - PARTITION_USR_SECONDARY_VERITY_SIG, - PARTITION_USR_OTHER_VERITY_SIG); + PARTITION_USR_VERITY_SIG); } PartitionDesignator partition_verity_of(PartitionDesignator p) { @@ -48,21 +36,9 @@ PartitionDesignator partition_verity_of(PartitionDesignator p) { case PARTITION_ROOT: return PARTITION_ROOT_VERITY; - case PARTITION_ROOT_SECONDARY: - return PARTITION_ROOT_SECONDARY_VERITY; - - case PARTITION_ROOT_OTHER: - return PARTITION_ROOT_OTHER_VERITY; - case PARTITION_USR: return PARTITION_USR_VERITY; - case PARTITION_USR_SECONDARY: - return PARTITION_USR_SECONDARY_VERITY; - - case PARTITION_USR_OTHER: - return PARTITION_USR_OTHER_VERITY; - default: return _PARTITION_DESIGNATOR_INVALID; } @@ -74,82 +50,27 @@ PartitionDesignator partition_verity_sig_of(PartitionDesignator p) { case PARTITION_ROOT: return PARTITION_ROOT_VERITY_SIG; - case PARTITION_ROOT_SECONDARY: - return PARTITION_ROOT_SECONDARY_VERITY_SIG; - - case PARTITION_ROOT_OTHER: - return PARTITION_ROOT_OTHER_VERITY_SIG; - case PARTITION_USR: return PARTITION_USR_VERITY_SIG; - case PARTITION_USR_SECONDARY: - return PARTITION_USR_SECONDARY_VERITY_SIG; - - case PARTITION_USR_OTHER: - return PARTITION_USR_OTHER_VERITY_SIG; - default: return _PARTITION_DESIGNATOR_INVALID; } } -PartitionDesignator partition_root_of_arch(Architecture arch) { - switch (arch) { - - case native_architecture(): - return PARTITION_ROOT; - -#ifdef ARCHITECTURE_SECONDARY - case ARCHITECTURE_SECONDARY: - return PARTITION_ROOT_SECONDARY; -#endif - - default: - return PARTITION_ROOT_OTHER; - } -} - -PartitionDesignator partition_usr_of_arch(Architecture arch) { - switch (arch) { - - case native_architecture(): - return PARTITION_USR; - -#ifdef ARCHITECTURE_SECONDARY - case ARCHITECTURE_SECONDARY: - return PARTITION_USR_SECONDARY; -#endif - - default: - return PARTITION_USR_OTHER; - } -} static const char *const partition_designator_table[] = { [PARTITION_ROOT] = "root", - [PARTITION_ROOT_SECONDARY] = "root-secondary", - [PARTITION_ROOT_OTHER] = "root-other", [PARTITION_USR] = "usr", - [PARTITION_USR_SECONDARY] = "usr-secondary", - [PARTITION_USR_OTHER] = "usr-other", [PARTITION_HOME] = "home", [PARTITION_SRV] = "srv", [PARTITION_ESP] = "esp", [PARTITION_XBOOTLDR] = "xbootldr", [PARTITION_SWAP] = "swap", [PARTITION_ROOT_VERITY] = "root-verity", - [PARTITION_ROOT_SECONDARY_VERITY] = "root-secondary-verity", - [PARTITION_ROOT_OTHER_VERITY] = "root-other-verity", [PARTITION_USR_VERITY] = "usr-verity", - [PARTITION_USR_SECONDARY_VERITY] = "usr-secondary-verity", - [PARTITION_USR_OTHER_VERITY] = "usr-other-verity", [PARTITION_ROOT_VERITY_SIG] = "root-verity-sig", - [PARTITION_ROOT_SECONDARY_VERITY_SIG] = "root-secondary-verity-sig", - [PARTITION_ROOT_OTHER_VERITY_SIG] = "root-other-verity-sig", [PARTITION_USR_VERITY_SIG] = "usr-verity-sig", - [PARTITION_USR_SECONDARY_VERITY_SIG] = "usr-secondary-verity-sig", - [PARTITION_USR_OTHER_VERITY_SIG] = "usr-other-verity-sig", [PARTITION_TMP] = "tmp", [PARTITION_VAR] = "var", [PARTITION_USER_HOME] = "user-home", @@ -160,11 +81,7 @@ DEFINE_STRING_TABLE_LOOKUP(partition_designator, PartitionDesignator); static const char *const partition_mountpoint_table[] = { [PARTITION_ROOT] = "/\0", - [PARTITION_ROOT_SECONDARY] = "/\0", - [PARTITION_ROOT_OTHER] = "/\0", [PARTITION_USR] = "/usr\0", - [PARTITION_USR_SECONDARY] = "/usr\0", - [PARTITION_USR_OTHER] = "/usr\0", [PARTITION_HOME] = "/home\0", [PARTITION_SRV] = "/srv\0", [PARTITION_ESP] = "/efi\0/boot\0", @@ -176,12 +93,12 @@ static const char *const partition_mountpoint_table[] = { DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(partition_mountpoint, PartitionDesignator); #define _GPT_ARCH_SEXTET(arch, name) \ - { SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER }, \ - { SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER_VERITY }, \ - { SD_GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER_VERITY_SIG }, \ - { SD_GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER }, \ - { SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER_VERITY }, \ - { SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER_VERITY_SIG } + { SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .designator = PARTITION_ROOT }, \ + { SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_VERITY }, \ + { SD_GPT_ROOT_##arch##_VERITY_SIG, "root-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_VERITY_SIG }, \ + { SD_GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .designator = PARTITION_USR }, \ + { SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_USR_VERITY }, \ + { SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_USR_VERITY_SIG } const GptPartitionType gpt_partition_type_table[] = { _GPT_ARCH_SEXTET(ALPHA, "alpha"), @@ -212,12 +129,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_SECONDARY }, - { SD_GPT_ROOT_NATIVE_VERITY, "root-secondary-verity", native_architecture(), .designator = PARTITION_ROOT_SECONDARY_VERITY }, - { SD_GPT_ROOT_NATIVE_VERITY_SIG, "root-secondary-verity-sig", native_architecture(), .designator = PARTITION_ROOT_SECONDARY_VERITY_SIG }, - { SD_GPT_USR_NATIVE, "usr-secondary", native_architecture(), .designator = PARTITION_USR_SECONDARY }, - { SD_GPT_USR_NATIVE_VERITY, "usr-secondary-verity", native_architecture(), .designator = PARTITION_USR_SECONDARY_VERITY }, - { SD_GPT_USR_NATIVE_VERITY_SIG, "usr-secondary-verity-sig", native_architecture(), .designator = PARTITION_USR_SECONDARY_VERITY_SIG }, + { 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 }, #endif { SD_GPT_ESP, "esp", _ARCHITECTURE_INVALID, .designator = PARTITION_ESP }, @@ -266,17 +183,27 @@ const char *gpt_partition_type_uuid_to_string_harder( return sd_id128_to_uuid_string(id, buffer); } -int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret) { +int gpt_partition_type_from_string(const char *s, GptPartitionType *ret) { + sd_id128_t id; + int r; + assert(s); for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++) if (streq(s, gpt_partition_type_table[i].name)) { if (ret) - *ret = gpt_partition_type_table[i].uuid; + *ret = gpt_partition_type_table[i]; return 0; } - return sd_id128_from_string(s, ret); + r = sd_id128_from_string(s, &id); + if (r < 0) + return r; + + if (ret) + *ret = gpt_partition_type_from_uuid(id); + + return 0; } Architecture gpt_partition_type_uuid_to_arch(sd_id128_t id) { @@ -299,7 +226,7 @@ int gpt_partition_label_valid(const char *s) { return char16_strlen(recoded) <= GPT_LABEL_MAX; } -static GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) { +GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) { const GptPartitionType *pt; pt = gpt_partition_type_find_by_uuid(id); @@ -313,91 +240,45 @@ static GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) { }; } -bool gpt_partition_type_is_root(sd_id128_t id) { - return IN_SET(gpt_partition_type_from_uuid(id).designator, - PARTITION_ROOT, - PARTITION_ROOT_SECONDARY, - PARTITION_ROOT_OTHER); +const char *gpt_partition_type_mountpoint_nulstr(GptPartitionType type) { + return partition_mountpoint_to_string(type.designator); } -bool gpt_partition_type_is_root_verity(sd_id128_t id) { - return IN_SET(gpt_partition_type_from_uuid(id).designator, +bool gpt_partition_type_knows_read_only(GptPartitionType type) { + return IN_SET(type.designator, + PARTITION_ROOT, + PARTITION_USR, + /* pretty much implied, but let's set the bit to make things really clear */ PARTITION_ROOT_VERITY, - PARTITION_ROOT_SECONDARY_VERITY, - PARTITION_ROOT_OTHER_VERITY); -} - -bool gpt_partition_type_is_root_verity_sig(sd_id128_t id) { - return IN_SET(gpt_partition_type_from_uuid(id).designator, - PARTITION_ROOT_VERITY_SIG, - PARTITION_ROOT_SECONDARY_VERITY_SIG, - PARTITION_ROOT_OTHER_VERITY_SIG); + PARTITION_USR_VERITY, + PARTITION_HOME, + PARTITION_SRV, + PARTITION_VAR, + PARTITION_TMP, + PARTITION_XBOOTLDR); } -bool gpt_partition_type_is_usr(sd_id128_t id) { - return IN_SET(gpt_partition_type_from_uuid(id).designator, +bool gpt_partition_type_knows_growfs(GptPartitionType type) { + return IN_SET(type.designator, + PARTITION_ROOT, PARTITION_USR, - PARTITION_USR_SECONDARY, - PARTITION_USR_OTHER); + PARTITION_HOME, + PARTITION_SRV, + PARTITION_VAR, + PARTITION_TMP, + PARTITION_XBOOTLDR); } -bool gpt_partition_type_is_usr_verity(sd_id128_t id) { - return IN_SET(gpt_partition_type_from_uuid(id).designator, +bool gpt_partition_type_knows_no_auto(GptPartitionType type) { + return IN_SET(type.designator, + PARTITION_ROOT, + PARTITION_ROOT_VERITY, + PARTITION_USR, PARTITION_USR_VERITY, - PARTITION_USR_SECONDARY_VERITY, - PARTITION_USR_OTHER_VERITY); -} - -bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id) { - return IN_SET(gpt_partition_type_from_uuid(id).designator, - PARTITION_USR_VERITY_SIG, - PARTITION_USR_SECONDARY_VERITY_SIG, - PARTITION_USR_OTHER_VERITY_SIG); -} - -const char *gpt_partition_type_mountpoint_nulstr(sd_id128_t id) { - PartitionDesignator d = gpt_partition_type_from_uuid(id).designator; - if (d < 0) - return NULL; - - return partition_mountpoint_to_string(d); -} - -bool gpt_partition_type_knows_read_only(sd_id128_t id) { - return gpt_partition_type_is_root(id) || - gpt_partition_type_is_usr(id) || - /* pretty much implied, but let's set the bit to make things really clear */ - gpt_partition_type_is_root_verity(id) || - gpt_partition_type_is_usr_verity(id) || - IN_SET(gpt_partition_type_from_uuid(id).designator, - PARTITION_HOME, - PARTITION_SRV, - PARTITION_VAR, - PARTITION_TMP, - PARTITION_XBOOTLDR); -} - -bool gpt_partition_type_knows_growfs(sd_id128_t id) { - return gpt_partition_type_is_root(id) || - gpt_partition_type_is_usr(id) || - IN_SET(gpt_partition_type_from_uuid(id).designator, - PARTITION_HOME, - PARTITION_SRV, - PARTITION_VAR, - PARTITION_TMP, - PARTITION_XBOOTLDR); -} - -bool gpt_partition_type_knows_no_auto(sd_id128_t id) { - return gpt_partition_type_is_root(id) || - gpt_partition_type_is_root_verity(id) || - gpt_partition_type_is_usr(id) || - gpt_partition_type_is_usr_verity(id) || - IN_SET(gpt_partition_type_from_uuid(id).designator, - PARTITION_HOME, - PARTITION_SRV, - PARTITION_VAR, - PARTITION_TMP, - PARTITION_XBOOTLDR, - PARTITION_SWAP); + PARTITION_HOME, + PARTITION_SRV, + PARTITION_VAR, + PARTITION_TMP, + PARTITION_XBOOTLDR, + PARTITION_SWAP); } diff --git a/src/shared/gpt.h b/src/shared/gpt.h index e0ab44a6427..967e20e0af5 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -12,28 +12,16 @@ typedef enum PartitionDesignator { PARTITION_ROOT, /* Primary architecture */ - PARTITION_ROOT_SECONDARY, /* Secondary architecture */ - PARTITION_ROOT_OTHER, /* Any architecture not covered by the primary or secondary architecture. */ PARTITION_USR, - PARTITION_USR_SECONDARY, - PARTITION_USR_OTHER, PARTITION_HOME, PARTITION_SRV, PARTITION_ESP, PARTITION_XBOOTLDR, PARTITION_SWAP, PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */ - PARTITION_ROOT_SECONDARY_VERITY, /* verity data for the PARTITION_ROOT_SECONDARY partition */ - PARTITION_ROOT_OTHER_VERITY, PARTITION_USR_VERITY, - PARTITION_USR_SECONDARY_VERITY, - PARTITION_USR_OTHER_VERITY, PARTITION_ROOT_VERITY_SIG, /* PKCS#7 signature for root hash for the PARTITION_ROOT partition */ - PARTITION_ROOT_SECONDARY_VERITY_SIG, /* ditto for the PARTITION_ROOT_SECONDARY partition */ - PARTITION_ROOT_OTHER_VERITY_SIG, PARTITION_USR_VERITY_SIG, - PARTITION_USR_SECONDARY_VERITY_SIG, - PARTITION_USR_OTHER_VERITY_SIG, PARTITION_TMP, PARTITION_VAR, PARTITION_USER_HOME, @@ -46,8 +34,6 @@ bool partition_designator_is_versioned(PartitionDesignator d); PartitionDesignator partition_verity_of(PartitionDesignator p); PartitionDesignator partition_verity_sig_of(PartitionDesignator p); -PartitionDesignator partition_root_of_arch(Architecture arch); -PartitionDesignator partition_usr_of_arch(Architecture arch); const char* partition_designator_to_string(PartitionDesignator d) _const_; PartitionDesignator partition_designator_from_string(const char *name) _pure_; @@ -56,7 +42,6 @@ const char *gpt_partition_type_uuid_to_string(sd_id128_t id); const char *gpt_partition_type_uuid_to_string_harder( sd_id128_t id, char buffer[static SD_ID128_UUID_STRING_MAX]); -int gpt_partition_type_uuid_from_string(const char *s, sd_id128_t *ret); #define GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(id) \ gpt_partition_type_uuid_to_string_harder((id), (char[SD_ID128_UUID_STRING_MAX]) {}) @@ -74,15 +59,11 @@ extern const GptPartitionType gpt_partition_type_table[]; int gpt_partition_label_valid(const char *s); -bool gpt_partition_type_is_root(sd_id128_t id); -bool gpt_partition_type_is_root_verity(sd_id128_t id); -bool gpt_partition_type_is_root_verity_sig(sd_id128_t id); -bool gpt_partition_type_is_usr(sd_id128_t id); -bool gpt_partition_type_is_usr_verity(sd_id128_t id); -bool gpt_partition_type_is_usr_verity_sig(sd_id128_t id); +GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id); +int gpt_partition_type_from_string(const char *s, GptPartitionType *ret); -const char *gpt_partition_type_mountpoint_nulstr(sd_id128_t id); +const char *gpt_partition_type_mountpoint_nulstr(GptPartitionType type); -bool gpt_partition_type_knows_read_only(sd_id128_t id); -bool gpt_partition_type_knows_growfs(sd_id128_t id); -bool gpt_partition_type_knows_no_auto(sd_id128_t id); +bool gpt_partition_type_knows_read_only(GptPartitionType type); +bool gpt_partition_type_knows_growfs(GptPartitionType type); +bool gpt_partition_type_knows_no_auto(GptPartitionType type); diff --git a/src/sysupdate/sysupdate-partition.c b/src/sysupdate/sysupdate-partition.c index fa46574fd6b..33d0e584ba0 100644 --- a/src/sysupdate/sysupdate-partition.c +++ b/src/sysupdate/sysupdate-partition.c @@ -111,6 +111,7 @@ int read_partition_info( struct fdisk_parttype *pt; uint64_t start, size, flags; sd_id128_t ptid, id; + GptPartitionType type; size_t partno; int r; @@ -178,6 +179,8 @@ int read_partition_info( if (!label_copy) return log_oom(); + type = gpt_partition_type_from_uuid(ptid); + *ret = (PartitionInfo) { .partno = partno, .start = start, @@ -187,9 +190,9 @@ int read_partition_info( .uuid = id, .label = TAKE_PTR(label_copy), .device = TAKE_PTR(device), - .no_auto = FLAGS_SET(flags, SD_GPT_FLAG_NO_AUTO) && gpt_partition_type_knows_no_auto(ptid), - .read_only = FLAGS_SET(flags, SD_GPT_FLAG_READ_ONLY) && gpt_partition_type_knows_read_only(ptid), - .growfs = FLAGS_SET(flags, SD_GPT_FLAG_GROWFS) && gpt_partition_type_knows_growfs(ptid), + .no_auto = FLAGS_SET(flags, SD_GPT_FLAG_NO_AUTO) && gpt_partition_type_knows_no_auto(type), + .read_only = FLAGS_SET(flags, SD_GPT_FLAG_READ_ONLY) && gpt_partition_type_knows_read_only(type), + .growfs = FLAGS_SET(flags, SD_GPT_FLAG_GROWFS) && gpt_partition_type_knows_growfs(type), }; return 1; /* found! */ @@ -269,6 +272,7 @@ int patch_partition( _cleanup_(fdisk_unref_partitionp) struct fdisk_partition *pa = NULL; _cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL; bool tweak_no_auto, tweak_read_only, tweak_growfs; + GptPartitionType type; int r, fd; assert(device); @@ -313,16 +317,18 @@ int patch_partition( return log_error_errno(r, "Failed to update partition UUID: %m"); } + type = gpt_partition_type_from_uuid(info->type); + /* Tweak the read-only flag, but only if supported by the partition type */ tweak_no_auto = FLAGS_SET(change, PARTITION_NO_AUTO) && - gpt_partition_type_knows_no_auto(info->type); + gpt_partition_type_knows_no_auto(type); tweak_read_only = FLAGS_SET(change, PARTITION_READ_ONLY) && - gpt_partition_type_knows_read_only(info->type); + gpt_partition_type_knows_read_only(type); tweak_growfs = FLAGS_SET(change, PARTITION_GROWFS) && - gpt_partition_type_knows_growfs(info->type); + gpt_partition_type_knows_growfs(type); if (change & PARTITION_FLAGS) { uint64_t flags; diff --git a/src/sysupdate/sysupdate-resource.c b/src/sysupdate/sysupdate-resource.c index 8104e9c82e9..bf521980e26 100644 --- a/src/sysupdate/sysupdate-resource.c +++ b/src/sysupdate/sysupdate-resource.c @@ -194,7 +194,7 @@ static int resource_load_from_blockdev(Resource *rr) { continue; /* Check if partition type matches */ - if (rr->partition_type_set && !sd_id128_equal(pinfo.type, rr->partition_type)) + if (rr->partition_type_set && !sd_id128_equal(pinfo.type, rr->partition_type.uuid)) continue; /* A label of "_empty" means "not used so far" for us */ diff --git a/src/sysupdate/sysupdate-resource.h b/src/sysupdate/sysupdate-resource.h index 86be0d33893..3209988c24f 100644 --- a/src/sysupdate/sysupdate-resource.h +++ b/src/sysupdate/sysupdate-resource.h @@ -5,8 +5,7 @@ #include #include -#include "sd-id128.h" - +#include "gpt.h" #include "hashmap.h" #include "macro.h" @@ -74,7 +73,7 @@ struct Resource { char *path; bool path_auto; /* automatically find root path (only available if target resource, not source resource) */ char **patterns; - sd_id128_t partition_type; + GptPartitionType partition_type; bool partition_type_set; /* All instances of this resource we found */ diff --git a/src/sysupdate/sysupdate-transfer.c b/src/sysupdate/sysupdate-transfer.c index d6705cd12ec..0c3d65a00dc 100644 --- a/src/sysupdate/sysupdate-transfer.c +++ b/src/sysupdate/sysupdate-transfer.c @@ -344,7 +344,7 @@ static int config_parse_resource_ptype( assert(rvalue); - r = gpt_partition_type_uuid_from_string(rvalue, &rr->partition_type); + r = gpt_partition_type_from_string(rvalue, &rr->partition_type); if (r < 0) { log_syntax(unit, LOG_WARNING, filename, line, r, "Failed parse partition type, ignoring: %s", rvalue); @@ -654,18 +654,18 @@ int transfer_vacuum( if (t->target.n_empty + t->target.n_instances < 2) return log_error_errno(SYNTHETIC_ERRNO(ENOSPC), "Partition table has less than two partition slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s), refusing.", - SD_ID128_FORMAT_VAL(t->target.partition_type), - gpt_partition_type_uuid_to_string(t->target.partition_type)); + SD_ID128_FORMAT_VAL(t->target.partition_type.uuid), + gpt_partition_type_uuid_to_string(t->target.partition_type.uuid)); if (space > t->target.n_empty + t->target.n_instances) return log_error_errno(SYNTHETIC_ERRNO(ENOSPC), "Partition table does not have enough partition slots of right type " SD_ID128_UUID_FORMAT_STR " (%s) for operation.", - SD_ID128_FORMAT_VAL(t->target.partition_type), - gpt_partition_type_uuid_to_string(t->target.partition_type)); + SD_ID128_FORMAT_VAL(t->target.partition_type.uuid), + gpt_partition_type_uuid_to_string(t->target.partition_type.uuid)); if (space == t->target.n_empty + t->target.n_instances) return log_error_errno(SYNTHETIC_ERRNO(ENOSPC), "Asked to empty all partition table slots of the right type " SD_ID128_UUID_FORMAT_STR " (%s), can't allow that. One instance must always remain.", - SD_ID128_FORMAT_VAL(t->target.partition_type), - gpt_partition_type_uuid_to_string(t->target.partition_type)); + SD_ID128_FORMAT_VAL(t->target.partition_type.uuid), + gpt_partition_type_uuid_to_string(t->target.partition_type.uuid)); rm = LESS_BY(space, t->target.n_empty); remain = LESS_BY(t->target.n_instances, rm); @@ -858,7 +858,7 @@ int transfer_acquire_instance(Transfer *t, Instance *i) { r = find_suitable_partition( t->target.path, i->metadata.size, - t->target.partition_type_set ? &t->target.partition_type : NULL, + t->target.partition_type_set ? &t->target.partition_type.uuid : NULL, &t->partition_info); if (r < 0) return r; diff --git a/src/test/test-gpt.c b/src/test/test-gpt.c index 8c313c66cc8..377b79f1556 100644 --- a/src/test/test-gpt.c +++ b/src/test/test-gpt.c @@ -19,13 +19,13 @@ TEST(gpt_types_against_architectures) { for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++) FOREACH_STRING(suffix, "", "-verity", "-verity-sig") { _cleanup_free_ char *joined = NULL; - sd_id128_t id; + GptPartitionType type; joined = strjoin(prefix, architecture_to_string(a), suffix); if (!joined) return (void) log_oom(); - r = gpt_partition_type_uuid_from_string(joined, &id); + r = gpt_partition_type_from_string(joined, &type); if (r < 0) { printf("%s %s\n", RED_CROSS_MARK(), joined); continue; @@ -34,15 +34,15 @@ TEST(gpt_types_against_architectures) { printf("%s %s\n", GREEN_CHECK_MARK(), joined); if (streq(prefix, "root-") && streq(suffix, "")) - assert_se(gpt_partition_type_is_root(id)); + assert_se(type.designator == PARTITION_ROOT); if (streq(prefix, "root-") && streq(suffix, "-verity")) - assert_se(gpt_partition_type_is_root_verity(id)); + assert_se(type.designator == PARTITION_ROOT_VERITY); if (streq(prefix, "usr-") && streq(suffix, "")) - assert_se(gpt_partition_type_is_usr(id)); + assert_se(type.designator == PARTITION_USR); if (streq(prefix, "usr-") && streq(suffix, "-verity")) - assert_se(gpt_partition_type_is_usr_verity(id)); + assert_se(type.designator == PARTITION_USR_VERITY); - assert_se(gpt_partition_type_uuid_to_arch(id) == a); + assert_se(type.arch == a); } }