grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] Dynamic device.map


From: Colin Watson
Subject: [RFC] Dynamic device.map
Date: Mon, 7 Dec 2009 14:28:06 +0000
User-agent: Mutt/1.5.18 (2008-05-17)

As Robert said recently, we're trying to get rid of our reliance on
device.map. Right now, it is still necessary to at least have entries in
device.map for any disks you wish to use with GRUB, although they don't
have to be particularly sensible; any bidirectional mapping will do (at
least as long as the 'search' command works).

I'd like to make it possible to run with no device.map at all, since
that makes it possible to plug in new disks without having to
reconfigure GRUB. Here's a draft patch to do this. I haven't supplied a
ChangeLog entry yet since it isn't suitable for commit yet, as noted in
TODO comments, but I'd welcome comments on the approach here.

This does slow down (e.g.) grub-probe a little: on my laptop with a
single hard disk, the median time for three runs of './grub-probe
--target=drive /' is 0.09 seconds, while the median time for three runs
of './grub-probe --target=drive -m /boot/grub/device.map.invalid /' is
0.18 seconds. I expect it would be worse on machines with many disks.
For the most part, I doubt this is a significant problem (certainly not
in e.g. grub-setup), but it will probably make a difference in scripts
that call grub-probe many times, such as grub-mkconfig. I suggest that
those should check whether the default device.map exists, and, if not,
send the output of grub-mkdevicemap to a temporary file and use that as
an ephemeral device.map cache.

=== modified file 'conf/any-emu.rmk'
--- conf/any-emu.rmk    2009-11-26 00:08:42 +0000
+++ conf/any-emu.rmk    2009-12-07 13:31:59 +0000
@@ -40,7 +40,7 @@ grub_emu_SOURCES = commands/minicmd.c co
        fs/befs.c fs/befs_be.c fs/tar.c                                 \
        \
        util/console.c util/hostfs.c util/grub-emu.c util/misc.c        \
-       util/hostdisk.c util/getroot.c                                  \
+       util/hostdisk.c util/getroot.c util/deviceiter.c                \
        \
        disk/raid.c disk/raid5_recover.c disk/raid6_recover.c           \
        disk/mdraid_linux.c disk/dmraid_nvidia.c disk/lvm.c             \

=== modified file 'conf/common.rmk'
--- conf/common.rmk     2009-11-25 23:10:02 +0000
+++ conf/common.rmk     2009-12-07 13:32:14 +0000
@@ -17,6 +17,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              \
        \

=== modified file 'conf/i386-pc.rmk'
--- conf/i386-pc.rmk    2009-11-25 23:10:02 +0000
+++ conf/i386-pc.rmk    2009-12-07 13:32:32 +0000
@@ -93,6 +93,7 @@ util/i386/pc/grub-mkimage.c_DEPENDENCIES
 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/deviceiter.c                                       \
        util/misc.c util/getroot.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 fs/fshelp.c            \

=== modified file 'conf/sparc64-ieee1275.rmk'
--- conf/sparc64-ieee1275.rmk   2009-12-03 11:18:56 +0000
+++ conf/sparc64-ieee1275.rmk   2009-12-07 13:32:43 +0000
@@ -68,6 +68,7 @@ grub_mkimage_SOURCES = util/sparc64/ieee
 # 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/deviceiter.c                                       \
        util/misc.c util/getroot.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 fs/fshelp.c            \

=== modified file 'util/hostdisk.c'
--- util/hostdisk.c     2009-11-23 20:30:56 +0000
+++ util/hostdisk.c     2009-12-07 14:14:53 +0000
@@ -23,6 +23,7 @@
 #include <grub/types.h>
 #include <grub/err.h>
 #include <grub/util/misc.h>
+#include <grub/util/deviceiter.h>
 #include <grub/util/hostdisk.h>
 #include <grub/misc.h>
 #include <grub/i18n.h>
@@ -551,6 +552,59 @@ static struct grub_disk_dev grub_util_bi
   };
 
 static void
+make_dynamic_device_map (void)
+{
+  auto int NESTED_FUNC_ATTR process_device (const char *name, int is_floppy);
+
+  int NESTED_FUNC_ATTR process_device (const char *name, int is_floppy)
+  {
+    int num_fd = 0;
+    int num_hd = 0;
+    int drive;
+    struct stat st;
+
+    drive = find_free_slot ();
+    if (drive < 0)
+      grub_util_error ("%s: Map table size exceeded", name);
+
+    /* TODO duplication from read_device_map */
+#ifdef __MINGW32__
+    (void) st;
+    if (grub_util_get_disk_size (name) == -1LL)
+#else
+    if (stat (name, &st) == -1)
+#endif
+      {
+       grub_util_info ("Cannot stat `%s', skipping", name);
+       return 0;
+      }
+
+    /* TODO abstract via something like grub_util_emit_devicemap_entry? */
+    if (is_floppy)
+      asprintf (&map[drive].drive, "fd%d", num_fd++);
+    else
+      asprintf (&map[drive].drive, "hd%d", num_hd++);
+
+    /* TODO duplication from read_device_map */
+#ifdef __linux__
+    /* On Linux, the devfs uses symbolic links horribly, and that
+       confuses the interface very much, so use realpath to expand
+       symbolic links.  */
+    map[drive].device = xmalloc (PATH_MAX);
+    if (! realpath (name, map[drive].device))
+      grub_util_error ("Cannot get the real path of `%s'", name);
+#else
+    map[drive].device = xstrdup (name);
+#endif
+
+    return 0;
+  }
+
+  /* TODO implement --no-floppy properly */
+  grub_util_iterate_devices (process_device, 0);
+}
+
+static void
 read_device_map (const char *dev_map)
 {
   FILE *fp;
@@ -568,6 +622,7 @@ read_device_map (const char *dev_map)
   if (! fp)
     {
       grub_util_info (_("Cannot open `%s'"), dev_map);
+      make_dynamic_device_map ();
       return;
     }
 

Thanks,

-- 
Colin Watson                                       address@hidden




reply via email to

[Prev in Thread] Current Thread [Next in Thread]