[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Fix LVM/RAID probing without device.map
From: |
Colin Watson |
Subject: |
[PATCH] Fix LVM/RAID probing without device.map |
Date: |
Mon, 22 Mar 2010 14:29:24 +0000 |
User-agent: |
Mutt/1.5.18 (2008-05-17) |
We're trying to get rid of our reliance on device.map, for all the
well-known reasons: it causes problems when OS device names change, etc.
For the most part, GRUB 1.98 works fine without it, because if you run
grub-probe or grub-setup in a way that requires them to look at e.g.
/dev/sda, then they'll generate a temporary mapping to a GRUB device
name so that internal functions work.
However, LVM and RAID don't work in this configuration. This is because
they rely on disk/lvm.c and disk/raid.c being able to iterate over all
devices to scan for LVM and RAID physical volumes, which only works if
all the plausible devices on which those PVs might live have already
been probed.
The following patch arranges to probe all the underlying devices if
device.map doesn't exist. In the case of grub-probe, we only do so if
the device name indicates that it's LVM or RAID, to avoid slowing down
update-grub unnecessarily when those device abstractions aren't
involved.
2010-03-22 Colin Watson <address@hidden>
* util/hostdisk.c (store_grub_dev): New function.
(grub_util_biosdisk_probe_device): Likewise.
* include/grub/util/hostdisk.h (grub_util_biosdisk_probe_device):
New prototype.
* util/grub-probe.c (probe): Accept new dev_map parameter. If this
cannot be statted and the target device is LVM or RAID, probe all
devices and reinitialise the LVM and RAID modules.
(main): Update calls to probe.
* util/i386/pc/grub-setup.c (main): If the device map cannot be
statted, probe all devices.
* util/sparc64/ieee1275/grub-setup.c (main): Likewise.
* conf/common.rmk (grub_probe_SOURCES): Add util/deviceiter.c.
* conf/i386-pc.rmk (grub_setup_SOURCES): Likewise.
* conf/sparc64-ieee1275.rmk (grub_setup_SOURCES): Likewise.
=== modified file 'conf/common.rmk'
--- conf/common.rmk 2010-03-14 16:50:55 +0000
+++ conf/common.rmk 2010-03-22 14:21:18 +0000
@@ -26,6 +26,7 @@ sbin_UTILITIES += grub-probe
util/grub-probe.c_DEPENDENCIES = grub_probe_init.h
grub_probe_SOURCES = gnulib/progname.c util/grub-probe.c \
util/hostdisk.c util/misc.c util/getroot.c \
+ util/deviceiter.c \
kern/device.c kern/disk.c kern/err.c kern/misc.c \
kern/parser.c kern/partition.c kern/file.c kern/list.c \
\
=== modified file 'conf/i386-pc.rmk'
--- conf/i386-pc.rmk 2010-03-14 16:50:55 +0000
+++ conf/i386-pc.rmk 2010-03-22 14:21:18 +0000
@@ -75,7 +75,8 @@ util/grub-mkrawimage.c_DEPENDENCIES = Ma
util/i386/pc/grub-setup.c_DEPENDENCIES = grub_setup_init.h
grub_setup_SOURCES = gnulib/progname.c \
util/i386/pc/grub-setup.c util/hostdisk.c \
- util/misc.c util/getroot.c kern/device.c kern/disk.c \
+ util/misc.c util/getroot.c util/deviceiter.c \
+ kern/device.c kern/disk.c \
kern/err.c kern/misc.c kern/parser.c kern/partition.c \
kern/file.c kern/fs.c kern/env.c kern/list.c \
fs/fshelp.c \
=== modified file 'conf/sparc64-ieee1275.rmk'
--- conf/sparc64-ieee1275.rmk 2010-03-14 16:50:55 +0000
+++ conf/sparc64-ieee1275.rmk 2010-03-22 14:21:18 +0000
@@ -50,7 +50,8 @@ grub_mkimage_SOURCES = util/grub-mkrawim
# For grub-setup.
util/sparc64/ieee1275/grub-setup.c_DEPENDENCIES = grub_setup_init.h
grub_setup_SOURCES = util/sparc64/ieee1275/grub-setup.c util/hostdisk.c
\
- util/misc.c util/getroot.c kern/device.c kern/disk.c \
+ util/misc.c util/getroot.c util/deviceiter.c \
+ kern/device.c kern/disk.c \
kern/err.c kern/misc.c kern/parser.c kern/partition.c \
kern/file.c kern/fs.c kern/env.c kern/list.c \
fs/fshelp.c \
=== modified file 'include/grub/util/hostdisk.h'
--- include/grub/util/hostdisk.h 2008-09-08 13:52:30 +0000
+++ include/grub/util/hostdisk.h 2010-03-22 14:21:18 +0000
@@ -22,6 +22,7 @@
void grub_util_biosdisk_init (const char *dev_map);
void grub_util_biosdisk_fini (void);
+int grub_util_biosdisk_probe_device (const char *name, int is_floppy);
char *grub_util_biosdisk_get_grub_dev (const char *os_dev);
#endif /* ! GRUB_BIOSDISK_MACHINE_UTIL_HEADER */
=== modified file 'util/grub-probe.c'
--- util/grub-probe.c 2010-01-20 02:11:07 +0000
+++ util/grub-probe.c 2010-03-22 14:21:18 +0000
@@ -28,6 +28,7 @@
#include <grub/msdos_partition.h>
#include <grub/util/hostdisk.h>
#include <grub/util/getroot.h>
+#include <grub/util/deviceiter.h>
#include <grub/term.h>
#include <grub/env.h>
#include <grub/raid.h>
@@ -106,13 +107,14 @@ probe_raid_level (grub_disk_t disk)
}
static void
-probe (const char *path, char *device_name)
+probe (const char *path, char *device_name, const char *dev_map)
{
char *drive_name = NULL;
char *grub_path = NULL;
char *filebuf_via_grub = NULL, *filebuf_via_sys = NULL;
grub_device_t dev = NULL;
grub_fs_t fs;
+ struct stat dev_map_stat;
if (path == NULL)
{
@@ -136,6 +138,22 @@ probe (const char *path, char *device_na
goto end;
}
+ if (stat (dev_map, &dev_map_stat) == -1 &&
+ grub_util_get_dev_abstraction (device_name) != GRUB_DEV_ABSTRACTION_NONE)
+ {
+ /* If we don't have a device map, then we won't yet know about the
+ physical volumes underlying this device, so probe all devices. */
+ grub_util_iterate_devices (grub_util_biosdisk_probe_device, 0);
+
+ /* Now reinitialise the higher layers. */
+ grub_lvm_fini ();
+ grub_mdraid_fini ();
+ grub_raid_fini ();
+ grub_raid_init ();
+ grub_mdraid_init ();
+ grub_lvm_init ();
+ }
+
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", device_name);
@@ -428,9 +446,9 @@ main (int argc, char *argv[])
/* Do it. */
if (argument_is_device)
- probe (NULL, argument);
+ probe (NULL, argument, dev_map ? : DEFAULT_DEVICE_MAP);
else
- probe (argument, NULL);
+ probe (argument, NULL, dev_map ? : DEFAULT_DEVICE_MAP);
/* Free resources. */
grub_fini_all ();
=== modified file 'util/hostdisk.c'
--- util/hostdisk.c 2010-03-14 15:39:14 +0000
+++ util/hostdisk.c 2010-03-22 14:21:18 +0000
@@ -1024,6 +1024,48 @@ find_system_device (const char *os_dev)
return i;
}
+static void
+store_grub_dev (const char *grub_disk, const char *os_disk)
+{
+ unsigned int i;
+
+ for (i = 0; i < ARRAY_SIZE (map); i++)
+ if (! map[i].device)
+ break;
+ else if (strcmp (map[i].drive, grub_disk) == 0)
+ {
+ if (strcmp (map[i].device, os_disk) == 0)
+ return;
+ grub_util_error (_("drive `%s' already mapped to `%s'"),
+ map[i].drive, map[i].device);
+ }
+
+ if (i == ARRAY_SIZE (map))
+ grub_util_error (_("device count exceeds limit"));
+
+ map[i].drive = xstrdup (grub_disk);
+ map[i].device = xstrdup (os_disk);
+}
+
+static int num_hd = 0;
+static int num_fd = 0;
+
+int
+grub_util_biosdisk_probe_device (const char *name, int is_floppy)
+{
+ char *grub_disk;
+
+ if (is_floppy)
+ grub_disk = xasprintf ("fd%d", num_fd++);
+ else
+ grub_disk = xasprintf ("hd%d", num_hd++);
+
+ store_grub_dev (grub_disk, name);
+ free (grub_disk);
+
+ return 0;
+}
+
char *
grub_util_biosdisk_get_grub_dev (const char *os_dev)
{
=== modified file 'util/i386/pc/grub-setup.c'
--- util/i386/pc/grub-setup.c 2010-03-08 22:20:02 +0000
+++ util/i386/pc/grub-setup.c 2010-03-22 14:21:18 +0000
@@ -36,6 +36,7 @@
#include <grub/util/raid.h>
#include <grub/util/lvm.h>
#include <grub/util/getroot.h>
+#include <grub/util/deviceiter.h>
static const grub_gpt_part_type_t grub_gpt_partition_type_bios_boot =
GRUB_GPT_PARTITION_TYPE_BIOS_BOOT;
@@ -631,6 +632,7 @@ main (int argc, char *argv[])
char *core_file = 0;
char *dir = 0;
char *dev_map = 0;
+ struct stat dev_map_stat;
char *root_dev = 0;
char *dest_dev;
int must_embed = 0, force = 0, fs_probe = 1;
@@ -729,6 +731,9 @@ main (int argc, char *argv[])
/* Initialize the emulated biosdisk driver. */
grub_util_biosdisk_init (dev_map ? : DEFAULT_DEVICE_MAP);
+ if (stat (dev_map ? : DEFAULT_DEVICE_MAP, &dev_map_stat) == -1)
+ grub_util_iterate_devices (grub_util_biosdisk_probe_device, 0);
+
/* Initialize all modules. */
grub_init_all ();
=== modified file 'util/sparc64/ieee1275/grub-setup.c'
--- util/sparc64/ieee1275/grub-setup.c 2010-01-16 00:26:52 +0000
+++ util/sparc64/ieee1275/grub-setup.c 2010-03-22 14:21:18 +0000
@@ -46,6 +46,7 @@
#include <sys/stat.h>
#include <dirent.h>
#include <grub/util/getroot.h>
+#include <grub/util/deviceiter.h>
#define _GNU_SOURCE 1
#include <getopt.h>
@@ -618,6 +619,7 @@ int
main (int argc, char *argv[])
{
struct grub_setup_info ginfo;
+ struct stat dev_map_stat;
set_program_name (argv[0]);
@@ -630,6 +632,9 @@ main (int argc, char *argv[])
/* Initialize the emulated biosdisk driver. */
grub_util_biosdisk_init (ginfo.dev_map ? ginfo.dev_map : DEFAULT_DEVICE_MAP);
+ if (stat (ginfo.dev_map ? : DEFAULT_DEVICE_MAP, &dev_map_stat) == -1)
+ grub_util_iterate_devices (grub_util_biosdisk_probe_device, 0);
+
/* Initialize all modules. */
grub_init_all ();
Comments?
--
Colin Watson address@hidden
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [PATCH] Fix LVM/RAID probing without device.map,
Colin Watson <=