From: Lennart Poettering Date: Wed, 21 Apr 2021 14:17:44 +0000 (+0200) Subject: dissect: look for new GPT partition flag marking partitions for growing X-Git-Tag: v249-rc1~279^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=de98f63140fd55d8639011c25a44b7b10fcccf29;p=thirdparty%2Fsystemd.git dissect: look for new GPT partition flag marking partitions for growing systemd-repart can grow partitions dynamically at boot, but it won't grow the file systems inside them. In /etc/fstab you can request that via x-systemd.growfs. So far we didn't have a nice scheme for images with GPT auto-discovery however, and that meant in particular in tools such as systemd-nspawn the file systems couldn't be grown automatically. Let's address this: let's define a new GPT partition flag that can be set for our partition types. If set it indicates that the file system should be grown to the partition size on mount. This commit adds the flag and adds code to discover it when dissecting images. There's no code yet to actually do something about it. --- diff --git a/src/shared/dissect-image.c b/src/shared/dissect-image.c index b4250144573..37c27d41604 100644 --- a/src/shared/dissect-image.c +++ b/src/shared/dissect-image.c @@ -543,7 +543,8 @@ int dissect_image( sd_id128_t usr_uuid = SD_ID128_NULL, usr_verity_uuid = SD_ID128_NULL; #endif bool is_gpt, is_mbr, multiple_generic = false, - generic_rw = false; /* initialize to appease gcc */ + generic_rw = false, /* initialize to appease gcc */ + generic_growfs = false; _cleanup_(sd_device_unrefp) sd_device *d = NULL; _cleanup_(dissected_image_unrefp) DissectedImage *m = NULL; _cleanup_(blkid_free_probep) blkid_probe b = NULL; @@ -804,7 +805,7 @@ int dissect_image( int architecture = _ARCHITECTURE_INVALID; const char *stype, *sid, *fstype = NULL, *label; sd_id128_t type_id, id; - bool rw = true; + bool rw = true, growfs = false; sid = blkid_partition_get_uuid(pp); if (!sid) @@ -822,23 +823,25 @@ int dissect_image( if (sd_id128_equal(type_id, GPT_HOME)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; designator = PARTITION_HOME; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_SRV)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; designator = PARTITION_SRV; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_ESP)) { @@ -855,18 +858,19 @@ int dissect_image( } else if (sd_id128_equal(type_id, GPT_XBOOTLDR)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; designator = PARTITION_XBOOTLDR; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } #ifdef GPT_ROOT_NATIVE else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; @@ -878,6 +882,7 @@ int dissect_image( designator = PARTITION_ROOT; architecture = native_architecture(); rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_ROOT_NATIVE_VERITY)) { @@ -901,7 +906,7 @@ int dissect_image( #ifdef GPT_ROOT_SECONDARY else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; @@ -913,6 +918,7 @@ int dissect_image( designator = PARTITION_ROOT_SECONDARY; architecture = SECONDARY_ARCHITECTURE; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_ROOT_SECONDARY_VERITY)) { @@ -936,7 +942,7 @@ int dissect_image( #ifdef GPT_USR_NATIVE else if (sd_id128_equal(type_id, GPT_USR_NATIVE)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; @@ -948,6 +954,7 @@ int dissect_image( designator = PARTITION_USR; architecture = native_architecture(); rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_USR_NATIVE_VERITY)) { @@ -971,7 +978,7 @@ int dissect_image( #ifdef GPT_USR_SECONDARY else if (sd_id128_equal(type_id, GPT_USR_SECONDARY)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; @@ -983,6 +990,7 @@ int dissect_image( designator = PARTITION_USR_SECONDARY; architecture = SECONDARY_ARCHITECTURE; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_USR_SECONDARY_VERITY)) { @@ -1015,7 +1023,7 @@ int dissect_image( } else if (sd_id128_equal(type_id, GPT_LINUX_GENERIC)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; @@ -1025,6 +1033,7 @@ int dissect_image( else { generic_nr = nr; generic_rw = !(pflags & GPT_FLAG_READ_ONLY); + generic_growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); generic_uuid = id; generic_node = strdup(node); if (!generic_node) @@ -1033,17 +1042,18 @@ int dissect_image( } else if (sd_id128_equal(type_id, GPT_TMP)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; designator = PARTITION_TMP; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } else if (sd_id128_equal(type_id, GPT_VAR)) { - check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY); + check_partition_flags(node, pflags, GPT_FLAG_NO_AUTO|GPT_FLAG_READ_ONLY|GPT_FLAG_GROWFS); if (pflags & GPT_FLAG_NO_AUTO) continue; @@ -1071,6 +1081,7 @@ int dissect_image( designator = PARTITION_VAR; rw = !(pflags & GPT_FLAG_READ_ONLY); + growfs = FLAGS_SET(pflags, GPT_FLAG_GROWFS); } if (designator != _PARTITION_DESIGNATOR_INVALID) { @@ -1117,6 +1128,7 @@ int dissect_image( .found = true, .partno = nr, .rw = rw, + .growfs = growfs, .architecture = architecture, .node = TAKE_PTR(n), .fstype = TAKE_PTR(t), @@ -1140,6 +1152,7 @@ int dissect_image( else { generic_nr = nr; generic_rw = true; + generic_growfs = false; generic_node = strdup(node); if (!generic_node) return -ENOMEM; @@ -1175,6 +1188,7 @@ int dissect_image( .found = true, .partno = nr, .rw = true, + .growfs = false, .architecture = _ARCHITECTURE_INVALID, .node = TAKE_PTR(n), .uuid = id, @@ -1263,6 +1277,7 @@ int dissect_image( m->partitions[PARTITION_ROOT] = (DissectedPartition) { .found = true, .rw = generic_rw, + .growfs = generic_growfs, .partno = generic_nr, .architecture = _ARCHITECTURE_INVALID, .node = TAKE_PTR(generic_node), @@ -1325,6 +1340,9 @@ int dissect_image( if (p->fstype && fstype_is_ro(p->fstype)) p->rw = false; + + if (!p->rw) + p->growfs = false; } *ret = TAKE_PTR(m); diff --git a/src/shared/dissect-image.h b/src/shared/dissect-image.h index 88106ee4f35..822380323ab 100644 --- a/src/shared/dissect-image.h +++ b/src/shared/dissect-image.h @@ -18,6 +18,7 @@ typedef struct VeritySettings VeritySettings; struct DissectedPartition { bool found:1; bool rw:1; + bool growfs:1; int partno; /* -1 if there was no partition and the images contains a file system directly */ int architecture; /* Intended architecture: either native, secondary or unset (-1). */ sd_id128_t uuid; /* Partition entry UUID as reported by the GPT */ diff --git a/src/shared/gpt.h b/src/shared/gpt.h index f3a74813f07..a99417219d6 100644 --- a/src/shared/gpt.h +++ b/src/shared/gpt.h @@ -112,7 +112,8 @@ * auto-discovery. These happen to be identical to what Microsoft defines for its own Basic Data Partitions, * but that's just because we saw no point in defining any other values here. */ #define GPT_FLAG_READ_ONLY (1ULL << 60) -#define GPT_FLAG_NO_AUTO (1ULL << 63) +#define GPT_FLAG_NO_AUTO (1ULL << 63) +#define GPT_FLAG_GROWFS (1ULL << 59) const char *gpt_partition_type_uuid_to_string(sd_id128_t id); const char *gpt_partition_type_uuid_to_string_harder(