]> git.ipfire.org Git - thirdparty/grub.git/commitdiff
2008-06-26 Robert Millan <rmh@aybabtu.com>
authorrobertmh <robertmh@localhost>
Thu, 26 Jun 2008 14:26:07 +0000 (14:26 +0000)
committerrobertmh <robertmh@localhost>
Thu, 26 Jun 2008 14:26:07 +0000 (14:26 +0000)
        * disk/fs_uuid.c: New file.
        * conf/common.rmk (pkglib_MODULES): Add `fs_uuid.mod'.
        (fs_uuid_mod_SOURCES, fs_uuid_mod_CFLAGS)
        (fs_uuid_mod_LDFLAGS): New variables.
        * include/grub/disk.h (grub_disk_dev_id): Add
        `GRUB_DISK_DEVICE_UUID_ID'.
        * kern/disk.c (grub_disk_dev_iterate): Allow disk devices not to
        implement iterate().

ChangeLog
conf/common.mk
conf/common.rmk
disk/fs_uuid.c [new file with mode: 0644]
include/grub/disk.h
kern/disk.c

index d5aa52455e306c73db164107956bce06257abc8d..d8a5674ea6bbcb8e81afb705a94919ab7909d650 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2008-06-26  Robert Millan  <rmh@aybabtu.com>
+
+       * disk/fs_uuid.c: New file.
+       * conf/common.rmk (pkglib_MODULES): Add `fs_uuid.mod'.
+       (fs_uuid_mod_SOURCES, fs_uuid_mod_CFLAGS)
+       (fs_uuid_mod_LDFLAGS): New variables.
+       * include/grub/disk.h (grub_disk_dev_id): Add
+       `GRUB_DISK_DEVICE_UUID_ID'.
+       * kern/disk.c (grub_disk_dev_iterate): Allow disk devices not to
+       implement iterate().
+
 2008-06-26  Robert Millan  <rmh@aybabtu.com>
 
        * util/grub.d/10_linux.in: Avoid passing UUIDs to Linux when either
index 0b8cacf663b409bfbfc620a9d066c435c85d792c..9228f1cbfad8218be0e38a22f41dcf11a28881c9 100644 (file)
@@ -1938,7 +1938,7 @@ lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
 # Commands.
 pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod       \
        cmp.mod cat.mod help.mod font.mod search.mod            \
-       loopback.mod configfile.mod echo.mod                    \
+       loopback.mod fs_uuid.mod configfile.mod echo.mod        \
        terminfo.mod test.mod blocklist.mod hexdump.mod         \
        read.mod sleep.mod
 
