ctdb-protocol: Fix marshalling for ctdb_vnn_map
authorAmitay Isaacs <amitay@gmail.com>
Thu, 29 Jun 2017 09:04:56 +0000 (19:04 +1000)
committerMartin Schwenke <martins@samba.org>
Wed, 30 Aug 2017 12:59:22 +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 5ba54f80e6029da8d16a7d7c320dc22ba232700d..475f578dcdfb8e02e13f2c85fb4972a8a71bac04 100644 (file)
@@ -456,7 +456,7 @@ static void ctdb_req_control_data_push(struct ctdb_req_control_data *cd,
                break;
 
        case CTDB_CONTROL_SETVNNMAP:
-               ctdb_vnn_map_push(cd->data.vnnmap, buf);
+               ctdb_vnn_map_push(cd->data.vnnmap, buf, &np);
                break;
 
        case CTDB_CONTROL_SET_DEBUG:
@@ -739,7 +739,7 @@ static int ctdb_req_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_SETVNNMAP:
                ret = ctdb_vnn_map_pull(buf, buflen, mem_ctx,
-                                       &cd->data.vnnmap);
+                                       &cd->data.vnnmap, &np);
                break;
 
        case CTDB_CONTROL_SET_DEBUG:
@@ -1427,7 +1427,7 @@ static void ctdb_reply_control_data_push(struct ctdb_reply_control_data *cd,
                break;
 
        case CTDB_CONTROL_GETVNNMAP:
-               ctdb_vnn_map_push(cd->data.vnnmap, buf);
+               ctdb_vnn_map_push(cd->data.vnnmap, buf, &np);
                break;
 
        case CTDB_CONTROL_GET_DEBUG:
@@ -1593,7 +1593,7 @@ static int ctdb_reply_control_data_pull(uint8_t *buf, size_t buflen,
 
        case CTDB_CONTROL_GETVNNMAP:
                ret = ctdb_vnn_map_pull(buf, buflen, mem_ctx,
-                                       &cd->data.vnnmap);
+                                       &cd->data.vnnmap, &np);
                break;
 
        case CTDB_CONTROL_GET_DEBUG:
index 8064c9ee91b1d84948a343bae8fb0dd02e742855..0d59a1f5e499b12cecf28a95b039ad21042cf33a 100644 (file)
@@ -117,10 +117,10 @@ void ctdb_statistics_list_push(struct ctdb_statistics_list *stats_list,
 int ctdb_statistics_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
                              struct ctdb_statistics_list **out);
 
-size_t ctdb_vnn_map_len(struct ctdb_vnn_map *vnnmap);
-void ctdb_vnn_map_push(struct ctdb_vnn_map *vnnmap, uint8_t *buf);
+size_t ctdb_vnn_map_len(struct ctdb_vnn_map *in);
+void ctdb_vnn_map_push(struct ctdb_vnn_map *in, uint8_t *buf, size_t *npush);
 int ctdb_vnn_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                     struct ctdb_vnn_map **out);
+                     struct ctdb_vnn_map **out, size_t  *npull);
 
 size_t ctdb_dbid_map_len(struct ctdb_dbid_map *dbmap);
 void ctdb_dbid_map_push(struct ctdb_dbid_map *dbmap, uint8_t *buf);
index 61ef7dde8083fcf9f6ebaa8aa09841d95978304b..e324af12d32e21a51dac00dd30e351ec63f648fa 100644 (file)
@@ -845,64 +845,91 @@ int ctdb_statistics_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
        return 0;
 }
 
-struct ctdb_vnn_map_wire {
-       uint32_t generation;
-       uint32_t size;
-       uint32_t map[1];
-};
-
-size_t ctdb_vnn_map_len(struct ctdb_vnn_map *vnnmap)
+size_t ctdb_vnn_map_len(struct ctdb_vnn_map *in)
 {
-       return offsetof(struct ctdb_vnn_map, map) +
-              vnnmap->size * sizeof(uint32_t);
+       size_t len;
+
+       len = ctdb_uint32_len(&in->generation) + ctdb_uint32_len(&in->size);
+       if (in->size > 0) {
+               len += in->size * ctdb_uint32_len(&in->map[0]);
+       }
+
+       return len;
 }
 
-void ctdb_vnn_map_push(struct ctdb_vnn_map *vnnmap, uint8_t *buf)
+void ctdb_vnn_map_push(struct ctdb_vnn_map *in, uint8_t *buf, size_t *npush)
 {
-       struct ctdb_vnn_map_wire *wire = (struct ctdb_vnn_map_wire *)buf;
+       size_t offset = 0, np;
+       uint32_t i;
+
+       ctdb_uint32_push(&in->generation, buf+offset, &np);
+       offset += np;
+
+       ctdb_uint32_push(&in->size, buf+offset, &np);
+       offset += np;
 
-       memcpy(wire, vnnmap, offsetof(struct ctdb_vnn_map, map));
-       memcpy(wire->map, vnnmap->map, vnnmap->size * sizeof(uint32_t));
+       for (i=0; i<in->size; i++) {
+               ctdb_uint32_push(&in->map[i], buf+offset, &np);
+               offset += np;
+       }
+
+       *npush = offset;
 }
 
 int ctdb_vnn_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
