[parted-devel] [PATCH] support read-only and no-auto flags used by systemd-gpt-auto-generator

Arvin Schnell aschnell at suse.com
Wed Sep 30 07:02:04 BST 2020


Hi,

systemd-gpt-auto-generator can mount partitions automatically
without an fstab entry. This can be controlled by some flags in
the GPT, among them READ_ONLY and NO_AUTO (see [1]). This patch
adds supports for those two flags.

Thanks,
  Arvin

[1] https://www.freedesktop.org/software/systemd/man/systemd-gpt-auto-generator.html

---
 doc/C/parted.8                   |  3 ++-
 doc/parted.texi                  |  8 ++++++
 include/parted/disk.in.h         |  6 +++--
 libparted/disk.c                 |  4 +++
 libparted/labels/gpt.c           | 42 +++++++++++++++++++++++++----
 tests/Makefile.am                |  1 +
 tests/t3320-read_only-no_auto.sh | 46 ++++++++++++++++++++++++++++++++
 7 files changed, 102 insertions(+), 8 deletions(-)
 create mode 100755 tests/t3320-read_only-no_auto.sh

diff --git a/doc/C/parted.8 b/doc/C/parted.8
index 297c39a..c3d634f 100644
--- a/doc/C/parted.8
+++ b/doc/C/parted.8
@@ -112,7 +112,8 @@ or an LVM logical volume if necessary.
 .B set \fIpartition\fP \fIflag\fP \fIstate\fP
 Change the state of the \fIflag\fP on \fIpartition\fP to \fIstate\fP.
 Supported flags are: "boot", "root", "swap", "hidden", "raid", "lvm", "lba",
-"legacy_boot", "irst", "msftres", "esp", "chromeos_kernel", "bls_boot" and "palo".
+"legacy_boot", "irst", "msftres", "esp", "chromeos_kernel", "bls_boot", "palo",
+"read_only" and "no_auto".
 \fIstate\fP should be either "on" or "off".
 .TP
 .B unit \fIunit\fP
diff --git a/doc/parted.texi b/doc/parted.texi
index 213fc84..b9b1d30 100644
--- a/doc/parted.texi
+++ b/doc/parted.texi
@@ -918,6 +918,14 @@ as a PReP boot partition on PowerPC PReP or IBM RS6K/CHRP hardware.
 (MS-DOS) - Enable this to indicate that a partition can be used
 as a diagnostics / recovery partition.
 
+ at item read_only
+(GPT) - this flags tells systemd-gpt-auto-generator to mount the
+partition read-only.
+
+ at item no_auto
+(GPT) - this flags tells systemd-gpt-auto-generator to not automatically
+mount the partition.
+
 @end table
 
 The print command displays all enabled flags for each partition.
diff --git a/include/parted/disk.in.h b/include/parted/disk.in.h
index fadb995..4aa8af6 100644
--- a/include/parted/disk.in.h
+++ b/include/parted/disk.in.h
@@ -77,10 +77,12 @@ enum _PedPartitionFlag {
         PED_PARTITION_IRST=17,
         PED_PARTITION_ESP=18,
         PED_PARTITION_CHROMEOS_KERNEL=19,
-        PED_PARTITION_BLS_BOOT=20
+        PED_PARTITION_BLS_BOOT=20,
+        PED_PARTITION_READ_ONLY=21,
+        PED_PARTITION_NO_AUTO=22
 };
 #define PED_PARTITION_FIRST_FLAG        PED_PARTITION_BOOT
