mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 05:18:17 +03:00
Merge pull request #25001 from DaanDeMeyer/repart-filter
repart: Add --include/--exclude-partitions
This commit is contained in:
commit
2b0cff0469
@ -363,6 +363,23 @@
|
|||||||
if <option>--split</option> is enabled.</para></listitem>
|
if <option>--split</option> is enabled.</para></listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><option>--include-partitions=</option><arg rep="repeat">PARTITION</arg></term>
|
||||||
|
<term><option>--exclude-partitions=</option><arg rep="repeat">PARTITION</arg></term>
|
||||||
|
|
||||||
|
<listitem><para>These options specify which partition types <command>systemd-repart</command> should
|
||||||
|
operate on. If <option>--include-partitions=</option> is used, all partitions that aren't specified
|
||||||
|
are excluded. If <option>--exclude-partitions=</option> is used, all partitions that are specified
|
||||||
|
are excluded. Both options take a comma separated list of GPT partition type UUIDs or identifiers
|
||||||
|
(see <varname>Type=</varname> in
|
||||||
|
<citerefentry><refentrytitle>repart.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>). 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 <command>systemd-repart</command> again without these options, the
|
||||||
|
missing partitions will be added as if they had not been excluded the first time
|
||||||
|
<command>systemd-repart</command> was executed.</para></listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<xi:include href="standard-options.xml" xpointer="help" />
|
<xi:include href="standard-options.xml" xpointer="help" />
|
||||||
<xi:include href="standard-options.xml" xpointer="version" />
|
<xi:include href="standard-options.xml" xpointer="version" />
|
||||||
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
<xi:include href="standard-options.xml" xpointer="no-pager" />
|
||||||
|
@ -123,10 +123,13 @@ static int verb_show(int argc, char **argv, void *userdata) {
|
|||||||
if (have_uuid)
|
if (have_uuid)
|
||||||
id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ";
|
id = gpt_partition_type_uuid_to_string(uuid) ?: "XYZ";
|
||||||
else {
|
else {
|
||||||
r = gpt_partition_type_uuid_from_string(*p, &uuid);
|
GptPartitionType type;
|
||||||
|
|
||||||
|
r = gpt_partition_type_from_string(*p, &type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Unknown identifier \"%s\".", *p);
|
return log_error_errno(r, "Unknown identifier \"%s\".", *p);
|
||||||
|
|
||||||
|
uuid = type.uuid;
|
||||||
id = *p;
|
id = *p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,14 @@ static enum {
|
|||||||
EMPTY_CREATE, /* create disk as loopback file, create a partition table always */
|
EMPTY_CREATE, /* create disk as loopback file, create a partition table always */
|
||||||
} arg_empty = EMPTY_REFUSE;
|
} arg_empty = EMPTY_REFUSE;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
FILTER_PARTITIONS_NONE,
|
||||||
|
FILTER_PARTITIONS_EXCLUDE,
|
||||||
|
FILTER_PARTITIONS_INCLUDE,
|
||||||
|
_FILTER_PARTITIONS_MAX,
|
||||||
|
_FILTER_PARTITIONS_INVALID = -EINVAL,
|
||||||
|
} FilterPartitionsType;
|
||||||
|
|
||||||
static bool arg_dry_run = true;
|
static bool arg_dry_run = true;
|
||||||
static const char *arg_node = NULL;
|
static const char *arg_node = NULL;
|
||||||
static char *arg_root = NULL;
|
static char *arg_root = NULL;
|
||||||
@ -128,6 +136,9 @@ static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
|
|||||||
static char *arg_tpm2_public_key = NULL;
|
static char *arg_tpm2_public_key = NULL;
|
||||||
static uint32_t arg_tpm2_public_key_pcr_mask = UINT32_MAX;
|
static uint32_t arg_tpm2_public_key_pcr_mask = UINT32_MAX;
|
||||||
static bool arg_split = false;
|
static bool arg_split = false;
|
||||||
|
static sd_id128_t *arg_filter_partitions = NULL;
|
||||||
|
static size_t arg_filter_partitions_size = 0;
|
||||||
|
static FilterPartitionsType arg_filter_partitions_type = FILTER_PARTITIONS_NONE;
|
||||||
|
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
|
||||||
@ -137,6 +148,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_private_key, EVP_PKEY_freep);
|
|||||||
STATIC_DESTRUCTOR_REGISTER(arg_certificate, X509_freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_certificate, X509_freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_device, freep);
|
||||||
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
|
STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
|
||||||
|
STATIC_DESTRUCTOR_REGISTER(arg_filter_partitions, freep);
|
||||||
|
|
||||||
typedef struct Partition Partition;
|
typedef struct Partition Partition;
|
||||||
typedef struct FreeArea FreeArea;
|
typedef struct FreeArea FreeArea;
|
||||||
@ -164,7 +176,7 @@ struct Partition {
|
|||||||
char *definition_path;
|
char *definition_path;
|
||||||
char **drop_in_files;
|
char **drop_in_files;
|
||||||
|
|
||||||
sd_id128_t type_uuid;
|
GptPartitionType type;
|
||||||
sd_id128_t current_uuid, new_uuid;
|
sd_id128_t current_uuid, new_uuid;
|
||||||
bool new_uuid_is_set;
|
bool new_uuid_is_set;
|
||||||
char *current_label, *new_label;
|
char *current_label, *new_label;
|
||||||
@ -372,6 +384,19 @@ static void partition_foreignize(Partition *p) {
|
|||||||
p->verity = VERITY_OFF;
|
p->verity = VERITY_OFF;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool partition_skip(const Partition *p) {
|
||||||
|
assert(p);
|
||||||
|
|
||||||
|
if (arg_filter_partitions_type == FILTER_PARTITIONS_NONE)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < arg_filter_partitions_size; i++)
|
||||||
|
if (sd_id128_equal(p->type.uuid, arg_filter_partitions[i]))
|
||||||
|
return arg_filter_partitions_type == FILTER_PARTITIONS_EXCLUDE;
|
||||||
|
|
||||||
|
return arg_filter_partitions_type == FILTER_PARTITIONS_INCLUDE;
|
||||||
|
}
|
||||||
|
|
||||||
static Partition* partition_unlink_and_free(Context *context, Partition *p) {
|
static Partition* partition_unlink_and_free(Context *context, Partition *p) {
|
||||||
if (!p)
|
if (!p)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -1025,20 +1050,29 @@ static int context_grow_partitions(Context *context) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void context_place_partitions(Context *context) {
|
static uint64_t find_first_unused_partno(Context *context) {
|
||||||
uint64_t partno = 0;
|
uint64_t partno = 0;
|
||||||
|
|
||||||
assert(context);
|
assert(context);
|
||||||
|
|
||||||
/* Determine next partition number to assign */
|
for (bool changed = true; changed;) {
|
||||||
LIST_FOREACH(partitions, p, context->partitions) {
|
changed = false;
|
||||||
if (!PARTITION_EXISTS(p))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
assert(p->partno != UINT64_MAX);
|
LIST_FOREACH(partitions, p, context->partitions) {
|
||||||
if (p->partno >= partno)
|
if (p->partno != UINT64_MAX && p->partno == partno) {
|
||||||
partno = p->partno + 1;
|
partno++;
|
||||||
|
changed = true;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return partno;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void context_place_partitions(Context *context) {
|
||||||
|
|
||||||
|
assert(context);
|
||||||
|
|
||||||
for (size_t i = 0; i < context->n_free_areas; i++) {
|
for (size_t i = 0; i < context->n_free_areas; i++) {
|
||||||
FreeArea *a = context->free_areas[i];
|
FreeArea *a = context->free_areas[i];
|
||||||
@ -1062,7 +1096,7 @@ static void context_place_partitions(Context *context) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
p->offset = start;
|
p->offset = start;
|
||||||
p->partno = partno++;
|
p->partno = find_first_unused_partno(context);
|
||||||
|
|
||||||
assert(left >= p->new_size);
|
assert(left >= p->new_size);
|
||||||
start += p->new_size;
|
start += p->new_size;
|
||||||
@ -1087,12 +1121,12 @@ static int config_parse_type(
|
|||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
sd_id128_t *type_uuid = ASSERT_PTR(data);
|
GptPartitionType *type = ASSERT_PTR(data);
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
|
|
||||||
r = gpt_partition_type_uuid_from_string(rvalue, type_uuid);
|
r = gpt_partition_type_from_string(rvalue, type);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition type: %s", rvalue);
|
return log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse partition type: %s", rvalue);
|
||||||
|
|
||||||
@ -1478,7 +1512,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) {
|
static int partition_read_definition(Partition *p, const char *path, const char *const *conf_file_dirs) {
|
||||||
|
|
||||||
ConfigTableItem table[] = {
|
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", "Label", config_parse_label, 0, &p->new_label },
|
||||||
{ "Partition", "UUID", config_parse_uuid, 0, p },
|
{ "Partition", "UUID", config_parse_uuid, 0, p },
|
||||||
{ "Partition", "Priority", config_parse_int32, 0, &p->priority },
|
{ "Partition", "Priority", config_parse_int32, 0, &p->priority },
|
||||||
@ -1535,7 +1569,7 @@ static int partition_read_definition(Partition *p, const char *path, const char
|
|||||||
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
|
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
|
||||||
"PaddingMinBytes= larger than PaddingMaxBytes=, refusing.");
|
"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),
|
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
|
||||||
"Type= not defined, refusing.");
|
"Type= not defined, refusing.");
|
||||||
|
|
||||||
@ -1599,13 +1633,13 @@ static int partition_read_definition(Partition *p, const char *path, const char
|
|||||||
verity_mode_to_string(p->verity));
|
verity_mode_to_string(p->verity));
|
||||||
|
|
||||||
/* Verity partitions are read only, let's imply the RO flag hence, unless explicitly configured otherwise. */
|
/* 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) ||
|
if ((p->type.designator == PARTITION_ROOT_VERITY ||
|
||||||
gpt_partition_type_is_usr_verity(p->type_uuid)) &&
|
p->type.designator == PARTITION_USR_VERITY) &&
|
||||||
p->read_only < 0)
|
p->read_only < 0)
|
||||||
p->read_only = true;
|
p->read_only = true;
|
||||||
|
|
||||||
/* Default to "growfs" on, unless read-only */
|
/* 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->read_only <= 0)
|
||||||
p->growfs = true;
|
p->growfs = true;
|
||||||
|
|
||||||
@ -2099,7 +2133,7 @@ static int context_load_partition_table(
|
|||||||
LIST_FOREACH(partitions, pp, context->partitions) {
|
LIST_FOREACH(partitions, pp, context->partitions) {
|
||||||
last = pp;
|
last = pp;
|
||||||
|
|
||||||
if (!sd_id128_equal(pp->type_uuid, ptid))
|
if (!sd_id128_equal(pp->type.uuid, ptid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (!pp->current_partition) {
|
if (!pp->current_partition) {
|
||||||
@ -2136,7 +2170,7 @@ static int context_load_partition_table(
|
|||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
np->current_uuid = id;
|
np->current_uuid = id;
|
||||||
np->type_uuid = ptid;
|
np->type = gpt_partition_type_from_uuid(ptid);
|
||||||
np->current_size = sz;
|
np->current_size = sz;
|
||||||
np->offset = start;
|
np->offset = start;
|
||||||
np->partno = partno;
|
np->partno = partno;
|
||||||
@ -2295,7 +2329,7 @@ static const char *partition_label(const Partition *p) {
|
|||||||
if (p->current_label)
|
if (p->current_label)
|
||||||
return 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) {
|
static int context_dump_partitions(Context *context, const char *node) {
|
||||||
@ -2369,7 +2403,7 @@ static int context_dump_partitions(Context *context, const char *node) {
|
|||||||
|
|
||||||
r = table_add_many(
|
r = table_add_many(
|
||||||
t,
|
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_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_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(),
|
TABLE_STRING, p->definition_path ? basename(p->definition_path) : "-", TABLE_SET_COLOR, p->definition_path ? NULL : ansi_grey(),
|
||||||
@ -2503,7 +2537,7 @@ static int partition_hint(const Partition *p, const char *node, char **ret) {
|
|||||||
else if (!sd_id128_is_null(p->current_uuid))
|
else if (!sd_id128_is_null(p->current_uuid))
|
||||||
id = p->current_uuid;
|
id = p->current_uuid;
|
||||||
else
|
else
|
||||||
id = p->type_uuid;
|
id = p->type.uuid;
|
||||||
|
|
||||||
buf = strdup(SD_ID128_TO_UUID_STRING(id));
|
buf = strdup(SD_ID128_TO_UUID_STRING(id));
|
||||||
|
|
||||||
@ -2921,6 +2955,9 @@ static int context_wipe_and_discard(Context *context, bool from_scratch) {
|
|||||||
if (!p->allocated_to_area)
|
if (!p->allocated_to_area)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
r = context_wipe_partition(context, p);
|
r = context_wipe_partition(context, p);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
@ -3178,6 +3215,9 @@ static int context_copy_blocks(Context *context) {
|
|||||||
if (PARTITION_EXISTS(p)) /* Never copy over existing partitions */
|
if (PARTITION_EXISTS(p)) /* Never copy over existing partitions */
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
assert(p->new_size != UINT64_MAX);
|
assert(p->new_size != UINT64_MAX);
|
||||||
assert(p->copy_blocks_size != UINT64_MAX);
|
assert(p->copy_blocks_size != UINT64_MAX);
|
||||||
assert(p->new_size >= p->copy_blocks_size);
|
assert(p->new_size >= p->copy_blocks_size);
|
||||||
@ -3463,7 +3503,7 @@ static int make_copy_files_denylist(Context *context, Set **ret) {
|
|||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
LIST_FOREACH(partitions, p, context->partitions) {
|
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)
|
if (!sources)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -3528,6 +3568,9 @@ static int context_mkfs(Context *context) {
|
|||||||
if (p->copy_blocks_fd >= 0)
|
if (p->copy_blocks_fd >= 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
assert(p->offset != UINT64_MAX);
|
assert(p->offset != UINT64_MAX);
|
||||||
assert(p->new_size != UINT64_MAX);
|
assert(p->new_size != UINT64_MAX);
|
||||||
|
|
||||||
@ -3699,6 +3742,9 @@ static int context_verity_hash(Context *context) {
|
|||||||
if (p->verity != VERITY_HASH)
|
if (p->verity != VERITY_HASH)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
assert_se(dp = p->siblings[VERITY_DATA]);
|
assert_se(dp = p->siblings[VERITY_DATA]);
|
||||||
assert(!dp->dropped);
|
assert(!dp->dropped);
|
||||||
|
|
||||||
@ -3861,6 +3907,9 @@ static int context_verity_sig(Context *context) {
|
|||||||
if (p->verity != VERITY_SIG)
|
if (p->verity != VERITY_SIG)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
assert_se(hp = p->siblings[VERITY_HASH]);
|
assert_se(hp = p->siblings[VERITY_HASH]);
|
||||||
assert(!hp->dropped);
|
assert(!hp->dropped);
|
||||||
|
|
||||||
@ -3955,13 +4004,13 @@ static int partition_acquire_uuid(Context *context, Partition *p, sd_id128_t *re
|
|||||||
if (p == q)
|
if (p == q)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!sd_id128_equal(p->type_uuid, q->type_uuid))
|
if (!sd_id128_equal(p->type.uuid, q->type.uuid))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
k++;
|
k++;
|
||||||
}
|
}
|
||||||
|
|
||||||
plaintext.type_uuid = p->type_uuid;
|
plaintext.type_uuid = p->type.uuid;
|
||||||
plaintext.counter = htole64(k);
|
plaintext.counter = htole64(k);
|
||||||
|
|
||||||
hmac_sha256(context->seed.bytes, sizeof(context->seed.bytes),
|
hmac_sha256(context->seed.bytes, sizeof(context->seed.bytes),
|
||||||
@ -4002,7 +4051,7 @@ static int partition_acquire_label(Context *context, Partition *p, char **ret) {
|
|||||||
assert(p);
|
assert(p);
|
||||||
assert(ret);
|
assert(ret);
|
||||||
|
|
||||||
prefix = gpt_partition_type_uuid_to_string(p->type_uuid);
|
prefix = gpt_partition_type_uuid_to_string(p->type.uuid);
|
||||||
if (!prefix)
|
if (!prefix)
|
||||||
prefix = "linux";
|
prefix = "linux";
|
||||||
|
|
||||||
@ -4118,35 +4167,35 @@ static uint64_t partition_merge_flags(Partition *p) {
|
|||||||
f = p->gpt_flags;
|
f = p->gpt_flags;
|
||||||
|
|
||||||
if (p->no_auto >= 0) {
|
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);
|
SET_FLAG(f, SD_GPT_FLAG_NO_AUTO, p->no_auto);
|
||||||
else {
|
else {
|
||||||
char buffer[SD_ID128_UUID_STRING_MAX];
|
char buffer[SD_ID128_UUID_STRING_MAX];
|
||||||
log_warning("Configured NoAuto=%s for partition type '%s' that doesn't support it, ignoring.",
|
log_warning("Configured NoAuto=%s for partition type '%s' that doesn't support it, ignoring.",
|
||||||
yes_no(p->no_auto),
|
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 (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);
|
SET_FLAG(f, SD_GPT_FLAG_READ_ONLY, p->read_only);
|
||||||
else {
|
else {
|
||||||
char buffer[SD_ID128_UUID_STRING_MAX];
|
char buffer[SD_ID128_UUID_STRING_MAX];
|
||||||
log_warning("Configured ReadOnly=%s for partition type '%s' that doesn't support it, ignoring.",
|
log_warning("Configured ReadOnly=%s for partition type '%s' that doesn't support it, ignoring.",
|
||||||
yes_no(p->read_only),
|
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 (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);
|
SET_FLAG(f, SD_GPT_FLAG_GROWFS, p->growfs);
|
||||||
else {
|
else {
|
||||||
char buffer[SD_ID128_UUID_STRING_MAX];
|
char buffer[SD_ID128_UUID_STRING_MAX];
|
||||||
log_warning("Configured GrowFileSystem=%s for partition type '%s' that doesn't support it, ignoring.",
|
log_warning("Configured GrowFileSystem=%s for partition type '%s' that doesn't support it, ignoring.",
|
||||||
yes_no(p->growfs),
|
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4162,6 +4211,9 @@ static int context_mangle_partitions(Context *context) {
|
|||||||
if (p->dropped)
|
if (p->dropped)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
assert(p->new_size != UINT64_MAX);
|
assert(p->new_size != UINT64_MAX);
|
||||||
assert(p->offset != UINT64_MAX);
|
assert(p->offset != UINT64_MAX);
|
||||||
assert(p->partno != UINT64_MAX);
|
assert(p->partno != UINT64_MAX);
|
||||||
@ -4225,7 +4277,7 @@ static int context_mangle_partitions(Context *context) {
|
|||||||
if (!t)
|
if (!t)
|
||||||
return log_oom();
|
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)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to initialize partition type: %m");
|
return log_error_errno(r, "Failed to initialize partition type: %m");
|
||||||
|
|
||||||
@ -4284,8 +4336,8 @@ static int split_name_printf(Partition *p) {
|
|||||||
assert(p);
|
assert(p);
|
||||||
|
|
||||||
const Specifier table[] = {
|
const Specifier table[] = {
|
||||||
{ 't', specifier_string, GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(p->type_uuid) },
|
{ 't', specifier_string, GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(p->type.uuid) },
|
||||||
{ 'T', specifier_id128, &p->type_uuid },
|
{ 'T', specifier_id128, &p->type.uuid },
|
||||||
{ 'U', specifier_id128, &p->new_uuid },
|
{ 'U', specifier_id128, &p->new_uuid },
|
||||||
{ 'n', specifier_uint64, &p->partno },
|
{ 'n', specifier_uint64, &p->partno },
|
||||||
|
|
||||||
@ -4402,6 +4454,9 @@ static int context_split(Context *context) {
|
|||||||
if (!p->split_name_resolved)
|
if (!p->split_name_resolved)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
if (partition_skip(p))
|
||||||
|
continue;
|
||||||
|
|
||||||
fname = strjoin(base, ".", p->split_name_resolved, ext);
|
fname = strjoin(base, ".", p->split_name_resolved, ext);
|
||||||
if (!fname)
|
if (!fname)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
@ -4614,7 +4669,7 @@ static int context_can_factory_reset(Context *context) {
|
|||||||
|
|
||||||
static int resolve_copy_blocks_auto_candidate(
|
static int resolve_copy_blocks_auto_candidate(
|
||||||
dev_t partition_devno,
|
dev_t partition_devno,
|
||||||
sd_id128_t partition_type_uuid,
|
GptPartitionType partition_type,
|
||||||
dev_t restrict_devno,
|
dev_t restrict_devno,
|
||||||
sd_id128_t *ret_uuid) {
|
sd_id128_t *ret_uuid) {
|
||||||
|
|
||||||
@ -4706,10 +4761,10 @@ static int resolve_copy_blocks_auto_candidate(
|
|||||||
return false;
|
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.",
|
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),
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -4766,7 +4821,7 @@ static int find_backing_devno(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int resolve_copy_blocks_auto(
|
static int resolve_copy_blocks_auto(
|
||||||
sd_id128_t type_uuid,
|
GptPartitionType type,
|
||||||
const char *root,
|
const char *root,
|
||||||
dev_t restrict_devno,
|
dev_t restrict_devno,
|
||||||
dev_t *ret_devno,
|
dev_t *ret_devno,
|
||||||
@ -4796,30 +4851,30 @@ static int resolve_copy_blocks_auto(
|
|||||||
* partitions in the host, using the appropriate directory as key and ensuring that the partition
|
* partitions in the host, using the appropriate directory as key and ensuring that the partition
|
||||||
* type matches. */
|
* type matches. */
|
||||||
|
|
||||||
if (gpt_partition_type_is_root(type_uuid))
|
if (type.designator == PARTITION_ROOT)
|
||||||
try1 = "/";
|
try1 = "/";
|
||||||
else if (gpt_partition_type_is_usr(type_uuid))
|
else if (type.designator == PARTITION_USR)
|
||||||
try1 = "/usr/";
|
try1 = "/usr/";
|
||||||
else if (gpt_partition_type_is_root_verity(type_uuid))
|
else if (type.designator == PARTITION_ROOT_VERITY)
|
||||||
try1 = "/";
|
try1 = "/";
|
||||||
else if (gpt_partition_type_is_usr_verity(type_uuid))
|
else if (type.designator == PARTITION_USR_VERITY)
|
||||||
try1 = "/usr/";
|
try1 = "/usr/";
|
||||||
else if (sd_id128_equal(type_uuid, SD_GPT_ESP)) {
|
else if (type.designator == PARTITION_ESP) {
|
||||||
try1 = "/efi/";
|
try1 = "/efi/";
|
||||||
try2 = "/boot/";
|
try2 = "/boot/";
|
||||||
} else if (sd_id128_equal(type_uuid, SD_GPT_XBOOTLDR))
|
} else if (type.designator == PARTITION_XBOOTLDR)
|
||||||
try1 = "/boot/";
|
try1 = "/boot/";
|
||||||
else
|
else
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||||
"Partition type " SD_ID128_FORMAT_STR " not supported from automatic source block device discovery.",
|
"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);
|
r = find_backing_devno(try1, root, &devno);
|
||||||
if (r == -ENOENT && try2)
|
if (r == -ENOENT && try2)
|
||||||
r = find_backing_devno(try2, root, &devno);
|
r = find_backing_devno(try2, root, &devno);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_error_errno(r, "Failed to resolve automatic CopyBlocks= path for partition type " SD_ID128_FORMAT_STR ", sorry: %m",
|
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);
|
xsprintf_sys_block_path(p, "/slaves", devno);
|
||||||
d = opendir(p);
|
d = opendir(p);
|
||||||
@ -4861,7 +4916,7 @@ static int resolve_copy_blocks_auto(
|
|||||||
continue;
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r > 0) {
|
if (r > 0) {
|
||||||
@ -4877,7 +4932,7 @@ static int resolve_copy_blocks_auto(
|
|||||||
} else if (errno != ENOENT)
|
} else if (errno != ENOENT)
|
||||||
return log_error_errno(errno, "Failed open %s: %m", p);
|
return log_error_errno(errno, "Failed open %s: %m", p);
|
||||||
else {
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r > 0)
|
if (r > 0)
|
||||||
@ -4934,7 +4989,7 @@ static int context_open_copy_block_paths(
|
|||||||
} else if (p->copy_blocks_auto) {
|
} else if (p->copy_blocks_auto) {
|
||||||
dev_t devno;
|
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)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -5171,6 +5226,32 @@ static int context_minimize(Context *context) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int parse_filter_partitions(const char *p) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
_cleanup_free_ char *name = NULL;
|
||||||
|
GptPartitionType type;
|
||||||
|
|
||||||
|
r = extract_first_word(&p, &name, ",", EXTRACT_CUNESCAPE|EXTRACT_DONT_COALESCE_SEPARATORS);
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "Failed to extract partition designator: %s", optarg);
|
||||||
|
|
||||||
|
r = gpt_partition_type_from_string(name, &type);
|
||||||
|
if (r < 0)
|
||||||
|
return log_error_errno(r, "'%s' is not a valid partition designator", name);
|
||||||
|
|
||||||
|
if (!GREEDY_REALLOC(arg_filter_partitions, arg_filter_partitions_size + 1))
|
||||||
|
return log_oom();
|
||||||
|
|
||||||
|
arg_filter_partitions[arg_filter_partitions_size++] = type.uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int help(void) {
|
static int help(void) {
|
||||||
_cleanup_free_ char *link = NULL;
|
_cleanup_free_ char *link = NULL;
|
||||||
int r;
|
int r;
|
||||||
@ -5213,6 +5294,10 @@ static int help(void) {
|
|||||||
" --json=pretty|short|off\n"
|
" --json=pretty|short|off\n"
|
||||||
" Generate JSON output\n"
|
" Generate JSON output\n"
|
||||||
" --split=BOOL Whether to generate split artifacts\n"
|
" --split=BOOL Whether to generate split artifacts\n"
|
||||||
|
" --include-partitions=PARTITION1,PARTITION2,PARTITION3,…\n"
|
||||||
|
" Only operate on partitions of the specified types\n"
|
||||||
|
" --exclude-partitions=PARTITION1,PARTITION2,PARTITION3,…\n"
|
||||||
|
" Don't operate on partitions of the specified types\n"
|
||||||
"\nSee the %s for details.\n",
|
"\nSee the %s for details.\n",
|
||||||
program_invocation_short_name,
|
program_invocation_short_name,
|
||||||
ansi_highlight(),
|
ansi_highlight(),
|
||||||
@ -5248,6 +5333,8 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
ARG_TPM2_PUBLIC_KEY,
|
ARG_TPM2_PUBLIC_KEY,
|
||||||
ARG_TPM2_PUBLIC_KEY_PCRS,
|
ARG_TPM2_PUBLIC_KEY_PCRS,
|
||||||
ARG_SPLIT,
|
ARG_SPLIT,
|
||||||
|
ARG_INCLUDE_PARTITIONS,
|
||||||
|
ARG_EXCLUDE_PARTITIONS,
|
||||||
};
|
};
|
||||||
|
|
||||||
static const struct option options[] = {
|
static const struct option options[] = {
|
||||||
@ -5275,6 +5362,8 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
{ "tpm2-public-key", required_argument, NULL, ARG_TPM2_PUBLIC_KEY },
|
{ "tpm2-public-key", required_argument, NULL, ARG_TPM2_PUBLIC_KEY },
|
||||||
{ "tpm2-public-key-pcrs", required_argument, NULL, ARG_TPM2_PUBLIC_KEY_PCRS },
|
{ "tpm2-public-key-pcrs", required_argument, NULL, ARG_TPM2_PUBLIC_KEY_PCRS },
|
||||||
{ "split", required_argument, NULL, ARG_SPLIT },
|
{ "split", required_argument, NULL, ARG_SPLIT },
|
||||||
|
{ "include-partitions", required_argument, NULL, ARG_INCLUDE_PARTITIONS },
|
||||||
|
{ "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -5529,6 +5618,32 @@ static int parse_argv(int argc, char *argv[]) {
|
|||||||
arg_split = r;
|
arg_split = r;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ARG_INCLUDE_PARTITIONS:
|
||||||
|
if (arg_filter_partitions_type == FILTER_PARTITIONS_EXCLUDE)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Combination of --include-partitions= and --exclude-partitions= is invalid.");
|
||||||
|
|
||||||
|
r = parse_filter_partitions(optarg);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
arg_filter_partitions_type = FILTER_PARTITIONS_INCLUDE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case ARG_EXCLUDE_PARTITIONS:
|
||||||
|
if (arg_filter_partitions_type == FILTER_PARTITIONS_INCLUDE)
|
||||||
|
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||||
|
"Combination of --include-partitions= and --exclude-partitions= is invalid.");
|
||||||
|
|
||||||
|
r = parse_filter_partitions(optarg);
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
arg_filter_partitions_type = FILTER_PARTITIONS_EXCLUDE;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
case '?':
|
case '?':
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
@ -333,6 +333,27 @@ static int open_partition(const char *node, bool is_partition, const LoopDevice
|
|||||||
return TAKE_FD(fd);
|
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(
|
static int dissect_image(
|
||||||
DissectedImage *m,
|
DissectedImage *m,
|
||||||
int fd,
|
int fd,
|
||||||
@ -606,10 +627,9 @@ static int dissect_image(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_gpt) {
|
if (is_gpt) {
|
||||||
PartitionDesignator designator = _PARTITION_DESIGNATOR_INVALID;
|
|
||||||
Architecture architecture = _ARCHITECTURE_INVALID;
|
|
||||||
const char *stype, *sid, *fstype = NULL, *label;
|
const char *stype, *sid, *fstype = NULL, *label;
|
||||||
sd_id128_t type_id, id;
|
sd_id128_t type_id, id;
|
||||||
|
GptPartitionType type;
|
||||||
bool rw = true, growfs = false;
|
bool rw = true, growfs = false;
|
||||||
|
|
||||||
sid = blkid_partition_get_uuid(pp);
|
sid = blkid_partition_get_uuid(pp);
|
||||||
@ -624,9 +644,11 @@ static int dissect_image(
|
|||||||
if (sd_id128_from_string(stype, &type_id) < 0)
|
if (sd_id128_from_string(stype, &type_id) < 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
type = gpt_partition_type_from_uuid(type_id);
|
||||||
|
|
||||||
label = blkid_partition_get_name(pp); /* libblkid returns NULL here if empty */
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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)
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_HOME;
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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)
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_SRV;
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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
|
/* 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
|
* 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)
|
if (pflags & SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_ESP;
|
|
||||||
fstype = "vfat";
|
fstype = "vfat";
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, SD_GPT_XBOOTLDR)) {
|
} else if (type.designator == PARTITION_XBOOTLDR) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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)
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_XBOOTLDR;
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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))
|
if (!sd_id128_is_null(root_uuid) && !sd_id128_equal(root_uuid, id))
|
||||||
continue;
|
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);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
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))
|
if (!sd_id128_is_null(root_verity_uuid) && !sd_id128_equal(root_verity_uuid, id))
|
||||||
continue;
|
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";
|
fstype = "DM_verity_hash";
|
||||||
rw = false;
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
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)
|
if (verity->designator >= 0 && verity->designator != PARTITION_ROOT)
|
||||||
continue;
|
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";
|
fstype = "verity_hash_signature";
|
||||||
rw = false;
|
rw = false;
|
||||||
|
|
||||||
} else if (gpt_partition_type_is_usr(type_id)) {
|
} else if (type.designator == PARTITION_USR) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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))
|
if (!sd_id128_is_null(usr_uuid) && !sd_id128_equal(usr_uuid, id))
|
||||||
continue;
|
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);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
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))
|
if (!sd_id128_is_null(usr_verity_uuid) && !sd_id128_equal(usr_verity_uuid, id))
|
||||||
continue;
|
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";
|
fstype = "DM_verity_hash";
|
||||||
rw = false;
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY);
|
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)
|
if (verity->designator >= 0 && verity->designator != PARTITION_USR)
|
||||||
continue;
|
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";
|
fstype = "verity_hash_signature";
|
||||||
rw = false;
|
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);
|
check_partition_flags(node, pflags, SD_GPT_FLAG_NO_AUTO);
|
||||||
|
|
||||||
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_SWAP;
|
} else if (type.designator == PARTITION_LINUX_GENERIC) {
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, SD_GPT_LINUX_GENERIC)) {
|
|
||||||
|
|
||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
||||||
@ -827,7 +831,7 @@ static int dissect_image(
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else if (sd_id128_equal(type_id, SD_GPT_TMP)) {
|
} else if (type.designator == PARTITION_TMP) {
|
||||||
|
|
||||||
check_partition_flags(node, pflags,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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)
|
if (pflags & SD_GPT_FLAG_NO_AUTO)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
designator = PARTITION_TMP;
|
|
||||||
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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,
|
check_partition_flags(node, pflags,
|
||||||
SD_GPT_FLAG_NO_AUTO | SD_GPT_FLAG_READ_ONLY | SD_GPT_FLAG_GROWFS);
|
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);
|
rw = !(pflags & SD_GPT_FLAG_READ_ONLY);
|
||||||
growfs = FLAGS_SET(pflags, SD_GPT_FLAG_GROWFS);
|
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_free_ char *t = NULL, *o = NULL, *l = NULL;
|
||||||
_cleanup_close_ int mount_node_fd = -1;
|
_cleanup_close_ int mount_node_fd = -1;
|
||||||
const char *options = NULL;
|
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
|
/* 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
|
* 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
|
* let the newest version win. This permits a simple A/B versioning
|
||||||
* scheme in OS images. */
|
* scheme in OS images. */
|
||||||
|
|
||||||
if (!partition_designator_is_versioned(designator) ||
|
if (compare_arch(type.arch, m->partitions[type.designator].architecture) <= 0)
|
||||||
strverscmp_improved(m->partitions[designator].label, label) >= 0)
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dissected_partition_done(m->partitions + designator);
|
if (!partition_designator_is_versioned(type.designator) ||
|
||||||
|
strverscmp_improved(m->partitions[type.designator].label, label) >= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
dissected_partition_done(m->partitions + type.designator);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) {
|
if (FLAGS_SET(flags, DISSECT_IMAGE_OPEN_PARTITION_DEVICES)) {
|
||||||
@ -909,19 +914,19 @@ static int dissect_image(
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
options = mount_options_from_designator(mount_options, designator);
|
options = mount_options_from_designator(mount_options, type.designator);
|
||||||
if (options) {
|
if (options) {
|
||||||
o = strdup(options);
|
o = strdup(options);
|
||||||
if (!o)
|
if (!o)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
m->partitions[designator] = (DissectedPartition) {
|
m->partitions[type.designator] = (DissectedPartition) {
|
||||||
.found = true,
|
.found = true,
|
||||||
.partno = nr,
|
.partno = nr,
|
||||||
.rw = rw,
|
.rw = rw,
|
||||||
.growfs = growfs,
|
.growfs = growfs,
|
||||||
.architecture = architecture,
|
.architecture = type.arch,
|
||||||
.node = TAKE_PTR(node),
|
.node = TAKE_PTR(node),
|
||||||
.fstype = TAKE_PTR(t),
|
.fstype = TAKE_PTR(t),
|
||||||
.label = TAKE_PTR(l),
|
.label = TAKE_PTR(l),
|
||||||
@ -1001,121 +1006,21 @@ static int dissect_image(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m->partitions[PARTITION_ROOT].found) {
|
if (!m->partitions[PARTITION_ROOT].found &&
|
||||||
/* If we found the primary arch, then invalidate the secondary and other arch to avoid any
|
(m->partitions[PARTITION_ROOT_VERITY].found ||
|
||||||
* ambiguities, since we never want to mount the secondary or other arch in this case. */
|
m->partitions[PARTITION_ROOT_VERITY_SIG].found))
|
||||||
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. */
|
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]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Hmm, we found a signature partition but no Verity data? Something is off. */
|
/* 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)
|
if (m->partitions[PARTITION_ROOT_VERITY_SIG].found && !m->partitions[PARTITION_ROOT_VERITY].found)
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
if (m->partitions[PARTITION_USR].found) {
|
if (!m->partitions[PARTITION_USR].found &&
|
||||||
/* Invalidate secondary and other arch /usr/ if we found the primary arch */
|
(m->partitions[PARTITION_USR_VERITY].found ||
|
||||||
m->partitions[PARTITION_USR_SECONDARY].found = false;
|
m->partitions[PARTITION_USR_VERITY_SIG].found))
|
||||||
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 */
|
return -EADDRNOTAVAIL; /* as above */
|
||||||
|
|
||||||
else if (m->partitions[PARTITION_USR_SECONDARY].found) {
|
/* as above */
|
||||||
|
|
||||||
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]);
|
|
||||||
|
|
||||||
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. */
|
|
||||||
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
|
if (m->partitions[PARTITION_USR_VERITY_SIG].found && !m->partitions[PARTITION_USR_VERITY].found)
|
||||||
return -EADDRNOTAVAIL;
|
return -EADDRNOTAVAIL;
|
||||||
|
|
||||||
|
209
src/shared/gpt.c
209
src/shared/gpt.c
@ -23,23 +23,11 @@ bool partition_designator_is_versioned(PartitionDesignator d) {
|
|||||||
|
|
||||||
return IN_SET(d,
|
return IN_SET(d,
|
||||||
PARTITION_ROOT,
|
PARTITION_ROOT,
|
||||||
PARTITION_ROOT_SECONDARY,
|
|
||||||
PARTITION_ROOT_OTHER,
|
|
||||||
PARTITION_USR,
|
PARTITION_USR,
|
||||||
PARTITION_USR_SECONDARY,
|
|
||||||
PARTITION_USR_OTHER,
|
|
||||||
PARTITION_ROOT_VERITY,
|
PARTITION_ROOT_VERITY,
|
||||||
PARTITION_ROOT_SECONDARY_VERITY,
|
|
||||||
PARTITION_ROOT_OTHER_VERITY,
|
|
||||||
PARTITION_USR_VERITY,
|
PARTITION_USR_VERITY,
|
||||||
PARTITION_USR_SECONDARY_VERITY,
|
|
||||||
PARTITION_USR_OTHER_VERITY,
|
|
||||||
PARTITION_ROOT_VERITY_SIG,
|
PARTITION_ROOT_VERITY_SIG,
|
||||||
PARTITION_ROOT_SECONDARY_VERITY_SIG,
|
PARTITION_USR_VERITY_SIG);
|
||||||
PARTITION_ROOT_OTHER_VERITY_SIG,
|
|
||||||
PARTITION_USR_VERITY_SIG,
|
|
||||||
PARTITION_USR_SECONDARY_VERITY_SIG,
|
|
||||||
PARTITION_USR_OTHER_VERITY_SIG);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PartitionDesignator partition_verity_of(PartitionDesignator p) {
|
PartitionDesignator partition_verity_of(PartitionDesignator p) {
|
||||||
@ -48,21 +36,9 @@ PartitionDesignator partition_verity_of(PartitionDesignator p) {
|
|||||||
case PARTITION_ROOT:
|
case PARTITION_ROOT:
|
||||||
return PARTITION_ROOT_VERITY;
|
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:
|
case PARTITION_USR:
|
||||||
return PARTITION_USR_VERITY;
|
return PARTITION_USR_VERITY;
|
||||||
|
|
||||||
case PARTITION_USR_SECONDARY:
|
|
||||||
return PARTITION_USR_SECONDARY_VERITY;
|
|
||||||
|
|
||||||
case PARTITION_USR_OTHER:
|
|
||||||
return PARTITION_USR_OTHER_VERITY;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return _PARTITION_DESIGNATOR_INVALID;
|
return _PARTITION_DESIGNATOR_INVALID;
|
||||||
}
|
}
|
||||||
@ -74,82 +50,27 @@ PartitionDesignator partition_verity_sig_of(PartitionDesignator p) {
|
|||||||
case PARTITION_ROOT:
|
case PARTITION_ROOT:
|
||||||
return PARTITION_ROOT_VERITY_SIG;
|
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:
|
case PARTITION_USR:
|
||||||
return PARTITION_USR_VERITY_SIG;
|
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:
|
default:
|
||||||
return _PARTITION_DESIGNATOR_INVALID;
|
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[] = {
|
static const char *const partition_designator_table[] = {
|
||||||
[PARTITION_ROOT] = "root",
|
[PARTITION_ROOT] = "root",
|
||||||
[PARTITION_ROOT_SECONDARY] = "root-secondary",
|
|
||||||
[PARTITION_ROOT_OTHER] = "root-other",
|
|
||||||
[PARTITION_USR] = "usr",
|
[PARTITION_USR] = "usr",
|
||||||
[PARTITION_USR_SECONDARY] = "usr-secondary",
|
|
||||||
[PARTITION_USR_OTHER] = "usr-other",
|
|
||||||
[PARTITION_HOME] = "home",
|
[PARTITION_HOME] = "home",
|
||||||
[PARTITION_SRV] = "srv",
|
[PARTITION_SRV] = "srv",
|
||||||
[PARTITION_ESP] = "esp",
|
[PARTITION_ESP] = "esp",
|
||||||
[PARTITION_XBOOTLDR] = "xbootldr",
|
[PARTITION_XBOOTLDR] = "xbootldr",
|
||||||
[PARTITION_SWAP] = "swap",
|
[PARTITION_SWAP] = "swap",
|
||||||
[PARTITION_ROOT_VERITY] = "root-verity",
|
[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_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_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_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_TMP] = "tmp",
|
||||||
[PARTITION_VAR] = "var",
|
[PARTITION_VAR] = "var",
|
||||||
[PARTITION_USER_HOME] = "user-home",
|
[PARTITION_USER_HOME] = "user-home",
|
||||||
@ -160,11 +81,7 @@ DEFINE_STRING_TABLE_LOOKUP(partition_designator, PartitionDesignator);
|
|||||||
|
|
||||||
static const char *const partition_mountpoint_table[] = {
|
static const char *const partition_mountpoint_table[] = {
|
||||||
[PARTITION_ROOT] = "/\0",
|
[PARTITION_ROOT] = "/\0",
|
||||||
[PARTITION_ROOT_SECONDARY] = "/\0",
|
|
||||||
[PARTITION_ROOT_OTHER] = "/\0",
|
|
||||||
[PARTITION_USR] = "/usr\0",
|
[PARTITION_USR] = "/usr\0",
|
||||||
[PARTITION_USR_SECONDARY] = "/usr\0",
|
|
||||||
[PARTITION_USR_OTHER] = "/usr\0",
|
|
||||||
[PARTITION_HOME] = "/home\0",
|
[PARTITION_HOME] = "/home\0",
|
||||||
[PARTITION_SRV] = "/srv\0",
|
[PARTITION_SRV] = "/srv\0",
|
||||||
[PARTITION_ESP] = "/efi\0/boot\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_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(partition_mountpoint, PartitionDesignator);
|
||||||
|
|
||||||
#define _GPT_ARCH_SEXTET(arch, name) \
|
#define _GPT_ARCH_SEXTET(arch, name) \
|
||||||
{ SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER }, \
|
{ SD_GPT_ROOT_##arch, "root-" name, ARCHITECTURE_##arch, .designator = PARTITION_ROOT }, \
|
||||||
{ SD_GPT_ROOT_##arch##_VERITY, "root-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_ROOT_OTHER_VERITY }, \
|
{ 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_OTHER_VERITY_SIG }, \
|
{ 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_OTHER }, \
|
{ SD_GPT_USR_##arch, "usr-" name, ARCHITECTURE_##arch, .designator = PARTITION_USR }, \
|
||||||
{ SD_GPT_USR_##arch##_VERITY, "usr-" name "-verity", ARCHITECTURE_##arch, .designator = PARTITION_USR_OTHER_VERITY }, \
|
{ 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_OTHER_VERITY_SIG }
|
{ SD_GPT_USR_##arch##_VERITY_SIG, "usr-" name "-verity-sig", ARCHITECTURE_##arch, .designator = PARTITION_USR_VERITY_SIG }
|
||||||
|
|
||||||
const GptPartitionType gpt_partition_type_table[] = {
|
const GptPartitionType gpt_partition_type_table[] = {
|
||||||
_GPT_ARCH_SEXTET(ALPHA, "alpha"),
|
_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 },
|
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-verity-sig", native_architecture(), .designator = PARTITION_USR_VERITY_SIG },
|
||||||
#endif
|
#endif
|
||||||
#ifdef SD_GPT_ROOT_SECONDARY
|
#ifdef SD_GPT_ROOT_SECONDARY
|
||||||
{ SD_GPT_ROOT_NATIVE, "root-secondary", native_architecture(), .designator = PARTITION_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_SECONDARY_VERITY },
|
{ 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_SECONDARY_VERITY_SIG },
|
{ 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_SECONDARY },
|
{ SD_GPT_USR_NATIVE, "usr-secondary", native_architecture(), .designator = PARTITION_USR },
|
||||||
{ SD_GPT_USR_NATIVE_VERITY, "usr-secondary-verity", native_architecture(), .designator = PARTITION_USR_SECONDARY_VERITY },
|
{ 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_SECONDARY_VERITY_SIG },
|
{ SD_GPT_USR_NATIVE_VERITY_SIG, "usr-secondary-verity-sig", native_architecture(), .designator = PARTITION_USR_VERITY_SIG },
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
{ SD_GPT_ESP, "esp", _ARCHITECTURE_INVALID, .designator = PARTITION_ESP },
|
{ 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);
|
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);
|
assert(s);
|
||||||
|
|
||||||
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
|
for (size_t i = 0; i < ELEMENTSOF(gpt_partition_type_table) - 1; i++)
|
||||||
if (streq(s, gpt_partition_type_table[i].name)) {
|
if (streq(s, gpt_partition_type_table[i].name)) {
|
||||||
if (ret)
|
if (ret)
|
||||||
*ret = gpt_partition_type_table[i].uuid;
|
*ret = gpt_partition_type_table[i];
|
||||||
return 0;
|
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) {
|
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;
|
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;
|
const GptPartitionType *pt;
|
||||||
|
|
||||||
pt = gpt_partition_type_find_by_uuid(id);
|
pt = gpt_partition_type_find_by_uuid(id);
|
||||||
@ -313,63 +240,17 @@ static GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gpt_partition_type_is_root(sd_id128_t id) {
|
const char *gpt_partition_type_mountpoint_nulstr(GptPartitionType type) {
|
||||||
return IN_SET(gpt_partition_type_from_uuid(id).designator,
|
return partition_mountpoint_to_string(type.designator);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool gpt_partition_type_knows_read_only(GptPartitionType type) {
|
||||||
|
return IN_SET(type.designator,
|
||||||
PARTITION_ROOT,
|
PARTITION_ROOT,
|
||||||
PARTITION_ROOT_SECONDARY,
|
|
||||||
PARTITION_ROOT_OTHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gpt_partition_type_is_root_verity(sd_id128_t id) {
|
|
||||||
return IN_SET(gpt_partition_type_from_uuid(id).designator,
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gpt_partition_type_is_usr(sd_id128_t id) {
|
|
||||||
return IN_SET(gpt_partition_type_from_uuid(id).designator,
|
|
||||||
PARTITION_USR,
|
PARTITION_USR,
|
||||||
PARTITION_USR_SECONDARY,
|
|
||||||
PARTITION_USR_OTHER);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool gpt_partition_type_is_usr_verity(sd_id128_t id) {
|
|
||||||
return IN_SET(gpt_partition_type_from_uuid(id).designator,
|
|
||||||
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 */
|
/* pretty much implied, but let's set the bit to make things really clear */
|
||||||
gpt_partition_type_is_root_verity(id) ||
|
PARTITION_ROOT_VERITY,
|
||||||
gpt_partition_type_is_usr_verity(id) ||
|
PARTITION_USR_VERITY,
|
||||||
IN_SET(gpt_partition_type_from_uuid(id).designator,
|
|
||||||
PARTITION_HOME,
|
PARTITION_HOME,
|
||||||
PARTITION_SRV,
|
PARTITION_SRV,
|
||||||
PARTITION_VAR,
|
PARTITION_VAR,
|
||||||
@ -377,10 +258,10 @@ bool gpt_partition_type_knows_read_only(sd_id128_t id) {
|
|||||||
PARTITION_XBOOTLDR);
|
PARTITION_XBOOTLDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gpt_partition_type_knows_growfs(sd_id128_t id) {
|
bool gpt_partition_type_knows_growfs(GptPartitionType type) {
|
||||||
return gpt_partition_type_is_root(id) ||
|
return IN_SET(type.designator,
|
||||||
gpt_partition_type_is_usr(id) ||
|
PARTITION_ROOT,
|
||||||
IN_SET(gpt_partition_type_from_uuid(id).designator,
|
PARTITION_USR,
|
||||||
PARTITION_HOME,
|
PARTITION_HOME,
|
||||||
PARTITION_SRV,
|
PARTITION_SRV,
|
||||||
PARTITION_VAR,
|
PARTITION_VAR,
|
||||||
@ -388,12 +269,12 @@ bool gpt_partition_type_knows_growfs(sd_id128_t id) {
|
|||||||
PARTITION_XBOOTLDR);
|
PARTITION_XBOOTLDR);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool gpt_partition_type_knows_no_auto(sd_id128_t id) {
|
bool gpt_partition_type_knows_no_auto(GptPartitionType type) {
|
||||||
return gpt_partition_type_is_root(id) ||
|
return IN_SET(type.designator,
|
||||||
gpt_partition_type_is_root_verity(id) ||
|
PARTITION_ROOT,
|
||||||
gpt_partition_type_is_usr(id) ||
|
PARTITION_ROOT_VERITY,
|
||||||
gpt_partition_type_is_usr_verity(id) ||
|
PARTITION_USR,
|
||||||
IN_SET(gpt_partition_type_from_uuid(id).designator,
|
PARTITION_USR_VERITY,
|
||||||
PARTITION_HOME,
|
PARTITION_HOME,
|
||||||
PARTITION_SRV,
|
PARTITION_SRV,
|
||||||
PARTITION_VAR,
|
PARTITION_VAR,
|
||||||
|
@ -12,28 +12,16 @@
|
|||||||
|
|
||||||
typedef enum PartitionDesignator {
|
typedef enum PartitionDesignator {
|
||||||
PARTITION_ROOT, /* Primary architecture */
|
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,
|
||||||
PARTITION_USR_SECONDARY,
|
|
||||||
PARTITION_USR_OTHER,
|
|
||||||
PARTITION_HOME,
|
PARTITION_HOME,
|
||||||
PARTITION_SRV,
|
PARTITION_SRV,
|
||||||
PARTITION_ESP,
|
PARTITION_ESP,
|
||||||
PARTITION_XBOOTLDR,
|
PARTITION_XBOOTLDR,
|
||||||
PARTITION_SWAP,
|
PARTITION_SWAP,
|
||||||
PARTITION_ROOT_VERITY, /* verity data for the PARTITION_ROOT partition */
|
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_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_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_VERITY_SIG,
|
||||||
PARTITION_USR_SECONDARY_VERITY_SIG,
|
|
||||||
PARTITION_USR_OTHER_VERITY_SIG,
|
|
||||||
PARTITION_TMP,
|
PARTITION_TMP,
|
||||||
PARTITION_VAR,
|
PARTITION_VAR,
|
||||||
PARTITION_USER_HOME,
|
PARTITION_USER_HOME,
|
||||||
@ -46,8 +34,6 @@ bool partition_designator_is_versioned(PartitionDesignator d);
|
|||||||
|
|
||||||
PartitionDesignator partition_verity_of(PartitionDesignator p);
|
PartitionDesignator partition_verity_of(PartitionDesignator p);
|
||||||
PartitionDesignator partition_verity_sig_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_;
|
const char* partition_designator_to_string(PartitionDesignator d) _const_;
|
||||||
PartitionDesignator partition_designator_from_string(const char *name) _pure_;
|
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(
|
const char *gpt_partition_type_uuid_to_string_harder(
|
||||||
sd_id128_t id,
|
sd_id128_t id,
|
||||||
char buffer[static SD_ID128_UUID_STRING_MAX]);
|
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) \
|
#define GPT_PARTITION_TYPE_UUID_TO_STRING_HARDER(id) \
|
||||||
gpt_partition_type_uuid_to_string_harder((id), (char[SD_ID128_UUID_STRING_MAX]) {})
|
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);
|
int gpt_partition_label_valid(const char *s);
|
||||||
|
|
||||||
bool gpt_partition_type_is_root(sd_id128_t id);
|
GptPartitionType gpt_partition_type_from_uuid(sd_id128_t id);
|
||||||
bool gpt_partition_type_is_root_verity(sd_id128_t id);
|
int gpt_partition_type_from_string(const char *s, GptPartitionType *ret);
|
||||||
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);
|
|
||||||
|
|
||||||
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_read_only(GptPartitionType type);
|
||||||
bool gpt_partition_type_knows_growfs(sd_id128_t id);
|
bool gpt_partition_type_knows_growfs(GptPartitionType type);
|
||||||
bool gpt_partition_type_knows_no_auto(sd_id128_t id);
|
bool gpt_partition_type_knows_no_auto(GptPartitionType type);
|
||||||
|
@ -111,6 +111,7 @@ int read_partition_info(
|
|||||||
struct fdisk_parttype *pt;
|
struct fdisk_parttype *pt;
|
||||||
uint64_t start, size, flags;
|
uint64_t start, size, flags;
|
||||||
sd_id128_t ptid, id;
|
sd_id128_t ptid, id;
|
||||||
|
GptPartitionType type;
|
||||||
size_t partno;
|
size_t partno;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@ -178,6 +179,8 @@ int read_partition_info(
|
|||||||
if (!label_copy)
|
if (!label_copy)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
|
type = gpt_partition_type_from_uuid(ptid);
|
||||||
|
|
||||||
*ret = (PartitionInfo) {
|
*ret = (PartitionInfo) {
|
||||||
.partno = partno,
|
.partno = partno,
|
||||||
.start = start,
|
.start = start,
|
||||||
@ -187,9 +190,9 @@ int read_partition_info(
|
|||||||
.uuid = id,
|
.uuid = id,
|
||||||
.label = TAKE_PTR(label_copy),
|
.label = TAKE_PTR(label_copy),
|
||||||
.device = TAKE_PTR(device),
|
.device = TAKE_PTR(device),
|
||||||
.no_auto = FLAGS_SET(flags, SD_GPT_FLAG_NO_AUTO) && gpt_partition_type_knows_no_auto(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(ptid),
|
.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(ptid),
|
.growfs = FLAGS_SET(flags, SD_GPT_FLAG_GROWFS) && gpt_partition_type_knows_growfs(type),
|
||||||
};
|
};
|
||||||
|
|
||||||
return 1; /* found! */
|
return 1; /* found! */
|
||||||
@ -269,6 +272,7 @@ int patch_partition(
|
|||||||
_cleanup_(fdisk_unref_partitionp) struct fdisk_partition *pa = NULL;
|
_cleanup_(fdisk_unref_partitionp) struct fdisk_partition *pa = NULL;
|
||||||
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
|
_cleanup_(fdisk_unref_contextp) struct fdisk_context *c = NULL;
|
||||||
bool tweak_no_auto, tweak_read_only, tweak_growfs;
|
bool tweak_no_auto, tweak_read_only, tweak_growfs;
|
||||||
|
GptPartitionType type;
|
||||||
int r, fd;
|
int r, fd;
|
||||||
|
|
||||||
assert(device);
|
assert(device);
|
||||||
@ -313,16 +317,18 @@ int patch_partition(
|
|||||||
return log_error_errno(r, "Failed to update partition UUID: %m");
|
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 the read-only flag, but only if supported by the partition type */
|
||||||
tweak_no_auto =
|
tweak_no_auto =
|
||||||
FLAGS_SET(change, PARTITION_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 =
|
tweak_read_only =
|
||||||
FLAGS_SET(change, PARTITION_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 =
|
tweak_growfs =
|
||||||
FLAGS_SET(change, PARTITION_GROWFS) &&
|
FLAGS_SET(change, PARTITION_GROWFS) &&
|
||||||
gpt_partition_type_knows_growfs(info->type);
|
gpt_partition_type_knows_growfs(type);
|
||||||
|
|
||||||
if (change & PARTITION_FLAGS) {
|
if (change & PARTITION_FLAGS) {
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
|
@ -194,7 +194,7 @@ static int resource_load_from_blockdev(Resource *rr) {
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* Check if partition type matches */
|
/* 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;
|
continue;
|
||||||
|
|
||||||
/* A label of "_empty" means "not used so far" for us */
|
/* A label of "_empty" means "not used so far" for us */
|
||||||
|
@ -5,8 +5,7 @@
|
|||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
|
|
||||||
#include "sd-id128.h"
|
#include "gpt.h"
|
||||||
|
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
|
|
||||||
@ -74,7 +73,7 @@ struct Resource {
|
|||||||
char *path;
|
char *path;
|
||||||
bool path_auto; /* automatically find root path (only available if target resource, not source resource) */
|
bool path_auto; /* automatically find root path (only available if target resource, not source resource) */
|
||||||
char **patterns;
|
char **patterns;
|
||||||
sd_id128_t partition_type;
|
GptPartitionType partition_type;
|
||||||
bool partition_type_set;
|
bool partition_type_set;
|
||||||
|
|
||||||
/* All instances of this resource we found */
|
/* All instances of this resource we found */
|
||||||
|
@ -344,7 +344,7 @@ static int config_parse_resource_ptype(
|
|||||||
|
|
||||||
assert(rvalue);
|
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) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed parse partition type, ignoring: %s", rvalue);
|
"Failed parse partition type, ignoring: %s", rvalue);
|
||||||
@ -654,18 +654,18 @@ int transfer_vacuum(
|
|||||||
if (t->target.n_empty + t->target.n_instances < 2)
|
if (t->target.n_empty + t->target.n_instances < 2)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
|
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.",
|
"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),
|
SD_ID128_FORMAT_VAL(t->target.partition_type.uuid),
|
||||||
gpt_partition_type_uuid_to_string(t->target.partition_type));
|
gpt_partition_type_uuid_to_string(t->target.partition_type.uuid));
|
||||||
if (space > t->target.n_empty + t->target.n_instances)
|
if (space > t->target.n_empty + t->target.n_instances)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
|
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.",
|
"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),
|
SD_ID128_FORMAT_VAL(t->target.partition_type.uuid),
|
||||||
gpt_partition_type_uuid_to_string(t->target.partition_type));
|
gpt_partition_type_uuid_to_string(t->target.partition_type.uuid));
|
||||||
if (space == t->target.n_empty + t->target.n_instances)
|
if (space == t->target.n_empty + t->target.n_instances)
|
||||||
return log_error_errno(SYNTHETIC_ERRNO(ENOSPC),
|
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.",
|
"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),
|
SD_ID128_FORMAT_VAL(t->target.partition_type.uuid),
|
||||||
gpt_partition_type_uuid_to_string(t->target.partition_type));
|
gpt_partition_type_uuid_to_string(t->target.partition_type.uuid));
|
||||||
|
|
||||||
rm = LESS_BY(space, t->target.n_empty);
|
rm = LESS_BY(space, t->target.n_empty);
|
||||||
remain = LESS_BY(t->target.n_instances, rm);
|
remain = LESS_BY(t->target.n_instances, rm);
|
||||||
@ -858,7 +858,7 @@ int transfer_acquire_instance(Transfer *t, Instance *i) {
|
|||||||
r = find_suitable_partition(
|
r = find_suitable_partition(
|
||||||
t->target.path,
|
t->target.path,
|
||||||
i->metadata.size,
|
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);
|
&t->partition_info);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
@ -19,13 +19,13 @@ TEST(gpt_types_against_architectures) {
|
|||||||
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++)
|
for (Architecture a = 0; a < _ARCHITECTURE_MAX; a++)
|
||||||
FOREACH_STRING(suffix, "", "-verity", "-verity-sig") {
|
FOREACH_STRING(suffix, "", "-verity", "-verity-sig") {
|
||||||
_cleanup_free_ char *joined = NULL;
|
_cleanup_free_ char *joined = NULL;
|
||||||
sd_id128_t id;
|
GptPartitionType type;
|
||||||
|
|
||||||
joined = strjoin(prefix, architecture_to_string(a), suffix);
|
joined = strjoin(prefix, architecture_to_string(a), suffix);
|
||||||
if (!joined)
|
if (!joined)
|
||||||
return (void) log_oom();
|
return (void) log_oom();
|
||||||
|
|
||||||
r = gpt_partition_type_uuid_from_string(joined, &id);
|
r = gpt_partition_type_from_string(joined, &type);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
printf("%s %s\n", RED_CROSS_MARK(), joined);
|
printf("%s %s\n", RED_CROSS_MARK(), joined);
|
||||||
continue;
|
continue;
|
||||||
@ -34,15 +34,15 @@ TEST(gpt_types_against_architectures) {
|
|||||||
printf("%s %s\n", GREEN_CHECK_MARK(), joined);
|
printf("%s %s\n", GREEN_CHECK_MARK(), joined);
|
||||||
|
|
||||||
if (streq(prefix, "root-") && streq(suffix, ""))
|
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"))
|
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, ""))
|
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"))
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -133,6 +133,40 @@ SizeMaxBytes=64M
|
|||||||
PaddingMinBytes=92M
|
PaddingMinBytes=92M
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
|
systemd-repart --definitions="$defs" \
|
||||||
|
--dry-run=no \
|
||||||
|
--seed="$seed" \
|
||||||
|
--include-partitions=home,swap \
|
||||||
|
"$imgs/zzz"
|
||||||
|
|
||||||
|
output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$')
|
||||||
|
|
||||||
|
assert_eq "$output" "label: gpt
|
||||||
|
label-id: 1D2CE291-7CCE-4F7D-BC83-FDB49AD74EBD
|
||||||
|
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\""
|
||||||
|
|
||||||
|
systemd-repart --definitions="$defs" \
|
||||||
|
--dry-run=no \
|
||||||
|
--seed="$seed" \
|
||||||
|
--exclude-partitions=root \
|
||||||
|
"$imgs/zzz"
|
||||||
|
|
||||||
|
output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$')
|
||||||
|
|
||||||
|
assert_eq "$output" "label: gpt
|
||||||
|
label-id: 1D2CE291-7CCE-4F7D-BC83-FDB49AD74EBD
|
||||||
|
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\""
|
||||||
|
|
||||||
systemd-repart --definitions="$defs" \
|
systemd-repart --definitions="$defs" \
|
||||||
--dry-run=no \
|
--dry-run=no \
|
||||||
--seed="$seed" \
|
--seed="$seed" \
|
||||||
|
Loading…
Reference in New Issue
Block a user