1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

ctdb-protocol: Fix marshalling for ctdb_g_lock_list

Signed-off-by: Amitay Isaacs <amitay@gmail.com>
Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
Amitay Isaacs 2017-07-13 15:27:17 +10:00 committed by Martin Schwenke
parent 0d5cc74a91
commit 3f5f61b903
6 changed files with 117 additions and 36 deletions

View File

@ -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) {

View File

@ -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 */

View File

@ -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;
}

View File

@ -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]);

View File

@ -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;
}

View File

@ -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)
{