Merge common RAID and LVM logic to an abstract diskfilter.

Add LDM support using the same framework.

	* Makefile.util.def (libgrubkern): Add grub-core/disk/ldm.c,
	grub-core/disk/diskfilter.c and grub-core/partmap/gpt.c.
	(libgrubmods): Remove grub-core/disk/raid.c and
	grub-core/partmap/gpt.c.
	* grub-core/Makefile.core.def (ldm): New module.
	(raid): Renamed to diskfilter. All users updated.
	* grub-core/disk/raid.c: Moved to ...
	* grub-core/disk/diskfilter.c: ... here.
	* grub-core/disk/diskfilter.c: Rename grub_raid_ to grub_diskfilter_.
	(lv_num): New var.
	(find_array): Renamed to ...
	(find_lv): ... this. Support multi-LV. Skip nameless LVs
	(grub_is_array_readable): Renamed to ...
	(grub_is_lv_readable): ... this. Support multinode hierarchy.
	(insert_array): New argument id.
	(is_node_readable): New function.
	(scan_device): Rename to ...
	(scan_disk): .. this. Restrict to one disk.
	(scan_devices): New function.
	(grub_diskfilter_iterate): Support multi-LV.
	Skip invisible and nameless LVs.
	(grub_diskfilter_memberlist): Support multi-LV.
	(grub_diskfilter_read_node): New function.
	(grub_raid_read): Most of logic moved to ...
	(read_segment): ... here
	(read_lv): New function.
	(grub_diskfilter_get_vg_by_uuid): New function.
	(grub_diskfilter_make_raid): Likewise.
	* grub-core/disk/ldm.c: New file.
	* grub-core/disk/lvm.c (vg_list): Removed.
	(lv_count): Likewise.
	(scan_depth): Likewise.
	(is_lv_readable): Likewise.
	(grub_lvm_getvalue): Advance pointer past the number.
	(find_lv): Removed.
	(do_lvm_scan): Refactored into ...
	(grub_lvm_detect): ... this. Support raid.
	(grub_lvm_iterate): Removed.
	(grub_lvm_memberlist): Likewise.
	(grub_lvm_open): Likewise.
	(grub_lvm_close): Likewise.
	(read_lv): Likewise.
	(read_node): Likewise.
	(is_node_readable): Likewise.
	(is_lv_readable): Likewise.
	(grub_lvm_read): Likewise.
	(grub_lvm_write): Likewise.
	(grub_lvm_dev): Use diskfilter
	(GRUB_MOD_INIT): Likewise.
	(GRUB_MOD_FINI): Likewise.
	* grub-core/disk/dmraid_nvidia.c (grub_dmraid_nv_detect): Use
	new interface.
	* grub-core/disk/mdraid1x_linux.c (grub_mdraid_detect): Likewise.
	* grub-core/disk/mdraid_linux.c (grub_mdraid_detect): Likewise.
	* grub-core/disk/raid5_recover.c (grub_raid5_recover): Use
	grub_diskfilter_read_node.
	Fix a bug with xor.
	* grub-core/disk/raid6_recover.c (grub_raid6_recover): Use
	grub_diskfilter_read_node.
	Support GRUB_RAID_LAYOUT_MUL_FROM_POS.
	* grub-core/kern/disk.c (grub_disk_dev_list): Make global.
	(grub_disk_dev_iterate): Move from here...
	* include/grub/disk.h (grub_disk_dev_iterate): ... to here. Inlined.
	* grub-core/kern/emu/hostdisk.c (grub_hostdisk_find_partition_start):
	Make global.
	(grub_hostdisk_find_partition_start): Likewise.
	(grub_hostdisk_os_dev_to_grub_drive): New function.
	(grub_util_biosdisk_get_osdev): Check that disk is biosdisk.
	* grub-core/kern/emu/hostdisk.c (make_device_name): Move to ...
	* util/getroot.c (make_device_name): ... here.
	* grub-core/kern/emu/hostdisk.c (grub_util_get_dm_node_linear_info):
	Move to ...
	* util/getroot.c (grub_util_get_dm_node_linear_info): ...here.
	* grub-core/kern/emu/hostdisk.c
	(convert_system_partition_to_system_disk): Move to ...
	* util/getroot.c (convert_system_partition_to_system_disk): ...here.
	* grub-core/kern/emu/hostdisk.c (device_is_wholedisk): Move to ...
	* util/getroot.c (device_is_wholedisk): ... here.
	* grub-core/kern/emu/hostdisk.c (find_system_device): Move to ...
	* util/getroot.c (find_system_device): ... here.
	* grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_present):
	Move to ...
	* util/getroot.c (grub_util_biosdisk_is_present): ...here.
	* grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_get_grub_dev):
	Move to ...
	* util/getroot.c (grub_util_biosdisk_get_grub_dev): ... here.
	Handle LDM.
	* grub-core/kern/emu/hostdisk.c (grub_util_biosdisk_is_floppy):
	Move to ...
	* util/getroot.c (grub_util_biosdisk_is_floppy): ... here.
	* grub-core/partmap/gpt.c (grub_gpt_partition_map_iterate): Made global.
	* include/grub/disk.h (grub_disk_dev_id): Replaced RAID and LVM with
	DISKFILTER.
	* include/grub/raid.h: Renamed to ...
	* include/grub/diskfilter.h: ... this.
	* include/grub/diskfilter.h: Rename grub_raid_* to grub_diskfilter_*
	(GRUB_RAID_LAYOUT_*): Make into array.
	(GRUB_RAID_LAYOUT_MUL_FROM_POS): New value.
	(grub_diskfilter_vg): New struct.
	(grub_diskfilter_pv_id): Likewise.
	(grub_raid_member): Removed.
	(grub_raid_array): Likewise.
	(grub_diskfilter_pv): New struct.
	(grub_diskfilter_lv): Likewise.
	(grub_diskfilter_segment): Likewise.
	(grub_diskfilter_node): Likewise.
	(grub_diskfilter_get_vg_by_uuid): New proto.
	(grub_raid_register): Inline.
	(grub_diskfilter_unregister): Likewise.
	(grub_diskfilter_make_raid): New proto.
	(grub_diskfilter_vg_register): Likewise.
	(grub_diskfilter_read_node): Likewise.
	(grub_diskfilter_get_pv_from_disk) [GRUB_UTIL]: Likewise.
	* include/grub/emu/hostdisk.h (grub_util_get_ldm): New proto.
	(grub_util_is_ldm): Likewise.
	(grub_util_ldm_embed) [GRUB_UTIL]: Likewise.
	(grub_hostdisk_find_partition_start): Likewise.
	(grub_hostdisk_os_dev_to_grub_drive): Likewise.
	* include/grub/gpt_partition.h (GRUB_GPT_PARTITION_TYPE_LDM):
	New definition.
	(grub_gpt_partition_map_iterate): New proto.
	* include/grub/lvm.h (grub_lvm_vg): Removed.
	(grub_lvm_pv): Likewise.
	(grub_lvm_lv): Likewise.
	(grub_lvm_segment): Likewise.
	(grub_lvm_node): Likewise.
	* util/getroot.c [...]
	* util/grub-probe.c (probe_raid_level): Handle diskfilter.
	(probe_abstraction): Likewise.
	* util/grub-setup.c (setup): Remove must_embed. Support LDM.
	(main): Remove dead logic.
