[syslinux] [PATCH] Add filesystem UUID to SYSAPPEND for FAT

Serj Kalichev serj.kalichev at gmail.com
Tue Nov 19 04:30:06 PST 2013


Filesystem UUID shows the partition we boot kernel from.
The kernel parameter has format like FSUUID=DA1A-0B2E.
The SYSAPPEND bit is 0x40000. Now the FAT only supports FSUUID.
The patch is based on 67aaaeeb228.

Signed-off-by: Serj Kalichev <serj.kalichev at gmail.com>
---
 com32/include/syslinux/sysappend.h |  1 +
 core/fs/btrfs/btrfs.c              |  3 ++-
 core/fs/ext2/ext2.c                |  1 +
 core/fs/fat/fat.c                  | 31 +++++++++++++++++++++++++++++++
 core/fs/fat/fat_fs.h               |  2 ++
 core/fs/fs.c                       | 12 ++++++++++++
 core/fs/iso9660/iso9660.c          |  1 +
 core/fs/ntfs/ntfs.c                |  1 +
 core/fs/pxe/pxe.c                  |  1 +
 core/fs/xfs/xfs.c                  |  1 +
 core/include/core.h                |  1 +
 core/include/fs.h                  |  4 ++++
 core/sysappend.c                   | 17 +++++++++++++++++
 13 files changed, 75 insertions(+), 1 deletion(-)

diff --git a/com32/include/syslinux/sysappend.h b/com32/include/syslinux/sysappend.h
index f243eab..1e2eb3a 100644
--- a/com32/include/syslinux/sysappend.h
+++ b/com32/include/syslinux/sysappend.h
@@ -53,6 +53,7 @@ enum syslinux_sysappend {
     SYSAPPEND_BIOSVENDOR,	/* BIOS vendor */
     SYSAPPEND_BIOSVERSION,	/* BIOS version string */
     SYSAPPEND_SYSFF,		/* System form factor */
+    SYSAPPEND_FSUUID,		/* Boot filesystem UUID */
     SYSAPPEND_MAX		/* Total number of strings */
 };
 
diff --git a/core/fs/btrfs/btrfs.c b/core/fs/btrfs/btrfs.c
index 16386cc..dfa9ad7 100644
--- a/core/fs/btrfs/btrfs.c
+++ b/core/fs/btrfs/btrfs.c
@@ -674,5 +674,6 @@ const struct fs_ops btrfs_fs_ops = {
     .next_extent   = btrfs_next_extent,
     .readdir       = btrfs_readdir,
     .chdir_start   = generic_chdir_start,
-    .open_config   = generic_open_config
+    .open_config   = generic_open_config,
+    .fs_uuid       = NULL,
 };
diff --git a/core/fs/ext2/ext2.c b/core/fs/ext2/ext2.c
index 957c60b..df0856f 100644
--- a/core/fs/ext2/ext2.c
+++ b/core/fs/ext2/ext2.c
@@ -336,4 +336,5 @@ const struct fs_ops ext2_fs_ops = {
     .readlink      = ext2_readlink,
     .readdir       = ext2_readdir,
     .next_extent   = ext2_next_extent,
+    .fs_uuid       = NULL,
 };
diff --git a/core/fs/fat/fat.c b/core/fs/fat/fat.c
index d7346ae..a718586 100644
--- a/core/fs/fat/fat.c
+++ b/core/fs/fat/fat.c
@@ -1,5 +1,6 @@
 #include <dprintf.h>
 #include <stdio.h>
+#include <ctype.h>
 #include <string.h>
 #include <sys/dirent.h>
 #include <cache.h>
@@ -777,6 +778,12 @@ static int vfat_fs_init(struct fs_info *fs)
     }
     sbi->clusters = clusters;
 
