2008-06-06 Robert Millan
* 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().
diff -N -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/conf/common.rmk ./conf/common.rmk
--- ../grub2/conf/common.rmk 2008-04-13 14:11:33.000000000 +0200
+++ ./conf/common.rmk 2008-06-05 02:09:31.000000000 +0200
@@ -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 -N -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/disk/fs_uuid.c ./disk/fs_uuid.c
--- ../grub2/disk/fs_uuid.c 1970-01-01 01:00:00.000000000 +0100
+++ ./disk/fs_uuid.c 2008-06-05 21:53:38.000000000 +0200
@@ -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 .
+ */
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include
+
+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);
+}
diff -N -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/include/grub/disk.h ./include/grub/disk.h
--- ../grub2/include/grub/disk.h 2008-04-26 19:51:01.000000000 +0200
+++ ./include/grub/disk.h 2008-06-05 22:45:34.000000000 +0200
@@ -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;
diff -N -x ChangeLog -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../grub2/kern/disk.c ./kern/disk.c
--- ../grub2/kern/disk.c 2008-02-08 13:22:51.000000000 +0100
+++ ./kern/disk.c 2008-06-05 22:46:24.000000000 +0200
@@ -202,7 +202,7 @@ grub_disk_dev_iterate (int (*hook) (cons
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;