From: Lennart Poettering Date: Wed, 21 Apr 2021 15:31:34 +0000 (+0200) Subject: repart: add GrowFileSystem= setting to set new GPT partition flag for newly created... X-Git-Tag: v249-rc1~279^2~3 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=1c41c1dc346dd0d5d235fe0866bbe2d9be924dcd;p=thirdparty%2Fsystemd.git repart: add GrowFileSystem= setting to set new GPT partition flag for newly created partitions And set it to on by default, except if partition is marked read-only. --- diff --git a/man/repart.d.xml b/man/repart.d.xml index d45a4c9b186..6e3322e064b 100644 --- a/man/repart.d.xml +++ b/man/repart.d.xml @@ -55,11 +55,13 @@ partition slot greater than the highest slot number currently in use. Any existing partitions that have no matching partition file are left as they are. - Note that these definitions may only be used to created and initialize new partitions or grow + Note that these definitions may only be used to create and initialize new partitions or to grow existing ones. In the latter case it will not grow the contained files systems however; separate mechanisms, such as systemd-growfs8 may be - used to grow the file systems inside of these partitions. + used to grow the file systems inside of these partitions. Partitions may also be marked for automatic + growing via the GrowFileSystem= setting, in which case the file system is grown on + first mount by tools that respect this flag. See below for details. @@ -580,13 +582,39 @@ ReadOnly= - - Configures the Read-Only partition flags (bit 60) of the partition table entry. This - option is a friendly way to set bit 60 of the partition flags value without setting any of the other - bits, and may be set via Flags= too, see above. - - If both Flags= and ReadOnly= are set the latter controls - the value of the flag. + GrowFileSystem= + + Configures the Read-Only and Grow-File-System partition flags (bit 60 and 59) of the + partition table entry, as defined by the Discoverable Partitions Specification. Only + available for partition types supported by the specification. This option is a friendly way to set bit + 60 and 59 of the partition flags value without setting any of the other bits, and may be set via + Flags= too, see above. + + If Flags= is used in conjunction with one or both of + ReadOnly=/GrowFileSystem= the latter control the value of the + relevant flags, i.e. the high-level settings + ReadOnly=/GrowFileSystem= override the low-level setting + Flags=. + + Note that the two flags affect only automatic partition mounting, as implemented by + systemd-gpt-auto-generator8 + or the option of various commands (such as + systemd-nspawn1). It + has no effect on explicit mounts, such as those done via mount8 or + fstab5 + + If both bit 50 and 59 are set for a partition (i.e. the partition is marked both read-only and + marked for file system growing) the latter is typically without effect: the read-only flag takes + precedence in most tools reading these flags, and since growing the file system involves writing to + the partition it is consequently ignored. + + ReadOnly= defaults to on for Verity partition + types. GrowFileSystem= defaults to on for all partition types that support it, + except if the partition is marked read-only (and thus effectively, defaults to off for Verity + partitions). diff --git a/src/partition/repart.c b/src/partition/repart.c index 3b311099525..51b8f20dbcc 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -170,6 +170,7 @@ struct Partition { uint64_t gpt_flags; int read_only; + int growfs; LIST_FIELDS(Partition, partitions); }; @@ -243,6 +244,7 @@ static Partition *partition_new(void) { .copy_blocks_fd = -1, .copy_blocks_size = UINT64_MAX, .read_only = -1, + .growfs = -1, }; return p; @@ -1316,6 +1318,7 @@ static int partition_read_definition(Partition *p, const char *path) { { "Partition", "Encrypt", config_parse_encrypt, 0, &p->encrypt }, { "Partition", "Flags", config_parse_gpt_flags, 0, &p->gpt_flags }, { "Partition", "ReadOnly", config_parse_tristate, 0, &p->read_only }, + { "Partition", "GrowFileSystem", config_parse_tristate, 0, &p->growfs }, {} }; int r; @@ -1363,6 +1366,11 @@ static int partition_read_definition(Partition *p, const char *path) { p->read_only < 0) p->read_only = true; + /* Default to "growfs" on, unless read-only */ + if (gpt_partition_type_knows_growfs(p->type_uuid) && + p->read_only <= 0) + p->growfs = true; + return 0; } @@ -3255,6 +3263,38 @@ static int set_gpt_flags(struct fdisk_partition *q, uint64_t flags) { return fdisk_partition_set_attrs(q, a); } +static uint64_t partition_merge_flags(Partition *p) { + uint64_t f; + + assert(p); + + f = p->gpt_flags; + + if (p->read_only >= 0) { + if (gpt_partition_type_knows_read_only(p->type_uuid)) + SET_FLAG(f, GPT_FLAG_READ_ONLY, p->read_only); + else { + char buffer[ID128_UUID_STRING_MAX]; + log_warning("Configured ReadOnly=%s for partition type '%s' that doesn't support it, ignoring.", + yes_no(p->read_only), + gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer)); + } + } + + if (p->growfs >= 0) { + if (gpt_partition_type_knows_growfs(p->type_uuid)) + SET_FLAG(f, GPT_FLAG_GROWFS, p->growfs); + else { + char buffer[ID128_UUID_STRING_MAX]; + log_warning("Configured GrowFileSystem=%s for partition type '%s' that doesn't support it, ignoring.", + yes_no(p->growfs), + gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer)); + } + } + + return f; +} + static int context_mangle_partitions(Context *context) { Partition *p; int r; @@ -3323,7 +3363,6 @@ static int context_mangle_partitions(Context *context) { _cleanup_(fdisk_unref_partitionp) struct fdisk_partition *q = NULL; _cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL; char ids[ID128_UUID_STRING_MAX]; - uint64_t f; assert(!p->new_partition); assert(p->offset % 512 == 0); @@ -3371,19 +3410,8 @@ static int context_mangle_partitions(Context *context) { if (r < 0) return log_error_errno(r, "Failed to set partition label: %m"); - /* Merge the read only setting with the literal flags */ - f = p->gpt_flags; - if (p->read_only >= 0) { - if (gpt_partition_type_knows_read_only(p->type_uuid)) - SET_FLAG(f, GPT_FLAG_READ_ONLY, p->read_only); - else { - char buffer[ID128_UUID_STRING_MAX]; - log_warning("Configured ReadOnly=yes for partition type '%s' that doesn't support it, ignoring.", - gpt_partition_type_uuid_to_string_harder(p->type_uuid, buffer)); - } - } - - r = set_gpt_flags(q, f); + /* Merge the read only + growfs setting with the literal flags, and set them for the partition */ + r = set_gpt_flags(q, partition_merge_flags(p)); if (r < 0) return log_error_errno(r, "Failed to set GPT partition flags: %m"); diff --git a/src/partition/test-repart.sh b/src/partition/test-repart.sh index 8598a998875..525be8e56ad 100755 --- a/src/partition/test-repart.sh +++ b/src/partition/test-repart.sh @@ -65,9 +65,9 @@ device: $D/zzz unit: sectors first-lba: 2048 last-lba: 2097118 -$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first" -$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59" $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" EOF @@ -100,9 +100,9 @@ device: $D/zzz unit: sectors first-lba: 2048 last-lba: 2097118 -$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first" -$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59" $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" $D/zzz5 : start= 1908696, size= 188416, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label" EOF @@ -120,9 +120,9 @@ device: $D/zzz unit: sectors first-lba: 2048 last-lba: 4194270 -$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first" -$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59" $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" $D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label" EOF @@ -150,9 +150,9 @@ device: $D/zzz unit: sectors first-lba: 2048 last-lba: 6291422 -$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first" -$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59" $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" $D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label" $D/zzz6 : start= 4194264, size= 2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=2A1D97E1-D0A3-46CC-A26E-ADC643926617, name="block-copy" @@ -187,9 +187,9 @@ device: $D/zzz unit: sectors first-lba: 2048 last-lba: 6389726 -$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first" -$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64" -$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2" +$D/zzz1 : start= 2048, size= 591856, type=933AC7E1-2EB4-4F13-B844-0E14E2AEF915, uuid=A6005774-F558-4330-A8E5-D6D2C01C01D6, name="home-first", attrs="GUID:59" +$D/zzz2 : start= 593904, size= 591856, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=CE9C76EB-A8F1-40FF-813C-11DCA6C0A55B, name="root-x86-64", attrs="GUID:59" +$D/zzz3 : start= 1185760, size= 591864, type=4F68BCE3-E8CD-4DB1-96E7-FBCAF984B709, uuid=AC60A837-550C-43BD-B5C4-9CB73B884E79, name="root-x86-64-2", attrs="GUID:59" $D/zzz4 : start= 1777624, size= 131072, type=0657FD6D-A4AB-43C4-84E5-0933C84B4F4F, uuid=2AA78CDB-59C7-4173-AF11-C7453737A5D1, name="swap" $D/zzz5 : start= 1908696, size= 2285568, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=A0A1A2A3-A4A5-A6A7-A8A9-AAABACADAEAF, name="custom_label" $D/zzz6 : start= 4194264, size= 2097152, type=0FC63DAF-8483-4772-8E79-3D69D8477DE4, uuid=2A1D97E1-D0A3-46CC-A26E-ADC643926617, name="block-copy" diff --git a/src/shared/gpt.c b/src/shared/gpt.c index 69da6c72806..558b69c4879 100644 --- a/src/shared/gpt.c +++ b/src/shared/gpt.c @@ -163,3 +163,14 @@ bool gpt_partition_type_knows_read_only(sd_id128_t id) { gpt_partition_type_is_root_verity(id) || /* pretty much implied, but let's set the bit to make things really clear */ gpt_partition_type_is_usr_verity(id); /* ditto */ } + +bool gpt_partition_type_knows_growfs(sd_id128_t id) { + return gpt_partition_type_is_root(id) || + gpt_partition_type_is_usr(id) || + sd_id128_in_set(id, + GPT_HOME, + GPT_SRV, + GPT_VAR, + GPT_TMP, + GPT_XBOOTLDR); +} diff --git a/src/shared/gpt.h b/src/shared/gpt.h index a99417219d6..6581973793d 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -136,3 +136,4 @@ 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_knows_read_only(sd_id128_t id); +bool gpt_partition_type_knows_growfs(sd_id128_t id);