]> sourceware.org Git - dm.git/commitdiff
Support new target message ioctl.
authorAlasdair Kergon <agk@redhat.com>
Tue, 8 Jun 2004 20:34:39 +0000 (20:34 +0000)
committerAlasdair Kergon <agk@redhat.com>
Tue, 8 Jun 2004 20:34:39 +0000 (20:34 +0000)
VERSION
WHATS_NEW
dmsetup/dmsetup.c
kernel/ioctl/dm-ioctl.h
lib/.exported_symbols
lib/ioctl/libdm-compat.h
lib/ioctl/libdm-iface.c
lib/ioctl/libdm-targets.h
lib/libdevmapper.h

diff --git a/VERSION b/VERSION
index 2f113652c1e505325ea0ac8b1a48911763b5ea1b..5431b94898f7fab4c3d2b4bd20d7a1090596c23f 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.00.17-cvs (2004-04-19)
+1.00.18-cvs (2004-06-08)
index ae78594f9e6711bb2f4060e85257e8d508c62c56..2e3526370aae0d4e799975847f8414e3e5205d98 100644 (file)
--- 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'
index f7d0b5e793b558ef92b9bd6f27146e9b97c4588d..555f413bc50d917ae76ed69cff448a41a27ef67f 100644 (file)
@@ -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", "<dev_name>", 1, 1, _clear},
        {"reload", "<dev_name> [<table_file>]", 1, 2, _reload},
        {"rename", "<dev_name> <new_name>", 2, 2, _rename},
+       {"message", "<dev_name> <sector> <message>", 3, -1, _message},
        {"ls", "", 0, 0, _ls},
        {"info", "[<dev_name>]", 0, 1, _info},
        {"deps", "[<dev_name>]", 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);
index 3caa494537eeea005d0068ad61b703af25270dd4..2a04be4f56e93a2196ed451d9dbd7506e0fca239 100644 (file)
@@ -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 <linux/types.h>
 
@@ -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 */
index 1b7ab160d44577347d70ef01d23b1ad02229df5b..01fe677e903771e8f39f20f95ca6cddc1cfb27b6 100644 (file)
@@ -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
index 4f8e4b49da123d4248b18c36fe42e2d5b0a88c0b..ed6e85f29376797485cc8e1721177384d86cba86 100644 (file)
@@ -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* */
 
index 555bfe756019dbee0fee7212a2715fdd4b280f08..3c72e9d5abd71607e906367f922ecfb4cf088733 100644 (file)
@@ -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))) {
index 498b9618fd6edea67ebe2d8040f7308b46162d10..97fa8661d5c4e56ef17cba1ebb0f31619964abd9 100644 (file)
@@ -45,6 +45,8 @@ struct dm_task {
                struct dm_ioctl_v1 *v1;
        } dmi;
        char *newname;
+       char *message;
+       uint64_t sector;
 
        char *uuid;
 };
index 7d838ef2d24da860a3a5df3c7f7717560bb7ac1d..f0aeccde3006b3d72e5e444c1e368cfd35d0aa13 100644 (file)
@@ -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.
This page took 0.04301 seconds and 5 git commands to generate.