This commit is contained in:
Vladimir 'phcoder' Serbinenko 2012-01-29 14:28:01 +01:00
parent 8a7f9b9c50
commit 076e7c0fda
27 changed files with 4249 additions and 3052 deletions

View file

@ -133,7 +133,7 @@ write_rootdev (char *core_img, grub_device_t root_dev,
static void
setup (const char *dir,
const char *boot_file, const char *core_file,
const char *root, const char *dest, int must_embed, int force,
const char *root, const char *dest, int force,
int fs_probe, int allow_floppy)
{
char *boot_path, *core_path, *core_path_dev, *core_path_dev_full;
@ -281,6 +281,7 @@ setup (const char *dir,
grub_partition_map_t dest_partmap = NULL;
grub_partition_t container = dest_dev->disk->partition;
int multiple_partmaps = 0;
int is_ldm;
grub_err_t err;
grub_disk_addr_t *sectors;
int i;
@ -328,6 +329,8 @@ setup (const char *dir,
if (!fs)
grub_errno = GRUB_ERR_NONE;
is_ldm = grub_util_is_ldm (dest_dev->disk);
#ifdef GRUB_MACHINE_PCBIOS
if (fs_probe)
{
@ -352,6 +355,17 @@ setup (const char *dir,
"result in FILESYSTEM DESTRUCTION if valuable data is overwritten "
"by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"), dest_dev->disk->name, dest_partmap->name);
if (is_ldm && dest_partmap && strcmp (dest_partmap->name, "msdos") != 0
&& strcmp (dest_partmap->name, "gpt") != 0)
grub_util_error (_("%s appears to contain a %s partition map and "
"LDM which isn't known to be a safe combination."
" Installing GRUB there could "
"result in FILESYSTEM DESTRUCTION if valuable data"
" is overwritten "
"by grub-setup (--skip-fs-probe disables this "
"check, use at your own risk)"),
dest_dev->disk->name, dest_partmap->name);
}
#endif
@ -364,14 +378,14 @@ setup (const char *dir,
free (tmp_img);
if (! dest_partmap && ! fs)
if (! dest_partmap && ! fs && !is_ldm)
{
grub_util_warn (_("Attempting to install GRUB to a partitionless disk or to a partition. This is a BAD idea."));
goto unable_to_embed;
}
if (multiple_partmaps || (dest_partmap && fs))
if (multiple_partmaps || (dest_partmap && fs) || (is_ldm && fs))
{
grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels or both partition label and filesystem. This is not supported yet."));
grub_util_warn (_("Attempting to install GRUB to a disk with multiple partition labels. This is not supported yet."));
goto unable_to_embed;
}
@ -390,7 +404,10 @@ setup (const char *dir,
}
nsec = core_sectors;
if (dest_partmap)
if (is_ldm)
err = grub_util_ldm_embed (dest_dev->disk, &nsec,
GRUB_EMBED_PCBIOS, &sectors);
else if (dest_partmap)
err = dest_partmap->embed (dest_dev->disk, &nsec,
GRUB_EMBED_PCBIOS, &sectors);
else
@ -485,14 +502,16 @@ setup (const char *dir,
unable_to_embed:
if (must_embed)
grub_util_error (_("embedding is not possible, but this is required when "
"the root device is on a RAID array or LVM volume"));
#ifdef GRUB_MACHINE_PCBIOS
if (dest_dev->disk->id != root_dev->disk->id)
if (dest_dev->disk->id != root_dev->disk->id
|| dest_dev->disk->dev->id != root_dev->disk->dev->id)
grub_util_error (_("embedding is not possible, but this is required for "
"cross-disk install"));
"cross-disk, RAID and LVM install"));
#else
if (dest_dev->disk->dev->id != root_dev->disk->dev->id)
grub_util_error (_("embedding is not possible, but this is required for "
"RAID and LVM install"));
#endif
grub_util_warn (_("Embedding is not possible. GRUB can only be installed in this "
@ -853,7 +872,6 @@ main (int argc, char *argv[])
{
char *root_dev = NULL;
char *dest_dev = NULL;
int must_embed = 0;
struct arguments arguments;
set_program_name (argv[0]);
@ -888,8 +906,8 @@ main (int argc, char *argv[])
grub_lvm_fini ();
grub_mdraid09_fini ();
grub_mdraid1x_fini ();
grub_raid_fini ();
grub_raid_init ();
grub_diskfilter_fini ();
grub_diskfilter_init ();
grub_mdraid09_init ();
grub_mdraid1x_init ();
grub_lvm_init ();
@ -944,53 +962,12 @@ main (int argc, char *argv[])
arguments.dir ? : DEFAULT_DIRECTORY);
}
#if defined(__linux__) || defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
if (grub_util_lvm_isvolume (root_dev))
must_embed = 1;
#endif
#ifdef __linux__
if (root_dev[0] == 'm' && root_dev[1] == 'd'
&& ((root_dev[2] >= '0' && root_dev[2] <= '9') || root_dev[2] == '/'))
{
/* FIXME: we can avoid this on RAID1. */
must_embed = 1;
}
if (dest_dev[0] == 'm' && dest_dev[1] == 'd'
&& ((dest_dev[2] >= '0' && dest_dev[2] <= '9') || dest_dev[2] == '/'))
{
char **devicelist;
int i;
if (arguments.device[0] == '/')
devicelist = grub_util_raid_getmembers (arguments.device, 1);
else
{
char *devname;
devname = xasprintf ("/dev/%s", dest_dev);
devicelist = grub_util_raid_getmembers (dest_dev, 1);
free (devname);
}
for (i = 0; devicelist[i]; i++)
{
setup (arguments.dir ? : DEFAULT_DIRECTORY,
arguments.boot_file ? : DEFAULT_BOOT_FILE,
arguments.core_file ? : DEFAULT_CORE_FILE,
root_dev, grub_util_get_grub_dev (devicelist[i]), 1,
arguments.force, arguments.fs_probe,
arguments.allow_floppy);
}
}
else
#endif
/* Do the real work. */
setup (arguments.dir ? : DEFAULT_DIRECTORY,
arguments.boot_file ? : DEFAULT_BOOT_FILE,
arguments.core_file ? : DEFAULT_CORE_FILE,
root_dev, dest_dev, must_embed, arguments.force,
arguments.fs_probe, arguments.allow_floppy);
/* Do the real work. */
setup (arguments.dir ? : DEFAULT_DIRECTORY,
arguments.boot_file ? : DEFAULT_BOOT_FILE,
arguments.core_file ? : DEFAULT_CORE_FILE,
root_dev, dest_dev, arguments.force,
arguments.fs_probe, arguments.allow_floppy);
/* Free resources. */
grub_fini_all ();