diff -Naurp parted_orig/include/parted/linux.h parted-multipath-name-fix/include/parted/linux.h --- parted_orig/include/parted/linux.h 2007-07-23 19:58:31.000000000 +0200 +++ parted-multipath-name-fix/include/parted/linux.h 2008-12-15 14:35:09.000000000 +0100 @@ -32,6 +32,7 @@ typedef struct _LinuxSpecific LinuxSpeci struct _LinuxSpecific { int fd; + char* dmtype; /**< device map target type */ #if defined(__s390__) || defined(__s390x__) unsigned int real_sector_size; /* IBM internal dasd structure (i guess ;), required. */ diff -Naurp parted_orig/libparted/arch/linux.c parted-multipath-name-fix/libparted/arch/linux.c --- parted_orig/libparted/arch/linux.c 2008-12-15 14:34:17.000000000 +0100 +++ parted-multipath-name-fix/libparted/arch/linux.c 2008-12-15 14:35:09.000000000 +0100 @@ -31,6 +31,7 @@ #include #include #include +#include #include #include #include @@ -296,6 +297,44 @@ _is_sx8_major (int major) #ifdef ENABLE_DEVICE_MAPPER static int +_dm_maptype (PedDevice *dev) +{ + LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); + struct dm_task *dmt; + void *next; + uint64_t start, length; + char *target_type = NULL; + char *params; + int r = -1; + const char* dev_dir = getenv ("DM_DEV_DIR"); + + if (dev_dir && *dev_dir && !dm_set_dev_dir(dev_dir)) + return r; + + if (!(dmt = dm_task_create(DM_DEVICE_TABLE))) + return r; + + if (!dm_task_set_name(dmt, dev->path)) + goto bad; + + dm_task_no_open_count(dmt); + + if (!dm_task_run(dmt)) + goto bad; + + next = dm_get_next_target(dmt, NULL, &start, &length, + &target_type, ¶ms); + + arch_specific->dmtype = strdup(target_type); + if (arch_specific->dmtype == NULL) + goto bad; + r = 0; +bad: + dm_task_destroy(dmt); + return r; +} + +static int readFD (int fd, char **buf) { char* p; @@ -485,6 +524,13 @@ _device_probe_type (PedDevice* dev) #ifdef ENABLE_DEVICE_MAPPER } else if (_is_dm_major(dev_major)) { dev->type = PED_DEVICE_DM; + if (_dm_maptype(dev)) { + ped_exception_throw ( + PED_EXCEPTION_BUG, + PED_EXCEPTION_CANCEL, + _("Unable to determine the dm type of %s."), + dev->path); + } #endif } else if (dev_major == XVD_MAJOR && (dev_minor % 0x10 == 0)) { dev->type = PED_DEVICE_XVD; @@ -1102,6 +1148,7 @@ static PedDevice* linux_new (const char* path) { PedDevice* dev; + LinuxSpecific* arch_specific; PED_ASSERT (path != NULL, return NULL); @@ -1117,6 +1164,8 @@ linux_new (const char* path) = (LinuxSpecific*) ped_malloc (sizeof (LinuxSpecific)); if (!dev->arch_specific) goto error_free_path; + arch_specific = LINUX_SPECIFIC (dev); + arch_specific->dmtype = NULL; dev->open_count = 0; dev->read_only = 0; @@ -1188,12 +1237,19 @@ linux_new (const char* path) goto error_free_arch_specific; break; -#ifdef ENABLE_DEVICE_MAPPER case PED_DEVICE_DM: - if (!init_generic (dev, _("Linux device-mapper"))) + { + char* type; + if (arch_specific->dmtype == NULL + || asprintf(&type, _("Linux device-mapper (%s)"), + arch_specific->dmtype) == -1) goto error_free_arch_specific; - break; -#endif + bool ok = init_generic (dev, type); + free (type); + if (!ok) + goto error_free_arch_specific; + break; + } case PED_DEVICE_XVD: if (!init_generic (dev, _("Xen Virtual Block Device"))) @@ -1226,10 +1282,11 @@ error: static void linux_destroy (PedDevice* dev) { - ped_free (dev->arch_specific); - ped_free (dev->path); - ped_free (dev->model); - ped_free (dev); + free (((LinuxSpecific*)dev->arch_specific)->dmtype); + free (dev->arch_specific); + free (dev->path); + free (dev->model); + free (dev); } static int @@ -1964,6 +2021,7 @@ _device_get_part_path (PedDevice* dev, i int path_len = strlen (dev->path); int result_len = path_len + 16; char* result; + LinuxSpecific* arch_specific = LINUX_SPECIFIC (dev); result = (char*) ped_malloc (result_len); if (!result) @@ -1976,12 +2034,17 @@ _device_get_part_path (PedDevice* dev, i /* replace /disc with /path%d */ strcpy (result, dev->path); snprintf (result + path_len - 5, 16, "/part%d", num); +#ifdef ENABLE_DEVICE_MAPPER + } else if (dev->type == PED_DEVICE_DM && arch_specific->dmtype && + strcmp(arch_specific->dmtype, "multipath") == 0) { + /* This is what multipath-tools upstream and Debian uses, it's + * a pure userpace (udev) decision! */ + snprintf (result, result_len, "%s_part%d", dev->path, num); +#endif } else if (dev->type == PED_DEVICE_DAC960 || dev->type == PED_DEVICE_CPQARRAY || dev->type == PED_DEVICE_ATARAID -#ifdef ENABLE_DEVICE_MAPPER || dev->type == PED_DEVICE_DM -#endif || isdigit (dev->path[path_len - 1])) snprintf (result, result_len, "%sp%d", dev->path, num); else