diff options
author | Amitay Isaacs <amitay@gmail.com> | 2017-07-13 15:27:17 +1000 |
---|---|---|
committer | Martin Schwenke <martins@samba.org> | 2017-08-30 14:59:25 +0200 |
commit | 3f5f61b903f950ef46334830406a2bd8dd269300 (patch) | |
tree | 24bf371dbc32d72adbd5937dc659122d9b8aad9c /ctdb | |
parent | 0d5cc74a913a5aad2b71c3d60d2e8d838dfa70d0 (diff) | |
download | samba-3f5f61b903f950ef46334830406a2bd8dd269300.tar.gz |
ctdb-protocol: Fix marshalling for ctdb_g_lock_list
Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
Diffstat (limited to 'ctdb')
-rw-r--r-- | ctdb/client/client_db.c | 12 | ||||
-rw-r--r-- | ctdb/protocol/protocol_api.h | 7 | ||||
-rw-r--r-- | ctdb/protocol/protocol_types.c | 73 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_common.c | 2 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_types_compat_test.c | 57 | ||||
-rw-r--r-- | ctdb/tests/src/protocol_types_test.c | 2 |
6 files changed, 117 insertions, 36 deletions
diff --git a/ctdb/client/client_db.c b/ctdb/client/client_db.c index 037f115be10..e3eaf7dd106 100644 --- a/ctdb/client/client_db.c +++ b/ctdb/client/client_db.c @@ -1699,6 +1699,7 @@ static void ctdb_g_lock_lock_fetched(struct tevent_req *subreq) struct ctdb_g_lock_lock_state *state = tevent_req_data( req, struct ctdb_g_lock_lock_state); TDB_DATA data; + size_t np; int ret = 0; state->h = ctdb_fetch_lock_recv(subreq, NULL, state, &data, &ret); @@ -1716,7 +1717,7 @@ static void ctdb_g_lock_lock_fetched(struct tevent_req *subreq) } ret = ctdb_g_lock_list_pull(data.dptr, data.dsize, state, - &state->lock_list); + &state->lock_list, &np); talloc_free(data.dptr); if (ret != 0) { DEBUG(DEBUG_ERR, ("g_lock_lock: %s invalid lock data\n", @@ -1855,6 +1856,7 @@ static int ctdb_g_lock_lock_update(struct tevent_req *req) struct ctdb_g_lock_lock_state *state = tevent_req_data( req, struct ctdb_g_lock_lock_state); TDB_DATA data; + size_t np; int ret; data.dsize = ctdb_g_lock_list_len(state->lock_list); @@ -1863,7 +1865,7 @@ static int ctdb_g_lock_lock_update(struct tevent_req *req) return ENOMEM; } - ctdb_g_lock_list_push(state->lock_list, data.dptr); + ctdb_g_lock_list_push(state->lock_list, data.dptr, &np); ret = ctdb_store_record(state->h, data); talloc_free(data.dptr); return ret; @@ -1964,6 +1966,7 @@ static void ctdb_g_lock_unlock_fetched(struct tevent_req *subreq) struct ctdb_g_lock_unlock_state *state = tevent_req_data( req, struct ctdb_g_lock_unlock_state); TDB_DATA data; + size_t np; int ret = 0; state->h = ctdb_fetch_lock_recv(subreq, NULL, state, &data, &ret); @@ -1976,7 +1979,7 @@ static void ctdb_g_lock_unlock_fetched(struct tevent_req *subreq) } ret = ctdb_g_lock_list_pull(data.dptr, data.dsize, state, - &state->lock_list); + &state->lock_list, &np); if (ret != 0) { DEBUG(DEBUG_ERR, ("g_lock_unlock: %s invalid lock data\n", (char *)state->key.dptr)); @@ -2027,6 +2030,7 @@ static int ctdb_g_lock_unlock_update(struct tevent_req *req) if (state->lock_list->num != 0) { TDB_DATA data; + size_t np; data.dsize = ctdb_g_lock_list_len(state->lock_list); data.dptr = talloc_size(state, data.dsize); @@ -2034,7 +2038,7 @@ static int ctdb_g_lock_unlock_update(struct tevent_req *req) return ENOMEM; } - ctdb_g_lock_list_push(state->lock_list, data.dptr); + ctdb_g_lock_list_push(state->lock_list, data.dptr, &np); ret = ctdb_store_record(state->h, data); talloc_free(data.dptr); if (ret != 0) { diff --git a/ctdb/protocol/protocol_api.h b/ctdb/protocol/protocol_api.h index 6d25a465306..9e47f2691d9 100644 --- a/ctdb/protocol/protocol_api.h +++ b/ctdb/protocol/protocol_api.h @@ -69,10 +69,11 @@ void ctdb_g_lock_push(struct ctdb_g_lock *in, uint8_t *buf, size_t *npush); int ctdb_g_lock_pull(uint8_t *buf, size_t buflen, struct ctdb_g_lock *out, size_t *npull); -size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *lock_list); -void ctdb_g_lock_list_push(struct ctdb_g_lock_list *lock_list, uint8_t *buf); +size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *in); +void ctdb_g_lock_list_push(struct ctdb_g_lock_list *in, uint8_t *buf, + size_t *npush); int ctdb_g_lock_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, - struct ctdb_g_lock_list **out); + struct ctdb_g_lock_list **out, size_t *npull); /* From protocol/protocol_header.c */ diff --git a/ctdb/protocol/protocol_types.c b/ctdb/protocol/protocol_types.c index 0dde5a75105..3fc00c96335 100644 --- a/ctdb/protocol/protocol_types.c +++ b/ctdb/protocol/protocol_types.c @@ -4986,55 +4986,74 @@ int ctdb_g_lock_pull(uint8_t *buf, size_t buflen, struct ctdb_g_lock *out, return 0; } -size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *lock_list) +size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *in) { - return lock_list->num * sizeof(struct ctdb_g_lock); + size_t len = 0; + + if (in->num > 0) { + len += in->num * ctdb_g_lock_len(&in->lock[0]); + } + + return len; } -void ctdb_g_lock_list_push(struct ctdb_g_lock_list *lock_list, uint8_t *buf) +void ctdb_g_lock_list_push(struct ctdb_g_lock_list *in, uint8_t *buf, + size_t *npush) { size_t offset = 0, np; - int i; + uint32_t i; - for (i=0; i<lock_list->num; i++) { - ctdb_g_lock_push(&lock_list->lock[i], &buf[offset], &np); + for (i=0; i<in->num; i++) { + ctdb_g_lock_push(&in->lock[i], buf+offset, &np); offset += np; } + + *npush = offset; } int ctdb_g_lock_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx, - struct ctdb_g_lock_list **out) + struct ctdb_g_lock_list **out, size_t *npull) { - struct ctdb_g_lock_list *lock_list; - unsigned count; - size_t offset, np; - int ret, i; + struct ctdb_g_lock_list *val; + struct ctdb_g_lock lock = { 0 }; + size_t offset = 0, np; + uint32_t i; + int ret; - lock_list = talloc_zero(mem_ctx, struct ctdb_g_lock_list); - if (lock_list == NULL) { + val = talloc(mem_ctx, struct ctdb_g_lock_list); + if (val == NULL) { return ENOMEM; } - count = buflen / sizeof(struct ctdb_g_lock); - lock_list->lock = talloc_array(lock_list, struct ctdb_g_lock, count); - if (lock_list->lock == NULL) { - talloc_free(lock_list); - return ENOMEM; + if (buflen == 0) { + val->lock = NULL; + val->num = 0; + goto done; } - offset = 0; - for (i=0; i<count; i++) { - ret = ctdb_g_lock_pull(&buf[offset], buflen-offset, - &lock_list->lock[i], &np); + val->num = buflen / ctdb_g_lock_len(&lock); + + val->lock = talloc_array(val, struct ctdb_g_lock, val->num); + if (val->lock == NULL) { + ret = ENOMEM; + goto fail; + } + + for (i=0; i<val->num; i++) { + ret = ctdb_g_lock_pull(buf+offset, buflen-offset, + &val->lock[i], &np); if (ret != 0) { - talloc_free(lock_list); - return ret; + goto fail; } offset += np; } - lock_list->num = count; - - *out = lock_list; +done: + *out = val; + *npull = offset; return 0; + +fail: + talloc_free(val); + return ENOMEM; } diff --git a/ctdb/tests/src/protocol_common.c b/ctdb/tests/src/protocol_common.c index 138a44ee5d1..f5fe3c7901b 100644 --- a/ctdb/tests/src/protocol_common.c +++ b/ctdb/tests/src/protocol_common.c @@ -1366,7 +1366,7 @@ void fill_ctdb_g_lock_list(TALLOC_CTX *mem_ctx, struct ctdb_g_lock_list *p) int i; p->num = rand_int(20) + 1; - p->lock = talloc_array(mem_ctx, struct ctdb_g_lock, p->num); + p->lock = talloc_zero_array(mem_ctx, struct ctdb_g_lock, p->num); assert(p->lock != NULL); for (i=0; i<p->num; i++) { fill_ctdb_g_lock(&p->lock[i]); diff --git a/ctdb/tests/src/protocol_types_compat_test.c b/ctdb/tests/src/protocol_types_compat_test.c index dfeb3562b0f..033a0b31226 100644 --- a/ctdb/tests/src/protocol_types_compat_test.c +++ b/ctdb/tests/src/protocol_types_compat_test.c @@ -2209,6 +2209,60 @@ static int ctdb_g_lock_pull_old(uint8_t *buf, size_t buflen, return 0; } +static size_t ctdb_g_lock_list_len_old(struct ctdb_g_lock_list *in) +{ + return in->num * sizeof(struct ctdb_g_lock); +} + +static void ctdb_g_lock_list_push_old(struct ctdb_g_lock_list *in, + uint8_t *buf) +{ + size_t offset = 0; + int i; + + for (i=0; i<in->num; i++) { + ctdb_g_lock_push_old(&in->lock[i], &buf[offset]); + offset += sizeof(struct ctdb_g_lock); + } +} + +static int ctdb_g_lock_list_pull_old(uint8_t *buf, size_t buflen, + TALLOC_CTX *mem_ctx, + struct ctdb_g_lock_list **out) +{ + struct ctdb_g_lock_list *val; + unsigned count; + size_t offset; + int ret, i; + + val = talloc_zero(mem_ctx, struct ctdb_g_lock_list); + if (val == NULL) { + return ENOMEM; + } + + count = buflen / sizeof(struct ctdb_g_lock); + val->lock = talloc_array(val, struct ctdb_g_lock, count); + if (val->lock == NULL) { + talloc_free(val); + return ENOMEM; + } + + offset = 0; + for (i=0; i<count; i++) { + ret = ctdb_g_lock_pull_old(&buf[offset], buflen-offset, + &val->lock[i]); + if (ret != 0) { + talloc_free(val); + return ret; + } + offset += sizeof(struct ctdb_g_lock); + } + + val->num = count; + + *out = val; + return 0; +} COMPAT_TYPE3_TEST(struct ctdb_statistics, ctdb_statistics); COMPAT_TYPE3_TEST(struct ctdb_vnn_map, ctdb_vnn_map); @@ -2256,6 +2310,8 @@ COMPAT_TYPE3_TEST(struct ctdb_disable_message, ctdb_disable_message); COMPAT_TYPE1_TEST(struct ctdb_server_id, ctdb_server_id); COMPAT_TYPE1_TEST(struct ctdb_g_lock, ctdb_g_lock); +COMPAT_TYPE3_TEST(struct ctdb_g_lock_list, ctdb_g_lock_list); + int main(int argc, char *argv[]) { if (argc == 2) { @@ -2305,6 +2361,7 @@ int main(int argc, char *argv[]) COMPAT_TEST_FUNC(ctdb_disable_message)(); COMPAT_TEST_FUNC(ctdb_server_id)(); COMPAT_TEST_FUNC(ctdb_g_lock)(); + COMPAT_TEST_FUNC(ctdb_g_lock_list)(); return 0; } diff --git a/ctdb/tests/src/protocol_types_test.c b/ctdb/tests/src/protocol_types_test.c index 3a4e0755a50..15ccd49999f 100644 --- a/ctdb/tests/src/protocol_types_test.c +++ b/ctdb/tests/src/protocol_types_test.c @@ -73,7 +73,7 @@ PROTOCOL_TYPE3_TEST(struct ctdb_srvid_message, ctdb_srvid_message); PROTOCOL_TYPE3_TEST(struct ctdb_disable_message, ctdb_disable_message); PROTOCOL_TYPE1_TEST(struct ctdb_server_id, ctdb_server_id); PROTOCOL_TYPE1_TEST(struct ctdb_g_lock, ctdb_g_lock); -DEFINE_TEST(struct ctdb_g_lock_list, ctdb_g_lock_list); +PROTOCOL_TYPE3_TEST(struct ctdb_g_lock_list, ctdb_g_lock_list); static void test_ctdb_rec_buffer_read_write(void) { |