+    /* fs UUID - serial number */
+    if (FAT32 == sbi->fat_type)
+	sbi->uuid = fat.fat32.num_serial;
+    else
+	sbi->uuid = fat.fat12_16.num_serial;
+
     /* Initialize the cache */
     cache_init(fs->fs_dev, fs->block_shift);
 
@@ -811,6 +818,29 @@ static int vfat_copy_superblock(void *buf)
 	return 0;
 }
 
+#define FAT_UUID_LEN (4 + 1 + 4 + 1)
+static char *vfat_fs_uuid(struct fs_info *fs)
+{
+    char *uuid = NULL;
+    char *ptr;
+
+    uuid = malloc(FAT_UUID_LEN);
+    if (!uuid)
+	return NULL;
+
+    if (snprintf(uuid, FAT_UUID_LEN, "%04x-%04x",
+	          (uint16_t)(FAT_SB(fs)->uuid >> 16),
+	          (uint16_t)FAT_SB(fs)->uuid) < 0) {
+	free(uuid);
+	return NULL;
+    }
+
+    for (ptr = uuid; ptr && *ptr; ptr++)
+	*ptr = toupper(*ptr);
+
+    return uuid;
+}
+
 const struct fs_ops vfat_fs_ops = {
     .fs_name       = "vfat",
     .fs_flags      = FS_USEMEM | FS_THISIND,
@@ -826,4 +856,5 @@ const struct fs_ops vfat_fs_ops = {
     .iget          = vfat_iget,
     .next_extent   = fat_next_extent,
     .copy_super    = vfat_copy_superblock,
+    .fs_uuid       = vfat_fs_uuid,
 };
diff --git a/core/fs/fat/fat_fs.h b/core/fs/fat/fat_fs.h
index 7ea3db8..5c26d69 100644
--- a/core/fs/fat/fat_fs.h
+++ b/core/fs/fat/fat_fs.h
@@ -98,6 +98,8 @@ struct fat_sb_info {
 	int      clust_size;
 
 	int      fat_type;
+
+	uint32_t uuid;             /* fs UUID */
 } __attribute__ ((packed));
 
 struct fat_dir_entry {
diff --git a/core/fs/fs.c b/core/fs/fs.c
index 8c1feea..6965d1d 100644
--- a/core/fs/fs.c
+++ b/core/fs/fs.c
@@ -5,6 +5,7 @@
 #include <unistd.h>
 #include <fcntl.h>
 #include <dprintf.h>
+#include <syslinux/sysappend.h>
 #include "core.h"
 #include "dev.h"
 #include "fs.h"
@@ -374,6 +375,13 @@ __export void close_file(uint16_t handle)
     }
 }
 
+__export char *fs_uuid(void)
+{
+    if (!this_fs || !this_fs->fs_ops || !this_fs->fs_ops->fs_uuid)
+	return NULL;
+    return this_fs->fs_ops->fs_uuid(this_fs);
+}
+
 /*
  * it will do:
  *    initialize the memory management function;
@@ -440,4 +448,8 @@ void fs_init(const struct fs_ops **ops, void *priv)
 
     SectorShift = fs.sector_shift;
     SectorSize  = fs.sector_size;
+
+    /* Add FSUUID=... string to cmdline */
+    sysappend_set_fs_uuid();
+
 }
diff --git a/core/fs/iso9660/iso9660.c b/core/fs/iso9660/iso9660.c
index fe58a5b..4756cf7 100644
--- a/core/fs/iso9660/iso9660.c
+++ b/core/fs/iso9660/iso9660.c
@@ -299,4 +299,5 @@ const struct fs_ops iso_fs_ops = {
     .iget          = iso_iget,
     .readdir       = iso_readdir,
     .next_extent   = no_next_extent,
+    .fs_uuid       = NULL,
 };
