--- /dev/null
+/*
+ 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;
+}
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
*/
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) {
test_req_message_test();
+ test_ctdb_event_header();
+
+ test_event_request_data();
+ test_event_reply_data();
+ test_event_request();
+ test_event_reply();
+
return 0;
}
#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"
return val;
}
+static int32_t rand32i(void)
+{
+ return INT_MIN + random();
+}
+
static uint32_t rand32(void)
{
return random();
}
}
+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,
* Functions to test marshalling routines
*/
-static int32_t rand32i(void)
-{
- return INT_MIN + random();
-}
-
static void test_ctdb_int32(void)
{
int32_t p1, p2;
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);
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;