From: Colin Watson <cjwatson@ubuntu.com>
To: grub-devel@gnu.org
Subject: [PATCH] Fix LVM/RAID probing without device.map
Date: Mon, 22 Mar 2010 14:29:24 +0000 [thread overview]
Message-ID: <20100322142923.GD20777@riva.ucam.org> (raw)
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 <cjwatson@ubuntu.com>
* 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 [cjwatson@ubuntu.com]
next reply other threads:[~2010-03-22 14:45 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-03-22 14:29 Colin Watson [this message]
2010-04-02 23:11 ` [PATCH] Fix LVM/RAID probing without device.map Vladimir 'φ-coder/phcoder' Serbinenko
2010-04-02 23:25 ` Vladimir 'φ-coder/phcoder' Serbinenko
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=20100322142923.GD20777@riva.ucam.org \
--to=cjwatson@ubuntu.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.