mirror of
https://github.com/samba-team/samba.git
synced 2025-01-12 09:18:10 +03:00
ctdb-protocol: Fix marshalling for ctdb_req_message
Signed-off-by: Amitay Isaacs <amitay@gmail.com> Reviewed-by: Martin Schwenke <martin@meltin.net>
This commit is contained in:
parent
504c486b7d
commit
582ebec08e
@ -316,31 +316,40 @@ static int ctdb_message_data_pull(uint8_t *buf, size_t buflen,
|
||||
size_t ctdb_req_message_len(struct ctdb_req_header *h,
|
||||
struct ctdb_req_message *c)
|
||||
{
|
||||
return offsetof(struct ctdb_req_message_wire, data) +
|
||||
ctdb_message_data_len(&c->data, c->srvid);
|
||||
uint32_t u32 = ctdb_message_data_len(&c->data, c->srvid);
|
||||
|
||||
return ctdb_req_header_len(h) +
|
||||
ctdb_uint64_len(&c->srvid) +
|
||||
ctdb_uint32_len(&u32) + u32;
|
||||
}
|
||||
|
||||
int ctdb_req_message_push(struct ctdb_req_header *h,
|
||||
struct ctdb_req_message *message,
|
||||
struct ctdb_req_message *c,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
struct ctdb_req_message_wire *wire =
|
||||
(struct ctdb_req_message_wire *)buf;
|
||||
size_t length, np;
|
||||
size_t offset = 0, np;
|
||||
size_t length;
|
||||
uint32_t u32;
|
||||
|
||||
length = ctdb_req_message_len(h, message);
|
||||
length = ctdb_req_message_len(h, c);
|
||||
if (*buflen < length) {
|
||||
*buflen = length;
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
h->length = *buflen;
|
||||
ctdb_req_header_push(h, (uint8_t *)&wire->hdr, &np);
|
||||
ctdb_req_header_push(h, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
wire->srvid = message->srvid;
|
||||
wire->datalen = ctdb_message_data_len(&message->data, message->srvid);
|
||||
ctdb_message_data_push(&message->data, message->srvid, wire->data,
|
||||
&np);
|
||||
ctdb_uint64_push(&c->srvid, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
u32 = ctdb_message_data_len(&c->data, c->srvid);
|
||||
ctdb_uint32_push(&u32, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
ctdb_message_data_push(&c->data, c->srvid, buf+offset, &np);
|
||||
offset += np;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -350,36 +359,44 @@ int ctdb_req_message_pull(uint8_t *buf, size_t buflen,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_message *c)
|
||||
{
|
||||
struct ctdb_req_message_wire *wire =
|
||||
(struct ctdb_req_message_wire *)buf;
|
||||
size_t length, np;
|
||||
struct ctdb_req_header header;
|
||||
size_t offset = 0, np;
|
||||
uint32_t u32;
|
||||
int ret;
|
||||
|
||||
length = offsetof(struct ctdb_req_message_wire, data);
|
||||
if (buflen < length) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (wire->datalen > buflen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (length + wire->datalen < length) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (buflen < length + wire->datalen) {
|
||||
return EMSGSIZE;
|
||||
ret = ctdb_req_header_pull(buf+offset, buflen-offset, &header, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
if (h != NULL) {
|
||||
ret = ctdb_req_header_pull((uint8_t *)&wire->hdr, buflen, h,
|
||||
&np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
*h = header;
|
||||
}
|
||||
|
||||
c->srvid = wire->srvid;
|
||||
ret = ctdb_message_data_pull(wire->data, wire->datalen, wire->srvid,
|
||||
ret = ctdb_uint64_pull(buf+offset, buflen-offset, &c->srvid, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
if (buflen-offset < u32) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
ret = ctdb_message_data_pull(buf+offset, u32, c->srvid,
|
||||
mem_ctx, &c->data, &np);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
offset += np;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -52,6 +52,7 @@ output=$(
|
||||
generate_control_output "ctdb_req_control"
|
||||
generate_control_output "ctdb_reply_control"
|
||||
generate_message_output "ctdb_message_data"
|
||||
generate_message_output "ctdb_req_message"
|
||||
echo "ctdb_req_message"
|
||||
)
|
||||
|
||||
|
@ -1921,6 +1921,20 @@ void verify_ctdb_message_data(union ctdb_message_data *md,
|
||||
}
|
||||
}
|
||||
|
||||
void fill_ctdb_req_message(TALLOC_CTX *mem_ctx, struct ctdb_req_message *c,
|
||||
uint64_t srvid)
|
||||
{
|
||||
c->srvid = srvid;
|
||||
fill_ctdb_message_data(mem_ctx, &c->data, srvid);
|
||||
}
|
||||
|
||||
void verify_ctdb_req_message(struct ctdb_req_message *c,
|
||||
struct ctdb_req_message *c2)
|
||||
{
|
||||
assert(c->srvid == c2->srvid);
|
||||
verify_ctdb_message_data(&c->data, &c2->data, c->srvid);
|
||||
}
|
||||
|
||||
void fill_ctdb_req_message_data(TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_message_data *c)
|
||||
{
|
||||
|
@ -79,6 +79,11 @@ void fill_ctdb_message_data(TALLOC_CTX *mem_ctx, union ctdb_message_data *md,
|
||||
void verify_ctdb_message_data(union ctdb_message_data *md,
|
||||
union ctdb_message_data *md2, uint64_t srvid);
|
||||
|
||||
void fill_ctdb_req_message(TALLOC_CTX *mem_ctx, struct ctdb_req_message *c,
|
||||
uint64_t srvid);
|
||||
void verify_ctdb_req_message(struct ctdb_req_message *c,
|
||||
struct ctdb_req_message *c2);
|
||||
|
||||
void fill_ctdb_req_message_data(TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_message_data *c);
|
||||
void verify_ctdb_req_message_data(struct ctdb_req_message_data *c,
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "protocol/protocol_header.c"
|
||||
#include "protocol/protocol_call.c"
|
||||
#include "protocol/protocol_control.c"
|
||||
#include "protocol/protocol_message.c"
|
||||
|
||||
#include "tests/src/protocol_common.h"
|
||||
#include "tests/src/protocol_common_ctdb.h"
|
||||
@ -891,6 +892,75 @@ static int ctdb_reply_control_pull_old(uint8_t *buf, size_t buflen,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static size_t ctdb_req_message_len_old(struct ctdb_req_header *h,
|
||||
struct ctdb_req_message *c)
|
||||
{
|
||||
return offsetof(struct ctdb_req_message_wire, data) +
|
||||
ctdb_message_data_len(&c->data, c->srvid);
|
||||
}
|
||||
|
||||
static int ctdb_req_message_push_old(struct ctdb_req_header *h,
|
||||
struct ctdb_req_message *c,
|
||||
uint8_t *buf, size_t *buflen)
|
||||
{
|
||||
struct ctdb_req_message_wire *wire =
|
||||
(struct ctdb_req_message_wire *)buf;
|
||||
size_t length, np;
|
||||
|
||||
length = ctdb_req_message_len_old(h, c);
|
||||
if (*buflen < length) {
|
||||
*buflen = length;
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
h->length = *buflen;
|
||||
ctdb_req_header_push_old(h, (uint8_t *)&wire->hdr);
|
||||
|
||||
wire->srvid = c->srvid;
|
||||
wire->datalen = ctdb_message_data_len(&c->data, c->srvid);
|
||||
ctdb_message_data_push(&c->data, c->srvid, wire->data, &np);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ctdb_req_message_pull_old(uint8_t *buf, size_t buflen,
|
||||
struct ctdb_req_header *h,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
struct ctdb_req_message *c)
|
||||
{
|
||||
struct ctdb_req_message_wire *wire =
|
||||
(struct ctdb_req_message_wire *)buf;
|
||||
size_t length, np;
|
||||
int ret;
|
||||
|
||||
length = offsetof(struct ctdb_req_message_wire, data);
|
||||
if (buflen < length) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (wire->datalen > buflen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (length + wire->datalen < length) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
if (buflen < length + wire->datalen) {
|
||||
return EMSGSIZE;
|
||||
}
|
||||
|
||||
if (h != NULL) {
|
||||
ret = ctdb_req_header_pull_old((uint8_t *)&wire->hdr, buflen,
|
||||
h);
|
||||
if (ret != 0) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
c->srvid = wire->srvid;
|
||||
ret = ctdb_message_data_pull(wire->data, wire->datalen, wire->srvid,
|
||||
mem_ctx, &c->data, &np);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
COMPAT_CTDB1_TEST(struct ctdb_req_header, ctdb_req_header);
|
||||
|
||||
@ -903,11 +973,35 @@ COMPAT_CTDB4_TEST(struct ctdb_reply_dmaster, ctdb_reply_dmaster, CTDB_REPLY_DMAS
|
||||
COMPAT_CTDB5_TEST(struct ctdb_req_control, ctdb_req_control, CTDB_REQ_CONTROL);
|
||||
COMPAT_CTDB6_TEST(struct ctdb_reply_control, ctdb_reply_control, CTDB_REPLY_CONTROL);
|
||||
|
||||
COMPAT_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message, CTDB_REQ_MESSAGE);
|
||||
|
||||
#define NUM_CONTROLS 151
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
uint32_t opcode;
|
||||
uint64_t test_srvid[] = {
|
||||
CTDB_SRVID_BANNING,
|
||||
CTDB_SRVID_ELECTION,
|
||||
CTDB_SRVID_RECONFIGURE,
|
||||
CTDB_SRVID_RELEASE_IP,
|
||||
CTDB_SRVID_TAKE_IP,
|
||||
CTDB_SRVID_SET_NODE_FLAGS,
|
||||
CTDB_SRVID_RECD_UPDATE_IP,
|
||||
CTDB_SRVID_VACUUM_FETCH,
|
||||
CTDB_SRVID_DETACH_DATABASE,
|
||||
CTDB_SRVID_MEM_DUMP,
|
||||
CTDB_SRVID_GETLOG,
|
||||
CTDB_SRVID_CLEARLOG,
|
||||
CTDB_SRVID_PUSH_NODE_FLAGS,
|
||||
CTDB_SRVID_RELOAD_NODES,
|
||||
CTDB_SRVID_TAKEOVER_RUN,
|
||||
CTDB_SRVID_REBALANCE_NODE,
|
||||
CTDB_SRVID_DISABLE_TAKEOVER_RUNS,
|
||||
CTDB_SRVID_DISABLE_RECOVERIES,
|
||||
CTDB_SRVID_DISABLE_IP_CHECK,
|
||||
};
|
||||
int i;
|
||||
|
||||
if (argc == 2) {
|
||||
int seed = atoi(argv[1]);
|
||||
@ -929,5 +1023,9 @@ int main(int argc, char *argv[])
|
||||
COMPAT_TEST_FUNC(ctdb_reply_control)(opcode);
|
||||
}
|
||||
|
||||
for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
|
||||
COMPAT_TEST_FUNC(ctdb_req_message)(test_srvid[i]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -300,6 +300,8 @@ PROTOCOL_CTDB6_TEST(struct ctdb_reply_control, ctdb_reply_control,
|
||||
CTDB_REPLY_CONTROL);
|
||||
|
||||
PROTOCOL_CTDB3_TEST(union ctdb_message_data, ctdb_message_data);
|
||||
PROTOCOL_CTDB7_TEST(struct ctdb_req_message, ctdb_req_message,
|
||||
CTDB_REQ_MESSAGE);
|
||||
|
||||
static void test_ctdb_req_message_data(void)
|
||||
{
|
||||
@ -396,6 +398,9 @@ int main(int argc, char *argv[])
|
||||
for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
|
||||
TEST_FUNC(ctdb_message_data)(test_srvid[i]);
|
||||
}
|
||||
for (i=0; i<ARRAY_SIZE(test_srvid); i++) {
|
||||
TEST_FUNC(ctdb_req_message)(test_srvid[i]);
|
||||
}
|
||||
test_ctdb_req_message_data();
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user