vfs_ceph_new: handle case of readlinkat with empty name string
[Samba.git] / ctdb / protocol / protocol_types.c
blob0eb1923207e9a78f0f1e5f0b39bab43598d948cf
1 /*
2 CTDB protocol marshalling
4 Copyright (C) Amitay Isaacs 2015-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/>.
20 #include "replace.h"
21 #include "system/network.h"
23 #include <talloc.h>
24 #include <tdb.h>
26 #include "protocol.h"
27 #include "protocol_private.h"
28 #include "protocol_api.h"
30 size_t ctdb_tdb_data_len(TDB_DATA *in)
32 return in->dsize > UINT32_MAX ? UINT32_MAX : in->dsize;
35 void ctdb_tdb_data_push(TDB_DATA *in, uint8_t *buf, size_t *npush)
37 size_t len = ctdb_tdb_data_len(in);
39 if (len > 0) {
40 memcpy(buf, in->dptr, len);
43 *npush = len;
46 int ctdb_tdb_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
47 TDB_DATA *out, size_t *npull)
49 TDB_DATA val;
51 if (buflen > UINT32_MAX) {
52 return EMSGSIZE;
55 val.dsize = buflen;
56 if (val.dsize > 0) {
57 val.dptr = talloc_memdup(mem_ctx, buf, buflen);
58 if (val.dptr == NULL) {
59 return ENOMEM;
61 } else {
62 val.dptr = NULL;
65 *out = val;
66 *npull = buflen;
67 return 0;
70 size_t ctdb_tdb_datan_len(TDB_DATA *in)
72 uint32_t u32 = ctdb_tdb_data_len(in);
74 return ctdb_uint32_len(&u32) + u32;
77 void ctdb_tdb_datan_push(TDB_DATA *in, uint8_t *buf, size_t *npush)
79 size_t offset = 0, np;
80 uint32_t u32 = ctdb_tdb_data_len(in);
82 ctdb_uint32_push(&u32, buf+offset, &np);
83 offset += np;
85 ctdb_tdb_data_push(in, buf+offset, &np);
86 offset += np;
88 *npush = offset;
91 int ctdb_tdb_datan_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
92 TDB_DATA *out, size_t *npull)
94 size_t offset = 0, np;
95 uint32_t u32;
96 int ret;
98 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
99 if (ret != 0) {
100 return ret;
102 offset += np;
104 if (buflen-offset < u32) {
105 return EMSGSIZE;
108 ret = ctdb_tdb_data_pull(buf+offset, u32, mem_ctx, out, &np);
109 if (ret != 0) {
110 return ret;
112 offset += np;
114 *npull = offset;
115 return 0;
118 size_t ctdb_latency_counter_len(struct ctdb_latency_counter *in)
120 return ctdb_int32_len(&in->num) +
121 ctdb_padding_len(4) +
122 ctdb_double_len(&in->min) +
123 ctdb_double_len(&in->max) +
124 ctdb_double_len(&in->total);
127 void ctdb_latency_counter_push(struct ctdb_latency_counter *in, uint8_t *buf,
128 size_t *npush)
130 size_t offset = 0, np;
132 ctdb_int32_push(&in->num, buf+offset, &np);
133 offset += np;
135 ctdb_padding_push(4, buf+offset, &np);
136 offset += np;
138 ctdb_double_push(&in->min, buf+offset, &np);
139 offset += np;
141 ctdb_double_push(&in->max, buf+offset, &np);
142 offset += np;
144 ctdb_double_push(&in->total, buf+offset, &np);
145 offset += np;
147 *npush = offset;
150 int ctdb_latency_counter_pull(uint8_t *buf, size_t buflen,
151 struct ctdb_latency_counter *out, size_t *npull)
153 size_t offset = 0, np;
154 int ret;
156 ret = ctdb_int32_pull(buf+offset, buflen-offset, &out->num, &np);
157 if (ret != 0) {
158 return ret;
160 offset += np;
162 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
163 if (ret != 0) {
164 return ret;
166 offset += np;
168 ret = ctdb_double_pull(buf+offset, buflen-offset, &out->min, &np);
169 if (ret != 0) {
170 return ret;
172 offset += np;
174 ret = ctdb_double_pull(buf+offset, buflen-offset, &out->max, &np);
175 if (ret != 0) {
176 return ret;
178 offset += np;
180 ret = ctdb_double_pull(buf+offset, buflen-offset, &out->total, &np);
181 if (ret != 0) {
182 return ret;
184 offset += np;
186 *npull = offset;
187 return 0;
190 size_t ctdb_statistics_len(struct ctdb_statistics *in)
192 return ctdb_uint32_len(&in->num_clients) +
193 ctdb_uint32_len(&in->frozen) +
194 ctdb_uint32_len(&in->recovering) +
195 ctdb_uint32_len(&in->client_packets_sent) +
196 ctdb_uint32_len(&in->client_packets_recv) +
197 ctdb_uint32_len(&in->node_packets_sent) +
198 ctdb_uint32_len(&in->node_packets_recv) +
199 ctdb_uint32_len(&in->keepalive_packets_sent) +
200 ctdb_uint32_len(&in->keepalive_packets_recv) +
201 ctdb_uint32_len(&in->node.req_call) +
202 ctdb_uint32_len(&in->node.reply_call) +
203 ctdb_uint32_len(&in->node.req_dmaster) +
204 ctdb_uint32_len(&in->node.reply_dmaster) +
205 ctdb_uint32_len(&in->node.reply_error) +
206 ctdb_uint32_len(&in->node.req_message) +
207 ctdb_uint32_len(&in->node.req_control) +
208 ctdb_uint32_len(&in->node.reply_control) +
209 ctdb_uint32_len(&in->node.req_tunnel) +
210 ctdb_uint32_len(&in->client.req_call) +
211 ctdb_uint32_len(&in->client.req_message) +
212 ctdb_uint32_len(&in->client.req_control) +
213 ctdb_uint32_len(&in->client.req_tunnel) +
214 ctdb_uint32_len(&in->timeouts.call) +
215 ctdb_uint32_len(&in->timeouts.control) +
216 ctdb_uint32_len(&in->timeouts.traverse) +
217 ctdb_padding_len(4) +
218 ctdb_latency_counter_len(&in->reclock.ctdbd) +
219 ctdb_latency_counter_len(&in->reclock.recd) +
220 ctdb_uint32_len(&in->locks.num_calls) +
221 ctdb_uint32_len(&in->locks.num_current) +
222 ctdb_uint32_len(&in->locks.num_pending) +
223 ctdb_uint32_len(&in->locks.num_failed) +
224 ctdb_latency_counter_len(&in->locks.latency) +
225 MAX_COUNT_BUCKETS * ctdb_uint32_len(&in->locks.buckets[0]) +
226 ctdb_uint32_len(&in->total_calls) +
227 ctdb_uint32_len(&in->pending_calls) +
228 ctdb_uint32_len(&in->childwrite_calls) +
229 ctdb_uint32_len(&in->pending_childwrite_calls) +
230 ctdb_uint32_len(&in->memory_used) +
231 ctdb_uint32_len(&in->__last_counter) +
232 ctdb_uint32_len(&in->max_hop_count) +
233 MAX_COUNT_BUCKETS *
234 ctdb_uint32_len(&in->hop_count_bucket[0]) +
235 ctdb_padding_len(4) +
236 ctdb_latency_counter_len(&in->call_latency) +
237 ctdb_latency_counter_len(&in->childwrite_latency) +
238 ctdb_uint32_len(&in->num_recoveries) +
239 ctdb_padding_len(4) +
240 ctdb_timeval_len(&in->statistics_start_time) +
241 ctdb_timeval_len(&in->statistics_current_time) +
242 ctdb_uint32_len(&in->total_ro_delegations) +
243 ctdb_uint32_len(&in->total_ro_revokes);
246 void ctdb_statistics_push(struct ctdb_statistics *in, uint8_t *buf,
247 size_t *npush)
249 size_t offset = 0, np;
250 int i;
252 ctdb_uint32_push(&in->num_clients, buf+offset, &np);
253 offset += np;
255 ctdb_uint32_push(&in->frozen, buf+offset, &np);
256 offset += np;
258 ctdb_uint32_push(&in->recovering, buf+offset, &np);
259 offset += np;
261 ctdb_uint32_push(&in->client_packets_sent, buf+offset, &np);
262 offset += np;
264 ctdb_uint32_push(&in->client_packets_recv, buf+offset, &np);
265 offset += np;
267 ctdb_uint32_push(&in->node_packets_sent, buf+offset, &np);
268 offset += np;
270 ctdb_uint32_push(&in->node_packets_recv, buf+offset, &np);
271 offset += np;
273 ctdb_uint32_push(&in->keepalive_packets_sent, buf+offset, &np);
274 offset += np;
276 ctdb_uint32_push(&in->keepalive_packets_recv, buf+offset, &np);
277 offset += np;
279 ctdb_uint32_push(&in->node.req_call, buf+offset, &np);
280 offset += np;
282 ctdb_uint32_push(&in->node.reply_call, buf+offset, &np);
283 offset += np;
285 ctdb_uint32_push(&in->node.req_dmaster, buf+offset, &np);
286 offset += np;
288 ctdb_uint32_push(&in->node.reply_dmaster, buf+offset, &np);
289 offset += np;
291 ctdb_uint32_push(&in->node.reply_error, buf+offset, &np);
292 offset += np;
294 ctdb_uint32_push(&in->node.req_message, buf+offset, &np);
295 offset += np;
297 ctdb_uint32_push(&in->node.req_control, buf+offset, &np);
298 offset += np;
300 ctdb_uint32_push(&in->node.reply_control, buf+offset, &np);
301 offset += np;
303 ctdb_uint32_push(&in->node.req_tunnel, buf+offset, &np);
304 offset += np;
306 ctdb_uint32_push(&in->client.req_call, buf+offset, &np);
307 offset += np;
309 ctdb_uint32_push(&in->client.req_message, buf+offset, &np);
310 offset += np;
312 ctdb_uint32_push(&in->client.req_control, buf+offset, &np);
313 offset += np;
315 ctdb_uint32_push(&in->client.req_tunnel, buf+offset, &np);
316 offset += np;
318 ctdb_uint32_push(&in->timeouts.call, buf+offset, &np);
319 offset += np;
321 ctdb_uint32_push(&in->timeouts.control, buf+offset, &np);
322 offset += np;
324 ctdb_uint32_push(&in->timeouts.traverse, buf+offset, &np);
325 offset += np;
327 ctdb_padding_push(4, buf+offset, &np);
328 offset += np;
330 ctdb_latency_counter_push(&in->reclock.ctdbd, buf+offset, &np);
331 offset += np;
333 ctdb_latency_counter_push(&in->reclock.recd, buf+offset, &np);
334 offset += np;
336 ctdb_uint32_push(&in->locks.num_calls, buf+offset, &np);
337 offset += np;
339 ctdb_uint32_push(&in->locks.num_current, buf+offset, &np);
340 offset += np;
342 ctdb_uint32_push(&in->locks.num_pending, buf+offset, &np);
343 offset += np;
345 ctdb_uint32_push(&in->locks.num_failed, buf+offset, &np);
346 offset += np;
348 ctdb_latency_counter_push(&in->locks.latency, buf+offset, &np);
349 offset += np;
351 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
352 ctdb_uint32_push(&in->locks.buckets[i], buf+offset, &np);
353 offset += np;
356 ctdb_uint32_push(&in->total_calls, buf+offset, &np);
357 offset += np;
359 ctdb_uint32_push(&in->pending_calls, buf+offset, &np);
360 offset += np;
362 ctdb_uint32_push(&in->childwrite_calls, buf+offset, &np);
363 offset += np;
365 ctdb_uint32_push(&in->pending_childwrite_calls, buf+offset, &np);
366 offset += np;
368 ctdb_uint32_push(&in->memory_used, buf+offset, &np);
369 offset += np;
371 ctdb_uint32_push(&in->__last_counter, buf+offset, &np);
372 offset += np;
374 ctdb_uint32_push(&in->max_hop_count, buf+offset, &np);
375 offset += np;
377 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
378 ctdb_uint32_push(&in->hop_count_bucket[i], buf+offset, &np);
379 offset += np;
382 ctdb_padding_push(4, buf+offset, &np);
383 offset += np;
385 ctdb_latency_counter_push(&in->call_latency, buf+offset, &np);
386 offset += np;
388 ctdb_latency_counter_push(&in->childwrite_latency, buf+offset, &np);
389 offset += np;
391 ctdb_uint32_push(&in->num_recoveries, buf+offset, &np);
392 offset += np;
394 ctdb_padding_push(4, buf+offset, &np);
395 offset += np;
397 ctdb_timeval_push(&in->statistics_start_time, buf+offset, &np);
398 offset += np;
400 ctdb_timeval_push(&in->statistics_current_time, buf+offset, &np);
401 offset += np;
403 ctdb_uint32_push(&in->total_ro_delegations, buf+offset, &np);
404 offset += np;
406 ctdb_uint32_push(&in->total_ro_revokes, buf+offset, &np);
407 offset += np;
409 *npush = offset;
412 static int ctdb_statistics_pull_elems(uint8_t *buf, size_t buflen,
413 TALLOC_CTX *mem_ctx,
414 struct ctdb_statistics *out,
415 size_t *npull)
417 size_t offset = 0, np;
418 int ret, i;
420 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->num_clients,
421 &np);
422 if (ret != 0) {
423 return ret;
425 offset += np;
427 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->frozen, &np);
428 if (ret != 0) {
429 return ret;
431 offset += np;
433 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->recovering,
434 &np);
435 if (ret != 0) {
436 return ret;
438 offset += np;
440 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
441 &out->client_packets_sent, &np);
442 if (ret != 0) {
443 return ret;
445 offset += np;
447 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
448 &out->client_packets_recv, &np);
449 if (ret != 0) {
450 return ret;
452 offset += np;
454 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
455 &out->node_packets_sent, &np);
456 if (ret != 0) {
457 return ret;
459 offset += np;
461 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
462 &out->node_packets_recv, &np);
463 if (ret != 0) {
464 return ret;
466 offset += np;
468 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
469 &out->keepalive_packets_sent, &np);
470 if (ret != 0) {
471 return ret;
473 offset += np;
475 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
476 &out->keepalive_packets_recv, &np);
477 if (ret != 0) {
478 return ret;
480 offset += np;
482 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
483 &out->node.req_call, &np);
484 if (ret != 0) {
485 return ret;
487 offset += np;
489 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
490 &out->node.reply_call, &np);
491 if (ret != 0) {
492 return ret;
494 offset += np;
496 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
497 &out->node.req_dmaster, &np);
498 if (ret != 0) {
499 return ret;
501 offset += np;
503 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
504 &out->node.reply_dmaster, &np);
505 if (ret != 0) {
506 return ret;
508 offset += np;
510 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
511 &out->node.reply_error, &np);
512 if (ret != 0) {
513 return ret;
515 offset += np;
517 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
518 &out->node.req_message, &np);
519 if (ret != 0) {
520 return ret;
522 offset += np;
524 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
525 &out->node.req_control, &np);
526 if (ret != 0) {
527 return ret;
529 offset += np;
531 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
532 &out->node.reply_control, &np);
533 if (ret != 0) {
534 return ret;
536 offset += np;
538 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
539 &out->node.req_tunnel, &np);
540 if (ret != 0) {
541 return ret;
543 offset += np;
545 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
546 &out->client.req_call, &np);
547 if (ret != 0) {
548 return ret;
550 offset += np;
552 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
553 &out->client.req_message, &np);
554 if (ret != 0) {
555 return ret;
557 offset += np;
559 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
560 &out->client.req_control, &np);
561 if (ret != 0) {
562 return ret;
564 offset += np;
566 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
567 &out->client.req_tunnel, &np);
568 if (ret != 0) {
569 return ret;
571 offset += np;
573 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
574 &out->timeouts.call, &np);
575 if (ret != 0) {
576 return ret;
578 offset += np;
580 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
581 &out->timeouts.control, &np);
582 if (ret != 0) {
583 return ret;
585 offset += np;
587 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
588 &out->timeouts.traverse, &np);
589 if (ret != 0) {
590 return ret;
592 offset += np;
594 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
595 if (ret != 0) {
596 return ret;
598 offset += np;
600 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
601 &out->reclock.ctdbd, &np);
602 if (ret != 0) {
603 return ret;
605 offset += np;
607 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
608 &out->reclock.recd, &np);
609 if (ret != 0) {
610 return ret;
612 offset += np;
614 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
615 &out->locks.num_calls, &np);
616 if (ret != 0) {
617 return ret;
619 offset += np;
621 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
622 &out->locks.num_current, &np);
623 if (ret != 0) {
624 return ret;
626 offset += np;
628 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
629 &out->locks.num_pending, &np);
630 if (ret != 0) {
631 return ret;
633 offset += np;
635 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
636 &out->locks.num_failed, &np);
637 if (ret != 0) {
638 return ret;
640 offset += np;
642 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
643 &out->locks.latency, &np);
644 if (ret != 0) {
645 return ret;
647 offset += np;
649 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
650 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
651 &out->locks.buckets[i], &np);
652 if (ret != 0) {
653 return ret;
655 offset += np;
658 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
659 &out->total_calls, &np);
660 if (ret != 0) {
661 return ret;
663 offset += np;
665 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
666 &out->pending_calls, &np);
667 if (ret != 0) {
668 return ret;
670 offset += np;
672 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
673 &out->childwrite_calls, &np);
674 if (ret != 0) {
675 return ret;
677 offset += np;
679 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
680 &out->pending_childwrite_calls, &np);
681 if (ret != 0) {
682 return ret;
684 offset += np;
686 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->memory_used,
687 &np);
688 if (ret != 0) {
689 return ret;
691 offset += np;
693 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
694 &out->__last_counter, &np);
695 if (ret != 0) {
696 return ret;
698 offset += np;
700 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
701 &out->max_hop_count, &np);
702 if (ret != 0) {
703 return ret;
705 offset += np;
707 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
708 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
709 &out->hop_count_bucket[i], &np);
710 if (ret != 0) {
711 return ret;
713 offset += np;
716 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
717 if (ret != 0) {
718 return ret;
720 offset += np;
722 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
723 &out->call_latency, &np);
724 if (ret != 0) {
725 return ret;
727 offset += np;
729 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
730 &out->childwrite_latency, &np);
731 if (ret != 0) {
732 return ret;
734 offset += np;
736 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
737 &out->num_recoveries, &np);
738 if (ret != 0) {
739 return ret;
741 offset += np;
743 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
744 if (ret != 0) {
745 return ret;
747 offset += np;
749 ret = ctdb_timeval_pull(buf+offset, buflen-offset,
750 &out->statistics_start_time, &np);
751 if (ret != 0) {
752 return ret;
754 offset += np;
756 ret = ctdb_timeval_pull(buf+offset, buflen-offset,
757 &out->statistics_current_time, &np);
758 if (ret != 0) {
759 return ret;
761 offset += np;
763 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
764 &out->total_ro_delegations, &np);
765 if (ret != 0) {
766 return ret;
768 offset += np;
770 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
771 &out->total_ro_revokes, &np);
772 if (ret != 0) {
773 return ret;
775 offset += np;
777 *npull = offset;
778 return 0;
781 int ctdb_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
782 struct ctdb_statistics **out, size_t *npull)
784 struct ctdb_statistics *val;
785 size_t np;
786 int ret;
788 val = talloc(mem_ctx, struct ctdb_statistics);
789 if (val == NULL) {
790 return ENOMEM;
793 ret = ctdb_statistics_pull_elems(buf, buflen, val, val, &np);
794 if (ret != 0) {
795 talloc_free(val);
796 return ret;
799 *out = val;
800 *npull = np;
801 return 0;
804 size_t ctdb_statistics_list_len(struct ctdb_statistics_list *in)
806 size_t len;
808 len = ctdb_int32_len(&in->num) + ctdb_padding_len(4);
809 if (in->num > 0) {
810 len += in->num * ctdb_statistics_len(&in->stats[0]);
813 return len;
816 void ctdb_statistics_list_push(struct ctdb_statistics_list *in,
817 uint8_t *buf, size_t *npush)
819 size_t offset = 0, np;
820 int i;
822 ctdb_int32_push(&in->num, buf+offset, &np);
823 offset += np;
825 ctdb_padding_push(4, buf+offset, &np);
826 offset += np;
828 for (i=0; i<in->num; i++) {
829 ctdb_statistics_push(&in->stats[i], buf+offset, &np);
830 offset += np;
833 *npush = offset;
836 int ctdb_statistics_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
837 struct ctdb_statistics_list **out,
838 size_t *npull)
840 struct ctdb_statistics_list *val;
841 size_t offset = 0, np;
842 int ret, i;
844 val = talloc(mem_ctx, struct ctdb_statistics_list);
845 if (val == NULL) {
846 return ENOMEM;
849 ret = ctdb_int32_pull(buf+offset, buflen-offset, &val->num, &np);
850 if (ret != 0) {
851 goto fail;
853 offset += np;
855 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
856 if (ret != 0) {
857 goto fail;
859 offset += np;
861 if (val->num == 0) {
862 val->stats = NULL;
863 goto done;
866 val->stats = talloc_array(val, struct ctdb_statistics, val->num);
867 if (val->stats == NULL) {
868 ret = ENOMEM;
869 goto fail;
872 for (i=0; i<val->num; i++) {
873 ret = ctdb_statistics_pull_elems(buf+offset, buflen-offset,
874 val, &val->stats[i], &np);
875 if (ret != 0) {
876 goto fail;
878 offset += np;
881 done:
882 *out = val;
883 *npull = offset;
884 return 0;
886 fail:
887 talloc_free(val);
888 return ret;
891 size_t ctdb_vnn_map_len(struct ctdb_vnn_map *in)
893 size_t len;
895 len = ctdb_uint32_len(&in->generation) + ctdb_uint32_len(&in->size);
896 if (in->size > 0) {
897 len += in->size * ctdb_uint32_len(&in->map[0]);
900 return len;
903 void ctdb_vnn_map_push(struct ctdb_vnn_map *in, uint8_t *buf, size_t *npush)
905 size_t offset = 0, np;
906 uint32_t i;
908 ctdb_uint32_push(&in->generation, buf+offset, &np);
909 offset += np;
911 ctdb_uint32_push(&in->size, buf+offset, &np);
912 offset += np;
914 for (i=0; i<in->size; i++) {
915 ctdb_uint32_push(&in->map[i], buf+offset, &np);
916 offset += np;
919 *npush = offset;
922 int ctdb_vnn_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
923 struct ctdb_vnn_map **out, size_t *npull)
925 struct ctdb_vnn_map *val;
926 size_t offset = 0, np;
927 uint32_t i;
928 int ret;
930 val = talloc(mem_ctx, struct ctdb_vnn_map);
931 if (val == NULL) {
932 return ENOMEM;
935 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->generation,
936 &np);
937 if (ret != 0) {
938 goto fail;
940 offset += np;
942 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->size, &np);
943 if (ret != 0) {
944 goto fail;
946 offset += np;
948 if (val->size == 0) {
949 val->map = NULL;
950 goto done;
953 val->map = talloc_array(val, uint32_t, val->size);
954 if (val->map == NULL) {
955 ret = ENOMEM;
956 goto fail;
959 for (i=0; i<val->size; i++) {
960 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
961 &val->map[i], &np);
962 if (ret != 0) {
963 goto fail;
965 offset += np;
968 done:
969 *out = val;
970 *npull = offset;
971 return 0;
973 fail:
974 talloc_free(val);
975 return ret;
978 size_t ctdb_dbid_len(struct ctdb_dbid *in)
980 return ctdb_uint32_len(&in->db_id) +
981 ctdb_uint8_len(&in->flags) +
982 ctdb_padding_len(3);
985 void ctdb_dbid_push(struct ctdb_dbid *in, uint8_t *buf, size_t *npush)
987 size_t offset = 0, np;
989 ctdb_uint32_push(&in->db_id, buf+offset, &np);
990 offset += np;
992 ctdb_uint8_push(&in->flags, buf+offset, &np);
993 offset += np;
995 ctdb_padding_push(3, buf+offset, &np);
996 offset += np;
998 *npush = offset;
1001 static int ctdb_dbid_pull_elems(uint8_t *buf, size_t buflen,
1002 TALLOC_CTX *mem_ctx, struct ctdb_dbid *out,
1003 size_t *npull)
1005 size_t offset = 0, np;
1006 int ret;
1008 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->db_id, &np);
1009 if (ret != 0) {
1010 return ret;
1012 offset += np;
1014 ret = ctdb_uint8_pull(buf+offset, buflen-offset, &out->flags, &np);
1015 if (ret != 0) {
1016 return ret;
1018 offset += np;
1020 ret = ctdb_padding_pull(buf+offset, buflen-offset, 3, &np);
1021 if (ret != 0) {
1022 return ret;
1024 offset += np;
1026 *npull = offset;
1027 return 0;
1030 int ctdb_dbid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1031 struct ctdb_dbid **out, size_t *npull)
1033 struct ctdb_dbid *val;
1034 size_t np;
1035 int ret;
1037 val = talloc(mem_ctx, struct ctdb_dbid);
1038 if (val == NULL) {
1039 return ENOMEM;
1042 ret = ctdb_dbid_pull_elems(buf, buflen, val, val, &np);
1043 if (ret != 0) {
1044 talloc_free(val);
1045 return ret;
1048 *out = val;
1049 *npull = np;
1050 return 0;
1053 size_t ctdb_dbid_map_len(struct ctdb_dbid_map *in)
1055 size_t len;
1057 len = ctdb_uint32_len(&in->num);
1058 if (in->num > 0) {
1059 len += in->num * ctdb_dbid_len(&in->dbs[0]);
1062 return len;
1065 void ctdb_dbid_map_push(struct ctdb_dbid_map *in, uint8_t *buf, size_t *npush)
1067 size_t offset = 0, np;
1068 uint32_t i;
1070 ctdb_uint32_push(&in->num, buf+offset, &np);
1071 offset += np;
1073 for (i=0; i<in->num; i++) {
1074 ctdb_dbid_push(&in->dbs[i], buf+offset, &np);
1075 offset += np;
1078 *npush = offset;
1081 int ctdb_dbid_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1082 struct ctdb_dbid_map **out, size_t *npull)
1084 struct ctdb_dbid_map *val;
1085 size_t offset = 0, np;
1086 uint32_t i;
1087 int ret;
1089 val = talloc(mem_ctx, struct ctdb_dbid_map);
1090 if (val == NULL) {
1091 return ENOMEM;
1094 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
1095 if (ret != 0) {
1096 goto fail;
1098 offset += np;
1100 if (val->num == 0) {
1101 val->dbs = NULL;
1102 goto done;
1105 val->dbs = talloc_array(val, struct ctdb_dbid, val->num);
1106 if (val->dbs == NULL) {
1107 ret = ENOMEM;
1108 goto fail;
1111 for (i=0; i<val->num; i++) {
1112 ret = ctdb_dbid_pull_elems(buf+offset, buflen-offset, val,
1113 &val->dbs[i], &np);
1114 if (ret != 0) {
1115 goto fail;
1117 offset += np;
1120 done:
1121 *out = val;
1122 *npull = offset;
1123 return 0;
1125 fail:
1126 talloc_free(val);
1127 return ret;
1130 size_t ctdb_pulldb_len(struct ctdb_pulldb *in)
1132 return ctdb_uint32_len(&in->db_id) +
1133 ctdb_uint32_len(&in->lmaster);
1136 void ctdb_pulldb_push(struct ctdb_pulldb *in, uint8_t *buf, size_t *npush)
1138 size_t offset = 0, np;
1140 ctdb_uint32_push(&in->db_id, buf+offset, &np);
1141 offset += np;
1143 ctdb_uint32_push(&in->lmaster, buf+offset, &np);
1144 offset += np;
1146 *npush = offset;
1149 int ctdb_pulldb_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1150 struct ctdb_pulldb **out, size_t *npull)
1152 struct ctdb_pulldb *val;
1153 size_t offset = 0, np;
1154 int ret;
1156 val = talloc(mem_ctx, struct ctdb_pulldb);
1157 if (val == NULL) {
1158 return ENOMEM;
1161 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1162 if (ret != 0) {
1163 talloc_free(val);
1164 return ret;
1166 offset += np;
1168 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->lmaster, &np);
1169 if (ret != 0) {
1170 talloc_free(val);
1171 return ret;
1173 offset += np;
1175 *out = val;
1176 *npull = offset;
1177 return 0;
1180 size_t ctdb_pulldb_ext_len(struct ctdb_pulldb_ext *in)
1182 return ctdb_uint32_len(&in->db_id) +
1183 ctdb_uint32_len(&in->lmaster) +
1184 ctdb_uint64_len(&in->srvid);
1187 void ctdb_pulldb_ext_push(struct ctdb_pulldb_ext *in, uint8_t *buf,
1188 size_t *npush)
1190 size_t offset = 0, np;
1192 ctdb_uint32_push(&in->db_id, buf+offset, &np);
1193 offset += np;
1195 ctdb_uint32_push(&in->lmaster, buf+offset, &np);
1196 offset += np;
1198 ctdb_uint64_push(&in->srvid, buf+offset, &np);
1199 offset += np;
1201 *npush = offset;
1204 int ctdb_pulldb_ext_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1205 struct ctdb_pulldb_ext **out, size_t *npull)
1207 struct ctdb_pulldb_ext *val;
1208 size_t offset = 0, np;
1209 int ret;
1211 val = talloc(mem_ctx, struct ctdb_pulldb_ext);
1212 if (val == NULL) {
1213 return ENOMEM;
1216 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1217 if (ret != 0) {
1218 goto fail;
1220 offset += np;
1222 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->lmaster, &np);
1223 if (ret != 0) {
1224 goto fail;
1226 offset += np;
1228 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
1229 if (ret != 0) {
1230 goto fail;
1232 offset += np;
1234 *out = val;
1235 *npull = offset;
1236 return 0;
1238 fail:
1239 talloc_free(val);
1240 return ret;
1243 size_t ctdb_db_vacuum_len(struct ctdb_db_vacuum *in)
1245 return ctdb_uint32_len(&in->db_id) +
1246 ctdb_bool_len(&in->full_vacuum_run);
1249 void ctdb_db_vacuum_push(struct ctdb_db_vacuum *in,
1250 uint8_t *buf,
1251 size_t *npush)
1253 size_t offset = 0, np;
1255 ctdb_uint32_push(&in->db_id, buf+offset, &np);
1256 offset += np;
1258 ctdb_bool_push(&in->full_vacuum_run, buf+offset, &np);
1259 offset += np;
1261 *npush = offset;
1264 int ctdb_db_vacuum_pull(uint8_t *buf,
1265 size_t buflen,
1266 TALLOC_CTX *mem_ctx,
1267 struct ctdb_db_vacuum **out,
1268 size_t *npull)
1270 struct ctdb_db_vacuum *val;
1271 size_t offset = 0, np;
1272 int ret;
1274 val = talloc(mem_ctx, struct ctdb_db_vacuum);
1275 if (val == NULL) {
1276 return ENOMEM;
1279 ret = ctdb_uint32_pull(buf+offset,
1280 buflen-offset,
1281 &val->db_id,
1282 &np);
1283 if (ret != 0) {
1284 goto fail;
1286 offset += np;
1288 ret = ctdb_bool_pull(buf+offset,
1289 buflen-offset,
1290 &val->full_vacuum_run,
1291 &np);
1292 if (ret != 0) {
1293 goto fail;
1295 offset += np;
1297 *out = val;
1298 *npull = offset;
1299 return 0;
1301 fail:
1302 talloc_free(val);
1303 return ret;
1306 size_t ctdb_echo_data_len(struct ctdb_echo_data *in)
1309 * No overflow check, none of the routines in this file do it
1310 * and there's no way to report it anyway.
1312 return ctdb_uint32_len(&in->timeout) + ctdb_tdb_datan_len(&in->buf);
1315 void ctdb_echo_data_push(struct ctdb_echo_data *in,
1316 uint8_t *buf,
1317 size_t *npush)
1319 size_t offset = 0, np;
1322 * No overflow check, none of the routines in this file do it
1323 * and there's no way to report it anyway.
1326 ctdb_uint32_push(&in->timeout, buf+offset, &np);
1327 offset += np;
1329 ctdb_tdb_datan_push(&in->buf, buf+offset, &np);
1330 offset += np;
1332 *npush = offset;
1335 int ctdb_echo_data_pull(uint8_t *buf,
1336 size_t buflen,
1337 TALLOC_CTX *mem_ctx,
1338 struct ctdb_echo_data **out,
1339 size_t *npull)
1341 struct ctdb_echo_data *val;
1342 size_t offset = 0, np;
1343 int ret;
1345 val = talloc(mem_ctx, struct ctdb_echo_data);
1346 if (val == NULL) {
1347 return ENOMEM;
1350 ret = ctdb_uint32_pull(buf+offset,
1351 buflen-offset,
1352 &val->timeout,
1353 &np);
1354 if (ret != 0) {
1355 goto fail;
1357 offset += np;
1359 ret = ctdb_tdb_datan_pull(buf+offset,
1360 buflen-offset,
1361 val,
1362 &val->buf,
1363 &np);
1364 if (ret != 0) {
1365 goto fail;
1367 offset += np;
1369 *out = val;
1370 *npull = offset;
1371 return 0;
1373 fail:
1374 talloc_free(val);
1375 return ret;
1378 size_t ctdb_ltdb_header_len(struct ctdb_ltdb_header *in)
1380 return ctdb_uint64_len(&in->rsn) +
1381 ctdb_uint32_len(&in->dmaster) +
1382 ctdb_uint32_len(&in->reserved1) +
1383 ctdb_uint32_len(&in->flags) +
1384 ctdb_padding_len(4);
1387 void ctdb_ltdb_header_push(struct ctdb_ltdb_header *in, uint8_t *buf,
1388 size_t *npush)
1390 size_t offset = 0, np;
1392 ctdb_uint64_push(&in->rsn, buf+offset, &np);
1393 offset += np;
1395 ctdb_uint32_push(&in->dmaster, buf+offset, &np);
1396 offset += np;
1398 ctdb_uint32_push(&in->reserved1, buf+offset, &np);
1399 offset += np;
1401 ctdb_uint32_push(&in->flags, buf+offset, &np);
1402 offset += np;
1404 ctdb_padding_push(4, buf+offset, &np);
1405 offset += np;
1407 *npush = offset;
1410 int ctdb_ltdb_header_pull(uint8_t *buf, size_t buflen,
1411 struct ctdb_ltdb_header *out, size_t *npull)
1413 size_t offset = 0, np;
1414 int ret;
1416 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &out->rsn, &np);
1417 if (ret != 0) {
1418 return ret;
1420 offset += np;
1422 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->dmaster, &np);
1423 if (ret != 0) {
1424 return ret;
1426 offset += np;
1428 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->reserved1,
1429 &np);
1430 if (ret != 0) {
1431 return ret;
1433 offset += np;
1435 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->flags, &np);
1436 if (ret != 0) {
1437 return ret;
1439 offset += np;
1441 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
1442 if (ret != 0) {
1443 return ret;
1445 offset += np;
1447 *npull = offset;
1448 return 0;
1451 int ctdb_ltdb_header_extract(TDB_DATA *data, struct ctdb_ltdb_header *header)
1453 size_t np;
1454 int ret;
1456 ret = ctdb_ltdb_header_pull(data->dptr, data->dsize, header, &np);
1457 if (ret != 0) {
1458 return ret;
1461 data->dptr += np;
1462 data->dsize -= np;
1464 return 0;
1467 size_t ctdb_rec_data_len(struct ctdb_rec_data *in)
1469 uint32_t u32;
1471 u32 = ctdb_uint32_len(&in->reqid) +
1472 ctdb_tdb_datan_len(&in->key) +
1473 ctdb_tdb_datan_len(&in->data);
1475 if (in->header != NULL) {
1476 u32 += ctdb_ltdb_header_len(in->header);
1479 return ctdb_uint32_len(&u32) + u32;
1482 void ctdb_rec_data_push(struct ctdb_rec_data *in, uint8_t *buf, size_t *npush)
1484 size_t offset = 0, np;
1485 uint32_t u32;
1487 u32 = ctdb_rec_data_len(in);
1488 ctdb_uint32_push(&u32, buf+offset, &np);
1489 offset += np;
1491 ctdb_uint32_push(&in->reqid, buf+offset, &np);
1492 offset += np;
1494 u32 = ctdb_tdb_data_len(&in->key);
1495 ctdb_uint32_push(&u32, buf+offset, &np);
1496 offset += np;
1498 u32 = ctdb_tdb_data_len(&in->data);
1499 if (in->header != NULL) {
1500 u32 += ctdb_ltdb_header_len(in->header);
1503 ctdb_uint32_push(&u32, buf+offset, &np);
1504 offset += np;
1506 ctdb_tdb_data_push(&in->key, buf+offset, &np);
1507 offset += np;
1509 /* If ltdb header is not NULL, then it is pushed as part of the data */
1510 if (in->header != NULL) {
1511 ctdb_ltdb_header_push(in->header, buf+offset, &np);
1512 offset += np;
1514 ctdb_tdb_data_push(&in->data, buf+offset, &np);
1515 offset += np;
1517 *npush = offset;
1520 static int ctdb_rec_data_pull_data(uint8_t *buf, size_t buflen,
1521 uint32_t *reqid,
1522 TDB_DATA *key, TDB_DATA *data,
1523 size_t *npull)
1525 size_t offset = 0, np;
1526 size_t len;
1527 uint32_t u32;
1528 int ret;
1530 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
1531 if (ret != 0) {
1532 return ret;
1534 offset += np;
1536 if (buflen < u32) {
1537 return EMSGSIZE;
1539 len = u32;
1541 ret = ctdb_uint32_pull(buf+offset, len-offset, reqid, &np);
1542 if (ret != 0) {
1543 return ret;
1545 offset += np;
1547 ret = ctdb_uint32_pull(buf+offset, len-offset, &u32, &np);
1548 if (ret != 0) {
1549 return ret;
1551 offset += np;
1552 key->dsize = u32;
1554 ret = ctdb_uint32_pull(buf+offset, len-offset, &u32, &np);
1555 if (ret != 0) {
1556 return ret;
1558 offset += np;
1559 data->dsize = u32;
1561 if (len-offset < key->dsize) {
1562 return EMSGSIZE;
1565 key->dptr = buf+offset;
1566 offset += key->dsize;
1568 if (len-offset < data->dsize) {
1569 return EMSGSIZE;
1572 data->dptr = buf+offset;
1573 offset += data->dsize;
1575 *npull = offset;
1576 return 0;
1579 static int ctdb_rec_data_pull_elems(uint8_t *buf, size_t buflen,
1580 TALLOC_CTX *mem_ctx,
1581 struct ctdb_rec_data *out,
1582 size_t *npull)
1584 uint32_t reqid;
1585 TDB_DATA key, data;
1586 size_t np;
1587 int ret;
1589 ret = ctdb_rec_data_pull_data(buf, buflen, &reqid, &key, &data, &np);
1590 if (ret != 0) {
1591 return ret;
1594 out->reqid = reqid;
1596 /* Always set header to NULL. If it is required, extract it using
1597 * ctdb_rec_data_extract_header()
1599 out->header = NULL;
1601 out->key.dsize = key.dsize;
1602 if (key.dsize > 0) {
1603 out->key.dptr = talloc_memdup(mem_ctx, key.dptr, key.dsize);
1604 if (out->key.dptr == NULL) {
1605 return ENOMEM;
1609 out->data.dsize = data.dsize;
1610 if (data.dsize > 0) {
1611 out->data.dptr = talloc_memdup(mem_ctx, data.dptr, data.dsize);
1612 if (out->data.dptr == NULL) {
1613 return ENOMEM;
1617 *npull = np;
1618 return 0;
1621 int ctdb_rec_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1622 struct ctdb_rec_data **out, size_t *npull)
1624 struct ctdb_rec_data *val;
1625 size_t np;
1626 int ret;
1628 val = talloc(mem_ctx, struct ctdb_rec_data);
1629 if (val == NULL) {
1630 return ENOMEM;
1633 ret = ctdb_rec_data_pull_elems(buf, buflen, val, val, &np);
1634 if (ret != 0) {
1635 TALLOC_FREE(val);
1636 return ret;
1639 *out = val;
1640 *npull = np;
1641 return ret;
1644 size_t ctdb_rec_buffer_len(struct ctdb_rec_buffer *in)
1646 return ctdb_uint32_len(&in->db_id) +
1647 ctdb_uint32_len(&in->count) +
1648 in->buflen;
1651 void ctdb_rec_buffer_push(struct ctdb_rec_buffer *in, uint8_t *buf,
1652 size_t *npush)
1654 size_t offset = 0, np;
1656 ctdb_uint32_push(&in->db_id, buf+offset, &np);
1657 offset += np;
1659 ctdb_uint32_push(&in->count, buf+offset, &np);
1660 offset += np;
1662 memcpy(buf+offset, in->buf, in->buflen);
1663 offset += in->buflen;
1665 *npush = offset;
1668 int ctdb_rec_buffer_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1669 struct ctdb_rec_buffer **out, size_t *npull)
1671 struct ctdb_rec_buffer *val;
1672 size_t offset = 0, np;
1673 size_t length;
1674 int ret;
1676 val = talloc(mem_ctx, struct ctdb_rec_buffer);
1677 if (val == NULL) {
1678 return ENOMEM;
1681 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1682 if (ret != 0) {
1683 goto fail;
1685 offset += np;
1687 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->count, &np);
1688 if (ret != 0) {
1689 goto fail;
1691 offset += np;
1693 /* Since there is no buflen provided, walk the records to
1694 * validate the length of the buffer.
1696 val->buf = buf+offset;
1697 val->buflen = buflen-offset;
1699 length = 0;
1700 ret = ctdb_rec_buffer_traverse(val, NULL, &length);
1701 if (ret != 0) {
1702 goto fail;
1705 if (length > buflen-offset) {
1706 ret = EMSGSIZE;
1707 goto fail;
1710 val->buf = talloc_memdup(val, buf+offset, length);
1711 if (val->buf == NULL) {
1712 ret = ENOMEM;
1713 goto fail;
1715 val->buflen = length;
1716 offset += length;
1718 *out = val;
1719 *npull = offset;
1720 return 0;
1722 fail:
1723 talloc_free(val);
1724 return ret;
1727 struct ctdb_rec_buffer *ctdb_rec_buffer_init(TALLOC_CTX *mem_ctx,
1728 uint32_t db_id)
1730 struct ctdb_rec_buffer *recbuf;
1732 recbuf = talloc_zero(mem_ctx, struct ctdb_rec_buffer);
1733 if (recbuf == NULL) {
1734 return recbuf;
1737 recbuf->db_id = db_id;
1739 return recbuf;
1742 int ctdb_rec_buffer_add(TALLOC_CTX *mem_ctx, struct ctdb_rec_buffer *recbuf,
1743 uint32_t reqid, struct ctdb_ltdb_header *header,
1744 TDB_DATA key, TDB_DATA data)
1746 struct ctdb_rec_data recdata;
1747 size_t len, np;
1748 uint8_t *ptr;
1750 recdata.reqid = reqid;
1751 recdata.header = header;
1752 recdata.key = key;
1753 recdata.data = data;
1755 len = ctdb_rec_data_len(&recdata);
1757 ptr = talloc_realloc(mem_ctx, recbuf->buf, uint8_t,
1758 recbuf->buflen + len);
1759 if (ptr == NULL) {
1760 return ENOMEM;
1763 ctdb_rec_data_push(&recdata, &ptr[recbuf->buflen], &np);
1765 recbuf->count++;
1766 recbuf->buf = ptr;
1767 recbuf->buflen += np;
1768 return 0;
1771 int ctdb_rec_buffer_traverse(struct ctdb_rec_buffer *recbuf,
1772 ctdb_rec_parser_func_t func,
1773 void *private_data)
1775 TDB_DATA key, data;
1776 uint32_t reqid;
1777 size_t offset, reclen;
1778 unsigned int i;
1779 int ret = 0;
1781 offset = 0;
1782 for (i=0; i<recbuf->count; i++) {
1783 ret = ctdb_rec_data_pull_data(&recbuf->buf[offset],
1784 recbuf->buflen - offset,
1785 &reqid, &key, &data, &reclen);
1786 if (ret != 0) {
1787 return ret;
1790 if (func != NULL) {
1791 ret = func(reqid, NULL, key, data, private_data);
1792 if (ret != 0) {
1793 break;
1797 offset += reclen;
1800 if (ret != 0) {
1801 return ret;
1804 if (func == NULL) {
1805 size_t *length = (size_t *)private_data;
1807 *length = offset;
1810 return 0;
1813 int ctdb_rec_buffer_write(struct ctdb_rec_buffer *recbuf, int fd)
1815 ssize_t n;
1817 n = write(fd, &recbuf->db_id, sizeof(uint32_t));
1818 if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1819 return (errno != 0 ? errno : EIO);
1821 n = write(fd, &recbuf->count, sizeof(uint32_t));
1822 if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1823 return (errno != 0 ? errno : EIO);
1825 n = write(fd, &recbuf->buflen, sizeof(size_t));
1826 if (n == -1 || (size_t)n != sizeof(size_t)) {
1827 return (errno != 0 ? errno : EIO);
1829 n = write(fd, recbuf->buf, recbuf->buflen);
1830 if (n == -1 || (size_t)n != recbuf->buflen) {
1831 return (errno != 0 ? errno : EIO);
1834 return 0;
1837 int ctdb_rec_buffer_read(int fd, TALLOC_CTX *mem_ctx,
1838 struct ctdb_rec_buffer **out)
1840 struct ctdb_rec_buffer *recbuf;
1841 ssize_t n;
1843 recbuf = talloc(mem_ctx, struct ctdb_rec_buffer);
1844 if (recbuf == NULL) {
1845 return ENOMEM;
1848 n = read(fd, &recbuf->db_id, sizeof(uint32_t));
1849 if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1850 return (errno != 0 ? errno : EIO);
1852 n = read(fd, &recbuf->count, sizeof(uint32_t));
1853 if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1854 return (errno != 0 ? errno : EIO);
1856 n = read(fd, &recbuf->buflen, sizeof(size_t));
1857 if (n == -1 || (size_t)n != sizeof(size_t)) {
1858 return (errno != 0 ? errno : EIO);
1861 recbuf->buf = talloc_size(recbuf, recbuf->buflen);
1862 if (recbuf->buf == NULL) {
1863 return ENOMEM;
1866 n = read(fd, recbuf->buf, recbuf->buflen);
1867 if (n == -1 || (size_t)n != recbuf->buflen) {
1868 return (errno != 0 ? errno : EIO);
1871 *out = recbuf;
1872 return 0;
1875 size_t ctdb_traverse_start_len(struct ctdb_traverse_start *in)
1877 return ctdb_uint32_len(&in->db_id) +
1878 ctdb_uint32_len(&in->reqid) +
1879 ctdb_uint64_len(&in->srvid);
1882 void ctdb_traverse_start_push(struct ctdb_traverse_start *in, uint8_t *buf,
1883 size_t *npush)
1885 size_t offset = 0, np;
1887 ctdb_uint32_push(&in->db_id, buf+offset, &np);
1888 offset += np;
1890 ctdb_uint32_push(&in->reqid, buf+offset, &np);
1891 offset += np;
1893 ctdb_uint64_push(&in->srvid, buf+offset, &np);
1894 offset += np;
1896 *npush = offset;
1899 int ctdb_traverse_start_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1900 struct ctdb_traverse_start **out, size_t *npull)
1902 struct ctdb_traverse_start *val;
1903 size_t offset = 0, np;
1904 int ret;
1906 val = talloc(mem_ctx, struct ctdb_traverse_start);
1907 if (val == NULL) {
1908 return ENOMEM;
1911 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1912 if (ret != 0) {
1913 goto fail;
1915 offset += np;
1917 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
1918 if (ret != 0) {
1919 goto fail;
1921 offset += np;
1923 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
1924 if (ret != 0) {
1925 goto fail;
1927 offset += np;
1929 *out = val;
1930 *npull = offset;
1931 return 0;
1933 fail:
1934 talloc_free(val);
1935 return ret;
1938 size_t ctdb_traverse_all_len(struct ctdb_traverse_all *in)
1940 return ctdb_uint32_len(&in->db_id) +
1941 ctdb_uint32_len(&in->reqid) +
1942 ctdb_uint32_len(&in->pnn) +
1943 ctdb_uint32_len(&in->client_reqid) +
1944 ctdb_uint64_len(&in->srvid);
1947 void ctdb_traverse_all_push(struct ctdb_traverse_all *in, uint8_t *buf,
1948 size_t *npush)
1950 size_t offset = 0, np;
1952 ctdb_uint32_push(&in->db_id, buf+offset, &np);
1953 offset += np;
1955 ctdb_uint32_push(&in->reqid, buf+offset, &np);
1956 offset += np;
1958 ctdb_uint32_push(&in->pnn, buf+offset, &np);
1959 offset += np;
1961 ctdb_uint32_push(&in->client_reqid, buf+offset, &np);
1962 offset += np;
1964 ctdb_uint64_push(&in->srvid, buf+offset, &np);
1965 offset += np;
1967 *npush = offset;
1970 int ctdb_traverse_all_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1971 struct ctdb_traverse_all **out, size_t *npull)
1973 struct ctdb_traverse_all *val;
1974 size_t offset = 0, np;
1975 int ret;
1977 val = talloc(mem_ctx, struct ctdb_traverse_all);
1978 if (val == NULL) {
1979 return ENOMEM;
1982 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1983 if (ret != 0) {
1984 goto fail;
1986 offset += np;
1988 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
1989 if (ret != 0) {
1990 goto fail;
1992 offset += np;
1994 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
1995 if (ret != 0) {
1996 goto fail;
1998 offset += np;
2000 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->client_reqid,
2001 &np);
2002 if (ret != 0) {
2003 goto fail;
2005 offset += np;
2007 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
2008 if (ret != 0) {
2009 goto fail;
2011 offset += np;
2013 *out = val;
2014 *npull = offset;
2015 return 0;
2017 fail:
2018 talloc_free(val);
2019 return ret;
2022 size_t ctdb_traverse_start_ext_len(struct ctdb_traverse_start_ext *in)
2024 return ctdb_uint32_len(&in->db_id) +
2025 ctdb_uint32_len(&in->reqid) +
2026 ctdb_uint64_len(&in->srvid) +
2027 ctdb_bool_len(&in->withemptyrecords) +
2028 ctdb_padding_len(7);
2031 void ctdb_traverse_start_ext_push(struct ctdb_traverse_start_ext *in,
2032 uint8_t *buf, size_t *npush)
2034 size_t offset = 0, np;
2036 ctdb_uint32_push(&in->db_id, buf+offset, &np);
2037 offset += np;
2039 ctdb_uint32_push(&in->reqid, buf+offset, &np);
2040 offset += np;
2042 ctdb_uint64_push(&in->srvid, buf+offset, &np);
2043 offset += np;
2045 ctdb_bool_push(&in->withemptyrecords, buf+offset, &np);
2046 offset += np;
2048 ctdb_padding_push(7, buf+offset, &np);
2049 offset += np;
2051 *npush = offset;
2054 int ctdb_traverse_start_ext_pull(uint8_t *buf, size_t buflen,
2055 TALLOC_CTX *mem_ctx,
2056 struct ctdb_traverse_start_ext **out,
2057 size_t *npull)
2059 struct ctdb_traverse_start_ext *val;
2060 size_t offset = 0, np;
2061 int ret;
2063 val = talloc(mem_ctx, struct ctdb_traverse_start_ext);
2064 if (val == NULL) {
2065 return ENOMEM;
2068 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
2069 if (ret != 0) {
2070 goto fail;
2072 offset += np;
2074 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
2075 if (ret != 0) {
2076 goto fail;
2078 offset += np;
2080 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
2081 if (ret != 0) {
2082 goto fail;
2084 offset += np;
2086 ret = ctdb_bool_pull(buf+offset, buflen-offset,
2087 &val->withemptyrecords, &np);
2088 if (ret != 0) {
2089 goto fail;
2091 offset += np;
2093 ret = ctdb_padding_pull(buf+offset, buflen-offset, 7, &np);
2094 if (ret != 0) {
2095 goto fail;
2097 offset += np;
2099 *out = val;
2100 *npull = offset;
2101 return 0;
2103 fail:
2104 talloc_free(val);
2105 return ret;
2108 size_t ctdb_traverse_all_ext_len(struct ctdb_traverse_all_ext *in)
2110 return ctdb_uint32_len(&in->db_id) +
2111 ctdb_uint32_len(&in->reqid) +
2112 ctdb_uint32_len(&in->pnn) +
2113 ctdb_uint32_len(&in->client_reqid) +
2114 ctdb_uint64_len(&in->srvid) +
2115 ctdb_bool_len(&in->withemptyrecords) +
2116 ctdb_padding_len(7);
2119 void ctdb_traverse_all_ext_push(struct ctdb_traverse_all_ext *in,
2120 uint8_t *buf, size_t *npush)
2122 size_t offset = 0, np;
2124 ctdb_uint32_push(&in->db_id, buf+offset, &np);
2125 offset += np;
2127 ctdb_uint32_push(&in->reqid, buf+offset, &np);
2128 offset += np;
2130 ctdb_uint32_push(&in->pnn, buf+offset, &np);
2131 offset += np;
2133 ctdb_uint32_push(&in->client_reqid, buf+offset, &np);
2134 offset += np;
2136 ctdb_uint64_push(&in->srvid, buf+offset, &np);
2137 offset += np;
2139 ctdb_bool_push(&in->withemptyrecords, buf+offset, &np);
2140 offset += np;
2142 ctdb_padding_push(7, buf+offset, &np);
2143 offset += np;
2145 *npush = offset;
2148 int ctdb_traverse_all_ext_pull(uint8_t *buf, size_t buflen,
2149 TALLOC_CTX *mem_ctx,
2150 struct ctdb_traverse_all_ext **out,
2151 size_t *npull)
2153 struct ctdb_traverse_all_ext *val;
2154 size_t offset = 0, np;
2155 int ret;
2157 val = talloc(mem_ctx, struct ctdb_traverse_all_ext);
2158 if (val == NULL) {
2159 return ENOMEM;
2162 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
2163 if (ret != 0) {
2164 goto fail;
2166 offset += np;
2168 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
2169 if (ret != 0) {
2170 goto fail;
2172 offset += np;
2174 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
2175 if (ret != 0) {
2176 goto fail;
2178 offset += np;
2180 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->client_reqid,
2181 &np);
2182 if (ret != 0) {
2183 goto fail;
2185 offset += np;
2187 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
2188 if (ret != 0) {
2189 goto fail;
2191 offset += np;
2193 ret = ctdb_bool_pull(buf+offset, buflen-offset,
2194 &val->withemptyrecords, &np);
2195 if (ret != 0) {
2196 goto fail;
2198 offset += np;
2200 ret = ctdb_padding_pull(buf+offset, buflen-offset, 7, &np);
2201 if (ret != 0) {
2202 goto fail;
2204 offset += np;
2206 *out = val;
2207 *npull = offset;
2208 return 0;
2210 fail:
2211 talloc_free(val);
2212 return ret;
2215 size_t ctdb_sock_addr_len(ctdb_sock_addr *in)
2217 return sizeof(ctdb_sock_addr);
2220 void ctdb_sock_addr_push(ctdb_sock_addr *in, uint8_t *buf, size_t *npush)
2222 memcpy(buf, in, sizeof(ctdb_sock_addr));
2223 *npush = sizeof(ctdb_sock_addr);
2226 int ctdb_sock_addr_pull_elems(uint8_t *buf, size_t buflen,
2227 TALLOC_CTX *mem_ctx, ctdb_sock_addr *out,
2228 size_t *npull)
2230 if (buflen < sizeof(ctdb_sock_addr)) {
2231 return EMSGSIZE;
2234 memcpy(out, buf, sizeof(ctdb_sock_addr));
2235 *npull = sizeof(ctdb_sock_addr);
2237 return 0;
2240 int ctdb_sock_addr_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2241 ctdb_sock_addr **out, size_t *npull)
2243 ctdb_sock_addr *val;
2244 size_t np;
2245 int ret;
2247 val = talloc(mem_ctx, ctdb_sock_addr);
2248 if (val == NULL) {
2249 return ENOMEM;
2252 ret = ctdb_sock_addr_pull_elems(buf, buflen, val, val, &np);
2253 if (ret != 0) {
2254 talloc_free(val);
2255 return ret;
2258 *out = val;
2259 *npull = np;
2260 return ret;
2263 size_t ctdb_connection_len(struct ctdb_connection *in)
2265 return ctdb_sock_addr_len(&in->src) +
2266 ctdb_sock_addr_len(&in->dst);
2269 void ctdb_connection_push(struct ctdb_connection *in, uint8_t *buf,
2270 size_t *npush)
2272 size_t offset = 0, np;
2274 ctdb_sock_addr_push(&in->src, buf+offset, &np);
2275 offset += np;
2277 ctdb_sock_addr_push(&in->dst, buf+offset, &np);
2278 offset += np;
2280 *npush = offset;
2283 static int ctdb_connection_pull_elems(uint8_t *buf, size_t buflen,
2284 TALLOC_CTX *mem_ctx,
2285 struct ctdb_connection *out,
2286 size_t *npull)
2288 size_t offset = 0, np;
2289 int ret;
2291 ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset,
2292 mem_ctx, &out->src, &np);
2293 if (ret != 0) {
2294 return ret;
2296 offset += np;
2298 ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset,
2299 mem_ctx, &out->dst, &np);
2300 if (ret != 0) {
2301 return ret;
2303 offset += np;
2305 *npull = offset;
2306 return 0;
2309 int ctdb_connection_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2310 struct ctdb_connection **out, size_t *npull)
2312 struct ctdb_connection *val;
2313 size_t np;
2314 int ret;
2316 val = talloc(mem_ctx, struct ctdb_connection);
2317 if (val == NULL) {
2318 return ENOMEM;
2321 ret = ctdb_connection_pull_elems(buf, buflen, val, val, &np);
2322 if (ret != 0) {
2323 talloc_free(val);
2324 return ret;
2327 *out = val;
2328 *npull = np;
2329 return ret;
2332 size_t ctdb_connection_list_len(struct ctdb_connection_list *in)
2334 size_t len;
2336 len = ctdb_uint32_len(&in->num);
2337 if (in->num > 0) {
2338 len += in->num * ctdb_connection_len(&in->conn[0]);
2341 return len;
2344 void ctdb_connection_list_push(struct ctdb_connection_list *in, uint8_t *buf,
2345 size_t *npush)
2347 size_t offset = 0, np;
2348 uint32_t i;
2350 ctdb_uint32_push(&in->num, buf+offset, &np);
2351 offset += np;
2353 for (i=0; i<in->num; i++) {
2354 ctdb_connection_push(&in->conn[i], buf+offset, &np);
2355 offset += np;
2358 *npush = offset;
2361 int ctdb_connection_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2362 struct ctdb_connection_list **out, size_t *npull)
2364 struct ctdb_connection_list *val;
2365 size_t offset = 0, np;
2366 uint32_t i;
2367 int ret;
2369 val = talloc(mem_ctx, struct ctdb_connection_list);
2370 if (val == NULL) {
2371 return ENOMEM;
2374 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
2375 if (ret != 0) {
2376 goto fail;
2378 offset += np;
2380 if (val->num == 0) {
2381 val->conn = NULL;
2382 goto done;
2385 val->conn = talloc_array(val, struct ctdb_connection, val->num);
2386 if (val->conn == NULL) {
2387 ret = ENOMEM;
2388 goto fail;
2391 for (i=0; i<val->num; i++) {
2392 ret = ctdb_connection_pull_elems(buf+offset, buflen-offset,
2393 val, &val->conn[i], &np);
2394 if (ret != 0) {
2395 goto fail;
2397 offset += np;
2400 done:
2401 *out = val;
2402 *npull = offset;
2403 return 0;
2405 fail:
2406 talloc_free(val);
2407 return ret;
2410 size_t ctdb_tunable_len(struct ctdb_tunable *in)
2412 return ctdb_uint32_len(&in->value) +
2413 ctdb_stringn_len(&in->name);
2416 void ctdb_tunable_push(struct ctdb_tunable *in, uint8_t *buf, size_t *npush)
2418 size_t offset = 0, np;
2420 ctdb_uint32_push(&in->value, buf+offset, &np);
2421 offset += np;
2423 ctdb_stringn_push(&in->name, buf+offset, &np);
2424 offset += np;
2426 *npush = offset;
2429 int ctdb_tunable_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2430 struct ctdb_tunable **out, size_t *npull)
2432 struct ctdb_tunable *val;
2433 size_t offset = 0, np;
2434 int ret;
2436 val = talloc(mem_ctx, struct ctdb_tunable);
2437 if (val == NULL) {
2438 return ENOMEM;
2441 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->value, &np);
2442 if (ret != 0) {
2443 goto fail;
2445 offset += np;
2447 ret = ctdb_stringn_pull(buf+offset, buflen-offset, mem_ctx,
2448 &val->name, &np);
2449 if (ret != 0) {
2450 goto fail;
2452 offset += np;
2454 *out = val;
2455 *npull = offset;
2456 return 0;
2458 fail:
2459 talloc_free(val);
2460 return ret;
2463 size_t ctdb_node_flag_change_len(struct ctdb_node_flag_change *in)
2465 return ctdb_uint32_len(&in->pnn) +
2466 ctdb_uint32_len(&in->new_flags) +
2467 ctdb_uint32_len(&in->old_flags);
2470 void ctdb_node_flag_change_push(struct ctdb_node_flag_change *in,
2471 uint8_t *buf, size_t *npush)
2473 size_t offset = 0, np;
2475 ctdb_uint32_push(&in->pnn, buf+offset, &np);
2476 offset += np;
2478 ctdb_uint32_push(&in->new_flags, buf+offset, &np);
2479 offset += np;
2481 ctdb_uint32_push(&in->old_flags, buf+offset, &np);
2482 offset += np;
2484 *npush = offset;
2487 int ctdb_node_flag_change_pull(uint8_t *buf, size_t buflen,
2488 TALLOC_CTX *mem_ctx,
2489 struct ctdb_node_flag_change **out,
2490 size_t *npull)
2492 struct ctdb_node_flag_change *val;
2493 size_t offset = 0, np;
2494 int ret;
2496 val = talloc(mem_ctx, struct ctdb_node_flag_change);
2497 if (val == NULL) {
2498 return ENOMEM;
2501 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
2502 if (ret != 0) {
2503 goto fail;
2505 offset += np;
2507 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->new_flags,
2508 &np);
2509 if (ret != 0) {
2510 goto fail;
2512 offset += np;
2514 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->old_flags,
2515 &np);
2516 if (ret != 0) {
2517 goto fail;
2519 offset += np;
2521 *out = val;
2522 *npull = offset;
2523 return 0;
2525 fail:
2526 talloc_free(val);
2527 return ret;
2530 size_t ctdb_var_list_len(struct ctdb_var_list *in)
2532 uint32_t u32 = 0;
2533 int i;
2535 for (i=0; i<in->count; i++) {
2536 u32 += ctdb_string_len(&in->var[i]);
2539 return ctdb_uint32_len(&u32) + u32;
2542 void ctdb_var_list_push(struct ctdb_var_list *in, uint8_t *buf, size_t *npush)
2544 size_t offset = 0, np;
2545 uint32_t u32;
2546 int i;
2547 uint8_t sep = ':';
2549 /* The length only corresponds to the payload size */
2550 u32 = ctdb_var_list_len(in);
2551 u32 -= ctdb_uint32_len(&u32);
2553 ctdb_uint32_push(&u32, buf+offset, &np);
2554 offset += np;
2556 /* The variables are separated by ':' and the complete string is null
2557 * terminated.
2559 for (i=0; i<in->count; i++) {
2560 ctdb_string_push(&in->var[i], buf+offset, &np);
2561 offset += np;
2563 if (i < in->count - 1) {
2564 /* Replace '\0' with ':' */
2565 ctdb_uint8_push(&sep, buf+offset-1, &np);
2569 *npush = offset;
2572 int ctdb_var_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2573 struct ctdb_var_list **out, size_t *npull)
2575 struct ctdb_var_list *val;
2576 const char *str, **list;
2577 char *s, *tok, *ptr = NULL;
2578 size_t offset = 0, np;
2579 uint32_t u32;
2580 int ret;
2582 val = talloc_zero(mem_ctx, struct ctdb_var_list);
2583 if (val == NULL) {
2584 return ENOMEM;
2587 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
2588 if (ret != 0) {
2589 goto fail;
2591 offset += np;
2593 if (buflen-offset < u32) {
2594 ret = EMSGSIZE;
2595 goto fail;
2598 ret = ctdb_string_pull(buf+offset, u32, val, &str, &np);
2599 if (ret != 0) {
2600 goto fail;
2602 offset += np;
2604 s = discard_const(str);
2605 while ((tok = strtok_r(s, ":", &ptr)) != NULL) {
2606 list = talloc_realloc(val, val->var, const char *,
2607 val->count+1);
2608 if (list == NULL) {
2609 ret = ENOMEM;
2610 goto fail;
2613 val->var = list;
2615 s = talloc_strdup(val, tok);
2616 if (s == NULL) {
2617 ret = ENOMEM;
2618 goto fail;
2621 val->var[val->count] = s;
2622 val->count += 1;
2623 s = NULL;
2626 talloc_free(discard_const(str));
2627 *out = val;
2628 *npull = offset;
2629 return 0;
2631 fail:
2632 talloc_free(val);
2633 return ret;
2636 size_t ctdb_tunable_list_len(struct ctdb_tunable_list *in)
2638 return ctdb_uint32_len(&in->max_redirect_count) +
2639 ctdb_uint32_len(&in->seqnum_interval) +
2640 ctdb_uint32_len(&in->control_timeout) +
2641 ctdb_uint32_len(&in->traverse_timeout) +
2642 ctdb_uint32_len(&in->keepalive_interval) +
2643 ctdb_uint32_len(&in->keepalive_limit) +
2644 ctdb_uint32_len(&in->recover_timeout) +
2645 ctdb_uint32_len(&in->recover_interval) +
2646 ctdb_uint32_len(&in->election_timeout) +
2647 ctdb_uint32_len(&in->takeover_timeout) +
2648 ctdb_uint32_len(&in->monitor_interval) +
2649 ctdb_uint32_len(&in->tickle_update_interval) +
2650 ctdb_uint32_len(&in->script_timeout) +
2651 ctdb_uint32_len(&in->monitor_timeout_count) +
2652 ctdb_uint32_len(&in->script_unhealthy_on_timeout) +
2653 ctdb_uint32_len(&in->recovery_grace_period) +
2654 ctdb_uint32_len(&in->recovery_ban_period) +
2655 ctdb_uint32_len(&in->database_hash_size) +
2656 ctdb_uint32_len(&in->database_max_dead) +
2657 ctdb_uint32_len(&in->rerecovery_timeout) +
2658 ctdb_uint32_len(&in->enable_bans) +
2659 ctdb_uint32_len(&in->deterministic_public_ips) +
2660 ctdb_uint32_len(&in->reclock_ping_period) +
2661 ctdb_uint32_len(&in->no_ip_failback) +
2662 ctdb_uint32_len(&in->disable_ip_failover) +
2663 ctdb_uint32_len(&in->verbose_memory_names) +
2664 ctdb_uint32_len(&in->recd_ping_timeout) +
2665 ctdb_uint32_len(&in->recd_ping_failcount) +
2666 ctdb_uint32_len(&in->log_latency_ms) +
2667 ctdb_uint32_len(&in->reclock_latency_ms) +
2668 ctdb_uint32_len(&in->recovery_drop_all_ips) +
2669 ctdb_uint32_len(&in->verify_recovery_lock) +
2670 ctdb_uint32_len(&in->vacuum_interval) +
2671 ctdb_uint32_len(&in->vacuum_max_run_time) +
2672 ctdb_uint32_len(&in->repack_limit) +
2673 ctdb_uint32_len(&in->vacuum_limit) +
2674 ctdb_uint32_len(&in->max_queue_depth_drop_msg) +
2675 ctdb_uint32_len(&in->allow_unhealthy_db_read) +
2676 ctdb_uint32_len(&in->stat_history_interval) +
2677 ctdb_uint32_len(&in->deferred_attach_timeout) +
2678 ctdb_uint32_len(&in->vacuum_fast_path_count) +
2679 ctdb_uint32_len(&in->lcp2_public_ip_assignment) +
2680 ctdb_uint32_len(&in->allow_client_db_attach) +
2681 ctdb_uint32_len(&in->recover_pdb_by_seqnum) +
2682 ctdb_uint32_len(&in->deferred_rebalance_on_node_add) +
2683 ctdb_uint32_len(&in->fetch_collapse) +
2684 ctdb_uint32_len(&in->hopcount_make_sticky) +
2685 ctdb_uint32_len(&in->sticky_duration) +
2686 ctdb_uint32_len(&in->sticky_pindown) +
2687 ctdb_uint32_len(&in->no_ip_takeover) +
2688 ctdb_uint32_len(&in->db_record_count_warn) +
2689 ctdb_uint32_len(&in->db_record_size_warn) +
2690 ctdb_uint32_len(&in->db_size_warn) +
2691 ctdb_uint32_len(&in->pulldb_preallocation_size) +
2692 ctdb_uint32_len(&in->no_ip_host_on_all_disabled) +
2693 ctdb_uint32_len(&in->samba3_hack) +
2694 ctdb_uint32_len(&in->mutex_enabled) +
2695 ctdb_uint32_len(&in->lock_processes_per_db) +
2696 ctdb_uint32_len(&in->rec_buffer_size_limit) +
2697 ctdb_uint32_len(&in->queue_buffer_size) +
2698 ctdb_uint32_len(&in->ip_alloc_algorithm) +
2699 ctdb_uint32_len(&in->allow_mixed_versions);
2702 void ctdb_tunable_list_push(struct ctdb_tunable_list *in, uint8_t *buf,
2703 size_t *npush)
2705 size_t offset = 0, np;
2707 ctdb_uint32_push(&in->max_redirect_count, buf+offset, &np);
2708 offset += np;
2710 ctdb_uint32_push(&in->seqnum_interval, buf+offset, &np);
2711 offset += np;
2713 ctdb_uint32_push(&in->control_timeout, buf+offset, &np);
2714 offset += np;
2716 ctdb_uint32_push(&in->traverse_timeout, buf+offset, &np);
2717 offset += np;
2719 ctdb_uint32_push(&in->keepalive_interval, buf+offset, &np);
2720 offset += np;
2722 ctdb_uint32_push(&in->keepalive_limit, buf+offset, &np);
2723 offset += np;
2725 ctdb_uint32_push(&in->recover_timeout, buf+offset, &np);
2726 offset += np;
2728 ctdb_uint32_push(&in->recover_interval, buf+offset, &np);
2729 offset += np;
2731 ctdb_uint32_push(&in->election_timeout, buf+offset, &np);
2732 offset += np;
2734 ctdb_uint32_push(&in->takeover_timeout, buf+offset, &np);
2735 offset += np;
2737 ctdb_uint32_push(&in->monitor_interval, buf+offset, &np);
2738 offset += np;
2740 ctdb_uint32_push(&in->tickle_update_interval, buf+offset, &np);
2741 offset += np;
2743 ctdb_uint32_push(&in->script_timeout, buf+offset, &np);
2744 offset += np;
2746 ctdb_uint32_push(&in->monitor_timeout_count, buf+offset, &np);
2747 offset += np;
2749 ctdb_uint32_push(&in->script_unhealthy_on_timeout, buf+offset, &np);
2750 offset += np;
2752 ctdb_uint32_push(&in->recovery_grace_period, buf+offset, &np);
2753 offset += np;
2755 ctdb_uint32_push(&in->recovery_ban_period, buf+offset, &np);
2756 offset += np;
2758 ctdb_uint32_push(&in->database_hash_size, buf+offset, &np);
2759 offset += np;
2761 ctdb_uint32_push(&in->database_max_dead, buf+offset, &np);
2762 offset += np;
2764 ctdb_uint32_push(&in->rerecovery_timeout, buf+offset, &np);
2765 offset += np;
2767 ctdb_uint32_push(&in->enable_bans, buf+offset, &np);
2768 offset += np;
2770 ctdb_uint32_push(&in->deterministic_public_ips, buf+offset, &np);
2771 offset += np;
2773 ctdb_uint32_push(&in->reclock_ping_period, buf+offset, &np);
2774 offset += np;
2776 ctdb_uint32_push(&in->no_ip_failback, buf+offset, &np);
2777 offset += np;
2779 ctdb_uint32_push(&in->disable_ip_failover, buf+offset, &np);
2780 offset += np;
2782 ctdb_uint32_push(&in->verbose_memory_names, buf+offset, &np);
2783 offset += np;
2785 ctdb_uint32_push(&in->recd_ping_timeout, buf+offset, &np);
2786 offset += np;
2788 ctdb_uint32_push(&in->recd_ping_failcount, buf+offset, &np);
2789 offset += np;
2791 ctdb_uint32_push(&in->log_latency_ms, buf+offset, &np);
2792 offset += np;
2794 ctdb_uint32_push(&in->reclock_latency_ms, buf+offset, &np);
2795 offset += np;
2797 ctdb_uint32_push(&in->recovery_drop_all_ips, buf+offset, &np);
2798 offset += np;
2800 ctdb_uint32_push(&in->verify_recovery_lock, buf+offset, &np);
2801 offset += np;
2803 ctdb_uint32_push(&in->vacuum_interval, buf+offset, &np);
2804 offset += np;
2806 ctdb_uint32_push(&in->vacuum_max_run_time, buf+offset, &np);
2807 offset += np;
2809 ctdb_uint32_push(&in->repack_limit, buf+offset, &np);
2810 offset += np;
2812 ctdb_uint32_push(&in->vacuum_limit, buf+offset, &np);
2813 offset += np;
2815 ctdb_uint32_push(&in->max_queue_depth_drop_msg, buf+offset, &np);
2816 offset += np;
2818 ctdb_uint32_push(&in->allow_unhealthy_db_read, buf+offset, &np);
2819 offset += np;
2821 ctdb_uint32_push(&in->stat_history_interval, buf+offset, &np);
2822 offset += np;
2824 ctdb_uint32_push(&in->deferred_attach_timeout, buf+offset, &np);
2825 offset += np;
2827 ctdb_uint32_push(&in->vacuum_fast_path_count, buf+offset, &np);
2828 offset += np;
2830 ctdb_uint32_push(&in->lcp2_public_ip_assignment, buf+offset, &np);
2831 offset += np;
2833 ctdb_uint32_push(&in->allow_client_db_attach, buf+offset, &np);
2834 offset += np;
2836 ctdb_uint32_push(&in->recover_pdb_by_seqnum, buf+offset, &np);
2837 offset += np;
2839 ctdb_uint32_push(&in->deferred_rebalance_on_node_add, buf+offset, &np);
2840 offset += np;
2842 ctdb_uint32_push(&in->fetch_collapse, buf+offset, &np);
2843 offset += np;
2845 ctdb_uint32_push(&in->hopcount_make_sticky, buf+offset, &np);
2846 offset += np;
2848 ctdb_uint32_push(&in->sticky_duration, buf+offset, &np);
2849 offset += np;
2851 ctdb_uint32_push(&in->sticky_pindown, buf+offset, &np);
2852 offset += np;
2854 ctdb_uint32_push(&in->no_ip_takeover, buf+offset, &np);
2855 offset += np;
2857 ctdb_uint32_push(&in->db_record_count_warn, buf+offset, &np);
2858 offset += np;
2860 ctdb_uint32_push(&in->db_record_size_warn, buf+offset, &np);
2861 offset += np;
2863 ctdb_uint32_push(&in->db_size_warn, buf+offset, &np);
2864 offset += np;
2866 ctdb_uint32_push(&in->pulldb_preallocation_size, buf+offset, &np);
2867 offset += np;
2869 ctdb_uint32_push(&in->no_ip_host_on_all_disabled, buf+offset, &np);
2870 offset += np;
2872 ctdb_uint32_push(&in->samba3_hack, buf+offset, &np);
2873 offset += np;
2875 ctdb_uint32_push(&in->mutex_enabled, buf+offset, &np);
2876 offset += np;
2878 ctdb_uint32_push(&in->lock_processes_per_db, buf+offset, &np);
2879 offset += np;
2881 ctdb_uint32_push(&in->rec_buffer_size_limit, buf+offset, &np);
2882 offset += np;
2884 ctdb_uint32_push(&in->queue_buffer_size, buf+offset, &np);
2885 offset += np;
2887 ctdb_uint32_push(&in->ip_alloc_algorithm, buf+offset, &np);
2888 offset += np;
2890 ctdb_uint32_push(&in->allow_mixed_versions, buf+offset, &np);
2891 offset += np;
2893 *npush = offset;
2896 static int ctdb_tunable_list_pull_elems(uint8_t *buf, size_t buflen,
2897 TALLOC_CTX *mem_ctx,
2898 struct ctdb_tunable_list *out,
2899 size_t *npull)
2901 size_t offset = 0, np;
2902 int ret;
2904 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2905 &out->max_redirect_count, &np);
2906 if (ret != 0) {
2907 return ret;
2909 offset += np;
2911 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2912 &out->seqnum_interval, &np);
2913 if (ret != 0) {
2914 return ret;
2916 offset += np;
2918 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2919 &out->control_timeout, &np);
2920 if (ret != 0) {
2921 return ret;
2923 offset += np;
2925 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2926 &out->traverse_timeout, &np);
2927 if (ret != 0) {
2928 return ret;
2930 offset += np;
2932 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2933 &out->keepalive_interval, &np);
2934 if (ret != 0) {
2935 return ret;
2937 offset += np;
2939 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2940 &out->keepalive_limit, &np);
2941 if (ret != 0) {
2942 return ret;
2944 offset += np;
2946 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2947 &out->recover_timeout, &np);
2948 if (ret != 0) {
2949 return ret;
2951 offset += np;
2953 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2954 &out->recover_interval, &np);
2955 if (ret != 0) {
2956 return ret;
2958 offset += np;
2960 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2961 &out->election_timeout, &np);
2962 if (ret != 0) {
2963 return ret;
2965 offset += np;
2967 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2968 &out->takeover_timeout, &np);
2969 if (ret != 0) {
2970 return ret;
2972 offset += np;
2974 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2975 &out->monitor_interval, &np);
2976 if (ret != 0) {
2977 return ret;
2979 offset += np;
2981 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2982 &out->tickle_update_interval, &np);
2983 if (ret != 0) {
2984 return ret;
2986 offset += np;
2988 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2989 &out->script_timeout, &np);
2990 if (ret != 0) {
2991 return ret;
2993 offset += np;
2995 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2996 &out->monitor_timeout_count, &np);
2997 if (ret != 0) {
2998 return ret;
3000 offset += np;
3002 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3003 &out->script_unhealthy_on_timeout, &np);
3004 if (ret != 0) {
3005 return ret;
3007 offset += np;
3009 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3010 &out->recovery_grace_period, &np);
3011 if (ret != 0) {
3012 return ret;
3014 offset += np;
3016 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3017 &out->recovery_ban_period, &np);
3018 if (ret != 0) {
3019 return ret;
3021 offset += np;
3023 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3024 &out->database_hash_size, &np);
3025 if (ret != 0) {
3026 return ret;
3028 offset += np;
3030 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3031 &out->database_max_dead, &np);
3032 if (ret != 0) {
3033 return ret;
3035 offset += np;
3037 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3038 &out->rerecovery_timeout, &np);
3039 if (ret != 0) {
3040 return ret;
3042 offset += np;
3044 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3045 &out->enable_bans, &np);
3046 if (ret != 0) {
3047 return ret;
3049 offset += np;
3051 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3052 &out->deterministic_public_ips, &np);
3053 if (ret != 0) {
3054 return ret;
3056 offset += np;
3058 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3059 &out->reclock_ping_period, &np);
3060 if (ret != 0) {
3061 return ret;
3063 offset += np;
3065 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3066 &out->no_ip_failback, &np);
3067 if (ret != 0) {
3068 return ret;
3070 offset += np;
3072 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3073 &out->disable_ip_failover, &np);
3074 if (ret != 0) {
3075 return ret;
3077 offset += np;
3079 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3080 &out->verbose_memory_names, &np);
3081 if (ret != 0) {
3082 return ret;
3084 offset += np;
3086 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3087 &out->recd_ping_timeout, &np);
3088 if (ret != 0) {
3089 return ret;
3091 offset += np;
3093 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3094 &out->recd_ping_failcount, &np);
3095 if (ret != 0) {
3096 return ret;
3098 offset += np;
3100 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3101 &out->log_latency_ms, &np);
3102 if (ret != 0) {
3103 return ret;
3105 offset += np;
3107 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3108 &out->reclock_latency_ms, &np);
3109 if (ret != 0) {
3110 return ret;
3112 offset += np;
3114 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3115 &out->recovery_drop_all_ips, &np);
3116 if (ret != 0) {
3117 return ret;
3119 offset += np;
3121 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3122 &out->verify_recovery_lock, &np);
3123 if (ret != 0) {
3124 return ret;
3126 offset += np;
3128 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3129 &out->vacuum_interval, &np);
3130 if (ret != 0) {
3131 return ret;
3133 offset += np;
3135 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3136 &out->vacuum_max_run_time, &np);
3137 if (ret != 0) {
3138 return ret;
3140 offset += np;
3142 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3143 &out->repack_limit, &np);
3144 if (ret != 0) {
3145 return ret;
3147 offset += np;
3149 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3150 &out->vacuum_limit, &np);
3151 if (ret != 0) {
3152 return ret;
3154 offset += np;
3156 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3157 &out->max_queue_depth_drop_msg, &np);
3158 if (ret != 0) {
3159 return ret;
3161 offset += np;
3163 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3164 &out->allow_unhealthy_db_read, &np);
3165 if (ret != 0) {
3166 return ret;
3168 offset += np;
3170 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3171 &out->stat_history_interval, &np);
3172 if (ret != 0) {
3173 return ret;
3175 offset += np;
3177 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3178 &out->deferred_attach_timeout, &np);
3179 if (ret != 0) {
3180 return ret;
3182 offset += np;
3184 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3185 &out->vacuum_fast_path_count, &np);
3186 if (ret != 0) {
3187 return ret;
3189 offset += np;
3191 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3192 &out->lcp2_public_ip_assignment, &np);
3193 if (ret != 0) {
3194 return ret;
3196 offset += np;
3198 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3199 &out->allow_client_db_attach, &np);
3200 if (ret != 0) {
3201 return ret;
3203 offset += np;
3205 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3206 &out->recover_pdb_by_seqnum, &np);
3207 if (ret != 0) {
3208 return ret;
3210 offset += np;
3212 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3213 &out->deferred_rebalance_on_node_add, &np);
3214 if (ret != 0) {
3215 return ret;
3217 offset += np;
3219 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3220 &out->fetch_collapse, &np);
3221 if (ret != 0) {
3222 return ret;
3224 offset += np;
3226 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3227 &out->hopcount_make_sticky, &np);
3228 if (ret != 0) {
3229 return ret;
3231 offset += np;
3233 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3234 &out->sticky_duration, &np);
3235 if (ret != 0) {
3236 return ret;
3238 offset += np;
3240 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3241 &out->sticky_pindown, &np);
3242 if (ret != 0) {
3243 return ret;
3245 offset += np;
3247 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3248 &out->no_ip_takeover, &np);
3249 if (ret != 0) {
3250 return ret;
3252 offset += np;
3254 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3255 &out->db_record_count_warn, &np);
3256 if (ret != 0) {
3257 return ret;
3259 offset += np;
3261 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3262 &out->db_record_size_warn, &np);
3263 if (ret != 0) {
3264 return ret;
3266 offset += np;
3268 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3269 &out->db_size_warn, &np);
3270 if (ret != 0) {
3271 return ret;
3273 offset += np;
3275 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3276 &out->pulldb_preallocation_size, &np);
3277 if (ret != 0) {
3278 return ret;
3280 offset += np;
3282 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3283 &out->no_ip_host_on_all_disabled, &np);
3284 if (ret != 0) {
3285 return ret;
3287 offset += np;
3289 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3290 &out->samba3_hack, &np);
3291 if (ret != 0) {
3292 return ret;
3294 offset += np;
3296 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3297 &out->mutex_enabled, &np);
3298 if (ret != 0) {
3299 return ret;
3301 offset += np;
3303 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3304 &out->lock_processes_per_db, &np);
3305 if (ret != 0) {
3306 return ret;
3308 offset += np;
3310 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3311 &out->rec_buffer_size_limit, &np);
3312 if (ret != 0) {
3313 return ret;
3315 offset += np;
3317 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3318 &out->queue_buffer_size, &np);
3319 if (ret != 0) {
3320 return ret;
3322 offset += np;
3324 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3325 &out->ip_alloc_algorithm, &np);
3326 if (ret != 0) {
3327 return ret;
3329 offset += np;
3331 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3332 &out->allow_mixed_versions, &np);
3333 if (ret != 0) {
3334 return ret;
3336 offset += np;
3338 *npull = offset;
3339 return 0;
3342 int ctdb_tunable_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3343 struct ctdb_tunable_list **out, size_t *npull)
3345 struct ctdb_tunable_list *val;
3346 size_t np;
3347 int ret;
3349 val = talloc(mem_ctx, struct ctdb_tunable_list);
3350 if (val == NULL) {
3351 return ENOMEM;
3354 ret = ctdb_tunable_list_pull_elems(buf, buflen, val, val, &np);
3355 if (ret != 0) {
3356 talloc_free(val);
3357 return ret;
3360 *out = val;
3361 *npull = np;
3362 return 0;
3365 size_t ctdb_tickle_list_len(struct ctdb_tickle_list *in)
3367 size_t len;
3369 len = ctdb_sock_addr_len(&in->addr) +
3370 ctdb_uint32_len(&in->num);
3371 if (in->num > 0) {
3372 len += in->num * ctdb_connection_len(&in->conn[0]);
3375 return len;
3378 void ctdb_tickle_list_push(struct ctdb_tickle_list *in, uint8_t *buf,
3379 size_t *npush)
3381 size_t offset = 0, np;
3382 uint32_t i;
3384 ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3385 offset += np;
3387 ctdb_uint32_push(&in->num, buf+offset, &np);
3388 offset += np;
3390 for (i=0; i<in->num; i++) {
3391 ctdb_connection_push(&in->conn[i], buf+offset, &np);
3392 offset += np;
3395 *npush = offset;
3398 int ctdb_tickle_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3399 struct ctdb_tickle_list **out, size_t *npull)
3401 struct ctdb_tickle_list *val;
3402 size_t offset = 0, np;
3403 uint32_t i;
3404 int ret;
3406 val = talloc(mem_ctx, struct ctdb_tickle_list);
3407 if (val == NULL) {
3408 return ENOMEM;
3411 ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, val,
3412 &val->addr, &np);
3413 if (ret != 0) {
3414 goto fail;
3416 offset += np;
3418 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
3419 if (ret != 0) {
3420 goto fail;
3422 offset += np;
3424 if (val->num == 0) {
3425 val->conn = NULL;
3426 goto done;
3429 val->conn = talloc_array(val, struct ctdb_connection, val->num);
3430 if (val->conn == NULL) {
3431 ret = ENOMEM;
3432 goto fail;
3435 for (i=0; i<val->num; i++) {
3436 ret = ctdb_connection_pull_elems(buf+offset, buflen-offset,
3437 val, &val->conn[i], &np);
3438 if (ret != 0) {
3439 goto fail;
3441 offset += np;
3444 done:
3445 *out = val;
3446 *npull = offset;
3447 return 0;
3449 fail:
3450 talloc_free(val);
3451 return ret;
3454 size_t ctdb_addr_info_len(struct ctdb_addr_info *in)
3456 return ctdb_sock_addr_len(&in->addr) +
3457 ctdb_uint32_len(&in->mask) +
3458 ctdb_stringn_len(&in->iface);
3461 void ctdb_addr_info_push(struct ctdb_addr_info *in, uint8_t *buf,
3462 size_t *npush)
3464 size_t offset = 0, np;
3466 ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3467 offset += np;
3469 ctdb_uint32_push(&in->mask, buf+offset, &np);
3470 offset += np;
3472 ctdb_stringn_push(&in->iface, buf+offset, &np);
3473 offset += np;
3475 *npush = offset;
3478 int ctdb_addr_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3479 struct ctdb_addr_info **out, size_t *npull)
3481 struct ctdb_addr_info *val;
3482 size_t offset = 0, np;
3483 int ret;
3485 val = talloc(mem_ctx, struct ctdb_addr_info);
3486 if (val == NULL) {
3487 return ENOMEM;
3490 ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, val,
3491 &val->addr, &np);
3492 if (ret != 0) {
3493 goto fail;
3495 offset += np;
3497 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->mask, &np);
3498 if (ret != 0) {
3499 goto fail;
3501 offset += np;
3503 ret = ctdb_stringn_pull(buf+offset, buflen-offset, val, &val->iface,
3504 &np);
3505 if (ret != 0) {
3506 goto fail;
3508 offset += np;
3510 *out = val;
3511 *npull = offset;
3512 return 0;
3514 fail:
3515 talloc_free(val);
3516 return ret;
3519 size_t ctdb_transdb_len(struct ctdb_transdb *in)
3521 return ctdb_uint32_len(&in->db_id) +
3522 ctdb_uint32_len(&in->tid);
3525 void ctdb_transdb_push(struct ctdb_transdb *in, uint8_t *buf, size_t *npush)
3527 size_t offset = 0, np;
3529 ctdb_uint32_push(&in->db_id, buf+offset, &np);
3530 offset += np;
3532 ctdb_uint32_push(&in->tid, buf+offset, &np);
3533 offset += np;
3535 *npush = offset;
3538 int ctdb_transdb_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3539 struct ctdb_transdb **out, size_t *npull)
3541 struct ctdb_transdb *val;
3542 size_t offset = 0, np;
3543 int ret;
3545 val = talloc(mem_ctx, struct ctdb_transdb);
3546 if (val == NULL) {
3547 return ENOMEM;
3550 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
3551 if (ret != 0) {
3552 goto fail;
3554 offset += np;
3556 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->tid, &np);
3557 if (ret != 0) {
3558 goto fail;
3560 offset += np;
3562 *out = val;
3563 *npull = offset;
3564 return 0;
3566 fail:
3567 talloc_free(val);
3568 return ret;
3571 size_t ctdb_uptime_len(struct ctdb_uptime *in)
3573 return ctdb_timeval_len(&in->current_time) +
3574 ctdb_timeval_len(&in->ctdbd_start_time) +
3575 ctdb_timeval_len(&in->last_recovery_started) +
3576 ctdb_timeval_len(&in->last_recovery_finished);
3579 void ctdb_uptime_push(struct ctdb_uptime *in, uint8_t *buf, size_t *npush)
3581 size_t offset = 0, np;
3583 ctdb_timeval_push(&in->current_time, buf+offset, &np);
3584 offset += np;
3586 ctdb_timeval_push(&in->ctdbd_start_time, buf+offset, &np);
3587 offset += np;
3589 ctdb_timeval_push(&in->last_recovery_started, buf+offset, &np);
3590 offset += np;
3592 ctdb_timeval_push(&in->last_recovery_finished, buf+offset, &np);
3593 offset += np;
3595 *npush = offset;
3598 int ctdb_uptime_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3599 struct ctdb_uptime **out, size_t *npull)
3601 struct ctdb_uptime *val;
3602 size_t offset = 0, np;
3603 int ret;
3605 val = talloc(mem_ctx, struct ctdb_uptime);
3606 if (val == NULL) {
3607 return ENOMEM;
3610 ret = ctdb_timeval_pull(buf+offset, buflen-offset, &val->current_time,
3611 &np);
3612 if (ret != 0) {
3613 goto fail;
3615 offset += np;
3617 ret = ctdb_timeval_pull(buf+offset, buflen-offset,
3618 &val->ctdbd_start_time, &np);
3619 if (ret != 0) {
3620 goto fail;
3622 offset += np;
3624 ret = ctdb_timeval_pull(buf+offset, buflen-offset,
3625 &val->last_recovery_started, &np);
3626 if (ret != 0) {
3627 goto fail;
3629 offset += np;
3631 ret = ctdb_timeval_pull(buf+offset, buflen-offset,
3632 &val->last_recovery_finished, &np);
3633 if (ret != 0) {
3634 goto fail;
3636 offset += np;
3638 *out = val;
3639 *npull = offset;
3640 return 0;
3642 fail:
3643 talloc_free(val);
3644 return ret;
3647 size_t ctdb_public_ip_len(struct ctdb_public_ip *in)
3649 return ctdb_uint32_len(&in->pnn) +
3650 ctdb_sock_addr_len(&in->addr);
3653 void ctdb_public_ip_push(struct ctdb_public_ip *in, uint8_t *buf,
3654 size_t *npush)
3656 size_t offset = 0, np;
3658 ctdb_uint32_push(&in->pnn, buf+offset, &np);
3659 offset += np;
3661 ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3662 offset += np;
3664 *npush = offset;
3667 static int ctdb_public_ip_pull_elems(uint8_t *buf, size_t buflen,
3668 TALLOC_CTX *mem_ctx,
3669 struct ctdb_public_ip *out, size_t *npull)
3671 size_t offset = 0, np;
3672 int ret;
3674 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->pnn, &np);
3675 if (ret != 0) {
3676 return ret;
3678 offset += np;
3680 ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, mem_ctx,
3681 &out->addr, &np);
3682 if (ret != 0) {
3683 return ret;
3685 offset += np;
3687 *npull = offset;
3688 return 0;
3691 int ctdb_public_ip_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3692 struct ctdb_public_ip **out, size_t *npull)
3694 struct ctdb_public_ip *val;
3695 size_t np;
3696 int ret;
3698 val = talloc(mem_ctx, struct ctdb_public_ip);
3699 if (val == NULL) {
3700 return ENOMEM;
3703 ret = ctdb_public_ip_pull_elems(buf, buflen, val, val, &np);
3704 if (ret != 0) {
3705 TALLOC_FREE(val);
3706 return ret;
3709 *out = val;
3710 *npull = np;
3711 return ret;
3714 size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *in)
3716 size_t len;
3718 len = ctdb_uint32_len(&in->num);
3719 if (in->num > 0) {
3720 len += in->num * ctdb_public_ip_len(&in->ip[0]);
3723 return len;
3726 void ctdb_public_ip_list_push(struct ctdb_public_ip_list *in, uint8_t *buf,
3727 size_t *npush)
3729 size_t offset = 0, np;
3730 uint32_t i;
3732 ctdb_uint32_push(&in->num, buf+offset, &np);
3733 offset += np;
3735 for (i=0; i<in->num; i++) {
3736 ctdb_public_ip_push(&in->ip[i], buf+offset, &np);
3737 offset += np;
3740 *npush = offset;
3743 int ctdb_public_ip_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3744 struct ctdb_public_ip_list **out, size_t *npull)
3746 struct ctdb_public_ip_list *val;
3747 size_t offset = 0, np;
3748 uint32_t i;
3749 int ret;
3751 val = talloc(mem_ctx, struct ctdb_public_ip_list);
3752 if (val == NULL) {
3753 return ENOMEM;
3756 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
3757 if (ret != 0) {
3758 goto fail;
3760 offset += np;
3762 if (val->num == 0) {
3763 val->ip = NULL;
3764 goto done;
3767 val->ip = talloc_array(val, struct ctdb_public_ip, val->num);
3768 if (val->ip == NULL) {
3769 ret = ENOMEM;
3770 goto fail;
3773 for (i=0; i<val->num; i++) {
3774 ret = ctdb_public_ip_pull_elems(buf+offset, buflen-offset,
3775 val->ip, &val->ip[i], &np);
3776 if (ret != 0) {
3777 goto fail;
3779 offset += np;
3782 done:
3783 *out = val;
3784 *npull = offset;
3785 return 0;
3787 fail:
3788 talloc_free(val);
3789 return ret;
3792 size_t ctdb_node_and_flags_len(struct ctdb_node_and_flags *in)
3794 return ctdb_uint32_len(&in->pnn) +
3795 ctdb_uint32_len(&in->flags) +
3796 ctdb_sock_addr_len(&in->addr);
3799 void ctdb_node_and_flags_push(struct ctdb_node_and_flags *in, uint8_t *buf,
3800 size_t *npush)
3802 size_t offset = 0, np;
3804 ctdb_uint32_push(&in->pnn, buf+offset, &np);
3805 offset += np;
3807 ctdb_uint32_push(&in->flags, buf+offset, &np);
3808 offset += np;
3810 ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3811 offset += np;
3813 *npush = offset;
3816 static int ctdb_node_and_flags_pull_elems(uint8_t *buf, size_t buflen,
3817 TALLOC_CTX *mem_ctx,
3818 struct ctdb_node_and_flags *out,
3819 size_t *npull)
3821 size_t offset = 0, np;
3822 int ret;
3824 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->pnn, &np);
3825 if (ret != 0) {
3826 return ret;
3828 offset += np;
3830 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->flags, &np);
3831 if (ret != 0) {
3832 return ret;
3834 offset += np;
3836 ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, mem_ctx,
3837 &out->addr, &np);
3838 if (ret != 0) {
3839 return ret;
3841 offset += np;
3843 *npull = offset;
3844 return 0;
3847 int ctdb_node_and_flags_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3848 struct ctdb_node_and_flags **out, size_t *npull)
3850 struct ctdb_node_and_flags *val;
3851 size_t np;
3852 int ret;
3854 val = talloc(mem_ctx, struct ctdb_node_and_flags);
3855 if (val == NULL) {
3856 return ENOMEM;
3859 ret = ctdb_node_and_flags_pull_elems(buf, buflen, val, val, &np);
3860 if (ret != 0) {
3861 TALLOC_FREE(val);
3862 return ret;
3865 *out = val;
3866 *npull = np;
3867 return ret;
3870 size_t ctdb_node_map_len(struct ctdb_node_map *in)
3872 size_t len;
3874 len = ctdb_uint32_len(&in->num);
3875 if (in->num > 0) {
3876 len += in->num * ctdb_node_and_flags_len(&in->node[0]);
3879 return len;
3882 void ctdb_node_map_push(struct ctdb_node_map *in, uint8_t *buf, size_t *npush)
3884 size_t offset = 0, np;
3885 uint32_t i;
3887 ctdb_uint32_push(&in->num, buf+offset, &np);
3888 offset += np;
3890 for (i=0; i<in->num; i++) {
3891 ctdb_node_and_flags_push(&in->node[i], buf+offset, &np);
3892 offset += np;
3895 *npush = offset;
3898 int ctdb_node_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3899 struct ctdb_node_map **out, size_t *npull)
3901 struct ctdb_node_map *val;
3902 size_t offset = 0, np;
3903 uint32_t i;
3904 int ret;
3906 val = talloc(mem_ctx, struct ctdb_node_map);
3907 if (val == NULL) {
3908 return ENOMEM;
3911 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
3912 if (ret != 0) {
3913 goto fail;
3915 offset += np;
3917 if (val->num == 0) {
3918 val->node = NULL;
3919 goto done;
3922 val->node = talloc_array(val, struct ctdb_node_and_flags, val->num);
3923 if (val->node == NULL) {
3924 ret = ENOMEM;
3925 goto fail;
3928 for (i=0; i<val->num; i++) {
3929 ret = ctdb_node_and_flags_pull_elems(buf+offset,
3930 buflen-offset,
3931 val->node, &val->node[i],
3932 &np);
3933 if (ret != 0) {
3934 goto fail;
3936 offset += np;
3939 done:
3940 *out = val;
3941 *npull = offset;
3942 return 0;
3944 fail:
3945 talloc_free(val);
3946 return ret;
3949 size_t ctdb_script_len(struct ctdb_script *in)
3951 return ctdb_chararray_len(in->name, MAX_SCRIPT_NAME+1) +
3952 ctdb_timeval_len(&in->start) +
3953 ctdb_timeval_len(&in->finished) +
3954 ctdb_int32_len(&in->status) +
3955 ctdb_chararray_len(in->output, MAX_SCRIPT_OUTPUT+1) +
3956 ctdb_padding_len(4);
3959 void ctdb_script_push(struct ctdb_script *in, uint8_t *buf, size_t *npush)
3961 size_t offset = 0, np;
3963 ctdb_chararray_push(in->name, MAX_SCRIPT_NAME+1, buf+offset, &np);
3964 offset += np;
3966 ctdb_timeval_push(&in->start, buf+offset, &np);
3967 offset += np;
3969 ctdb_timeval_push(&in->finished, buf+offset, &np);
3970 offset += np;
3972 ctdb_int32_push(&in->status, buf+offset, &np);
3973 offset += np;
3975 ctdb_chararray_push(in->output, MAX_SCRIPT_OUTPUT+1, buf+offset, &np);
3976 offset += np;
3978 ctdb_padding_push(4, buf+offset, &np);
3979 offset += np;
3981 *npush = offset;
3984 static int ctdb_script_pull_elems(uint8_t *buf, size_t buflen,
3985 TALLOC_CTX *mem_ctx,
3986 struct ctdb_script *out, size_t *npull)
3988 size_t offset = 0, np;
3989 int ret;
3991 ret = ctdb_chararray_pull(buf+offset, buflen-offset,
3992 out->name, MAX_SCRIPT_NAME+1, &np);
3993 if (ret != 0) {
3994 return ret;
3996 offset += np;
3998 ret = ctdb_timeval_pull(buf+offset, buflen-offset, &out->start, &np);
3999 if (ret != 0) {
4000 return ret;
4002 offset += np;
4004 ret = ctdb_timeval_pull(buf+offset, buflen-offset, &out->finished,
4005 &np);
4006 if (ret != 0) {
4007 return ret;
4009 offset += np;
4011 ret = ctdb_int32_pull(buf+offset, buflen-offset, &out->status, &np);
4012 if (ret != 0) {
4013 return ret;
4015 offset += np;
4017 ret = ctdb_chararray_pull(buf+offset, buflen-offset,
4018 out->output, MAX_SCRIPT_OUTPUT+1, &np);
4019 if (ret != 0) {
4020 return ret;
4022 offset += np;
4024 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4025 if (ret != 0) {
4026 return ret;
4028 offset += np;
4030 *npull = offset;
4031 return 0;
4034 int ctdb_script_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4035 struct ctdb_script **out, size_t *npull)
4037 struct ctdb_script *val;
4038 size_t np;
4039 int ret;
4041 val = talloc(mem_ctx, struct ctdb_script);
4042 if (val == NULL) {
4043 return ENOMEM;
4046 ret = ctdb_script_pull_elems(buf, buflen, val, val, &np);
4047 if (ret != 0) {
4048 TALLOC_FREE(val);
4049 return ret;
4052 *out = val;
4053 *npull = np;
4054 return ret;
4057 size_t ctdb_script_list_len(struct ctdb_script_list *in)
4059 size_t len;
4061 if (in == NULL) {
4062 return 0;
4065 len = ctdb_uint32_len(&in->num_scripts) + ctdb_padding_len(4);
4066 if (in->num_scripts > 0) {
4067 len += in->num_scripts * ctdb_script_len(&in->script[0]);
4070 return len;
4073 void ctdb_script_list_push(struct ctdb_script_list *in, uint8_t *buf,
4074 size_t *npush)
4076 size_t offset = 0, np;
4077 uint32_t i;
4079 if (in == NULL) {
4080 *npush = 0;
4081 return;
4084 ctdb_uint32_push(&in->num_scripts, buf+offset, &np);
4085 offset += np;
4087 ctdb_padding_push(4, buf+offset, &np);
4088 offset += np;
4090 for (i=0; i<in->num_scripts; i++) {
4091 ctdb_script_push(&in->script[i], buf+offset, &np);
4092 offset += np;
4095 *npush = offset;
4098 int ctdb_script_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4099 struct ctdb_script_list **out, size_t *npull)
4101 struct ctdb_script_list *val;
4102 size_t offset = 0, np;
4103 uint32_t i;
4104 int ret;
4106 /* If event scripts have never been run, the result will be NULL */
4107 if (buflen == 0) {
4108 val = NULL;
4109 goto done;
4112 val = talloc(mem_ctx, struct ctdb_script_list);
4113 if (val == NULL) {
4114 return ENOMEM;
4117 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num_scripts,
4118 &np);
4119 if (ret != 0) {
4120 goto fail;
4122 offset += np;
4124 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4125 if (ret != 0) {
4126 goto fail;
4128 offset += np;
4130 if (val->num_scripts == 0) {
4131 val->script = NULL;
4132 goto done;
4135 val->script = talloc_array(val, struct ctdb_script, val->num_scripts);
4136 if (val->script == NULL) {
4137 ret = ENOMEM;
4138 goto fail;
4141 for (i=0; i<val->num_scripts; i++) {
4142 ret = ctdb_script_pull_elems(buf+offset, buflen-offset,
4143 val, &val->script[i], &np);
4144 if (ret != 0) {
4145 goto fail;
4147 offset += np;
4150 done:
4151 *out = val;
4152 *npull = offset;
4153 return 0;
4155 fail:
4156 talloc_free(val);
4157 return ret;
4160 size_t ctdb_ban_state_len(struct ctdb_ban_state *in)
4162 return ctdb_uint32_len(&in->pnn) +
4163 ctdb_uint32_len(&in->time);
4166 void ctdb_ban_state_push(struct ctdb_ban_state *in, uint8_t *buf,
4167 size_t *npush)
4169 size_t offset = 0, np;
4171 ctdb_uint32_push(&in->pnn, buf+offset, &np);
4172 offset += np;
4174 ctdb_uint32_push(&in->time, buf+offset, &np);
4175 offset += np;
4177 *npush = offset;
4180 int ctdb_ban_state_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4181 struct ctdb_ban_state **out, size_t *npull)
4183 struct ctdb_ban_state *val;
4184 size_t offset = 0, np;
4185 int ret;
4187 val = talloc(mem_ctx, struct ctdb_ban_state);
4188 if (val == NULL) {
4189 return ENOMEM;
4192 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
4193 if (ret != 0) {
4194 goto fail;
4196 offset += np;
4198 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->time, &np);
4199 if (ret != 0) {
4200 goto fail;
4202 offset += np;
4204 *out = val;
4205 *npull = offset;
4206 return 0;
4208 fail:
4209 talloc_free(val);
4210 return ret;
4213 size_t ctdb_notify_data_len(struct ctdb_notify_data *in)
4215 return ctdb_uint64_len(&in->srvid) +
4216 ctdb_tdb_datan_len(&in->data);
4219 void ctdb_notify_data_push(struct ctdb_notify_data *in, uint8_t *buf,
4220 size_t *npush)
4222 size_t offset = 0, np;
4224 ctdb_uint64_push(&in->srvid, buf+offset, &np);
4225 offset += np;
4227 ctdb_tdb_datan_push(&in->data, buf+offset, &np);
4228 offset += np;
4230 *npush = offset;
4233 int ctdb_notify_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4234 struct ctdb_notify_data **out, size_t *npull)
4236 struct ctdb_notify_data *val;
4237 size_t offset = 0, np;
4238 int ret;
4240 val = talloc(mem_ctx, struct ctdb_notify_data);
4241 if (val == NULL) {
4242 return ENOMEM;
4245 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
4246 if (ret != 0) {
4247 goto fail;
4249 offset += np;
4251 ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, val, &val->data,
4252 &np);
4253 if (ret != 0) {
4254 goto fail;
4256 offset += np;
4258 *out = val;
4259 *npull = offset;
4260 return 0;
4262 fail:
4263 talloc_free(val);
4264 return ret;
4267 size_t ctdb_iface_len(struct ctdb_iface *in)
4269 return ctdb_chararray_len(in->name, CTDB_IFACE_SIZE+2) +
4270 ctdb_uint16_len(&in->link_state) +
4271 ctdb_uint32_len(&in->references);
4274 void ctdb_iface_push(struct ctdb_iface *in, uint8_t *buf, size_t *npush)
4276 size_t offset = 0, np;
4278 ctdb_chararray_push(in->name, CTDB_IFACE_SIZE+2, buf+offset, &np);
4279 offset += np;
4281 ctdb_uint16_push(&in->link_state, buf+offset, &np);
4282 offset += np;
4284 ctdb_uint32_push(&in->references, buf+offset, &np);
4285 offset += np;
4287 *npush = offset;
4290 static int ctdb_iface_pull_elems(uint8_t *buf, size_t buflen,
4291 TALLOC_CTX *mem_ctx,
4292 struct ctdb_iface *out, size_t *npull)
4294 size_t offset = 0, np;
4295 int ret;
4297 ret = ctdb_chararray_pull(buf+offset, buflen-offset,
4298 out->name, CTDB_IFACE_SIZE+2, &np);
4299 if (ret != 0) {
4300 return ret;
4302 offset += np;
4304 ret = ctdb_uint16_pull(buf+offset, buflen-offset, &out->link_state,
4305 &np);
4306 if (ret != 0) {
4307 return ret;
4309 offset += np;
4311 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->references,
4312 &np);
4313 if (ret != 0) {
4314 return ret;
4316 offset += np;
4318 *npull = offset;
4319 return 0;
4322 int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4323 struct ctdb_iface **out, size_t *npull)
4325 struct ctdb_iface *val;
4326 size_t np;
4327 int ret;
4329 val = talloc(mem_ctx, struct ctdb_iface);
4330 if (val == NULL) {
4331 return ENOMEM;
4334 ret = ctdb_iface_pull_elems(buf, buflen, val, val, &np);
4335 if (ret != 0) {
4336 talloc_free(val);
4337 return ret;
4340 *out = val;
4341 *npull = np;
4342 return ret;
4345 size_t ctdb_iface_list_len(struct ctdb_iface_list *in)
4347 size_t len;
4349 len = ctdb_uint32_len(&in->num);
4350 if (in->num > 0) {
4351 len += in->num * ctdb_iface_len(&in->iface[0]);
4354 return len;
4357 void ctdb_iface_list_push(struct ctdb_iface_list *in, uint8_t *buf,
4358 size_t *npush)
4360 size_t offset = 0, np;
4361 uint32_t i;
4363 ctdb_uint32_push(&in->num, buf+offset, &np);
4364 offset += np;
4366 for (i=0; i<in->num; i++) {
4367 ctdb_iface_push(&in->iface[i], buf+offset, &np);
4368 offset += np;
4371 *npush = offset;
4374 int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4375 struct ctdb_iface_list **out, size_t *npull)
4377 struct ctdb_iface_list *val;
4378 size_t offset = 0, np;
4379 uint32_t i;
4380 int ret;
4382 val = talloc(mem_ctx, struct ctdb_iface_list);
4383 if (val == NULL) {
4384 return ENOMEM;
4387 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
4388 if (ret != 0) {
4389 goto fail;
4391 offset += np;
4393 if (val->num == 0) {
4394 val->iface = NULL;
4395 goto done;
4398 val->iface = talloc_array(val, struct ctdb_iface, val->num);
4399 if (val->iface == NULL) {
4400 ret = ENOMEM;
4401 goto fail;
4404 for (i=0; i<val->num; i++) {
4405 ret = ctdb_iface_pull_elems(buf+offset, buflen-offset,
4406 val, &val->iface[i], &np);
4407 if (ret != 0) {
4408 goto fail;
4410 offset += np;
4413 done:
4414 *out = val;
4415 *npull = offset;
4416 return 0;
4418 fail:
4419 talloc_free(val);
4420 return ret;
4423 size_t ctdb_public_ip_info_len(struct ctdb_public_ip_info *in)
4425 return ctdb_public_ip_len(&in->ip) +
4426 ctdb_uint32_len(&in->active_idx) +
4427 ctdb_iface_list_len(in->ifaces);
4430 void ctdb_public_ip_info_push(struct ctdb_public_ip_info *in, uint8_t *buf,
4431 size_t *npush)
4433 size_t offset = 0, np;
4435 ctdb_public_ip_push(&in->ip, buf+offset, &np);
4436 offset += np;
4438 ctdb_uint32_push(&in->active_idx, buf+offset, &np);
4439 offset += np;
4441 ctdb_iface_list_push(in->ifaces, buf+offset, &np);
4442 offset += np;
4444 *npush = offset;
4447 int ctdb_public_ip_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4448 struct ctdb_public_ip_info **out, size_t *npull)
4450 struct ctdb_public_ip_info *val;
4451 size_t offset = 0, np;
4452 int ret;
4454 val = talloc(mem_ctx, struct ctdb_public_ip_info);
4455 if (val == NULL) {
4456 return ENOMEM;
4459 ret = ctdb_public_ip_pull_elems(buf+offset, buflen-offset, val,
4460 &val->ip, &np);
4461 if (ret != 0) {
4462 goto fail;
4464 offset += np;
4466 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->active_idx,
4467 &np);
4468 if (ret != 0) {
4469 goto fail;
4471 offset += np;
4473 ret = ctdb_iface_list_pull(buf+offset, buflen-offset, val,
4474 &val->ifaces, &np);
4475 if (ret != 0) {
4476 goto fail;
4478 offset += np;
4480 *out = val;
4481 *npull = offset;
4482 return 0;
4484 fail:
4485 talloc_free(val);
4486 return ret;
4489 size_t ctdb_key_data_len(struct ctdb_key_data *in)
4491 return ctdb_uint32_len(&in->db_id) +
4492 ctdb_padding_len(4) +
4493 ctdb_ltdb_header_len(&in->header) +
4494 ctdb_tdb_datan_len(&in->key);
4497 void ctdb_key_data_push(struct ctdb_key_data *in, uint8_t *buf, size_t *npush)
4499 size_t offset = 0, np;
4501 ctdb_uint32_push(&in->db_id, buf+offset, &np);
4502 offset += np;
4504 ctdb_padding_push(4, buf+offset, &np);
4505 offset += np;
4507 ctdb_ltdb_header_push(&in->header, buf+offset, &np);
4508 offset += np;
4510 ctdb_tdb_datan_push(&in->key, buf+offset, &np);
4511 offset += np;
4513 *npush = offset;
4516 int ctdb_key_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4517 struct ctdb_key_data **out, size_t *npull)
4519 struct ctdb_key_data *val;
4520 size_t offset = 0, np;
4521 int ret;
4523 val = talloc(mem_ctx, struct ctdb_key_data);
4524 if (val == NULL) {
4525 return ENOMEM;
4528 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
4529 if (ret != 0) {
4530 goto fail;
4532 offset += np;
4534 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4535 if (ret != 0) {
4536 goto fail;
4538 offset += np;
4540 ret = ctdb_ltdb_header_pull(buf+offset, buflen-offset, &val->header,
4541 &np);
4542 if (ret != 0) {
4543 goto fail;
4545 offset += np;
4547 ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, val, &val->key,
4548 &np);
4549 if (ret != 0) {
4550 goto fail;
4552 offset += np;
4554 *out = val;
4555 *npull = offset;
4556 return 0;
4558 fail:
4559 talloc_free(val);
4560 return ret;
4563 /* In the tdb_data structure marshalling, we are only interested in dsize.
4564 * The dptr value is ignored. The actual tdb_data blob is stored separately.
4566 * This is only required for ctdb_db_statistics and will be dropped in future.
4569 static size_t tdb_data_struct_len(TDB_DATA *data)
4571 return sizeof(void *) + sizeof(size_t);
4574 static void tdb_data_struct_push(TDB_DATA *data, uint8_t *buf, size_t *npush)
4576 size_t offset = 0;
4578 memcpy(buf+offset, &data->dptr, sizeof(void *));
4579 offset += sizeof(void *);
4581 memcpy(buf+offset, &data->dsize, sizeof(size_t));
4582 offset += sizeof(size_t);
4584 *npush = offset;
4587 static int tdb_data_struct_pull(uint8_t *buf, size_t buflen, TDB_DATA *data,
4588 size_t *npull)
4590 size_t offset = 0;
4591 void *ptr;
4593 if (buflen-offset < sizeof(void *)) {
4594 return EMSGSIZE;
4597 memcpy(&ptr, buf+offset, sizeof(void *));
4598 offset += sizeof(void *);
4599 data->dptr = NULL;
4601 if (buflen-offset < sizeof(size_t)) {
4602 return EMSGSIZE;
4605 memcpy(&data->dsize, buf+offset, sizeof(size_t));
4606 offset += sizeof(size_t);
4608 *npull = offset;
4609 return 0;
4612 size_t ctdb_db_statistics_len(struct ctdb_db_statistics *in)
4614 TDB_DATA data = { 0 };
4615 size_t len;
4616 uint32_t u32 = 0;
4617 int i;
4619 len = ctdb_uint32_len(&in->locks.num_calls) +
4620 ctdb_uint32_len(&in->locks.num_current) +
4621 ctdb_uint32_len(&in->locks.num_pending) +
4622 ctdb_uint32_len(&in->locks.num_failed) +
4623 ctdb_latency_counter_len(&in->locks.latency) +
4624 MAX_COUNT_BUCKETS *
4625 ctdb_uint32_len(&in->locks.buckets[0]) +
4626 ctdb_latency_counter_len(&in->vacuum.latency) +
4627 ctdb_uint32_len(&in->db_ro_delegations) +
4628 ctdb_uint32_len(&in->db_ro_revokes) +
4629 MAX_COUNT_BUCKETS *
4630 ctdb_uint32_len(&in->hop_count_bucket[0]) +
4631 ctdb_uint32_len(&in->num_hot_keys) +
4632 ctdb_padding_len(4) +
4633 MAX_HOT_KEYS *
4634 (ctdb_uint32_len(&u32) + ctdb_padding_len(4) +
4635 tdb_data_struct_len(&data));
4637 for (i=0; i<MAX_HOT_KEYS; i++) {
4638 len += ctdb_tdb_data_len(&in->hot_keys[i].key);
4641 return len;
4644 void ctdb_db_statistics_push(struct ctdb_db_statistics *in, uint8_t *buf,
4645 size_t *npush)
4647 size_t offset = 0, np;
4648 uint32_t num_hot_keys;
4649 int i;
4651 ctdb_uint32_push(&in->locks.num_calls, buf+offset, &np);
4652 offset += np;
4654 ctdb_uint32_push(&in->locks.num_current, buf+offset, &np);
4655 offset += np;
4657 ctdb_uint32_push(&in->locks.num_pending, buf+offset, &np);
4658 offset += np;
4660 ctdb_uint32_push(&in->locks.num_failed, buf+offset, &np);
4661 offset += np;
4663 ctdb_latency_counter_push(&in->locks.latency, buf+offset, &np);
4664 offset += np;
4666 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4667 ctdb_uint32_push(&in->locks.buckets[i], buf+offset, &np);
4668 offset += np;
4671 ctdb_latency_counter_push(&in->vacuum.latency, buf+offset, &np);
4672 offset += np;
4674 ctdb_uint32_push(&in->db_ro_delegations, buf+offset, &np);
4675 offset += np;
4677 ctdb_uint32_push(&in->db_ro_revokes, buf+offset, &np);
4678 offset += np;
4680 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4681 ctdb_uint32_push(&in->hop_count_bucket[i], buf+offset, &np);
4682 offset += np;
4685 num_hot_keys = MAX_HOT_KEYS;
4686 ctdb_uint32_push(&num_hot_keys, buf+offset, &np);
4687 offset += np;
4689 ctdb_padding_push(4, buf+offset, &np);
4690 offset += np;
4692 for (i=0; i<MAX_HOT_KEYS; i++) {
4693 ctdb_uint32_push(&in->hot_keys[i].count, buf+offset, &np);
4694 offset += np;
4696 ctdb_padding_push(4, buf+offset, &np);
4697 offset += np;
4699 tdb_data_struct_push(&in->hot_keys[i].key, buf+offset, &np);
4700 offset += np;
4703 for (i=0; i<MAX_HOT_KEYS; i++) {
4704 ctdb_tdb_data_push(&in->hot_keys[i].key, buf+offset, &np);
4705 offset += np;
4708 *npush = offset;
4711 static int ctdb_db_statistics_pull_elems(uint8_t *buf, size_t buflen,
4712 TALLOC_CTX *mem_ctx,
4713 struct ctdb_db_statistics *out,
4714 size_t *npull)
4716 size_t offset = 0, np;
4717 int ret, i;
4719 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4720 &out->locks.num_calls, &np);
4721 if (ret != 0) {
4722 return ret;
4724 offset += np;
4726 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4727 &out->locks.num_current, &np);
4728 if (ret != 0) {
4729 return ret;
4731 offset += np;
4733 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4734 &out->locks.num_pending, &np);
4735 if (ret != 0) {
4736 return ret;
4738 offset += np;
4740 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4741 &out->locks.num_failed, &np);
4742 if (ret != 0) {
4743 return ret;
4745 offset += np;
4747 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
4748 &out->locks.latency, &np);
4749 if (ret != 0) {
4750 return ret;
4752 offset += np;
4754 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4755 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4756 &out->locks.buckets[i], &np);
4757 if (ret != 0) {
4758 return ret;
4760 offset += np;
4763 ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
4764 &out->vacuum.latency, &np);
4765 if (ret != 0) {
4766 return ret;
4768 offset += np;
4770 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4771 &out->db_ro_delegations, &np);
4772 if (ret != 0) {
4773 return ret;
4775 offset += np;
4777 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4778 &out->db_ro_revokes, &np);
4779 if (ret != 0) {
4780 return ret;
4782 offset += np;
4784 for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4785 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4786 &out->hop_count_bucket[i], &np);
4787 if (ret != 0) {
4788 return ret;
4790 offset += np;
4793 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4794 &out->num_hot_keys, &np);
4795 if (ret != 0) {
4796 return ret;
4798 offset += np;
4800 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4801 if (ret != 0) {
4802 return ret;
4804 offset += np;
4806 for (i=0; i<MAX_HOT_KEYS; i++) {
4807 ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4808 &out->hot_keys[i].count, &np);
4809 if (ret != 0) {
4810 return ret;
4812 offset += np;
4814 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4815 if (ret != 0) {
4816 return ret;
4818 offset += np;
4820 ret = tdb_data_struct_pull(buf+offset, buflen-offset,
4821 &out->hot_keys[i].key, &np);
4822 if (ret != 0) {
4823 return ret;
4825 offset += np;
4828 for (i=0; i<MAX_HOT_KEYS; i++) {
4829 ret = ctdb_tdb_data_pull(buf+offset,
4830 out->hot_keys[i].key.dsize,
4831 out, &out->hot_keys[i].key, &np);
4832 if (ret != 0) {
4833 return ret;
4835 offset += np;
4838 *npull = offset;
4839 return 0;
4842 int ctdb_db_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4843 struct ctdb_db_statistics **out, size_t *npull)
4845 struct ctdb_db_statistics *val;
4846 size_t np;
4847 int ret;
4849 val = talloc(mem_ctx, struct ctdb_db_statistics);
4850 if (val == NULL) {
4851 return ENOMEM;
4854 ret = ctdb_db_statistics_pull_elems(buf, buflen, val, val, &np);
4855 if (ret != 0) {
4856 talloc_free(val);
4857 return ret;
4860 *out = val;
4861 *npull = np;
4862 return 0;
4865 size_t ctdb_pid_srvid_len(struct ctdb_pid_srvid *in)
4867 return ctdb_pid_len(&in->pid) +
4868 ctdb_uint64_len(&in->srvid);
4871 void ctdb_pid_srvid_push(struct ctdb_pid_srvid *in, uint8_t *buf,
4872 size_t *npush)
4874 size_t offset = 0, np;
4876 ctdb_pid_push(&in->pid, buf+offset, &np);
4877 offset += np;
4879 ctdb_uint64_push(&in->srvid, buf+offset, &np);
4880 offset += np;
4882 *npush = offset;
4885 int ctdb_pid_srvid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4886 struct ctdb_pid_srvid **out, size_t *npull)
4888 struct ctdb_pid_srvid *val;
4889 size_t offset = 0, np;
4890 int ret;
4892 val = talloc(mem_ctx, struct ctdb_pid_srvid);
4893 if (val == NULL) {
4894 return ENOMEM;
4897 ret = ctdb_pid_pull(buf+offset, buflen-offset, &val->pid, &np);
4898 if (ret != 0) {
4899 goto fail;
4901 offset += np;
4903 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
4904 if (ret != 0) {
4905 goto fail;
4907 offset += np;
4909 *out = val;
4910 *npull = offset;
4911 return 0;
4913 fail:
4914 talloc_free(val);
4915 return ret;
4918 size_t ctdb_election_message_len(struct ctdb_election_message *in)
4920 return ctdb_uint32_len(&in->num_connected) +
4921 ctdb_padding_len(4) +
4922 ctdb_timeval_len(&in->priority_time) +
4923 ctdb_uint32_len(&in->pnn) +
4924 ctdb_uint32_len(&in->node_flags);
4927 void ctdb_election_message_push(struct ctdb_election_message *in,
4928 uint8_t *buf, size_t *npush)
4930 size_t offset = 0, np;
4932 ctdb_uint32_push(&in->num_connected, buf+offset, &np);
4933 offset += np;
4935 ctdb_padding_push(4, buf+offset, &np);
4936 offset += np;
4938 ctdb_timeval_push(&in->priority_time, buf+offset, &np);
4939 offset += np;
4941 ctdb_uint32_push(&in->pnn, buf+offset, &np);
4942 offset += np;
4944 ctdb_uint32_push(&in->node_flags, buf+offset, &np);
4945 offset += np;
4947 *npush = offset;
4950 int ctdb_election_message_pull(uint8_t *buf, size_t buflen,
4951 TALLOC_CTX *mem_ctx,
4952 struct ctdb_election_message **out,
4953 size_t *npull)
4955 struct ctdb_election_message *val;
4956 size_t offset = 0, np;
4957 int ret;
4959 val = talloc(mem_ctx, struct ctdb_election_message);
4960 if (val == NULL) {
4961 return ENOMEM;
4964 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num_connected,
4965 &np);
4966 if (ret != 0) {
4967 goto fail;
4969 offset += np;
4971 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4972 if (ret != 0) {
4973 goto fail;
4975 offset += np;
4977 ret = ctdb_timeval_pull(buf+offset, buflen-offset,
4978 &val->priority_time, &np);
4979 if (ret != 0) {
4980 goto fail;
4982 offset += np;
4984 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
4985 if (ret != 0) {
4986 goto fail;
4988 offset += np;
4990 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->node_flags,
4991 &np);
4992 if (ret != 0) {
4993 goto fail;
4995 offset += np;
4997 *out = val;
4998 *npull = offset;
4999 return 0;
5001 fail:
5002 talloc_free(val);
5003 return ret;
5006 size_t ctdb_srvid_message_len(struct ctdb_srvid_message *in)
5008 return ctdb_uint32_len(&in->pnn) +
5009 ctdb_padding_len(4) +
5010 ctdb_uint64_len(&in->srvid);
5013 void ctdb_srvid_message_push(struct ctdb_srvid_message *in, uint8_t *buf,
5014 size_t *npush)
5016 size_t offset = 0, np;
5018 ctdb_uint32_push(&in->pnn, buf+offset, &np);
5019 offset += np;
5021 ctdb_padding_push(4, buf+offset, &np);
5022 offset += np;
5024 ctdb_uint64_push(&in->srvid, buf+offset, &np);
5025 offset += np;
5027 *npush = offset;
5030 int ctdb_srvid_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
5031 struct ctdb_srvid_message **out, size_t *npull)
5033 struct ctdb_srvid_message *val;
5034 size_t offset = 0, np;
5035 int ret;
5037 val = talloc(mem_ctx, struct ctdb_srvid_message);
5038 if (val == NULL) {
5039 return ENOMEM;
5042 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
5043 if (ret != 0) {
5044 goto fail;
5046 offset += np;
5048 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5049 if (ret != 0) {
5050 goto fail;
5052 offset += np;
5054 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
5055 if (ret != 0) {
5056 goto fail;
5058 offset += np;
5060 *out = val;
5061 *npull = offset;
5062 return 0;
5064 fail:
5065 talloc_free(val);
5066 return ret;
5069 size_t ctdb_disable_message_len(struct ctdb_disable_message *in)
5071 return ctdb_uint32_len(&in->pnn) +
5072 ctdb_padding_len(4) +
5073 ctdb_uint64_len(&in->srvid) +
5074 ctdb_uint32_len(&in->timeout) +
5075 ctdb_padding_len(4);
5078 void ctdb_disable_message_push(struct ctdb_disable_message *in, uint8_t *buf,
5079 size_t *npush)
5081 size_t offset = 0, np;
5083 ctdb_uint32_push(&in->pnn, buf+offset, &np);
5084 offset += np;
5086 ctdb_padding_push(4, buf+offset, &np);
5087 offset += np;
5089 ctdb_uint64_push(&in->srvid, buf+offset, &np);
5090 offset += np;
5092 ctdb_uint32_push(&in->timeout, buf+offset, &np);
5093 offset += np;
5095 ctdb_padding_push(4, buf+offset, &np);
5096 offset += np;
5098 *npush = offset;
5101 int ctdb_disable_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
5102 struct ctdb_disable_message **out,
5103 size_t *npull)
5105 struct ctdb_disable_message *val;
5106 size_t offset = 0, np;
5107 int ret;
5109 val = talloc(mem_ctx, struct ctdb_disable_message);
5110 if (val == NULL) {
5111 return ENOMEM;
5114 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
5115 if (ret != 0) {
5116 goto fail;
5118 offset += np;
5120 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5121 if (ret != 0) {
5122 goto fail;
5124 offset += np;
5126 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
5127 if (ret != 0) {
5128 goto fail;
5130 offset += np;
5132 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->timeout, &np);
5133 if (ret != 0) {
5134 goto fail;
5136 offset += np;
5138 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5139 if (ret != 0) {
5140 goto fail;
5142 offset += np;
5144 *out = val;
5145 *npull = offset;
5146 return 0;
5148 fail:
5149 talloc_free(val);
5150 return ret;
5153 size_t ctdb_server_id_len(struct ctdb_server_id *in)
5155 return ctdb_uint64_len(&in->pid) +
5156 ctdb_uint32_len(&in->task_id) +
5157 ctdb_uint32_len(&in->vnn) +
5158 ctdb_uint64_len(&in->unique_id);
5161 void ctdb_server_id_push(struct ctdb_server_id *in, uint8_t *buf,
5162 size_t *npush)
5164 size_t offset = 0, np;
5166 ctdb_uint64_push(&in->pid, buf+offset, &np);
5167 offset += np;
5169 ctdb_uint32_push(&in->task_id, buf+offset, &np);
5170 offset += np;
5172 ctdb_uint32_push(&in->vnn, buf+offset, &np);
5173 offset += np;
5175 ctdb_uint64_push(&in->unique_id, buf+offset, &np);
5176 offset += np;
5178 *npush = offset;
5181 int ctdb_server_id_pull(uint8_t *buf, size_t buflen,
5182 struct ctdb_server_id *out, size_t *npull)
5184 size_t offset = 0, np;
5185 int ret;
5187 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &out->pid, &np);
5188 if (ret != 0) {
5189 return ret;
5191 offset += np;
5193 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->task_id, &np);
5194 if (ret != 0) {
5195 return ret;
5197 offset += np;
5199 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->vnn, &np);
5200 if (ret != 0) {
5201 return ret;
5203 offset += np;
5205 ret = ctdb_uint64_pull(buf+offset, buflen-offset, &out->unique_id,
5206 &np);
5207 if (ret != 0) {
5208 return ret;
5210 offset += np;
5212 *npull = offset;
5213 return 0;
5216 size_t ctdb_g_lock_len(struct ctdb_g_lock *in)
5218 return ctdb_uint32_len(&in->type) +
5219 ctdb_padding_len(4) +
5220 ctdb_server_id_len(&in->sid);
5223 void ctdb_g_lock_push(struct ctdb_g_lock *in, uint8_t *buf, size_t *npush)
5225 size_t offset = 0, np;
5226 uint32_t type;
5228 type = in->type;
5229 ctdb_uint32_push(&type, buf+offset, &np);
5230 offset += np;
5232 ctdb_padding_push(4, buf+offset, &np);
5233 offset += np;
5235 ctdb_server_id_push(&in->sid, buf+offset, &np);
5236 offset += np;
5238 *npush = offset;
5241 int ctdb_g_lock_pull(uint8_t *buf, size_t buflen, struct ctdb_g_lock *out,
5242 size_t *npull)
5244 size_t offset = 0, np;
5245 int ret;
5246 uint32_t type;
5248 ret = ctdb_uint32_pull(buf+offset, buflen-offset, &type, &np);
5249 if (ret != 0) {
5250 return ret;
5252 offset += np;
5254 if (type == 0) {
5255 out->type = CTDB_G_LOCK_READ;
5256 } else if (type == 1) {
5257 out->type = CTDB_G_LOCK_WRITE;
5258 } else {
5259 return EPROTO;
5262 ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5263 if (ret != 0) {
5264 return ret;
5266 offset += np;
5268 ret = ctdb_server_id_pull(buf+offset, buflen-offset, &out->sid, &np);
5269 if (ret != 0) {
5270 return ret;
5272 offset += np;
5274 *npull = offset;
5275 return 0;
5278 size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *in)
5280 size_t len = 0;
5282 if (in->num > 0) {
5283 len += in->num * ctdb_g_lock_len(&in->lock[0]);
5286 return len;
5289 void ctdb_g_lock_list_push(struct ctdb_g_lock_list *in, uint8_t *buf,
5290 size_t *npush)
5292 size_t offset = 0, np;
5293 uint32_t i;
5295 for (i=0; i<in->num; i++) {
5296 ctdb_g_lock_push(&in->lock[i], buf+offset, &np);
5297 offset += np;
5300 *npush = offset;
5303 int ctdb_g_lock_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
5304 struct ctdb_g_lock_list **out, size_t *npull)
5306 struct ctdb_g_lock_list *val;
5307 struct ctdb_g_lock lock = { 0 };
5308 size_t offset = 0, np;
5309 uint32_t i;
5310 int ret;
5312 val = talloc(mem_ctx, struct ctdb_g_lock_list);
5313 if (val == NULL) {
5314 return ENOMEM;
5317 if (buflen == 0) {
5318 val->lock = NULL;
5319 val->num = 0;
5320 goto done;
5323 val->num = buflen / ctdb_g_lock_len(&lock);
5325 val->lock = talloc_array(val, struct ctdb_g_lock, val->num);
5326 if (val->lock == NULL) {
5327 ret = ENOMEM;
5328 goto fail;
5331 for (i=0; i<val->num; i++) {
5332 ret = ctdb_g_lock_pull(buf+offset, buflen-offset,
5333 &val->lock[i], &np);
5334 if (ret != 0) {
5335 goto fail;
5337 offset += np;
5340 done:
5341 *out = val;
5342 *npull = offset;
5343 return 0;
5345 fail:
5346 talloc_free(val);
5347 return ret;