-#define PED_PARTITION_LAST_FLAG         PED_PARTITION_BLS_BOOT
+#define PED_PARTITION_LAST_FLAG         PED_PARTITION_NO_AUTO
 
 enum _PedDiskTypeFeature {
         PED_DISK_TYPE_EXTENDED=1,       /**< supports extended partitions */
diff --git a/libparted/disk.c b/libparted/disk.c
index 099837b..31e5a0e 100644
--- a/libparted/disk.c
+++ b/libparted/disk.c
@@ -2411,6 +2411,10 @@ ped_partition_flag_get_name (PedPartitionFlag flag)
                 return N_("chromeos_kernel");
 	case PED_PARTITION_BLS_BOOT:
 		return N_("bls_boot");
+	case PED_PARTITION_READ_ONLY:
+		return N_("read_only");
+	case PED_PARTITION_NO_AUTO:
+		return N_("no_auto");
 
 	default:
 		ped_exception_throw (
diff --git a/libparted/labels/gpt.c b/libparted/labels/gpt.c
index 93f7add..3e636f0 100644
--- a/libparted/labels/gpt.c
+++ b/libparted/labels/gpt.c
@@ -190,16 +190,22 @@ struct __attribute__ ((packed)) _GuidPartitionEntryAttributes_t
   uint64_t RequiredToFunction:1;
   uint64_t NoBlockIOProtocol:1;
   uint64_t LegacyBIOSBootable:1;
-  uint64_t Reserved:45;
-  uint64_t GuidSpecific:16;
+  uint64_t Reserved1:45;
+  uint64_t GuidSpecific:12;
+  uint64_t ReadOnly:1;
+  uint64_t Reserved2:2;
+  uint64_t NoAuto:1;
 #else
 #       warning "Using crippled partition entry type"
   uint32_t RequiredToFunction:1;
   uint32_t NoBlockIOProtocol:1;
   uint32_t LegacyBIOSBootable:1;
-  uint32_t Reserved:30;
-  uint32_t LOST:5;
-  uint32_t GuidSpecific:16;
+  uint32_t Reserved1:29;
+  uint32_t Reserved2:16;
+  uint32_t GuidSpecific:12;
+  uint32_t ReadOnly:1;
+  uint32_t Reserved3:2;
+  uint32_t NoAuto:1;
 #endif
 };
 
@@ -313,6 +319,8 @@ typedef struct _GPTPartitionData
   int irst;
   int chromeos_kernel;
   int bls_boot;
+  int read_only;
+  int no_auto;
 } GPTPartitionData;
 
 static PedDiskType gpt_disk_type;
@@ -838,12 +846,18 @@ _parse_part_entry (PedDisk *disk, GuidPartitionEntry_t *pte)
     = gpt_part_data->irst
     = gpt_part_data->chromeos_kernel
     = gpt_part_data->bls_boot
+    = gpt_part_data->read_only
+    = gpt_part_data->no_auto
     = gpt_part_data->bios_grub = gpt_part_data->atvrecv = 0;
 
   if (pte->Attributes.RequiredToFunction & 0x1)
     gpt_part_data->hidden = 1;
   if (pte->Attributes.LegacyBIOSBootable & 0x1)
     gpt_part_data->legacy_boot = 1;
+  if (pte->Attributes.ReadOnly & 0x1)
+    gpt_part_data->read_only = 1;
+  if (pte->Attributes.NoAuto & 0x1)
+    gpt_part_data->no_auto = 1;
 
   if (!guid_cmp (gpt_part_data->type, PARTITION_SYSTEM_GUID))
     gpt_part_data->boot = 1;
@@ -1247,6 +1261,10 @@ _partition_generate_part_entry (PedPartition *part, GuidPartitionEntry_t *pte)
     pte->Attributes.RequiredToFunction = 1;
   if (gpt_part_data->legacy_boot)
     pte->Attributes.LegacyBIOSBootable = 1;
+  if (gpt_part_data->read_only)
+    pte->Attributes.ReadOnly = 1;
+  if (gpt_part_data->no_auto)
+    pte->Attributes.NoAuto = 1;
 
   for (i = 0; i < 36; i++)
     pte->PartitionName[i] = gpt_part_data->name[i];
