--- /dev/null
+/*
+ CTDB event daemon protocol
+
+ Copyright (C) Amitay Isaacs 2018
+
+ 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 <talloc.h>
+
+#include "protocol/protocol_basic.h"
+
+#include "event_protocol.h"
+#include "event_protocol_api.h"
+
+static size_t ctdb_event_script_action_len(enum ctdb_event_script_action in)
+{
+ uint32_t u32 = in;
+
+ return ctdb_uint32_len(&u32);
+}
+
+static void ctdb_event_script_action_push(enum ctdb_event_script_action in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ uint32_t u32 = in;
+
+ ctdb_uint32_push(&u32, buf, npush);
+}
+
+static int ctdb_event_script_action_pull(uint8_t *buf,
+ size_t buflen,
+ enum ctdb_event_script_action *out,
+ size_t *npull)
+{
+ enum ctdb_event_script_action value;
+ uint32_t u32;
+ size_t np;
+ int ret;
+
+ ret = ctdb_uint32_pull(buf, buflen, &u32, &np);
+ if (ret != 0) {
+ return ret;
+ }
+
+ switch (u32) {
+ case 0:
+ value = CTDB_EVENT_SCRIPT_DISABLE;
+ break;
+
+ case 1:
+ value = CTDB_EVENT_SCRIPT_ENABLE;
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ *out = value;
+ *npull = np;
+
+ return 0;
+}
+
+static size_t ctdb_event_command_len(enum ctdb_event_command in)
+{
+ uint32_t u32 = in;
+
+ return ctdb_uint32_len(&u32);
+}
+
+static void ctdb_event_command_push(enum ctdb_event_command in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ uint32_t u32 = in;
+
+ ctdb_uint32_push(&u32, buf, npush);
+}
+
+static int ctdb_event_command_pull(uint8_t *buf,
+ size_t buflen,
+ enum ctdb_event_command *out,
+ size_t *npull)
+{
+ enum ctdb_event_command value;
+ uint32_t u32;
+ size_t np;
+ int ret;
+
+ ret = ctdb_uint32_pull(buf, buflen, &u32, &np);
+ if (ret != 0) {
+ return ret;
+ }
+
+ switch (u32) {
+ case 1:
+ value = CTDB_EVENT_CMD_RUN;
+ break;
+
+ case 2:
+ value = CTDB_EVENT_CMD_STATUS;
+ break;
+
+ case 3:
+ value = CTDB_EVENT_CMD_SCRIPT;
+ break;
+
+ default:
+ return EINVAL;
+ }
+
+ *out = value;
+ *npull = np;
+
+ return 0;
+}
+
+static size_t ctdb_event_script_len(struct ctdb_event_script *in)
+{
+ return ctdb_stringn_len(&in->name) +
+ ctdb_timeval_len(&in->begin) +
+ ctdb_timeval_len(&in->end) +
+ ctdb_int32_len(&in->result) +
+ ctdb_stringn_len(&in->output);
+}
+
+static void ctdb_event_script_push(struct ctdb_event_script *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_stringn_push(&in->name, buf+offset, &np);
+ offset += np;
+
+ ctdb_timeval_push(&in->begin, buf+offset, &np);
+ offset += np;
+
+ ctdb_timeval_push(&in->end, buf+offset, &np);
+ offset += np;
+
+ ctdb_int32_push(&in->result, buf+offset, &np);
+ offset += np;
+
+ ctdb_stringn_push(&in->output, buf+offset, &np);
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_script_pull_elems(uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_script *value,
+ size_t *npull)
+{
+ size_t offset = 0, np;
+ int ret;
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ mem_ctx,
+ &value->name,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_timeval_pull(buf+offset,
+ buflen-offset,
+ &value->begin,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_timeval_pull(buf+offset,
+ buflen-offset,
+ &value->end,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_int32_pull(buf+offset,
+ buflen-offset,
+ &value->result,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ mem_ctx,
+ &value->output,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ *npull = offset;
+
+ return 0;
+}
+
+#ifdef EVENT_PROTOCOL_TEST
+static int ctdb_event_script_pull(uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_script **out,
+ size_t *npull)
+{
+ struct ctdb_event_script *value;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_script);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_event_script_pull_elems(buf, buflen, value, value, npull);
+ if (ret != 0) {
+ talloc_free(value);
+ return ret;
+ }
+
+ *out = value;
+
+ return 0;
+}
+#endif
+
+static size_t ctdb_event_script_list_len(struct ctdb_event_script_list *in)
+{
+ size_t len;
+ int i;
+
+ len = ctdb_int32_len(&in->num_scripts);
+
+ for (i=0; i<in->num_scripts; i++) {
+ len += ctdb_event_script_len(&in->script[i]);
+ }
+
+ return len;
+}
+
+static void ctdb_event_script_list_push(struct ctdb_event_script_list *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+ int i;
+
+ ctdb_int32_push(&in->num_scripts, buf+offset, &np);
+ offset += np;
+
+ for (i=0; i<in->num_scripts; i++) {
+ ctdb_event_script_push(&in->script[i], buf+offset, &np);
+ offset += np;
+ }
+
+ *npush = offset;
+}
+
+static int ctdb_event_script_list_pull(uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_script_list **out,
+ size_t *npull)
+{
+ struct ctdb_event_script_list *value = NULL;
+ size_t offset = 0, np;
+ int num_scripts;
+ int ret, i;
+
+ ret = ctdb_int32_pull(buf+offset, buflen-offset, &num_scripts, &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ if (num_scripts < 0) {
+ return EINVAL;
+ }
+
+ value = talloc_zero(mem_ctx, struct ctdb_event_script_list);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ value->num_scripts = num_scripts;
+ if (num_scripts == 0) {
+ goto done;
+ }
+
+ value->script = talloc_array(value, struct ctdb_event_script,
+ num_scripts);
+ if (value->script == NULL) {
+ goto fail;
+ }
+
+ for (i=0; i<num_scripts; i++) {
+ ret = ctdb_event_script_pull_elems(buf+offset,
+ buflen-offset,
+ value,
+ &value->script[i],
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+ }
+
+done:
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+static size_t ctdb_event_request_run_len(struct ctdb_event_request_run *in)
+{
+ return ctdb_stringn_len(&in->component) +
+ ctdb_stringn_len(&in->event) +
+ ctdb_stringn_len(&in->args) +
+ ctdb_uint32_len(&in->timeout) +
+ ctdb_uint32_len(&in->flags);
+}
+
+static void ctdb_event_request_run_push(struct ctdb_event_request_run *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_stringn_push(&in->component, buf+offset, &np);
+ offset += np;
+
+ ctdb_stringn_push(&in->event, buf+offset, &np);
+ offset += np;
+
+ ctdb_stringn_push(&in->args, buf+offset, &np);
+ offset += np;
+
+ ctdb_uint32_push(&in->timeout, buf+offset, &np);
+ offset += np;
+
+ ctdb_uint32_push(&in->flags, buf+offset, &np);
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_request_run_pull(uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request_run **out,
+ size_t *npull)
+{
+ struct ctdb_event_request_run *value;
+ size_t offset = 0, np;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_request_run);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->component,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->event,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->args,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_uint32_pull(buf+offset,
+ buflen-offset,
+ &value->timeout,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_uint32_pull(buf+offset,
+ buflen-offset,
+ &value->flags,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+static size_t ctdb_event_request_status_len(
+ struct ctdb_event_request_status *in)
+{
+ return ctdb_stringn_len(&in->component) +
+ ctdb_stringn_len(&in->event);
+}
+
+static void ctdb_event_request_status_push(
+ struct ctdb_event_request_status *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_stringn_push(&in->component, buf+offset, &np);
+ offset += np;
+
+ ctdb_stringn_push(&in->event, buf+offset, &np);
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_request_status_pull(
+ uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request_status **out,
+ size_t *npull)
+{
+ struct ctdb_event_request_status *value;
+ size_t offset = 0, np;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_request_status);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->component,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->event,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+static size_t ctdb_event_request_script_len(
+ struct ctdb_event_request_script *in)
+{
+ return ctdb_stringn_len(&in->component) +
+ ctdb_stringn_len(&in->script) +
+ ctdb_event_script_action_len(in->action);
+}
+
+static void ctdb_event_request_script_push(
+ struct ctdb_event_request_script *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_stringn_push(&in->component, buf+offset, &np);
+ offset += np;
+
+ ctdb_stringn_push(&in->script, buf+offset, &np);
+ offset += np;
+
+ ctdb_event_script_action_push(in->action, buf+offset, &np);
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_request_script_pull(
+ uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request_script **out,
+ size_t *npull)
+{
+ struct ctdb_event_request_script *value;
+ size_t offset = 0, np;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_request_script);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->component,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_stringn_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->script,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_event_script_action_pull(buf+offset,
+ buflen-offset,
+ &value->action,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+static size_t ctdb_event_reply_status_len(
+ struct ctdb_event_reply_status *in)
+{
+ return ctdb_int32_len(&in->summary) +
+ ctdb_event_script_list_len(in->script_list);
+}
+
+static void ctdb_event_reply_status_push(
+ struct ctdb_event_reply_status *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_int32_push(&in->summary, buf+offset, &np);
+ offset += np;
+
+ ctdb_event_script_list_push(in->script_list, buf+offset, &np);
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_reply_status_pull(
+ uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply_status **out,
+ size_t *npull)
+{
+ struct ctdb_event_reply_status *value;
+ size_t offset = 0, np;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_reply_status);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_int32_pull(buf+offset, buflen-offset, &value->summary, &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_event_script_list_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->script_list,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+static size_t ctdb_event_header_len(struct ctdb_event_header *in)
+{
+ return ctdb_uint32_len(&in->length) +
+ ctdb_uint32_len(&in->version) +
+ ctdb_uint32_len(&in->reqid);
+}
+
+static void ctdb_event_header_push(struct ctdb_event_header *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_uint32_push(&in->length, buf+offset, &np);
+ offset += np;
+
+ ctdb_uint32_push(&in->version, buf+offset, &np);
+ offset += np;
+
+ ctdb_uint32_push(&in->reqid, buf+offset, &np);
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_header_pull(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *value,
+ size_t *npull)
+{
+ size_t offset = 0, np;
+ int ret;
+
+ ret = ctdb_uint32_pull(buf+offset,
+ buflen-offset,
+ &value->length,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_uint32_pull(buf+offset,
+ buflen-offset,
+ &value->version,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_uint32_pull(buf+offset,
+ buflen-offset,
+ &value->reqid,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ *npull = offset;
+
+ return 0;
+}
+
+int ctdb_event_header_extract(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *value)
+{
+ size_t np;
+
+ return ctdb_event_header_pull(buf, buflen, value, &np);
+}
+
+static size_t ctdb_event_request_data_len(struct ctdb_event_request *in)
+{
+ size_t len;
+
+ len = ctdb_event_command_len(in->cmd);
+
+ switch (in->cmd) {
+ case CTDB_EVENT_CMD_RUN:
+ len += ctdb_event_request_run_len(in->data.run);
+ break;
+
+ case CTDB_EVENT_CMD_STATUS:
+ len += ctdb_event_request_status_len(in->data.status);
+ break;
+
+ case CTDB_EVENT_CMD_SCRIPT:
+ len += ctdb_event_request_script_len(in->data.script);
+ break;
+
+ default:
+ break;
+ }
+
+ return len;
+}
+
+static void ctdb_event_request_data_push(struct ctdb_event_request *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_event_command_push(in->cmd, buf+offset, &np);
+ offset += np;
+
+ switch (in->cmd) {
+ case CTDB_EVENT_CMD_RUN:
+ ctdb_event_request_run_push(in->data.run, buf+offset, &np);
+ break;
+
+ case CTDB_EVENT_CMD_STATUS:
+ ctdb_event_request_status_push(in->data.status,
+ buf+offset,
+ &np);
+ break;
+
+ case CTDB_EVENT_CMD_SCRIPT:
+ ctdb_event_request_script_push(in->data.script,
+ buf+offset,
+ &np);
+ break;
+ default:
+ np = 0;
+ break;
+ }
+ offset += np;
+
+ *npush = offset;
+}
+
+static int ctdb_event_request_data_pull(uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request **out,
+ size_t *npull)
+{
+ struct ctdb_event_request *value;
+ size_t offset = 0, np;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_request);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_event_command_pull(buf+offset,
+ buflen-offset,
+ &value->cmd,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ switch (value->cmd) {
+ case CTDB_EVENT_CMD_RUN:
+ ret = ctdb_event_request_run_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->data.run,
+ &np);
+ break;
+
+ case CTDB_EVENT_CMD_STATUS:
+ ret = ctdb_event_request_status_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->data.status,
+ &np);
+ break;
+
+ case CTDB_EVENT_CMD_SCRIPT:
+ ret = ctdb_event_request_script_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->data.script,
+ &np);
+ break;
+
+ default:
+ np = 0;
+ break;
+ }
+
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+static size_t ctdb_event_reply_data_len(struct ctdb_event_reply *in)
+{
+ size_t len;
+
+ len = ctdb_event_command_len(in->cmd) +
+ ctdb_int32_len(&in->result);
+
+ if (in->result != 0) {
+ goto done;
+ }
+
+ switch (in->cmd) {
+ case CTDB_EVENT_CMD_STATUS:
+ len += ctdb_event_reply_status_len(in->data.status);
+ break;
+
+ default:
+ break;
+ }
+
+done:
+ return len;
+}
+
+static void ctdb_event_reply_data_push(struct ctdb_event_reply *in,
+ uint8_t *buf,
+ size_t *npush)
+{
+ size_t offset = 0, np;
+
+ ctdb_event_command_push(in->cmd, buf+offset, &np);
+ offset += np;
+
+ ctdb_int32_push(&in->result, buf+offset, &np);
+ offset += np;
+
+ if (in->result != 0) {
+ goto done;
+ }
+
+ switch (in->cmd) {
+ case CTDB_EVENT_CMD_STATUS:
+ ctdb_event_reply_status_push(in->data.status, buf+offset, &np);
+ break;
+
+ default:
+ np = 0;
+ break;
+ }
+ offset += np;
+
+done:
+ *npush = offset;
+}
+
+static int ctdb_event_reply_data_pull(uint8_t *buf,
+ size_t buflen,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply **out,
+ size_t *npull)
+{
+ struct ctdb_event_reply *value;
+ size_t offset = 0, np;
+ int ret;
+
+ value = talloc(mem_ctx, struct ctdb_event_reply);
+ if (value == NULL) {
+ return ENOMEM;
+ }
+
+ ret = ctdb_event_command_pull(buf+offset,
+ buflen-offset,
+ &value->cmd,
+ &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ ret = ctdb_int32_pull(buf+offset, buflen-offset, &value->result, &np);
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+ if (value->result != 0) {
+ goto done;
+ }
+
+ switch (value->cmd) {
+ case CTDB_EVENT_CMD_STATUS:
+ ret = ctdb_event_reply_status_pull(buf+offset,
+ buflen-offset,
+ value,
+ &value->data.status,
+ &np);
+ break;
+
+ default:
+ np = 0;
+ break;
+ }
+
+ if (ret != 0) {
+ goto fail;
+ }
+ offset += np;
+
+done:
+ *out = value;
+ *npull = offset;
+
+ return 0;
+
+fail:
+ talloc_free(value);
+ return ret;
+}
+
+size_t ctdb_event_request_len(struct ctdb_event_header *h,
+ struct ctdb_event_request *in)
+{
+ return ctdb_event_header_len(h) +
+ ctdb_event_request_data_len(in);
+}
+
+int ctdb_event_request_push(struct ctdb_event_header *h,
+ struct ctdb_event_request *in,
+ uint8_t *buf,
+ size_t *buflen)
+{
+ size_t len, offset = 0, np;
+
+ len = ctdb_event_request_len(h, in);
+ if (*buflen < len) {
+ *buflen = len;
+ return EMSGSIZE;
+ }
+
+ h->length = *buflen;
+
+ ctdb_event_header_push(h, buf+offset, &np);
+ offset += np;
+
+ ctdb_event_request_data_push(in, buf+offset, &np);
+ offset += np;
+
+ if (offset > *buflen) {
+ return EMSGSIZE;
+ }
+
+ return 0;
+}
+
+int ctdb_event_request_pull(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *h,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request **out)
+{
+ size_t offset = 0, np;
+ int ret;
+
+ ret = ctdb_event_header_pull(buf+offset, buflen-offset, h, &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_event_request_data_pull(buf+offset,
+ buflen-offset,
+ mem_ctx,
+ out,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ if (offset > buflen) {
+ return EMSGSIZE;
+ }
+
+ return 0;
+}
+
+size_t ctdb_event_reply_len(struct ctdb_event_header *h,
+ struct ctdb_event_reply *in)
+{
+ return ctdb_event_header_len(h) +
+ ctdb_event_reply_data_len(in);
+}
+
+int ctdb_event_reply_push(struct ctdb_event_header *h,
+ struct ctdb_event_reply *in,
+ uint8_t *buf,
+ size_t *buflen)
+{
+ size_t len, offset = 0, np;
+
+ len = ctdb_event_reply_len(h, in);
+ if (*buflen < len) {
+ *buflen = len;
+ return EMSGSIZE;
+ }
+
+ h->length = *buflen;
+
+ ctdb_event_header_push(h, buf+offset, &np);
+ offset += np;
+
+ ctdb_event_reply_data_push(in, buf+offset, &np);
+ offset += np;
+
+ if (offset > *buflen) {
+ return EMSGSIZE;
+ }
+
+ return 0;
+}
+
+int ctdb_event_reply_pull(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *h,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply **out)
+{
+ size_t offset = 0, np;
+ int ret;
+
+ ret = ctdb_event_header_pull(buf+offset, buflen-offset, h, &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ ret = ctdb_event_reply_data_pull(buf+offset,
+ buflen-offset,
+ mem_ctx,
+ out,
+ &np);
+ if (ret != 0) {
+ return ret;
+ }
+ offset += np;
+
+ if (offset > buflen) {
+ return EMSGSIZE;
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ CTDB event daemon protocol
+ Based on eventd code
+
+ Copyright (C) Amitay Isaacs 2018
+
+ 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/>.
+*/
+
+#ifndef __CTDB_EVENT_PROTOCOL_H__
+#define __CTDB_EVENT_PROTOCOL_H__
+
+#define CTDB_EVENT_PROTOCOL_VERSION 1
+
+enum ctdb_event_script_action {
+ CTDB_EVENT_SCRIPT_DISABLE = 0,
+ CTDB_EVENT_SCRIPT_ENABLE = 1,
+};
+
+enum ctdb_event_command {
+ CTDB_EVENT_CMD_RUN = 1,
+ CTDB_EVENT_CMD_STATUS = 2,
+ CTDB_EVENT_CMD_SCRIPT = 3,
+ CTDB_EVENT_CMD_MAX = 4,
+};
+
+struct ctdb_event_script {
+ const char *name;
+ struct timeval begin;
+ struct timeval end;
+ int result;
+ const char *output;
+};
+
+struct ctdb_event_script_list {
+ int num_scripts;
+ struct ctdb_event_script *script;
+};
+
+#define CTDB_EVENT_RUN_ALL 1
+
+struct ctdb_event_request_run {
+ const char *component;
+ const char *event;
+ const char *args;
+ uint32_t timeout;
+ uint32_t flags;
+};
+
+struct ctdb_event_request_status {
+ const char *component;
+ const char *event;
+};
+
+struct ctdb_event_request_script {
+ const char *component;
+ const char *script;
+ enum ctdb_event_script_action action;
+};
+
+struct ctdb_event_reply_status {
+ int32_t summary;
+ struct ctdb_event_script_list *script_list;
+};
+
+struct ctdb_event_header {
+ uint32_t length;
+ uint32_t version;
+ uint32_t reqid;
+};
+
+struct ctdb_event_request {
+ enum ctdb_event_command cmd;
+ union {
+ struct ctdb_event_request_run *run;
+ struct ctdb_event_request_status *status;
+ struct ctdb_event_request_script *script;
+ } data;
+};
+
+struct ctdb_event_reply {
+ enum ctdb_event_command cmd;
+ int32_t result;
+ union {
+ struct ctdb_event_reply_status *status;
+ } data;
+};
+
+#endif /* __CTDB_EVENT_PROTOCOL_H__ */
--- /dev/null
+/*
+ CTDB event daemon protocol
+
+ Copyright (C) Amitay Isaacs 2018
+
+ 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/>.
+*/
+
+#ifndef __CTDB_EVENT_PROTOCOL_API_H__
+#define __CTDB_EVENT_PROTOCOL_API_H__
+
+#include <talloc.h>
+
+#include "event/event_protocol.h"
+
+/* From event/event_protocol.c */
+
+int ctdb_event_header_extract(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *h);
+
+size_t ctdb_event_request_len(struct ctdb_event_header *h,
+ struct ctdb_event_request *in);
+int ctdb_event_request_push(struct ctdb_event_header *h,
+ struct ctdb_event_request *in,
+ uint8_t *buf,
+ size_t *buflen);
+int ctdb_event_request_pull(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *h,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request **out);
+
+size_t ctdb_event_reply_len(struct ctdb_event_header *h,
+ struct ctdb_event_reply *in);
+int ctdb_event_reply_push(struct ctdb_event_header *h,
+ struct ctdb_event_reply *in,
+ uint8_t *buf,
+ size_t *buflen);
+int ctdb_event_reply_pull(uint8_t *buf,
+ size_t buflen,
+ struct ctdb_event_header *h,
+ TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply **out);
+
+/* From event/event_protocol_util.c */
+
+const char *ctdb_event_command_to_string(enum ctdb_event_command cmd);
+
+#endif /* __CTDB_EVENT_PROTOCOL_API_H__ */
--- /dev/null
+/*
+ CTDB event daemon - protocol test
+
+ Copyright (C) Amitay Isaacs 2018
+
+ 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 <talloc.h>
+#include <assert.h>
+
+#define EVENT_PROTOCOL_TEST
+#include "event/event_protocol.c"
+
+#include "tests/src/protocol_common_basic.h"
+
+/*
+ * Functions to fill and verify event protocol structures
+ */
+
+static void fill_ctdb_event_script(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_script *p)
+{
+ fill_ctdb_stringn(mem_ctx, &p->name);
+ fill_ctdb_timeval(&p->begin);
+ fill_ctdb_timeval(&p->end);
+ p->result = rand32i();
+ fill_ctdb_stringn(mem_ctx, &p->output);
+}
+
+static void verify_ctdb_event_script(struct ctdb_event_script *p1,
+ struct ctdb_event_script *p2)
+{
+ verify_ctdb_stringn(&p1->name, &p2->name);
+ verify_ctdb_timeval(&p1->begin, &p2->begin);
+ verify_ctdb_timeval(&p1->end, &p2->end);
+ assert(p1->result == p2->result);
+ verify_ctdb_stringn(&p1->output, &p2->output);
+}
+
+static void fill_ctdb_event_script_list(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_script_list *p)
+{
+ int i;
+
+ p->num_scripts = rand_int(32);
+ if (p->num_scripts > 0) {
+ p->script = talloc_array(mem_ctx,
+ struct ctdb_event_script,
+ p->num_scripts);
+ assert(p->script != NULL);
+
+ for (i=0; i<p->num_scripts; i++) {
+ fill_ctdb_event_script(mem_ctx, &p->script[i]);
+ }
+ } else {
+ p->script = NULL;
+ }
+}
+
+static void verify_ctdb_event_script_list(struct ctdb_event_script_list *p1,
+ struct ctdb_event_script_list *p2)
+{
+ int i;
+
+ assert(p1->num_scripts == p2->num_scripts);
+ for (i=0; i<p1->num_scripts; i++) {
+ verify_ctdb_event_script(&p1->script[i], &p2->script[i]);
+ }
+}
+
+static void fill_ctdb_event_request_run(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request_run *p)
+{
+ fill_ctdb_stringn(mem_ctx, &p->component);
+ fill_ctdb_stringn(mem_ctx, &p->event);
+ fill_ctdb_stringn(mem_ctx, &p->args);
+ p->timeout = rand32();
+ p->flags = rand32();
+}
+
+static void verify_ctdb_event_request_run(struct ctdb_event_request_run *p1,
+ struct ctdb_event_request_run *p2)
+{
+ verify_ctdb_stringn(&p1->component, &p2->component);
+ verify_ctdb_stringn(&p1->event, &p2->event);
+ verify_ctdb_stringn(&p1->args, &p2->args);
+ assert(p1->timeout == p2->timeout);
+ assert(p1->flags == p2->flags);
+}
+
+static void fill_ctdb_event_request_status(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request_status *p)
+{
+ fill_ctdb_stringn(mem_ctx, &p->component);
+ fill_ctdb_stringn(mem_ctx, &p->event);
+}
+
+static void verify_ctdb_event_request_status(
+ struct ctdb_event_request_status *p1,
+ struct ctdb_event_request_status *p2)
+{
+ verify_ctdb_stringn(&p1->component, &p2->component);
+ verify_ctdb_stringn(&p1->event, &p2->event);
+}
+
+static void fill_ctdb_event_request_script(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request_script *p)
+{
+ fill_ctdb_stringn(mem_ctx, &p->component);
+ fill_ctdb_stringn(mem_ctx, &p->script);
+ if (rand_int(1) == 0) {
+ p->action = CTDB_EVENT_SCRIPT_DISABLE;
+ } else {
+ p->action = CTDB_EVENT_SCRIPT_ENABLE;
+ }
+}
+
+static void fill_ctdb_event_reply_status(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply_status *p)
+{
+ p->summary = rand32i();
+ p->script_list = talloc(mem_ctx, struct ctdb_event_script_list);
+ assert(p->script_list != NULL);
+
+ fill_ctdb_event_script_list(mem_ctx, p->script_list);
+}
+
+static void verify_ctdb_event_reply_status(struct ctdb_event_reply_status *p1,
+ struct ctdb_event_reply_status *p2)
+{
+ assert(p1->summary == p2->summary);
+ verify_ctdb_event_script_list(p1->script_list, p2->script_list);
+}
+
+static void verify_ctdb_event_request_script(
+ struct ctdb_event_request_script *p1,
+ struct ctdb_event_request_script *p2)
+{
+ verify_ctdb_stringn(&p1->component, &p2->component);
+ verify_ctdb_stringn(&p1->script, &p2->script);
+ assert(p1->action == p2->action);
+}
+
+static void fill_ctdb_event_request_data(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request *p,
+ uint32_t cmd)
+{
+ p->cmd = cmd;
+
+ switch (cmd) {
+ case CTDB_EVENT_CMD_RUN:
+ p->data.run = talloc(mem_ctx, struct ctdb_event_request_run);
+ assert(p->data.run != NULL);
+
+ fill_ctdb_event_request_run(mem_ctx, p->data.run);
+ break;
+
+ case CTDB_EVENT_CMD_STATUS:
+ p->data.status = talloc(mem_ctx,
+ struct ctdb_event_request_status);
+ assert(p->data.status != NULL);
+
+ fill_ctdb_event_request_status(mem_ctx, p->data.status);
+ break;
+
+ case CTDB_EVENT_CMD_SCRIPT:
+ p->data.script = talloc(mem_ctx,
+ struct ctdb_event_request_script);
+ assert(p->data.script != NULL);
+
+ fill_ctdb_event_request_script(mem_ctx, p->data.script);
+ break;
+
+ default:
+ assert(cmd > 0 && cmd < CTDB_EVENT_CMD_MAX);
+ }
+}
+
+static void verify_ctdb_event_request_data(struct ctdb_event_request *p1,
+ struct ctdb_event_request *p2)
+{
+ assert(p1->cmd == p2->cmd);
+
+ switch (p1->cmd) {
+ case CTDB_EVENT_CMD_RUN:
+ verify_ctdb_event_request_run(p1->data.run, p2->data.run);
+ break;
+
+ case CTDB_EVENT_CMD_STATUS:
+ verify_ctdb_event_request_status(p1->data.status,
+ p2->data.status);
+ break;
+
+ case CTDB_EVENT_CMD_SCRIPT:
+ verify_ctdb_event_request_script(p1->data.script,
+ p2->data.script);
+ break;
+
+ default:
+ assert(p1->cmd > 0 && p1->cmd < CTDB_EVENT_CMD_MAX);
+ }
+}
+
+static void fill_ctdb_event_reply_data(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply *p,
+ uint32_t cmd)
+{
+ p->cmd = cmd;
+ p->result = rand32i();
+
+ if (p->result != 0) {
+ return;
+ }
+
+ switch (cmd) {
+ case CTDB_EVENT_CMD_STATUS:
+ p->data.status = talloc(mem_ctx,
+ struct ctdb_event_reply_status);
+ assert(p->data.status != NULL);
+
+ fill_ctdb_event_reply_status(mem_ctx, p->data.status);
+ break;
+
+ default:
+ assert(cmd > 0 && cmd < CTDB_EVENT_CMD_MAX);
+ }
+}
+
+static void verify_ctdb_event_reply_data(struct ctdb_event_reply *p1,
+ struct ctdb_event_reply *p2)
+{
+ assert(p1->cmd == p2->cmd);
+ assert(p1->result == p2->result);
+
+ if (p1->result != 0) {
+ return;
+ }
+
+ switch (p1->cmd) {
+ case CTDB_EVENT_CMD_STATUS:
+ verify_ctdb_event_reply_status(p1->data.status,
+ p2->data.status);
+ break;
+
+ default:
+ assert(p1->cmd > 0 && p1->cmd < CTDB_EVENT_CMD_MAX);
+ }
+}
+
+static void fill_ctdb_event_header(struct ctdb_event_header *p)
+{
+ p->length = 0; /* updated by push functions */
+ p->version = 0; /* updated by push functions */
+ p->reqid = rand32();
+}
+
+static void verify_ctdb_event_header(struct ctdb_event_header *p1,
+ struct ctdb_event_header *p2)
+{
+ assert(p1->length == p2->length);
+ assert(p1->version == p2->version);
+ assert(p1->reqid == p2->reqid);
+}
+
+static void fill_ctdb_event_request(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_request *p,
+ uint32_t cmd)
+{
+ fill_ctdb_event_request_data(mem_ctx, p, cmd);
+}
+
+static void verify_ctdb_event_request(struct ctdb_event_request *p1,
+ struct ctdb_event_request *p2)
+{
+ verify_ctdb_event_request_data(p1, p2);
+}
+
+static void fill_ctdb_event_reply(TALLOC_CTX *mem_ctx,
+ struct ctdb_event_reply *p,
+ uint32_t cmd)
+{
+ fill_ctdb_event_reply_data(mem_ctx, p, cmd);
+}
+
+static void verify_ctdb_event_reply(struct ctdb_event_reply *p1,
+ struct ctdb_event_reply *p2)
+{
+ verify_ctdb_event_reply_data(p1, p2);
+}
+
+#define EVENT_PROTOCOL1_TEST(TYPE, NAME) \
+static void TEST_FUNC(NAME)(uint32_t cmd) \
+{ \
+ TALLOC_CTX *mem_ctx; \
+ TYPE c1, *c2; \
+ uint8_t *buf; \
+ size_t buflen, np; \
+ int ret; \
+\
+ printf("%s %u\n", #NAME, cmd); \
+ fflush(stdout); \
+ mem_ctx = talloc_new(NULL); \
+ assert(mem_ctx != NULL); \
+ FILL_FUNC(NAME)(mem_ctx, &c1, cmd); \
+ buflen = LEN_FUNC(NAME)(&c1); \
+ buf = talloc_size(mem_ctx, buflen); \
+ assert(buf != NULL); \
+ np = 0; \
+ PUSH_FUNC(NAME)(&c1, buf, &np); \
+ assert(np == buflen); \
+ np = 0; \
+ ret = PULL_FUNC(NAME)(buf, buflen, mem_ctx, &c2, &np); \
+ assert(ret == 0); \
+ assert(np == buflen); \
+ VERIFY_FUNC(NAME)(&c1, c2); \
+ talloc_free(mem_ctx); \
+}
+
+#define EVENT_PROTOCOL2_TEST(TYPE, NAME) \
+static void TEST_FUNC(NAME)(uint32_t cmd) \
+{ \
+ TALLOC_CTX *mem_ctx; \
+ struct ctdb_event_header h1, h2; \
+ TYPE c1, *c2; \
+ uint8_t *buf; \
+ size_t buflen, len; \
+ int ret; \
+\
+ printf("%s %u\n", #NAME, cmd); \
+ fflush(stdout); \
+ mem_ctx = talloc_new(NULL); \
+ assert(mem_ctx != NULL); \
+ fill_ctdb_event_header(&h1); \
+ FILL_FUNC(NAME)(mem_ctx, &c1, cmd); \
+ buflen = LEN_FUNC(NAME)(&h1, &c1); \
+ buf = talloc_size(mem_ctx, buflen); \
+ assert(buf != NULL); \
+ len = 0; \
+ ret = PUSH_FUNC(NAME)(&h1, &c1, buf, &len); \
+ assert(ret == EMSGSIZE); \
+ assert(len == buflen); \
+ ret = PUSH_FUNC(NAME)(&h1, &c1, buf, &buflen); \
+ assert(ret == 0); \
+ ret = PULL_FUNC(NAME)(buf, buflen, &h2, mem_ctx, &c2); \
+ assert(ret == 0); \
+ verify_ctdb_event_header(&h1, &h2); \
+ VERIFY_FUNC(NAME)(&c1, c2); \
+ talloc_free(mem_ctx); \
+}
+
+PROTOCOL_TYPE3_TEST(struct ctdb_event_script, ctdb_event_script);
+PROTOCOL_TYPE3_TEST(struct ctdb_event_script_list, ctdb_event_script_list);
+
+PROTOCOL_TYPE3_TEST(struct ctdb_event_request_run, ctdb_event_request_run);
+PROTOCOL_TYPE3_TEST(struct ctdb_event_request_status,
+ ctdb_event_request_status);
+PROTOCOL_TYPE3_TEST(struct ctdb_event_request_script,
+ ctdb_event_request_script);
+
+PROTOCOL_TYPE3_TEST(struct ctdb_event_reply_status, ctdb_event_reply_status);
+
+EVENT_PROTOCOL1_TEST(struct ctdb_event_request, ctdb_event_request_data);
+EVENT_PROTOCOL1_TEST(struct ctdb_event_reply, ctdb_event_reply_data);
+
+EVENT_PROTOCOL2_TEST(struct ctdb_event_request, ctdb_event_request);
+EVENT_PROTOCOL2_TEST(struct ctdb_event_reply, ctdb_event_reply);
+
+int main(int argc, const char **argv)
+{
+ uint32_t cmd;
+
+ if (argc == 2) {
+ int seed = atoi(argv[1]);
+ srandom(seed);
+ }
+
+ TEST_FUNC(ctdb_event_script)();
+ TEST_FUNC(ctdb_event_script_list)();
+
+ TEST_FUNC(ctdb_event_request_run)();
+ TEST_FUNC(ctdb_event_request_status)();
+ TEST_FUNC(ctdb_event_request_script)();
+
+ TEST_FUNC(ctdb_event_reply_status)();
+
+ for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
+ TEST_FUNC(ctdb_event_request_data)(cmd);
+ }
+ for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
+ TEST_FUNC(ctdb_event_reply_data)(cmd);
+ }
+
+ for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
+ TEST_FUNC(ctdb_event_request)(cmd);
+ }
+ for (cmd=1; cmd<CTDB_EVENT_CMD_MAX; cmd++) {
+ TEST_FUNC(ctdb_event_reply)(cmd);
+ }
+
+ return 0;
+}
--- /dev/null
+/*
+ CTDB event daemon - protocol utilities
+
+ Copyright (C) Amitay Isaacs 2018
+
+ 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 "event/event_protocol.h"
+#include "event/event_protocol_api.h"
+
+static struct {
+ enum ctdb_event_command command;
+ const char *label;
+} event_command_map[] = {
+ { CTDB_EVENT_CMD_RUN, "RUN" },
+ { CTDB_EVENT_CMD_STATUS, "STATUS" },
+ { CTDB_EVENT_CMD_SCRIPT, "SCRIPT" },
+ { CTDB_EVENT_CMD_MAX, NULL },
+};
+
+const char *ctdb_event_command_to_string(enum ctdb_event_command command)
+{
+ int i;
+
+ for (i=0; event_command_map[i].label != NULL; i++) {
+ if (event_command_map[i].command == command) {
+ return event_command_map[i].label;
+ }
+ }
+
+ return "UNKNOWN";
+}
--- /dev/null
+#!/bin/sh
+
+. "${TEST_SCRIPTS_DIR}/unit.sh"
+
+last_command=3
+
+generate_output ()
+{
+ for i in $(seq 1 $last_command) ; do
+ echo "$1 $i"
+ done
+}
+
+output=$(
+ generate_output "ctdb_event_request_data"
+ generate_output "ctdb_event_reply_data"
+ generate_output "ctdb_event_request"
+ generate_output "ctdb_event_reply"
+)
+
+ok "$output"
+
+for i in $(seq 1 100) ; do
+ unit_test event_protocol_test $i
+done
ctdb-util samba-util talloc replace popt''',
install_path='${CTDB_HELPER_BINDIR}')
+ bld.SAMBA_SUBSYSTEM('ctdb-event-protocol',
+ source=bld.SUBDIR('event',
+ '''event_protocol.c
+ event_protocol_util.c
+ '''),
+ deps='ctdb-protocol-basic')
+
bld.SAMBA_BINARY('ctdbd',
source='server/ctdbd.c ' +
bld.SUBDIR('server',
samba-util talloc tdb''',
install_path='${CTDB_TEST_LIBEXECDIR}')
+ bld.SAMBA_BINARY('event_protocol_test',
+ source='event/event_protocol_test.c',
+ deps='''ctdb-protocol-tests-basic
+ ctdb-protocol-basic talloc''',
+ install_path='${CTDB_TEST_LIBEXECDIR}')
+
bld.SAMBA_SUBSYSTEM('ctdb-tests-common',
source=bld.SUBDIR('tests/src',
'cluster_wait.c test_options.c'),