-                     struct ctdb_vnn_map **out)
+                     struct ctdb_vnn_map **out, size_t *npull)
 {
-       struct ctdb_vnn_map *vnnmap;
-       struct ctdb_vnn_map_wire *wire = (struct ctdb_vnn_map_wire *)buf;
+       struct ctdb_vnn_map *val;
+       size_t offset = 0, np;
+       uint32_t i;
+       int ret;
 
-       if (buflen < offsetof(struct ctdb_vnn_map_wire, map)) {
-               return EMSGSIZE;
-       }
-       if (wire->size > buflen / sizeof(uint32_t)) {
-               return EMSGSIZE;
+       val = talloc(mem_ctx, struct ctdb_vnn_map);
+       if (val == NULL) {
+               return ENOMEM;
        }
-       if (offsetof(struct ctdb_vnn_map_wire, map) +
-           wire->size * sizeof(uint32_t) <
-           offsetof(struct ctdb_vnn_map_wire, map)) {
-                   return EMSGSIZE;
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->generation,
+                              &np);
+       if (ret != 0) {
+               goto fail;
        }
-       if (buflen < offsetof(struct ctdb_vnn_map_wire, map) +
-                    wire->size * sizeof(uint32_t)) {
-               return EMSGSIZE;
+       offset += np;
+
+       ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->size, &np);
+       if (ret != 0) {
+               goto fail;
        }
+       offset += np;
 
-       vnnmap = talloc(mem_ctx, struct ctdb_vnn_map);
-       if (vnnmap == NULL) {
-               return ENOMEM;
+       if (val->size == 0) {
+               val->map = NULL;
+               goto done;
        }
 
-       memcpy(vnnmap, wire, offsetof(struct ctdb_vnn_map, map));
+       val->map = talloc_array(val, uint32_t, val->size);
+       if (val->map == NULL) {
+               ret = ENOMEM;
+               goto fail;
+       }
 
-       vnnmap->map = talloc_memdup(vnnmap, wire->map,
-                                   wire->size * sizeof(uint32_t));
-       if (vnnmap->map == NULL) {
-               talloc_free(vnnmap);
-               return ENOMEM;
+       for (i=0; i<val->size; i++) {
+               ret = ctdb_uint32_pull(buf+offset, buflen-offset,
+                                      &val->map[i], &np);
+               if (ret != 0) {
+                       goto fail;
+               }
+               offset += np;
        }
 
-       *out = vnnmap;
+done:
+       *out = val;
+       *npull = offset;
        return 0;
+
+fail:
+       talloc_free(val);
+       return ret;
 }
 
 struct ctdb_dbid_map_wire {
index 555ec1c1485540621db1034512b24831cf96a79f..ef95041719d0c12e9d9f2329939a362e254a9a9c 100644 (file)
@@ -124,8 +124,70 @@ static int ctdb_statistics_pull_old(uint8_t *buf, size_t buflen,
        return 0;
 }
 
+struct ctdb_vnn_map_wire {
+       uint32_t generation;
+       uint32_t size;
+       uint32_t map[1];
+};
+
+static size_t ctdb_vnn_map_len_old(struct ctdb_vnn_map *in)
+{
+       return offsetof(struct ctdb_vnn_map, map) +
+              in->size * sizeof(uint32_t);
+}
+
+static void ctdb_vnn_map_push_old(struct ctdb_vnn_map *in, uint8_t *buf)
+{
+       struct ctdb_vnn_map_wire *wire = (struct ctdb_vnn_map_wire *)buf;
+
+       memcpy(wire, in, offsetof(struct ctdb_vnn_map, map));
+       memcpy(wire->map, in->map, in->size * sizeof(uint32_t));
+}
+
+static int ctdb_vnn_map_pull_old(uint8_t *buf, size_t buflen,
+                                TALLOC_CTX *mem_ctx,
+                                struct ctdb_vnn_map **out)
+{
+       struct ctdb_vnn_map *val;
+       struct ctdb_vnn_map_wire *wire = (struct ctdb_vnn_map_wire *)buf;
+
+       if (buflen < offsetof(struct ctdb_vnn_map_wire, map)) {
+               return EMSGSIZE;
+       }
+       if (wire->size > buflen / sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+       if (offsetof(struct ctdb_vnn_map_wire, map) +
+           wire->size * sizeof(uint32_t) <
+           offsetof(struct ctdb_vnn_map_wire, map)) {
+                   return EMSGSIZE;
+       }
+       if (buflen < offsetof(struct ctdb_vnn_map_wire, map) +
+                    wire->size * sizeof(uint32_t)) {
+               return EMSGSIZE;
+       }
+
+       val = talloc(mem_ctx, struct ctdb_vnn_map);
+       if (val == NULL) {
+               return ENOMEM;
+       }
+
+       memcpy(val, wire, offsetof(struct ctdb_vnn_map, map));
+
+       val->map = talloc_memdup(val, wire->map,
+                                wire->size * sizeof(uint32_t));
+       if (val->map == NULL) {
+               talloc_free(val);
+               return ENOMEM;
+       }
+
+       *out = val;
+       return 0;
+}
+
 
 COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
+COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
 
 int main(int argc, char *argv[])
 {
@@ -135,6 +197,7 @@ int main(int argc, char *argv[])
        }
 
        COMPAT_TEST_FUNC(ctdb_statistics)();
+       COMPAT_TEST_FUNC(ctdb_vnn_map)();
 
        return 0;
 }
index e291ff36f5c9d8d8abe4af354dd4fa005a86a612..79f5d40e85411c835aed588ba025815f3396f10b 100644 (file)
@@ -64,7 +64,7 @@ static void test_ctdb_g_lock(void)
 }
 
 PROTOCOL_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics);
-DEFINE_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
+PROTOCOL_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map);
 DEFINE_TEST(struct ctdb_dbid_map, ctdb_dbid_map);
 DEFINE_TEST(struct ctdb_pulldb, ctdb_pulldb);
 DEFINE_TEST(struct ctdb_pulldb_ext, ctdb_pulldb_ext);