@@ -1395,6 +1413,8 @@ gpt_partition_new (const PedDisk *disk,
   gpt_part_data->irst = 0;
   gpt_part_data->chromeos_kernel = 0;
   gpt_part_data->bls_boot = 0;
+  gpt_part_data->read_only = 0;
+  gpt_part_data->no_auto = 0;
   uuid_generate ((unsigned char *) &gpt_part_data->uuid);
   swap_uuid_and_efi_guid (&gpt_part_data->uuid);
   memset (gpt_part_data->name, 0, sizeof gpt_part_data->name);
@@ -1912,6 +1932,12 @@ gpt_partition_set_flag (PedPartition *part, PedPartitionFlag flag, int state)
     case PED_PARTITION_LEGACY_BOOT:
       gpt_part_data->legacy_boot = state;
       return 1;
+    case PED_PARTITION_READ_ONLY:
+      gpt_part_data->read_only = state;
+      return 1;
+    case PED_PARTITION_NO_AUTO:
+      gpt_part_data->no_auto = state;
+      return 1;
     case PED_PARTITION_ROOT:
     case PED_PARTITION_LBA:
     default:
@@ -1958,6 +1984,10 @@ gpt_partition_get_flag (const PedPartition *part, PedPartitionFlag flag)
       return gpt_part_data->irst;
     case PED_PARTITION_BLS_BOOT:
       return gpt_part_data->bls_boot;
+    case PED_PARTITION_READ_ONLY:
+      return gpt_part_data->read_only;
+    case PED_PARTITION_NO_AUTO:
+      return gpt_part_data->no_auto;
     case PED_PARTITION_SWAP:
 	return gpt_part_data->swap;
     case PED_PARTITION_CHROMEOS_KERNEL:
@@ -1993,6 +2023,8 @@ gpt_partition_is_flag_available (const PedPartition *part,
     case PED_PARTITION_ESP:
     case PED_PARTITION_CHROMEOS_KERNEL:
     case PED_PARTITION_BLS_BOOT:
+    case PED_PARTITION_READ_ONLY:
+    case PED_PARTITION_NO_AUTO:
       return 1;
     case PED_PARTITION_ROOT:
     case PED_PARTITION_LBA:
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 0d7c022..ce16448 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -58,6 +58,7 @@ TESTS = \
   t3200-type-change.sh \
   t3300-palo-prep.sh \
   t3310-flags.sh \
+  t3320-read_only-no_auto.sh \
   t3400-whole-disk-FAT-partition.sh \
   t4000-sun-raid-type.sh \
   t4001-sun-vtoc.sh \
diff --git a/tests/t3320-read_only-no_auto.sh b/tests/t3320-read_only-no_auto.sh
new file mode 100755
index 0000000..53ef94b
--- /dev/null
+++ b/tests/t3320-read_only-no_auto.sh
@@ -0,0 +1,46 @@
+#!/bin/sh
+# Ensure that read_only and no_auto flags work properly.
+
+# Copyright (C) 2020 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+. "${srcdir=.}/init.sh"; path_prepend_ ../parted
+ss=$sector_size_
+
+cat > exp <<EOF || framework_failure
+1:2048s:4095s:2048s:ext4:test:read_only;
+1:2048s:4095s:2048s:ext4:test:read_only, no_auto;
+1:2048s:4095s:2048s:ext4:test:no_auto;
+1:2048s:4095s:2048s:ext4:test:;
+EOF
+
+dev=dev-file
+
+n_sectors=5000
+dd if=/dev/null of=$dev bs=$ss seek=$n_sectors || fail=1
+
+parted -m -s $dev mklabel gpt \
+  mkpart test ext4 $((1*2048))s $((2*2048-1))s unit s \
+  set 1 read_only on print \
+  set 1 no_auto on print \
+  set 1 read_only off print \
+  set 1 no_auto off print \
+    > out 2> err || fail=1
+
+grep -E '^1:2048s:4095s:2048s:ext4:test:.*;$' out > k; mv k out
+
+compare exp out || fail=1
+
+Exit $fail
-- 
Arvin Schnell, <aschnell at suse.com>
Senior Software Engineer, Research & Development

SUSE Software Solutions Germany GmbH
Maxfeldstraße 5
90409 Nürnberg
Germany

(HRB 36809, AG Nürnberg)

Geschäftsführer: Felix Imendörffer



More information about the parted-devel mailing list