summaryrefslogtreecommitdiffstats
path: root/libdm/ioctl
diff options
context:
space:
mode:
authorPeter Rajnoha <prajnoha@redhat.com>2012-02-15 12:01:28 +0000
committerPeter Rajnoha <prajnoha@redhat.com>2012-02-15 12:01:28 +0000
commit573e57f83fef8264a776333a4977086d7bb02821 (patch)
tree0ccd44c4f6b3e5d9aa45a82487f1f526ba05e0df /libdm/ioctl
parent69a82801efa9901a1e19464b4b2f770701e7993a (diff)
downloadlvm2-573e57f83fef8264a776333a4977086d7bb02821.tar.gz
lvm2-573e57f83fef8264a776333a4977086d7bb02821.tar.xz
lvm2-573e57f83fef8264a776333a4977086d7bb02821.zip
Unamngle dm device name list automatically on ioctl return.
If dm_task_get_name or dm_task_get_names gets called, these will return unmangled form of the names so the name mangling stays totally transparent to any libdevmapper user (unless DM_STRING_MANGLING_NONE is used in which case the name is not touched and it is is returned as it is in kernel). For example: dmsetup create "a b" - will create a\x20b device in kernel and so udev will create /dev/mapper/a\x20b dm_task_get_name/names will still return "a b" In AUTO mode, the libdevmapper user can still query the device by using the mangled ("a\x20b") or unmangled form of the name when calling dm_task_set_name. If mangled name is provided, it's detected and the name is kept as it is. If unmangled name is provided, it will be mangled. IOW in AUTO mode it's totally transparent and it should not require any changes in the code using libdevmapper. However, any libdevmapper user must be aware of the fact that the mangled form of the name appears in /dev/mapper (udev just can't deal with those blacklisted characters).
Diffstat (limited to 'libdm/ioctl')
-rw-r--r--libdm/ioctl/libdm-iface.c35
1 files changed, 35 insertions, 0 deletions
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index 83e81719..c5734e33 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -1523,6 +1523,39 @@ static const char *_sanitise_message(char *message)
return sanitised_message;
}
+static void _do_dm_ioctl_unmangle_name(char *name)
+{
+ char buf[DM_NAME_LEN];
+ int r;
+
+ if ((r = unmangle_name(name, DM_NAME_LEN, buf, sizeof(buf),
+ dm_get_name_mangling_mode())) < 0)
+ log_debug("_do_dm_ioctl_unmangle_name: failed to "
+ "unmangle \"%s\"", name);
+ else if (r)
+ memcpy(name, buf, strlen(buf) + 1);
+}
+
+static void _dm_ioctl_unmangle_names(int type, struct dm_ioctl *dmi)
+{
+ struct dm_names *names;
+ unsigned next = 0;
+ char *name;
+
+ if ((name = dmi->name))
+ _do_dm_ioctl_unmangle_name(name);
+
+ if (type == DM_DEVICE_LIST &&
+ ((names = ((struct dm_names *) ((char *)dmi + dmi->data_start)))) &&
+ names->dev) {
+ do {
+ names = (struct dm_names *)((char *) names + next);
+ _do_dm_ioctl_unmangle_name(names->name);
+ next = names->next;
+ } while (next);
+ }
+}
+
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
unsigned buffer_repeat_count,
unsigned retry_repeat_count,
@@ -1651,6 +1684,8 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
_udev_complete(dmt);
}
+ (void) _dm_ioctl_unmangle_names(dmt->type, dmi);
+
#else /* Userspace alternative for testing */
#endif
return dmi;