* kern/emu/misc.c (device_mapper_null_log): New function.

(grub_device_mapper_supported): New function.
* include/grub/emu/misc.h (grub_device_mapper_supported): Add
prototype.
* kern/emu/hostdisk.c (find_partition_start): Check whether
device-mapper is supported before trying to use it.
* util/deviceiter.c (grub_util_iterate_devices): Likewise.
This commit is contained in:
Colin Watson 2010-06-07 22:41:55 +01:00
parent da90820083
commit e0f4c43882
5 changed files with 152 additions and 97 deletions

View file

@ -1,3 +1,13 @@
2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* kern/emu/misc.c (device_mapper_null_log): New function.
(grub_device_mapper_supported): New function.
* include/grub/emu/misc.h (grub_device_mapper_supported): Add
prototype.
* kern/emu/hostdisk.c (find_partition_start): Check whether
device-mapper is supported before trying to use it.
* util/deviceiter.c (grub_util_iterate_devices): Likewise.
2010-06-07 Colin Watson <cjwatson@ubuntu.com> 2010-06-07 Colin Watson <cjwatson@ubuntu.com>
* docs/grub.texi (Naming convention): Use GRUB 2 syntax. * docs/grub.texi (Naming convention): Use GRUB 2 syntax.

View file

@ -48,4 +48,8 @@ int EXPORT_FUNC(asprintf) (char **buf, const char *fmt, ...);
char * EXPORT_FUNC(xasprintf) (const char *fmt, ...); char * EXPORT_FUNC(xasprintf) (const char *fmt, ...);
extern char * canonicalize_file_name (const char *path); extern char * canonicalize_file_name (const char *path);
#ifdef HAVE_DEVICE_MAPPER
int grub_device_mapper_supported (void);
#endif
#endif /* GRUB_EMU_MISC_H */ #endif /* GRUB_EMU_MISC_H */

View file

@ -342,7 +342,7 @@ find_partition_start (const char *dev)
# endif /* !defined(__NetBSD__) */ # endif /* !defined(__NetBSD__) */
# ifdef HAVE_DEVICE_MAPPER # ifdef HAVE_DEVICE_MAPPER
if (device_is_mapped (dev)) { if (grub_device_mapper_supported () && device_is_mapped (dev)) {
struct dm_task *task = NULL; struct dm_task *task = NULL;
grub_uint64_t start, length; grub_uint64_t start, length;
char *target_type, *params, *space; char *target_type, *params, *space;

View file

@ -22,6 +22,10 @@
#include <grub/time.h> #include <grub/time.h>
#include <grub/emu/misc.h> #include <grub/emu/misc.h>
#ifdef HAVE_DEVICE_MAPPER
# include <libdevmapper.h>
#endif
int verbosity; int verbosity;
void void
@ -311,3 +315,38 @@ grub_make_system_path_relative_to_its_root (const char *path)
return buf3; return buf3;
} }
#ifdef HAVE_DEVICE_MAPPER
static void device_mapper_null_log (int level __attribute__ ((unused)),
const char *file __attribute__ ((unused)),
int line __attribute__ ((unused)),
int dm_errno __attribute__ ((unused)),
const char *f __attribute__ ((unused)),
...)
{
}
int
grub_device_mapper_supported (void)
{
static int supported = -1;
if (supported == -1)
{
struct dm_task *dmt;
/* Suppress annoying log messages. */
dm_log_with_errno_init (&device_mapper_null_log);
dmt = dm_task_create (DM_DEVICE_VERSION);
supported = (dmt != NULL);
if (dmt)
dm_task_destroy (dmt);
/* Restore the original logger. */
dm_log_with_errno_init (NULL);
}
return supported;
}
#endif /* HAVE_DEVICE_MAPPER */

View file

