Package: grub-common Version: 1.98+20100804-2 Severity: important Tags: patch sid squeeze
Hello, current versions of grub-probe in squeeze and sid have problems with DMRAID partitions. The problems are demonstrated below. As a result, grub lenny->squeeze upgrade failed leaving my system without a bootloader. While grub-common/lenny had no support for DMRAID at all, it would be a pity to release current grub-common with half working DMRAID support. Therefore, it would be great if the bug was fixed in squeeze. A proposed patch is attached to this mail. Please forward the bug and/or the patch upstream. As you see, the root is mounted on the DMRAID partition. $ mount /dev/mapper/pdc_bacfhgjjjc1 on / type ext3 (rw,errors=remount-ro) tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755) proc on /proc type proc (rw,noexec,nosuid,nodev) sysfs on /sys type sysfs (rw,noexec,nosuid,nodev) udev on /dev type tmpfs (rw,mode=0755) tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev) devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620) fusectl on /sys/fs/fuse/connections type fusectl (rw) /dev/mapper/lvmmain-usr on /usr type ext3 (rw,errors=remount-ro) /dev/mapper/lvmmain-var on /var type ext3 (rw,errors=remount-ro) /dev/mapper/lvmmain-home on /home type ext3 (rw,errors=remount-ro) /dev/mapper/lvmmain-data on /mnt/data type ext3 (rw,user_xattr,errors=remount-ro) binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,noexec,nosuid,nodev) $ cat /boot/grub/device.map (fd0) /dev/fd0 (hd0) /dev/disk/by-id/ata-WDC_WD800BB-00DKA0_WD-WMAHL3755817 (hd1) /dev/disk/by-id/ata-WDC_WD800BB-00DKA0_WD-WMAHL3848610 (hd2) /dev/mapper/pdc_bacfhgjjjc $ ls -l /dev/mapper total 0 crw------- 1 root root 10, 59 Rgp 24 13:19 control lrwxrwxrwx 1 root root 7 Rgp 24 13:19 lvmmain-data -> ../dm-6 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 lvmmain-home -> ../dm-5 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 lvmmain-swap -> ../dm-7 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 lvmmain-usr -> ../dm-4 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 lvmmain-var -> ../dm-3 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 pdc_bacfhgjjjc -> ../dm-0 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 pdc_bacfhgjjjc1 -> ../dm-1 lrwxrwxrwx 1 root root 7 Rgp 24 13:19 pdc_bacfhgjjjc2 -> ../dm-2 The attached patch fixes the following issues. The first two prevent grub-install from working when / is mounted to a partition on the DMRAID disk. Before patching (1.98+20100804-4): # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/mapper/pdc_bacfhgjjjc1 grub-probe: error: cannot find a GRUB drive for /dev/mapper/pdc_bacfhgjjjc1. Check your device.map. # grub-probe --device-map=/boot/grub/device.map --target=fs / grub-probe: error: cannot find a GRUB drive for /dev/mapper/pdc_bacfhgjjjc1. Check your device.map. # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/dm-1 (/dev/dm-1) # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/mapper/pdc_bacfhgjjjc (hd2) # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/dm-0 (hd2) After patching: # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/mapper/pdc_bacfhgjjjc1 (hd2,msdos1) # grub-probe --device-map=/boot/grub/device.map --target=fs / ext2 # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/dm-1 (hd2,msdos1) # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/mapper/pdc_bacfhgjjjc (hd2) # grub-probe --device-map=/boot/grub/device.map --target=drive -d /dev/dm-0 (hd2) The patch also fixes a memory leak which I discovered when fixing the above (error message originates from libdevmapper): # grub-probe --device-map=/boot/grub/device.map --target=fs / ext2 You have a memory leak (not released memory pool): [0x88157e0] -- Modestas Vainius <[email protected]>
From: Modestas Vainius <[email protected]> Subject: fix DMRAID support in grub-probe Forwarded: no Last-Update: 2010-08-24 /dev/mapper/* are symlinks to /dev/dm-* and convert_system_partition_to_system_disk() checks against fully a canonicalized real path. Therefore, it should look for dm-* when identifying DMRAID devices. Likewise, return the same form (/dev/mapper/* or /dev/dm-$minor) which was asked for in the input. This is needed since strcmp() is typically used by the callers to check if returned device is the same as given. While at it, the patch also fixes a memory pool leak in dm_* related code. devmapper library complains loudly about memory pool leaks. --- a/kern/emu/hostdisk.c +++ b/kern/emu/hostdisk.c @@ -1157,13 +1157,14 @@ convert_system_partition_to_system_disk #ifdef HAVE_DEVICE_MAPPER /* If this is a DM-RAID device. */ - if ((strncmp ("mapper/", p, 7) == 0)) + if ((strncmp ("mapper/", p, 7) == 0) + || (strncmp("dm-", p, 3) == 0)) { - static struct dm_tree *tree = NULL; + struct dm_tree *tree = NULL; uint32_t maj, min; - struct dm_tree_node *node, *child; + struct dm_tree_node *node, *child, *mapper_node = NULL; void *handle; - const char *node_uuid, *mapper_name, *child_uuid, *child_name; + const char *node_uuid, *child_uuid; if (! tree) tree = dm_tree_create (); @@ -1171,6 +1172,7 @@ convert_system_partition_to_system_disk if (! tree) { grub_dprintf ("hostdisk", "dm_tree_create failed\n"); + free(path); return NULL; } @@ -1179,29 +1181,29 @@ convert_system_partition_to_system_disk if (! dm_tree_add_dev (tree, maj, min)) { grub_dprintf ("hostdisk", "dm_tree_add_dev failed\n"); - return NULL; + goto devmapper_out; } node = dm_tree_find_node (tree, maj, min); if (! node) { grub_dprintf ("hostdisk", "dm_tree_find_node failed\n"); - return NULL; + goto devmapper_out; } node_uuid = dm_tree_node_get_uuid (node); if (! node_uuid) { grub_dprintf ("hostdisk", "%s has no DM uuid\n", path); - return NULL; + goto devmapper_out; } else if (strncmp (node_uuid, "DMRAID-", 7) != 0) { grub_dprintf ("hostdisk", "%s is not DM-RAID\n", path); - return NULL; + goto devmapper_out; } handle = NULL; - mapper_name = NULL; + mapper_node = node; /* Counter-intuitively, device-mapper refers to the disk-like device containing a DM-RAID partition device as a "child" of the partition device. */ @@ -1222,26 +1224,47 @@ convert_system_partition_to_system_disk grub_dprintf ("hostdisk", "%s child is not DM-RAID\n", path); goto devmapper_out; } - child_name = dm_tree_node_get_name (child); - if (! child_name) + mapper_node = child; + +devmapper_out: + if (! mapper_node) { - grub_dprintf ("hostdisk", "%s child has no DM name\n", path); - goto devmapper_out; + /* Unable get info about parent node */ + free(path); + dm_tree_free(tree); + return NULL; } - mapper_name = child_name; -devmapper_out: - if (! mapper_name) + if ((strncmp ("/dev/dm-", os_dev, 8) == 0)) { - /* This is a DM-RAID disk, not a partition. */ - mapper_name = dm_tree_node_get_name (node); - if (! mapper_name) + /* Give a dm-$minor */ + const struct dm_info *info; + info = dm_tree_node_get_info (mapper_node); + if (! info) + { + grub_dprintf ("hostdisk", "%s has no DM info\n", path); + free(path); + dm_tree_free(tree); + return NULL; + } + snprintf (path, PATH_MAX, "/dev/dm-%u", info->minor); + } + else + { + /* Otherwise give a long name that is more user-friendly */ + const char *name; + name = dm_tree_node_get_name (mapper_node); + if (! name) { grub_dprintf ("hostdisk", "%s has no DM name\n", path); + free(path); + dm_tree_free(tree); return NULL; } + snprintf (path, PATH_MAX, "/dev/mapper/%s", name); } - return xasprintf ("/dev/mapper/%s", mapper_name); + dm_tree_free (tree); + return path; } #endif /* HAVE_DEVICE_MAPPER */ } @@ -1354,6 +1377,21 @@ find_system_device (const char *os_dev, os_disk = convert_system_partition_to_system_disk (os_dev, st); if (! os_disk) return -1; +#ifdef __linux__ + /* On Linux, map[i].device is passed through realpath(). See + read_device_map(). Hence use realpath'ed os_disk for strcmp() */ + { + char *rp; + rp = xmalloc (PATH_MAX); + if (realpath (os_disk, rp)) + { + free(os_disk); + os_disk = rp; + } + else + free(rp); + } +#endif for (i = 0; i < ARRAY_SIZE (map); i++) if (! map[i].device)
signature.asc
Description: This is a digitally signed message part.

