summaryrefslogtreecommitdiff
path: root/libparted/arch/linux.c
diff options
context:
space:
mode:
authorPhillip Susi <psusi@ubuntu.com>2012-10-19 17:32:00 +0200
committerJim Meyering <jim@meyering.net>2012-10-29 21:52:38 +0100
commit3cb820632a13a91e0c2e579aedbe8e86b4f0040e (patch)
treead217944b9b127dd1669e3d44063c82bd0fa9e52 /libparted/arch/linux.c
parentf87ff28d1aa8eff085e737ab22d031b0519e5510 (diff)
downloadparted-3cb820632a13a91e0c2e579aedbe8e86b4f0040e.tar.gz
libparted: don't probe every dm device in probe_all
We were probing every dm device. Only probe dmraid whole disk (non-partition) devices instead. This removes the clutter of LVM logical volumes, and dmraid partitions from the list, which usually do not make sense to partition. * NEWS (Changes in behavior): Mention it. * libparted/arch/linux.c (_is_dmraid_device): New function. (_dm_is_part): Likewise. (_probe_dm_devices): Use the latter. * tests/t6003-dm-hide.sh: New test. * tests/Makefile.am (TESTS): Add it.
Diffstat (limited to 'libparted/arch/linux.c')
-rw-r--r--libparted/arch/linux.c81
1 files changed, 80 insertions, 1 deletions
diff --git a/libparted/arch/linux.c b/libparted/arch/linux.c
index 5721d4b..083591f 100644
--- a/libparted/arch/linux.c
+++ b/libparted/arch/linux.c
@@ -65,6 +65,8 @@
# define _GL_ATTRIBUTE_FORMAT(spec) /* empty */
#endif
+#define STRPREFIX(a, b) (strncmp (a, b, strlen (b)) == 0)
+
#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))
#ifndef __NR__llseek
@@ -478,6 +480,82 @@ bad:
return r;
}
+/* Return nonzero if device-mapper device, DEVPATH, is part of a dmraid
+ array. Use the heuristic of checking for the string "DMRAID-" at the
+ start of its UUID. */
+static int
+_is_dmraid_device (const char *devpath)
+{
+ int rc = 0;
+
+ char const *dm_name = strrchr (devpath, '/');
+ char const *dm_basename = dm_name && *(++dm_name) ? dm_name : devpath;
+ struct dm_task *task = dm_task_create (DM_DEVICE_DEPS);
+ if (!task)
+ return 0;
+
+ dm_task_set_name (task, dm_basename);
+ if (!dm_task_run (task))
+ goto err;
+
+ const char *dmraid_uuid = dm_task_get_uuid (task);
+ if (STRPREFIX (dmraid_uuid, "DMRAID-"))
+ rc = 1;
+
+err:
+ dm_task_destroy (task);
+ return rc;
+}
+
+/* We consider a dm device that is a linear mapping with a *
+ * single target that also is a dm device to be a partition */
+
+static int
+_dm_is_part (const char *path)
+{
+ int rc = 0;
+ struct dm_task *task = dm_task_create (DM_DEVICE_DEPS);
+ if (!task)
+ return 0;
+
+ dm_task_set_name(task, path);
+ if (!dm_task_run(task))
+ goto err;
+
+ struct dm_info *info = alloca (sizeof *info);
+ memset(info, '\0', sizeof *info);
+ dm_task_get_info (task, info);
+ if (!info->exists)
+ goto err;
+
+ struct dm_deps *deps = dm_task_get_deps (task);
+ if (!deps)
+ goto err;
+
+ if (deps->count != 1)
+ goto err;
+ if (!_is_dm_major (major (deps->device[0])))
+ goto err;
+ dm_task_destroy (task);
+ if (!(task = dm_task_create (DM_DEVICE_TABLE)))
+ return 0;
+ dm_task_set_name (task, path);
+ if (!dm_task_run (task))
+ goto err;
+
+ char *target_type = NULL;
+ char *params = NULL;
+ uint64_t start, length;
+
+ dm_get_next_target (task, NULL, &start, &length, &target_type, &params);
+ if (strcmp (target_type, "linear"))
+ goto err;
+ rc = 1;
+
+err:
+ dm_task_destroy(task);
+ return rc;
+}
static int
_probe_dm_devices ()
@@ -504,7 +582,8 @@ _probe_dm_devices ()
if (stat (buf, &st) != 0)
continue;
- if (_is_dm_major(major(st.st_rdev)))
+ if (_is_dm_major(major(st.st_rdev)) && _is_dmraid_device (buf)
+ && !_dm_is_part(buf))
_ped_device_probe (buf);
}
closedir (mapper_dir);