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