summaryrefslogtreecommitdiffstats
path: root/libdm
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2011-07-01 14:09:19 +0000
committerAlasdair Kergon <agk@redhat.com>2011-07-01 14:09:19 +0000
commit2243718faef6ae371d7ebb8e70addb23cd062ca0 (patch)
tree97821946502435ad7d059ea9f4d22e35e0167b67 /libdm
parentb3c42d7cc1f51c4c66fe09ec6049ff7d8ee2f0bf (diff)
downloadlvm2-2243718faef6ae371d7ebb8e70addb23cd062ca0.tar.gz
lvm2-2243718faef6ae371d7ebb8e70addb23cd062ca0.tar.xz
lvm2-2243718faef6ae371d7ebb8e70addb23cd062ca0.zip
Add framework for validation of ioctls. Doesn't do any checks yet.
dmsetup --checks libdevmapper: dm_task_enable_checks() lvm.conf: activation/checks=1
Diffstat (limited to 'libdm')
-rw-r--r--libdm/ioctl/libdm-iface.c16
-rw-r--r--libdm/ioctl/libdm-targets.h1
-rw-r--r--libdm/libdevmapper.h6
-rw-r--r--libdm/libdm-common.c7
4 files changed, 29 insertions, 1 deletions
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index da492018..cfc19b62 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -1884,6 +1884,16 @@ no_match:
return r;
}
+static int _suspend_with_validation_v4(struct dm_task *dmt)
+{
+ /*
+ * FIXME Ensure we can't leave any I/O trapped between suspended devices.
+ */
+ dmt->enable_checks = 0;
+
+ return dm_task_run(dmt);
+}
+
static const char *_sanitise_message(char *message)
{
const char *sanitised_message = message ?: "";
@@ -1963,7 +1973,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
}
log_debug("dm %s %s%s %s%s%s %s%.0d%s%.0d%s"
- "%s%c%c%s%s%s%s %.0" PRIu64 " %s [%u]",
+ "%s%c%c%s%s%s%s%s %.0" PRIu64 " %s [%u]",
_cmd_data_v4[dmt->type].name,
dmt->new_uuid ? "UUID " : "",
dmi->name, dmi->uuid, dmt->newname ? " " : "",
@@ -1980,6 +1990,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
dmt->skip_lockfs ? "S " : "",
dmt->secure_data ? "W " : "",
dmt->query_inactive_table ? "I " : "",
+ dmt->enable_checks ? "C" : "",
dmt->sector, _sanitise_message(dmt->message),
dmi->data_size);
#ifdef DM_IOCTLS
@@ -2054,6 +2065,9 @@ int dm_task_run(struct dm_task *dmt)
if ((dmt->type == DM_DEVICE_RELOAD) && dmt->suppress_identical_reload)
return _reload_with_suppression_v4(dmt);
+ if ((dmt->type == DM_DEVICE_SUSPEND) && dmt->enable_checks)
+ return _suspend_with_validation_v4(dmt);
+
if (!_open_control()) {
_udev_complete(dmt);
return 0;
diff --git a/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h
index d8cca844..d61ccfda 100644
--- a/libdm/ioctl/libdm-targets.h
+++ b/libdm/ioctl/libdm-targets.h
@@ -65,6 +65,7 @@ struct dm_task {
int cookie_set;
int new_uuid;
int secure_data;
+ int enable_checks;
char *uuid;
};
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index a3ae8807..340e6e51 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -190,6 +190,12 @@ int dm_task_skip_lockfs(struct dm_task *dmt);
int dm_task_query_inactive_table(struct dm_task *dmt);
int dm_task_suppress_identical_reload(struct dm_task *dmt);
int dm_task_secure_data(struct dm_task *dmt);
+
+/*
+ * Enable checks for common mistakes such as issuing ioctls in an unsafe order.
+ */
+int dm_task_enable_checks(struct dm_task *dmt);
+
typedef enum {
DM_ADD_NODE_ON_RESUME, /* add /dev/mapper node with dmsetup resume */
DM_ADD_NODE_ON_CREATE /* add /dev/mapper node with dmsetup create */
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index fa6746a0..31a44e72 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -395,6 +395,13 @@ int dm_task_set_mode(struct dm_task *dmt, mode_t mode)
return 1;
}
+int dm_task_enable_checks(struct dm_task *dmt)
+{
+ dmt->enable_checks = 1;
+
+ return 1;
+}
+
int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
const char *ttype, const char *params)
{