ctdb-protocol: Fix marshalling for ctdb_req_message
authorAmitay Isaacs <amitay@gmail.com>
Fri, 21 Jul 2017 05:07:30 +0000 (15:07 +1000)
committerMartin Schwenke <martins@samba.org>
Wed, 30 Aug 2017 12:59:26 +0000 (14:59 +0200)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_message.c
ctdb/tests/cunit/protocol_test_101.sh
ctdb/tests/src/protocol_common_ctdb.c
ctdb/tests/src/protocol_common_ctdb.h
ctdb/tests/src/protocol_ctdb_compat_test.c
ctdb/tests/src/protocol_ctdb_test.c

index 2a33acd01ae6de00e5e75bb415e959127e0cbc0c..f254ed19408782133ec1286a40f9622b937e1b5d 100644 (file)
@@ -316,31 +316,40 @@ static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
 size_t ctdb_req_message_len(struct ctdb_req_header *h,
                            struct ctdb_req_message *c)
 {
-       return offsetof(struct ctdb_req_message_wire, data) +
-               ctdb_message_data_len(&c->data, c->srvid);
+       uint32_t u32 = ctdb_message_data_len(&c->data, c->srvid);
+
+       return ctdb_req_header_len(h) +
+               ctdb_uint64_len(&c->srvid) +
+               ctdb_uint32_len(&u32) + u32;
 }
 
 int ctdb_req_message_push(struct ctdb_req_header *h,
-                         struct ctdb_req_message *message,
+                         struct ctdb_req_message *c,
                          uint8_t *buf, size_t *buflen)
 {
-       struct ctdb_req_message_wire *wire =
-               (struct ctdb_req_message_wire *)buf;
-       size_t length, np;
+       size_t offset = 0, np;
+       size_t length;
+       uint32_t u32;
 
-       length = ctdb_req_message_len(h, message);
+       length = ctdb_req_message_len(h, c);
        if (*buflen < length) {
                *buflen = length;
                return EMSGSIZE;
        }
 
        h->length = *buflen;
-       ctdb_req_header_push(h, (uint8_t *)&wire->hdr, &np);
+       ctdb_req_header_push(h, buf+offset, &np);
+       offset += np;
 
-       wire->srvid = message->srvid;
-       wire->datalen = ctdb_message_data_len(&message->data, message->srvid);
-       ctdb_message_data_push(&message->data, message->srvid, wire->data,
-                              &np);
+       ctdb_uint64_push(&c->srvid, buf+offset, &np);
+       offset += np;
+
+       u32 = ctdb_message_data_len(&c->data, c->srvid);
+       ctdb_uint32_push(&u32, buf+offset, &np);
+       offset += np;
+
+       ctdb_message_data_push(&c->data, c->srvid, buf+offset, &np);
+       offset += np;
 
        return 0;
 }
