I just installed an LVM test system to debug this.

On Wed, Jan 09, 2008 at 05:27:37PM +0100, Martin Braure de Calignon wrote:
> 
> Le mercredi 09 janvier 2008 à 16:36 +0100, Robert Millan a écrit :
> 
> > There should be one.  Can you find out why 00_header is not echoing it?
> 
> because font_path is never called ?

It was; the problem had to do with the variable not being exported.

I'm proposing the attached patch for commit (ChangeLog entry in patch header).

This fixes the two known problems regarding load of lvm/raid modules.  I found
other two issues with lvm in runtime, which I just committed since the fix was
one-liner.

The remaining known problem is detecting partmap; I'll probably find time to do
that one too, but I'll need to know how can one obtain a machine-parseable
list of physical devices that conform an LVM virtual device (and the same for
software RAID).

-- 
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 /.)
	* include/grub/util/getroot.h (grub_dev_abstraction_types): New enum.
	(grub_util_get_dev_abstraction): New function prototype.
	(grub_util_get_grub_dev): Add `dev_abstraction' parameter.

	* util/getroot.c: Include `<grub/util/getroot.h>'
	(grub_util_get_grub_dev): Move detection of abstraction type to ...
	(grub_util_get_dev_abstraction): ... here (new function).

	* util/grub-emu.c (main): Update calls to grub_util_get_grub_dev()
	with new `dev_abstraction' parameter.
	* util/i386/pc/grub-setup.c (main): Likewise.

	* util/grub-probe.c: Convert PRINT_* to an enum.  Add
	`PRINT_ABSTRACTION'.
	(probe): Probe for abstraction type when requested.
	(main): Understand `--target=abstraction'.

	* util/i386/efi/grub-install.in: Add abstraction module to core
	image when it is found to be necessary.
	* util/i386/pc/grub-install.in: Likewise.
	* util/powerpc/ieee1275/grub-install.in: Likewise.

	* util/update-grub_lib.in (font_path): Return system path without
	converting to GRUB path.
	* util/update-grub.in: Convert system path returned by font_path()
	to a GRUB path.  Use `grub-probe -t abstraction' to determine what
	abstraction module is needed for loading fonts (if any).  Export
	that as `GRUB_PRELOAD_MODULES'.
	* util/grub.d/00_header.in: Process `GRUB_PRELOAD_MODULES' (print
	insmod commands).

diff -urp grub2/include/grub/util/getroot.h lvm/include/grub/util/getroot.h
--- grub2/include/grub/util/getroot.h	2007-07-22 01:32:25.000000000 +0200
+++ lvm/include/grub/util/getroot.h	2008-01-10 00:30:16.000000000 +0100
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003, 2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2003, 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
@@ -19,8 +19,16 @@
 #ifndef GRUB_UTIL_GETROOT_HEADER
 #define GRUB_UTIL_GETROOT_HEADER	1
 
+enum grub_dev_abstraction_types {
+  GRUB_DEV_ABSTRACTION_NONE,
+  GRUB_DEV_ABSTRACTION_LVM,
+  GRUB_DEV_ABSTRACTION_RAID,
+  GRUB_DEV_ABSTRACTION_UNKNOWN,
+};
+
 char *grub_guess_root_device (const char *dir);
 char *grub_get_prefix (const char *dir);
-char *grub_util_get_grub_dev (const char *os_dev);
+int grub_util_get_dev_abstraction (const char *os_dev);
+char *grub_util_get_grub_dev (const int dev_abstraction, const char *os_dev);
 
 #endif /* ! GRUB_UTIL_GETROOT_HEADER */
diff -urp grub2/util/getroot.c lvm/util/getroot.c
--- grub2/util/getroot.c	2007-07-22 01:32:31.000000000 +0200
+++ lvm/util/getroot.c	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 /* getroot.c - Get root device */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2006,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 1999,2000,2001,2002,2003,2006,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
@@ -24,6 +24,7 @@
 
 #include <grub/util/misc.h>
 #include <grub/util/biosdisk.h>
