summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2018-11-16 15:57:15 +0100
committerZdenek Kabelac <zkabelac@redhat.com>2018-11-17 00:30:50 +0100
commit43f8da76997a22be123e97b6d0f357d6ec2d0c7c (patch)
treec89101baba624968a4b6cccb6fdfef90d7738cde
parent1ae5bf2b833a5d55cf97de1619cc820d4e8c394f (diff)
downloadlvm2-43f8da76997a22be123e97b6d0f357d6ec2d0c7c.tar.gz
libdm: print params only for ioctls using them
When preparing ioctl buffer and flatting all parameters, add table parameters only to ioctl that do process them. Note: list of ioctl should be kept in sync with kernel code.
-rw-r--r--WHATS_NEW_DM1
-rw-r--r--device_mapper/ioctl/libdm-iface.c37
-rw-r--r--libdm/ioctl/libdm-iface.c37
3 files changed, 59 insertions, 16 deletions
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index c19d9a8a0..aa1734c91 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.155 -
====================================
+ Enhance ioctl flattening and add parameters only when needed.
Add DM_DEVICE_ARM_POLL for API completness matching kernel.
Do not add parameters for RESUME with DM_DEVICE_CREATE dm task.
diff --git a/device_mapper/ioctl/libdm-iface.c b/device_mapper/ioctl/libdm-iface.c
index 31a4bc099..1321dc008 100644
--- a/device_mapper/ioctl/libdm-iface.c
+++ b/device_mapper/ioctl/libdm-iface.c
@@ -1085,6 +1085,22 @@ static int _lookup_dev_name(uint64_t dev, char *buf, size_t len)
return r;
}
+static int _add_params(int type)
+{
+ switch (type) {
+ case DM_DEVICE_REMOVE_ALL:
+ case DM_DEVICE_CREATE:
+ case DM_DEVICE_REMOVE:
+ case DM_DEVICE_SUSPEND:
+ case DM_DEVICE_STATUS:
+ case DM_DEVICE_CLEAR:
+ case DM_DEVICE_ARM_POLL:
+ return 0; /* IOCTL_FLAGS_NO_PARAMS in drivers/md/dm-ioctl.c */
+ default:
+ return 1;
+ }
+}
+
static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
{
const size_t min_size = 16 * 1024;
@@ -1097,11 +1113,15 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
char *b, *e;
int count = 0;
- for (t = dmt->head; t; t = t->next) {
- len += sizeof(struct dm_target_spec);
- len += strlen(t->params) + 1 + ALIGNMENT;
- count++;
- }
+ if (_add_params(dmt->type))
+ for (t = dmt->head; t; t = t->next) {
+ len += sizeof(struct dm_target_spec);
+ len += strlen(t->params) + 1 + ALIGNMENT;
+ count++;
+ }
+ else if (dmt->head)
+ log_debug_activation(INTERNAL_ERROR "dm '%s' ioctl should not define parameters.",
+ _cmd_data_v4[dmt->type].name);
if (count && (dmt->sector || dmt->message)) {
log_error("targets and message are incompatible");
@@ -1251,9 +1271,10 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
b = (char *) (dmi + 1);
e = (char *) dmi + len;
- for (t = dmt->head; t; t = t->next)
- if (!(b = _add_target(t, b, e)))
- goto_bad;
+ if (_add_params(dmt->type))
+ for (t = dmt->head; t; t = t->next)
+ if (!(b = _add_target(t, b, e)))
+ goto_bad;
if (dmt->newname)
strcpy(b, dmt->newname);
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index 6e73b1d03..002669e8d 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -1097,6 +1097,22 @@ static int _lookup_dev_name(uint64_t dev, char *buf, size_t len)
return r;
}
+static int _add_params(int type)
+{
+ switch (type) {
+ case DM_DEVICE_REMOVE_ALL:
+ case DM_DEVICE_CREATE:
+ case DM_DEVICE_REMOVE:
+ case DM_DEVICE_SUSPEND:
+ case DM_DEVICE_STATUS:
+ case DM_DEVICE_CLEAR:
+ case DM_DEVICE_ARM_POLL:
+ return 0; /* IOCTL_FLAGS_NO_PARAMS in drivers/md/dm-ioctl.c */
+ default:
+ return 1;
+ }
+}
+
static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
{
const size_t min_size = 16 * 1024;
@@ -1109,11 +1125,15 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
char *b, *e;
int count = 0;
- for (t = dmt->head; t; t = t->next) {
- len += sizeof(struct dm_target_spec);
- len += strlen(t->params) + 1 + ALIGNMENT;
- count++;
- }
+ if (_add_params(dmt->type))
+ for (t = dmt->head; t; t = t->next) {
+ len += sizeof(struct dm_target_spec);
+ len += strlen(t->params) + 1 + ALIGNMENT;
+ count++;
+ }
+ else if (dmt->head)
+ log_debug_activation(INTERNAL_ERROR "dm '%s' ioctl should not define parameters.",
+ _cmd_data_v4[dmt->type].name);
if (count && (dmt->sector || dmt->message)) {
log_error("targets and message are incompatible");
@@ -1263,9 +1283,10 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
b = (char *) (dmi + 1);
e = (char *) dmi + len;
- for (t = dmt->head; t; t = t->next)
- if (!(b = _add_target(t, b, e)))
- goto_bad;
+ if (_add_params(dmt->type))
+ for (t = dmt->head; t; t = t->next)
+ if (!(b = _add_target(t, b, e)))
+ goto_bad;
if (dmt->newname)
strcpy(b, dmt->newname);