From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1K4ejQ-0007Sj-HF for mharc-grub-devel@gnu.org; Fri, 06 Jun 2008 12:24:00 -0400 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1K4ejN-0007SP-Ga for grub-devel@gnu.org; Fri, 06 Jun 2008 12:23:57 -0400 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1K4ejM-0007SD-Vy for grub-devel@gnu.org; Fri, 06 Jun 2008 12:23:57 -0400 Received: from [199.232.76.173] (port=54362 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1K4ejM-0007SA-Qu for grub-devel@gnu.org; Fri, 06 Jun 2008 12:23:56 -0400 Received: from aybabtu.com ([69.60.117.155]:37059) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1K4ejL-0004Gy-Q2 for grub-devel@gnu.org; Fri, 06 Jun 2008 12:23:56 -0400 Received: from [192.168.10.10] (helo=thorin) by aybabtu.com with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1K4eiB-0005qZ-6b for grub-devel@gnu.org; Fri, 06 Jun 2008 18:22:43 +0200 Received: from rmh by thorin with local (Exim 4.63) (envelope-from ) id 1K4ej5-0003it-Qa for grub-devel@gnu.org; Fri, 06 Jun 2008 18:23:39 +0200 Date: Fri, 6 Jun 2008 18:23:39 +0200 From: Robert Millan To: grub-devel@gnu.org Message-ID: <20080606162339.GA14162@thorin> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="2oS5YaxWCcQjTEyO" Content-Disposition: inline Content-Transfer-Encoding: 8bit Organization: free as in freedom X-Message-Flag: Worried about Outlook viruses? Switch to Thunderbird! www.mozilla.com/thunderbird X-Debbugs-No-Ack: true User-Agent: Mutt/1.5.13 (2006-08-11) X-detected-kernel: by monty-python.gnu.org: Genre and OS details not recognized. Subject: [PATCH] disk/fs_uuid.c X-BeenThere: grub-devel@gnu.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: The development of GRUB 2 List-Id: The development of GRUB 2 List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 06 Jun 2008 16:23:58 -0000 --2oS5YaxWCcQjTEyO Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit This disk driver allows access to partitions that contain a filesystem with known UUID via "(UUID=xxxxxxx)" syntax. The iterator is unimplemented on purpose, because it makes the code smaller and it isn't useful to waste time inspecting the same devices twice while scanning for LVM / whatsoever. Also note that as it currently stands it is highly inefficient. I can't understand why; new UUIDs are searched everytime on each open() call, but this shouldn't be much of an issue since we have a disk cache in kernel to make that efficient. At least, it isn't e.g. for grub_fs_probe() which is called multiple times. Even with this efficiency problem, since it doesn't interfere with anything else I'm inclined to commit it, if nobody objects. -- Robert Millan I know my rights; I want my phone call! What good is a phone call… if you are unable to speak? (as seen on /.) --2oS5YaxWCcQjTEyO Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="fs_uuid.diff" 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; --2oS5YaxWCcQjTEyO--