parted/fix-multipath-part-name.patch

167 lines
5.9 KiB
Diff

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 <stdio.h>
#include <syscall.h>
#include <unistd.h>
+#include <stdbool.h>
#include <dirent.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
@@ -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, &params);
+
+ 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