@ -33,6 +33,7 @@
#include <grub/util/deviceiter.h> #include <grub/util/deviceiter.h>
#include <grub/list.h> #include <grub/list.h>
#include <grub/misc.h> #include <grub/misc.h>
#include <grub/emu/misc.h>
#ifdef __linux__ #ifdef __linux__
# if !defined(__GLIBC__) || \ # if !defined(__GLIBC__) || \
@ -676,112 +677,113 @@ grub_util_iterate_devices (int NESTED_FUNC_ATTR (*hook) (const char *, int),
} }
/* DM-RAID. */ /* DM-RAID. */
{ if (grub_device_mapper_supported ())
struct dm_tree *tree = NULL; {
struct dm_task *task = NULL; struct dm_tree *tree = NULL;
struct dm_names *names = NULL; struct dm_task *task = NULL;
unsigned int next = 0; struct dm_names *names = NULL;
void *top_handle, *second_handle; unsigned int next = 0;
struct dm_tree_node *root, *top, *second; void *top_handle, *second_handle;
struct dmraid_seen *seen = NULL; struct dm_tree_node *root, *top, *second;
struct dmraid_seen *seen = NULL;
/* Build DM tree for all devices. */ /* Build DM tree for all devices. */
tree = dm_tree_create (); tree = dm_tree_create ();
dmraid_check (tree, "dm_tree_create failed\n"); dmraid_check (tree, "dm_tree_create failed\n");
task = dm_task_create (DM_DEVICE_LIST); task = dm_task_create (DM_DEVICE_LIST);
dmraid_check (task, "dm_task_create failed\n"); dmraid_check (task, "dm_task_create failed\n");
dmraid_check (dm_task_run (task), "dm_task_run failed\n"); dmraid_check (dm_task_run (task), "dm_task_run failed\n");
names = dm_task_get_names (task); names = dm_task_get_names (task);
dmraid_check (names, "dm_task_get_names failed\n"); dmraid_check (names, "dm_task_get_names failed\n");
dmraid_check (names->dev, "No DM devices found\n"); dmraid_check (names->dev, "No DM devices found\n");
do do
{ {
names = (void *) names + next; names = (void *) names + next;
dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev), dmraid_check (dm_tree_add_dev (tree, MAJOR (names->dev),
MINOR (names->dev)), MINOR (names->dev)),
"dm_tree_add_dev (%s) failed\n", names->name); "dm_tree_add_dev (%s) failed\n", names->name);
next = names->next; next = names->next;
} }
while (next); while (next);
/* Walk the second-level children of the inverted tree; that is, devices /* Walk the second-level children of the inverted tree; that is, devices
which are directly composed of non-DM devices such as hard disks. which are directly composed of non-DM devices such as hard disks.
This class includes all DM-RAID disks and excludes all DM-RAID This class includes all DM-RAID disks and excludes all DM-RAID
partitions. */ partitions. */
root = dm_tree_find_node (tree, 0, 0); root = dm_tree_find_node (tree, 0, 0);
top_handle = NULL; top_handle = NULL;
top = dm_tree_next_child (&top_handle, root, 1); top = dm_tree_next_child (&top_handle, root, 1);
while (top) while (top)
{ {
second_handle = NULL; second_handle = NULL;
second = dm_tree_next_child (&second_handle, top, 1); second = dm_tree_next_child (&second_handle, top, 1);
while (second) while (second)
{ {
const char *node_name, *node_uuid; const char *node_name, *node_uuid;
char *name; char *name;
struct dmraid_seen *seen_elt; struct dmraid_seen *seen_elt;
node_name = dm_tree_node_get_name (second); node_name = dm_tree_node_get_name (second);
dmraid_check (node_name, "dm_tree_node_get_name failed\n"); dmraid_check (node_name, "dm_tree_node_get_name failed\n");
node_uuid = dm_tree_node_get_uuid (second); node_uuid = dm_tree_node_get_uuid (second);
dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n"); dmraid_check (node_uuid, "dm_tree_node_get_uuid failed\n");
if (strncmp (node_uuid, "DMRAID-", 7) != 0) if (strncmp (node_uuid, "DMRAID-", 7) != 0)
{ {
grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name); grub_dprintf ("deviceiter", "%s is not DM-RAID\n", node_name);
goto dmraid_next_child; goto dmraid_next_child;
} }
/* Have we already seen this node? There are typically very few /* Have we already seen this node? There are typically very few
DM-RAID disks, so a list should be fast enough. */ DM-RAID disks, so a list should be fast enough. */
if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name)) if (grub_named_list_find (GRUB_AS_NAMED_LIST (seen), node_name))
{ {
grub_dprintf ("deviceiter", "Already seen DM device %s\n", grub_dprintf ("deviceiter", "Already seen DM device %s\n",
node_name); node_name);
goto dmraid_next_child; goto dmraid_next_child;
} }
name = xasprintf ("/dev/mapper/%s", node_name); name = xasprintf ("/dev/mapper/%s", node_name);
if (check_device (name)) if (check_device (name))
{ {
if (hook (name, 0)) if (hook (name, 0))
{ {
free (name); free (name);
while (seen) while (seen)
{ {
struct dmraid_seen *seen_elt = struct dmraid_seen *seen_elt =
grub_list_pop (GRUB_AS_LIST_P (&seen)); grub_list_pop (GRUB_AS_LIST_P (&seen));
free (seen_elt); free (seen_elt);
} }
if (task) if (task)
dm_task_destroy (task); dm_task_destroy (task);
if (tree) if (tree)
dm_tree_free (tree); dm_tree_free (tree);
return; return;
} }
} }
free (name); free (name);
seen_elt = xmalloc (sizeof *seen_elt); seen_elt = xmalloc (sizeof *seen_elt);
seen_elt->name = node_name; seen_elt->name = node_name;
grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt)); grub_list_push (GRUB_AS_LIST_P (&seen), GRUB_AS_LIST (seen_elt));
dmraid_next_child: dmraid_next_child:
second = dm_tree_next_child (&second_handle, top, 1); second = dm_tree_next_child (&second_handle, top, 1);
} }
top = dm_tree_next_child (&top_handle, root, 1); top = dm_tree_next_child (&top_handle, root, 1);
} }
dmraid_end: dmraid_end:
while (seen) while (seen)
{ {
struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen)); struct dmraid_seen *seen_elt = grub_list_pop (GRUB_AS_LIST_P (&seen));
free (seen_elt); free (seen_elt);
} }
if (task) if (task)
dm_task_destroy (task); dm_task_destroy (task);
if (tree) if (tree)
dm_tree_free (tree); dm_tree_free (tree);
} }
# endif /* HAVE_DEVICE_MAPPER */ # endif /* HAVE_DEVICE_MAPPER */
#endif /* __linux__ */ #endif /* __linux__ */
} }