ctdb-protocol: Fix marshalling for ctdb_node_map
authorAmitay Isaacs <amitay@gmail.com>
Thu, 6 Jul 2017 04:25:58 +0000 (14:25 +1000)
committerMartin Schwenke <martins@samba.org>
Wed, 30 Aug 2017 12:59:24 +0000 (14:59 +0200)
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
ctdb/protocol/protocol_control.c
ctdb/protocol/protocol_private.h
ctdb/protocol/protocol_types.c
ctdb/tests/src/protocol_types_compat_test.c
ctdb/tests/src/protocol_types_test.c

index 3970b4726975cf1dee9a775377b5dc6c7c75aaa8..98549f3a90bf3f89704c878e06baedd8ef29f026 100644 (file)
@@ -1504,7 +1504,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd,
                break;
 
        case CTDB_CONTROL_GET_NODEMAP:
-               ctdb_node_map_push(cd->data.nodemap, buf);
+               ctdb_node_map_push(cd->data.nodemap, buf, &np);
                break;
 
        case CTDB_CONTROL_GET_RECLOCK_FILE:
@@ -1554,7 +1554,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd,
                break;
 
        case CTDB_CONTROL_GET_NODES_FILE:
-               ctdb_node_map_push(cd->data.nodemap, buf);
+               ctdb_node_map_push(cd->data.nodemap, buf, &np);
                break;
 
        case CTDB_CONTROL_DB_PULL:
@@ -1682,7 +1682,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_GET_NODEMAP:
                ret = ctdb_node_map_pull(buf, buflen, mem_ctx,
-                                        &cd->data.nodemap);
+                                        &cd->data.nodemap, &np);
                break;
 
        case CTDB_CONTROL_GET_RECLOCK_FILE:
@@ -1741,7 +1741,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_GET_NODES_FILE:
                ret = ctdb_node_map_pull(buf, buflen, mem_ctx,
-                                        &cd->data.nodemap);
+                                        &cd->data.nodemap, &np);
                break;
 
        case CTDB_CONTROL_DB_PULL:
index ac67b9c1bee8bc326145ba2ce259c0b88939300d..0d0355db9c1a895f50b0fa327cee66376ae4ae52 100644 (file)
@@ -249,10 +249,10 @@ void ctdb_node_and_flags_push(struct ctdb_node_and_flags *in, uint8_t *buf,
 int ctdb_node_and_flags_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
                             struct ctdb_node_and_flags **out, size_t *npull);
 
-size_t ctdb_node_map_len(struct ctdb_node_map *nodemap);
-void ctdb_node_map_push(struct ctdb_node_map *nodemap, uint8_t *buf);
+size_t ctdb_node_map_len(struct ctdb_node_map *in);
+void ctdb_node_map_push(struct ctdb_node_map *in, uint8_t *buf, size_t *npush);
 int ctdb_node_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                      struct ctdb_node_map **out);
+                      struct ctdb_node_map **out, size_t *npull);
 
 size_t ctdb_script_len(struct ctdb_script *script);
 void ctdb_script_push(struct ctdb_script *script, uint8_t *buf);
index 818d805d6d8438e52d5a0f96d228935127eab414..c98e0d922c840b4c3cee85535125a571644a87be 100644 (file)
@@ -3610,84 +3610,83 @@ int ctdb_node_and_flags_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
        return ret;
 }
 
-struct ctdb_node_map_wire {
-       uint32_t num;
-       struct ctdb_node_and_flags node[1];
-};
-
-size_t ctdb_node_map_len(struct ctdb_node_map *nodemap)
+size_t ctdb_node_map_len(struct ctdb_node_map *in)
 {
-       return sizeof(uint32_t) +
-              nodemap->num * sizeof(struct ctdb_node_and_flags);
+       size_t len;
+
+       len = ctdb_uint32_len(&in->num);
+       if (in->num > 0) {
+               len += in->num * ctdb_node_and_flags_len(&in->node[0]);
+       }
+
+       return len;
 }
 
