diff options
author | Phillip Susi <psusi@ubuntu.com> | 2012-10-19 17:32:00 +0200 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2012-10-29 21:52:38 +0100 |
commit | 3cb820632a13a91e0c2e579aedbe8e86b4f0040e (patch) | |
tree | ad217944b9b127dd1669e3d44063c82bd0fa9e52 /libparted/arch/linux.c | |
parent | f87ff28d1aa8eff085e737ab22d031b0519e5510 (diff) | |
download | parted-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.c | 81 |
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, ¶ms); + 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); |