summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
authorAmitay Isaacs <amitay@gmail.com>2017-07-13 15:27:17 +1000
committerMartin Schwenke <martins@samba.org>2017-08-30 14:59:25 +0200
commit3f5f61b903f950ef46334830406a2bd8dd269300 (patch)
tree24bf371dbc32d72adbd5937dc659122d9b8aad9c /ctdb
parent0d5cc74a913a5aad2b71c3d60d2e8d838dfa70d0 (diff)
downloadsamba-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.c12
-rw-r--r--ctdb/protocol/protocol_api.h7
-rw-r--r--ctdb/protocol/protocol_types.c73
-rw-r--r--ctdb/tests/src/protocol_common.c2
-rw-r--r--ctdb/tests/src/protocol_types_compat_test.c57
-rw-r--r--ctdb/tests/src/protocol_types_test.c2
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)
{