On Sun, Jul 19, 2009 at 4:05 AM, Robert Millan<r...@aybabtu.com> wrote:
> On Sat, Jul 18, 2009 at 09:59:55PM +0200, Vladimir 'phcoder' Serbinenko wrote:
>> On Sat, Jul 18, 2009 at 9:43 PM, Bean<bean12...@gmail.com> wrote:
>> > On Sun, Jul 19, 2009 at 3:11 AM, Robert Millan<r...@aybabtu.com> wrote:
>> >> On Sat, Jul 18, 2009 at 10:11:19PM +0800, Bean wrote:
>> >>>      }
>> >>>
>> >>>    grub_raid_rescan ();
>> >>> +  grub_lvm_fini ();
>> >>> +  grub_lvm_init ();
>> >>
>> >> This is aside from this patch, but I don't see the purpose of this
>> >> grub_raid_rescan() function.  It's in raid.mod but only used by
>> >> grub-fstest, so at least it should be #ifdef'ed out, but looking at
>> >> what it does, it seems very ad-hoc.  It basically amounts to the
>> >> same you're doing with grub_lvm_fini() and grub_lvm_init().  Could
>> >> you fix this while at it?
>> >
>> > This is required. As raid and lvm scan device in init function, but
>> > grub-fstest uses loopback device, which hasn't been setup in
>> > grub_init_all. This code rescan raid and lvm, otherwise there won't be
>> > available.
>> >
>> This situation isn't strictly speaking restricted to grub-fstest then.
>> One would sensibly want to loopmount lvm image in grub shell. Is there
>> a way to do it cleanly?
>
> I think a good long-term solution is to move the scan function from
> grub_raid_init() to wheereever appropiate to make the scan happen
> dynamically everytime e.g. the iterate() function is called.  However,
> doing this efficiently needs some work.

Hi,

I've come up an alternative solution to grub_raid_rescan, we can use
the same trick as lvm, call fini and then init function, this would
have the same effect of rescanning. Now that grub_raid_rescan is gone,
I can simply raid.c further by moving grub_raid_scan_device into
grub_raid_register.

As for dynamically scanning, I think it's not common to mount lvm/raid
in loopback files, we could just ignore it for now.

-- 
Bean
diff --git a/disk/lvm.c b/disk/lvm.c
index 6707a40..126b494 100644
--- a/disk/lvm.c
+++ b/disk/lvm.c
@@ -271,15 +271,9 @@ grub_lvm_scan_device (const char *name)
   dlocn++;
   mda_offset = grub_le_to_cpu64 (dlocn->offset);
   mda_size = grub_le_to_cpu64 (dlocn->size);
-  dlocn++;
 
-  if (dlocn->offset)
-    {
-      grub_error (GRUB_ERR_NOT_IMPLEMENTED_YET,
-		  "We don't support multiple LVM metadata areas");
-
-      goto fail;
-    }
+  /* It's possible to have multiple copies of metadata areas, we just use the
+     first one.  */
 
   /* Allocate buffer space for the circular worst-case scenario. */
   metadatabuf = grub_malloc (2 * mda_size);
@@ -564,7 +558,10 @@ grub_lvm_scan_device (const char *name)
       {
 	if (! grub_memcmp (pv->id, pv_id, GRUB_LVM_ID_STRLEN))
 	  {
-	    pv->disk = grub_disk_open (name);
+	    /* This could happen to LVM on RAID, pv->disk points to the
+	       raid device, we shouldn't change it.  */
+	    if (! pv->disk)
+	      pv->disk = grub_disk_open (name);
 	    break;
 	  }
       }
diff --git a/disk/raid.c b/disk/raid.c
index c4d0857..23b69ad 100644
--- a/disk/raid.c
+++ b/disk/raid.c
@@ -590,56 +590,6 @@ insert_array (grub_disk_t disk, struct grub_raid_array *new_array,
 static grub_raid_t grub_raid_list;
 
 static void
-grub_raid_scan_device (int head_only)
-{
-  auto int hook (const char *name);
-  int hook (const char *name)
-    {
-      grub_disk_t disk;
-      struct grub_raid_array array;
-      struct grub_raid *p;
-
-      grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
-
-      disk = grub_disk_open (name);
-      if (!disk)
-        return 0;
-
-      if (disk->total_sectors == GRUB_ULONG_MAX)
-        {
-          grub_disk_close (disk);
-          return 0;
-        }
-
-      for (p = grub_raid_list; p; p = p->next)
-        {
-          if (! p->detect (disk, &array))
-            {
-              if (! insert_array (disk, &array, p->name))
-                return 0;
-
-              break;
-            }
-
-          /* This error usually means it's not raid, no need to display
-             it.  */
-          if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
-            grub_print_error ();
-
-          grub_errno = GRUB_ERR_NONE;
-          if (head_only)
-            break;
-        }
-
-      grub_disk_close (disk);
-
-      return 0;
-    }
-
-  grub_device_iterate (&hook);
-}
-
-static void
 free_array (void)
 {
   struct grub_raid_array *array;
@@ -668,9 +618,38 @@ free_array (void)
 void
 grub_raid_register (grub_raid_t raid)
 {
+  auto int hook (const char *name);
+  int hook (const char *name)
+    {
+      grub_disk_t disk;
+      struct grub_raid_array array;
+
+      grub_dprintf ("raid", "Scanning for RAID devices on disk %s\n", name);
+
+      disk = grub_disk_open (name);
+      if (!disk)
+        return 0;
+
+      if ((disk->total_sectors != GRUB_ULONG_MAX) &&
+	  (! grub_raid_list->detect (disk, &array)) &&
+	  (! insert_array (disk, &array, grub_raid_list->name)))
+	return 0;
+
+      /* This error usually means it's not raid, no need to display
+	 it.  */
+      if (grub_errno != GRUB_ERR_OUT_OF_RANGE)
+	grub_print_error ();
+
+      grub_errno = GRUB_ERR_NONE;
+      
+      grub_disk_close (disk);
+
+      return 0;
+    }
+
   raid->next = grub_raid_list;
   grub_raid_list = raid;
-  grub_raid_scan_device (1);
+  grub_device_iterate (&hook);
 }
 
 void
@@ -686,13 +665,6 @@ grub_raid_unregister (grub_raid_t raid)
       }
 }
 