diff --git a/core/fs/ntfs/ntfs.c b/core/fs/ntfs/ntfs.c
index f54df7e..6a983de 100644
--- a/core/fs/ntfs/ntfs.c
+++ b/core/fs/ntfs/ntfs.c
@@ -1385,4 +1385,5 @@ const struct fs_ops ntfs_fs_ops = {
     .iget_root      = ntfs_iget_root,
     .iget           = ntfs_iget,
     .next_extent    = ntfs_next_extent,
+    .fs_uuid        = NULL,
 };
diff --git a/core/fs/pxe/pxe.c b/core/fs/pxe/pxe.c
index 4de4dbf..5efcd9c 100644
--- a/core/fs/pxe/pxe.c
+++ b/core/fs/pxe/pxe.c
@@ -695,4 +695,5 @@ const struct fs_ops pxe_fs_ops = {
     .chdir_start   = pxe_chdir_start,
     .open_config   = pxe_open_config,
     .readdir	   = pxe_readdir,
+    .fs_uuid       = NULL,
 };
diff --git a/core/fs/xfs/xfs.c b/core/fs/xfs/xfs.c
index b6a396a..e42e952 100644
--- a/core/fs/xfs/xfs.c
+++ b/core/fs/xfs/xfs.c
@@ -428,4 +428,5 @@ const struct fs_ops xfs_fs_ops = {
     .iget		= xfs_iget,
     .next_extent	= xfs_next_extent,
     .readlink		= xfs_readlink,
+    .fs_uuid            = NULL,
 };
diff --git a/core/include/core.h b/core/include/core.h
index 127ac65..4af037e 100644
--- a/core/include/core.h
+++ b/core/include/core.h
@@ -81,6 +81,7 @@ extern void print_sysappend(void);
 extern const char *sysappend_strings[SYSAPPEND_MAX];
 extern uint32_t SysAppends;
 extern void sysappend_set_uuid(const uint8_t *uuid);
+extern void sysappend_set_fs_uuid(void);
 
 void __cdecl core_intcall(uint8_t, const com32sys_t *, com32sys_t *);
 void __cdecl core_farcall(uint32_t, const com32sys_t *, com32sys_t *);
diff --git a/core/include/fs.h b/core/include/fs.h
index 31ef315..22fd6bf 100644
--- a/core/include/fs.h
+++ b/core/include/fs.h
@@ -73,6 +73,9 @@ struct fs_ops {
     int      (*next_extent)(struct inode *, uint32_t);
 
     int      (*copy_super)(void *buf);
+
+    char *   (*fs_uuid)(struct fs_info *);
+
 };
 
 /*
@@ -205,6 +208,7 @@ void pm_open_file(com32sys_t *);
 void close_file(uint16_t handle);
 void pm_close_file(com32sys_t *);
 int open_config(void);
+char *fs_uuid(void);
 
 extern uint16_t SectorShift;
 
diff --git a/core/sysappend.c b/core/sysappend.c
index 890fb63..5c3f650 100644
--- a/core/sysappend.c
+++ b/core/sysappend.c
@@ -14,6 +14,7 @@
 #include <stdio.h>
 #include <stdbool.h>
 #include "core.h"
+#include "fs.h"
 
 /*
  * sysappend.c
@@ -106,6 +107,22 @@ void sysappend_set_uuid(const uint8_t *src)
     sysappend_strings[SYSAPPEND_SYSUUID] = sysuuid_str;
 }
 
+void sysappend_set_fs_uuid(void)
+{
+    static char fsuuid_str[7+32+7+1] = "FSUUID=";
+    char *uuid;
+
+    uuid = fs_uuid();
+    if (!uuid)
+	return;
+
+    snprintf(fsuuid_str + 7, sizeof(fsuuid_str) - 7, "%s", uuid);
+    fsuuid_str[sizeof(fsuuid_str) - 1] = '\0';
+    free(uuid);
+
+    sysappend_strings[SYSAPPEND_FSUUID] = fsuuid_str;
+}
+
 /*
  * Print the sysappend strings, in order
  */
-- 
1.8.1.2



More information about the Syslinux mailing list