@@ -350,36 +359,44 @@ int ctdb_req_message_pull(uint8_t *buf, size_t buflen,
                          TALLOC_CTX *mem_ctx,
                          struct ctdb_req_message *c)
 {
-       struct ctdb_req_message_wire *wire =
-               (struct ctdb_req_message_wire *)buf;
-       size_t length, np;
+       struct ctdb_req_header header;
+       size_t offset = 0, np;
+       uint32_t u32;
        int ret;
 
-       length = offsetof(struct ctdb_req_message_wire, data);
-       if (buflen < length) {
-               return EMSGSIZE;
+       ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
+       if (ret != 0) {
+               return ret;
        }
-       if (wire->datalen > buflen) {
-               return EMSGSIZE;
+       offset += np;
+
+       if (h != NULL) {
+               *h = header;
        }
-       if (length + wire->datalen < length) {
-               return EMSGSIZE;
+
+       ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->srvid, &np);
+       if (ret != 0) {
+               return ret;
        }
-       if (buflen < length + wire->datalen) {
-               return EMSGSIZE;
+       offset += np;
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
+       if (ret != 0) {
+               return ret;
        }
+       offset += np;
 
-       if (h != NULL) {
-               ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h,
-                                          &np);
-               if (ret != 0) {
-                       return ret;
-               }
+       if (buflen-offset < u32) {
+               return EMSGSIZE;
        }
 
-       c->srvid = wire->srvid;
-       ret = ctdb_message_data_pull(wire->data, wire->datalen, wire->srvid,
+       ret = ctdb_message_data_pull(buf+offset, u32, c->srvid,
                                     mem_ctx, &c->data, &np);
+       if (ret != 0) {
+               return ret;
+       }
+       offset += np;
+
        return ret;
 }
 
index 8d6a74acc347ad4564ce1b81256ac4c81afc9511..d21d16b31e4e5f49997854196452dc26003553ff 100755 (executable)
@@ -52,6 +52,7 @@ output=$(
     generate_control_output "ctdb_req_control"
     generate_control_output "ctdb_reply_control"
     generate_message_output "ctdb_message_data"
+    generate_message_output "ctdb_req_message"
     echo "ctdb_req_message"
 )
 
index 6f3a738dabcef7c13884f25ace8a14a10d8ef425..be9e2560cc69c8bd57c5b198c78f8161dc4f7d7d 100644 (file)
@@ -1921,6 +1921,20 @@ void verify_ctdb_message_data(union ctdb_message_data *md,
        }
 }
 
+void fill_ctdb_req_message(TALLOC_CTX *mem_ctx, struct ctdb_req_message *c,
+                          uint64_t srvid)
+{
+       c->srvid = srvid;
+       fill_ctdb_message_data(mem_ctx, &c->data, srvid);
+}
+
+void verify_ctdb_req_message(struct ctdb_req_message *c,
+                            struct ctdb_req_message *c2)
+{
+       assert(c->srvid == c2->srvid);
+       verify_ctdb_message_data(&c->data, &c2->data, c->srvid);
+}
+
 void fill_ctdb_req_message_data(TALLOC_CTX *mem_ctx,
                                struct ctdb_req_message_data *c)
 {
index bdf2c02ae7bd6990c1383025123a4cb5824cc0ea..f5bd16a8ef7ce6f98f8092ae81e1cec28d796082 100644 (file)
@@ -79,6 +79,11 @@ void fill_ctdb_message_data(TALLOC_CTX *mem_ctx, union ctdb_message_data *md,
 void verify_ctdb_message_data(union ctdb_message_data *md,
                              union ctdb_message_data *md2, uint64_t srvid);
 
+void fill_ctdb_req_message(TALLOC_CTX *mem_ctx, struct ctdb_req_message *c,
+                          uint64_t srvid);
+void verify_ctdb_req_message(struct ctdb_req_message *c,
+                            struct ctdb_req_message *c2);
+
 void fill_ctdb_req_message_data(TALLOC_CTX *mem_ctx,
                                struct ctdb_req_message_data *c);
 void verify_ctdb_req_message_data(struct ctdb_req_message_data *c,
index 960f131abb0550889d23487ac0a1cd1d3fa2474e..0de62f4299942384af8453919ca6de91ba589180 100644 (file)
@@ -27,6 +27,7 @@
 #include "protocol/protocol_header.c"
 #include "protocol/protocol_call.c"
 #include "protocol/protocol_control.c"
+#include "protocol/protocol_message.c"
 
 #include "tests/src/protocol_common.h"
 #include "tests/src/protocol_common_ctdb.h"
@@ -891,6 +892,75 @@ static int ctdb_reply_control_pull_old(uint8_t *buf, size_t buflen,
        return 0;
 }
 
+static size_t ctdb_req_message_len_old(struct ctdb_req_header *h,
+                                      struct ctdb_req_message *c)
+{
+       return offsetof(struct ctdb_req_message_wire, data) +
+               ctdb_message_data_len(&c->data, c->srvid);
+}
+
+static int ctdb_req_message_push_old(struct ctdb_req_header *h,
+                                    struct ctdb_req_message *c,
+                                    uint8_t *buf, size_t *buflen)
+{
+       struct ctdb_req_message_wire *wire =
+               (struct ctdb_req_message_wire *)buf;
+       size_t length, np;
+
+       length = ctdb_req_message_len_old(h, c);
+       if (*buflen < length) {
+               *buflen = length;
+               return EMSGSIZE;
+       }
+
+       h->length = *buflen;
+       ctdb_req_header_push_old(h, (uint8_t *)&wire->hdr);
+
+       wire->srvid = c->srvid;
+       wire->datalen = ctdb_message_data_len(&c->data, c->srvid);
+       ctdb_message_data_push(&c->data, c->srvid, wire->data, &np);
+
+       return 0;
+}
+
+static int ctdb_req_message_pull_old(uint8_t *buf, size_t buflen,
+                                    struct ctdb_req_header *h,
+                                    TALLOC_CTX *mem_ctx,
+                                    struct ctdb_req_message *c)
+{
+       struct ctdb_req_message_wire *wire =
+               (struct ctdb_req_message_wire *)buf;
+       size_t length, np;
+       int ret;
+
+       length = offsetof(struct ctdb_req_message_wire, data);
+       if (buflen < length) {
+               return EMSGSIZE;
+       }
+       if (wire->datalen > buflen) {
+               return EMSGSIZE;
+       }
+       if (length + wire->datalen < length) {
+               return EMSGSIZE;
+       }
+       if (buflen < length + wire->datalen) {
+               return EMSGSIZE;
+       }
+
+       if (h != NULL) {
+               ret = ctdb_req_header_pull_old((uint8_t *)&wire->hdr, buflen,
+                                              h);
+               if (ret != 0) {
+                       return ret;
+               }
+       }
+
+       c->srvid = wire->srvid;
+       ret = ctdb_message_data_pull(wire->data, wire->datalen, wire->srvid,
+                                    mem_ctx, &c->data, &np);
+       return ret;
+}
+
 
 COMPAT_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header);
 
@@ -903,11 +973,35 @@ COMPAT_CTDB4_TEST(struct ctdb_reply_dmaster, ctdb_reply_dmaster, CTDB_REPLY_DMAS
 COMPAT_CTDB5_TEST(struct ctdb_req_control, ctdb_req_control, CTDB_REQ_CONTROL);
 COMPAT_CTDB6_TEST(struct ctdb_reply_control, ctdb_reply_control, CTDB_REPLY_CONTROL);
 
+COMPAT_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message, CTDB_REQ_MESSAGE);
+
 #define NUM_CONTROLS   151
 
 int main(int argc, char *argv[])
 {
        uint32_t opcode;
+       uint64_t test_srvid[] = {
+               CTDB_SRVID_BANNING,
+               CTDB_SRVID_ELECTION,
+               CTDB_SRVID_RECONFIGURE,
+               CTDB_SRVID_RELEASE_IP,
+               CTDB_SRVID_TAKE_IP,
+               CTDB_SRVID_SET_NODE_FLAGS,
+               CTDB_SRVID_RECD_UPDATE_IP,
+               CTDB_SRVID_VACUUM_FETCH,
+               CTDB_SRVID_DETACH_DATABASE,
+               CTDB_SRVID_MEM_DUMP,
+               CTDB_SRVID_GETLOG,
+               CTDB_SRVID_CLEARLOG,
+               CTDB_SRVID_PUSH_NODE_FLAGS,
+               CTDB_SRVID_RELOAD_NODES,
+               CTDB_SRVID_TAKEOVER_RUN,
+               CTDB_SRVID_REBALANCE_NODE,
+               CTDB_SRVID_DISABLE_TAKEOVER_RUNS,
+               CTDB_SRVID_DISABLE_RECOVERIES,
+               CTDB_SRVID_DISABLE_IP_CHECK,
+       };
+       int i;
 
        if (argc == 2) {
                int seed = atoi(argv[1]);
@@ -929,5 +1023,9 @@ int main(int argc, char *argv[])
                COMPAT_TEST_FUNC(ctdb_reply_control)(opcode);
        }
 
+       for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
+               COMPAT_TEST_FUNC(ctdb_req_message)(test_srvid[i]);
+       }
+
        return 0;
 }
index 34b14230c0cc8017e77d8b4ea0bf773e8e458d60..31fe5c794e12b52696ca63b54fafda6ec38c3e0a 100644 (file)
@@ -300,6 +300,8 @@ PROTOCOL_CTDB6_TEST(struct ctdb_reply_control, ctdb_reply_control,
                        CTDB_REPLY_CONTROL);
 
 PROTOCOL_CTDB3_TEST(union ctdb_message_data, ctdb_message_data);
+PROTOCOL_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message,
+                       CTDB_REQ_MESSAGE);
 
 static void test_ctdb_req_message_data(void)
 {
@@ -396,6 +398,9 @@ int main(int argc, char *argv[])
        for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
                TEST_FUNC(ctdb_message_data)(test_srvid[i]);
        }
+       for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
+               TEST_FUNC(ctdb_req_message)(test_srvid[i]);
+       }
        test_ctdb_req_message_data();
 
        return 0;