* 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:
parent
da90820083
commit
e0f4c43882
5 changed files with 152 additions and 97 deletions
10
ChangeLog
10
ChangeLog
|
@ -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.
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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__ */
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue