libdm and dmsetup: support strings returned by message This patch adds a new function dm_task_get_message_result that returns string returned by a message. It also modifies the "dmsetup message" command so that it prints the returned string. Signed-off-by: Mikulas Patocka --- libdm/ioctl/libdm-iface.c | 19 +++++++++++++++++++ libdm/libdevmapper.h | 1 + libdm/misc/dm-ioctl.h | 5 +++++ tools/dmsetup.c | 9 +++++++++ 4 files changed, 34 insertions(+) Index: lvm2-copy/libdm/ioctl/libdm-iface.c =================================================================== --- lvm2-copy.orig/libdm/ioctl/libdm-iface.c 2013-07-19 20:25:45.000000000 +0200 +++ lvm2-copy/libdm/ioctl/libdm-iface.c 2013-07-19 20:25:48.000000000 +0200 @@ -700,6 +700,24 @@ struct dm_versions *dm_task_get_versions dmt->dmi.v4->data_start); } +const char *dm_task_get_message_result(struct dm_task *dmt) +{ + const char *start, *end; + if (!(dmt->dmi.v4->flags & DM_DATA_OUT_FLAG)) + return NULL; + start = (const char *) dmt->dmi.v4 + dmt->dmi.v4->data_start; + end = (const char *) dmt->dmi.v4 + dmt->dmi.v4->data_size; + if (end < start) { + log_error(INTERNAL_ERROR "Corrupted message structure returned: %d > %d", (int)dmt->dmi.v4->data_start, (int)dmt->dmi.v4->data_size); + return NULL; + } + if (!memchr(start, 0, end - start)) { + log_error(INTERNAL_ERROR "Message result doesn't contain terminating nul character"); + return NULL; + } + return start; +} + int dm_task_set_ro(struct dm_task *dmt) { dmt->read_only = 1; @@ -1870,6 +1888,7 @@ repeat_ioctl: case DM_DEVICE_STATUS: case DM_DEVICE_TABLE: case DM_DEVICE_WAITEVENT: + case DM_DEVICE_TARGET_MSG: _ioctl_buffer_double_factor++; _dm_zfree_dmi(dmi); goto repeat_ioctl; Index: lvm2-copy/libdm/libdevmapper.h =================================================================== --- lvm2-copy.orig/libdm/libdevmapper.h 2013-07-19 20:25:40.000000000 +0200 +++ lvm2-copy/libdm/libdevmapper.h 2013-07-19 20:25:48.000000000 +0200 @@ -186,6 +186,7 @@ const char *dm_task_get_uuid(const struc struct dm_deps *dm_task_get_deps(struct dm_task *dmt); struct dm_versions *dm_task_get_versions(struct dm_task *dmt); +const char *dm_task_get_message_result(struct dm_task *dmt); /* * These functions return device-mapper names based on the value Index: lvm2-copy/tools/dmsetup.c =================================================================== --- lvm2-copy.orig/tools/dmsetup.c 2013-07-19 20:25:47.000000000 +0200 +++ lvm2-copy/tools/dmsetup.c 2013-07-19 20:25:48.000000000 +0200 @@ -770,6 +770,7 @@ static int _message(CMD_ARGS) size_t sz = 1; struct dm_task *dmt; char *str; + const char *result; uint64_t sector; char *endptr; @@ -833,6 +834,14 @@ static int _message(CMD_ARGS) if (!dm_task_run(dmt)) goto out; + result = dm_task_get_message_result(dmt); + if (result) { + if (!*result || result[strlen(result) - 1] == '\n') + fputs(result, stdout); + else + puts(result); + } + r = 1; out: