tevent: avoid calling talloc_get_name(NULL) in tevent_req_default_print()
[Samba.git] / ctdb / protocol / protocol_types.c
blob4115e381c0b3468135a3e773a6371595d130f441
1 /*
2 CTDB protocol marshalling
4 Copyright (C) Amitay Isaacs 2015
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_int32_len(int32_t val)
32 return sizeof(int32_t);
35 void ctdb_int32_push(int32_t val, uint8_t *buf)
37 memcpy(buf, &val, sizeof(int32_t));
40 int ctdb_int32_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
41 int32_t *out)
43 if (buflen < sizeof(int32_t)) {
44 return EMSGSIZE;
47 *out = *(int32_t *)buf;
48 return 0;
51 size_t ctdb_uint32_len(uint32_t val)
53 return sizeof(uint32_t);
56 void ctdb_uint32_push(uint32_t val, uint8_t *buf)
58 memcpy(buf, &val, sizeof(uint32_t));
61 int ctdb_uint32_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
62 uint32_t *out)
64 if (buflen < sizeof(uint32_t)) {
65 return EMSGSIZE;
68 *out = *(uint32_t *)buf;
69 return 0;
72 size_t ctdb_uint64_len(uint64_t val)
74 return sizeof(uint64_t);
77 void ctdb_uint64_push(uint64_t val, uint8_t *buf)
79 memcpy(buf, &val, sizeof(uint64_t));
82 int ctdb_uint64_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
83 uint64_t *out)
85 if (buflen < sizeof(uint64_t)) {
86 return EMSGSIZE;
89 *out = *(uint64_t *)buf;
90 return 0;
93 size_t ctdb_double_len(double val)
95 return sizeof(double);
98 void ctdb_double_push(double val, uint8_t *buf)
100 memcpy(buf, &val, sizeof(double));
103 int ctdb_double_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
104 double *out)
106 if (buflen < sizeof(double)) {
107 return EMSGSIZE;
110 *out = *(double *)buf;
111 return 0;
114 size_t ctdb_uint8_array_len(struct ctdb_uint8_array *array)
116 return array->num * sizeof(uint8_t);
119 void ctdb_uint8_array_push(struct ctdb_uint8_array *array, uint8_t *buf)
121 if (array->num > 0) {
122 memcpy(buf, array->val, array->num * sizeof(uint8_t));
126 int ctdb_uint8_array_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
127 struct ctdb_uint8_array **out)
129 struct ctdb_uint8_array *array;
131 array = talloc(mem_ctx, struct ctdb_uint8_array);
132 if (array == NULL) {
133 return ENOMEM;
136 array->num = buflen / sizeof(uint8_t);
138 if (array->num > 0) {
139 array->val = talloc_array(array, uint8_t, array->num);
140 if (array->val == NULL) {
141 talloc_free(array);
142 return ENOMEM;
144 memcpy(array->val, buf, buflen);
145 } else {
146 array->val = NULL;
149 *out = array;
150 return 0;
153 size_t ctdb_uint64_array_len(struct ctdb_uint64_array *array)
155 return array->num * sizeof(uint64_t);
158 void ctdb_uint64_array_push(struct ctdb_uint64_array *array, uint8_t *buf)
160 if (array->num > 0) {
161 memcpy(buf, array->val, array->num * sizeof(uint64_t));
165 int ctdb_uint64_array_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
166 struct ctdb_uint64_array **out)
168 struct ctdb_uint64_array *array;
170 array = talloc(mem_ctx, struct ctdb_uint64_array);
171 if (array == NULL) {
172 return ENOMEM;
175 array->num = buflen / sizeof(uint64_t);
177 if (array->num > 0) {
178 array->val = talloc_array(array, uint64_t, array->num);
179 if (array->val == NULL) {
180 talloc_free(array);
181 return ENOMEM;
183 memcpy(array->val, buf, buflen);
184 } else {
185 array->val = NULL;
188 *out = array;
189 return 0;
192 size_t ctdb_pid_len(pid_t pid)
194 return sizeof(pid_t);
197 void ctdb_pid_push(pid_t pid, uint8_t *buf)
199 memcpy(buf, &pid, sizeof(pid_t));
202 int ctdb_pid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
203 pid_t *out)
205 if (buflen < sizeof(pid_t)) {
206 return EMSGSIZE;
209 *out = *(pid_t *)buf;
210 return 0;
213 size_t ctdb_string_len(const char *str)
215 if (str == NULL) {
216 return 0;
218 return strlen(str) + 1;
221 void ctdb_string_push(const char *str, uint8_t *buf)
223 if (str == NULL) {
224 return;
226 memcpy(buf, str, strlen(str)+1);
229 int ctdb_string_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
230 const char **out)
232 char *str;
234 if (buflen == 0) {
235 *out = NULL;
236 return 0;
239 str = talloc_strndup(mem_ctx, (char *)buf, buflen);
240 if (str == NULL) {
241 return ENOMEM;
244 *out = str;
245 return 0;
248 struct stringn_wire {
249 uint32_t length;
250 uint8_t str[1];
253 size_t ctdb_stringn_len(const char *str)
255 return sizeof(uint32_t) + ctdb_string_len(str);
258 void ctdb_stringn_push(const char *str, uint8_t *buf)
260 struct stringn_wire *wire = (struct stringn_wire *)buf;
262 wire->length = ctdb_string_len(str);
263 ctdb_string_push(str, wire->str);
266 int ctdb_stringn_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
267 const char **out)
269 char *str;
270 struct stringn_wire *wire = (struct stringn_wire *)buf;
272 if (buflen < sizeof(uint32_t)) {
273 return EMSGSIZE;
275 if (wire->length > buflen) {
276 return EMSGSIZE;
278 if (sizeof(uint32_t) + wire->length < sizeof(uint32_t)) {
279 return EMSGSIZE;
281 if (buflen < sizeof(uint32_t) + wire->length) {
282 return EMSGSIZE;
285 if (wire->length == 0) {
286 *out = NULL;
287 return 0;
290 str = talloc_strndup(mem_ctx, (char *)wire->str, wire->length);
291 if (str == NULL) {
292 return ENOMEM;
295 *out = str;
296 return 0;
299 size_t ctdb_statistics_len(struct ctdb_statistics *stats)
301 return sizeof(struct ctdb_statistics);
304 void ctdb_statistics_push(struct ctdb_statistics *stats, uint8_t *buf)
306 memcpy(buf, stats, sizeof(struct ctdb_statistics));
309 int ctdb_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
310 struct ctdb_statistics **out)
312 struct ctdb_statistics *stats;
313 struct ctdb_statistics *wire = (struct ctdb_statistics *)buf;
315 if (buflen < sizeof(struct ctdb_statistics)) {
316 return EMSGSIZE;
319 stats = talloc(mem_ctx, struct ctdb_statistics);
320 if (stats == NULL) {
321 return ENOMEM;
323 memcpy(stats, wire, sizeof(struct ctdb_statistics));
325 *out = stats;
326 return 0;
329 struct ctdb_statistics_list_wire {
330 uint32_t num;
331 struct ctdb_statistics stats[1];
334 size_t ctdb_statistics_list_len(struct ctdb_statistics_list *stats_list)
336 return offsetof(struct ctdb_statistics_list_wire, stats) +
337 stats_list->num * sizeof(struct ctdb_statistics);
340 void ctdb_statistics_list_push(struct ctdb_statistics_list *stats_list,
341 uint8_t *buf)
343 struct ctdb_statistics_list_wire *wire =
344 (struct ctdb_statistics_list_wire *)buf;
346 wire->num = stats_list->num;
347 memcpy(wire->stats, stats_list->stats,
348 stats_list->num * sizeof(struct ctdb_statistics));
351 int ctdb_statistics_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
352 struct ctdb_statistics_list **out)
354 struct ctdb_statistics_list *stats_list;
355 struct ctdb_statistics_list_wire *wire =
356 (struct ctdb_statistics_list_wire *)buf;
358 if (buflen < offsetof(struct ctdb_statistics_list_wire, stats)) {
359 return EMSGSIZE;
361 if (wire->num > buflen / sizeof(struct ctdb_statistics)) {
362 return EMSGSIZE;
364 if (offsetof(struct ctdb_statistics_list_wire, stats) +
365 wire->num * sizeof(struct ctdb_statistics) <
366 offsetof(struct ctdb_statistics_list_wire, stats)) {
367 return EMSGSIZE;
369 if (buflen < offsetof(struct ctdb_statistics_list_wire, stats) +
370 wire->num * sizeof(struct ctdb_statistics)) {
371 return EMSGSIZE;
374 stats_list = talloc(mem_ctx, struct ctdb_statistics_list);
375 if (stats_list == NULL) {
376 return ENOMEM;
379 stats_list->num = wire->num;
381 stats_list->stats = talloc_array(stats_list, struct ctdb_statistics,
382 wire->num);
383 if (stats_list->stats == NULL) {
384 talloc_free(stats_list);
385 return ENOMEM;
388 memcpy(stats_list->stats, wire->stats,
389 wire->num * sizeof(struct ctdb_statistics));
391 *out = stats_list;
392 return 0;
395 struct ctdb_vnn_map_wire {
396 uint32_t generation;
397 uint32_t size;
398 uint32_t map[1];
401 size_t ctdb_vnn_map_len(struct ctdb_vnn_map *vnnmap)
403 return offsetof(struct ctdb_vnn_map, map) +
404 vnnmap->size * sizeof(uint32_t);
407 void ctdb_vnn_map_push(struct ctdb_vnn_map *vnnmap, uint8_t *buf)
409 struct ctdb_vnn_map_wire *wire = (struct ctdb_vnn_map_wire *)buf;
411 memcpy(wire, vnnmap, offsetof(struct ctdb_vnn_map, map));
412 memcpy(wire->map, vnnmap->map, vnnmap->size * sizeof(uint32_t));
415 int ctdb_vnn_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
416 struct ctdb_vnn_map **out)
418 struct ctdb_vnn_map *vnnmap;
419 struct ctdb_vnn_map_wire *wire = (struct ctdb_vnn_map_wire *)buf;
421 if (buflen < offsetof(struct ctdb_vnn_map_wire, map)) {
422 return EMSGSIZE;
424 if (wire->size > buflen / sizeof(uint32_t)) {
425 return EMSGSIZE;
427 if (offsetof(struct ctdb_vnn_map_wire, map) +
428 wire->size * sizeof(uint32_t) <
429 offsetof(struct ctdb_vnn_map_wire, map)) {
430 return EMSGSIZE;
432 if (buflen < offsetof(struct ctdb_vnn_map_wire, map) +
433 wire->size * sizeof(uint32_t)) {
434 return EMSGSIZE;
437 vnnmap = talloc(mem_ctx, struct ctdb_vnn_map);
438 if (vnnmap == NULL) {
439 return ENOMEM;
442 memcpy(vnnmap, wire, offsetof(struct ctdb_vnn_map, map));
444 vnnmap->map = talloc_memdup(vnnmap, wire->map,
445 wire->size * sizeof(uint32_t));
446 if (vnnmap->map == NULL) {
447 talloc_free(vnnmap);
448 return ENOMEM;
451 *out = vnnmap;
452 return 0;
455 struct ctdb_dbid_map_wire {
456 uint32_t num;
457 struct ctdb_dbid dbs[1];
460 size_t ctdb_dbid_map_len(struct ctdb_dbid_map *dbmap)
462 return sizeof(uint32_t) + dbmap->num * sizeof(struct ctdb_dbid);
465 void ctdb_dbid_map_push(struct ctdb_dbid_map *dbmap, uint8_t *buf)
467 struct ctdb_dbid_map_wire *wire = (struct ctdb_dbid_map_wire *)buf;
469 wire->num = dbmap->num;
470 memcpy(wire->dbs, dbmap->dbs, dbmap->num * sizeof(struct ctdb_dbid));
473 int ctdb_dbid_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
474 struct ctdb_dbid_map **out)
476 struct ctdb_dbid_map *dbmap;
477 struct ctdb_dbid_map_wire *wire = (struct ctdb_dbid_map_wire *)buf;
479 if (buflen < sizeof(uint32_t)) {
480 return EMSGSIZE;
482 if (wire->num > buflen / sizeof(struct ctdb_dbid)) {
483 return EMSGSIZE;
485 if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_dbid) <
486 sizeof(uint32_t)) {
487 return EMSGSIZE;
489 if (buflen < sizeof(uint32_t) + wire->num * sizeof(struct ctdb_dbid)) {
490 return EMSGSIZE;
493 dbmap = talloc(mem_ctx, struct ctdb_dbid_map);
494 if (dbmap == NULL) {
495 return ENOMEM;
498 dbmap->num = wire->num;
500 dbmap->dbs = talloc_memdup(dbmap, wire->dbs,
501 wire->num * sizeof(struct ctdb_dbid));
502 if (dbmap->dbs == NULL) {
503 talloc_free(dbmap);
504 return ENOMEM;
507 *out = dbmap;
508 return 0;
511 size_t ctdb_pulldb_len(struct ctdb_pulldb *pulldb)
513 return sizeof(struct ctdb_pulldb);
516 void ctdb_pulldb_push(struct ctdb_pulldb *pulldb, uint8_t *buf)
518 memcpy(buf, pulldb, sizeof(struct ctdb_pulldb));
521 int ctdb_pulldb_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
522 struct ctdb_pulldb **out)
524 struct ctdb_pulldb *pulldb;
526 if (buflen < sizeof(struct ctdb_pulldb)) {
527 return EMSGSIZE;
530 pulldb = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_pulldb));
531 if (pulldb == NULL) {
532 return ENOMEM;
535 *out = pulldb;
536 return 0;
539 size_t ctdb_pulldb_ext_len(struct ctdb_pulldb_ext *pulldb)
541 return sizeof(struct ctdb_pulldb_ext);
544 void ctdb_pulldb_ext_push(struct ctdb_pulldb_ext *pulldb, uint8_t *buf)
546 memcpy(buf, pulldb, sizeof(struct ctdb_pulldb_ext));
549 int ctdb_pulldb_ext_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
550 struct ctdb_pulldb_ext **out)
552 struct ctdb_pulldb_ext *pulldb;
554 if (buflen < sizeof(struct ctdb_pulldb_ext)) {
555 return EMSGSIZE;
558 pulldb = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_pulldb_ext));
559 if (pulldb == NULL) {
560 return ENOMEM;
563 *out = pulldb;
564 return 0;
567 size_t ctdb_ltdb_header_len(struct ctdb_ltdb_header *header)
569 return sizeof(struct ctdb_ltdb_header);
572 void ctdb_ltdb_header_push(struct ctdb_ltdb_header *header, uint8_t *buf)
574 memcpy(buf, header, sizeof(struct ctdb_ltdb_header));
577 int ctdb_ltdb_header_pull(uint8_t *buf, size_t buflen,
578 struct ctdb_ltdb_header *header)
580 if (buflen < sizeof(struct ctdb_ltdb_header)) {
581 return EMSGSIZE;
584 memcpy(header, buf, sizeof(struct ctdb_ltdb_header));
585 return 0;
588 int ctdb_ltdb_header_extract(TDB_DATA *data, struct ctdb_ltdb_header *header)
590 int ret;
592 ret = ctdb_ltdb_header_pull(data->dptr, data->dsize, header);
593 if (ret != 0) {
594 return ret;
597 data->dptr += sizeof(struct ctdb_ltdb_header);
598 data->dsize -= sizeof(struct ctdb_ltdb_header);
600 return 0;
603 struct ctdb_rec_data_wire {
604 uint32_t length;
605 uint32_t reqid;
606 uint32_t keylen;
607 uint32_t datalen;
608 uint8_t data[1];
611 size_t ctdb_rec_data_len(struct ctdb_rec_data *rec)
613 return offsetof(struct ctdb_rec_data_wire, data) +
614 rec->key.dsize + rec->data.dsize +
615 (rec->header == NULL ? 0 : sizeof(struct ctdb_ltdb_header));
618 void ctdb_rec_data_push(struct ctdb_rec_data *rec, uint8_t *buf)
620 struct ctdb_rec_data_wire *wire = (struct ctdb_rec_data_wire *)buf;
621 size_t offset;
623 wire->length = ctdb_rec_data_len(rec);
624 wire->reqid = rec->reqid;
625 wire->keylen = rec->key.dsize;
626 wire->datalen = rec->data.dsize;
627 if (rec->header != NULL) {
628 wire->datalen += sizeof(struct ctdb_ltdb_header);
631 memcpy(wire->data, rec->key.dptr, rec->key.dsize);
632 offset = rec->key.dsize;
633 if (rec->header != NULL) {
634 memcpy(&wire->data[offset], rec->header,
635 sizeof(struct ctdb_ltdb_header));
636 offset += sizeof(struct ctdb_ltdb_header);
638 if (rec->data.dsize > 0) {
639 memcpy(&wire->data[offset], rec->data.dptr, rec->data.dsize);
643 static int ctdb_rec_data_pull_data(uint8_t *buf, size_t buflen,
644 uint32_t *reqid,
645 struct ctdb_ltdb_header **header,
646 TDB_DATA *key, TDB_DATA *data,
647 size_t *reclen)
649 struct ctdb_rec_data_wire *wire = (struct ctdb_rec_data_wire *)buf;
650 size_t offset;
652 if (buflen < offsetof(struct ctdb_rec_data_wire, data)) {
653 return EMSGSIZE;
655 if (wire->keylen > buflen || wire->datalen > buflen) {
656 return EMSGSIZE;
658 if (offsetof(struct ctdb_rec_data_wire, data) + wire->keylen <
659 offsetof(struct ctdb_rec_data_wire, data)) {
660 return EMSGSIZE;
662 if (offsetof(struct ctdb_rec_data_wire, data) +
663 wire->keylen + wire->datalen <
664 offsetof(struct ctdb_rec_data_wire, data)) {
665 return EMSGSIZE;
667 if (buflen < offsetof(struct ctdb_rec_data_wire, data) +
668 wire->keylen + wire->datalen) {
669 return EMSGSIZE;
672 *reqid = wire->reqid;
674 key->dsize = wire->keylen;
675 key->dptr = wire->data;
676 offset = wire->keylen;
678 /* Always set header to NULL. If it is required, exact it using
679 * ctdb_rec_data_extract_header()
681 *header = NULL;
683 data->dsize = wire->datalen;
684 data->dptr = &wire->data[offset];
686 *reclen = offsetof(struct ctdb_rec_data_wire, data) +
687 wire->keylen + wire->datalen;
689 return 0;
692 static int ctdb_rec_data_pull_elems(uint8_t *buf, size_t buflen,
693 TALLOC_CTX *mem_ctx,
694 struct ctdb_rec_data *out)
696 uint32_t reqid;
697 struct ctdb_ltdb_header *header;
698 TDB_DATA key, data;
699 size_t reclen;
700 int ret;
702 ret = ctdb_rec_data_pull_data(buf, buflen, &reqid, &header,
703 &key, &data, &reclen);
704 if (ret != 0) {
705 return ret;
708 out->reqid = reqid;
709 out->header = NULL;
711 out->key.dsize = key.dsize;
712 if (key.dsize > 0) {
713 out->key.dptr = talloc_memdup(mem_ctx, key.dptr, key.dsize);
714 if (out->key.dptr == NULL) {
715 return ENOMEM;
719 out->data.dsize = data.dsize;
720 if (data.dsize > 0) {
721 out->data.dptr = talloc_memdup(mem_ctx, data.dptr, data.dsize);
722 if (out->data.dptr == NULL) {
723 return ENOMEM;
727 return 0;
730 int ctdb_rec_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
731 struct ctdb_rec_data **out)
733 struct ctdb_rec_data *rec;
734 int ret;
736 rec = talloc(mem_ctx, struct ctdb_rec_data);
737 if (rec == NULL) {
738 return ENOMEM;
741 ret = ctdb_rec_data_pull_elems(buf, buflen, rec, rec);
742 if (ret != 0) {
743 TALLOC_FREE(rec);
746 *out = rec;
747 return ret;
750 struct ctdb_rec_buffer_wire {
751 uint32_t db_id;
752 uint32_t count;
753 uint8_t data[1];
756 size_t ctdb_rec_buffer_len(struct ctdb_rec_buffer *recbuf)
758 return offsetof(struct ctdb_rec_buffer_wire, data) + recbuf->buflen;
761 void ctdb_rec_buffer_push(struct ctdb_rec_buffer *recbuf, uint8_t *buf)
763 struct ctdb_rec_buffer_wire *wire = (struct ctdb_rec_buffer_wire *)buf;
765 wire->db_id = recbuf->db_id;
766 wire->count = recbuf->count;
767 if (recbuf->buflen > 0) {
768 memcpy(wire->data, recbuf->buf, recbuf->buflen);
772 int ctdb_rec_buffer_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
773 struct ctdb_rec_buffer **out)
775 struct ctdb_rec_buffer *recbuf;
776 struct ctdb_rec_buffer_wire *wire = (struct ctdb_rec_buffer_wire *)buf;
777 size_t offset;
779 if (buflen < offsetof(struct ctdb_rec_buffer_wire, data)) {
780 return EMSGSIZE;
783 recbuf = talloc(mem_ctx, struct ctdb_rec_buffer);
784 if (recbuf == NULL) {
785 return ENOMEM;
788 recbuf->db_id = wire->db_id;
789 recbuf->count = wire->count;
791 offset = offsetof(struct ctdb_rec_buffer_wire, data);
792 recbuf->buflen = buflen - offset;
793 recbuf->buf = talloc_memdup(recbuf, wire->data, recbuf->buflen);
794 if (recbuf->buf == NULL) {
795 talloc_free(recbuf);
796 return ENOMEM;
799 *out = recbuf;
800 return 0;
803 struct ctdb_rec_buffer *ctdb_rec_buffer_init(TALLOC_CTX *mem_ctx,
804 uint32_t db_id)
806 struct ctdb_rec_buffer *recbuf;
808 recbuf = talloc_zero(mem_ctx, struct ctdb_rec_buffer);
809 if (recbuf == NULL) {
810 return recbuf;
813 recbuf->db_id = db_id;
815 return recbuf;
818 int ctdb_rec_buffer_add(TALLOC_CTX *mem_ctx, struct ctdb_rec_buffer *recbuf,
819 uint32_t reqid, struct ctdb_ltdb_header *header,
820 TDB_DATA key, TDB_DATA data)
822 struct ctdb_rec_data recdata;
823 size_t len;
824 uint8_t *ptr;
826 recdata.reqid = reqid;
827 recdata.header = header;
828 recdata.key = key;
829 recdata.data = data;
831 len = ctdb_rec_data_len(&recdata);
833 ptr = talloc_realloc(mem_ctx, recbuf->buf, uint8_t,
834 recbuf->buflen + len);
835 if (ptr == NULL) {
836 return ENOMEM;
839 ctdb_rec_data_push(&recdata, &ptr[recbuf->buflen]);
841 recbuf->count++;
842 recbuf->buf = ptr;
843 recbuf->buflen += len;
844 return 0;
847 int ctdb_rec_buffer_traverse(struct ctdb_rec_buffer *recbuf,
848 ctdb_rec_parser_func_t func,
849 void *private_data)
851 struct ctdb_ltdb_header *header;
852 TDB_DATA key, data;
853 uint32_t reqid;
854 size_t offset, reclen;
855 int ret = 0, i;
857 offset = 0;
858 for (i=0; i<recbuf->count; i++) {
859 ret = ctdb_rec_data_pull_data(&recbuf->buf[offset],
860 recbuf->buflen - offset,
861 &reqid, &header,
862 &key, &data, &reclen);
863 if (ret != 0) {
864 return ret;
867 ret = func(reqid, header, key, data, private_data);
868 if (ret != 0) {
869 break;
872 offset += reclen;
875 return ret;
878 int ctdb_rec_buffer_write(struct ctdb_rec_buffer *recbuf, int fd)
880 ssize_t n;
882 n = write(fd, &recbuf->db_id, sizeof(uint32_t));
883 if (n == -1 || n != sizeof(uint32_t)) {
884 return (errno != 0 ? errno : EIO);
886 n = write(fd, &recbuf->count, sizeof(uint32_t));
887 if (n == -1 || n != sizeof(uint32_t)) {
888 return (errno != 0 ? errno : EIO);
890 n = write(fd, &recbuf->buflen, sizeof(size_t));
891 if (n == -1 || n != sizeof(size_t)) {
892 return (errno != 0 ? errno : EIO);
894 n = write(fd, recbuf->buf, recbuf->buflen);
895 if (n == -1 || n != recbuf->buflen) {
896 return (errno != 0 ? errno : EIO);
899 return 0;
902 int ctdb_rec_buffer_read(int fd, TALLOC_CTX *mem_ctx,
903 struct ctdb_rec_buffer **out)
905 struct ctdb_rec_buffer *recbuf;
906 ssize_t n;
908 recbuf = talloc(mem_ctx, struct ctdb_rec_buffer);
909 if (recbuf == NULL) {
910 return ENOMEM;
913 n = read(fd, &recbuf->db_id, sizeof(uint32_t));
914 if (n == -1 || n != sizeof(uint32_t)) {
915 return (errno != 0 ? errno : EIO);
917 n = read(fd, &recbuf->count, sizeof(uint32_t));
918 if (n == -1 || n != sizeof(uint32_t)) {
919 return (errno != 0 ? errno : EIO);
921 n = read(fd, &recbuf->buflen, sizeof(size_t));
922 if (n == -1 || n != sizeof(size_t)) {
923 return (errno != 0 ? errno : EIO);
926 recbuf->buf = talloc_size(recbuf, recbuf->buflen);
927 if (recbuf->buf == NULL) {
928 return ENOMEM;
931 n = read(fd, recbuf->buf, recbuf->buflen);
932 if (n == -1 || n != recbuf->buflen) {
933 return (errno != 0 ? errno : EIO);
936 *out = recbuf;
937 return 0;
940 size_t ctdb_traverse_start_len(struct ctdb_traverse_start *traverse)
942 return sizeof(struct ctdb_traverse_start);
945 void ctdb_traverse_start_push(struct ctdb_traverse_start *traverse,
946 uint8_t *buf)
948 memcpy(buf, traverse, sizeof(struct ctdb_traverse_start));
951 int ctdb_traverse_start_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
952 struct ctdb_traverse_start **out)
954 struct ctdb_traverse_start *traverse;
956 if (buflen < sizeof(struct ctdb_traverse_start)) {
957 return EMSGSIZE;
960 traverse = talloc_memdup(mem_ctx, buf,
961 sizeof(struct ctdb_traverse_start));
962 if (traverse == NULL) {
963 return ENOMEM;
966 *out = traverse;
967 return 0;
970 size_t ctdb_traverse_all_len(struct ctdb_traverse_all *traverse)
972 return sizeof(struct ctdb_traverse_all);
975 void ctdb_traverse_all_push(struct ctdb_traverse_all *traverse, uint8_t *buf)
977 memcpy(buf, traverse, sizeof(struct ctdb_traverse_all));
980 int ctdb_traverse_all_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
981 struct ctdb_traverse_all **out)
983 struct ctdb_traverse_all *traverse;
985 if (buflen < sizeof(struct ctdb_traverse_all)) {
986 return EMSGSIZE;
989 traverse = talloc_memdup(mem_ctx, buf,
990 sizeof(struct ctdb_traverse_all));
991 if (traverse == NULL) {
992 return ENOMEM;
995 *out = traverse;
996 return 0;
999 size_t ctdb_traverse_start_ext_len(struct ctdb_traverse_start_ext *traverse)
1001 return sizeof(struct ctdb_traverse_start_ext);
1004 void ctdb_traverse_start_ext_push(struct ctdb_traverse_start_ext *traverse,
1005 uint8_t *buf)
1007 memcpy(buf, traverse, sizeof(struct ctdb_traverse_start_ext));
1010 int ctdb_traverse_start_ext_pull(uint8_t *buf, size_t buflen,
1011 TALLOC_CTX *mem_ctx,
1012 struct ctdb_traverse_start_ext **out)
1014 struct ctdb_traverse_start_ext *traverse;
1016 if (buflen < sizeof(struct ctdb_traverse_start_ext)) {
1017 return EMSGSIZE;
1020 traverse = talloc_memdup(mem_ctx, buf,
1021 sizeof(struct ctdb_traverse_start_ext));
1022 if (traverse == NULL) {
1023 return ENOMEM;
1026 *out = traverse;
1027 return 0;
1030 size_t ctdb_traverse_all_ext_len(struct ctdb_traverse_all_ext *traverse)
1032 return sizeof(struct ctdb_traverse_all_ext);
1035 void ctdb_traverse_all_ext_push(struct ctdb_traverse_all_ext *traverse,
1036 uint8_t *buf)
1038 memcpy(buf, traverse, sizeof(struct ctdb_traverse_all_ext));
1041 int ctdb_traverse_all_ext_pull(uint8_t *buf, size_t buflen,
1042 TALLOC_CTX *mem_ctx,
1043 struct ctdb_traverse_all_ext **out)
1045 struct ctdb_traverse_all_ext *traverse;
1047 if (buflen < sizeof(struct ctdb_traverse_all_ext)) {
1048 return EMSGSIZE;
1051 traverse = talloc_memdup(mem_ctx, buf,
1052 sizeof(struct ctdb_traverse_all_ext));
1053 if (traverse == NULL) {
1054 return ENOMEM;
1057 *out = traverse;
1058 return 0;
1061 size_t ctdb_sock_addr_len(ctdb_sock_addr *addr)
1063 return sizeof(ctdb_sock_addr);
1066 void ctdb_sock_addr_push(ctdb_sock_addr *addr, uint8_t *buf)
1068 memcpy(buf, addr, sizeof(ctdb_sock_addr));
1071 static int ctdb_sock_addr_pull_elems(uint8_t *buf, size_t buflen,
1072 TALLOC_CTX *mem_ctx, ctdb_sock_addr *out)
1074 if (buflen < sizeof(ctdb_sock_addr)) {
1075 return EMSGSIZE;
1078 memcpy(out, buf, sizeof(ctdb_sock_addr));
1080 return 0;
1083 int ctdb_sock_addr_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1084 ctdb_sock_addr **out)
1086 ctdb_sock_addr *addr;
1087 int ret;
1089 addr = talloc(mem_ctx, ctdb_sock_addr);
1090 if (addr == NULL) {
1091 return false;
1094 ret = ctdb_sock_addr_pull_elems(buf, buflen, addr, addr);
1095 if (ret != 0) {
1096 TALLOC_FREE(addr);
1099 *out = addr;
1100 return ret;
1103 size_t ctdb_connection_len(struct ctdb_connection *conn)
1105 return sizeof(struct ctdb_connection);
1108 void ctdb_connection_push(struct ctdb_connection *conn, uint8_t *buf)
1110 memcpy(buf, conn, sizeof(struct ctdb_connection));
1113 static int ctdb_connection_pull_elems(uint8_t *buf, size_t buflen,
1114 TALLOC_CTX *mem_ctx,
1115 struct ctdb_connection *out)
1117 if (buflen < sizeof(struct ctdb_connection)) {
1118 return EMSGSIZE;
1121 memcpy(out, buf, sizeof(struct ctdb_connection));
1123 return 0;
1126 int ctdb_connection_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1127 struct ctdb_connection **out)
1129 struct ctdb_connection *conn;
1130 int ret;
1132 conn = talloc(mem_ctx, struct ctdb_connection);
1133 if (conn == NULL) {
1134 return ENOMEM;
1137 ret = ctdb_connection_pull_elems(buf, buflen, conn, conn);
1138 if (ret != 0) {
1139 TALLOC_FREE(conn);
1142 *out = conn;
1143 return ret;
1146 struct ctdb_tunable_wire {
1147 uint32_t value;
1148 uint32_t length;
1149 uint8_t name[1];
1152 size_t ctdb_tunable_len(struct ctdb_tunable *tunable)
1154 return offsetof(struct ctdb_tunable_wire, name) +
1155 strlen(tunable->name) + 1;
1158 void ctdb_tunable_push(struct ctdb_tunable *tunable, uint8_t *buf)
1160 struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf;
1162 wire->value = tunable->value;
1163 wire->length = strlen(tunable->name) + 1;
1164 memcpy(wire->name, tunable->name, wire->length);
1167 int ctdb_tunable_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1168 struct ctdb_tunable **out)
1170 struct ctdb_tunable *tunable;
1171 struct ctdb_tunable_wire *wire = (struct ctdb_tunable_wire *)buf;
1173 if (buflen < offsetof(struct ctdb_tunable_wire, name)) {
1174 return EMSGSIZE;
1176 if (wire->length > buflen) {
1177 return EMSGSIZE;
1179 if (offsetof(struct ctdb_tunable_wire, name) + wire->length <
1180 offsetof(struct ctdb_tunable_wire, name)) {
1181 return EMSGSIZE;
1183 if (buflen < offsetof(struct ctdb_tunable_wire, name) + wire->length) {
1184 return EMSGSIZE;
1187 tunable = talloc(mem_ctx, struct ctdb_tunable);
1188 if (tunable == NULL) {
1189 return ENOMEM;
1192 tunable->value = wire->value;
1193 tunable->name = talloc_memdup(tunable, wire->name, wire->length);
1194 if (tunable->name == NULL) {
1195 talloc_free(tunable);
1196 return ENOMEM;
1199 *out = tunable;
1200 return 0;
1203 size_t ctdb_node_flag_change_len(struct ctdb_node_flag_change *flag_change)
1205 return sizeof(struct ctdb_node_flag_change);
1208 void ctdb_node_flag_change_push(struct ctdb_node_flag_change *flag_change,
1209 uint8_t *buf)
1211 memcpy(buf, flag_change, sizeof(struct ctdb_node_flag_change));
1214 int ctdb_node_flag_change_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1215 struct ctdb_node_flag_change **out)
1217 struct ctdb_node_flag_change *flag_change;
1219 if (buflen < sizeof(struct ctdb_node_flag_change)) {
1220 return EMSGSIZE;
1223 flag_change = talloc_memdup(mem_ctx, buf,
1224 sizeof(struct ctdb_node_flag_change));
1225 if (flag_change == NULL) {
1226 return ENOMEM;
1229 *out = flag_change;
1230 return 0;
1233 struct ctdb_var_list_wire {
1234 uint32_t length;
1235 char list_str[1];
1238 size_t ctdb_var_list_len(struct ctdb_var_list *var_list)
1240 int i;
1241 size_t len = sizeof(uint32_t);
1243 for (i=0; i<var_list->count; i++) {
1244 len += strlen(var_list->var[i]) + 1;
1246 return len;
1249 void ctdb_var_list_push(struct ctdb_var_list *var_list, uint8_t *buf)
1251 struct ctdb_var_list_wire *wire = (struct ctdb_var_list_wire *)buf;
1252 int i, n;
1253 size_t offset = 0;
1255 if (var_list->count > 0) {
1256 n = sprintf(wire->list_str, "%s", var_list->var[0]);
1257 offset += n;
1259 for (i=1; i<var_list->count; i++) {
1260 n = sprintf(&wire->list_str[offset], ":%s", var_list->var[i]);
1261 offset += n;
1263 wire->length = offset + 1;
1266 int ctdb_var_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1267 struct ctdb_var_list **out)
1269 struct ctdb_var_list *var_list = NULL;
1270 struct ctdb_var_list_wire *wire = (struct ctdb_var_list_wire *)buf;
1271 char *str, *s, *tok, *ptr;
1272 const char **list;
1274 if (buflen < sizeof(uint32_t)) {
1275 return EMSGSIZE;
1277 if (wire->length > buflen) {
1278 return EMSGSIZE;
1280 if (sizeof(uint32_t) + wire->length < sizeof(uint32_t)) {
1281 return EMSGSIZE;
1283 if (buflen < sizeof(uint32_t) + wire->length) {
1284 return EMSGSIZE;
1287 str = talloc_strndup(mem_ctx, (char *)wire->list_str, wire->length);
1288 if (str == NULL) {
1289 return ENOMEM;
1292 var_list = talloc_zero(mem_ctx, struct ctdb_var_list);
1293 if (var_list == NULL) {
1294 goto fail;
1297 s = str;
1298 while ((tok = strtok_r(s, ":", &ptr)) != NULL) {
1299 s = NULL;
1300 list = talloc_realloc(var_list, var_list->var, const char *,
1301 var_list->count+1);
1302 if (list == NULL) {
1303 goto fail;
1306 var_list->var = list;
1307 var_list->var[var_list->count] = talloc_strdup(var_list, tok);
1308 if (var_list->var[var_list->count] == NULL) {
1309 goto fail;
1311 var_list->count++;
1314 talloc_free(str);
1315 *out = var_list;
1316 return 0;
1318 fail:
1319 talloc_free(str);
1320 talloc_free(var_list);
1321 return ENOMEM;
1324 size_t ctdb_tunable_list_len(struct ctdb_tunable_list *tun_list)
1326 return sizeof(struct ctdb_tunable_list);
1329 void ctdb_tunable_list_push(struct ctdb_tunable_list *tun_list, uint8_t *buf)
1331 memcpy(buf, tun_list, sizeof(struct ctdb_tunable_list));
1334 int ctdb_tunable_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1335 struct ctdb_tunable_list **out)
1337 struct ctdb_tunable_list *tun_list;
1339 if (buflen < sizeof(struct ctdb_tunable_list)) {
1340 return EMSGSIZE;
1343 tun_list = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_tunable_list));
1344 if (tun_list == NULL) {
1345 return ENOMEM;
1348 *out = tun_list;
1349 return 0;
1352 struct ctdb_tickle_list_wire {
1353 ctdb_sock_addr addr;
1354 uint32_t num;
1355 struct ctdb_connection conn[1];
1358 size_t ctdb_tickle_list_len(struct ctdb_tickle_list *tickles)
1360 return offsetof(struct ctdb_tickle_list, conn) +
1361 tickles->num * sizeof(struct ctdb_connection);
1364 void ctdb_tickle_list_push(struct ctdb_tickle_list *tickles, uint8_t *buf)
1366 struct ctdb_tickle_list_wire *wire =
1367 (struct ctdb_tickle_list_wire *)buf;
1368 size_t offset;
1369 int i;
1371 memcpy(&wire->addr, &tickles->addr, sizeof(ctdb_sock_addr));
1372 wire->num = tickles->num;
1374 offset = offsetof(struct ctdb_tickle_list_wire, conn);
1375 for (i=0; i<tickles->num; i++) {
1376 ctdb_connection_push(&tickles->conn[i], &buf[offset]);
1377 offset += ctdb_connection_len(&tickles->conn[i]);
1381 int ctdb_tickle_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1382 struct ctdb_tickle_list **out)
1384 struct ctdb_tickle_list *tickles;
1385 struct ctdb_tickle_list_wire *wire =
1386 (struct ctdb_tickle_list_wire *)buf;
1387 size_t offset;
1388 int i, ret;
1390 if (buflen < offsetof(struct ctdb_tickle_list_wire, conn)) {
1391 return EMSGSIZE;
1393 if (wire->num > buflen / sizeof(struct ctdb_connection)) {
1394 return EMSGSIZE;
1396 if (offsetof(struct ctdb_tickle_list_wire, conn) +
1397 wire->num * sizeof(struct ctdb_connection) <
1398 offsetof(struct ctdb_tickle_list_wire, conn)) {
1399 return EMSGSIZE;
1401 if (buflen < offsetof(struct ctdb_tickle_list_wire, conn) +
1402 wire->num * sizeof(struct ctdb_connection)) {
1403 return EMSGSIZE;
1406 tickles = talloc(mem_ctx, struct ctdb_tickle_list);
1407 if (tickles == NULL) {
1408 return ENOMEM;
1411 offset = offsetof(struct ctdb_tickle_list, conn);
1412 memcpy(tickles, wire, offset);
1414 tickles->conn = talloc_array(tickles, struct ctdb_connection,
1415 wire->num);
1416 if (tickles->conn == NULL) {
1417 talloc_free(tickles);
1418 return ENOMEM;
1421 for (i=0; i<wire->num; i++) {
1422 ret = ctdb_connection_pull_elems(&buf[offset], buflen-offset,
1423 tickles->conn,
1424 &tickles->conn[i]);
1425 if (ret != 0) {
1426 talloc_free(tickles);
1427 return ret;
1429 offset += ctdb_connection_len(&tickles->conn[i]);
1432 *out = tickles;
1433 return 0;
1436 struct ctdb_addr_info_wire {
1437 ctdb_sock_addr addr;
1438 uint32_t mask;
1439 uint32_t len;
1440 char iface[1];
1443 size_t ctdb_addr_info_len(struct ctdb_addr_info *arp)
1445 uint32_t len;
1447 len = offsetof(struct ctdb_addr_info_wire, iface);
1448 if (arp->iface != NULL) {
1449 len += strlen(arp->iface)+1;
1452 return len;
1455 void ctdb_addr_info_push(struct ctdb_addr_info *addr_info, uint8_t *buf)
1457 struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
1459 wire->addr = addr_info->addr;
1460 wire->mask = addr_info->mask;
1461 if (addr_info->iface == NULL) {
1462 wire->len = 0;
1463 } else {
1464 wire->len = strlen(addr_info->iface)+1;
1465 memcpy(wire->iface, addr_info->iface, wire->len);
1469 int ctdb_addr_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1470 struct ctdb_addr_info **out)
1472 struct ctdb_addr_info *addr_info;
1473 struct ctdb_addr_info_wire *wire = (struct ctdb_addr_info_wire *)buf;
1475 if (buflen < offsetof(struct ctdb_addr_info_wire, iface)) {
1476 return EMSGSIZE;
1478 if (wire->len > buflen) {
1479 return EMSGSIZE;
1481 if (offsetof(struct ctdb_addr_info_wire, iface) + wire->len <
1482 offsetof(struct ctdb_addr_info_wire, iface)) {
1483 return EMSGSIZE;
1485 if (buflen < offsetof(struct ctdb_addr_info_wire, iface) + wire->len) {
1486 return EMSGSIZE;
1489 addr_info = talloc(mem_ctx, struct ctdb_addr_info);
1490 if (addr_info == NULL) {
1491 return ENOMEM;
1494 addr_info->addr = wire->addr;
1495 addr_info->mask = wire->mask;
1497 if (wire->len == 0) {
1498 addr_info->iface = NULL;
1499 } else {
1500 addr_info->iface = talloc_strndup(addr_info, wire->iface,
1501 wire->len);
1502 if (addr_info->iface == NULL) {
1503 talloc_free(addr_info);
1504 return ENOMEM;
1508 *out = addr_info;
1509 return 0;
1512 size_t ctdb_transdb_len(struct ctdb_transdb *transdb)
1514 return sizeof(struct ctdb_transdb);
1517 void ctdb_transdb_push(struct ctdb_transdb *transdb, uint8_t *buf)
1519 memcpy(buf, transdb, sizeof(struct ctdb_transdb));
1522 int ctdb_transdb_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1523 struct ctdb_transdb **out)
1525 struct ctdb_transdb *transdb;
1527 if (buflen < sizeof(struct ctdb_transdb)) {
1528 return EMSGSIZE;
1531 transdb = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_transdb));
1532 if (transdb == NULL) {
1533 return ENOMEM;
1536 *out = transdb;
1537 return 0;
1540 size_t ctdb_uptime_len(struct ctdb_uptime *uptime)
1542 return sizeof(struct ctdb_uptime);
1545 void ctdb_uptime_push(struct ctdb_uptime *uptime, uint8_t *buf)
1547 memcpy(buf, uptime, sizeof(struct ctdb_uptime));
1550 int ctdb_uptime_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1551 struct ctdb_uptime **out)
1553 struct ctdb_uptime *uptime;
1555 if (buflen < sizeof(struct ctdb_uptime)) {
1556 return EMSGSIZE;
1559 uptime = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_uptime));
1560 if (uptime == NULL) {
1561 return ENOMEM;
1564 *out = uptime;
1565 return 0;
1568 size_t ctdb_public_ip_len(struct ctdb_public_ip *pubip)
1570 return sizeof(struct ctdb_public_ip);
1573 void ctdb_public_ip_push(struct ctdb_public_ip *pubip, uint8_t *buf)
1575 memcpy(buf, pubip, sizeof(struct ctdb_public_ip));
1578 static int ctdb_public_ip_pull_elems(uint8_t *buf, size_t buflen,
1579 TALLOC_CTX *mem_ctx,
1580 struct ctdb_public_ip *out)
1582 if (buflen < sizeof(struct ctdb_public_ip)) {
1583 return EMSGSIZE;
1586 memcpy(out, buf, sizeof(struct ctdb_public_ip));
1588 return 0;
1591 int ctdb_public_ip_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1592 struct ctdb_public_ip **out)
1594 struct ctdb_public_ip *pubip;
1595 int ret;
1597 pubip = talloc(mem_ctx, struct ctdb_public_ip);
1598 if (pubip == NULL) {
1599 return ENOMEM;
1602 ret = ctdb_public_ip_pull_elems(buf, buflen, pubip, pubip);
1603 if (ret != 0) {
1604 TALLOC_FREE(pubip);
1607 *out = pubip;
1608 return ret;
1611 struct ctdb_public_ip_list_wire {
1612 uint32_t num;
1613 struct ctdb_public_ip ip[1];
1616 size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *pubip_list)
1618 int i;
1619 size_t len;
1621 len = sizeof(uint32_t);
1622 for (i=0; i<pubip_list->num; i++) {
1623 len += ctdb_public_ip_len(&pubip_list->ip[i]);
1625 return len;
1628 void ctdb_public_ip_list_push(struct ctdb_public_ip_list *pubip_list,
1629 uint8_t *buf)
1631 struct ctdb_public_ip_list_wire *wire =
1632 (struct ctdb_public_ip_list_wire *)buf;
1633 size_t offset;
1634 int i;
1636 wire->num = pubip_list->num;
1638 offset = offsetof(struct ctdb_public_ip_list_wire, ip);
1639 for (i=0; i<pubip_list->num; i++) {
1640 ctdb_public_ip_push(&pubip_list->ip[i], &buf[offset]);
1641 offset += ctdb_public_ip_len(&pubip_list->ip[i]);
1645 int ctdb_public_ip_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1646 struct ctdb_public_ip_list **out)
1648 struct ctdb_public_ip_list *pubip_list;
1649 struct ctdb_public_ip_list_wire *wire =
1650 (struct ctdb_public_ip_list_wire *)buf;
1651 size_t offset;
1652 int i;
1653 bool ret;
1655 if (buflen < sizeof(uint32_t)) {
1656 return EMSGSIZE;
1658 if (wire->num > buflen / sizeof(struct ctdb_public_ip)) {
1659 return EMSGSIZE;
1661 if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_public_ip) <
1662 sizeof(uint32_t)) {
1663 return EMSGSIZE;
1665 if (buflen < sizeof(uint32_t) +
1666 wire->num * sizeof(struct ctdb_public_ip)) {
1667 return EMSGSIZE;
1670 pubip_list = talloc(mem_ctx, struct ctdb_public_ip_list);
1671 if (pubip_list == NULL) {
1672 return ENOMEM;
1675 pubip_list->num = wire->num;
1676 if (wire->num == 0) {
1677 pubip_list->ip = NULL;
1678 *out = pubip_list;
1679 return 0;
1681 pubip_list->ip = talloc_array(pubip_list, struct ctdb_public_ip,
1682 wire->num);
1683 if (pubip_list->ip == NULL) {
1684 talloc_free(pubip_list);
1685 return ENOMEM;
1688 offset = offsetof(struct ctdb_public_ip_list_wire, ip);
1689 for (i=0; i<wire->num; i++) {
1690 ret = ctdb_public_ip_pull_elems(&buf[offset], buflen-offset,
1691 pubip_list->ip,
1692 &pubip_list->ip[i]);
1693 if (ret != 0) {
1694 talloc_free(pubip_list);
1695 return ret;
1697 offset += ctdb_public_ip_len(&pubip_list->ip[i]);
1700 *out = pubip_list;
1701 return 0;
1704 size_t ctdb_node_and_flags_len(struct ctdb_node_and_flags *node)
1706 return sizeof(struct ctdb_node_and_flags);
1709 void ctdb_node_and_flags_push(struct ctdb_node_and_flags *node, uint8_t *buf)
1711 memcpy(buf, node, sizeof(struct ctdb_node_and_flags));
1714 static int ctdb_node_and_flags_pull_elems(TALLOC_CTX *mem_ctx,
1715 uint8_t *buf, size_t buflen,
1716 struct ctdb_node_and_flags *out)
1718 if (buflen < sizeof(struct ctdb_node_and_flags)) {
1719 return EMSGSIZE;
1722 memcpy(out, buf, sizeof(struct ctdb_node_and_flags));
1724 return 0;
1727 int ctdb_node_and_flags_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1728 struct ctdb_node_and_flags **out)
1730 struct ctdb_node_and_flags *node;
1731 int ret;
1733 node = talloc(mem_ctx, struct ctdb_node_and_flags);
1734 if (node == NULL) {
1735 return ENOMEM;
1738 ret = ctdb_node_and_flags_pull_elems(node, buf, buflen, node);
1739 if (ret != 0) {
1740 TALLOC_FREE(node);
1743 *out = node;
1744 return ret;
1747 struct ctdb_node_map_wire {
1748 uint32_t num;
1749 struct ctdb_node_and_flags node[1];
1752 size_t ctdb_node_map_len(struct ctdb_node_map *nodemap)
1754 return sizeof(uint32_t) +
1755 nodemap->num * sizeof(struct ctdb_node_and_flags);
1758 void ctdb_node_map_push(struct ctdb_node_map *nodemap, uint8_t *buf)
1760 struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
1761 size_t offset;
1762 int i;
1764 wire->num = nodemap->num;
1766 offset = offsetof(struct ctdb_node_map_wire, node);
1767 for (i=0; i<nodemap->num; i++) {
1768 ctdb_node_and_flags_push(&nodemap->node[i], &buf[offset]);
1769 offset += ctdb_node_and_flags_len(&nodemap->node[i]);
1773 int ctdb_node_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1774 struct ctdb_node_map **out)
1776 struct ctdb_node_map *nodemap;
1777 struct ctdb_node_map_wire *wire = (struct ctdb_node_map_wire *)buf;
1778 size_t offset;
1779 int i;
1780 bool ret;
1782 if (buflen < sizeof(uint32_t)) {
1783 return EMSGSIZE;
1785 if (wire->num > buflen / sizeof(struct ctdb_node_and_flags)) {
1786 return EMSGSIZE;
1788 if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_node_and_flags) <
1789 sizeof(uint32_t)) {
1790 return EMSGSIZE;
1792 if (buflen < sizeof(uint32_t) +
1793 wire->num * sizeof(struct ctdb_node_and_flags)) {
1794 return EMSGSIZE;
1797 nodemap = talloc(mem_ctx, struct ctdb_node_map);
1798 if (nodemap == NULL) {
1799 return ENOMEM;
1802 nodemap->num = wire->num;
1803 nodemap->node = talloc_array(nodemap, struct ctdb_node_and_flags,
1804 wire->num);
1805 if (nodemap->node == NULL) {
1806 talloc_free(nodemap);
1807 return ENOMEM;
1810 offset = offsetof(struct ctdb_node_map_wire, node);
1811 for (i=0; i<wire->num; i++) {
1812 ret = ctdb_node_and_flags_pull_elems(nodemap->node,
1813 &buf[offset],
1814 buflen-offset,
1815 &nodemap->node[i]);
1816 if (ret != 0) {
1817 talloc_free(nodemap);
1818 return ret;
1820 offset += ctdb_node_and_flags_len(&nodemap->node[i]);
1823 *out = nodemap;
1824 return 0;
1827 size_t ctdb_script_len(struct ctdb_script *script)
1829 return sizeof(struct ctdb_script);
1832 void ctdb_script_push(struct ctdb_script *script, uint8_t *buf)
1834 memcpy(buf, script, sizeof(struct ctdb_script));
1837 static int ctdb_script_pull_elems(uint8_t *buf, size_t buflen,
1838 TALLOC_CTX *mem_ctx,
1839 struct ctdb_script *out)
1841 if (buflen < sizeof(struct ctdb_script)) {
1842 return EMSGSIZE;
1845 memcpy(out, buf, sizeof(struct ctdb_script));
1847 return 0;
1850 int ctdb_script_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1851 struct ctdb_script **out)
1853 struct ctdb_script *script;
1854 int ret;
1856 script = talloc(mem_ctx, struct ctdb_script);
1857 if (script == NULL) {
1858 return ENOMEM;
1861 ret = ctdb_script_pull_elems(buf, buflen, script, script);
1862 if (ret != 0) {
1863 TALLOC_FREE(script);
1866 *out = script;
1867 return ret;
1870 struct ctdb_script_list_wire {
1871 uint32_t num_scripts;
1872 struct ctdb_script script[1];
1875 size_t ctdb_script_list_len(struct ctdb_script_list *script_list)
1877 int i;
1878 size_t len;
1880 if (script_list == NULL) {
1881 return 0;
1884 len = offsetof(struct ctdb_script_list_wire, script);
1885 for (i=0; i<script_list->num_scripts; i++) {
1886 len += ctdb_script_len(&script_list->script[i]);
1888 return len;
1891 void ctdb_script_list_push(struct ctdb_script_list *script_list, uint8_t *buf)
1893 struct ctdb_script_list_wire *wire =
1894 (struct ctdb_script_list_wire *)buf;
1895 size_t offset;
1896 int i;
1898 if (script_list == NULL) {
1899 return;
1902 wire->num_scripts = script_list->num_scripts;
1904 offset = offsetof(struct ctdb_script_list_wire, script);
1905 for (i=0; i<script_list->num_scripts; i++) {
1906 ctdb_script_push(&script_list->script[i], &buf[offset]);
1907 offset += ctdb_script_len(&script_list->script[i]);
1911 int ctdb_script_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1912 struct ctdb_script_list **out)
1914 struct ctdb_script_list *script_list;
1915 struct ctdb_script_list_wire *wire =
1916 (struct ctdb_script_list_wire *)buf;
1917 size_t offset;
1918 int i;
1919 bool ret;
1921 /* If event scripts have never been run, the result will be NULL */
1922 if (buflen == 0) {
1923 *out = NULL;
1924 return 0;
1927 offset = offsetof(struct ctdb_script_list_wire, script);
1929 if (buflen < offset) {
1930 return EMSGSIZE;
1932 if (wire->num_scripts > buflen / sizeof(struct ctdb_script)) {
1933 return EMSGSIZE;
1935 if (offset + wire->num_scripts * sizeof(struct ctdb_script) < offset) {
1936 return EMSGSIZE;
1938 if (buflen < offset + wire->num_scripts * sizeof(struct ctdb_script)) {
1939 return EMSGSIZE;
1942 script_list = talloc(mem_ctx, struct ctdb_script_list);
1943 if (script_list == NULL) {
1944 return ENOMEM;
1948 script_list->num_scripts = wire->num_scripts;
1949 script_list->script = talloc_array(script_list, struct ctdb_script,
1950 wire->num_scripts);
1951 if (script_list->script == NULL) {
1952 talloc_free(script_list);
1953 return ENOMEM;
1956 for (i=0; i<wire->num_scripts; i++) {
1957 ret = ctdb_script_pull_elems(&buf[offset], buflen-offset,
1958 script_list->script,
1959 &script_list->script[i]);
1960 if (ret != 0) {
1961 talloc_free(script_list);
1962 return ret;
1964 offset += ctdb_script_len(&script_list->script[i]);
1967 *out = script_list;
1968 return 0;
1971 size_t ctdb_ban_state_len(struct ctdb_ban_state *ban_state)
1973 return sizeof(struct ctdb_ban_state);
1976 void ctdb_ban_state_push(struct ctdb_ban_state *ban_state, uint8_t *buf)
1978 memcpy(buf, ban_state, sizeof(struct ctdb_ban_state));
1981 int ctdb_ban_state_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1982 struct ctdb_ban_state **out)
1984 struct ctdb_ban_state *ban_state;
1986 if (buflen < sizeof(struct ctdb_ban_state)) {
1987 return EMSGSIZE;
1990 ban_state = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_ban_state));
1991 if (ban_state == NULL) {
1992 return ENOMEM;
1995 *out = ban_state;
1996 return 0;
1999 struct ctdb_notify_data_wire {
2000 uint64_t srvid;
2001 uint32_t len;
2002 uint8_t data[1];
2005 size_t ctdb_notify_data_len(struct ctdb_notify_data *notify)
2007 return offsetof(struct ctdb_notify_data_wire, data) +
2008 notify->data.dsize;
2011 void ctdb_notify_data_push(struct ctdb_notify_data *notify, uint8_t *buf)
2013 struct ctdb_notify_data_wire *wire =
2014 (struct ctdb_notify_data_wire *)buf;
2016 wire->srvid = notify->srvid;
2017 wire->len = notify->data.dsize;
2018 memcpy(wire->data, notify->data.dptr, notify->data.dsize);
2021 int ctdb_notify_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2022 struct ctdb_notify_data **out)
2024 struct ctdb_notify_data *notify;
2025 struct ctdb_notify_data_wire *wire =
2026 (struct ctdb_notify_data_wire *)buf;
2028 if (buflen < offsetof(struct ctdb_notify_data_wire, data)) {
2029 return EMSGSIZE;
2031 if (wire->len > buflen) {
2032 return EMSGSIZE;
2034 if (offsetof(struct ctdb_notify_data_wire, data) + wire->len <
2035 offsetof(struct ctdb_notify_data_wire, data)) {
2036 return EMSGSIZE;
2038 if (buflen < offsetof(struct ctdb_notify_data_wire, data) + wire->len) {
2039 return EMSGSIZE;
2042 notify = talloc(mem_ctx, struct ctdb_notify_data);
2043 if (notify == NULL) {
2044 return ENOMEM;
2047 notify->srvid = wire->srvid;
2048 notify->data.dsize = wire->len;
2049 notify->data.dptr = talloc_memdup(notify, wire->data, wire->len);
2050 if (notify->data.dptr == NULL) {
2051 talloc_free(notify);
2052 return ENOMEM;
2055 *out = notify;
2056 return 0;
2059 size_t ctdb_iface_len(struct ctdb_iface *iface)
2061 return sizeof(struct ctdb_iface);
2064 void ctdb_iface_push(struct ctdb_iface *iface, uint8_t *buf)
2066 memcpy(buf, iface, sizeof(struct ctdb_iface));
2069 static int ctdb_iface_pull_elems(uint8_t *buf, size_t buflen,
2070 TALLOC_CTX *mem_ctx,
2071 struct ctdb_iface *out)
2073 if (buflen < sizeof(struct ctdb_iface)) {
2074 return EMSGSIZE;
2077 memcpy(out, buf, sizeof(struct ctdb_iface));
2079 return 0;
2082 int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2083 struct ctdb_iface **out)
2085 struct ctdb_iface *iface;
2086 int ret;
2088 iface = talloc(mem_ctx, struct ctdb_iface);
2089 if (iface == NULL) {
2090 return ENOMEM;
2093 ret = ctdb_iface_pull_elems(buf, buflen, iface, iface);
2094 if (ret != 0) {
2095 TALLOC_FREE(iface);
2098 *out = iface;
2099 return ret;
2102 struct ctdb_iface_list_wire {
2103 uint32_t num;
2104 struct ctdb_iface iface[1];
2107 size_t ctdb_iface_list_len(struct ctdb_iface_list *iface_list)
2109 return sizeof(uint32_t) +
2110 iface_list->num * sizeof(struct ctdb_iface);
2113 void ctdb_iface_list_push(struct ctdb_iface_list *iface_list, uint8_t *buf)
2115 struct ctdb_iface_list_wire *wire =
2116 (struct ctdb_iface_list_wire *)buf;
2118 wire->num = iface_list->num;
2119 memcpy(wire->iface, iface_list->iface,
2120 iface_list->num * sizeof(struct ctdb_iface));
2123 int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2124 struct ctdb_iface_list **out)
2126 struct ctdb_iface_list *iface_list;
2127 struct ctdb_iface_list_wire *wire =
2128 (struct ctdb_iface_list_wire *)buf;
2130 if (buflen < sizeof(uint32_t)) {
2131 return EMSGSIZE;
2133 if (wire->num > buflen / sizeof(struct ctdb_iface)) {
2134 return EMSGSIZE;
2136 if (sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface) <
2137 sizeof(uint32_t)) {
2138 return EMSGSIZE;
2140 if (buflen < sizeof(uint32_t) + wire->num * sizeof(struct ctdb_iface)) {
2141 return EMSGSIZE;
2144 iface_list = talloc(mem_ctx, struct ctdb_iface_list);
2145 if (iface_list == NULL) {
2146 return ENOMEM;
2149 iface_list->num = wire->num;
2150 iface_list->iface = talloc_array(iface_list, struct ctdb_iface,
2151 wire->num);
2152 if (iface_list->iface == NULL) {
2153 talloc_free(iface_list);
2154 return ENOMEM;
2157 memcpy(iface_list->iface, wire->iface,
2158 wire->num * sizeof(struct ctdb_iface));
2160 *out = iface_list;
2161 return 0;
2164 struct ctdb_public_ip_info_wire {
2165 struct ctdb_public_ip ip;
2166 uint32_t active_idx;
2167 uint32_t num;
2168 struct ctdb_iface ifaces[1];
2171 size_t ctdb_public_ip_info_len(struct ctdb_public_ip_info *ipinfo)
2173 return offsetof(struct ctdb_public_ip_info_wire, num) +
2174 ctdb_iface_list_len(ipinfo->ifaces);
2177 void ctdb_public_ip_info_push(struct ctdb_public_ip_info *ipinfo, uint8_t *buf)
2179 struct ctdb_public_ip_info_wire *wire =
2180 (struct ctdb_public_ip_info_wire *)buf;
2181 size_t offset;
2183 offset = offsetof(struct ctdb_public_ip_info_wire, num);
2184 memcpy(wire, ipinfo, offset);
2185 wire->num = ipinfo->ifaces->num;
2186 memcpy(wire->ifaces, ipinfo->ifaces->iface,
2187 ipinfo->ifaces->num * sizeof(struct ctdb_iface));
2190 int ctdb_public_ip_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2191 struct ctdb_public_ip_info **out)
2193 struct ctdb_public_ip_info *ipinfo;
2194 struct ctdb_public_ip_info_wire *wire =
2195 (struct ctdb_public_ip_info_wire *)buf;
2197 if (buflen < offsetof(struct ctdb_public_ip_info_wire, ifaces)) {
2198 return EMSGSIZE;
2200 if (wire->num > buflen / sizeof(struct ctdb_iface)) {
2201 return EMSGSIZE;
2203 if (offsetof(struct ctdb_public_ip_info_wire, ifaces) +
2204 wire->num * sizeof(struct ctdb_iface) <
2205 offsetof(struct ctdb_public_ip_info_wire, ifaces)) {
2206 return EMSGSIZE;
2208 if (buflen < offsetof(struct ctdb_public_ip_info_wire, ifaces) +
2209 wire->num * sizeof(struct ctdb_iface)) {
2210 return EMSGSIZE;
2213 ipinfo = talloc(mem_ctx, struct ctdb_public_ip_info);
2214 if (ipinfo == NULL) {
2215 return ENOMEM;
2218 memcpy(ipinfo, wire, offsetof(struct ctdb_public_ip_info_wire, num));
2220 ipinfo->ifaces = talloc(ipinfo, struct ctdb_iface_list);
2221 if (ipinfo->ifaces == NULL) {
2222 talloc_free(ipinfo);
2223 return ENOMEM;
2226 ipinfo->ifaces->num = wire->num;
2227 ipinfo->ifaces->iface = talloc_array(ipinfo->ifaces, struct ctdb_iface,
2228 wire->num);
2229 if (ipinfo->ifaces->iface == NULL) {
2230 talloc_free(ipinfo);
2231 return ENOMEM;
2234 memcpy(ipinfo->ifaces->iface, wire->ifaces,
2235 wire->num * sizeof(struct ctdb_iface));
2237 *out = ipinfo;
2238 return 0;
2241 struct ctdb_key_data_wire {
2242 uint32_t db_id;
2243 struct ctdb_ltdb_header header;
2244 uint32_t keylen;
2245 uint8_t key[1];
2248 size_t ctdb_key_data_len(struct ctdb_key_data *key)
2250 return offsetof(struct ctdb_key_data_wire, key) + key->key.dsize;
2253 void ctdb_key_data_push(struct ctdb_key_data *key, uint8_t *buf)
2255 struct ctdb_key_data_wire *wire = (struct ctdb_key_data_wire *)buf;
2257 memcpy(wire, key, offsetof(struct ctdb_key_data, key));
2258 wire->keylen = key->key.dsize;
2259 memcpy(wire->key, key->key.dptr, key->key.dsize);
2262 int ctdb_key_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2263 struct ctdb_key_data **out)
2265 struct ctdb_key_data *key_data;
2266 struct ctdb_key_data_wire *wire = (struct ctdb_key_data_wire *)buf;
2268 if (buflen < offsetof(struct ctdb_key_data_wire, key)) {
2269 return EMSGSIZE;
2271 if (wire->keylen > buflen) {
2272 return EMSGSIZE;
2274 if (offsetof(struct ctdb_key_data_wire, key) + wire->keylen <
2275 offsetof(struct ctdb_key_data_wire, key)) {
2276 return EMSGSIZE;
2278 if (buflen < offsetof(struct ctdb_key_data_wire, key) + wire->keylen) {
2279 return EMSGSIZE;
2282 key_data = talloc(mem_ctx, struct ctdb_key_data);
2283 if (key_data == NULL) {
2284 return ENOMEM;
2287 memcpy(key_data, wire, offsetof(struct ctdb_key_data, key));
2289 key_data->key.dsize = wire->keylen;
2290 key_data->key.dptr = talloc_memdup(key_data, wire->key, wire->keylen);
2291 if (key_data->key.dptr == NULL) {
2292 talloc_free(key_data);
2293 return ENOMEM;
2296 *out = key_data;
2297 return 0;
2300 struct ctdb_db_statistics_wire {
2301 struct ctdb_db_statistics dbstats;
2302 char hot_keys_wire[1];
2305 size_t ctdb_db_statistics_len(struct ctdb_db_statistics *dbstats)
2307 size_t len;
2308 int i;
2310 len = sizeof(struct ctdb_db_statistics);
2311 for (i=0; i<MAX_HOT_KEYS; i++) {
2312 len += dbstats->hot_keys[i].key.dsize;
2314 return len;
2317 void ctdb_db_statistics_push(struct ctdb_db_statistics *dbstats, void *buf)
2319 struct ctdb_db_statistics_wire *wire =
2320 (struct ctdb_db_statistics_wire *)buf;
2321 size_t offset;
2322 int i;
2324 dbstats->num_hot_keys = MAX_HOT_KEYS;
2325 memcpy(wire, dbstats, sizeof(struct ctdb_db_statistics));
2327 offset = 0;
2328 for (i=0; i<MAX_HOT_KEYS; i++) {
2329 memcpy(&wire->hot_keys_wire[offset],
2330 dbstats->hot_keys[i].key.dptr,
2331 dbstats->hot_keys[i].key.dsize);
2332 offset += dbstats->hot_keys[i].key.dsize;
2336 int ctdb_db_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2337 struct ctdb_db_statistics **out)
2339 struct ctdb_db_statistics *dbstats;
2340 struct ctdb_db_statistics_wire *wire =
2341 (struct ctdb_db_statistics_wire *)buf;
2342 size_t offset;
2343 int i;
2345 if (buflen < sizeof(struct ctdb_db_statistics)) {
2346 return EMSGSIZE;
2349 offset = 0;
2350 for (i=0; i<wire->dbstats.num_hot_keys; i++) {
2351 if (wire->dbstats.hot_keys[i].key.dsize > buflen) {
2352 return EMSGSIZE;
2354 if (offset + wire->dbstats.hot_keys[i].key.dsize < offset) {
2355 return EMSGSIZE;
2357 offset += wire->dbstats.hot_keys[i].key.dsize;
2358 if (offset > buflen) {
2359 return EMSGSIZE;
2362 if (sizeof(struct ctdb_db_statistics) + offset <
2363 sizeof(struct ctdb_db_statistics)) {
2364 return EMSGSIZE;
2366 if (buflen < sizeof(struct ctdb_db_statistics) + offset) {
2367 return EMSGSIZE;
2370 dbstats = talloc(mem_ctx, struct ctdb_db_statistics);
2371 if (dbstats == NULL) {
2372 return ENOMEM;
2375 memcpy(dbstats, wire, sizeof(struct ctdb_db_statistics));
2377 offset = 0;
2378 for (i=0; i<wire->dbstats.num_hot_keys; i++) {
2379 uint8_t *ptr;
2380 size_t key_size;
2382 key_size = dbstats->hot_keys[i].key.dsize;
2383 ptr = talloc_memdup(mem_ctx, &wire->hot_keys_wire[offset],
2384 key_size);
2385 if (ptr == NULL) {
2386 talloc_free(dbstats);
2387 return ENOMEM;
2389 dbstats->hot_keys[i].key.dptr = ptr;
2390 offset += key_size;
2393 *out = dbstats;
2394 return 0;
2397 size_t ctdb_election_message_len(struct ctdb_election_message *election)
2399 return sizeof(struct ctdb_election_message);
2402 void ctdb_election_message_push(struct ctdb_election_message *election,
2403 uint8_t *buf)
2405 memcpy(buf, election, sizeof(struct ctdb_election_message));
2408 int ctdb_election_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2409 struct ctdb_election_message **out)
2411 struct ctdb_election_message *election;
2413 if (buflen < sizeof(struct ctdb_election_message)) {
2414 return EMSGSIZE;
2417 election = talloc_memdup(mem_ctx, buf,
2418 sizeof(struct ctdb_election_message));
2419 if (election == NULL) {
2420 return ENOMEM;
2423 *out = election;
2424 return 0;
2427 size_t ctdb_srvid_message_len(struct ctdb_srvid_message *msg)
2429 return sizeof(struct ctdb_srvid_message);
2432 void ctdb_srvid_message_push(struct ctdb_srvid_message *msg, uint8_t *buf)
2434 memcpy(buf, msg, sizeof(struct ctdb_srvid_message));
2437 int ctdb_srvid_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2438 struct ctdb_srvid_message **out)
2440 struct ctdb_srvid_message *msg;
2442 if (buflen < sizeof(struct ctdb_srvid_message)) {
2443 return EMSGSIZE;
2446 msg = talloc_memdup(mem_ctx, buf, sizeof(struct ctdb_srvid_message));
2447 if (msg == NULL) {
2448 return ENOMEM;
2451 *out = msg;
2452 return 0;
2455 size_t ctdb_disable_message_len(struct ctdb_disable_message *disable)
2457 return sizeof(struct ctdb_disable_message);
2460 void ctdb_disable_message_push(struct ctdb_disable_message *disable,
2461 uint8_t *buf)
2463 memcpy(buf, disable, sizeof(struct ctdb_disable_message));
2466 int ctdb_disable_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2467 struct ctdb_disable_message **out)
2469 struct ctdb_disable_message *disable;
2471 if (buflen < sizeof(struct ctdb_disable_message)) {
2472 return EMSGSIZE;
2475 disable = talloc_memdup(mem_ctx, buf,
2476 sizeof(struct ctdb_disable_message));
2477 if (disable == NULL) {
2478 return ENOMEM;
2481 *out = disable;
2482 return 0;
2485 size_t ctdb_tdb_data_len(TDB_DATA data)
2487 return data.dsize;
2490 void ctdb_tdb_data_push(TDB_DATA data, uint8_t *buf)
2492 if (data.dsize > 0) {
2493 memcpy(buf, data.dptr, data.dsize);
2497 int ctdb_tdb_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2498 TDB_DATA *out)
2500 TDB_DATA data;
2502 data.dsize = buflen;
2503 if (data.dsize > 0) {
2504 data.dptr = talloc_memdup(mem_ctx, buf, buflen);
2505 if (data.dptr == NULL) {
2506 return ENOMEM;
2508 } else {
2509 data.dptr = NULL;
2512 *out = data;
2513 return 0;
2516 size_t ctdb_server_id_len(struct ctdb_server_id *sid)
2518 return sizeof(struct ctdb_server_id);
2521 void ctdb_server_id_push(struct ctdb_server_id *sid, uint8_t *buf)
2523 memcpy(buf, sid, sizeof(struct ctdb_server_id));
2526 int ctdb_server_id_pull(uint8_t *buf, size_t buflen,
2527 struct ctdb_server_id *sid)
2529 if (buflen < sizeof(struct ctdb_server_id)) {
2530 return EMSGSIZE;
2533 memcpy(sid, buf, sizeof(struct ctdb_server_id));
2534 return 0;
2537 size_t ctdb_g_lock_len(struct ctdb_g_lock *lock)
2539 return sizeof(struct ctdb_g_lock);
2542 void ctdb_g_lock_push(struct ctdb_g_lock *lock, uint8_t *buf)
2544 memcpy(buf, lock, sizeof(struct ctdb_g_lock));
2547 int ctdb_g_lock_pull(uint8_t *buf, size_t buflen, struct ctdb_g_lock *lock)
2549 if (buflen < sizeof(struct ctdb_g_lock)) {
2550 return EMSGSIZE;
2553 memcpy(lock, buf, sizeof(struct ctdb_g_lock));
2554 return 0;
2557 size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *lock_list)
2559 return lock_list->num * sizeof(struct ctdb_g_lock);
2562 void ctdb_g_lock_list_push(struct ctdb_g_lock_list *lock_list, uint8_t *buf)
2564 size_t offset = 0;
2565 int i;
2567 for (i=0; i<lock_list->num; i++) {
2568 ctdb_g_lock_push(&lock_list->lock[i], &buf[offset]);
2569 offset += sizeof(struct ctdb_g_lock);
2573 int ctdb_g_lock_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2574 struct ctdb_g_lock_list **out)
2576 struct ctdb_g_lock_list *lock_list;
2577 unsigned count;
2578 size_t offset;
2579 int ret, i;
2581 lock_list = talloc_zero(mem_ctx, struct ctdb_g_lock_list);
2582 if (lock_list == NULL) {
2583 return ENOMEM;
2586 count = buflen / sizeof(struct ctdb_g_lock);
2587 lock_list->lock = talloc_array(lock_list, struct ctdb_g_lock, count);
2588 if (lock_list->lock == NULL) {
2589 talloc_free(lock_list);
2590 return ENOMEM;
2593 offset = 0;
2594 for (i=0; i<count; i++) {
2595 ret = ctdb_g_lock_pull(&buf[offset], buflen-offset,
2596 &lock_list->lock[i]);
2597 if (ret != 0) {
2598 talloc_free(lock_list);
2599 return ret;
2601 offset += sizeof(struct ctdb_g_lock);
2604 lock_list->num = count;
2606 *out = lock_list;
2607 return 0;