2 ctdb protocol backward compatibility test
4 Copyright (C) Amitay Isaacs 2017
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/filesys.h"
25 #include "protocol/protocol_basic.c"
26 #include "protocol/protocol_types.c"
27 #include "protocol/protocol_header.c"
28 #include "protocol/protocol_call.c"
29 #include "protocol/protocol_control.c"
30 #include "protocol/protocol_message.c"
31 #include "protocol/protocol_keepalive.c"
32 #include "protocol/protocol_tunnel.c"
34 #include "tests/src/protocol_common.h"
35 #include "tests/src/protocol_common_ctdb.h"
37 #define COMPAT_TEST_FUNC(NAME) test_ ##NAME## _compat
38 #define OLD_LEN_FUNC(NAME) NAME## _len_old
39 #define OLD_PUSH_FUNC(NAME) NAME## _push_old
40 #define OLD_PULL_FUNC(NAME) NAME## _pull_old
42 #define COMPAT_CTDB1_TEST(TYPE, NAME) \
43 static void COMPAT_TEST_FUNC(NAME)(void) \
45 TALLOC_CTX *mem_ctx; \
46 uint8_t *buf1, *buf2; \
47 TYPE p = { 0 }, p1, p2; \
48 size_t buflen1, buflen2, np = 0; \
51 mem_ctx = talloc_new(NULL); \
52 assert(mem_ctx != NULL); \
53 FILL_FUNC(NAME)(&p); \
54 buflen1 = LEN_FUNC(NAME)(&p); \
55 buflen2 = OLD_LEN_FUNC(NAME)(&p); \
56 assert(buflen1 == buflen2); \
57 buf1 = talloc_zero_size(mem_ctx, buflen1); \
58 assert(buf1 != NULL); \
59 buf2 = talloc_zero_size(mem_ctx, buflen2); \
60 assert(buf2 != NULL); \
61 PUSH_FUNC(NAME)(&p, buf1, &np); \
62 OLD_PUSH_FUNC(NAME)(&p, buf2); \
63 assert(memcmp(buf1, buf2, buflen1) == 0); \
64 ret = PULL_FUNC(NAME)(buf1, buflen1, &p1, &np); \
66 ret = OLD_PULL_FUNC(NAME)(buf2, buflen2, &p2); \
68 VERIFY_FUNC(NAME)(&p1, &p2); \
69 talloc_free(mem_ctx); \
72 #define COMPAT_CTDB4_TEST(TYPE, NAME, OPER) \
73 static void COMPAT_TEST_FUNC(NAME)(void) \
75 TALLOC_CTX *mem_ctx; \
76 uint8_t *buf1, *buf2; \
77 struct ctdb_req_header h, h1, h2; \
78 TYPE p = { 0 }, p1, p2; \
79 size_t buflen1, buflen2; \
82 mem_ctx = talloc_new(NULL); \
83 assert(mem_ctx != NULL); \
84 fill_ctdb_req_header(&h); \
85 FILL_FUNC(NAME)(mem_ctx, &p); \
86 buflen1 = LEN_FUNC(NAME)(&h, &p); \
87 buflen2 = OLD_LEN_FUNC(NAME)(&h, &p); \
88 assert(buflen1 == buflen2); \
89 buf1 = talloc_zero_size(mem_ctx, buflen1); \
90 assert(buf1 != NULL); \
91 buf2 = talloc_zero_size(mem_ctx, buflen2); \
92 assert(buf2 != NULL); \
93 ret = PUSH_FUNC(NAME)(&h, &p, buf1, &buflen1); \
95 ret = OLD_PUSH_FUNC(NAME)(&h, &p, buf2, &buflen2); \
97 assert(memcmp(buf1, buf2, buflen1) == 0); \
98 ret = PULL_FUNC(NAME)(buf1, buflen1, &h1, mem_ctx, &p1); \
100 ret = OLD_PULL_FUNC(NAME)(buf2, buflen2, &h2, mem_ctx, &p2); \
102 verify_ctdb_req_header(&h1, &h2); \
103 VERIFY_FUNC(NAME)(&p1, &p2); \
104 talloc_free(mem_ctx); \
107 #define COMPAT_CTDB5_TEST(TYPE, NAME, OPER) \
108 static void COMPAT_TEST_FUNC(NAME)(uint32_t opcode) \
110 TALLOC_CTX *mem_ctx; \
111 uint8_t *buf1, *buf2; \
112 struct ctdb_req_header h, h1, h2; \
113 TYPE p = { 0 }, p1, p2; \
114 size_t buflen1, buflen2; \
117 mem_ctx = talloc_new(NULL); \
118 assert(mem_ctx != NULL); \
119 fill_ctdb_req_header(&h); \
120 FILL_FUNC(NAME)(mem_ctx, &p, opcode); \
121 buflen1 = LEN_FUNC(NAME)(&h, &p); \
122 buflen2 = OLD_LEN_FUNC(NAME)(&h, &p); \
123 assert(buflen1 == buflen2); \
124 buf1 = talloc_zero_size(mem_ctx, buflen1); \
125 assert(buf1 != NULL); \
126 buf2 = talloc_zero_size(mem_ctx, buflen2); \
127 assert(buf2 != NULL); \
128 ret = PUSH_FUNC(NAME)(&h, &p, buf1, &buflen1); \
130 ret = OLD_PUSH_FUNC(NAME)(&h, &p, buf2, &buflen2); \
132 assert(memcmp(buf1, buf2, buflen1) == 0); \
133 ret = PULL_FUNC(NAME)(buf1, buflen1, &h1, mem_ctx, &p1); \
135 ret = OLD_PULL_FUNC(NAME)(buf2, buflen2, &h2, mem_ctx, &p2); \
137 verify_ctdb_req_header(&h1, &h2); \
138 VERIFY_FUNC(NAME)(&p1, &p2); \
139 talloc_free(mem_ctx); \
142 #define COMPAT_CTDB6_TEST(TYPE, NAME, OPER) \
143 static void COMPAT_TEST_FUNC(NAME)(uint32_t opcode) \
145 TALLOC_CTX *mem_ctx; \
146 uint8_t *buf1, *buf2; \
147 struct ctdb_req_header h, h1, h2; \
148 TYPE p = { 0 }, p1, p2; \
149 size_t buflen1, buflen2; \
152 mem_ctx = talloc_new(NULL); \
153 assert(mem_ctx != NULL); \
154 fill_ctdb_req_header(&h); \
155 FILL_FUNC(NAME)(mem_ctx, &p, opcode); \
156 buflen1 = LEN_FUNC(NAME)(&h, &p); \
157 buflen2 = OLD_LEN_FUNC(NAME)(&h, &p); \
158 assert(buflen1 == buflen2); \
159 buf1 = talloc_zero_size(mem_ctx, buflen1); \
160 assert(buf1 != NULL); \
161 buf2 = talloc_zero_size(mem_ctx, buflen2); \
162 assert(buf2 != NULL); \
163 ret = PUSH_FUNC(NAME)(&h, &p, buf1, &buflen1); \
165 ret = OLD_PUSH_FUNC(NAME)(&h, &p, buf2, &buflen2); \
167 assert(memcmp(buf1, buf2, buflen1) == 0); \
168 ret = PULL_FUNC(NAME)(buf1, buflen1, opcode, &h1, mem_ctx, &p1); \
170 ret = OLD_PULL_FUNC(NAME)(buf2, buflen2, opcode, &h2, mem_ctx, &p2); \
172 verify_ctdb_req_header(&h1, &h2); \
173 VERIFY_FUNC(NAME)(&p1, &p2); \
174 talloc_free(mem_ctx); \
177 #define COMPAT_CTDB7_TEST(TYPE, NAME, OPER) \
178 static void COMPAT_TEST_FUNC(NAME)(uint64_t srvid) \
180 TALLOC_CTX *mem_ctx; \
181 uint8_t *buf1, *buf2; \
182 struct ctdb_req_header h, h1, h2; \
183 TYPE p = { 0 }, p1, p2; \
184 size_t buflen1, buflen2; \
187 mem_ctx = talloc_new(NULL); \
188 assert(mem_ctx != NULL); \
189 fill_ctdb_req_header(&h); \
190 FILL_FUNC(NAME)(mem_ctx, &p, srvid); \
191 buflen1 = LEN_FUNC(NAME)(&h, &p); \
192 buflen2 = OLD_LEN_FUNC(NAME)(&h, &p); \
193 assert(buflen1 == buflen2); \
194 buf1 = talloc_zero_size(mem_ctx, buflen1); \
195 assert(buf1 != NULL); \
196 buf2 = talloc_zero_size(mem_ctx, buflen2); \
197 assert(buf2 != NULL); \
198 ret = PUSH_FUNC(NAME)(&h, &p, buf1, &buflen1); \
200 ret = OLD_PUSH_FUNC(NAME)(&h, &p, buf2, &buflen2); \
202 assert(memcmp(buf1, buf2, buflen1) == 0); \
203 ret = PULL_FUNC(NAME)(buf1, buflen1, &h1, mem_ctx, &p1); \
205 ret = OLD_PULL_FUNC(NAME)(buf2, buflen2, &h2, mem_ctx, &p2); \
207 verify_ctdb_req_header(&h1, &h2); \
208 VERIFY_FUNC(NAME)(&p1, &p2); \
209 talloc_free(mem_ctx); \
213 static size_t ctdb_req_header_len_old(struct ctdb_req_header
*in
)
215 return sizeof(struct ctdb_req_header
);
218 static void ctdb_req_header_push_old(struct ctdb_req_header
*in
, uint8_t *buf
)
220 memcpy(buf
, in
, sizeof(struct ctdb_req_header
));
223 static int ctdb_req_header_pull_old(uint8_t *buf
, size_t buflen
,
224 struct ctdb_req_header
*out
)
226 if (buflen
< sizeof(struct ctdb_req_header
)) {
230 memcpy(out
, buf
, sizeof(struct ctdb_req_header
));
234 struct ctdb_req_call_wire
{
235 struct ctdb_req_header hdr
;
241 uint32_t calldatalen
;
242 uint8_t data
[1]; /* key[] followed by calldata[] */
245 static size_t ctdb_req_call_len_old(struct ctdb_req_header
*h
,
246 struct ctdb_req_call
*c
)
248 return offsetof(struct ctdb_req_call_wire
, data
) +
249 ctdb_tdb_data_len(&c
->key
) +
250 ctdb_tdb_data_len(&c
->calldata
);
253 static int ctdb_req_call_push_old(struct ctdb_req_header
*h
,
254 struct ctdb_req_call
*c
,
255 uint8_t *buf
, size_t *buflen
)
257 struct ctdb_req_call_wire
*wire
=
258 (struct ctdb_req_call_wire
*)buf
;
261 if (c
->key
.dsize
== 0) {
265 length
= ctdb_req_call_len_old(h
, c
);
266 if (*buflen
< length
) {
272 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
274 wire
->flags
= c
->flags
;
275 wire
->db_id
= c
->db_id
;
276 wire
->callid
= c
->callid
;
277 wire
->hopcount
= c
->hopcount
;
278 wire
->keylen
= ctdb_tdb_data_len(&c
->key
);
279 wire
->calldatalen
= ctdb_tdb_data_len(&c
->calldata
);
280 ctdb_tdb_data_push(&c
->key
, wire
->data
, &np
);
281 ctdb_tdb_data_push(&c
->calldata
, wire
->data
+ wire
->keylen
, &np
);
286 static int ctdb_req_call_pull_old(uint8_t *buf
, size_t buflen
,
287 struct ctdb_req_header
*h
,
289 struct ctdb_req_call
*c
)
291 struct ctdb_req_call_wire
*wire
=
292 (struct ctdb_req_call_wire
*)buf
;
296 length
= offsetof(struct ctdb_req_call_wire
, data
);
297 if (buflen
< length
) {
300 if (wire
->keylen
> buflen
|| wire
->calldatalen
> buflen
) {
303 if (length
+ wire
->keylen
< length
) {
306 if (length
+ wire
->keylen
+ wire
->calldatalen
< length
) {
309 if (buflen
< length
+ wire
->keylen
+ wire
->calldatalen
) {
314 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
321 c
->flags
= wire
->flags
;
322 c
->db_id
= wire
->db_id
;
323 c
->callid
= wire
->callid
;
324 c
->hopcount
= wire
->hopcount
;
326 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->keylen
, mem_ctx
, &c
->key
,
332 ret
= ctdb_tdb_data_pull(wire
->data
+ wire
->keylen
, wire
->calldatalen
,
333 mem_ctx
, &c
->calldata
, &np
);
341 struct ctdb_reply_call_wire
{
342 struct ctdb_req_header hdr
;
348 static size_t ctdb_reply_call_len_old(struct ctdb_req_header
*h
,
349 struct ctdb_reply_call
*c
)
351 return offsetof(struct ctdb_reply_call_wire
, data
) +
352 ctdb_tdb_data_len(&c
->data
);
355 static int ctdb_reply_call_push_old(struct ctdb_req_header
*h
,
356 struct ctdb_reply_call
*c
,
357 uint8_t *buf
, size_t *buflen
)
359 struct ctdb_reply_call_wire
*wire
=
360 (struct ctdb_reply_call_wire
*)buf
;
363 length
= ctdb_reply_call_len_old(h
, c
);
364 if (*buflen
< length
) {
370 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
372 wire
->status
= c
->status
;
373 wire
->datalen
= ctdb_tdb_data_len(&c
->data
);
374 ctdb_tdb_data_push(&c
->data
, wire
->data
, &np
);
379 static int ctdb_reply_call_pull_old(uint8_t *buf
, size_t buflen
,
380 struct ctdb_req_header
*h
,
382 struct ctdb_reply_call
*c
)
384 struct ctdb_reply_call_wire
*wire
=
385 (struct ctdb_reply_call_wire
*)buf
;
389 length
= offsetof(struct ctdb_reply_call_wire
, data
);
390 if (buflen
< length
) {
393 if (wire
->datalen
> buflen
) {
396 if (length
+ wire
->datalen
< length
) {
399 if (buflen
< length
+ wire
->datalen
) {
404 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
411 c
->status
= wire
->status
;
413 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->datalen
, mem_ctx
, &c
->data
,
422 struct ctdb_reply_error_wire
{
423 struct ctdb_req_header hdr
;
429 static size_t ctdb_reply_error_len_old(struct ctdb_req_header
*h
,
430 struct ctdb_reply_error
*c
)
432 return offsetof(struct ctdb_reply_error_wire
, msg
) +
433 ctdb_tdb_data_len(&c
->msg
);
436 static int ctdb_reply_error_push_old(struct ctdb_req_header
*h
,
437 struct ctdb_reply_error
*c
,
438 uint8_t *buf
, size_t *buflen
)
440 struct ctdb_reply_error_wire
*wire
=
441 (struct ctdb_reply_error_wire
*)buf
;
444 length
= ctdb_reply_error_len_old(h
, c
);
445 if (*buflen
< length
) {
451 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
453 wire
->status
= c
->status
;
454 wire
->msglen
= ctdb_tdb_data_len(&c
->msg
);
455 ctdb_tdb_data_push(&c
->msg
, wire
->msg
, &np
);
460 static int ctdb_reply_error_pull_old(uint8_t *buf
, size_t buflen
,
461 struct ctdb_req_header
*h
,
463 struct ctdb_reply_error
*c
)
465 struct ctdb_reply_error_wire
*wire
=
466 (struct ctdb_reply_error_wire
*)buf
;
470 length
= offsetof(struct ctdb_reply_error_wire
, msg
);
471 if (buflen
< length
) {
474 if (wire
->msglen
> buflen
) {
477 if (length
+ wire
->msglen
< length
) {
480 if (buflen
< length
+ wire
->msglen
) {
485 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
492 c
->status
= wire
->status
;
494 ret
= ctdb_tdb_data_pull(wire
->msg
, wire
->msglen
, mem_ctx
, &c
->msg
,
503 struct ctdb_req_dmaster_wire
{
504 struct ctdb_req_header hdr
;
513 static size_t ctdb_req_dmaster_len_old(struct ctdb_req_header
*h
,
514 struct ctdb_req_dmaster
*c
)
516 return offsetof(struct ctdb_req_dmaster_wire
, data
) +
517 ctdb_tdb_data_len(&c
->key
) + ctdb_tdb_data_len(&c
->data
);
520 static int ctdb_req_dmaster_push_old(struct ctdb_req_header
*h
,
521 struct ctdb_req_dmaster
*c
,
522 uint8_t *buf
, size_t *buflen
)
524 struct ctdb_req_dmaster_wire
*wire
=
525 (struct ctdb_req_dmaster_wire
*)buf
;
528 length
= ctdb_req_dmaster_len_old(h
, c
);
529 if (*buflen
< length
) {
535 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
537 wire
->db_id
= c
->db_id
;
539 wire
->dmaster
= c
->dmaster
;
540 wire
->keylen
= ctdb_tdb_data_len(&c
->key
);
541 wire
->datalen
= ctdb_tdb_data_len(&c
->data
);
542 ctdb_tdb_data_push(&c
->key
, wire
->data
, &np
);
543 ctdb_tdb_data_push(&c
->data
, wire
->data
+ wire
->keylen
, &np
);
548 static int ctdb_req_dmaster_pull_old(uint8_t *buf
, size_t buflen
,
549 struct ctdb_req_header
*h
,
551 struct ctdb_req_dmaster
*c
)
553 struct ctdb_req_dmaster_wire
*wire
=
554 (struct ctdb_req_dmaster_wire
*)buf
;
558 length
= offsetof(struct ctdb_req_dmaster_wire
, data
);
559 if (buflen
< length
) {
562 if (wire
->keylen
> buflen
|| wire
->datalen
> buflen
) {
565 if (length
+ wire
->keylen
< length
) {
568 if (length
+ wire
->keylen
+ wire
->datalen
< length
) {
571 if (buflen
< length
+ wire
->keylen
+ wire
->datalen
) {
576 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
583 c
->db_id
= wire
->db_id
;
585 c
->dmaster
= wire
->dmaster
;
587 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->keylen
, mem_ctx
, &c
->key
,
593 ret
= ctdb_tdb_data_pull(wire
->data
+ wire
->keylen
, wire
->datalen
,
594 mem_ctx
, &c
->data
, &np
);
602 struct ctdb_reply_dmaster_wire
{
603 struct ctdb_req_header hdr
;
611 static size_t ctdb_reply_dmaster_len_old(struct ctdb_req_header
*h
,
612 struct ctdb_reply_dmaster
*c
)
614 return offsetof(struct ctdb_reply_dmaster_wire
, data
) +
615 ctdb_tdb_data_len(&c
->key
) + ctdb_tdb_data_len(&c
->data
);
618 static int ctdb_reply_dmaster_push_old(struct ctdb_req_header
*h
,
619 struct ctdb_reply_dmaster
*c
,
620 uint8_t *buf
, size_t *buflen
)
622 struct ctdb_reply_dmaster_wire
*wire
=
623 (struct ctdb_reply_dmaster_wire
*)buf
;
626 length
= ctdb_reply_dmaster_len_old(h
, c
);
627 if (*buflen
< length
) {
633 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
635 wire
->db_id
= c
->db_id
;
637 wire
->keylen
= ctdb_tdb_data_len(&c
->key
);
638 wire
->datalen
= ctdb_tdb_data_len(&c
->data
);
639 ctdb_tdb_data_push(&c
->key
, wire
->data
, &np
);
640 ctdb_tdb_data_push(&c
->data
, wire
->data
+ wire
->keylen
, &np
);
645 static int ctdb_reply_dmaster_pull_old(uint8_t *buf
, size_t buflen
,
646 struct ctdb_req_header
*h
,
648 struct ctdb_reply_dmaster
*c
)
650 struct ctdb_reply_dmaster_wire
*wire
=
651 (struct ctdb_reply_dmaster_wire
*)buf
;
655 length
= offsetof(struct ctdb_reply_dmaster_wire
, data
);
656 if (buflen
< length
) {
659 if (wire
->keylen
> buflen
|| wire
->datalen
> buflen
) {
662 if (length
+ wire
->keylen
< length
) {
665 if (length
+ wire
->keylen
+ wire
->datalen
< length
) {
668 if (buflen
< length
+ wire
->keylen
+ wire
->datalen
) {
673 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
680 c
->db_id
= wire
->db_id
;
683 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->keylen
, mem_ctx
, &c
->key
,
689 ret
= ctdb_tdb_data_pull(wire
->data
+ wire
->keylen
, wire
->datalen
,
690 mem_ctx
, &c
->data
, &np
);
698 struct ctdb_req_control_wire
{
699 struct ctdb_req_header hdr
;
709 static size_t ctdb_req_control_len_old(struct ctdb_req_header
*h
,
710 struct ctdb_req_control
*c
)
712 return offsetof(struct ctdb_req_control_wire
, data
) +
713 ctdb_req_control_data_len(&c
->rdata
);
716 static int ctdb_req_control_push_old(struct ctdb_req_header
*h
,
717 struct ctdb_req_control
*c
,
718 uint8_t *buf
, size_t *buflen
)
720 struct ctdb_req_control_wire
*wire
=
721 (struct ctdb_req_control_wire
*)buf
;
724 length
= ctdb_req_control_len_old(h
, c
);
725 if (*buflen
< length
) {
731 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
733 wire
->opcode
= c
->opcode
;
735 wire
->srvid
= c
->srvid
;
736 wire
->client_id
= c
->client_id
;
737 wire
->flags
= c
->flags
;
739 wire
->datalen
= ctdb_req_control_data_len(&c
->rdata
);
740 ctdb_req_control_data_push(&c
->rdata
, wire
->data
, &np
);
745 static int ctdb_req_control_pull_old(uint8_t *buf
, size_t buflen
,
746 struct ctdb_req_header
*h
,
748 struct ctdb_req_control
*c
)
750 struct ctdb_req_control_wire
*wire
=
751 (struct ctdb_req_control_wire
*)buf
;
755 length
= offsetof(struct ctdb_req_control_wire
, data
);
756 if (buflen
< length
) {
759 if (wire
->datalen
> buflen
) {
762 if (length
+ wire
->datalen
< length
) {
765 if (buflen
< length
+ wire
->datalen
) {
770 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
777 c
->opcode
= wire
->opcode
;
779 c
->srvid
= wire
->srvid
;
780 c
->client_id
= wire
->client_id
;
781 c
->flags
= wire
->flags
;
783 ret
= ctdb_req_control_data_pull(wire
->data
, wire
->datalen
,
784 c
->opcode
, mem_ctx
, &c
->rdata
, &np
);
792 struct ctdb_reply_control_wire
{
793 struct ctdb_req_header hdr
;
800 static size_t ctdb_reply_control_len_old(struct ctdb_req_header
*h
,
801 struct ctdb_reply_control
*c
)
803 return offsetof(struct ctdb_reply_control_wire
, data
) +
805 ctdb_reply_control_data_len(&c
->rdata
) :
806 ctdb_string_len(&c
->errmsg
));
809 static int ctdb_reply_control_push_old(struct ctdb_req_header
*h
,
810 struct ctdb_reply_control
*c
,
811 uint8_t *buf
, size_t *buflen
)
813 struct ctdb_reply_control_wire
*wire
=
814 (struct ctdb_reply_control_wire
*)buf
;
817 length
= ctdb_reply_control_len_old(h
, c
);
818 if (*buflen
< length
) {
824 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
826 wire
->status
= c
->status
;
828 if (c
->status
== 0) {
829 wire
->datalen
= ctdb_reply_control_data_len(&c
->rdata
);
831 ctdb_reply_control_data_push(&c
->rdata
, wire
->data
, &np
);
834 wire
->errorlen
= ctdb_string_len(&c
->errmsg
);
835 ctdb_string_push(&c
->errmsg
, wire
->data
+ wire
->datalen
, &np
);
841 static int ctdb_reply_control_pull_old(uint8_t *buf
, size_t buflen
,
843 struct ctdb_req_header
*h
,
845 struct ctdb_reply_control
*c
)
847 struct ctdb_reply_control_wire
*wire
=
848 (struct ctdb_reply_control_wire
*)buf
;
852 length
= offsetof(struct ctdb_reply_control_wire
, data
);
853 if (buflen
< length
) {
856 if (wire
->datalen
> buflen
|| wire
->errorlen
> buflen
) {
859 if (length
+ wire
->datalen
< length
) {
862 if (length
+ wire
->datalen
+ wire
->errorlen
< length
) {
865 if (buflen
< length
+ wire
->datalen
+ wire
->errorlen
) {
870 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
877 c
->status
= wire
->status
;
879 if (c
->status
!= -1) {
880 ret
= ctdb_reply_control_data_pull(wire
->data
, wire
->datalen
,
888 ret
= ctdb_string_pull(wire
->data
+ wire
->datalen
, wire
->errorlen
,
889 mem_ctx
, &c
->errmsg
, &np
);
897 struct ctdb_req_message_wire
{
898 struct ctdb_req_header hdr
;
904 static size_t ctdb_req_message_len_old(struct ctdb_req_header
*h
,
905 struct ctdb_req_message
*c
)
907 return offsetof(struct ctdb_req_message_wire
, data
) +
908 ctdb_message_data_len(&c
->data
, c
->srvid
);
911 static int ctdb_req_message_push_old(struct ctdb_req_header
*h
,
912 struct ctdb_req_message
*c
,
913 uint8_t *buf
, size_t *buflen
)
915 struct ctdb_req_message_wire
*wire
=
916 (struct ctdb_req_message_wire
*)buf
;
919 length
= ctdb_req_message_len_old(h
, c
);
920 if (*buflen
< length
) {
926 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
928 wire
->srvid
= c
->srvid
;
929 wire
->datalen
= ctdb_message_data_len(&c
->data
, c
->srvid
);
930 ctdb_message_data_push(&c
->data
, c
->srvid
, wire
->data
, &np
);
935 static int ctdb_req_message_pull_old(uint8_t *buf
, size_t buflen
,
936 struct ctdb_req_header
*h
,
938 struct ctdb_req_message
*c
)
940 struct ctdb_req_message_wire
*wire
=
941 (struct ctdb_req_message_wire
*)buf
;
945 length
= offsetof(struct ctdb_req_message_wire
, data
);
946 if (buflen
< length
) {
949 if (wire
->datalen
> buflen
) {
952 if (length
+ wire
->datalen
< length
) {
955 if (buflen
< length
+ wire
->datalen
) {
960 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
967 c
->srvid
= wire
->srvid
;
968 ret
= ctdb_message_data_pull(wire
->data
, wire
->datalen
, wire
->srvid
,
969 mem_ctx
, &c
->data
, &np
);
973 static size_t ctdb_req_message_data_len_old(struct ctdb_req_header
*h
,
974 struct ctdb_req_message_data
*c
)
976 return offsetof(struct ctdb_req_message_wire
, data
) +
977 ctdb_tdb_data_len(&c
->data
);
980 static int ctdb_req_message_data_push_old(struct ctdb_req_header
*h
,
981 struct ctdb_req_message_data
*c
,
982 uint8_t *buf
, size_t *buflen
)
984 struct ctdb_req_message_wire
*wire
=
985 (struct ctdb_req_message_wire
*)buf
;
988 length
= ctdb_req_message_data_len_old(h
, c
);
989 if (*buflen
< length
) {
995 ctdb_req_header_push(h
, (uint8_t *)&wire
->hdr
, &np
);
997 wire
->srvid
= c
->srvid
;
998 wire
->datalen
= ctdb_tdb_data_len(&c
->data
);
999 ctdb_tdb_data_push(&c
->data
, wire
->data
, &np
);
1004 static int ctdb_req_message_data_pull_old(uint8_t *buf
, size_t buflen
,
1005 struct ctdb_req_header
*h
,
1006 TALLOC_CTX
*mem_ctx
,
1007 struct ctdb_req_message_data
*c
)
1009 struct ctdb_req_message_wire
*wire
=
1010 (struct ctdb_req_message_wire
*)buf
;
1014 length
= offsetof(struct ctdb_req_message_wire
, data
);
1015 if (buflen
< length
) {
1018 if (wire
->datalen
> buflen
) {
1021 if (length
+ wire
->datalen
< length
) {
1024 if (buflen
< length
+ wire
->datalen
) {
1029 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
1036 c
->srvid
= wire
->srvid
;
1038 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->datalen
,
1039 mem_ctx
, &c
->data
, &np
);
1047 struct ctdb_req_keepalive_wire
{
1048 struct ctdb_req_header hdr
;
1053 static size_t ctdb_req_keepalive_len_old(struct ctdb_req_header
*h
,
1054 struct ctdb_req_keepalive
*c
)
1056 return sizeof(struct ctdb_req_keepalive_wire
);
1059 static int ctdb_req_keepalive_push_old(struct ctdb_req_header
*h
,
1060 struct ctdb_req_keepalive
*c
,
1061 uint8_t *buf
, size_t *buflen
)
1063 struct ctdb_req_keepalive_wire
*wire
=
1064 (struct ctdb_req_keepalive_wire
*)buf
;
1067 length
= ctdb_req_keepalive_len_old(h
, c
);
1068 if (*buflen
< length
) {
1073 h
->length
= *buflen
;
1074 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
1076 wire
->version
= c
->version
;
1077 wire
->uptime
= c
->uptime
;
1082 static int ctdb_req_keepalive_pull_old(uint8_t *buf
, size_t buflen
,
1083 struct ctdb_req_header
*h
,
1084 TALLOC_CTX
*mem_ctx
,
1085 struct ctdb_req_keepalive
*c
)
1087 struct ctdb_req_keepalive_wire
*wire
=
1088 (struct ctdb_req_keepalive_wire
*)buf
;
1092 length
= sizeof(struct ctdb_req_keepalive_wire
);
1093 if (buflen
< length
) {
1098 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
1105 c
->version
= wire
->version
;
1106 c
->uptime
= wire
->uptime
;
1111 struct ctdb_req_tunnel_wire
{
1112 struct ctdb_req_header hdr
;
1119 static size_t ctdb_req_tunnel_len_old(struct ctdb_req_header
*h
,
1120 struct ctdb_req_tunnel
*c
)
1122 return offsetof(struct ctdb_req_tunnel_wire
, data
) +
1123 ctdb_tdb_data_len(&c
->data
);
1126 static int ctdb_req_tunnel_push_old(struct ctdb_req_header
*h
,
1127 struct ctdb_req_tunnel
*c
,
1128 uint8_t *buf
, size_t *buflen
)
1130 struct ctdb_req_tunnel_wire
*wire
=
1131 (struct ctdb_req_tunnel_wire
*)buf
;
1134 length
= ctdb_req_tunnel_len_old(h
, c
);
1135 if (*buflen
< length
) {
1140 h
->length
= *buflen
;
1141 ctdb_req_header_push_old(h
, (uint8_t *)&wire
->hdr
);
1143 wire
->tunnel_id
= c
->tunnel_id
;
1144 wire
->flags
= c
->flags
;
1145 wire
->datalen
= ctdb_tdb_data_len(&c
->data
);
1146 ctdb_tdb_data_push(&c
->data
, wire
->data
, &np
);
1151 static int ctdb_req_tunnel_pull_old(uint8_t *buf
, size_t buflen
,
1152 struct ctdb_req_header
*h
,
1153 TALLOC_CTX
*mem_ctx
,
1154 struct ctdb_req_tunnel
*c
)
1156 struct ctdb_req_tunnel_wire
*wire
=
1157 (struct ctdb_req_tunnel_wire
*)buf
;
1161 length
= offsetof(struct ctdb_req_tunnel_wire
, data
);
1162 if (buflen
< length
) {
1165 if (wire
->datalen
> buflen
) {
1168 if (length
+ wire
->datalen
< length
) {
1171 if (buflen
< length
+ wire
->datalen
) {
1176 ret
= ctdb_req_header_pull_old((uint8_t *)&wire
->hdr
, buflen
,
1183 c
->tunnel_id
= wire
->tunnel_id
;
1184 c
->flags
= wire
->flags
;
1186 ret
= ctdb_tdb_data_pull(wire
->data
, wire
->datalen
, mem_ctx
, &c
->data
,
1196 COMPAT_CTDB1_TEST(struct ctdb_req_header
, ctdb_req_header
);
1198 COMPAT_CTDB4_TEST(struct ctdb_req_call
, ctdb_req_call
, CTDB_REQ_CALL
);
1199 COMPAT_CTDB4_TEST(struct ctdb_reply_call
, ctdb_reply_call
, CTDB_REPLY_CALL
);
1200 COMPAT_CTDB4_TEST(struct ctdb_reply_error
, ctdb_reply_error
, CTDB_REPLY_ERROR
);
1201 COMPAT_CTDB4_TEST(struct ctdb_req_dmaster
, ctdb_req_dmaster
, CTDB_REQ_DMASTER
);
1202 COMPAT_CTDB4_TEST(struct ctdb_reply_dmaster
, ctdb_reply_dmaster
, CTDB_REPLY_DMASTER
);
1204 COMPAT_CTDB5_TEST(struct ctdb_req_control
, ctdb_req_control
, CTDB_REQ_CONTROL
);
1205 COMPAT_CTDB6_TEST(struct ctdb_reply_control
, ctdb_reply_control
, CTDB_REPLY_CONTROL
);
1207 COMPAT_CTDB7_TEST(struct ctdb_req_message
, ctdb_req_message
, CTDB_REQ_MESSAGE
);
1208 COMPAT_CTDB4_TEST(struct ctdb_req_message_data
, ctdb_req_message_data
, CTDB_REQ_MESSAGE
);
1210 COMPAT_CTDB4_TEST(struct ctdb_req_keepalive
, ctdb_req_keepalive
, CTDB_REQ_KEEPALIVE
);
1211 COMPAT_CTDB4_TEST(struct ctdb_req_tunnel
, ctdb_req_tunnel
, CTDB_REQ_TUNNEL
);
1213 #define NUM_CONTROLS 151
1215 static void protocol_ctdb_compat_test(void)
1218 uint64_t test_srvid
[] = {
1220 CTDB_SRVID_ELECTION
,
1222 CTDB_SRVID_RECONFIGURE
,
1223 CTDB_SRVID_RELEASE_IP
,
1225 CTDB_SRVID_SET_NODE_FLAGS
,
1226 CTDB_SRVID_RECD_UPDATE_IP
,
1227 CTDB_SRVID_VACUUM_FETCH
,
1228 CTDB_SRVID_DETACH_DATABASE
,
1229 CTDB_SRVID_MEM_DUMP
,
1231 CTDB_SRVID_CLEARLOG
,
1232 CTDB_SRVID_PUSH_NODE_FLAGS
,
1233 CTDB_SRVID_RELOAD_NODES
,
1234 CTDB_SRVID_TAKEOVER_RUN
,
1235 CTDB_SRVID_REBALANCE_NODE
,
1236 CTDB_SRVID_DISABLE_TAKEOVER_RUNS
,
1237 CTDB_SRVID_DISABLE_RECOVERIES
,
1238 CTDB_SRVID_DISABLE_IP_CHECK
,
1242 COMPAT_TEST_FUNC(ctdb_req_header
)();
1244 COMPAT_TEST_FUNC(ctdb_req_call
)();
1245 COMPAT_TEST_FUNC(ctdb_reply_call
)();
1246 COMPAT_TEST_FUNC(ctdb_reply_error
)();
1247 COMPAT_TEST_FUNC(ctdb_req_dmaster
)();
1248 COMPAT_TEST_FUNC(ctdb_reply_dmaster
)();
1250 for (opcode
=0; opcode
<NUM_CONTROLS
; opcode
++) {
1251 COMPAT_TEST_FUNC(ctdb_req_control
)(opcode
);
1253 for (opcode
=0; opcode
<NUM_CONTROLS
; opcode
++) {
1254 COMPAT_TEST_FUNC(ctdb_reply_control
)(opcode
);
1257 for (i
=0; i
<ARRAY_SIZE(test_srvid
); i
++) {
1258 COMPAT_TEST_FUNC(ctdb_req_message
)(test_srvid
[i
]);
1260 COMPAT_TEST_FUNC(ctdb_req_message_data
)();
1262 COMPAT_TEST_FUNC(ctdb_req_keepalive
)();
1263 COMPAT_TEST_FUNC(ctdb_req_tunnel
)();
1266 int main(int argc
, const char *argv
[])
1268 protocol_test_iterate(argc
, argv
, protocol_ctdb_compat_test
);