From d167da547da89c59b0c666f74f88887319562bb2 Mon Sep 17 00:00:00 2001 From: Alasdair Kergon Date: Tue, 8 Jun 2004 20:34:39 +0000 Subject: [PATCH] Support new target message ioctl. --- VERSION | 2 +- WHATS_NEW | 4 +++ dmsetup/dmsetup.c | 52 ++++++++++++++++++++++++++++-- kernel/ioctl/dm-ioctl.h | 67 +++++++++++++++++++++++++++++++++------ lib/.exported_symbols | 2 ++ lib/ioctl/libdm-compat.h | 1 + lib/ioctl/libdm-iface.c | 59 +++++++++++++++++++++++++++++++--- lib/ioctl/libdm-targets.h | 2 ++ lib/libdevmapper.h | 6 +++- 9 files changed, 178 insertions(+), 17 deletions(-) diff --git a/VERSION b/VERSION index 2f11365..5431b94 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.00.17-cvs (2004-04-19) +1.00.18-cvs (2004-06-08) diff --git a/WHATS_NEW b/WHATS_NEW index ae78594..2e35263 100644 --- a/WHATS_NEW +++ b/WHATS_NEW @@ -1,3 +1,7 @@ +Version 1.00.18 +============================= + Add target message-passing ioctl. + Version 1.00.17 - 17 Apr 2004 ============================= configure --with-owner= --with-group= to avoid -o and -g args to 'install' diff --git a/dmsetup/dmsetup.c b/dmsetup/dmsetup.c index f7d0b5e..555f413 100644 --- a/dmsetup/dmsetup.c +++ b/dmsetup/dmsetup.c @@ -248,6 +248,51 @@ static int _rename(int argc, char **argv, void *data) return r; } +static int _message(int argc, char **argv, void *data) +{ + int r = 0, sz = 1, i; + struct dm_task *dmt; + char *str; + + if (!(dmt = dm_task_create(DM_DEVICE_TARGET_MSG))) + return 0; + + if (!dm_task_set_name(dmt, argv[1])) + goto out; + + if (!dm_task_set_sector(dmt, atoll(argv[2]))) + goto out; + + argc -= 3; + argv += 3; + + for (i = 0; i < argc; i++) + sz += strlen(argv[i]) + 1; + + str = malloc(sz); + + for (i = 0; i < argc; i++) { + if (i) + strcat(str, " "); + strcat(str, argv[i]); + } + + if (!dm_task_set_message(dmt, str)) + goto out; + + free(str); + + if (!dm_task_run(dmt)) + goto out; + + r = 1; + + out: + dm_task_destroy(dmt); + + return r; +} + static int _version(int argc, char **argv, void *data) { int r = 0; @@ -264,8 +309,9 @@ static int _version(int argc, char **argv, void *data) goto out; if (!dm_task_get_driver_version(dmt, (char *) &version, - sizeof(version))) + sizeof(version))) { goto out; + } printf("Driver version: %s\n", version); @@ -623,6 +669,7 @@ static struct command _commands[] = { {"clear", "", 1, 1, _clear}, {"reload", " []", 1, 2, _reload}, {"rename", " ", 2, 2, _rename}, + {"message", " ", 3, -1, _message}, {"ls", "", 0, 0, _ls}, {"info", "[]", 0, 1, _info}, {"deps", "[]", 0, 1, _deps}, @@ -744,7 +791,8 @@ int main(int argc, char **argv) exit(1); } - if (argc < c->min_args + 1 || argc > c->max_args + 1) { + if (argc < c->min_args + 1 || + (c->max_args >= 0 && argc > c->max_args + 1)) { fprintf(stderr, "Incorrect number of arguments\n"); _usage(stderr); exit(1); diff --git a/kernel/ioctl/dm-ioctl.h b/kernel/ioctl/dm-ioctl.h index 3caa494..2a04be4 100644 --- a/kernel/ioctl/dm-ioctl.h +++ b/kernel/ioctl/dm-ioctl.h @@ -4,8 +4,8 @@ * This file is released under the LGPL. */ -#ifndef _LINUX_DM_IOCTL_H -#define _LINUX_DM_IOCTL_H +#ifndef _LINUX_DM_IOCTL_V4_H +#define _LINUX_DM_IOCTL_V4_H #include @@ -76,6 +76,9 @@ * * DM_TABLE_STATUS: * Return the targets status for the 'active' table. + * + * DM_TARGET_MSG: + * Pass a message string to the target at a specific offset of a device. */ /* @@ -129,8 +132,14 @@ struct dm_target_spec { int32_t status; /* used when reading from kernel only */ /* - * Offset in bytes (from the start of this struct) to - * next target_spec. + * Location of the next dm_target_spec. + * - When specifying targets on a DM_TABLE_LOAD command, this value is + * the number of bytes from the start of the "current" dm_target_spec + * to the start of the "next" dm_target_spec. + * - When retrieving targets on a DM_TABLE_STATUS command, this value + * is the number of bytes from the start of the first dm_target_spec + * (that follows the dm_ioctl struct) to the start of the "next" + * dm_target_spec. */ uint32_t next; @@ -172,6 +181,15 @@ struct dm_target_versions { char name[0]; }; +/* + * Used to pass message to a target + */ +struct dm_target_msg { + uint64_t sector; /* Device sector */ + + char message[0]; +}; + /* * If you change this make sure you make the corresponding change * to dm-ioctl.c:lookup_ioctl() @@ -198,8 +216,38 @@ enum { /* Added later */ DM_LIST_VERSIONS_CMD, + DM_TARGET_MSG_CMD, }; +/* + * The dm_ioctl struct passed into the ioctl is just the header + * on a larger chunk of memory. On x86-64 and other + * architectures the dm-ioctl struct will be padded to an 8 byte + * boundary so the size will be different, which would change the + * ioctl code - yes I really messed up. This hack forces these + * architectures to have the correct ioctl code. + */ +#ifdef CONFIG_COMPAT +typedef char ioctl_struct[308]; +#define DM_VERSION_32 _IOWR(DM_IOCTL, DM_VERSION_CMD, ioctl_struct) +#define DM_REMOVE_ALL_32 _IOWR(DM_IOCTL, DM_REMOVE_ALL_CMD, ioctl_struct) +#define DM_LIST_DEVICES_32 _IOWR(DM_IOCTL, DM_LIST_DEVICES_CMD, ioctl_struct) + +#define DM_DEV_CREATE_32 _IOWR(DM_IOCTL, DM_DEV_CREATE_CMD, ioctl_struct) +#define DM_DEV_REMOVE_32 _IOWR(DM_IOCTL, DM_DEV_REMOVE_CMD, ioctl_struct) +#define DM_DEV_RENAME_32 _IOWR(DM_IOCTL, DM_DEV_RENAME_CMD, ioctl_struct) +#define DM_DEV_SUSPEND_32 _IOWR(DM_IOCTL, DM_DEV_SUSPEND_CMD, ioctl_struct) +#define DM_DEV_STATUS_32 _IOWR(DM_IOCTL, DM_DEV_STATUS_CMD, ioctl_struct) +#define DM_DEV_WAIT_32 _IOWR(DM_IOCTL, DM_DEV_WAIT_CMD, ioctl_struct) + +#define DM_TABLE_LOAD_32 _IOWR(DM_IOCTL, DM_TABLE_LOAD_CMD, ioctl_struct) +#define DM_TABLE_CLEAR_32 _IOWR(DM_IOCTL, DM_TABLE_CLEAR_CMD, ioctl_struct) +#define DM_TABLE_DEPS_32 _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, ioctl_struct) +#define DM_TABLE_STATUS_32 _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, ioctl_struct) +#define DM_LIST_VERSIONS_32 _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, ioctl_struct) +#define DM_TARGET_MSG_32 _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, ioctl_struct) +#endif + #define DM_IOCTL 0xfd #define DM_VERSION _IOWR(DM_IOCTL, DM_VERSION_CMD, struct dm_ioctl) @@ -218,12 +266,13 @@ enum { #define DM_TABLE_DEPS _IOWR(DM_IOCTL, DM_TABLE_DEPS_CMD, struct dm_ioctl) #define DM_TABLE_STATUS _IOWR(DM_IOCTL, DM_TABLE_STATUS_CMD, struct dm_ioctl) #define DM_LIST_VERSIONS _IOWR(DM_IOCTL, DM_LIST_VERSIONS_CMD, struct dm_ioctl) - +#define DM_TARGET_MSG _IOWR(DM_IOCTL, DM_TARGET_MSG_CMD, struct dm_ioctl) + #define DM_VERSION_MAJOR 4 -#define DM_VERSION_MINOR 1 -#define DM_VERSION_PATCHLEVEL 1 -#define DM_VERSION_EXTRA "-ioctl-cvs (2004-04-07)" - +#define DM_VERSION_MINOR 2 +#define DM_VERSION_PATCHLEVEL 0 +#define DM_VERSION_EXTRA "-ioctl (2004-06-08)" + /* Status bits */ #define DM_READONLY_FLAG (1 << 0) /* In/Out */ #define DM_SUSPEND_FLAG (1 << 1) /* In/Out */ diff --git a/lib/.exported_symbols b/lib/.exported_symbols index 1b7ab16..01fe677 100644 --- a/lib/.exported_symbols +++ b/lib/.exported_symbols @@ -17,6 +17,8 @@ dm_task_set_newname dm_task_set_event_nr dm_task_set_major dm_task_set_minor +dm_task_set_sector +dm_task_set_message dm_task_add_target dm_get_next_target dm_task_run diff --git a/lib/ioctl/libdm-compat.h b/lib/ioctl/libdm-compat.h index 4f8e4b4..ed6e85f 100644 --- a/lib/ioctl/libdm-compat.h +++ b/lib/ioctl/libdm-compat.h @@ -115,6 +115,7 @@ static struct cmd_data _cmd_data_v1[] = { { "clear", 0, {4, 0, 0} }, { "mknodes", 0, {4, 0, 0} }, { "versions", 0, {4, 1, 0} }, + { "message", 0, {4, 2, 0} }, }; /* *INDENT-ON* */ diff --git a/lib/ioctl/libdm-iface.c b/lib/ioctl/libdm-iface.c index 555bfe7..3c72e9d 100644 --- a/lib/ioctl/libdm-iface.c +++ b/lib/ioctl/libdm-iface.c @@ -93,6 +93,9 @@ static struct cmd_data _cmd_data_v4[] = { #ifdef DM_LIST_VERSIONS {"versions", DM_LIST_VERSIONS, {4, 1, 0}}, #endif +#ifdef DM_TARGET_MSG + {"message", DM_TARGET_MSG, {4, 2, 0}}, +#endif }; /* *INDENT-ON* */ @@ -146,6 +149,9 @@ void dm_task_destroy(struct dm_task *dmt) if (dmt->newname) free(dmt->newname); + if (dmt->message) + free(dmt->message); + if (dmt->dmi.v4) free(dmt->dmi.v4); @@ -190,8 +196,9 @@ static int _unmarshal_status_v1(struct dm_task *dmt, struct dm_ioctl_v1 *dmi) if (!dm_task_add_target(dmt, spec->sector_start, (uint64_t) spec->length, spec->target_type, - outptr + sizeof(*spec))) + outptr + sizeof(*spec))) { return 0; + } outptr = outbuf + spec->next; } @@ -652,8 +659,9 @@ static int _unmarshal_status(struct dm_task *dmt, struct dm_ioctl *dmi) if (!dm_task_add_target(dmt, spec->sector_start, spec->length, spec->target_type, - outptr + sizeof(*spec))) + outptr + sizeof(*spec))) { return 0; + } outptr = outbuf + spec->next; } @@ -775,6 +783,23 @@ int dm_task_set_newname(struct dm_task *dmt, const char *newname) return 1; } +int dm_task_set_message(struct dm_task *dmt, const char *message) +{ + if (!(dmt->message = strdup(message))) { + log_error("dm_task_set_message: strdup(%s) failed", message); + return 0; + } + + return 1; +} + +int dm_task_set_sector(struct dm_task *dmt, uint64_t sector) +{ + dmt->sector = sector; + + return 1; +} + int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr) { dmt->event_nr = event_nr; @@ -861,6 +886,7 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt) struct dm_ioctl *dmi; struct target *t; + struct dm_target_msg *tmsg; size_t len = sizeof(struct dm_ioctl); void *b, *e; int count = 0; @@ -871,14 +897,32 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt) count++; } + if (count && (dmt->sector || dmt->message)) { + log_error("targets and message are incompatible"); + return NULL; + } + if (count && dmt->newname) { log_error("targets and newname are incompatible"); return NULL; } + if (dmt->newname && (dmt->sector || dmt->message)) { + log_error("message and newname are incompatible"); + return NULL; + } + + if (dmt->sector && !dmt->message) { + log_error("message is required with sector"); + return NULL; + } + if (dmt->newname) len += strlen(dmt->newname) + 1; + if (dmt->message) + len += sizeof(struct dm_target_msg) + strlen(dmt->message) + 1; + /* * Give len a minimum size so that we have space to store * dependencies or status information. @@ -933,6 +977,12 @@ static struct dm_ioctl *_flatten(struct dm_task *dmt) if (dmt->newname) strcpy(b, dmt->newname); + if (dmt->message) { + tmsg = (struct dm_target_msg *) b; + tmsg->sector = dmt->sector; + strcpy(tmsg->message, dmt->message); + } + return dmi; bad: @@ -1118,8 +1168,9 @@ int dm_task_run(struct dm_task *dmt) dmi->flags |= DM_STATUS_TABLE_FLAG; dmi->flags |= DM_EXISTS_FLAG; /* FIXME */ - log_debug("dm %s %s %s %s", _cmd_data_v4[dmt->type].name, dmi->name, - dmi->uuid, dmt->newname ? dmt->newname : ""); + log_debug("dm %s %s %s %s%.0llu %s", _cmd_data_v4[dmt->type].name, + dmi->name, dmi->uuid, dmt->newname ? dmt->newname : "", + dmt->sector, dmt->message ? dmt->message : ""); if (ioctl(_control_fd, command, dmi) < 0) { if (errno == ENXIO && ((dmt->type == DM_DEVICE_INFO) || (dmt->type == DM_DEVICE_MKNODES))) { diff --git a/lib/ioctl/libdm-targets.h b/lib/ioctl/libdm-targets.h index 498b961..97fa866 100644 --- a/lib/ioctl/libdm-targets.h +++ b/lib/ioctl/libdm-targets.h @@ -45,6 +45,8 @@ struct dm_task { struct dm_ioctl_v1 *v1; } dmi; char *newname; + char *message; + uint64_t sector; char *uuid; }; diff --git a/lib/libdevmapper.h b/lib/libdevmapper.h index 7d838ef..f0aeccd 100644 --- a/lib/libdevmapper.h +++ b/lib/libdevmapper.h @@ -68,7 +68,9 @@ enum { DM_DEVICE_MKNODES, - DM_DEVICE_LIST_VERSIONS + DM_DEVICE_LIST_VERSIONS, + + DM_DEVICE_TARGET_MSG }; struct dm_task; @@ -130,6 +132,8 @@ int dm_task_set_newname(struct dm_task *dmt, const char *newname); int dm_task_set_minor(struct dm_task *dmt, int minor); int dm_task_set_major(struct dm_task *dmt, int major); int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr); +int dm_task_set_message(struct dm_task *dmt, const char *message); +int dm_task_set_sector(struct dm_task *dmt, uint64_t sector); /* * Use these to prepare for a create or reload. -- 2.43.5