@@ -2614,6 +2614,62 @@ partmap-loopback_mod-disk_loopback.lst: disk/loopback.c $(disk/loopback.c_DEPEND
 loopback_mod_CFLAGS = $(COMMON_CFLAGS)
 loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For fs_uuid.mod
+fs_uuid_mod_SOURCES = disk/fs_uuid.c
+CLEANFILES += fs_uuid.mod mod-fs_uuid.o mod-fs_uuid.c pre-fs_uuid.o fs_uuid_mod-disk_fs_uuid.o und-fs_uuid.lst
+ifneq ($(fs_uuid_mod_EXPORTS),no)
+CLEANFILES += def-fs_uuid.lst
+DEFSYMFILES += def-fs_uuid.lst
+endif
+MOSTLYCLEANFILES += fs_uuid_mod-disk_fs_uuid.d
+UNDSYMFILES += und-fs_uuid.lst
+
+fs_uuid.mod: pre-fs_uuid.o mod-fs_uuid.o
+       -rm -f $@
+       $(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ $^
+       $(STRIP) --strip-unneeded -K grub_mod_init -K grub_mod_fini -R .note -R .comment $@
+
+pre-fs_uuid.o: $(fs_uuid_mod_DEPENDENCIES) fs_uuid_mod-disk_fs_uuid.o
+       -rm -f $@
+       $(TARGET_CC) $(fs_uuid_mod_LDFLAGS) $(TARGET_LDFLAGS) -Wl,-r,-d -o $@ fs_uuid_mod-disk_fs_uuid.o
+
+mod-fs_uuid.o: mod-fs_uuid.c
+       $(TARGET_CC) $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -c -o $@ $<
+
+mod-fs_uuid.c: moddep.lst genmodsrc.sh
+       sh $(srcdir)/genmodsrc.sh 'fs_uuid' $< > $@ || (rm -f $@; exit 1)
+
+ifneq ($(fs_uuid_mod_EXPORTS),no)
+def-fs_uuid.lst: pre-fs_uuid.o
+       $(NM) -g --defined-only -P -p $< | sed 's/^\([^ ]*\).*/\1 fs_uuid/' > $@
+endif
+
+und-fs_uuid.lst: pre-fs_uuid.o
+       echo 'fs_uuid' > $@
+       $(NM) -u -P -p $< | cut -f1 -d' ' >> $@
+
+fs_uuid_mod-disk_fs_uuid.o: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES)
+       $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS)  $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -MD -c -o $@ $<
+-include fs_uuid_mod-disk_fs_uuid.d
+
+CLEANFILES += cmd-fs_uuid_mod-disk_fs_uuid.lst fs-fs_uuid_mod-disk_fs_uuid.lst partmap-fs_uuid_mod-disk_fs_uuid.lst
+COMMANDFILES += cmd-fs_uuid_mod-disk_fs_uuid.lst
+FSFILES += fs-fs_uuid_mod-disk_fs_uuid.lst
+PARTMAPFILES += partmap-fs_uuid_mod-disk_fs_uuid.lst
+
+cmd-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) gencmdlist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $<    | sh $(srcdir)/gencmdlist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+fs-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genfslist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $<    | sh $(srcdir)/genfslist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+partmap-fs_uuid_mod-disk_fs_uuid.lst: disk/fs_uuid.c $(disk/fs_uuid.c_DEPENDENCIES) genpartmaplist.sh
+       set -e;           $(TARGET_CC) -Idisk -I$(srcdir)/disk $(TARGET_CPPFLAGS) $(TARGET_CFLAGS) $(fs_uuid_mod_CFLAGS) -E $<    | sh $(srcdir)/genpartmaplist.sh fs_uuid > $@ || (rm -f $@; exit 1)
+
+
+fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For configfile.mod
 configfile_mod_SOURCES = commands/configfile.c
 CLEANFILES += configfile.mod mod-configfile.o mod-configfile.c pre-configfile.o configfile_mod-commands_configfile.o und-configfile.lst
index acbebc7b7bdb688fcd90b2f1da81aee15fb30832..f34a2bf3b22706a34cbc0d54fdbe5f207a2e696f 100644 (file)
@@ -280,7 +280,7 @@ lvm_mod_LDFLAGS = $(COMMON_LDFLAGS)
 # Commands.
 pkglib_MODULES += hello.mod boot.mod terminal.mod ls.mod       \
        cmp.mod cat.mod help.mod font.mod search.mod            \
-       loopback.mod configfile.mod echo.mod                    \
+       loopback.mod fs_uuid.mod configfile.mod echo.mod        \
        terminfo.mod test.mod blocklist.mod hexdump.mod         \
        read.mod sleep.mod
 
@@ -344,6 +344,11 @@ loopback_mod_SOURCES = disk/loopback.c
 loopback_mod_CFLAGS = $(COMMON_CFLAGS)
 loopback_mod_LDFLAGS = $(COMMON_LDFLAGS)
 
+# For fs_uuid.mod
+fs_uuid_mod_SOURCES = disk/fs_uuid.c
+fs_uuid_mod_CFLAGS = $(COMMON_CFLAGS)
+fs_uuid_mod_LDFLAGS = $(COMMON_LDFLAGS)
+
 # For configfile.mod
 configfile_mod_SOURCES = commands/configfile.c
 configfile_mod_CFLAGS = $(COMMON_CFLAGS)
diff --git a/disk/fs_uuid.c b/disk/fs_uuid.c
new file mode 100644 (file)
index 0000000..47eb228
--- /dev/null
@@ -0,0 +1,137 @@
+/* fs_uuid.c - Access disks by their filesystem UUID.  */
+/*
+ *  GRUB  --  GRand Unified Bootloader
+ *  Copyright (C) 2007,2008  Free Software Foundation, Inc.
+ *
+ *  GRUB 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.
+ *
+ *  GRUB 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 GRUB.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/disk.h>
+#include <grub/dl.h>
+#include <grub/kernel.h>
+#include <grub/misc.h>
+#include <grub/mm.h>
+#include <grub/types.h>
+
+#include <grub/fs.h>
+
+static grub_device_t
+search_fs_uuid (const char *key, unsigned long *count)
+{
+  *count = 0;
+  grub_device_t ret = NULL;
+
+  auto int iterate_device (const char *name);
+  int iterate_device (const char *name)
+    {
+      grub_device_t dev;
+
+      dev = grub_device_open (name);
+      if (dev)
+       {
+         grub_fs_t fs;
+         
+         fs = grub_fs_probe (dev);
+         if (fs && fs->uuid)
+           {
+             char *uuid;
+             
+             (fs->uuid) (dev, &uuid);
+             if (grub_errno == GRUB_ERR_NONE && uuid)
+               {
+                 *count++;
+
+                 if (grub_strcmp (uuid, key) == 0)
+                   {
+                     ret = dev;
+                     grub_free (uuid);
+                     return 1;
+                   }
+                 grub_free (uuid);
+               }
+           }
+         
+         grub_device_close (dev);
+       }
+
+      grub_errno = GRUB_ERR_NONE;
+      return 0;
+    }
+  
+  grub_device_iterate (iterate_device);
+  
+  return ret;
+}
+
+static grub_err_t
+grub_fs_uuid_open (const char *name, grub_disk_t disk)
+{
+  grub_device_t dev;
+
+  if (grub_strncmp (name, "UUID=", sizeof ("UUID=")-1))
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "not a UUID virtual volume");
+
+  dev = search_fs_uuid (name + sizeof ("UUID=") - 1, &disk->id);
+  if (! dev)
+    return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "no matching UUID found");
+
+  disk->total_sectors = dev->disk->total_sectors;
+  disk->has_partitions = 0;
+  disk->partition = dev->disk->partition;
+  disk->data = dev->disk;
+
+  return GRUB_ERR_NONE;
+}
+
+static void
+grub_fs_uuid_close (grub_disk_t disk __attribute((unused)))
+{
+}
+
+static grub_err_t
+grub_fs_uuid_read (grub_disk_t disk, grub_disk_addr_t sector,
+                  grub_size_t size, char *buf)
+{
+  grub_disk_t parent = disk->data;
+  return parent->dev->read (parent, sector, size, buf);
+}
+
+static grub_err_t
+grub_fs_uuid_write (grub_disk_t disk, grub_disk_addr_t sector,
+                   grub_size_t size, const char *buf)
+{
+  grub_disk_t parent = disk->data;
+  return parent->dev->write (parent, sector, size, buf);
+}
+
+static struct grub_disk_dev grub_fs_uuid_dev =
+  {
+    .name = "fs_uuid",
+    .id = GRUB_DISK_DEVICE_UUID_ID,
+    .open = grub_fs_uuid_open,
+    .close = grub_fs_uuid_close,
+    .read = grub_fs_uuid_read,
+    .write = grub_fs_uuid_write,
+    .next = 0
+  };
+
+GRUB_MOD_INIT(fs_uuid)
+{
+  grub_disk_dev_register (&grub_fs_uuid_dev);
+}
+
+GRUB_MOD_FINI(fs_uuid)
+{
+  grub_disk_dev_unregister (&grub_fs_uuid_dev);
+}
index 3178203c053dcb00f2ab24e6a4e2f95e81fe9259..0e2789219d06214b0cf9cf864528ed98d95b98de 100644 (file)
@@ -38,6 +38,7 @@ enum grub_disk_dev_id
     GRUB_DISK_DEVICE_ATA_ID,
     GRUB_DISK_DEVICE_MEMDISK_ID,
     GRUB_DISK_DEVICE_NAND_ID,
+    GRUB_DISK_DEVICE_UUID_ID,
   };
 
 struct grub_disk;
index 2bbc8c54ab709fbedde93ff86b9fdfa65c78068c..980b5056ae6bd969657131acc16b2f7e055c2406 100644 (file)
@@ -202,7 +202,7 @@ grub_disk_dev_iterate (int (*hook) (const char *name))
   grub_disk_dev_t p;
 
   for (p = grub_disk_dev_list; p; p = p->next)
-    if ((p->iterate) (hook))
+    if (p->iterate && (p->iterate) (hook))
       return 1;
 
   return 0;