-void ctdb_node_map_push(struct ctdb_node_map *nodemap, uint8_t *buf)
+void ctdb_node_map_push(struct ctdb_node_map *in, uint8_t *buf, size_t *npush)
 {
-       struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
-       size_t offset, np;
-       int i;
+       size_t offset = 0, np;
+       uint32_t i;
 
-       wire->num = nodemap->num;
+       ctdb_uint32_push(&in->num, buf+offset, &np);
+       offset += np;
 
-       offset = offsetof(struct ctdb_node_map_wire, node);
-       for (i=0; i<nodemap->num; i++) {
-               ctdb_node_and_flags_push(&nodemap->node[i], &buf[offset], &np);
+       for (i=0; i<in->num; i++) {
+               ctdb_node_and_flags_push(&in->node[i], buf+offset, &np);
                offset += np;
        }
+
+       *npush = offset;
 }
 
 int ctdb_node_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                      struct ctdb_node_map **out)
+                      struct ctdb_node_map **out, size_t *npull)
 {
-       struct ctdb_node_map *nodemap;
-       struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
-       size_t offset, np;
-       int i;
-       bool ret;
+       struct ctdb_node_map *val;
+       size_t offset = 0, np;
+       uint32_t i;
+       int ret;
 
-       if (buflen < sizeof(uint32_t)) {
-               return EMSGSIZE;
-       }
-       if (wire->num > buflen / sizeof(struct ctdb_node_and_flags)) {
-               return EMSGSIZE;
-       }
-       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_node_and_flags) <
-           sizeof(uint32_t)) {
-               return EMSGSIZE;
+       val = talloc(mem_ctx, struct ctdb_node_map);
+       if (val == NULL) {
+               return ENOMEM;
        }
-       if (buflen < sizeof(uint32_t) +
-                    wire->num * sizeof(struct ctdb_node_and_flags)) {
-               return EMSGSIZE;
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
+       if (ret != 0) {
+               goto fail;
        }
+       offset += np;
 
-       nodemap = talloc(mem_ctx, struct ctdb_node_map);
-       if (nodemap == NULL) {
-               return ENOMEM;
+       if (val->num == 0) {
+               val->node = NULL;
+               goto done;
        }
 
-       nodemap->num = wire->num;
-       nodemap->node = talloc_array(nodemap, struct ctdb_node_and_flags,
-                                    wire->num);
-       if (nodemap->node == NULL) {
-               talloc_free(nodemap);
-               return ENOMEM;
+       val->node = talloc_array(val, struct ctdb_node_and_flags, val->num);
+       if (val->node == NULL) {
+               ret = ENOMEM;
+               goto fail;
        }
 
-       offset = offsetof(struct ctdb_node_map_wire, node);
-       for (i=0; i<wire->num; i++) {
-               ret = ctdb_node_and_flags_pull_elems(&buf[offset],
+       for (i=0; i<val->num; i++) {
+               ret = ctdb_node_and_flags_pull_elems(buf+offset,
                                                     buflen-offset,
-                                                    nodemap->node,
-                                                    &nodemap->node[i], &np);
+                                                    val->node, &val->node[i],
+                                                    &np);
                if (ret != 0) {
-                       talloc_free(nodemap);
-                       return ret;
+                       goto fail;
                }
                offset += np;
        }
 
-       *out = nodemap;
+done:
+       *out = val;
+       *npull = offset;
        return 0;
+
+fail:
+       talloc_free(val);
+       return ret;
 }
 
 size_t ctdb_script_len(struct ctdb_script *script)
index 7deedf23639416a6efce157d489936b7bebc0ccc..3454e638b7f0965d7a86c86275e19c9ac2eab57a 100644 (file)
@@ -1351,6 +1351,86 @@ static int ctdb_node_and_flags_pull_old(uint8_t *buf, size_t buflen,
        return ret;
 }
 
+struct ctdb_node_map_wire {
+       uint32_t num;
+       struct ctdb_node_and_flags node[1];
+};
+
+static size_t ctdb_node_map_len_old(struct ctdb_node_map *in)
+{
+       return sizeof(uint32_t) +
+              in->num * sizeof(struct ctdb_node_and_flags);
+}
+
+static void ctdb_node_map_push_old(struct ctdb_node_map *in, uint8_t *buf)
+{
+       struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
+       size_t offset;
+       int i;
+
+       wire->num = in->num;
+
+       offset = offsetof(struct ctdb_node_map_wire, node);
+       for (i=0; i<in->num; i++) {
+               ctdb_node_and_flags_push_old(&in->node[i], &buf[offset]);
+               offset += ctdb_node_and_flags_len_old(&in->node[i]);
+       }
+}
+
+static int ctdb_node_map_pull_old(uint8_t *buf, size_t buflen,
+                                 TALLOC_CTX *mem_ctx,
+                                 struct ctdb_node_map **out)
+{
+       struct ctdb_node_map *val;
+       struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
+       size_t offset;
+       int i;
+       bool ret;
+
+       if (buflen < sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (wire->num > buflen / sizeof(struct ctdb_node_and_flags)) {
+               return EMSGSIZE;
+       }
+       if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_node_and_flags) <
+           sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (buflen < sizeof(uint32_t) +
+                    wire->num * sizeof(struct ctdb_node_and_flags)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_node_map);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       val->num = wire->num;
+       val->node = talloc_array(val, struct ctdb_node_and_flags, wire->num);
+       if (val->node == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       offset = offsetof(struct ctdb_node_map_wire, node);
+       for (i=0; i<wire->num; i++) {
+               ret = ctdb_node_and_flags_pull_elems_old(val->node,
+                                                        &buf[offset],
+                                                        buflen-offset,
+                                                        &val->node[i]);
+               if (ret != 0) {
+                       talloc_free(val);
+                       return ret;
+               }
+               offset += ctdb_node_and_flags_len_old(&val->node[i]);
+       }
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
 COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
@@ -1379,6 +1459,7 @@ COMPAT_TYPE3_TEST(struct ctdb_uptime, ctdb_uptime);
 COMPAT_TYPE3_TEST(struct ctdb_public_ip, ctdb_public_ip);
 COMPAT_TYPE3_TEST(struct ctdb_public_ip_list, ctdb_public_ip_list);
 COMPAT_TYPE3_TEST(struct ctdb_node_and_flags, ctdb_node_and_flags);
+COMPAT_TYPE3_TEST(struct ctdb_node_map, ctdb_node_map);
 
 int main(int argc, char *argv[])
 {
@@ -1412,6 +1493,7 @@ int main(int argc, char *argv[])
        COMPAT_TEST_FUNC(ctdb_public_ip)();
        COMPAT_TEST_FUNC(ctdb_public_ip_list)();
        COMPAT_TEST_FUNC(ctdb_node_and_flags)();
+       COMPAT_TEST_FUNC(ctdb_node_map)();
 
        return 0;
 }
index f009b56f8983d0d3a5848faa2dfce09adc77fdb7..17759181fe547d50cf8a68ae6773c6c545b98d18 100644 (file)
@@ -73,7 +73,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_uptime, ctdb_uptime);
 PROTOCOL_TYPE3_TEST(struct ctdb_public_ip, ctdb_public_ip);
 PROTOCOL_TYPE3_TEST(struct ctdb_public_ip_list, ctdb_public_ip_list);
 PROTOCOL_TYPE3_TEST(struct ctdb_node_and_flags, ctdb_node_and_flags);
-DEFINE_TEST(struct ctdb_node_map, ctdb_node_map);
+PROTOCOL_TYPE3_TEST(struct ctdb_node_map, ctdb_node_map);
 DEFINE_TEST(struct ctdb_script, ctdb_script);
 DEFINE_TEST(struct ctdb_script_list, ctdb_script_list);
 DEFINE_TEST(struct ctdb_ban_state, ctdb_ban_state);