Greetings,

systemd-repart MountPoint fails to generate a correct fstab entry for
esp partitions.  It generates a standard partition UUID which does not
work for FAT file systems - a FAT volume ID must be used analogous to
what is generated for vfat in mkfs-util.c:make_filesystem().  The FAT
volume ID is in the form of 32 bits of uppercase hex digits with a
dash "-" between the high and low 16 bits: XXXX-XXXX (where X
represents an uppercase hex digit).

Attached is a patch I have been using with systemd v257 to provide
correct behavior.
Use the PARTUUID to mount ESP partitions

The ESP vfat partition fails to mount because the UUID generated by repart
matches neither the vfat serial number (although it's somewhat comparable) nor
the partition UUID.  The vfat serial number is quite short compared to a UUID
and may not be sufficiently long for use in mounting.  This generates the fstab
entry for the ESP partition as a FAT volume ID in the form of XXXX-XXXX where X
is an uppercase hex digit.

Thayne Harbaugh <tha...@mastodonlabs.com>

Index: systemd.git/src/repart/repart.c
===================================================================
--- systemd.git.orig/src/repart/repart.c
+++ systemd.git/src/repart/repart.c
@@ -7285,7 +7285,13 @@ static int context_fstab(Context *contex
                 if (!need_fstab_one(p))
                         continue;
 
-                what = strjoin("UUID=", SD_ID128_TO_UUID_STRING(p->fs_uuid));
+                switch(p->type.designator) {
+                case PARTITION_ESP:
+                        what = strjoin("UUID=", SD_ID128_TO_FATUUID_STRING(p->fs_uuid));
+                        break;
+                default:
+                        what = strjoin("UUID=", SD_ID128_TO_UUID_STRING(p->fs_uuid));
+                }
                 if (!what)
                         return log_oom();
 
Index: systemd.git/src/systemd/sd-id128.h
===================================================================
--- systemd.git.orig/src/systemd/sd-id128.h
+++ systemd.git/src/systemd/sd-id128.h
@@ -44,6 +44,11 @@ int sd_id128_from_string(const char *s,
 #define SD_ID128_TO_STRING(id) sd_id128_to_string((id), (char[SD_ID128_STRING_MAX]) {})
 #define SD_ID128_TO_UUID_STRING(id) sd_id128_to_uuid_string((id), (char[SD_ID128_UUID_STRING_MAX]) {})
 
+char* sd_id128_to_fatid_string(sd_id128_t id, char fidstr[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]);
+char* sd_id128_to_fatuuid_string(sd_id128_t id, char fidstr[_SD_ARRAY_STATIC SD_ID128_UUID_STRING_MAX]);
+
+#define SD_ID128_TO_FATUUID_STRING(id) sd_id128_to_fatuuid_string((id), (char[SD_ID128_UUID_STRING_MAX]) {})
+
 int sd_id128_randomize(sd_id128_t *ret);
 
 int sd_id128_get_machine(sd_id128_t *ret);
Index: systemd.git/src/libsystemd/sd-id128/sd-id128.c
===================================================================
--- systemd.git.orig/src/libsystemd/sd-id128/sd-id128.c
+++ systemd.git/src/libsystemd/sd-id128/sd-id128.c
@@ -108,6 +108,41 @@ _public_ int sd_id128_from_string(const
         return 0;
 }
 
+_public_ char *sd_id128_to_fatid_string(sd_id128_t id, char fidstr[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]) {
+        assert_return(fidstr, NULL);
+
+        snprintf(fidstr, SD_ID128_STRING_MAX, "%08" PRIX32,
+                ((uint32_t) id.bytes[0] << 24) |
+                ((uint32_t) id.bytes[1] << 16) |
+                ((uint32_t) id.bytes[2] << 8) |
+                ((uint32_t) id.bytes[3])  /* Take first 4 bytes of UUID */
+        );
+
+        fidstr[8] = 0;
+
+        return fidstr;
+}
+
+_public_ char *sd_id128_to_fatuuid_string(sd_id128_t id, char fidstr[_SD_ARRAY_STATIC SD_ID128_UUID_STRING_MAX]) {
+        assert_return(fidstr, NULL);
+
+        /* Similar to sd_id128_to_fatid_string() but formats the result as UUID instead of plain hex chars */
+
+        snprintf(fidstr, SD_ID128_STRING_MAX, "%04" PRIX16,
+                ((uint32_t) id.bytes[0] << 8) |
+                ((uint32_t) id.bytes[1])  /* Take first 2 bytes of UUID */
+        );
+        fidstr[4] = '-';
+        snprintf(fidstr+5, SD_ID128_STRING_MAX - 5, "%04" PRIX16,
+                ((uint32_t) id.bytes[2] << 8) |
+                ((uint32_t) id.bytes[3])  /* Take next 2 bytes of UUID */
+        );
+
+        fidstr[9] = 0;
+
+        return fidstr;
+}
+
 _public_ int sd_id128_string_equal(const char *s, sd_id128_t id) {
         sd_id128_t parsed;
         int r;
Index: systemd.git/src/libsystemd/libsystemd.sym
===================================================================
--- systemd.git.orig/src/libsystemd/libsystemd.sym
+++ systemd.git/src/libsystemd/libsystemd.sym
@@ -1058,4 +1058,6 @@ global:
         sd_device_monitor_get_events;
         sd_device_monitor_get_timeout;
         sd_device_monitor_receive;
+        sd_id128_to_fatid_string;
+        sd_id128_to_fatuuid_string;
 } LIBSYSTEMD_256;

Reply via email to