ctdb: Implement CTDB_CONTROL_ECHO_DATA
authorVolker Lendecke <vl@samba.org>
Wed, 18 Mar 2020 10:31:14 +0000 (11:31 +0100)
committerRalph Boehme <slow@samba.org>
Tue, 28 Apr 2020 09:08:39 +0000 (09:08 +0000)
Testing control: 4 bytes msec delay plus a blob, return the request after the
delay. This is an enhanced "ping" which can be used to test asynchronous
clients.

Doesn't have the full protocol implementation yet

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/server/ctdb_control.c

index d162268a178ca2cdf41bbcaae4c3822c2e3cd361..95f3b175934a871b7df8a1be845a441d6881519a 100644 (file)
@@ -89,6 +89,90 @@ static int32_t control_not_implemented(const char *unsupported,
        return -1;
 }
 
+struct ctdb_echo_data_state {
+       struct ctdb_context *ctdb;
+       struct ctdb_req_control_old *c;
+       struct ctdb_echo_data *data;
+};
+
+static void ctdb_echo_data_timeout(
+       struct tevent_context *ev,
+       struct tevent_timer *te,
+       struct timeval now,
+       void *private_data);
+
+static int32_t ctdb_control_echo_data(
+       struct ctdb_context *ctdb,
+       struct ctdb_req_control_old *c,
+       TDB_DATA indata,
+       bool *async_reply)
+{
+       struct ctdb_echo_data_state *state = NULL;
+       struct tevent_timer *te = NULL;
+       uint32_t delay = 0;
+       size_t np = 0;
+       int ret;
+
+       state = talloc_zero(ctdb, struct ctdb_echo_data_state);
+       CTDB_NO_MEMORY(ctdb, state);
+       state->ctdb = ctdb;
+
+       ret = ctdb_echo_data_pull(
+               indata.dptr, indata.dsize, state, &state->data, &np);
+       if (ret != 0) {
+               DBG_DEBUG("ctdb_echo_data_pull failed: %s\n",
+                         strerror(ret));
+               TALLOC_FREE(state);
+               return -1;
+       }
+
+       te = tevent_add_timer(
+               ctdb->ev,
+               state,
+               timeval_current_ofs_msec(delay),
+               ctdb_echo_data_timeout,
+               state);
+       if (te == NULL) {
+               DBG_DEBUG("tevent_add_timer failed\n");
+               TALLOC_FREE(state);
+               return -1;
+       }
+
+       state->c = talloc_move(state, &c);
+       *async_reply = true;
+
+       return 0;
+}
+
+static void ctdb_echo_data_timeout(
+       struct tevent_context *ev,
+       struct tevent_timer *te,
+       struct timeval now,
+       void *private_data)
+{
+       struct ctdb_echo_data_state *state = talloc_get_type_abort(
+               private_data, struct ctdb_echo_data_state);
+       size_t len = ctdb_echo_data_len(state->data);
+       uint8_t *buf = NULL;
+       size_t np;
+       TDB_DATA data;
+
+       DBG_DEBUG("reqid=%"PRIu32" len=%zu\n", state->c->hdr.reqid, len);
+
+       buf = talloc_array(state, uint8_t, len);
+       if (buf == NULL) {
+               DBG_WARNING("talloc_array(%zu) failed\n", len);
+               goto done;
+       }
+       ctdb_echo_data_push(state->data, buf, &np);
+       data = (TDB_DATA) { .dptr = buf, .dsize = np };
+
+       ctdb_request_control_reply(state->ctdb, state->c, &data, 0, NULL);
+
+done:
+       TALLOC_FREE(state);
+}
+
 /*
   process a control request
  */
@@ -740,6 +824,9 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
                CHECK_CONTROL_DATA_SIZE(ctdb_db_vacuum_len(&db_vacuum));
                return ctdb_control_db_vacuum(ctdb, c, indata, async_reply);
        }
+       case CTDB_CONTROL_ECHO_DATA: {
+               return ctdb_control_echo_data(ctdb, c, indata, async_reply);
+       }
 
        default:
                DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));