+#include <grub/util/getroot.h>
 
 static void
 strip_extra_slashes (char *dir)
@@ -239,27 +240,45 @@ grub_guess_root_device (const char *dir)
   return os_dev;
 }
 
-char *
-grub_util_get_grub_dev (const char *os_dev)
+int
+grub_util_get_dev_abstraction (const char *os_dev)
 {
   /* Check for LVM.  */
   if (!strncmp (os_dev, "/dev/mapper/", 12))
-    {
-      char *grub_dev = xmalloc (strlen (os_dev) - 12 + 1);
-
-      strcpy (grub_dev, os_dev+12);
-
-      return grub_dev;
-    }
+    return GRUB_DEV_ABSTRACTION_LVM;
 
   /* Check for RAID.  */
   if (!strncmp (os_dev, "/dev/md", 7))
+    return GRUB_DEV_ABSTRACTION_RAID;
+
+  /* No abstraction found.  */
+  return GRUB_DEV_ABSTRACTION_NONE;
+}
+
+char *
+grub_util_get_grub_dev (int abstraction, const char *os_dev)
+{
+  char *grub_dev;
+
+  if (abstraction == GRUB_DEV_ABSTRACTION_UNKNOWN)
+    abstraction = grub_util_get_dev_abstraction (os_dev);
+
+  switch (abstraction)
     {
-      const char *p;
-      char *grub_dev = xmalloc (20);
+    case GRUB_DEV_ABSTRACTION_LVM:
+      grub_dev = xmalloc (strlen (os_dev) - 12 + 1);
+
+      strcpy (grub_dev, os_dev + 12);
+
+      break;
+
+    case GRUB_DEV_ABSTRACTION_RAID:
+      grub_dev = xmalloc (20);
 
       if (os_dev[7] == '_' && os_dev[8] == 'd')
 	{
+	  const char *p;
+
 	  /* This a partitionable RAID device of the form /dev/md_dNNpMM. */
 	  int i;
 
@@ -297,17 +316,17 @@ grub_util_get_grub_dev (const char *os_d
 	}
       else if (os_dev[7] >= '0' && os_dev[7] <= '9')
 	{
-	  p = os_dev + 5;
-	  memcpy (grub_dev, p, 7);
+	  memcpy (grub_dev, os_dev + 5, 7);
 	  grub_dev[7] = '\0';
 	}
       else
 	grub_util_error ("Unknown kind of RAID device `%s'", os_dev);
 
+      break;
 
-      return grub_dev;
+    default:  /* GRUB_DEV_ABSTRACTION_NONE */
+      grub_dev = grub_util_biosdisk_get_grub_dev (os_dev);
     }
 
-  /* If it's not RAID or LVM, it should be a biosdisk.  */
-  return grub_util_biosdisk_get_grub_dev (os_dev);
+  return grub_dev;
 }
diff -urp grub2/util/grub.d/00_header.in lvm/util/grub.d/00_header.in
--- grub2/util/grub.d/00_header.in	2007-07-22 01:32:31.000000000 +0200
+++ lvm/util/grub.d/00_header.in	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 #! /bin/sh -e
 
 # update-grub helper script.
-# Copyright (C) 2006,2007  Free Software Foundation, Inc.
+# Copyright (C) 2006,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
@@ -24,6 +24,12 @@ [EMAIL PROTECTED]@
 # for convert_system_path_to_grub_path()
 . ${libdir}/grub/update-grub_lib
 
+# Do this as early as possible, since other commands might depend on it.
+# (e.g. the `font' command might need lvm or raid modules)
+for i in ${GRUB_PRELOAD_MODULES} ; do
+  echo "insmod $i"
+done
+
 if [ "x${GRUB_DEFAULT}" = "x" ] ; then GRUB_DEFAULT=0 ; fi
 if [ "x${GRUB_TIMEOUT}" = "x" ] ; then GRUB_TIMEOUT=5 ; fi
 
diff -urp grub2/util/grub-emu.c lvm/util/grub-emu.c
--- grub2/util/grub-emu.c	2007-08-02 19:24:06.000000000 +0200
+++ lvm/util/grub-emu.c	2008-01-10 00:30:16.000000000 +0100
@@ -1,6 +1,6 @@
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2003,2004,2005,2006,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 2003,2004,2005,2006,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
@@ -186,7 +186,7 @@ main (int argc, char *argv[])
       if (! device_name)
         grub_util_error ("cannot find a device for %s.\n", args.dir ? : DEFAULT_DIRECTORY);
 
-      args.root_dev = grub_util_get_grub_dev (device_name);
+      args.root_dev = grub_util_get_grub_dev (GRUB_DEV_ABSTRACTION_UNKNOWN, device_name);
       if (! args.root_dev)
 	{
 	  grub_util_info ("guessing the root device failed, because of `%s'",
diff -urp grub2/util/grub-probe.c lvm/util/grub-probe.c
--- grub2/util/grub-probe.c	2007-07-22 21:17:26.000000000 +0200
+++ lvm/util/grub-probe.c	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 /* grub-probe.c - probe device information for a given path */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 2005,2006,2007 Free Software Foundation, Inc.
+ *  Copyright (C) 2005,2006,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
@@ -39,10 +39,13 @@
 #define _GNU_SOURCE	1
 #include <getopt.h>
 
-#define PRINT_FS	0
-#define PRINT_DRIVE	1
-#define PRINT_DEVICE	2
-#define PRINT_PARTMAP	3
+enum {
+  PRINT_FS,
+  PRINT_DRIVE,
+  PRINT_DEVICE,
+  PRINT_PARTMAP,
+  PRINT_ABSTRACTION,
+};
 
 int print = PRINT_FS;
 
@@ -74,6 +77,7 @@ probe (const char *path)
 {
   char *device_name;
   char *drive_name = NULL;
+  int abstraction_type;
   grub_device_t dev;
   grub_fs_t fs;
   
@@ -87,7 +91,29 @@ probe (const char *path)
       goto end;
     }
 
-  drive_name = grub_util_get_grub_dev (device_name);
+  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_NONE:
+	  grub_util_info ("did not find LVM/RAID in %s, assuming raw device", device_name);
+	  goto end;
+	case GRUB_DEV_ABSTRACTION_LVM:
+	  abstraction_name = "lvm";
+	  break;
+	case GRUB_DEV_ABSTRACTION_RAID:
+	  abstraction_name = "raid";
+	  break;
+	}
+      printf ("%s\n", abstraction_name);
+      goto end;
+    }
+
+  drive_name = grub_util_get_grub_dev (abstraction_type, device_name);
   if (! drive_name)
     grub_util_error ("cannot find a GRUB drive for %s.\n", device_name);
   
@@ -159,8 +185,8 @@ Usage: grub-probe [OPTION]... PATH\n\
 Probe device information for a given path.\n\
 \n\
   -m, --device-map=FILE     use FILE as the device map [default=%s]\n\
-  -t, --target=(fs|drive|device|partmap)\n\
-                            print filesystem module, GRUB drive, system device or partition map module [default=fs]\n\
+  -t, --target=(fs|drive|device|partmap|abstraction)\n\
+                            print filesystem module, GRUB drive, system device, partition map module or abstraction module [default=fs]\n\
   -h, --help                display this message and exit\n\
   -V, --version             print version information and exit\n\
   -v, --verbose             print verbose messages\n\
@@ -206,6 +232,8 @@ main (int argc, char *argv[])
 	      print = PRINT_DEVICE;
 	    else if (!strcmp (optarg, "partmap"))
 	      print = PRINT_PARTMAP;
+	    else if (!strcmp (optarg, "abstraction"))
+	      print = PRINT_ABSTRACTION;
 	    else
 	      usage (1);
 	    break;
diff -urp grub2/util/i386/efi/grub-install.in lvm/util/i386/efi/grub-install.in
--- grub2/util/i386/efi/grub-install.in	2007-12-30 09:52:06.000000000 +0100
+++ lvm/util/i386/efi/grub-install.in	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Install GRUB on your EFI partition.
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007  Free Software Foundation, Inc.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,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
@@ -190,8 +190,11 @@ fi
 # filesystem will be accessible).
 partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
 
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
+
 # _chain is often useful
-modules="$modules $fs_module $partmap_module _chain"
+modules="$modules $fs_module $partmap_module $devabstraction_module _chain"
 
 $grub_mkimage --output=${grubdir}/grub.efi $modules || exit 1
 
diff -urp grub2/util/i386/pc/grub-install.in lvm/util/i386/pc/grub-install.in
--- grub2/util/i386/pc/grub-install.in	2007-12-30 09:52:06.000000000 +0100
+++ lvm/util/i386/pc/grub-install.in	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Install GRUB on your drive.
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007  Free Software Foundation, Inc.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,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
@@ -223,8 +223,11 @@ fi
 # filesystem will be accessible).
 partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
 
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
+
 # _chain is often useful
-modules="$modules $fs_module $partmap_module biosdisk _chain"
+modules="$modules $fs_module $partmap_module biosdisk $devabstraction_module _chain"
 
 $grub_mkimage --output=${grubdir}/core.img --prefix=`make_system_path_relative_to_its_root ${grubdir}` $modules || exit 1
 
diff -urp grub2/util/i386/pc/grub-setup.c lvm/util/i386/pc/grub-setup.c
--- grub2/util/i386/pc/grub-setup.c	2008-01-05 13:20:28.000000000 +0100
+++ lvm/util/i386/pc/grub-setup.c	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 /* grub-setup.c - make GRUB usable */
 /*
  *  GRUB  --  GRand Unified Bootloader
- *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007  Free Software Foundation, Inc.
+ *  Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,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
@@ -668,7 +668,7 @@ main (int argc, char *argv[])
   if (! dest_dev)
     {
       /* Possibly, the user specified an OS device file.  */
-      dest_dev = grub_util_get_grub_dev (argv[optind]);
+      dest_dev = grub_util_get_grub_dev (GRUB_DEV_ABSTRACTION_UNKNOWN, argv[optind]);
       if (! dest_dev)
 	{
 	  fprintf (stderr, "Invalid device `%s'.\n", argv[optind]);
@@ -694,7 +694,7 @@ main (int argc, char *argv[])
     }
   else
     {
-      root_dev = grub_util_get_grub_dev (grub_guess_root_device (dir ? : DEFAULT_DIRECTORY));
+      root_dev = grub_util_get_grub_dev (GRUB_DEV_ABSTRACTION_UNKNOWN, grub_guess_root_device (dir ? : DEFAULT_DIRECTORY));
       if (! root_dev)
 	{
 	  grub_util_info ("guessing the root device failed, because of `%s'",
@@ -734,7 +734,7 @@ main (int argc, char *argv[])
 		 dir ? : DEFAULT_DIRECTORY,
 		 boot_file ? : DEFAULT_BOOT_FILE,
 		 core_file ? : DEFAULT_CORE_FILE,
-		 root_dev, grub_util_get_grub_dev (devicelist[i]), 1);
+		 root_dev, grub_util_get_grub_dev (GRUB_DEV_ABSTRACTION_UNKNOWN, devicelist[i]), 1);
 	}
 
       free (raid_prefix);
diff -urp grub2/util/powerpc/ieee1275/grub-install.in lvm/util/powerpc/ieee1275/grub-install.in
--- grub2/util/powerpc/ieee1275/grub-install.in	2007-12-30 09:52:06.000000000 +0100
+++ lvm/util/powerpc/ieee1275/grub-install.in	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 #! /bin/sh
 
 # Install GRUB on your drive.
-# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,2007  Free Software Foundation, Inc.
+# Copyright (C) 1999,2000,2001,2002,2003,2004,2005,2006,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
@@ -176,7 +176,10 @@ fi
 # filesystem will be accessible).
 partmap_module=`$grub_probe --target=partmap --device-map=${device_map} ${grubdir} 2> /dev/null`
 
-modules="$modules $fs_module $partmap_module"
+# Device abstraction module, if any (lvm, raid).
+devabstraction_module=`$grub_probe --target=abstraction --device-map=${device_map} ${grubdir}`
+
+modules="$modules $fs_module $partmap_module $devabstraction_module"
 
 # Now perform the installation.
 "$grub_mkimage" --output=${grubdir}/grub $modules || exit 1
diff -urp grub2/util/update-grub.in lvm/util/update-grub.in
--- grub2/util/update-grub.in	2007-12-30 09:52:06.000000000 +0100
+++ lvm/util/update-grub.in	2008-01-10 00:30:16.000000000 +0100
@@ -1,7 +1,7 @@
 #! /bin/sh -e
 
 # Generate grub.cfg by inspecting /boot contents.
-# Copyright (C) 2006,2007  Free Software Foundation, Inc.
+# Copyright (C) 2006,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
@@ -103,7 +103,10 @@ esac
 # check for terminals that require fonts
 case ${GRUB_TERMINAL} in
   gfxterm)
