All of lore.kernel.org
 help / color / mirror / Atom feed
From: Robert Millan <rmh@aybabtu.com>
To: grub-devel@gnu.org
Subject: [PATCH] fix for partmap detection on RAID/LVM
Date: Wed, 6 Feb 2008 22:18:40 +0100	[thread overview]
Message-ID: <20080206211840.GA13360@thorin> (raw)

[-- Attachment #1: Type: text/plain, Size: 1081 bytes --]


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

<GPLv2> I know my rights; I want my phone call!
<DRM> What use is a phone call… if you are unable to speak?
(as seen on /.)

[-- Attachment #2: raid_partmap.diff --]
[-- Type: text/x-diff, Size: 3867 bytes --]

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;
     }
 

             reply	other threads:[~2008-02-06 21:20 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-06 21:18 Robert Millan [this message]
2008-02-06 23:14 ` [PATCH] fix for partmap detection on RAID/LVM Robert Millan
2008-02-08 14:52   ` Robert Millan
2008-02-08 19:20     ` Sam Morris
2008-02-08 19:38       ` Robert Millan
2008-02-08 21:38         ` Sam Morris
2008-02-08 22:39           ` Robert Millan
2008-02-09 10:39             ` Robert Millan
2008-02-09 10:48     ` Robert Millan
     [not found]     ` <1202733801.24963.11.camel@peder.flower>
2008-02-11 14:05       ` Robert Millan

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20080206211840.GA13360@thorin \
    --to=rmh@aybabtu.com \
    --cc=grub-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.