ctdb-protocol: Add marshalling for eventd protocol
authorAmitay Isaacs <amitay@gmail.com>
Wed, 31 Aug 2016 07:02:55 +0000 (17:02 +1000)
committerAmitay Isaacs <amitay@samba.org>
Sun, 18 Dec 2016 13:23:22 +0000 (14:23 +0100)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_api.h
ctdb/protocol/protocol_event.c [new file with mode: 0644]
ctdb/tests/cunit/protocol_test_002.sh
ctdb/tests/src/protocol_client_test.c
ctdb/tests/src/protocol_types_test.c
ctdb/wscript

index e967dea5a21e55157a0ce3da0589c1fe69d91ba6..fd7372447da6c6f07cb0883250f83c34016d3187 100644 (file)
@@ -644,6 +644,28 @@ int ctdb_req_message_data_pull(uint8_t *buf, size_t buflen,
                               TALLOC_CTX *mem_ctx,
                               struct ctdb_req_message_data *c);
 
+/* From protocol/protocol_event.c */
+
+void ctdb_event_header_fill(struct ctdb_event_header *h, uint32_t reqid);
+
+size_t ctdb_event_request_len(struct ctdb_event_request *in);
+
+int ctdb_event_request_push(struct ctdb_event_request *in,
+                           uint8_t *buf, size_t *buflen);
+
+int ctdb_event_request_pull(uint8_t *buf, size_t buflen,
+                           TALLOC_CTX *mem_ctx,
+                           struct ctdb_event_request *out);
+
+size_t ctdb_event_reply_len(struct ctdb_event_reply *in);
+
+int ctdb_event_reply_push(struct ctdb_event_reply *in,
+                         uint8_t *buf, size_t *buflen);
+
+int ctdb_event_reply_pull(uint8_t *buf, size_t buflen,
+                         TALLOC_CTX *mem_ctx,
+                         struct ctdb_event_reply *out);
+
 /* From protocol/protocol_packet.c */
 
 int ctdb_allocate_pkt(TALLOC_CTX *mem_ctx, size_t datalen,
diff --git a/ctdb/protocol/protocol_event.c b/ctdb/protocol/protocol_event.c
new file mode 100644 (file)
index 0000000..59f38e9
--- /dev/null
@@ -0,0 +1,848 @@
+/*
+   CTDB eventd protocol marshalling
+
+   Copyright (C) Amitay Isaacs  2016
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "replace.h"
+#include "system/network.h"
+
+#include <talloc.h>
+
+#include "protocol.h"
+#include "protocol_private.h"
+#include "protocol_api.h"
+
+static size_t ctdb_event_len(enum ctdb_event in)
+{
+       return ctdb_uint32_len((uint32_t)in);
+}
+
+static void ctdb_event_push(enum ctdb_event in, uint8_t *buf)
+{
+       ctdb_uint32_push((uint32_t)in, buf);
+}
+
+static int ctdb_event_pull(uint8_t *buf, size_t buflen,
+                          TALLOC_CTX *mem_ctx, enum ctdb_event *out)
+{
+       uint32_t uint32_value;
+       enum ctdb_event value;
+       int ret;
+
+       ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &uint32_value);
+       if (ret != 0) {
+               return ret;
+       }
+
+       switch (uint32_value) {
+       case 0:
+               value = CTDB_EVENT_INIT;
+               break;
+
+       case 1:
+               value = CTDB_EVENT_SETUP;
+               break;
+
+       case 2:
+               value = CTDB_EVENT_STARTUP;
+               break;
+
+       case 3:
+               value = CTDB_EVENT_START_RECOVERY;
+               break;
+
+       case 4:
+               value = CTDB_EVENT_RECOVERED;
+               break;
+
+       case 5:
+               value = CTDB_EVENT_TAKE_IP;
+               break;
+
+       case 6:
+               value = CTDB_EVENT_RELEASE_IP;
+               break;
+
+       case 7:
+               value = CTDB_EVENT_STOPPED;
+               break;
+
+       case 8:
+               value = CTDB_EVENT_MONITOR;
+               break;
+
+       case 9:
+               value = CTDB_EVENT_STATUS;
+               break;
+
+       case 10:
+               value = CTDB_EVENT_SHUTDOWN;
+               break;
+
+       case 11:
+               value = CTDB_EVENT_RELOAD;
+               break;
+
+       case 12:
+               value = CTDB_EVENT_UPDATE_IP;
+               break;
+
+       case 13:
+               value = CTDB_EVENT_IPREALLOCATED;
+               break;
+
+       default:
+               return EINVAL;
+       }
+
+       *out = value;
+       return 0;
+}
+
+static size_t ctdb_event_command_len(enum ctdb_event_command in)
+{
+       return ctdb_uint32_len((uint32_t)in);
+}
+
+static void ctdb_event_command_push(enum ctdb_event_command in, uint8_t *buf)
+{
+       ctdb_uint32_push((uint32_t)in, buf);
+}
+
+static int ctdb_event_command_pull(uint8_t *buf, size_t buflen,
+                                  TALLOC_CTX *mem_ctx,
+                                  enum ctdb_event_command *out)
+{
+       uint32_t uint32_value;
+       enum ctdb_event_command value;
+       int ret;
+
+       ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &uint32_value);
+       if (ret != 0) {
+               return ret;
+       }
+
+       switch (uint32_value) {
+       case 1:
+               value = CTDB_EVENT_COMMAND_RUN;
+               break;
+
+       case 2:
+               value = CTDB_EVENT_COMMAND_STATUS;
+               break;
+
+       case 3:
+               value = CTDB_EVENT_COMMAND_SCRIPT_LIST;
+               break;
+
+       case 4:
+               value = CTDB_EVENT_COMMAND_SCRIPT_ENABLE;
+               break;
+
+       case 5:
+               value = CTDB_EVENT_COMMAND_SCRIPT_DISABLE;
+               break;
+
+       default:
+               return EINVAL;
+       }
+
+       *out = value;
+       return 0;
+}
+
+static size_t ctdb_event_status_state_len(enum ctdb_event_status_state in)
+{
+       return ctdb_uint32_len((uint32_t)in);
+}
+
+static void ctdb_event_status_state_push(enum ctdb_event_status_state in,
+                                        uint8_t *buf)
+{
+       ctdb_uint32_push((uint32_t)in, buf);
+}
+
+static int ctdb_event_status_state_pull(uint8_t *buf, size_t buflen,
+                                       TALLOC_CTX *mem_ctx,
+                                       enum ctdb_event_status_state *out)
+{
+       uint32_t uint32_value;
+       enum ctdb_event_status_state value;
+       int ret;
+
+       ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &uint32_value);
+       if (ret != 0) {
+               return ret;
+       }
+
+       switch (uint32_value) {
+       case 1:
+               value = CTDB_EVENT_LAST_RUN;
+               break;
+
+       case 2:
+               value = CTDB_EVENT_LAST_PASS;
+               break;
+
+       case 3:
+               value = CTDB_EVENT_LAST_FAIL;
+               break;
+
+       default:
+               return EINVAL;
+       }
+
+       *out = value;
+       return 0;
+}
+
+static size_t ctdb_event_request_run_len(struct ctdb_event_request_run *in)
+{
+       return ctdb_event_len(in->event) +
+              ctdb_uint32_len(in->timeout) +
+              ctdb_stringn_len(in->arg_str);
+}
+
+static void ctdb_event_request_run_push(struct ctdb_event_request_run *in,
+                                       uint8_t *buf)
+{
+       size_t offset = 0;
+
+       ctdb_event_push(in->event, buf);
+       offset += ctdb_event_len(in->event);
+
+       ctdb_uint32_push(in->timeout, buf+offset);
+       offset += ctdb_uint32_len(in->timeout);
+
+       ctdb_stringn_push(in->arg_str, buf+offset);
+}
+
+static int ctdb_event_request_run_pull(uint8_t *buf, size_t buflen,
+                                      TALLOC_CTX *mem_ctx,
+                                      struct ctdb_event_request_run **out)
+{
+       struct ctdb_event_request_run *rdata;
+       size_t offset = 0;
+       int ret;
+
+       rdata = talloc(mem_ctx, struct ctdb_event_request_run);
+       if (rdata == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_event_pull(buf, buflen, rdata, &rdata->event);
+       if (ret != 0) {
+               goto fail;
+       }
+       offset += ctdb_event_len(rdata->event);
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset,
+                              rdata, &rdata->timeout);
+       if (ret != 0) {
+               goto fail;
+       }
+       offset += ctdb_uint32_len(rdata->timeout);
+
+       ret = ctdb_stringn_pull(buf+offset, buflen-offset,
+                               rdata, &rdata->arg_str);
+       if (ret != 0) {
+               goto fail;
+       }
+
+       *out = rdata;
+       return 0;
+
+fail:
+       talloc_free(rdata);
+       return ret;
+}
+
+static size_t ctdb_event_request_status_len(
+                               struct ctdb_event_request_status *in)
+{
+       return ctdb_event_len(in->event) +
+              ctdb_event_status_state_len(in->state);
+}
+
+static void ctdb_event_request_status_push(
+                               struct ctdb_event_request_status *in,
+                               uint8_t *buf)
+{
+       size_t offset = 0;
+
+       ctdb_event_push(in->event, buf);
+       offset += ctdb_event_len(in->event);
+
+       ctdb_event_status_state_push(in->state, buf+offset);
+}
+
+static int ctdb_event_request_status_pull(
+                               uint8_t *buf, size_t buflen,
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_request_status **out)
+{
+       struct ctdb_event_request_status *rdata;
+       size_t offset = 0;
+       int ret;
+
+       rdata = talloc(mem_ctx, struct ctdb_event_request_status);
+       if (rdata == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_event_pull(buf, buflen, rdata, &rdata->event);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+       offset += ctdb_event_len(rdata->event);
+
+       ret = ctdb_event_status_state_pull(buf+offset, buflen-offset,
+                                          rdata, &rdata->state);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+
+       *out = rdata;
+       return 0;
+}
+
+static size_t ctdb_event_request_script_enable_len(
+                               struct ctdb_event_request_script_enable *in)
+{
+       return ctdb_stringn_len(in->script_name);
+}
+
+static void ctdb_event_request_script_enable_push(
+                               struct ctdb_event_request_script_enable *in,
+                               uint8_t *buf)
+{
+       ctdb_stringn_push(in->script_name, buf);
+}
+
+static int ctdb_event_request_script_enable_pull(
+                               uint8_t *buf, size_t buflen,
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_request_script_enable **out)
+{
+       struct ctdb_event_request_script_enable *rdata;
+       int ret;
+
+       rdata = talloc(mem_ctx, struct ctdb_event_request_script_enable);
+       if (rdata == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_stringn_pull(buf, buflen, rdata, &rdata->script_name);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+
+       *out = rdata;
+       return 0;
+}
+
+static size_t ctdb_event_request_script_disable_len(
+                               struct ctdb_event_request_script_disable *in)
+{
+       return ctdb_stringn_len(in->script_name);
+}
+
+static void ctdb_event_request_script_disable_push(
+                               struct ctdb_event_request_script_disable *in,
+                               uint8_t *buf)
+{
+       ctdb_stringn_push(in->script_name, buf);
+}
+
+static int ctdb_event_request_script_disable_pull(
+                               uint8_t *buf, size_t buflen,
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_request_script_disable **out)
+{
+       struct ctdb_event_request_script_disable *rdata;
+       int ret;
+
+       rdata = talloc(mem_ctx, struct ctdb_event_request_script_disable);
+       if (rdata == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_stringn_pull(buf, buflen, rdata, &rdata->script_name);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+
+       *out = rdata;
+       return 0;
+}
+
+static size_t ctdb_event_request_data_len(struct ctdb_event_request_data *in)
+{
+       size_t len = 0;
+
+       len += ctdb_event_command_len(in->command);
+
+       switch(in->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               len += ctdb_event_request_run_len(in->data.run);
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               len += ctdb_event_request_status_len(in->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               len += ctdb_event_request_script_enable_len(
+                                               in->data.script_enable);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               len += ctdb_event_request_script_disable_len(
+                                               in->data.script_disable);
+               break;
+       }
+
+       return len;
+}
+
+static void ctdb_event_request_data_push(struct ctdb_event_request_data *in,
+                                        uint8_t *buf)
+{
+       size_t offset = 0;
+
+       ctdb_event_command_push(in->command, buf);
+       offset += ctdb_event_command_len(in->command);
+
+       switch (in->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               ctdb_event_request_run_push(in->data.run, buf+offset);
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               ctdb_event_request_status_push(in->data.status, buf+offset);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               ctdb_event_request_script_enable_push(
+                                               in->data.script_enable,
+                                               buf+offset);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               ctdb_event_request_script_disable_push(
+                                               in->data.script_disable,
+                                               buf+offset);
+               break;
+       }
+}
+
+static int ctdb_event_request_data_pull(uint8_t *buf, size_t buflen,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct ctdb_event_request_data *out)
+{
+       size_t offset = 0;
+       int ret;
+
+       ret = ctdb_event_command_pull(buf, buflen, mem_ctx, &out->command);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += ctdb_event_command_len(out->command);
+
+       switch (out->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               ret = ctdb_event_request_run_pull(buf+offset, buflen-offset,
+                                                 mem_ctx, &out->data.run);
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               ret = ctdb_event_request_status_pull(
+                                               buf+offset, buflen-offset,
+                                               mem_ctx, &out->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               ret = 0;
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               ret = ctdb_event_request_script_enable_pull(
+                                               buf+offset, buflen-offset,
+                                               mem_ctx,
+                                               &out->data.script_enable);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               ret = ctdb_event_request_script_disable_pull(
+                                               buf+offset, buflen-offset,
+                                               mem_ctx,
+                                               &out->data.script_disable);
+               break;
+       }
+
+       if (ret != 0) {
+               return ret;
+       }
+
+       return 0;
+}
+
+static size_t ctdb_event_reply_status_len(struct ctdb_event_reply_status *in)
+{
+       return ctdb_int32_len(in->status) +
+              ctdb_script_list_len(in->script_list);
+}
+
+static void ctdb_event_reply_status_push(struct ctdb_event_reply_status *in,
+                                        uint8_t *buf)
+{
+       size_t offset = 0;
+
+       ctdb_int32_push(in->status, buf);
+       offset += ctdb_int32_len(in->status);
+
+       ctdb_script_list_push(in->script_list, buf+offset);
+}
+
+static int ctdb_event_reply_status_pull(uint8_t *buf, size_t buflen,
+                                       TALLOC_CTX *mem_ctx,
+                                       struct ctdb_event_reply_status **out)
+{
+       struct ctdb_event_reply_status *rdata;
+       size_t offset = 0;
+       int ret;
+
+       rdata = talloc(mem_ctx, struct ctdb_event_reply_status);
+       if (rdata == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_int32_pull(buf, buflen, rdata, &rdata->status);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+       offset += ctdb_int32_len(rdata->status);
+
+       ret = ctdb_script_list_pull(buf+offset, buflen-offset,
+                                   rdata, &rdata->script_list);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+
+       *out = rdata;
+       return 0;
+}
+
+static size_t ctdb_event_reply_script_list_len(
+                               struct ctdb_event_reply_script_list *in)
+{
+       return ctdb_script_list_len(in->script_list);
+}
+
+static void ctdb_event_reply_script_list_push(
+                               struct ctdb_event_reply_script_list *in,
+                               uint8_t *buf)
+{
+       ctdb_script_list_push(in->script_list, buf);
+}
+
+static int ctdb_event_reply_script_list_pull(
+                               uint8_t *buf, size_t buflen,
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_reply_script_list **out)
+{
+       struct ctdb_event_reply_script_list *rdata;
+       int ret;
+
+       rdata = talloc(mem_ctx, struct ctdb_event_reply_script_list);
+       if (rdata == NULL) {
+               return ENOMEM;
+       }
+
+       ret = ctdb_script_list_pull(buf, buflen, rdata, &rdata->script_list);
+       if (ret != 0) {
+               talloc_free(rdata);
+               return ret;
+       }
+
+       *out = rdata;
+       return 0;
+}
+
+static size_t ctdb_event_reply_data_len(struct ctdb_event_reply_data *in)
+{
+       size_t len = 0;
+
+       len += ctdb_event_command_len(in->command);
+       len += ctdb_int32_len(in->result);
+
+       switch (in->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               len += ctdb_event_reply_status_len(in->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               len += ctdb_event_reply_script_list_len(in->data.script_list);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               break;
+       }
+
+       return len;
+}
+
+static void ctdb_event_reply_data_push(struct ctdb_event_reply_data *in,
+                                      uint8_t *buf)
+{
+       size_t offset = 0;
+
+       ctdb_event_command_push(in->command, buf);
+       offset += ctdb_event_command_len(in->command);
+
+       ctdb_int32_push(in->result, buf+offset);
+       offset += ctdb_int32_len(in->result);
+
+       switch (in->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               ctdb_event_reply_status_push(in->data.status, buf+offset);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               ctdb_event_reply_script_list_push(in->data.script_list,
+                                                 buf+offset);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               break;
+       }
+}
+
+static int ctdb_event_reply_data_pull(uint8_t *buf, size_t buflen,
+                                     TALLOC_CTX *mem_ctx,
+                                     struct ctdb_event_reply_data *out)
+{
+       size_t offset = 0;
+       int ret;
+
+       ret = ctdb_event_command_pull(buf, buflen, mem_ctx, &out->command);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += ctdb_event_command_len(out->command);
+
+       ret = ctdb_int32_pull(buf+offset, buflen-offset,
+                             mem_ctx, &out->result);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += ctdb_int32_len(out->result);
+
+       switch (out->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               ret = ctdb_event_reply_status_pull(
+                                       buf+offset, buflen-offset,
+                                       mem_ctx, &out->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               ret = ctdb_event_reply_script_list_pull(
+                                       buf+offset, buflen-offset,
+                                       mem_ctx, &out->data.script_list);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               break;
+       }
+
+       if (ret != 0) {
+               return ret;
+       }
+
+       return 0;
+}
+
+static size_t ctdb_event_header_len(struct ctdb_event_header *in)
+{
+       return ctdb_uint32_len(in->length) + ctdb_uint32_len(in->reqid);
+}
+
+static void ctdb_event_header_push(struct ctdb_event_header *in, uint8_t *buf)
+{
+       size_t offset = 0;
+
+       ctdb_uint32_push(in->length, buf);
+       offset += ctdb_uint32_len(in->length);
+
+       ctdb_uint32_push(in->reqid, buf+offset);
+}
+
+static int ctdb_event_header_pull(uint8_t *buf, size_t buflen,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct ctdb_event_header *out)
+{
+       size_t offset = 0;
+       int ret;
+
+       ret = ctdb_uint32_pull(buf, buflen, mem_ctx, &out->length);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += ctdb_uint32_len(out->length);
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset,
+                              mem_ctx, &out->reqid);
+       if (ret != 0) {
+               return ret;
+       }
+
+       return 0;
+}
+
+void ctdb_event_header_fill(struct ctdb_event_header *h, uint32_t reqid)
+{
+       h->length = ctdb_event_header_len(h);
+       h->reqid = reqid;
+}
+
+size_t ctdb_event_request_len(struct ctdb_event_request *in)
+{
+       return ctdb_event_header_len(&in->header) +
+              ctdb_event_request_data_len(&in->rdata);
+}
+
+int ctdb_event_request_push(struct ctdb_event_request *in,
+                           uint8_t *buf, size_t *buflen)
+{
+       size_t len, offset = 0;
+
+       len = ctdb_event_request_len(in);
+       if (*buflen < len) {
+               *buflen = len;
+               return EMSGSIZE;
+       }
+
+       in->header.length = *buflen;
+
+       ctdb_event_header_push(&in->header, buf);
+       offset += ctdb_event_header_len(&in->header);
+
+       ctdb_event_request_data_push(&in->rdata, buf+offset);
+
+       return 0;
+}
+
+int ctdb_event_request_pull(uint8_t *buf, size_t buflen,
+                           TALLOC_CTX *mem_ctx,
+                           struct ctdb_event_request *out)
+{
+       size_t offset = 0;
+       int ret;
+
+       ret = ctdb_event_header_pull(buf, buflen, mem_ctx, &out->header);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += ctdb_event_header_len(&out->header);
+
+       ret = ctdb_event_request_data_pull(buf+offset, buflen-offset,
+                                          mem_ctx, &out->rdata);
+       if (ret != 0) {
+               return ret;
+       }
+
+       return 0;
+}
+
+size_t ctdb_event_reply_len(struct ctdb_event_reply *in)
+{
+       return ctdb_event_header_len(&in->header) +
+              ctdb_event_reply_data_len(&in->rdata);
+}
+
+int ctdb_event_reply_push(struct ctdb_event_reply *in,
+                         uint8_t *buf, size_t *buflen)
+{
+       size_t len, offset = 0;
+
+       len = ctdb_event_reply_len(in);
+       if (*buflen < len) {
+               *buflen = len;
+               return EMSGSIZE;
+       }
+
+       in->header.length = *buflen;
+
+       ctdb_event_header_push(&in->header, buf);
+       offset += ctdb_event_header_len(&in->header);
+
+       ctdb_event_reply_data_push(&in->rdata, buf+offset);
+
+       return 0;
+}
+
+int ctdb_event_reply_pull(uint8_t *buf, size_t buflen,
+                         TALLOC_CTX *mem_ctx,
+                         struct ctdb_event_reply *out)
+{
+       size_t offset = 0;
+       int ret;
+
+       ret = ctdb_event_header_pull(buf, buflen, mem_ctx, &out->header);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += ctdb_event_header_len(&out->header);
+
+       ret = ctdb_event_reply_data_pull(buf+offset, buflen-offset,
+                                        mem_ctx, &out->rdata);
+       if (ret != 0) {
+               return ret;
+       }
+
+       return 0;
+}
index d248b367280c6cf8a60d57d96b497f5d4e6be41f..929ff658718d6b080f84ed2164333dd048319bda 100755 (executable)
@@ -11,6 +11,15 @@ control_output=$(
     echo
 )
 
+last_command=5
+
+command_output=$(
+    for i in $(seq 1 $last_command) ; do
+       echo -n "$i.. "
+    done
+    echo
+)
+
 output=$(
     echo "ctdb_req_header"
     echo "ctdb_req_call"
@@ -27,6 +36,15 @@ output=$(
     echo "ctdb_reply_control"
     echo "$control_output"
     echo "ctdb_req_message"
+    echo "ctdb_event_header"
+    echo "ctdb_event_request_data"
+    echo "$command_output"
+    echo "ctdb_event_reply_data"
+    echo "$command_output"
+    echo "ctdb_event_request"
+    echo "$command_output"
+    echo "ctdb_event_reply"
+    echo "$command_output"
 )
 
 ok "$output"
index e8e4485f8e8895fbf2ac51920c6e36f38112a6c1..0b6ffbbf4cc67bb9d00d932be95dc7cdbce68fe4 100644 (file)
@@ -1836,6 +1836,176 @@ static void verify_ctdb_req_message_data(struct ctdb_req_message_data *c,
        verify_tdb_data(&c->data, &c2->data);
 }
 
+/*
+ * Functions to fill and verify eventd protocol structures
+ */
+
+static void fill_ctdb_event_request_data(TALLOC_CTX *mem_ctx,
+                                        struct ctdb_event_request_data *r,
+                                        uint32_t command)
+{
+       r->command = command;
+
+       switch (command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               r->data.run = talloc(mem_ctx, struct ctdb_event_request_run);
+               assert(r->data.run != NULL);
+
+               fill_ctdb_event_request_run(mem_ctx, r->data.run);
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               r->data.status = talloc(mem_ctx,
+                                       struct ctdb_event_request_status);
+               assert(r->data.status != NULL);
+
+               fill_ctdb_event_request_status(mem_ctx, r->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               r->data.script_enable = talloc(mem_ctx,
+                               struct ctdb_event_request_script_enable);
+               assert(r->data.script_enable != NULL);
+
+               fill_ctdb_event_request_script_enable(mem_ctx,
+                                                     r->data.script_enable);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               r->data.script_disable = talloc(mem_ctx,
+                               struct ctdb_event_request_script_disable);
+               assert(r->data.script_disable != NULL);
+
+               fill_ctdb_event_request_script_disable(mem_ctx,
+                                                      r->data.script_disable);
+               break;
+       }
+}
+
+static void verify_ctdb_event_request_data(struct ctdb_event_request_data *r,
+                                          struct ctdb_event_request_data *r2)
+{
+       assert(r->command == r2->command);
+
+       switch (r->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               verify_ctdb_event_request_run(r->data.run, r2->data.run);
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               verify_ctdb_event_request_status(r->data.status,
+                                                r2->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               verify_ctdb_event_request_script_enable(r->data.script_enable,
+                                                       r2->data.script_enable);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               verify_ctdb_event_request_script_disable(r->data.script_disable,
+                                                        r2->data.script_disable);
+               break;
+       }
+}
+
+static void fill_ctdb_event_reply_data(TALLOC_CTX *mem_ctx,
+                                      struct ctdb_event_reply_data *r,
+                                      uint32_t command)
+{
+       r->command = command;
+       r->result = rand32i();
+
+       switch (command) {
+       case CTDB_EVENT_COMMAND_STATUS:
+               r->data.status = talloc(mem_ctx,
+                                       struct ctdb_event_reply_status);
+               assert(r->data.status != NULL);
+
+               fill_ctdb_event_reply_status(mem_ctx, r->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               r->data.script_list = talloc(mem_ctx,
+                               struct ctdb_event_reply_script_list);
+               assert(r->data.script_list != NULL);
+
+               fill_ctdb_event_reply_script_list(mem_ctx,
+                                                 r->data.script_list);
+               break;
+       }
+}
+
+static void verify_ctdb_event_reply_data(struct ctdb_event_reply_data *r,
+                                        struct ctdb_event_reply_data *r2)
+{
+       assert(r->command == r2->command);
+       assert(r->result == r2->result);
+
+       switch (r->command) {
+       case CTDB_EVENT_COMMAND_RUN:
+               break;
+
+       case CTDB_EVENT_COMMAND_STATUS:
+               verify_ctdb_event_reply_status(r->data.status,
+                                              r2->data.status);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_LIST:
+               verify_ctdb_event_reply_script_list(r->data.script_list,
+                                                   r2->data.script_list);
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
+               break;
+
+       case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
+               break;
+       }
+}
+
+static void verify_ctdb_event_header(struct ctdb_event_header *h,
+                                    struct ctdb_event_header *h2)
+{
+       verify_buffer(h, h2, ctdb_event_header_len(h));
+}
+
+static void fill_ctdb_event_request(TALLOC_CTX *mem_ctx,
+                                   struct ctdb_event_request *r,
+                                   uint32_t command)
+{
+       ctdb_event_header_fill(&r->header, rand());
+       fill_ctdb_event_request_data(mem_ctx, &r->rdata, command);
+}
+
+static void verify_ctdb_event_request(struct ctdb_event_request *r,
+                                     struct ctdb_event_request *r2)
+{
+       verify_ctdb_event_header(&r->header, &r2->header);
+       verify_ctdb_event_request_data(&r->rdata, &r2->rdata);
+}
+
+static void fill_ctdb_event_reply(TALLOC_CTX *mem_ctx,
+                                 struct ctdb_event_reply *r,
+                                 uint32_t command)
+{
+       ctdb_event_header_fill(&r->header, rand());
+       fill_ctdb_event_reply_data(mem_ctx, &r->rdata, command);
+}
+
+static void verify_ctdb_event_reply(struct ctdb_event_reply *r,
+                                   struct ctdb_event_reply *r2)
+{
+       verify_ctdb_event_header(&r->header, &r2->header);
+       verify_ctdb_event_reply_data(&r->rdata, &r2->rdata);
+}
+
 /*
  * Functions to test marshalling
  */
@@ -2263,6 +2433,179 @@ static void test_req_message_test(void)
        talloc_free(mem_ctx);
 }
 
+/*
+ * Functions to test eventd protocol marshalling
+ */
+
+static void test_ctdb_event_header(void)
+{
+       TALLOC_CTX *mem_ctx;
+       size_t buflen;
+       struct ctdb_event_header h, h2;
+       int ret;
+
+       printf("ctdb_event_header\n");
+       fflush(stdout);
+
+       mem_ctx = talloc_new(NULL);
+       assert(mem_ctx != NULL);
+
+       ctdb_event_header_fill(&h, REQID);
+
+       buflen = ctdb_event_header_len(&h);
+       ctdb_event_header_push(&h, BUFFER);
+       ret = ctdb_event_header_pull(BUFFER, buflen, mem_ctx, &h2);
+       assert(ret == 0);
+
+       verify_ctdb_event_header(&h, &h2);
+
+       talloc_free(mem_ctx);
+}
+
+#define NUM_COMMANDS   5
+
+static void test_event_request_data(void)
+{
+       TALLOC_CTX *mem_ctx;
+       size_t buflen;
+       struct ctdb_event_request_data rd, rd2;
+       uint32_t command;
+       int ret;
+
+       printf("ctdb_event_request_data\n");
+       fflush(stdout);
+
+       for (command=1; command<=NUM_COMMANDS; command++) {
+               mem_ctx = talloc_new(NULL);
+               assert(mem_ctx != NULL);
+
+               printf("%u.. ", command);
+               fflush(stdout);
+               fill_ctdb_event_request_data(mem_ctx, &rd, command);
+               buflen = ctdb_event_request_data_len(&rd);
+               ctdb_event_request_data_push(&rd, BUFFER);
+               ret = ctdb_event_request_data_pull(BUFFER, buflen, mem_ctx, &rd2);
+               assert(ret == 0);
+               verify_ctdb_event_request_data(&rd, &rd2);
+
+               talloc_free(mem_ctx);
+       }
+
+       printf("\n");
+       fflush(stdout);
+}
+
+static void test_event_reply_data(void)
+{
+       TALLOC_CTX *mem_ctx;
+       size_t buflen;
+       struct ctdb_event_reply_data rd, rd2;
+       uint32_t command;
+       int ret;
+
+       printf("ctdb_event_reply_data\n");
+       fflush(stdout);
+
+       for (command=1; command<=NUM_COMMANDS; command++) {
+               mem_ctx = talloc_new(NULL);
+               assert(mem_ctx != NULL);
+
+               printf("%u.. ", command);
+               fflush(stdout);
+               fill_ctdb_event_reply_data(mem_ctx, &rd, command);
+               buflen = ctdb_event_reply_data_len(&rd);
+               ctdb_event_reply_data_push(&rd, BUFFER);
+               ret = ctdb_event_reply_data_pull(BUFFER, buflen, mem_ctx, &rd2);
+               assert(ret == 0);
+               verify_ctdb_event_reply_data(&rd, &rd2);
+
+               talloc_free(mem_ctx);
+       }
+
+       printf("\n");
+       fflush(stdout);
+}
+
+static void test_event_request(void)
+{
+       TALLOC_CTX *mem_ctx;
+       uint8_t *buf;
+       size_t len, buflen;
+       int ret;
+       struct ctdb_event_request r, r2;
+       uint32_t command;
+
+       printf("ctdb_event_request\n");
+       fflush(stdout);
+
+       for (command=1; command<=NUM_COMMANDS; command++) {
+               mem_ctx = talloc_new(NULL);
+               assert(mem_ctx != NULL);
+
+               printf("%u.. ", command);
+               fflush(stdout);
+               fill_ctdb_event_request(mem_ctx, &r, command);
+               buflen = ctdb_event_request_len(&r);
+               buf = talloc_size(mem_ctx, buflen);
+               assert(buf != NULL);
+               len = 0;
+               ret = ctdb_event_request_push(&r, buf, &len);
+               assert(ret == EMSGSIZE);
+               assert(len == buflen);
+               ret = ctdb_event_request_push(&r, buf, &buflen);
+               assert(ret == 0);
+               ret = ctdb_event_request_pull(buf, buflen, mem_ctx, &r2);
+               assert(ret == 0);
+               assert(r2.header.length == buflen);
+               verify_ctdb_event_request(&r, &r2);
+
+               talloc_free(mem_ctx);
+       }
+
+       printf("\n");
+       fflush(stdout);
+}
+
+static void test_event_reply(void)
+{
+       TALLOC_CTX *mem_ctx;
+       uint8_t *buf;
+       size_t len, buflen;
+       int ret;
+       struct ctdb_event_reply r, r2;
+       uint32_t command;
+
+       printf("ctdb_event_reply\n");
+       fflush(stdout);
+
+       for (command=1; command<=NUM_COMMANDS; command++) {
+               mem_ctx = talloc_new(NULL);
+               assert(mem_ctx != NULL);
+
+               printf("%u.. ", command);
+               fflush(stdout);
+               fill_ctdb_event_reply(mem_ctx, &r, command);
+               buflen = ctdb_event_reply_len(&r);
+               buf = talloc_size(mem_ctx, buflen);
+               assert(buf != NULL);
+               len = 0;
+               ret = ctdb_event_reply_push(&r, buf, &len);
+               assert(ret == EMSGSIZE);
+               assert(len == buflen);
+               ret = ctdb_event_reply_push(&r, buf, &buflen);
+               assert(ret == 0);
+               ret = ctdb_event_reply_pull(buf, buflen, mem_ctx, &r2);
+               assert(ret == 0);
+               assert(r2.header.length == buflen);
+               verify_ctdb_event_reply(&r, &r2);
+
+               talloc_free(mem_ctx);
+       }
+
+       printf("\n");
+       fflush(stdout);
+}
+
 int main(int argc, char *argv[])
 {
        if (argc == 2) {
@@ -2286,5 +2629,12 @@ int main(int argc, char *argv[])
 
        test_req_message_test();
 
+       test_ctdb_event_header();
+
+       test_event_request_data();
+       test_event_reply_data();
+       test_event_request();
+       test_event_reply();
+
        return 0;
 }
index 8ef0fd4793b4a29d0c02a7980a1f861826a5e04c..94108ead04c5a1dd589d56a60763f8598f4b4760 100644 (file)
@@ -27,6 +27,7 @@
 #include "protocol/protocol_header.c"
 #include "protocol/protocol_call.c"
 #include "protocol/protocol_control.c"
+#include "protocol/protocol_event.c"
 #include "protocol/protocol_message.c"
 #include "protocol/protocol_packet.c"
 
@@ -47,6 +48,11 @@ static uint8_t rand8(void)
        return val;
 }
 
+static int32_t rand32i(void)
+{
+       return INT_MIN + random();
+}
+
 static uint32_t rand32(void)
 {
        return random();
@@ -909,6 +915,107 @@ static void verify_ctdb_db_statistics(struct ctdb_db_statistics *p1,
        }
 }
 
+static void fill_ctdb_event_request_run(TALLOC_CTX *mem_ctx,
+                                       struct ctdb_event_request_run *p)
+{
+       p->event = rand_int(CTDB_EVENT_MAX);
+       p->timeout = rand();
+       fill_ctdb_string(mem_ctx, &p->arg_str);
+}
+
+static void verify_ctdb_event_request_run(struct ctdb_event_request_run *p1,
+                                         struct ctdb_event_request_run *p2)
+{
+       assert(p1->event == p2->event);
+       assert(p1->timeout == p2->timeout);
+       verify_ctdb_string(p1->arg_str, p2->arg_str);
+}
+
+static void fill_ctdb_event_request_status(TALLOC_CTX *mem_ctx,
+                                          struct ctdb_event_request_status *p)
+{
+       p->event = rand_int(CTDB_EVENT_MAX);
+       p->state = rand_int(3) + 1;
+}
+
+static void verify_ctdb_event_request_status(
+                                       struct ctdb_event_request_status *p1,
+                                       struct ctdb_event_request_status *p2)
+{
+       assert(p1->event == p2->event);
+       assert(p1->state == p2->state);
+}
+
+static void fill_ctdb_event_request_script_enable(
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_request_script_enable *p)
+{
+       fill_ctdb_string(mem_ctx, &p->script_name);
+}
+
+static void verify_ctdb_event_request_script_enable(
+                               struct ctdb_event_request_script_enable *p1,
+                               struct ctdb_event_request_script_enable *p2)
+{
+       verify_ctdb_string(p1->script_name, p2->script_name);
+}
+
+static void fill_ctdb_event_request_script_disable(
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_request_script_disable *p)
+{
+       fill_ctdb_string(mem_ctx, &p->script_name);
+}
+
+static void verify_ctdb_event_request_script_disable(
+                               struct ctdb_event_request_script_disable *p1,
+                               struct ctdb_event_request_script_disable *p2)
+{
+       verify_ctdb_string(p1->script_name, p2->script_name);
+}
+
+static void fill_ctdb_event_reply_status(TALLOC_CTX *mem_ctx,
+                                        struct ctdb_event_reply_status *p)
+{
+       if (rand_int(2) == 0) {
+               p->status = 0;
+               p->script_list = talloc(mem_ctx, struct ctdb_script_list);
+               assert(p->script_list != NULL);
+               fill_ctdb_script_list(mem_ctx, p->script_list);
+       } else {
+               p->status = rand32i();
+               p->script_list = NULL;
+       }
+}
+
+static void verify_ctdb_event_reply_status(struct ctdb_event_reply_status *p1,
+                                          struct ctdb_event_reply_status *p2)
+{
+       assert(p1->status == p2->status);
+       if (p1->script_list == NULL) {
+               assert(p1->script_list == p2->script_list);
+       } else {
+               verify_ctdb_script_list(p1->script_list, p2->script_list);
+       }
+}
+
+static void fill_ctdb_event_reply_script_list(
+                               TALLOC_CTX *mem_ctx,
+                               struct ctdb_event_reply_script_list *p)
+{
+       p->script_list = talloc(mem_ctx, struct ctdb_script_list);
+       assert(p->script_list != NULL);
+
+       fill_ctdb_script_list(mem_ctx, p->script_list);
+}
+
+static void verify_ctdb_event_reply_script_list(
+                               struct ctdb_event_reply_script_list *p1,
+                               struct ctdb_event_reply_script_list *p2)
+{
+       verify_ctdb_script_list(p1->script_list, p2->script_list);
+}
+
 #ifndef PROTOCOL_TEST
 
 static void fill_ctdb_election_message(TALLOC_CTX *mem_ctx,
@@ -1017,11 +1124,6 @@ static void verify_ctdb_g_lock_list(struct ctdb_g_lock_list *p1,
  * Functions to test marshalling routines
  */
 
-static int32_t rand32i(void)
-{
-       return INT_MIN + random();
-}
-
 static void test_ctdb_int32(void)
 {
        int32_t p1, p2;
@@ -1225,6 +1327,15 @@ DEFINE_TEST(struct ctdb_srvid_message, ctdb_srvid_message);
 DEFINE_TEST(struct ctdb_disable_message, ctdb_disable_message);
 DEFINE_TEST(struct ctdb_g_lock_list, ctdb_g_lock_list);
 
+DEFINE_TEST(struct ctdb_event_request_run, ctdb_event_request_run);
+DEFINE_TEST(struct ctdb_event_request_status, ctdb_event_request_status);
+DEFINE_TEST(struct ctdb_event_request_script_enable,
+                               ctdb_event_request_script_enable);
+DEFINE_TEST(struct ctdb_event_request_script_disable,
+                               ctdb_event_request_script_disable);
+DEFINE_TEST(struct ctdb_event_reply_status, ctdb_event_reply_status);
+DEFINE_TEST(struct ctdb_event_reply_script_list, ctdb_event_reply_script_list);
+
 static void test_ctdb_rec_buffer_read_write(void)
 {
        TALLOC_CTX *mem_ctx = talloc_new(NULL);
@@ -1332,6 +1443,13 @@ int main(int argc, char *argv[])
        TEST_FUNC(ctdb_disable_message)();
        TEST_FUNC(ctdb_g_lock_list)();
 
+       TEST_FUNC(ctdb_event_request_run)();
+       TEST_FUNC(ctdb_event_request_status)();
+       TEST_FUNC(ctdb_event_request_script_enable)();
+       TEST_FUNC(ctdb_event_request_script_disable)();
+       TEST_FUNC(ctdb_event_reply_status)();
+       TEST_FUNC(ctdb_event_reply_script_list)();
+
        test_ctdb_rec_buffer_read_write();
 
        return 0;
index 4c79c1207ed0da1b7f9a365ba0465cd3d7f1efc4..979c653a65480d5b30e0dc375a7ee8979af574c6 100644 (file)
@@ -402,7 +402,8 @@ def build(bld):
                                              protocol_control.c
                                              protocol_client.c
                                              protocol_debug.c
-                                             protocol_util.c'''),
+                                             protocol_util.c
+                                             protocol_event.c'''),
                         includes='include',
                         deps='replace talloc tdb')