-    if GRUB_FONT_PATH=`font_path` ; then : ; else
+    if path=`font_path` ; then
+      GRUB_FONT_PATH="`convert_system_path_to_grub_path ${path}`"
+      GRUB_PRELOAD_MODULES="`${GRUB_PRELOAD_MODULES} ${grub_probe} -t abstraction ${path}`"
+    else
       # fallback to console
       GRUB_TERMINAL=console
     fi
@@ -121,7 +124,7 @@ esac
 
 # These are defined in this script, export them here so that user can
 # override them.
-export GRUB_DEVICE GRUB_FS GRUB_DRIVE GRUB_DRIVE_BOOT GRUB_DRIVE_BOOT_GRUB GRUB_FONT_PATH
+export GRUB_DEVICE GRUB_FS GRUB_DRIVE GRUB_DRIVE_BOOT GRUB_DRIVE_BOOT_GRUB GRUB_FONT_PATH GRUB_PRELOAD_MODULES
 
 # These are optional, user-defined variables.
 export GRUB_DEFAULT GRUB_TIMEOUT GRUB_DISTRIBUTOR GRUB_CMDLINE_LINUX GRUB_TERMINAL GRUB_SERIAL_COMMAND
diff -urp grub2/util/update-grub_lib.in lvm/util/update-grub_lib.in
--- grub2/util/update-grub_lib.in	2007-12-25 10:09:43.000000000 +0100
+++ lvm/util/update-grub_lib.in	2008-01-10 00:30:16.000000000 +0100
@@ -1,5 +1,5 @@
 # Helper library for update-grub
-# Copyright (C) 2007  Free Software Foundation, Inc.
+# 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
@@ -93,19 +93,14 @@ convert_system_path_to_grub_path ()
 
 font_path ()
 {
-  if [ "x${GRUB_FONT_PATH}" = "x" ] ; then : ; else
-    echo "${GRUB_FONT_PATH}"
-    return 0
-  fi
-
   # Prefer system path for space reasons (/boot/grub might be a very small
   # partition in case of OpenFirmware, etc).
   for dir in ${pkgdatadir} /usr/share/grub /boot/grub ; do
     # Prefer complete fonts over incomplete ones.
     for basename in unicode unifont ascii ; do
-      if path=`convert_system_path_to_grub_path ${dir}/${basename}.pff` ; then
-        GRUB_FONT_PATH="${path}"
-        echo "${GRUB_FONT_PATH}"
+      path="${dir}/${basename}.pff"
+      if convert_system_path_to_grub_path ${path} > /dev/null ; then
+        echo "${path}"
         return 0
       fi
     done
_______________________________________________
Grub-devel mailing list
Grub-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/grub-devel

Reply via email to