[lvm-devel] [PATCH 1/1] add dm remap functionality.
Sergei Shtepa
sergei.shtepa at veeam.com
Thu Jan 28 17:15:18 UTC 2021
dm remap allow to use blk_interposer.
Now we can use the "dmsetup remap" command to insert
any dm device into the block layer stack.
changes:
* add DM_DEV_REMAP ioctl.
* added bin_data field in struct dm_task. This can become
a more universal abstraction instead of the newname,
message and geometry fields.
Signed-off-by: Sergei Shtepa <sergei.shtepa at veeam.com>
---
device_mapper/all.h | 6 +-
device_mapper/ioctl/libdm-iface.c | 99 ++++++++++++++++++++++++-----
device_mapper/ioctl/libdm-targets.h | 2 +
device_mapper/libdm-common.c | 10 +--
device_mapper/misc/dm-ioctl.h | 16 ++++-
libdm/.exported_symbols.Base | 2 +
libdm/dm-tools/dmsetup.c | 63 ++++++++++++++++--
libdm/ioctl/libdm-iface.c | 91 +++++++++++++++++++++-----
libdm/ioctl/libdm-targets.h | 2 +
libdm/libdevmapper.h | 12 ++--
libdm/libdm-common.c | 10 +--
libdm/misc/dm-ioctl.h | 16 ++++-
12 files changed, 276 insertions(+), 53 deletions(-)
diff --git a/device_mapper/all.h b/device_mapper/all.h
index 1080d25ad..c248c6470 100644
--- a/device_mapper/all.h
+++ b/device_mapper/all.h
@@ -123,7 +123,9 @@ enum {
DM_DEVICE_ARM_POLL,
- DM_DEVICE_GET_TARGET_VERSION
+ DM_DEVICE_GET_TARGET_VERSION,
+
+ DM_DEVICE_REMAP
};
/*
@@ -226,6 +228,8 @@ int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
int dm_task_set_message(struct dm_task *dmt, const char *message);
int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
+int dm_task_set_remap_start(struct dm_task *dmt, const char *donor_device);
+int dm_task_set_remap_finish(struct dm_task *dmt);
int dm_task_no_flush(struct dm_task *dmt);
int dm_task_no_open_count(struct dm_task *dmt);
int dm_task_skip_lockfs(struct dm_task *dmt);
diff --git a/device_mapper/ioctl/libdm-iface.c b/device_mapper/ioctl/libdm-iface.c
index 8e7240673..cfe18705e 100644
--- a/device_mapper/ioctl/libdm-iface.c
+++ b/device_mapper/ioctl/libdm-iface.c
@@ -37,8 +37,8 @@
#endif
/*
- * Ensure build compatibility.
- * The hard-coded versions here are the highest present
+ * Ensure build compatibility.
+ * The hard-coded versions here are the highest present
* in the _cmd_data arrays.
*/
@@ -122,6 +122,9 @@ static struct cmd_data _cmd_data_v4[] = {
#ifdef DM_GET_TARGET_VERSION
{"target-version", DM_GET_TARGET_VERSION, {4, 41, 0}},
#endif
+#ifdef DM_DEV_REMAP
+ {"remap", DM_DEV_REMAP, {4, 44, 0}},
+#endif
};
/* *INDENT-ON* */
@@ -451,7 +454,7 @@ static int _open_control(void)
*/
if (!_open_and_assign_control_fd(control))
goto_bad;
-
+
if (!_create_dm_bitset(1)) {
log_error("Failed to set up list of device-mapper major numbers");
return 0;
@@ -510,6 +513,7 @@ void dm_task_destroy(struct dm_task *dmt)
free(dmt->newname);
free(dmt->message);
free(dmt->geometry);
+ free(dmt->bin_data);
free(dmt->uuid);
free(dmt->mangled_uuid);
free(dmt);
@@ -567,7 +571,7 @@ static int _check_version(char *version, size_t size, int log_suppress)
}
/*
- * Find out device-mapper's major version number the first time
+ * Find out device-mapper's major version number the first time
* this is called and whether or not we support it.
*/
int dm_check_version(void)
@@ -879,6 +883,59 @@ int dm_task_set_sector(struct dm_task *dmt, uint64_t sector)
return 1;
}
+int dm_task_set_remap_start(struct dm_task *dmt, const char *donor_device)
+{
+ size_t len;
+ uint32_t param_sz;
+ struct dm_remap_param *param;
+
+ len = strlen(donor_device);
+ if (!len) {
+ log_error("Invalid donor device name");
+ return 0;
+ }
+
+ param_sz = sizeof(struct dm_remap_param) + len + 1;
+ param = malloc(param_sz);
+ if (!param) {
+ log_error("Insufficient memory");
+ return 0;
+ }
+
+ param->cmd = REMAP_START_CMD;
+ if (!strcpy((char*)(param->params), donor_device)) {
+ log_error("Failed to copy donor device name");
+
+ free(param);
+ return 0;
+ }
+
+ dmt->bin_data = (uint8_t *)param;
+ dmt->bin_data_sz = param_sz;
+
+ return 1;
+}
+
+int dm_task_set_remap_finish(struct dm_task *dmt)
+{
+ uint32_t param_sz;
+ struct dm_remap_param *param;
+
+ param_sz = sizeof(struct dm_remap_param);
+ param = malloc(param_sz);
+ if (!param) {
+ log_error("Insufficient memory");
+ return 0;
+ }
+
+ param->cmd = REMAP_FINISH_CMD;
+
+ dmt->bin_data = (uint8_t *)param;
+ dmt->bin_data_sz = param_sz;
+
+ return 1;
+}
+
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads,
const char *sectors, const char *start)
{
@@ -1066,19 +1123,19 @@ static int _lookup_dev_name(uint64_t dev, char *buf, size_t len)
unsigned next = 0;
struct dm_task *dmt;
int r = 0;
-
+
if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
return 0;
-
+
if (!dm_task_run(dmt))
goto out;
if (!(names = dm_task_get_names(dmt)))
goto out;
-
+
if (!names->dev)
goto out;
-
+
do {
names = (struct dm_names *)((char *) names + next);
if (names->dev == dev) {
@@ -1167,6 +1224,11 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
return NULL;
}
+ if (dmt->bin_data && (dmt->geometry || dmt->message || dmt->newname)) {
+ log_error("binary data parameter are incompatible with geometry, message or newname");
+ return NULL;
+ }
+
if (dmt->newname)
len += strlen(dmt->newname) + 1;
@@ -1176,6 +1238,8 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
if (dmt->geometry)
len += strlen(dmt->geometry) + 1;
+ if (dmt->bin_data)
+ len += dmt->bin_data_sz;
/*
* Give len a minimum size so that we have space to store
* dependencies or status information.
@@ -1288,15 +1352,20 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
if (dmt->newname)
strcpy(b, dmt->newname);
- if (dmt->message) {
+ else if (dmt->message) {
tmsg = (struct dm_target_msg *) b;
tmsg->sector = dmt->sector;
strcpy(tmsg->message, dmt->message);
- }
- if (dmt->geometry)
+ } else if (dmt->geometry)
strcpy(b, dmt->geometry);
+ else if (dmt->bin_data) {
+ uint8_t *data = (uint8_t *)(dmi) + dmi->data_start;
+
+ memcpy(data, dmt->bin_data, dmt->bin_data_sz);
+ }
+
return dmi;
bad:
@@ -1606,7 +1675,7 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
t1 = t1->next;
t2 = t2->next;
}
-
+
if (!t1 && !t2) {
dmt->dmi.v4 = task->dmi.v4;
task->dmi.v4 = NULL;
@@ -1658,7 +1727,7 @@ static int _check_children_not_suspended_v4(struct dm_task *dmt, uint64_t device
task->event_nr = dmt->event_nr & DM_UDEV_FLAGS_MASK;
task->cookie_set = dmt->cookie_set;
task->add_node = dmt->add_node;
-
+
if (!(r = dm_task_run(task)))
goto out;
@@ -1675,7 +1744,7 @@ static int _check_children_not_suspended_v4(struct dm_task *dmt, uint64_t device
"(%u:%u)", info.major, info.minor);
else
log_error(INTERNAL_ERROR "Attempt to suspend device %s%s%s%.0d%s%.0d%s%s"
- "that uses already-suspended device (%u:%u)",
+ "that uses already-suspended device (%u:%u)",
DEV_NAME(dmt) ? : "", DEV_UUID(dmt) ? : "",
dmt->major > 0 ? "(" : "",
dmt->major > 0 ? dmt->major : 0,
@@ -2117,7 +2186,7 @@ repeat_ioctl:
MAJOR(dmi->dev), MINOR(dmi->dev),
dmt->read_ahead, dmt->read_ahead_flags);
break;
-
+
case DM_DEVICE_MKNODES:
if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmi->name, MAJOR(dmi->dev),
diff --git a/device_mapper/ioctl/libdm-targets.h b/device_mapper/ioctl/libdm-targets.h
index 9786a7eda..a4feae23d 100644
--- a/device_mapper/ioctl/libdm-targets.h
+++ b/device_mapper/ioctl/libdm-targets.h
@@ -50,6 +50,8 @@ struct dm_task {
union {
struct dm_ioctl *v4;
} dmi;
+ uint8_t *bin_data;
+ uint32_t bin_data_sz;
char *newname;
char *message;
char *geometry;
diff --git a/device_mapper/libdm-common.c b/device_mapper/libdm-common.c
index 9b87e4e74..a47e16e77 100644
--- a/device_mapper/libdm-common.c
+++ b/device_mapper/libdm-common.c
@@ -619,7 +619,7 @@ static int _dm_task_set_name_from_path(struct dm_task *dmt, const char *path,
/*
* Found directly.
* If supplied path points to same device as last component
- * under /dev/mapper, use that name directly.
+ * under /dev/mapper, use that name directly.
*/
if (dm_snprintf(buf, sizeof(buf), "%s/%s", _dm_dir, name) == -1) {
log_error("Couldn't create path for %s", name);
@@ -1371,7 +1371,7 @@ static int _set_dev_node_read_ahead(const char *dev_name,
if (current_read_ahead >= read_ahead) {
log_debug_activation("%s: retaining kernel read ahead of %" PRIu32
- " (requested %" PRIu32 ")",
+ " (requested %" PRIu32 ")",
dev_name, current_read_ahead, read_ahead);
return 1;
}
@@ -2438,7 +2438,7 @@ static int _udev_notify_sem_inc(uint32_t cookie, int semid)
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
- return 0;
+ return 0;
}
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
@@ -2642,6 +2642,8 @@ static const char *_task_type_disp(int type)
return "TARGET_MSG";
case DM_DEVICE_SET_GEOMETRY:
return "SET_GEOMETRY";
+ case DM_DEVICE_REMAP:
+ return "REMAP";
}
return "unknown";
}
@@ -2744,7 +2746,7 @@ static int _udev_wait(uint32_t cookie, int *nowait)
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
- return 0;
+ return 0;
}
if (val > 1)
diff --git a/device_mapper/misc/dm-ioctl.h b/device_mapper/misc/dm-ioctl.h
index 49954a764..f18564c7a 100644
--- a/device_mapper/misc/dm-ioctl.h
+++ b/device_mapper/misc/dm-ioctl.h
@@ -215,6 +215,16 @@ struct dm_target_msg {
char message[];
};
+enum {
+ REMAP_START_CMD = 1,
+ REMAP_FINISH_CMD,
+};
+
+struct dm_remap_param {
+ uint8_t cmd;
+ uint8_t params[0];
+};
+
/*
* If you change this make sure you make the corresponding change
* to dm-ioctl.c:lookup_ioctl()
@@ -245,6 +255,7 @@ enum {
DM_DEV_SET_GEOMETRY_CMD,
DM_DEV_ARM_POLL_CMD,
DM_GET_TARGET_VERSION_CMD,
+ DM_DEV_REMAP_CMD
};
#define DM_IOCTL 0xfd
@@ -260,6 +271,7 @@ enum {
#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
#define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, DM_DEV_ARM_POLL_CMD, struct dm_ioctl)
+#define DM_DEV_REMAP _IOWR(DM_IOCTL, DM_DEV_REMAP_CMD, struct dm_ioctl)
#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
@@ -274,9 +286,9 @@ enum {
#define DM_GET_TARGET_VERSION _IOWR(DM_IOCTL, DM_GET_TARGET_VERSION_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 36
+#define DM_VERSION_MINOR 44
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2017-06-09)"
+#define DM_VERSION_EXTRA "-ioctl (2020-12-25)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
diff --git a/libdm/.exported_symbols.Base b/libdm/.exported_symbols.Base
index 4dc5c936c..333e926eb 100644
--- a/libdm/.exported_symbols.Base
+++ b/libdm/.exported_symbols.Base
@@ -214,6 +214,8 @@ dm_task_set_name
dm_task_set_newname
dm_task_set_newuuid
dm_task_set_read_ahead
+dm_task_set_remap_start
+dm_task_set_remap_finish
dm_task_set_ro
dm_task_set_sector
dm_task_set_uid
diff --git a/libdm/dm-tools/dmsetup.c b/libdm/dm-tools/dmsetup.c
index 46fa81069..c027daef6 100644
--- a/libdm/dm-tools/dmsetup.c
+++ b/libdm/dm-tools/dmsetup.c
@@ -889,7 +889,7 @@ static int _display_info_cols(struct dm_task *dmt, struct dm_info *info)
if (!(_report_type & (DR_STATS | DR_STATS_META))) {
/*
- * If _selection_cmd is set we are applying -S to some other command, so suppress
+ * If _selection_cmd is set we are applying -S to some other command, so suppress
* output and run that other command if the device matches the criteria.
*/
if (!dm_report_object_is_selected(_report, &obj, _selection_cmd ? 0 : 1, &selected))
@@ -1297,7 +1297,7 @@ static int _create_concise(const struct command *cmd, int argc, char **argv)
*n++ = *c++;
continue;
- }
+ }
/* Comma marking end of field? */
if (*c == ',' && f < 4) {
@@ -1312,7 +1312,7 @@ static int _create_concise(const struct command *cmd, int argc, char **argv)
c++;
continue;
- }
+ }
/* Comma marking end of a table line? */
if (*c == ',' && f >= 4) {
@@ -1320,7 +1320,7 @@ static int _create_concise(const struct command *cmd, int argc, char **argv)
*n++ = '\n', c++;
continue;
- }
+ }
/* Semi-colon marking end of device? */
if (*c == ';' || *(c + 1) == '\0') {
@@ -1381,7 +1381,7 @@ static int _create_concise(const struct command *cmd, int argc, char **argv)
c++;
continue;
- }
+ }
/* Normal character */
*n++ = *c++;
@@ -1634,6 +1634,56 @@ static int _splitname(CMD_ARGS)
return r;
}
+static int _remap(CMD_ARGS)
+{
+ int r = 0;
+ struct dm_task *dmt;
+
+ if (!(dmt = dm_task_create(DM_DEVICE_REMAP)))
+ return_0;
+
+ if (argc < 1) {
+ log_error("Please provide remap command 'start' or 'finish'.");
+ goto out;
+ }
+ if (strcmp(argv[0], "start") == 0) {
+ if (argc < 3) {
+ log_error("Please provide a name for the acceptor dm device and donor device.");
+ goto out;
+ }
+
+ if (!_set_task_device(dmt, argv[1], 0))
+ goto_out;
+
+ if (!dm_task_set_remap_start(dmt, argv[2]))
+ goto_out;
+
+ } else if (strcmp(argv[0], "finish") == 0) {
+ if (argc < 2) {
+ log_error("Please provide a name for the acceptor dm device.");
+ goto out;
+ }
+
+ if (!_set_task_device(dmt, argv[1], 0))
+ goto_out;
+
+ if (!dm_task_set_remap_finish(dmt))
+ goto_out;
+ } else {
+ log_error("Invalid remap command. Supported only 'start' or 'finish'.");
+ goto out;
+ }
+
+ /* run the task */
+ if (!_task_run(dmt))
+ goto_out;
+
+ r = 1; /* success */
+out:
+ dm_task_destroy(dmt);
+ return r;
+}
+
static uint32_t _get_cookie_value(const char *str_value)
{
unsigned long int value;
@@ -2196,7 +2246,7 @@ static int _error_device(CMD_ARGS)
log_error("No device specified.");
return 0;
}
-
+
size = _get_device_size(name);
if (!(dmt = dm_task_create(DM_DEVICE_RELOAD)))
@@ -6275,6 +6325,7 @@ static struct command _dmsetup_commands[] = {
{"version", "", 0, 0, 0, 0, _version},
{"setgeometry", "<device> <cyl> <head> <sect> <start>", 5, 5, 0, 0, _setgeometry},
{"splitname", "<device> [<subsystem>]", 1, 2, 0, 0, _splitname},
+ {"remap", "<start | finish> <acceptor dm device> [<donor device>]", 2, 3, 0, 0, _remap},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c
index f4be478da..e7c618657 100644
--- a/libdm/ioctl/libdm-iface.c
+++ b/libdm/ioctl/libdm-iface.c
@@ -36,8 +36,8 @@
#include "libdm/misc/dm-ioctl.h"
/*
- * Ensure build compatibility.
- * The hard-coded versions here are the highest present
+ * Ensure build compatibility.
+ * The hard-coded versions here are the highest present
* in the _cmd_data arrays.
*/
@@ -121,6 +121,9 @@ static struct cmd_data _cmd_data_v4[] = {
#ifdef DM_GET_TARGET_VERSION
{"target-version", DM_GET_TARGET_VERSION, {4, 41, 0}},
#endif
+#ifdef DM_DEV_REMAP
+ {"remap", DM_DEV_REMAP, {4, 44, 0}},
+#endif
};
/* *INDENT-ON* */
@@ -450,7 +453,7 @@ static int _open_control(void)
*/
if (!_open_and_assign_control_fd(control))
goto_bad;
-
+
if (!_create_dm_bitset(1)) {
log_error("Failed to set up list of device-mapper major numbers");
return 0;
@@ -566,7 +569,7 @@ static int _check_version(char *version, size_t size, int log_suppress)
}
/*
- * Find out device-mapper's major version number the first time
+ * Find out device-mapper's major version number the first time
* this is called and whether or not we support it.
*/
int dm_check_version(void)
@@ -887,6 +890,59 @@ int dm_task_set_sector(struct dm_task *dmt, uint64_t sector)
return 1;
}
+int dm_task_set_remap_start(struct dm_task *dmt, const char *donor_device)
+{
+ size_t len;
+ uint32_t param_sz;
+ struct dm_remap_param *param;
+
+ len = strlen(donor_device);
+ if (!len) {
+ log_error("Invalid donor device name");
+ return 0;
+ }
+
+ param_sz = sizeof(struct dm_remap_param) + len + 1;
+ param = malloc(param_sz);
+ if (!param) {
+ log_error("Insufficient memory");
+ return 0;
+ }
+
+ param->cmd = REMAP_START_CMD;
+ if (!strcpy((char*)(param->params), donor_device)) {
+ log_error("Failed to copy donor device name");
+
+ free(param);
+ return 0;
+ }
+
+ dmt->bin_data = (uint8_t *)param;
+ dmt->bin_data_sz = param_sz;
+
+ return 1;
+}
+
+int dm_task_set_remap_finish(struct dm_task *dmt)
+{
+ uint32_t param_sz;
+ struct dm_remap_param *param;
+
+ param_sz = sizeof(struct dm_remap_param);
+ param = malloc(param_sz);
+ if (!param) {
+ log_error("Insufficient memory");
+ return 0;
+ }
+
+ param->cmd = REMAP_FINISH_CMD;
+
+ dmt->bin_data = (uint8_t *)param;
+ dmt->bin_data_sz = param_sz;
+
+ return 1;
+}
+
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads,
const char *sectors, const char *start)
{
@@ -1074,19 +1130,19 @@ static int _lookup_dev_name(uint64_t dev, char *buf, size_t len)
unsigned next = 0;
struct dm_task *dmt;
int r = 0;
-
+
if (!(dmt = dm_task_create(DM_DEVICE_LIST)))
return 0;
-
+
if (!dm_task_run(dmt))
goto out;
if (!(names = dm_task_get_names(dmt)))
goto out;
-
+
if (!names->dev)
goto out;
-
+
do {
names = (struct dm_names *)((char *) names + next);
if (names->dev == dev) {
@@ -1300,15 +1356,20 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt, unsigned repeat_count)
if (dmt->newname)
strcpy(b, dmt->newname);
- if (dmt->message) {
+ else if (dmt->message) {
tmsg = (struct dm_target_msg *) b;
tmsg->sector = dmt->sector;
strcpy(tmsg->message, dmt->message);
- }
- if (dmt->geometry)
+ } else if (dmt->geometry)
strcpy(b, dmt->geometry);
+ else if (dmt->bin_data) {
+ uint8_t *data = (uint8_t *)(dmi) + dmi->data_start;
+
+ memcpy(data, dmt->bin_data, dmt->bin_data_sz);
+ }
+
return dmi;
bad:
@@ -1606,7 +1667,7 @@ static int _reload_with_suppression_v4(struct dm_task *dmt)
t1 = t1->next;
t2 = t2->next;
}
-
+
if (!t1 && !t2) {
dmt->dmi.v4 = task->dmi.v4;
task->dmi.v4 = NULL;
@@ -1658,7 +1719,7 @@ static int _check_children_not_suspended_v4(struct dm_task *dmt, uint64_t device
task->event_nr = dmt->event_nr & DM_UDEV_FLAGS_MASK;
task->cookie_set = dmt->cookie_set;
task->add_node = dmt->add_node;
-
+
if (!(r = dm_task_run(task)))
goto out;
@@ -1675,7 +1736,7 @@ static int _check_children_not_suspended_v4(struct dm_task *dmt, uint64_t device
"(%u:%u)", info.major, info.minor);
else
log_error(INTERNAL_ERROR "Attempt to suspend device %s%s%s%.0d%s%.0d%s%s"
- "that uses already-suspended device (%u:%u)",
+ "that uses already-suspended device (%u:%u)",
DEV_NAME(dmt) ? : "", DEV_UUID(dmt) ? : "",
dmt->major > 0 ? "(" : "",
dmt->major > 0 ? dmt->major : 0,
@@ -2119,7 +2180,7 @@ repeat_ioctl:
MAJOR(dmi->dev), MINOR(dmi->dev),
dmt->read_ahead, dmt->read_ahead_flags);
break;
-
+
case DM_DEVICE_MKNODES:
if (dmi->flags & DM_EXISTS_FLAG)
add_dev_node(dmi->name, MAJOR(dmi->dev),
diff --git a/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h
index b5b20d5e9..16b9d87db 100644
--- a/libdm/ioctl/libdm-targets.h
+++ b/libdm/ioctl/libdm-targets.h
@@ -50,6 +50,8 @@ struct dm_task {
union {
struct dm_ioctl *v4;
} dmi;
+ uint8_t *bin_data;
+ uint32_t bin_data_sz;
char *newname;
char *message;
char *geometry;
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index a61ffe17e..a2064debc 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -117,14 +117,16 @@ enum {
DM_DEVICE_MKNODES,
DM_DEVICE_LIST_VERSIONS,
-
+
DM_DEVICE_TARGET_MSG,
DM_DEVICE_SET_GEOMETRY,
DM_DEVICE_ARM_POLL,
- DM_DEVICE_GET_TARGET_VERSION
+ DM_DEVICE_GET_TARGET_VERSION,
+
+ DM_DEVICE_REMAP
};
/*
@@ -227,6 +229,8 @@ int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
int dm_task_set_message(struct dm_task *dmt, const char *message);
int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
+int dm_task_set_remap_start(struct dm_task *dmt, const char *donor_device);
+int dm_task_set_remap_finish(struct dm_task *dmt);
int dm_task_no_flush(struct dm_task *dmt);
int dm_task_no_open_count(struct dm_task *dmt);
int dm_task_skip_lockfs(struct dm_task *dmt);
@@ -544,7 +548,7 @@ int dm_message_supports_precise_timestamps(void);
/*
* Precise timetamps and histogram support.
- *
+ *
* Test for the presence of precise_timestamps and histogram support.
*/
int dm_stats_driver_supports_precise(void);
@@ -3744,7 +3748,7 @@ int dm_udev_complete(uint32_t cookie);
int dm_udev_wait(uint32_t cookie);
/*
- * dm_dev_wait_immediate
+ * dm_dev_wait_immediate
* If *ready is 1 on return, the wait is complete.
* If *ready is 0 on return, the wait is incomplete and either
* this function or dm_udev_wait() must be called again.
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index a28829765..c2390cf90 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -617,7 +617,7 @@ static int _dm_task_set_name_from_path(struct dm_task *dmt, const char *path,
/*
* Found directly.
* If supplied path points to same device as last component
- * under /dev/mapper, use that name directly.
+ * under /dev/mapper, use that name directly.
*/
if (dm_snprintf(buf, sizeof(buf), "%s/%s", _dm_dir, name) == -1) {
log_error("Couldn't create path for %s", name);
@@ -1369,7 +1369,7 @@ static int _set_dev_node_read_ahead(const char *dev_name,
if (current_read_ahead >= read_ahead) {
log_debug_activation("%s: retaining kernel read ahead of %" PRIu32
- " (requested %" PRIu32 ")",
+ " (requested %" PRIu32 ")",
dev_name, current_read_ahead, read_ahead);
return 1;
}
@@ -2437,7 +2437,7 @@ static int _udev_notify_sem_inc(uint32_t cookie, int semid)
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
- return 0;
+ return 0;
}
log_debug_activation("Udev cookie 0x%" PRIx32 " (semid %d) incremented to %d",
@@ -2641,6 +2641,8 @@ static const char *_task_type_disp(int type)
return "TARGET_MSG";
case DM_DEVICE_SET_GEOMETRY:
return "SET_GEOMETRY";
+ case DM_DEVICE_REMAP:
+ return "REMAP";
}
return "unknown";
}
@@ -2743,7 +2745,7 @@ static int _udev_wait(uint32_t cookie, int *nowait)
log_error("semid %d: sem_ctl GETVAL failed for "
"cookie 0x%" PRIx32 ": %s",
semid, cookie, strerror(errno));
- return 0;
+ return 0;
}
if (val > 1)
diff --git a/libdm/misc/dm-ioctl.h b/libdm/misc/dm-ioctl.h
index 55dee2148..5c49aea12 100644
--- a/libdm/misc/dm-ioctl.h
+++ b/libdm/misc/dm-ioctl.h
@@ -215,6 +215,16 @@ struct dm_target_msg {
char message[];
};
+enum {
+ REMAP_START_CMD = 1,
+ REMAP_FINISH_CMD,
+};
+
+struct dm_remap_param {
+ uint8_t cmd;
+ uint8_t params[0];
+};
+
/*
* If you change this make sure you make the corresponding change
* to dm-ioctl.c:lookup_ioctl()
@@ -245,6 +255,7 @@ enum {
DM_DEV_SET_GEOMETRY_CMD,
DM_DEV_ARM_POLL_CMD,
DM_GET_TARGET_VERSION_CMD,
+ DM_DEV_REMAP_CMD
};
#define DM_IOCTL 0xfd
@@ -260,6 +271,7 @@ enum {
#define DM_DEV_STATUS _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, struct dm_ioctl)
#define DM_DEV_WAIT _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, struct dm_ioctl)
#define DM_DEV_ARM_POLL _IOWR(DM_IOCTL, DM_DEV_ARM_POLL_CMD, struct dm_ioctl)
+#define DM_DEV_REMAP _IOWR(DM_IOCTL, DM_DEV_REMAP_CMD, struct dm_ioctl)
#define DM_TABLE_LOAD _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, struct dm_ioctl)
#define DM_TABLE_CLEAR _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, struct dm_ioctl)
@@ -273,9 +285,9 @@ enum {
#define DM_GET_TARGET_VERSION _IOWR(DM_IOCTL, DM_GET_TARGET_VERSION_CMD, struct dm_ioctl)
#define DM_VERSION_MAJOR 4
-#define DM_VERSION_MINOR 36
+#define DM_VERSION_MINOR 44
#define DM_VERSION_PATCHLEVEL 0
-#define DM_VERSION_EXTRA "-ioctl (2017-06-09)"
+#define DM_VERSION_EXTRA "-ioctl (2020-12-25)"
/* Status bits */
#define DM_READONLY_FLAG (1 << 0) /* In/Out */
--
2.20.1
More information about the lvm-devel
mailing list