From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with archive (Exim 4.43) id 1JMrh5-0005Wd-4K for mharc-grub-devel@gnu.org; Wed, 06 Feb 2008 16:20:35 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1JMrh4-0005V4-1p for grub-devel@gnu.org; Wed, 06 Feb 2008 16:20:34 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1JMrh3-0005Ta-Dd for grub-devel@gnu.org; Wed, 06 Feb 2008 16:20:33 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1JMrh3-0005TQ-5e for grub-devel@gnu.org; Wed, 06 Feb 2008 16:20:33 -0500 Received: from aybabtu.com ([69.60.117.155]) by monty-python.gnu.org with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.60) (envelope-from ) id 1JMrh2-0007tc-RS for grub-devel@gnu.org; Wed, 06 Feb 2008 16:20:33 -0500 Received: from [192.168.10.6] (helo=thorin) by aybabtu.com with esmtps (TLS-1.0:RSA_AES_256_CBC_SHA1:32) (Exim 4.63) (envelope-from ) id 1JMrgx-0002wH-E1 for grub-devel@gnu.org; Wed, 06 Feb 2008 22:20:31 +0100 Received: from rmh by thorin with local (Exim 4.63) (envelope-from ) id 1JMrfE-0003XJ-5F for grub-devel@gnu.org; Wed, 06 Feb 2008 22:18:40 +0100 Date: Wed, 6 Feb 2008 22:18:40 +0100 From: Robert Millan To: grub-devel@gnu.org Message-ID: <20080206211840.GA13360@thorin> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="PEIAKu/WMn1b1Hv9" 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] fix for partmap detection on RAID/LVM 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: Wed, 06 Feb 2008 21:20:34 -0000 --PEIAKu/WMn1b1Hv9 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit This is my proposed approach for fixing the partmap detection problem in LVM/RAID. The problem: grub-probe just tests for partmap in the target drive directly (which usually doesn't have any), and not in the physical drives that make the RAID array (or LVM volume). My proposed solution: RAID implements grub_raid_parent, which returns a linked list of "parent" (alternate naming suggestions welcome!) drives conforming a specific array. grub_disk_t abstracts that by providing a parent() member (for GRUB_UTIL only) on top of it (so e.g. LVM can implement the same). grub-probe receives the list from this interface and probes partmap in each member. I had in mind something nifty with probe() recursing into itself, in order to support bizarre combinations like lvm inside dm-raid, but on second thoughts my current change is not intrusive and wouldn't preclude this kind of restructuring if someone feels like it. Comments? -- Robert Millan I know my rights; I want my phone call! What use is a phone call… if you are unable to speak? (as seen on /.) --PEIAKu/WMn1b1Hv9 Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="raid_partmap.diff" diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../old/disk/raid.c ./disk/raid.c --- ../old/disk/raid.c 2007-12-30 09:52:03.000000000 +0100 +++ ./disk/raid.c 2008-02-06 21:44:30.000000000 +0100 @@ -67,6 +67,26 @@ grub_raid_iterate (int (*hook) (const ch return 0; } +#ifdef GRUB_UTIL +static grub_parent_t +grub_raid_parent (grub_disk_t disk) +{ + struct grub_raid_array *array = disk->data; + grub_parent_t list = NULL, tmp; + int i; + + for (i = 0; i < array->total_devs; i++) + { + tmp = grub_malloc (sizeof (*tmp)); + tmp->disk = array->device[i]; + tmp->next = list; + list = tmp; + } + + return list; +} +#endif + static grub_err_t grub_raid_open (const char *name, grub_disk_t disk) { @@ -524,6 +544,9 @@ static struct grub_disk_dev grub_raid_de .close = grub_raid_close, .read = grub_raid_read, .write = grub_raid_write, +#ifdef GRUB_UTIL + .parent = grub_raid_parent, +#endif .next = 0 }; diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../old/include/grub/disk.h ./include/grub/disk.h --- ../old/include/grub/disk.h 2008-01-21 00:20:36.000000000 +0100 +++ ./include/grub/disk.h 2008-02-06 21:43:19.000000000 +0100 @@ -40,6 +40,9 @@ enum grub_disk_dev_id }; struct grub_disk; +#ifdef GRUB_UTIL +struct grub_parent; +#endif /* Disk device. */ struct grub_disk_dev @@ -67,6 +70,10 @@ struct grub_disk_dev grub_err_t (*write) (struct grub_disk *disk, grub_disk_addr_t sector, grub_size_t size, const char *buf); +#ifdef GRUB_UTIL + struct grub_parent *(*parent) (struct grub_disk *disk); +#endif + /* The next disk device. */ struct grub_disk_dev *next; }; @@ -105,6 +112,15 @@ struct grub_disk }; typedef struct grub_disk *grub_disk_t; +#ifdef GRUB_UTIL +struct grub_parent +{ + grub_disk_t disk; + struct grub_parent *next; +}; +typedef struct grub_parent *grub_parent_t; +#endif + /* The sector size. */ #define GRUB_DISK_SECTOR_SIZE 0x200 #define GRUB_DISK_SECTOR_BITS 9 diff -x configure -x config.h.in -x CVS -x '*~' -x '*.mk' -urp ../old/util/grub-probe.c ./util/grub-probe.c --- ../old/util/grub-probe.c 2008-02-06 22:09:01.000000000 +0100 +++ ./util/grub-probe.c 2008-02-06 22:09:20.000000000 +0100 @@ -75,6 +75,31 @@ grub_refresh (void) } static void +probe_partmap (grub_disk_t disk) +{ + char *name; + char *underscore; + + if (disk->partition == NULL) + { + grub_util_info ("No partition map found for %s", disk->name); + return; + } + + name = strdup (disk->partition->partmap->name); + if (! name) + grub_util_error ("Not enough memory"); + + underscore = strchr (name, '_'); + if (! underscore) + grub_util_error ("Invalid partition map %s", name); + + *underscore = '\0'; + printf ("%s\n", name); + free (name); +} + +static void probe (const char *path) { char *device_name; @@ -133,23 +158,17 @@ probe (const char *path) if (print == PRINT_PARTMAP) { - char *name; - char *underscore; - - if (dev->disk->partition == NULL) - grub_util_error ("Cannot detect partition map for %s", drive_name); - - name = strdup (dev->disk->partition->partmap->name); - if (! name) - grub_util_error ("not enough memory"); - - underscore = strchr (name, '_'); - if (! underscore) - grub_util_error ("Invalid partition map %s", name); - - *underscore = '\0'; - printf ("%s\n", name); - free (name); + grub_parent_t list = NULL; + /* Check if dev->disk itself is contained in a partmap. */ + probe_partmap (dev->disk); + /* In case of LVM/RAID, check the parent devices as well. */ + if (dev->disk->dev->parent) + list = dev->disk->dev->parent (dev->disk); + while (list) + { + probe_partmap (list->disk); + list = list->next; + } goto end; } --PEIAKu/WMn1b1Hv9--