]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
dissect: look for new GPT partition flag marking partitions for growing
authorLennart Poettering <lennart@poettering.net>
Wed, 21 Apr 2021 14:17:44 +0000 (16:17 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 23 Apr 2021 15:55:45 +0000 (17:55 +0200)
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.

src/shared/dissect-image.c
src/shared/dissect-image.h
src/shared/gpt.h

index b42501445738bf74812db78b479772d16f77c099..37c27d41604f6ad86f2d1ccfa8e514cbf559d676 100644 (file)
@@ -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);
index 88106ee4f35ca932c5d4b43a285eaf60cdd56031..822380323ab661c9cb2b48a43ade8975e7e80117 100644 (file)
@@ -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 */
index f3a74813f072c601db663206b62620143be42872..a99417219d69484101723647038b1805d6ce0791 100644 (file)
  * 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(