repart: Add --skip-partitions=

--include-partitions and --exclude-partitions now fully exclude
partitions from repart. Whenever a partition type is excluded, we
don't take any partitions of that type into account at all when
running systemd-repart.

--skip-partitions= is introduced to do what --exclude-partitions did
previously. Any skipped partitions are taken into acount when doing
size calculations, but are not yet populated.

Why do we need both concepts? Exclusion is needed so that we can
use shared repart definitions to generate bootable and non-bootable
images. When generating a non-bootable image, we use --exclude-partitions
to exclude the ESP partition. Skipping is needed so that we can
populate the root partition while skipping the ESP partition, get
the roothash of the root partition, use that to generate a UKI, and
finally populate the ESP partition with the UKI included.
This commit is contained in:
Daan De Meyer 2022-11-22 14:27:30 +01:00
parent 220780db86
commit 7d505753f1
3 changed files with 49 additions and 13 deletions

View file

@ -372,11 +372,18 @@
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
<citerefentry><refentrytitle>repart.d</refentrytitle><manvolnum>5</manvolnum></citerefentry>).
</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--skip-partitions=</option><arg rep="repeat">PARTITION</arg></term>
<listitem><para>This option specifies which partition types <command>systemd-repart</command> should
skip. All partitions that are skipped using this option are still taken into account when calculating
the sizes and offsets of other partitions, but aren't actually written to the disk image. The net
effect of this option is that if you run <command>systemd-repart</command> again without these
options, the missing partitions will be added as if they had not been skipped the first time
<command>systemd-repart</command> was executed.</para></listitem>
</varlistentry>

View file

@ -145,6 +145,8 @@ static bool arg_split = false;
static sd_id128_t *arg_filter_partitions = NULL;
static size_t arg_n_filter_partitions = 0;
static FilterPartitionsType arg_filter_partitions_type = FILTER_PARTITIONS_NONE;
static sd_id128_t *arg_skip_partitions = NULL;
static size_t arg_n_skip_partitions = 0;
STATIC_DESTRUCTOR_REGISTER(arg_root, freep);
STATIC_DESTRUCTOR_REGISTER(arg_image, freep);
@ -385,7 +387,7 @@ static void partition_foreignize(Partition *p) {
p->verity = VERITY_OFF;
}
static bool partition_skip(const Partition *p) {
static bool partition_exclude(const Partition *p) {
assert(p);
if (arg_filter_partitions_type == FILTER_PARTITIONS_NONE)
@ -398,6 +400,16 @@ static bool partition_skip(const Partition *p) {
return arg_filter_partitions_type == FILTER_PARTITIONS_INCLUDE;
}
static bool partition_skip(const Partition *p) {
assert(p);
for (size_t i = 0; i < arg_n_skip_partitions; i++)
if (sd_id128_equal(p->type.uuid, arg_skip_partitions[i]))
return true;
return false;
}
static Partition* partition_unlink_and_free(Context *context, Partition *p) {
if (!p)
return NULL;
@ -1559,6 +1571,9 @@ static int partition_read_definition(Partition *p, const char *path, const char
if (r < 0)
return r;
if (partition_exclude(p))
return 0;
if (p->size_min != UINT64_MAX && p->size_max != UINT64_MAX && p->size_min > p->size_max)
return log_syntax(NULL, LOG_ERR, path, 1, SYNTHETIC_ERRNO(EINVAL),
"SizeMinBytes= larger than SizeMaxBytes=, refusing.");
@ -1657,7 +1672,7 @@ static int partition_read_definition(Partition *p, const char *path, const char
} else if (streq(p->split_name_format, "-"))
p->split_name_format = mfree(p->split_name_format);
return 0;
return 1;
}
static int find_verity_sibling(Context *context, Partition *p, VerityMode mode, Partition **ret) {
@ -1732,6 +1747,8 @@ static int context_read_definitions(
r = partition_read_definition(p, *f, dirs);
if (r < 0)
return r;
if (r == 0)
continue;
LIST_INSERT_AFTER(partitions, context->partitions, last, p);
last = TAKE_PTR(p);
@ -5405,9 +5422,12 @@ static int help(void) {
" Generate JSON output\n"
" --split=BOOL Whether to generate split artifacts\n"
" --include-partitions=PARTITION1,PARTITION2,PARTITION3,…\n"
" Only operate on partitions of the specified types\n"
" Ignore partitions not of the specified types\n"
" --exclude-partitions=PARTITION1,PARTITION2,PARTITION3,…\n"
" Don't operate on partitions of the specified types\n"
" Ignore partitions of the specified types\n"
" --skip-partitions=PARTITION1,PARTITION2,PARTITION3,…\n"
" Take partitions of the specified types into account\n"
" but don't populate them yet\n"
"\nSee the %s for details.\n",
program_invocation_short_name,
ansi_highlight(),
@ -5445,6 +5465,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_SPLIT,
ARG_INCLUDE_PARTITIONS,
ARG_EXCLUDE_PARTITIONS,
ARG_SKIP_PARTITIONS,
};
static const struct option options[] = {
@ -5474,6 +5495,7 @@ static int parse_argv(int argc, char *argv[]) {
{ "split", required_argument, NULL, ARG_SPLIT },
{ "include-partitions", required_argument, NULL, ARG_INCLUDE_PARTITIONS },
{ "exclude-partitions", required_argument, NULL, ARG_EXCLUDE_PARTITIONS },
{ "skip-partitions", required_argument, NULL, ARG_SKIP_PARTITIONS },
{}
};
@ -5754,6 +5776,13 @@ static int parse_argv(int argc, char *argv[]) {
break;
case ARG_SKIP_PARTITIONS:
r = parse_partition_types(optarg, &arg_skip_partitions, &arg_n_skip_partitions);
if (r < 0)
return r;
break;
case '?':
return -EINVAL;

View file

@ -154,13 +154,14 @@ device: $imgs/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
$imgs/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
$imgs/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
$imgs/zzz1 : start= 2048, size= 1775576, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
$imgs/zzz2 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
runas testuser systemd-repart --definitions="$defs" \
--dry-run=no \
--seed="$seed" \
--exclude-partitions=root \
--empty=force \
--skip-partitions=home,root \
"$imgs/zzz"
output=$(sfdisk -d "$imgs/zzz" | grep -v -e 'sector-size' -e '^$')
@ -171,7 +172,6 @@ device: $imgs/zzz
unit: sectors
first-lba: 2048
last-lba: 2097118
$imgs/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=4980595D-D74A-483A-AA9E-9903879A0EE5, name=\"home-first\", attrs=\"GUID:59\"
$imgs/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=78C92DB8-3D2B-4823-B0DC-792B78F66F1E, name=\"swap\""
runas testuser systemd-repart --definitions="$defs" \