-void
-grub_raid_rescan (void)
-{
-  free_array ();
-  grub_raid_scan_device (0);
-}
-
 static struct grub_disk_dev grub_raid_dev =
   {
     .name = "raid",
diff --git a/include/grub/raid.h b/include/grub/raid.h
index 595ced1..8fa4c38 100644
--- a/include/grub/raid.h
+++ b/include/grub/raid.h
@@ -67,7 +67,6 @@ typedef struct grub_raid *grub_raid_t;
 void grub_raid_register (grub_raid_t raid);
 void grub_raid_unregister (grub_raid_t raid);
 
-void grub_raid_rescan (void);
 void grub_raid_block_xor (char *buf1, const char *buf2, int size);
 
 typedef grub_err_t (*grub_raid5_recover_func_t) (struct grub_raid_array *array,
diff --git a/util/grub-fstest.c b/util/grub-fstest.c
index 4722269..a4de2ae 100644
--- a/util/grub-fstest.c
+++ b/util/grub-fstest.c
@@ -28,7 +28,6 @@
 #include <grub/env.h>
 #include <grub/term.h>
 #include <grub/mm.h>
-#include <grub/raid.h>
 #include <grub/lib/hexdump.h>
 #include <grub/lib/crc.h>
 #include <grub/command.h>
@@ -293,7 +292,13 @@ fstest (char **images, int num_disks, int cmd, int n, char **args)
         grub_util_error ("loopback command fails.");
     }
 
-  grub_raid_rescan ();
+  grub_lvm_fini ();
+  grub_mdraid_fini ();
+  grub_raid_fini ();  
+  grub_raid_init ();
+  grub_mdraid_init ();
+  grub_lvm_init ();
+
   switch (cmd)
     {
     case CMD_LS:
diff --git a/util/grub-probe.c b/util/grub-probe.c
index 97d3860..df920af 100644
--- a/util/grub-probe.c
+++ b/util/grub-probe.c
@@ -106,7 +106,6 @@ probe (const char *path, char *device_name)
   char *drive_name = NULL;
   char *grub_path = NULL;
   char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
-  int abstraction_type;
   grub_device_t dev = NULL;
   grub_fs_t fs;
 
@@ -132,28 +131,6 @@ probe (const char *path, char *device_name)
       goto end;
     }
 
-  abstraction_type = grub_util_get_dev_abstraction (device_name);
-  /* No need to check for errors; lack of abstraction is permissible.  */
-
-  if (print == PRINT_ABSTRACTION)
-    {
-      char *abstraction_name;
-      switch (abstraction_type)
-	{
-	case GRUB_DEV_ABSTRACTION_LVM:
-	  abstraction_name = "lvm";
-	  break;
-	case GRUB_DEV_ABSTRACTION_RAID:
-	  abstraction_name = "raid mdraid";
-	  break;
-	default:
-	  grub_util_info ("did not find LVM/RAID in %s, assuming raw device", device_name);
-	  goto end;
-	}
-      printf ("%s\n", abstraction_name);
-      goto end;
-    }
-
   drive_name = grub_util_get_grub_dev (device_name);
   if (! drive_name)
     grub_util_error ("Cannot find a GRUB drive for %s.  Check your device.map.\n", device_name);
@@ -169,6 +146,33 @@ probe (const char *path, char *device_name)
   if (! dev)
     grub_util_error ("%s", grub_errmsg);
 
+  if (print == PRINT_ABSTRACTION)
+    {
+      grub_disk_memberlist_t list = NULL, tmp;
+      const int is_lvm = (dev->disk->dev->id == GRUB_DISK_DEVICE_LVM_ID);
+      int is_raid = (dev->disk->dev->id == GRUB_DISK_DEVICE_RAID_ID);
+
+      if ((is_lvm) && (dev->disk->dev->memberlist))
+	list = dev->disk->dev->memberlist (dev->disk);
+      while (list)
+	{
+	  is_raid |= (list->disk->dev->id == GRUB_DISK_DEVICE_RAID_ID);
+	  tmp = list->next;
+	  free (list);
+	  list = tmp;
+	}
+
+      if (is_raid)
+	printf ("raid mdraid");
+
+      if (is_lvm)
+	printf ((is_raid) ? " lvm" : "lvm");
+	
+      printf ("\n");
+
+      goto end;
+    }
+
   if (print == PRINT_PARTMAP)
     {
       grub_disk_memberlist_t list = NULL, tmp;
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to