1 /*
2    CTDB protocol marshalling
3 
4    Copyright (C) Amitay Isaacs  2015-2017
5 
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.
10 
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.
15 
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/>.
18 */
19 
20 #include "replace.h"
21 #include "system/network.h"
22 
23 #include <talloc.h>
24 #include <tdb.h>
25 
26 #include "protocol.h"
27 #include "protocol_private.h"
28 #include "protocol_api.h"
29 
ctdb_tdb_data_len(TDB_DATA * in)30 size_t ctdb_tdb_data_len(TDB_DATA *in)
31 {
32 	return in->dsize > UINT32_MAX ? UINT32_MAX : in->dsize;
33 }
34 
ctdb_tdb_data_push(TDB_DATA * in,uint8_t * buf,size_t * npush)35 void ctdb_tdb_data_push(TDB_DATA *in, uint8_t *buf, size_t *npush)
36 {
37 	size_t len = ctdb_tdb_data_len(in);
38 
39 	if (len > 0) {
40 		memcpy(buf, in->dptr, len);
41 	}
42 
43 	*npush = len;
44 }
45 
ctdb_tdb_data_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,TDB_DATA * out,size_t * npull)46 int ctdb_tdb_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
47 		       TDB_DATA *out, size_t *npull)
48 {
49 	TDB_DATA val;
50 
51 	if (buflen > UINT32_MAX) {
52 		return EMSGSIZE;
53 	}
54 
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;
60 		}
61 	} else {
62 		val.dptr = NULL;
63 	}
64 
65 	*out = val;
66 	*npull = buflen;
67 	return 0;
68 }
69 
ctdb_tdb_datan_len(TDB_DATA * in)70 size_t ctdb_tdb_datan_len(TDB_DATA *in)
71 {
72 	uint32_t u32 = ctdb_tdb_data_len(in);
73 
74 	return ctdb_uint32_len(&u32) + u32;
75 }
76 
ctdb_tdb_datan_push(TDB_DATA * in,uint8_t * buf,size_t * npush)77 void ctdb_tdb_datan_push(TDB_DATA *in, uint8_t *buf, size_t *npush)
78 {
79 	size_t offset = 0, np;
80 	uint32_t u32 = ctdb_tdb_data_len(in);
81 
82 	ctdb_uint32_push(&u32, buf+offset, &np);
83 	offset += np;
84 
85 	ctdb_tdb_data_push(in, buf+offset, &np);
86 	offset += np;
87 
88 	*npush = offset;
89 }
90 
ctdb_tdb_datan_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,TDB_DATA * out,size_t * npull)91 int ctdb_tdb_datan_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
92 			TDB_DATA *out, size_t *npull)
93 {
94 	size_t offset = 0, np;
95 	uint32_t u32;
96 	int ret;
97 
98 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
99 	if (ret != 0) {
100 		return ret;
101 	}
102 	offset += np;
103 
104 	if (buflen-offset < u32) {
105 		return EMSGSIZE;
106 	}
107 
108 	ret = ctdb_tdb_data_pull(buf+offset, u32, mem_ctx, out, &np);
109 	if (ret != 0) {
110 		return ret;
111 	}
112 	offset += np;
113 
114 	*npull = offset;
115 	return 0;
116 }
117 
ctdb_latency_counter_len(struct ctdb_latency_counter * in)118 size_t ctdb_latency_counter_len(struct ctdb_latency_counter *in)
119 {
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);
125 }
126 
ctdb_latency_counter_push(struct ctdb_latency_counter * in,uint8_t * buf,size_t * npush)127 void ctdb_latency_counter_push(struct ctdb_latency_counter *in, uint8_t *buf,
128 			       size_t *npush)
129 {
130 	size_t offset = 0, np;
131 
132 	ctdb_int32_push(&in->num, buf+offset, &np);
133 	offset += np;
134 
135 	ctdb_padding_push(4, buf+offset, &np);
136 	offset += np;
137 
138 	ctdb_double_push(&in->min, buf+offset, &np);
139 	offset += np;
140 
141 	ctdb_double_push(&in->max, buf+offset, &np);
142 	offset += np;
143 
144 	ctdb_double_push(&in->total, buf+offset, &np);
145 	offset += np;
146 
147 	*npush = offset;
148 }
149 
ctdb_latency_counter_pull(uint8_t * buf,size_t buflen,struct ctdb_latency_counter * out,size_t * npull)150 int ctdb_latency_counter_pull(uint8_t *buf, size_t buflen,
151 			      struct ctdb_latency_counter *out, size_t *npull)
152 {
153 	size_t offset = 0, np;
154 	int ret;
155 
156 	ret = ctdb_int32_pull(buf+offset, buflen-offset, &out->num, &np);
157 	if (ret != 0) {
158 		return ret;
159 	}
160 	offset += np;
161 
162 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
163 	if (ret != 0) {
164 		return ret;
165 	}
166 	offset += np;
167 
168 	ret = ctdb_double_pull(buf+offset, buflen-offset, &out->min, &np);
169 	if (ret != 0) {
170 		return ret;
171 	}
172 	offset += np;
173 
174 	ret = ctdb_double_pull(buf+offset, buflen-offset, &out->max, &np);
175 	if (ret != 0) {
176 		return ret;
177 	}
178 	offset += np;
179 
180 	ret = ctdb_double_pull(buf+offset, buflen-offset, &out->total, &np);
181 	if (ret != 0) {
182 		return ret;
183 	}
184 	offset += np;
185 
186 	*npull = offset;
187 	return 0;
188 }
189 
ctdb_statistics_len(struct ctdb_statistics * in)190 size_t ctdb_statistics_len(struct ctdb_statistics *in)
191 {
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);
244 }
245 
ctdb_statistics_push(struct ctdb_statistics * in,uint8_t * buf,size_t * npush)246 void ctdb_statistics_push(struct ctdb_statistics *in, uint8_t *buf,
247 			  size_t *npush)
248 {
249 	size_t offset = 0, np;
250 	int i;
251 
252 	ctdb_uint32_push(&in->num_clients, buf+offset, &np);
253 	offset += np;
254 
255 	ctdb_uint32_push(&in->frozen, buf+offset, &np);
256 	offset += np;
257 
258 	ctdb_uint32_push(&in->recovering, buf+offset, &np);
259 	offset += np;
260 
261 	ctdb_uint32_push(&in->client_packets_sent, buf+offset, &np);
262 	offset += np;
263 
264 	ctdb_uint32_push(&in->client_packets_recv, buf+offset, &np);
265 	offset += np;
266 
267 	ctdb_uint32_push(&in->node_packets_sent, buf+offset, &np);
268 	offset += np;
269 
270 	ctdb_uint32_push(&in->node_packets_recv, buf+offset, &np);
271 	offset += np;
272 
273 	ctdb_uint32_push(&in->keepalive_packets_sent, buf+offset, &np);
274 	offset += np;
275 
276 	ctdb_uint32_push(&in->keepalive_packets_recv, buf+offset, &np);
277 	offset += np;
278 
279 	ctdb_uint32_push(&in->node.req_call, buf+offset, &np);
280 	offset += np;
281 
282 	ctdb_uint32_push(&in->node.reply_call, buf+offset, &np);
283 	offset += np;
284 
285 	ctdb_uint32_push(&in->node.req_dmaster, buf+offset, &np);
286 	offset += np;
287 
288 	ctdb_uint32_push(&in->node.reply_dmaster, buf+offset, &np);
289 	offset += np;
290 
291 	ctdb_uint32_push(&in->node.reply_error, buf+offset, &np);
292 	offset += np;
293 
294 	ctdb_uint32_push(&in->node.req_message, buf+offset, &np);
295 	offset += np;
296 
297 	ctdb_uint32_push(&in->node.req_control, buf+offset, &np);
298 	offset += np;
299 
300 	ctdb_uint32_push(&in->node.reply_control, buf+offset, &np);
301 	offset += np;
302 
303 	ctdb_uint32_push(&in->node.req_tunnel, buf+offset, &np);
304 	offset += np;
305 
306 	ctdb_uint32_push(&in->client.req_call, buf+offset, &np);
307 	offset += np;
308 
309 	ctdb_uint32_push(&in->client.req_message, buf+offset, &np);
310 	offset += np;
311 
312 	ctdb_uint32_push(&in->client.req_control, buf+offset, &np);
313 	offset += np;
314 
315 	ctdb_uint32_push(&in->client.req_tunnel, buf+offset, &np);
316 	offset += np;
317 
318 	ctdb_uint32_push(&in->timeouts.call, buf+offset, &np);
319 	offset += np;
320 
321 	ctdb_uint32_push(&in->timeouts.control, buf+offset, &np);
322 	offset += np;
323 
324 	ctdb_uint32_push(&in->timeouts.traverse, buf+offset, &np);
325 	offset += np;
326 
327 	ctdb_padding_push(4, buf+offset, &np);
328 	offset += np;
329 
330 	ctdb_latency_counter_push(&in->reclock.ctdbd, buf+offset, &np);
331 	offset += np;
332 
333 	ctdb_latency_counter_push(&in->reclock.recd, buf+offset, &np);
334 	offset += np;
335 
336 	ctdb_uint32_push(&in->locks.num_calls, buf+offset, &np);
337 	offset += np;
338 
339 	ctdb_uint32_push(&in->locks.num_current, buf+offset, &np);
340 	offset += np;
341 
342 	ctdb_uint32_push(&in->locks.num_pending, buf+offset, &np);
343 	offset += np;
344 
345 	ctdb_uint32_push(&in->locks.num_failed, buf+offset, &np);
346 	offset += np;
347 
348 	ctdb_latency_counter_push(&in->locks.latency, buf+offset, &np);
349 	offset += np;
350 
351 	for (i=0; i<MAX_COUNT_BUCKETS; i++) {
352 		ctdb_uint32_push(&in->locks.buckets[i], buf+offset, &np);
353 		offset += np;
354 	}
355 
356 	ctdb_uint32_push(&in->total_calls, buf+offset, &np);
357 	offset += np;
358 
359 	ctdb_uint32_push(&in->pending_calls, buf+offset, &np);
360 	offset += np;
361 
362 	ctdb_uint32_push(&in->childwrite_calls, buf+offset, &np);
363 	offset += np;
364 
365 	ctdb_uint32_push(&in->pending_childwrite_calls, buf+offset, &np);
366 	offset += np;
367 
368 	ctdb_uint32_push(&in->memory_used, buf+offset, &np);
369 	offset += np;
370 
371 	ctdb_uint32_push(&in->__last_counter, buf+offset, &np);
372 	offset += np;
373 
374 	ctdb_uint32_push(&in->max_hop_count, buf+offset, &np);
375 	offset += np;
376 
377 	for (i=0; i<MAX_COUNT_BUCKETS; i++) {
378 		ctdb_uint32_push(&in->hop_count_bucket[i], buf+offset, &np);
379 		offset += np;
380 	}
381 
382 	ctdb_padding_push(4, buf+offset, &np);
383 	offset += np;
384 
385 	ctdb_latency_counter_push(&in->call_latency, buf+offset, &np);
386 	offset += np;
387 
388 	ctdb_latency_counter_push(&in->childwrite_latency, buf+offset, &np);
389 	offset += np;
390 
391 	ctdb_uint32_push(&in->num_recoveries, buf+offset, &np);
392 	offset += np;
393 
394 	ctdb_padding_push(4, buf+offset, &np);
395 	offset += np;
396 
397 	ctdb_timeval_push(&in->statistics_start_time, buf+offset, &np);
398 	offset += np;
399 
400 	ctdb_timeval_push(&in->statistics_current_time, buf+offset, &np);
401 	offset += np;
402 
403 	ctdb_uint32_push(&in->total_ro_delegations, buf+offset, &np);
404 	offset += np;
405 
406 	ctdb_uint32_push(&in->total_ro_revokes, buf+offset, &np);
407 	offset += np;
408 
409 	*npush = offset;
410 }
411 
ctdb_statistics_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_statistics * out,size_t * npull)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)
416 {
417 	size_t offset = 0, np;
418 	int ret, i;
419 
420 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->num_clients,
421 			       &np);
422 	if (ret != 0) {
423 		return ret;
424 	}
425 	offset += np;
426 
427 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->frozen, &np);
428 	if (ret != 0) {
429 		return ret;
430 	}
431 	offset += np;
432 
433 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->recovering,
434 			       &np);
435 	if (ret != 0) {
436 		return ret;
437 	}
438 	offset += np;
439 
440 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
441 			       &out->client_packets_sent, &np);
442 	if (ret != 0) {
443 		return ret;
444 	}
445 	offset += np;
446 
447 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
448 			       &out->client_packets_recv, &np);
449 	if (ret != 0) {
450 		return ret;
451 	}
452 	offset += np;
453 
454 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
455 			       &out->node_packets_sent, &np);
456 	if (ret != 0) {
457 		return ret;
458 	}
459 	offset += np;
460 
461 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
462 			       &out->node_packets_recv, &np);
463 	if (ret != 0) {
464 		return ret;
465 	}
466 	offset += np;
467 
468 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
469 			       &out->keepalive_packets_sent, &np);
470 	if (ret != 0) {
471 		return ret;
472 	}
473 	offset += np;
474 
475 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
476 			       &out->keepalive_packets_recv, &np);
477 	if (ret != 0) {
478 		return ret;
479 	}
480 	offset += np;
481 
482 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
483 			       &out->node.req_call, &np);
484 	if (ret != 0) {
485 		return ret;
486 	}
487 	offset += np;
488 
489 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
490 			       &out->node.reply_call, &np);
491 	if (ret != 0) {
492 		return ret;
493 	}
494 	offset += np;
495 
496 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
497 			       &out->node.req_dmaster, &np);
498 	if (ret != 0) {
499 		return ret;
500 	}
501 	offset += np;
502 
503 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
504 			       &out->node.reply_dmaster, &np);
505 	if (ret != 0) {
506 		return ret;
507 	}
508 	offset += np;
509 
510 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
511 			       &out->node.reply_error, &np);
512 	if (ret != 0) {
513 		return ret;
514 	}
515 	offset += np;
516 
517 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
518 			       &out->node.req_message, &np);
519 	if (ret != 0) {
520 		return ret;
521 	}
522 	offset += np;
523 
524 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
525 			       &out->node.req_control, &np);
526 	if (ret != 0) {
527 		return ret;
528 	}
529 	offset += np;
530 
531 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
532 			       &out->node.reply_control, &np);
533 	if (ret != 0) {
534 		return ret;
535 	}
536 	offset += np;
537 
538 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
539 			       &out->node.req_tunnel, &np);
540 	if (ret != 0) {
541 		return ret;
542 	}
543 	offset += np;
544 
545 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
546 			       &out->client.req_call, &np);
547 	if (ret != 0) {
548 		return ret;
549 	}
550 	offset += np;
551 
552 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
553 			       &out->client.req_message, &np);
554 	if (ret != 0) {
555 		return ret;
556 	}
557 	offset += np;
558 
559 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
560 			       &out->client.req_control, &np);
561 	if (ret != 0) {
562 		return ret;
563 	}
564 	offset += np;
565 
566 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
567 			       &out->client.req_tunnel, &np);
568 	if (ret != 0) {
569 		return ret;
570 	}
571 	offset += np;
572 
573 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
574 			       &out->timeouts.call, &np);
575 	if (ret != 0) {
576 		return ret;
577 	}
578 	offset += np;
579 
580 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
581 			       &out->timeouts.control, &np);
582 	if (ret != 0) {
583 		return ret;
584 	}
585 	offset += np;
586 
587 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
588 			       &out->timeouts.traverse, &np);
589 	if (ret != 0) {
590 		return ret;
591 	}
592 	offset += np;
593 
594 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
595 	if (ret != 0) {
596 		return ret;
597 	}
598 	offset += np;
599 
600 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
601 					&out->reclock.ctdbd, &np);
602 	if (ret != 0) {
603 		return ret;
604 	}
605 	offset += np;
606 
607 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
608 					&out->reclock.recd, &np);
609 	if (ret != 0) {
610 		return ret;
611 	}
612 	offset += np;
613 
614 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
615 			       &out->locks.num_calls, &np);
616 	if (ret != 0) {
617 		return ret;
618 	}
619 	offset += np;
620 
621 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
622 			       &out->locks.num_current, &np);
623 	if (ret != 0) {
624 		return ret;
625 	}
626 	offset += np;
627 
628 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
629 			       &out->locks.num_pending, &np);
630 	if (ret != 0) {
631 		return ret;
632 	}
633 	offset += np;
634 
635 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
636 			       &out->locks.num_failed, &np);
637 	if (ret != 0) {
638 		return ret;
639 	}
640 	offset += np;
641 
642 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
643 					&out->locks.latency, &np);
644 	if (ret != 0) {
645 		return ret;
646 	}
647 	offset += np;
648 
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;
654 		}
655 		offset += np;
656 	}
657 
658 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
659 			       &out->total_calls, &np);
660 	if (ret != 0) {
661 		return ret;
662 	}
663 	offset += np;
664 
665 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
666 			       &out->pending_calls, &np);
667 	if (ret != 0) {
668 		return ret;
669 	}
670 	offset += np;
671 
672 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
673 			       &out->childwrite_calls, &np);
674 	if (ret != 0) {
675 		return ret;
676 	}
677 	offset += np;
678 
679 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
680 			       &out->pending_childwrite_calls, &np);
681 	if (ret != 0) {
682 		return ret;
683 	}
684 	offset += np;
685 
686 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->memory_used,
687 			       &np);
688 	if (ret != 0) {
689 		return ret;
690 	}
691 	offset += np;
692 
693 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
694 			       &out->__last_counter, &np);
695 	if (ret != 0) {
696 		return ret;
697 	}
698 	offset += np;
699 
700 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
701 			       &out->max_hop_count, &np);
702 	if (ret != 0) {
703 		return ret;
704 	}
705 	offset += np;
706 
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;
712 		}
713 		offset += np;
714 	}
715 
716 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
717 	if (ret != 0) {
718 		return ret;
719 	}
720 	offset += np;
721 
722 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
723 					&out->call_latency, &np);
724 	if (ret != 0) {
725 		return ret;
726 	}
727 	offset += np;
728 
729 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
730 					&out->childwrite_latency, &np);
731 	if (ret != 0) {
732 		return ret;
733 	}
734 	offset += np;
735 
736 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
737 			       &out->num_recoveries, &np);
738 	if (ret != 0) {
739 		return ret;
740 	}
741 	offset += np;
742 
743 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
744 	if (ret != 0) {
745 		return ret;
746 	}
747 	offset += np;
748 
749 	ret = ctdb_timeval_pull(buf+offset, buflen-offset,
750 				&out->statistics_start_time, &np);
751 	if (ret != 0) {
752 		return ret;
753 	}
754 	offset += np;
755 
756 	ret = ctdb_timeval_pull(buf+offset, buflen-offset,
757 				&out->statistics_current_time, &np);
758 	if (ret != 0) {
759 		return ret;
760 	}
761 	offset += np;
762 
763 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
764 			       &out->total_ro_delegations, &np);
765 	if (ret != 0) {
766 		return ret;
767 	}
768 	offset += np;
769 
770 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
771 			       &out->total_ro_revokes, &np);
772 	if (ret != 0) {
773 		return ret;
774 	}
775 	offset += np;
776 
777 	*npull = offset;
778 	return 0;
779 }
780 
ctdb_statistics_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_statistics ** out,size_t * npull)781 int ctdb_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
782 			 struct ctdb_statistics **out, size_t *npull)
783 {
784 	struct ctdb_statistics *val;
785 	size_t np;
786 	int ret;
787 
788 	val = talloc(mem_ctx, struct ctdb_statistics);
789 	if (val == NULL) {
790 		return ENOMEM;
791 	}
792 
793 	ret = ctdb_statistics_pull_elems(buf, buflen, val, val, &np);
794 	if (ret != 0) {
795 		talloc_free(val);
796 		return ret;
797 	}
798 
799 	*out = val;
800 	*npull = np;
801 	return 0;
802 }
803 
ctdb_statistics_list_len(struct ctdb_statistics_list * in)804 size_t ctdb_statistics_list_len(struct ctdb_statistics_list *in)
805 {
806 	size_t len;
807 
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]);
811 	}
812 
813 	return len;
814 }
815 
ctdb_statistics_list_push(struct ctdb_statistics_list * in,uint8_t * buf,size_t * npush)816 void ctdb_statistics_list_push(struct ctdb_statistics_list *in,
817 			       uint8_t *buf, size_t *npush)
818 {
819 	size_t offset = 0, np;
820 	int i;
821 
822 	ctdb_int32_push(&in->num, buf+offset, &np);
823 	offset += np;
824 
825 	ctdb_padding_push(4, buf+offset, &np);
826 	offset += np;
827 
828 	for (i=0; i<in->num; i++) {
829 		ctdb_statistics_push(&in->stats[i], buf+offset, &np);
830 		offset += np;
831 	}
832 
833 	*npush = offset;
834 }
835 
ctdb_statistics_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_statistics_list ** out,size_t * npull)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)
839 {
840 	struct ctdb_statistics_list *val;
841 	size_t offset = 0, np;
842 	int ret, i;
843 
844 	val = talloc(mem_ctx, struct ctdb_statistics_list);
845 	if (val == NULL) {
846 		return ENOMEM;
847 	}
848 
849 	ret = ctdb_int32_pull(buf+offset, buflen-offset, &val->num, &np);
850 	if (ret != 0) {
851 		goto fail;
852 	}
853 	offset += np;
854 
855 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
856 	if (ret != 0) {
857 		goto fail;
858 	}
859 	offset += np;
860 
861 	if (val->num == 0) {
862 		val->stats = NULL;
863 		goto done;
864 	}
865 
866 	val->stats = talloc_array(val, struct ctdb_statistics, val->num);
867 	if (val->stats == NULL) {
868 		ret = ENOMEM;
869 		goto fail;
870 	}
871 
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;
877 		}
878 		offset += np;
879 	}
880 
881 done:
882 	*out = val;
883 	*npull = offset;
884 	return 0;
885 
886 fail:
887 	talloc_free(val);
888 	return ret;
889 }
890 
ctdb_vnn_map_len(struct ctdb_vnn_map * in)891 size_t ctdb_vnn_map_len(struct ctdb_vnn_map *in)
892 {
893 	size_t len;
894 
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]);
898 	}
899 
900 	return len;
901 }
902 
ctdb_vnn_map_push(struct ctdb_vnn_map * in,uint8_t * buf,size_t * npush)903 void ctdb_vnn_map_push(struct ctdb_vnn_map *in, uint8_t *buf, size_t *npush)
904 {
905 	size_t offset = 0, np;
906 	uint32_t i;
907 
908 	ctdb_uint32_push(&in->generation, buf+offset, &np);
909 	offset += np;
910 
911 	ctdb_uint32_push(&in->size, buf+offset, &np);
912 	offset += np;
913 
914 	for (i=0; i<in->size; i++) {
915 		ctdb_uint32_push(&in->map[i], buf+offset, &np);
916 		offset += np;
917 	}
918 
919 	*npush = offset;
920 }
921 
ctdb_vnn_map_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_vnn_map ** out,size_t * npull)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)
924 {
925 	struct ctdb_vnn_map *val;
926 	size_t offset = 0, np;
927 	uint32_t i;
928 	int ret;
929 
930 	val = talloc(mem_ctx, struct ctdb_vnn_map);
931 	if (val == NULL) {
932 		return ENOMEM;
933 	}
934 
935 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->generation,
936 			       &np);
937 	if (ret != 0) {
938 		goto fail;
939 	}
940 	offset += np;
941 
942 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->size, &np);
943 	if (ret != 0) {
944 		goto fail;
945 	}
946 	offset += np;
947 
948 	if (val->size == 0) {
949 		val->map = NULL;
950 		goto done;
951 	}
952 
953 	val->map = talloc_array(val, uint32_t, val->size);
954 	if (val->map == NULL) {
955 		ret = ENOMEM;
956 		goto fail;
957 	}
958 
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;
964 		}
965 		offset += np;
966 	}
967 
968 done:
969 	*out = val;
970 	*npull = offset;
971 	return 0;
972 
973 fail:
974 	talloc_free(val);
975 	return ret;
976 }
977 
ctdb_dbid_len(struct ctdb_dbid * in)978 size_t ctdb_dbid_len(struct ctdb_dbid *in)
979 {
980 	return ctdb_uint32_len(&in->db_id) +
981 		ctdb_uint8_len(&in->flags) +
982 		ctdb_padding_len(3);
983 }
984 
ctdb_dbid_push(struct ctdb_dbid * in,uint8_t * buf,size_t * npush)985 void ctdb_dbid_push(struct ctdb_dbid *in, uint8_t *buf, size_t *npush)
986 {
987 	size_t offset = 0, np;
988 
989 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
990 	offset += np;
991 
992 	ctdb_uint8_push(&in->flags, buf+offset, &np);
993 	offset += np;
994 
995 	ctdb_padding_push(3, buf+offset, &np);
996 	offset += np;
997 
998 	*npush = offset;
999 }
1000 
ctdb_dbid_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_dbid * out,size_t * npull)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)
1004 {
1005 	size_t offset = 0, np;
1006 	int ret;
1007 
1008 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->db_id, &np);
1009 	if (ret != 0) {
1010 		return ret;
1011 	}
1012 	offset += np;
1013 
1014 	ret = ctdb_uint8_pull(buf+offset, buflen-offset, &out->flags, &np);
1015 	if (ret != 0) {
1016 		return ret;
1017 	}
1018 	offset += np;
1019 
1020 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 3, &np);
1021 	if (ret != 0) {
1022 		return ret;
1023 	}
1024 	offset += np;
1025 
1026 	*npull = offset;
1027 	return 0;
1028 }
1029 
ctdb_dbid_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_dbid ** out,size_t * npull)1030 int ctdb_dbid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1031 		   struct ctdb_dbid **out, size_t *npull)
1032 {
1033 	struct ctdb_dbid *val;
1034 	size_t np;
1035 	int ret;
1036 
1037 	val = talloc(mem_ctx, struct ctdb_dbid);
1038 	if (val == NULL) {
1039 		return ENOMEM;
1040 	}
1041 
1042 	ret = ctdb_dbid_pull_elems(buf, buflen, val, val, &np);
1043 	if (ret != 0) {
1044 		talloc_free(val);
1045 		return ret;
1046 	}
1047 
1048 	*out = val;
1049 	*npull = np;
1050 	return 0;
1051 }
1052 
ctdb_dbid_map_len(struct ctdb_dbid_map * in)1053 size_t ctdb_dbid_map_len(struct ctdb_dbid_map *in)
1054 {
1055 	size_t len;
1056 
1057 	len = ctdb_uint32_len(&in->num);
1058 	if (in->num > 0) {
1059 		len += in->num * ctdb_dbid_len(&in->dbs[0]);
1060 	}
1061 
1062 	return len;
1063 }
1064 
ctdb_dbid_map_push(struct ctdb_dbid_map * in,uint8_t * buf,size_t * npush)1065 void ctdb_dbid_map_push(struct ctdb_dbid_map *in, uint8_t *buf, size_t *npush)
1066 {
1067 	size_t offset = 0, np;
1068 	uint32_t i;
1069 
1070 	ctdb_uint32_push(&in->num, buf+offset, &np);
1071 	offset += np;
1072 
1073 	for (i=0; i<in->num; i++) {
1074 		ctdb_dbid_push(&in->dbs[i], buf+offset, &np);
1075 		offset += np;
1076 	}
1077 
1078 	*npush = offset;
1079 }
1080 
ctdb_dbid_map_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_dbid_map ** out,size_t * npull)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)
1083 {
1084 	struct ctdb_dbid_map *val;
1085 	size_t offset = 0, np;
1086 	uint32_t i;
1087 	int ret;
1088 
1089 	val = talloc(mem_ctx, struct ctdb_dbid_map);
1090 	if (val == NULL) {
1091 		return ENOMEM;
1092 	}
1093 
1094 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
1095 	if (ret != 0) {
1096 		goto fail;
1097 	}
1098 	offset += np;
1099 
1100 	if (val->num == 0) {
1101 		val->dbs = NULL;
1102 		goto done;
1103 	}
1104 
1105 	val->dbs = talloc_array(val, struct ctdb_dbid, val->num);
1106 	if (val->dbs == NULL) {
1107 		ret = ENOMEM;
1108 		goto fail;
1109 	}
1110 
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;
1116 		}
1117 		offset += np;
1118 	}
1119 
1120 done:
1121 	*out = val;
1122 	*npull = offset;
1123 	return 0;
1124 
1125 fail:
1126 	talloc_free(val);
1127 	return ret;
1128 }
1129 
ctdb_pulldb_len(struct ctdb_pulldb * in)1130 size_t ctdb_pulldb_len(struct ctdb_pulldb *in)
1131 {
1132 	return ctdb_uint32_len(&in->db_id) +
1133 		ctdb_uint32_len(&in->lmaster);
1134 }
1135 
ctdb_pulldb_push(struct ctdb_pulldb * in,uint8_t * buf,size_t * npush)1136 void ctdb_pulldb_push(struct ctdb_pulldb *in, uint8_t *buf, size_t *npush)
1137 {
1138 	size_t offset = 0, np;
1139 
1140 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1141 	offset += np;
1142 
1143 	ctdb_uint32_push(&in->lmaster, buf+offset, &np);
1144 	offset += np;
1145 
1146 	*npush = offset;
1147 }
1148 
ctdb_pulldb_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_pulldb ** out,size_t * npull)1149 int ctdb_pulldb_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1150 		     struct ctdb_pulldb **out, size_t *npull)
1151 {
1152 	struct ctdb_pulldb *val;
1153 	size_t offset = 0, np;
1154 	int ret;
1155 
1156 	val = talloc(mem_ctx, struct ctdb_pulldb);
1157 	if (val == NULL) {
1158 		return ENOMEM;
1159 	}
1160 
1161 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1162 	if (ret != 0) {
1163 		talloc_free(val);
1164 		return ret;
1165 	}
1166 	offset += np;
1167 
1168 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->lmaster, &np);
1169 	if (ret != 0) {
1170 		talloc_free(val);
1171 		return ret;
1172 	}
1173 	offset += np;
1174 
1175 	*out = val;
1176 	*npull = offset;
1177 	return 0;
1178 }
1179 
ctdb_pulldb_ext_len(struct ctdb_pulldb_ext * in)1180 size_t ctdb_pulldb_ext_len(struct ctdb_pulldb_ext *in)
1181 {
1182 	return ctdb_uint32_len(&in->db_id) +
1183 		ctdb_uint32_len(&in->lmaster) +
1184 		ctdb_uint64_len(&in->srvid);
1185 }
1186 
ctdb_pulldb_ext_push(struct ctdb_pulldb_ext * in,uint8_t * buf,size_t * npush)1187 void ctdb_pulldb_ext_push(struct ctdb_pulldb_ext *in, uint8_t *buf,
1188 			  size_t *npush)
1189 {
1190 	size_t offset = 0, np;
1191 
1192 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1193 	offset += np;
1194 
1195 	ctdb_uint32_push(&in->lmaster, buf+offset, &np);
1196 	offset += np;
1197 
1198 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
1199 	offset += np;
1200 
1201 	*npush = offset;
1202 }
1203 
ctdb_pulldb_ext_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_pulldb_ext ** out,size_t * npull)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)
1206 {
1207 	struct ctdb_pulldb_ext *val;
1208 	size_t offset = 0, np;
1209 	int ret;
1210 
1211 	val = talloc(mem_ctx, struct ctdb_pulldb_ext);
1212 	if (val == NULL) {
1213 		return ENOMEM;
1214 	}
1215 
1216 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1217 	if (ret != 0) {
1218 		goto fail;
1219 	}
1220 	offset += np;
1221 
1222 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->lmaster, &np);
1223 	if (ret != 0) {
1224 		goto fail;
1225 	}
1226 	offset += np;
1227 
1228 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
1229 	if (ret != 0) {
1230 		goto fail;
1231 	}
1232 	offset += np;
1233 
1234 	*out = val;
1235 	*npull = offset;
1236 	return 0;
1237 
1238 fail:
1239 	talloc_free(val);
1240 	return ret;
1241 }
1242 
ctdb_db_vacuum_len(struct ctdb_db_vacuum * in)1243 size_t ctdb_db_vacuum_len(struct ctdb_db_vacuum *in)
1244 {
1245 	return ctdb_uint32_len(&in->db_id) +
1246 		ctdb_bool_len(&in->full_vacuum_run);
1247 }
1248 
ctdb_db_vacuum_push(struct ctdb_db_vacuum * in,uint8_t * buf,size_t * npush)1249 void ctdb_db_vacuum_push(struct ctdb_db_vacuum *in,
1250 			 uint8_t *buf,
1251 			 size_t *npush)
1252 {
1253 	size_t offset = 0, np;
1254 
1255 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1256 	offset += np;
1257 
1258 	ctdb_bool_push(&in->full_vacuum_run, buf+offset, &np);
1259 	offset += np;
1260 
1261 	*npush = offset;
1262 }
1263 
ctdb_db_vacuum_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_db_vacuum ** out,size_t * npull)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)
1269 {
1270 	struct ctdb_db_vacuum *val;
1271 	size_t offset = 0, np;
1272 	int ret;
1273 
1274 	val = talloc(mem_ctx, struct ctdb_db_vacuum);
1275 	if (val == NULL) {
1276 		return ENOMEM;
1277 	}
1278 
1279 	ret = ctdb_uint32_pull(buf+offset,
1280 			       buflen-offset,
1281 			       &val->db_id,
1282 			       &np);
1283 	if (ret != 0) {
1284 		goto fail;;
1285 	}
1286 	offset += np;
1287 
1288 	ret = ctdb_bool_pull(buf+offset,
1289 			     buflen-offset,
1290 			     &val->full_vacuum_run,
1291 			     &np);
1292 	if (ret != 0) {
1293 		goto fail;
1294 	}
1295 	offset += np;
1296 
1297 	*out = val;
1298 	*npull = offset;
1299 	return 0;
1300 
1301 fail:
1302 	talloc_free(val);
1303 	return ret;
1304 }
1305 
ctdb_ltdb_header_len(struct ctdb_ltdb_header * in)1306 size_t ctdb_ltdb_header_len(struct ctdb_ltdb_header *in)
1307 {
1308 	return ctdb_uint64_len(&in->rsn) +
1309 		ctdb_uint32_len(&in->dmaster) +
1310 		ctdb_uint32_len(&in->reserved1) +
1311 		ctdb_uint32_len(&in->flags) +
1312 		ctdb_padding_len(4);
1313 }
1314 
ctdb_ltdb_header_push(struct ctdb_ltdb_header * in,uint8_t * buf,size_t * npush)1315 void ctdb_ltdb_header_push(struct ctdb_ltdb_header *in, uint8_t *buf,
1316 			   size_t *npush)
1317 {
1318 	size_t offset = 0, np;
1319 
1320 	ctdb_uint64_push(&in->rsn, buf+offset, &np);
1321 	offset += np;
1322 
1323 	ctdb_uint32_push(&in->dmaster, buf+offset, &np);
1324 	offset += np;
1325 
1326 	ctdb_uint32_push(&in->reserved1, buf+offset, &np);
1327 	offset += np;
1328 
1329 	ctdb_uint32_push(&in->flags, buf+offset, &np);
1330 	offset += np;
1331 
1332 	ctdb_padding_push(4, buf+offset, &np);
1333 	offset += np;
1334 
1335 	*npush = offset;
1336 }
1337 
ctdb_ltdb_header_pull(uint8_t * buf,size_t buflen,struct ctdb_ltdb_header * out,size_t * npull)1338 int ctdb_ltdb_header_pull(uint8_t *buf, size_t buflen,
1339 			  struct ctdb_ltdb_header *out, size_t *npull)
1340 {
1341 	size_t offset = 0, np;
1342 	int ret;
1343 
1344 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &out->rsn, &np);
1345 	if (ret != 0) {
1346 		return ret;
1347 	}
1348 	offset += np;
1349 
1350 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->dmaster, &np);
1351 	if (ret != 0) {
1352 		return ret;
1353 	}
1354 	offset += np;
1355 
1356 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->reserved1,
1357 			       &np);
1358 	if (ret != 0) {
1359 		return ret;
1360 	}
1361 	offset += np;
1362 
1363 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->flags, &np);
1364 	if (ret != 0) {
1365 		return ret;
1366 	}
1367 	offset += np;
1368 
1369 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
1370 	if (ret != 0) {
1371 		return ret;
1372 	}
1373 	offset += np;
1374 
1375 	*npull = offset;
1376 	return 0;
1377 }
1378 
ctdb_ltdb_header_extract(TDB_DATA * data,struct ctdb_ltdb_header * header)1379 int ctdb_ltdb_header_extract(TDB_DATA *data, struct ctdb_ltdb_header *header)
1380 {
1381 	size_t np;
1382 	int ret;
1383 
1384 	ret = ctdb_ltdb_header_pull(data->dptr, data->dsize, header, &np);
1385 	if (ret != 0) {
1386 		return ret;
1387 	}
1388 
1389 	data->dptr += np;
1390 	data->dsize -= np;
1391 
1392 	return 0;
1393 }
1394 
ctdb_rec_data_len(struct ctdb_rec_data * in)1395 size_t ctdb_rec_data_len(struct ctdb_rec_data *in)
1396 {
1397 	uint32_t u32;
1398 
1399 	u32 = ctdb_uint32_len(&in->reqid) +
1400 		ctdb_tdb_datan_len(&in->key) +
1401 		ctdb_tdb_datan_len(&in->data);
1402 
1403 	if (in->header != NULL) {
1404 		u32 += ctdb_ltdb_header_len(in->header);
1405 	}
1406 
1407 	return ctdb_uint32_len(&u32) + u32;
1408 }
1409 
ctdb_rec_data_push(struct ctdb_rec_data * in,uint8_t * buf,size_t * npush)1410 void ctdb_rec_data_push(struct ctdb_rec_data *in, uint8_t *buf, size_t *npush)
1411 {
1412 	size_t offset = 0, np;
1413 	uint32_t u32;
1414 
1415 	u32 = ctdb_rec_data_len(in);
1416 	ctdb_uint32_push(&u32, buf+offset, &np);
1417 	offset += np;
1418 
1419 	ctdb_uint32_push(&in->reqid, buf+offset, &np);
1420 	offset += np;
1421 
1422 	u32 = ctdb_tdb_data_len(&in->key);
1423 	ctdb_uint32_push(&u32, buf+offset, &np);
1424 	offset += np;
1425 
1426 	u32 = ctdb_tdb_data_len(&in->data);
1427 	if (in->header != NULL) {
1428 		u32 += ctdb_ltdb_header_len(in->header);
1429 	}
1430 
1431 	ctdb_uint32_push(&u32, buf+offset, &np);
1432 	offset += np;
1433 
1434 	ctdb_tdb_data_push(&in->key, buf+offset, &np);
1435 	offset += np;
1436 
1437 	/* If ltdb header is not NULL, then it is pushed as part of the data */
1438 	if (in->header != NULL) {
1439 		ctdb_ltdb_header_push(in->header, buf+offset, &np);
1440 		offset += np;
1441 	}
1442 	ctdb_tdb_data_push(&in->data, buf+offset, &np);
1443 	offset += np;
1444 
1445 	*npush = offset;
1446 }
1447 
ctdb_rec_data_pull_data(uint8_t * buf,size_t buflen,uint32_t * reqid,TDB_DATA * key,TDB_DATA * data,size_t * npull)1448 static int ctdb_rec_data_pull_data(uint8_t *buf, size_t buflen,
1449 				   uint32_t *reqid,
1450 				   TDB_DATA *key, TDB_DATA *data,
1451 				   size_t *npull)
1452 {
1453 	size_t offset = 0, np;
1454 	size_t len;
1455 	uint32_t u32;
1456 	int ret;
1457 
1458 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
1459 	if (ret != 0) {
1460 		return ret;
1461 	}
1462 	offset += np;
1463 
1464 	if (buflen < u32) {
1465 		return EMSGSIZE;
1466 	}
1467 	len = u32;
1468 
1469 	ret = ctdb_uint32_pull(buf+offset, len-offset, reqid, &np);
1470 	if (ret != 0) {
1471 		return ret;
1472 	}
1473 	offset += np;
1474 
1475 	ret = ctdb_uint32_pull(buf+offset, len-offset, &u32, &np);
1476 	if (ret != 0) {
1477 		return ret;
1478 	}
1479 	offset += np;
1480 	key->dsize = u32;
1481 
1482 	ret = ctdb_uint32_pull(buf+offset, len-offset, &u32, &np);
1483 	if (ret != 0) {
1484 		return ret;
1485 	}
1486 	offset += np;
1487 	data->dsize = u32;
1488 
1489 	if (len-offset < key->dsize) {
1490 		return EMSGSIZE;
1491 	}
1492 
1493 	key->dptr = buf+offset;
1494 	offset += key->dsize;
1495 
1496 	if (len-offset < data->dsize) {
1497 		return EMSGSIZE;
1498 	}
1499 
1500 	data->dptr = buf+offset;
1501 	offset += data->dsize;
1502 
1503 	*npull = offset;
1504 	return 0;
1505 }
1506 
ctdb_rec_data_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_rec_data * out,size_t * npull)1507 static int ctdb_rec_data_pull_elems(uint8_t *buf, size_t buflen,
1508 				    TALLOC_CTX *mem_ctx,
1509 				    struct ctdb_rec_data *out,
1510 				    size_t *npull)
1511 {
1512 	uint32_t reqid;
1513 	TDB_DATA key, data;
1514 	size_t np;
1515 	int ret;
1516 
1517 	ret = ctdb_rec_data_pull_data(buf, buflen, &reqid, &key, &data, &np);
1518 	if (ret != 0) {
1519 		return ret;
1520 	}
1521 
1522 	out->reqid = reqid;
1523 
1524 	/* Always set header to NULL.  If it is required, extract it using
1525 	 * ctdb_rec_data_extract_header()
1526 	 */
1527 	out->header = NULL;
1528 
1529 	out->key.dsize = key.dsize;
1530 	if (key.dsize > 0) {
1531 		out->key.dptr = talloc_memdup(mem_ctx, key.dptr, key.dsize);
1532 		if (out->key.dptr == NULL) {
1533 			return ENOMEM;
1534 		}
1535 	}
1536 
1537 	out->data.dsize = data.dsize;
1538 	if (data.dsize > 0) {
1539 		out->data.dptr = talloc_memdup(mem_ctx, data.dptr, data.dsize);
1540 		if (out->data.dptr == NULL) {
1541 			return ENOMEM;
1542 		}
1543 	}
1544 
1545 	*npull = np;
1546 	return 0;
1547 }
1548 
ctdb_rec_data_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_rec_data ** out,size_t * npull)1549 int ctdb_rec_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1550 		       struct ctdb_rec_data **out, size_t *npull)
1551 {
1552 	struct ctdb_rec_data *val;
1553 	size_t np;
1554 	int ret;
1555 
1556 	val = talloc(mem_ctx, struct ctdb_rec_data);
1557 	if (val == NULL) {
1558 		return ENOMEM;
1559 	}
1560 
1561 	ret = ctdb_rec_data_pull_elems(buf, buflen, val, val, &np);
1562 	if (ret != 0) {
1563 		TALLOC_FREE(val);
1564 		return ret;
1565 	}
1566 
1567 	*out = val;
1568 	*npull = np;
1569 	return ret;
1570 }
1571 
ctdb_rec_buffer_len(struct ctdb_rec_buffer * in)1572 size_t ctdb_rec_buffer_len(struct ctdb_rec_buffer *in)
1573 {
1574 	return ctdb_uint32_len(&in->db_id) +
1575 		ctdb_uint32_len(&in->count) +
1576 		in->buflen;
1577 }
1578 
ctdb_rec_buffer_push(struct ctdb_rec_buffer * in,uint8_t * buf,size_t * npush)1579 void ctdb_rec_buffer_push(struct ctdb_rec_buffer *in, uint8_t *buf,
1580 			  size_t *npush)
1581 {
1582 	size_t offset = 0, np;
1583 
1584 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1585 	offset += np;
1586 
1587 	ctdb_uint32_push(&in->count, buf+offset, &np);
1588 	offset += np;
1589 
1590 	memcpy(buf+offset, in->buf, in->buflen);
1591 	offset += in->buflen;
1592 
1593 	*npush = offset;
1594 }
1595 
ctdb_rec_buffer_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_rec_buffer ** out,size_t * npull)1596 int ctdb_rec_buffer_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1597 			 struct ctdb_rec_buffer **out, size_t *npull)
1598 {
1599 	struct ctdb_rec_buffer *val;
1600 	size_t offset = 0, np;
1601 	size_t length;
1602 	int ret;
1603 
1604 	val = talloc(mem_ctx, struct ctdb_rec_buffer);
1605 	if (val == NULL) {
1606 		return ENOMEM;
1607 	}
1608 
1609 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1610 	if (ret != 0) {
1611 		goto fail;
1612 	}
1613 	offset += np;
1614 
1615 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->count, &np);
1616 	if (ret != 0) {
1617 		goto fail;
1618 	}
1619 	offset += np;
1620 
1621 	/* Since there is no buflen provided, walk the records to
1622 	 * validate the length of the buffer.
1623 	 */
1624 	val->buf = buf+offset;
1625 	val->buflen = buflen-offset;
1626 
1627 	length = 0;
1628 	ret = ctdb_rec_buffer_traverse(val, NULL, &length);
1629 	if (ret != 0) {
1630 		goto fail;
1631 	}
1632 
1633 	if (length > buflen-offset) {
1634 		ret = EMSGSIZE;
1635 		goto fail;
1636 	}
1637 
1638 	val->buf = talloc_memdup(val, buf+offset, length);
1639 	if (val->buf == NULL) {
1640 		ret = ENOMEM;
1641 		goto fail;
1642 	}
1643 	val->buflen = length;
1644 	offset += length;
1645 
1646 	*out = val;
1647 	*npull = offset;
1648 	return 0;
1649 
1650 fail:
1651 	talloc_free(val);
1652 	return ret;
1653 }
1654 
ctdb_rec_buffer_init(TALLOC_CTX * mem_ctx,uint32_t db_id)1655 struct ctdb_rec_buffer *ctdb_rec_buffer_init(TALLOC_CTX *mem_ctx,
1656 					     uint32_t db_id)
1657 {
1658 	struct ctdb_rec_buffer *recbuf;
1659 
1660 	recbuf = talloc_zero(mem_ctx, struct ctdb_rec_buffer);
1661 	if (recbuf == NULL) {
1662 		return recbuf;
1663 	}
1664 
1665 	recbuf->db_id = db_id;
1666 
1667 	return recbuf;
1668 }
1669 
ctdb_rec_buffer_add(TALLOC_CTX * mem_ctx,struct ctdb_rec_buffer * recbuf,uint32_t reqid,struct ctdb_ltdb_header * header,TDB_DATA key,TDB_DATA data)1670 int ctdb_rec_buffer_add(TALLOC_CTX *mem_ctx, struct ctdb_rec_buffer *recbuf,
1671 			uint32_t reqid, struct ctdb_ltdb_header *header,
1672 			TDB_DATA key, TDB_DATA data)
1673 {
1674 	struct ctdb_rec_data recdata;
1675 	size_t len, np;
1676 	uint8_t *ptr;
1677 
1678 	recdata.reqid = reqid;
1679 	recdata.header = header;
1680 	recdata.key = key;
1681 	recdata.data = data;
1682 
1683 	len = ctdb_rec_data_len(&recdata);
1684 
1685 	ptr = talloc_realloc(mem_ctx, recbuf->buf, uint8_t,
1686 			     recbuf->buflen + len);
1687 	if (ptr == NULL) {
1688 		return ENOMEM;
1689 	}
1690 
1691 	ctdb_rec_data_push(&recdata, &ptr[recbuf->buflen], &np);
1692 
1693 	recbuf->count++;
1694 	recbuf->buf = ptr;
1695 	recbuf->buflen += np;
1696 	return 0;
1697 }
1698 
ctdb_rec_buffer_traverse(struct ctdb_rec_buffer * recbuf,ctdb_rec_parser_func_t func,void * private_data)1699 int ctdb_rec_buffer_traverse(struct ctdb_rec_buffer *recbuf,
1700 			     ctdb_rec_parser_func_t func,
1701 			     void *private_data)
1702 {
1703 	TDB_DATA key, data;
1704 	uint32_t reqid;
1705 	size_t offset, reclen;
1706 	unsigned int i;
1707 	int ret = 0;
1708 
1709 	offset = 0;
1710 	for (i=0; i<recbuf->count; i++) {
1711 		ret = ctdb_rec_data_pull_data(&recbuf->buf[offset],
1712 					      recbuf->buflen - offset,
1713 					      &reqid, &key, &data, &reclen);
1714 		if (ret != 0) {
1715 			return ret;
1716 		}
1717 
1718 		if (func != NULL) {
1719 			ret = func(reqid, NULL, key, data, private_data);
1720 			if (ret != 0) {
1721 				break;
1722 			}
1723 		}
1724 
1725 		offset += reclen;
1726 	}
1727 
1728 	if (ret != 0) {
1729 		return ret;
1730 	}
1731 
1732 	if (func == NULL) {
1733 		size_t *length = (size_t *)private_data;
1734 
1735 		*length = offset;
1736 	}
1737 
1738 	return 0;
1739 }
1740 
ctdb_rec_buffer_write(struct ctdb_rec_buffer * recbuf,int fd)1741 int ctdb_rec_buffer_write(struct ctdb_rec_buffer *recbuf, int fd)
1742 {
1743 	ssize_t n;
1744 
1745 	n = write(fd, &recbuf->db_id, sizeof(uint32_t));
1746 	if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1747 		return (errno != 0 ? errno : EIO);
1748 	}
1749 	n = write(fd, &recbuf->count, sizeof(uint32_t));
1750 	if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1751 		return (errno != 0 ? errno : EIO);
1752 	}
1753 	n = write(fd, &recbuf->buflen, sizeof(size_t));
1754 	if (n == -1 || (size_t)n != sizeof(size_t)) {
1755 		return (errno != 0 ? errno : EIO);
1756 	}
1757 	n = write(fd, recbuf->buf, recbuf->buflen);
1758 	if (n == -1 || (size_t)n != recbuf->buflen) {
1759 		return (errno != 0 ? errno : EIO);
1760 	}
1761 
1762 	return 0;
1763 }
1764 
ctdb_rec_buffer_read(int fd,TALLOC_CTX * mem_ctx,struct ctdb_rec_buffer ** out)1765 int ctdb_rec_buffer_read(int fd, TALLOC_CTX *mem_ctx,
1766 			 struct ctdb_rec_buffer **out)
1767 {
1768 	struct ctdb_rec_buffer *recbuf;
1769 	ssize_t n;
1770 
1771 	recbuf = talloc(mem_ctx, struct ctdb_rec_buffer);
1772 	if (recbuf == NULL) {
1773 		return ENOMEM;
1774 	}
1775 
1776 	n = read(fd, &recbuf->db_id, sizeof(uint32_t));
1777 	if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1778 		return (errno != 0 ? errno : EIO);
1779 	}
1780 	n = read(fd, &recbuf->count, sizeof(uint32_t));
1781 	if (n == -1 || (size_t)n != sizeof(uint32_t)) {
1782 		return (errno != 0 ? errno : EIO);
1783 	}
1784 	n = read(fd, &recbuf->buflen, sizeof(size_t));
1785 	if (n == -1 || (size_t)n != sizeof(size_t)) {
1786 		return (errno != 0 ? errno : EIO);
1787 	}
1788 
1789 	recbuf->buf = talloc_size(recbuf, recbuf->buflen);
1790 	if (recbuf->buf == NULL) {
1791 		return ENOMEM;
1792 	}
1793 
1794 	n = read(fd, recbuf->buf, recbuf->buflen);
1795 	if (n == -1 || (size_t)n != recbuf->buflen) {
1796 		return (errno != 0 ? errno : EIO);
1797 	}
1798 
1799 	*out = recbuf;
1800 	return 0;
1801 }
1802 
ctdb_traverse_start_len(struct ctdb_traverse_start * in)1803 size_t ctdb_traverse_start_len(struct ctdb_traverse_start *in)
1804 {
1805 	return ctdb_uint32_len(&in->db_id) +
1806 		ctdb_uint32_len(&in->reqid) +
1807 		ctdb_uint64_len(&in->srvid);
1808 }
1809 
ctdb_traverse_start_push(struct ctdb_traverse_start * in,uint8_t * buf,size_t * npush)1810 void ctdb_traverse_start_push(struct ctdb_traverse_start *in, uint8_t *buf,
1811 			      size_t *npush)
1812 {
1813 	size_t offset = 0, np;
1814 
1815 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1816 	offset += np;
1817 
1818 	ctdb_uint32_push(&in->reqid, buf+offset, &np);
1819 	offset += np;
1820 
1821 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
1822 	offset += np;
1823 
1824 	*npush = offset;
1825 }
1826 
ctdb_traverse_start_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_traverse_start ** out,size_t * npull)1827 int ctdb_traverse_start_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1828 			     struct ctdb_traverse_start **out, size_t *npull)
1829 {
1830 	struct ctdb_traverse_start *val;
1831 	size_t offset = 0, np;
1832 	int ret;
1833 
1834 	val = talloc(mem_ctx, struct ctdb_traverse_start);
1835 	if (val == NULL) {
1836 		return ENOMEM;
1837 	}
1838 
1839 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1840 	if (ret != 0) {
1841 		goto fail;
1842 	}
1843 	offset += np;
1844 
1845 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
1846 	if (ret != 0) {
1847 		goto fail;
1848 	}
1849 	offset += np;
1850 
1851 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
1852 	if (ret != 0) {
1853 		goto fail;
1854 	}
1855 	offset += np;
1856 
1857 	*out = val;
1858 	*npull = offset;
1859 	return 0;
1860 
1861 fail:
1862 	talloc_free(val);
1863 	return ret;
1864 }
1865 
ctdb_traverse_all_len(struct ctdb_traverse_all * in)1866 size_t ctdb_traverse_all_len(struct ctdb_traverse_all *in)
1867 {
1868 	return ctdb_uint32_len(&in->db_id) +
1869 		ctdb_uint32_len(&in->reqid) +
1870 		ctdb_uint32_len(&in->pnn) +
1871 		ctdb_uint32_len(&in->client_reqid) +
1872 		ctdb_uint64_len(&in->srvid);
1873 }
1874 
ctdb_traverse_all_push(struct ctdb_traverse_all * in,uint8_t * buf,size_t * npush)1875 void ctdb_traverse_all_push(struct ctdb_traverse_all *in, uint8_t *buf,
1876 			    size_t *npush)
1877 {
1878 	size_t offset = 0, np;
1879 
1880 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1881 	offset += np;
1882 
1883 	ctdb_uint32_push(&in->reqid, buf+offset, &np);
1884 	offset += np;
1885 
1886 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
1887 	offset += np;
1888 
1889 	ctdb_uint32_push(&in->client_reqid, buf+offset, &np);
1890 	offset += np;
1891 
1892 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
1893 	offset += np;
1894 
1895 	*npush = offset;
1896 }
1897 
ctdb_traverse_all_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_traverse_all ** out,size_t * npull)1898 int ctdb_traverse_all_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
1899 			   struct ctdb_traverse_all **out, size_t *npull)
1900 {
1901 	struct ctdb_traverse_all *val;
1902 	size_t offset = 0, np;
1903 	int ret;
1904 
1905 	val = talloc(mem_ctx, struct ctdb_traverse_all);
1906 	if (val == NULL) {
1907 		return ENOMEM;
1908 	}
1909 
1910 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1911 	if (ret != 0) {
1912 		goto fail;
1913 	}
1914 	offset += np;
1915 
1916 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
1917 	if (ret != 0) {
1918 		goto fail;
1919 	}
1920 	offset += np;
1921 
1922 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
1923 	if (ret != 0) {
1924 		goto fail;
1925 	}
1926 	offset += np;
1927 
1928 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->client_reqid,
1929 			       &np);
1930 	if (ret != 0) {
1931 		goto fail;
1932 	}
1933 	offset += np;
1934 
1935 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
1936 	if (ret != 0) {
1937 		goto fail;
1938 	}
1939 	offset += np;
1940 
1941 	*out = val;
1942 	*npull = offset;
1943 	return 0;
1944 
1945 fail:
1946 	talloc_free(val);
1947 	return ret;
1948 }
1949 
ctdb_traverse_start_ext_len(struct ctdb_traverse_start_ext * in)1950 size_t ctdb_traverse_start_ext_len(struct ctdb_traverse_start_ext *in)
1951 {
1952 	return ctdb_uint32_len(&in->db_id) +
1953 		ctdb_uint32_len(&in->reqid) +
1954 		ctdb_uint64_len(&in->srvid) +
1955 		ctdb_bool_len(&in->withemptyrecords) +
1956 		ctdb_padding_len(7);
1957 }
1958 
ctdb_traverse_start_ext_push(struct ctdb_traverse_start_ext * in,uint8_t * buf,size_t * npush)1959 void ctdb_traverse_start_ext_push(struct ctdb_traverse_start_ext *in,
1960 				  uint8_t *buf, size_t *npush)
1961 {
1962 	size_t offset = 0, np;
1963 
1964 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
1965 	offset += np;
1966 
1967 	ctdb_uint32_push(&in->reqid, buf+offset, &np);
1968 	offset += np;
1969 
1970 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
1971 	offset += np;
1972 
1973 	ctdb_bool_push(&in->withemptyrecords, buf+offset, &np);
1974 	offset += np;
1975 
1976 	ctdb_padding_push(7, buf+offset, &np);
1977 	offset += np;
1978 
1979 	*npush = offset;
1980 }
1981 
ctdb_traverse_start_ext_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_traverse_start_ext ** out,size_t * npull)1982 int ctdb_traverse_start_ext_pull(uint8_t *buf, size_t buflen,
1983 				 TALLOC_CTX *mem_ctx,
1984 				 struct ctdb_traverse_start_ext **out,
1985 				 size_t *npull)
1986 {
1987 	struct ctdb_traverse_start_ext *val;
1988 	size_t offset = 0, np;
1989 	int ret;
1990 
1991 	val = talloc(mem_ctx, struct ctdb_traverse_start_ext);
1992 	if (val == NULL) {
1993 		return ENOMEM;
1994 	}
1995 
1996 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
1997 	if (ret != 0) {
1998 		goto fail;
1999 	}
2000 	offset += np;
2001 
2002 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
2003 	if (ret != 0) {
2004 		goto fail;
2005 	}
2006 	offset += np;
2007 
2008 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
2009 	if (ret != 0) {
2010 		goto fail;
2011 	}
2012 	offset += np;
2013 
2014 	ret = ctdb_bool_pull(buf+offset, buflen-offset,
2015 			     &val->withemptyrecords, &np);
2016 	if (ret != 0) {
2017 		goto fail;
2018 	}
2019 	offset += np;
2020 
2021 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 7, &np);
2022 	if (ret != 0) {
2023 		goto fail;
2024 	}
2025 	offset += np;
2026 
2027 	*out = val;
2028 	*npull = offset;
2029 	return 0;
2030 
2031 fail:
2032 	talloc_free(val);
2033 	return ret;
2034 }
2035 
ctdb_traverse_all_ext_len(struct ctdb_traverse_all_ext * in)2036 size_t ctdb_traverse_all_ext_len(struct ctdb_traverse_all_ext *in)
2037 {
2038 	return ctdb_uint32_len(&in->db_id) +
2039 		ctdb_uint32_len(&in->reqid) +
2040 		ctdb_uint32_len(&in->pnn) +
2041 		ctdb_uint32_len(&in->client_reqid) +
2042 		ctdb_uint64_len(&in->srvid) +
2043 		ctdb_bool_len(&in->withemptyrecords) +
2044 		ctdb_padding_len(7);
2045 }
2046 
ctdb_traverse_all_ext_push(struct ctdb_traverse_all_ext * in,uint8_t * buf,size_t * npush)2047 void ctdb_traverse_all_ext_push(struct ctdb_traverse_all_ext *in,
2048 				uint8_t *buf, size_t *npush)
2049 {
2050 	size_t offset = 0, np;
2051 
2052 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
2053 	offset += np;
2054 
2055 	ctdb_uint32_push(&in->reqid, buf+offset, &np);
2056 	offset += np;
2057 
2058 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
2059 	offset += np;
2060 
2061 	ctdb_uint32_push(&in->client_reqid, buf+offset, &np);
2062 	offset += np;
2063 
2064 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
2065 	offset += np;
2066 
2067 	ctdb_bool_push(&in->withemptyrecords, buf+offset, &np);
2068 	offset += np;
2069 
2070 	ctdb_padding_push(7, buf+offset, &np);
2071 	offset += np;
2072 
2073 	*npush = offset;
2074 }
2075 
ctdb_traverse_all_ext_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_traverse_all_ext ** out,size_t * npull)2076 int ctdb_traverse_all_ext_pull(uint8_t *buf, size_t buflen,
2077 			       TALLOC_CTX *mem_ctx,
2078 			       struct ctdb_traverse_all_ext **out,
2079 			       size_t *npull)
2080 {
2081 	struct ctdb_traverse_all_ext *val;
2082 	size_t offset = 0, np;
2083 	int ret;
2084 
2085 	val = talloc(mem_ctx, struct ctdb_traverse_all_ext);
2086 	if (val == NULL) {
2087 		return ENOMEM;
2088 	}
2089 
2090 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
2091 	if (ret != 0) {
2092 		goto fail;
2093 	}
2094 	offset += np;
2095 
2096 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->reqid, &np);
2097 	if (ret != 0) {
2098 		goto fail;
2099 	}
2100 	offset += np;
2101 
2102 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
2103 	if (ret != 0) {
2104 		goto fail;
2105 	}
2106 	offset += np;
2107 
2108 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->client_reqid,
2109 			       &np);
2110 	if (ret != 0) {
2111 		goto fail;
2112 	}
2113 	offset += np;
2114 
2115 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
2116 	if (ret != 0) {
2117 		goto fail;
2118 	}
2119 	offset += np;
2120 
2121 	ret = ctdb_bool_pull(buf+offset, buflen-offset,
2122 			     &val->withemptyrecords, &np);
2123 	if (ret != 0) {
2124 		goto fail;
2125 	}
2126 	offset += np;
2127 
2128 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 7, &np);
2129 	if (ret != 0) {
2130 		goto fail;
2131 	}
2132 	offset += np;
2133 
2134 	*out = val;
2135 	*npull = offset;
2136 	return 0;
2137 
2138 fail:
2139 	talloc_free(val);
2140 	return ret;
2141 }
2142 
ctdb_sock_addr_len(ctdb_sock_addr * in)2143 size_t ctdb_sock_addr_len(ctdb_sock_addr *in)
2144 {
2145 	return sizeof(ctdb_sock_addr);
2146 }
2147 
ctdb_sock_addr_push(ctdb_sock_addr * in,uint8_t * buf,size_t * npush)2148 void ctdb_sock_addr_push(ctdb_sock_addr *in, uint8_t *buf, size_t *npush)
2149 {
2150 	memcpy(buf, in, sizeof(ctdb_sock_addr));
2151 	*npush = sizeof(ctdb_sock_addr);
2152 }
2153 
ctdb_sock_addr_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,ctdb_sock_addr * out,size_t * npull)2154 int ctdb_sock_addr_pull_elems(uint8_t *buf, size_t buflen,
2155 			      TALLOC_CTX *mem_ctx, ctdb_sock_addr *out,
2156 			      size_t *npull)
2157 {
2158 	if (buflen < sizeof(ctdb_sock_addr)) {
2159 		return EMSGSIZE;
2160 	}
2161 
2162 	memcpy(out, buf, sizeof(ctdb_sock_addr));
2163 	*npull = sizeof(ctdb_sock_addr);
2164 
2165 	return 0;
2166 }
2167 
ctdb_sock_addr_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,ctdb_sock_addr ** out,size_t * npull)2168 int ctdb_sock_addr_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2169 			ctdb_sock_addr **out, size_t *npull)
2170 {
2171 	ctdb_sock_addr *val;
2172 	size_t np;
2173 	int ret;
2174 
2175 	val = talloc(mem_ctx, ctdb_sock_addr);
2176 	if (val == NULL) {
2177 		return ENOMEM;
2178 	}
2179 
2180 	ret = ctdb_sock_addr_pull_elems(buf, buflen, val, val, &np);
2181 	if (ret != 0) {
2182 		talloc_free(val);
2183 		return ret;
2184 	}
2185 
2186 	*out = val;
2187 	*npull = np;
2188 	return ret;
2189 }
2190 
ctdb_connection_len(struct ctdb_connection * in)2191 size_t ctdb_connection_len(struct ctdb_connection *in)
2192 {
2193 	return ctdb_sock_addr_len(&in->src) +
2194 		ctdb_sock_addr_len(&in->dst);
2195 }
2196 
ctdb_connection_push(struct ctdb_connection * in,uint8_t * buf,size_t * npush)2197 void ctdb_connection_push(struct ctdb_connection *in, uint8_t *buf,
2198 			  size_t *npush)
2199 {
2200 	size_t offset = 0, np;
2201 
2202 	ctdb_sock_addr_push(&in->src, buf+offset, &np);
2203 	offset += np;
2204 
2205 	ctdb_sock_addr_push(&in->dst, buf+offset, &np);
2206 	offset += np;
2207 
2208 	*npush = offset;
2209 }
2210 
ctdb_connection_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_connection * out,size_t * npull)2211 static int ctdb_connection_pull_elems(uint8_t *buf, size_t buflen,
2212 				      TALLOC_CTX *mem_ctx,
2213 				      struct ctdb_connection *out,
2214 				      size_t *npull)
2215 {
2216 	size_t offset = 0, np;
2217 	int ret;
2218 
2219 	ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset,
2220 					mem_ctx, &out->src, &np);
2221 	if (ret != 0) {
2222 		return ret;
2223 	}
2224 	offset += np;
2225 
2226 	ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset,
2227 					mem_ctx, &out->dst, &np);
2228 	if (ret != 0) {
2229 		return ret;
2230 	}
2231 	offset += np;
2232 
2233 	*npull = offset;
2234 	return 0;
2235 }
2236 
ctdb_connection_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_connection ** out,size_t * npull)2237 int ctdb_connection_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2238 			 struct ctdb_connection **out, size_t *npull)
2239 {
2240 	struct ctdb_connection *val;
2241 	size_t np;
2242 	int ret;
2243 
2244 	val = talloc(mem_ctx, struct ctdb_connection);
2245 	if (val == NULL) {
2246 		return ENOMEM;
2247 	}
2248 
2249 	ret = ctdb_connection_pull_elems(buf, buflen, val, val, &np);
2250 	if (ret != 0) {
2251 		talloc_free(val);
2252 		return ret;
2253 	}
2254 
2255 	*out = val;
2256 	*npull = np;
2257 	return ret;
2258 }
2259 
ctdb_connection_list_len(struct ctdb_connection_list * in)2260 size_t ctdb_connection_list_len(struct ctdb_connection_list *in)
2261 {
2262 	size_t len;
2263 
2264 	len = ctdb_uint32_len(&in->num);
2265 	if (in->num > 0) {
2266 		len += in->num * ctdb_connection_len(&in->conn[0]);
2267 	}
2268 
2269 	return len;
2270 }
2271 
ctdb_connection_list_push(struct ctdb_connection_list * in,uint8_t * buf,size_t * npush)2272 void ctdb_connection_list_push(struct ctdb_connection_list *in, uint8_t *buf,
2273 			       size_t *npush)
2274 {
2275 	size_t offset = 0, np;
2276 	uint32_t i;
2277 
2278 	ctdb_uint32_push(&in->num, buf+offset, &np);
2279 	offset += np;
2280 
2281 	for (i=0; i<in->num; i++) {
2282 		ctdb_connection_push(&in->conn[i], buf+offset, &np);
2283 		offset += np;
2284 	}
2285 
2286 	*npush = offset;
2287 }
2288 
ctdb_connection_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_connection_list ** out,size_t * npull)2289 int ctdb_connection_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2290 			      struct ctdb_connection_list **out, size_t *npull)
2291 {
2292 	struct ctdb_connection_list *val;
2293 	size_t offset = 0, np;
2294 	uint32_t i;
2295 	int ret;
2296 
2297 	val = talloc(mem_ctx, struct ctdb_connection_list);
2298 	if (val == NULL) {
2299 		return ENOMEM;
2300 	}
2301 
2302 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
2303 	if (ret != 0) {
2304 		goto fail;
2305 	}
2306 	offset += np;
2307 
2308 	if (val->num == 0) {
2309 		val->conn = NULL;
2310 		goto done;
2311 	}
2312 
2313 	val->conn = talloc_array(val, struct ctdb_connection, val->num);
2314 	if (val->conn == NULL) {
2315 		ret = ENOMEM;
2316 		goto fail;
2317 	}
2318 
2319 	for (i=0; i<val->num; i++) {
2320 		ret = ctdb_connection_pull_elems(buf+offset, buflen-offset,
2321 						 val, &val->conn[i], &np);
2322 		if (ret != 0) {
2323 			goto fail;
2324 		}
2325 		offset += np;
2326 	}
2327 
2328 done:
2329 	*out = val;
2330 	*npull = offset;
2331 	return 0;
2332 
2333 fail:
2334 	talloc_free(val);
2335 	return ret;
2336 }
2337 
ctdb_tunable_len(struct ctdb_tunable * in)2338 size_t ctdb_tunable_len(struct ctdb_tunable *in)
2339 {
2340 	return ctdb_uint32_len(&in->value) +
2341 		ctdb_stringn_len(&in->name);
2342 }
2343 
ctdb_tunable_push(struct ctdb_tunable * in,uint8_t * buf,size_t * npush)2344 void ctdb_tunable_push(struct ctdb_tunable *in, uint8_t *buf, size_t *npush)
2345 {
2346 	size_t offset = 0, np;
2347 
2348 	ctdb_uint32_push(&in->value, buf+offset, &np);
2349 	offset += np;
2350 
2351 	ctdb_stringn_push(&in->name, buf+offset, &np);
2352 	offset += np;
2353 
2354 	*npush = offset;
2355 }
2356 
ctdb_tunable_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_tunable ** out,size_t * npull)2357 int ctdb_tunable_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2358 		      struct ctdb_tunable **out, size_t *npull)
2359 {
2360 	struct ctdb_tunable *val;
2361 	size_t offset = 0, np;
2362 	int ret;
2363 
2364 	val = talloc(mem_ctx, struct ctdb_tunable);
2365 	if (val == NULL) {
2366 		return ENOMEM;
2367 	}
2368 
2369 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->value, &np);
2370 	if (ret != 0) {
2371 		goto fail;
2372 	}
2373 	offset += np;
2374 
2375 	ret = ctdb_stringn_pull(buf+offset, buflen-offset, mem_ctx,
2376 				&val->name, &np);
2377 	if (ret != 0) {
2378 		goto fail;
2379 	}
2380 	offset += np;
2381 
2382 	*out = val;
2383 	*npull = offset;
2384 	return 0;
2385 
2386 fail:
2387 	talloc_free(val);
2388 	return ret;
2389 }
2390 
ctdb_node_flag_change_len(struct ctdb_node_flag_change * in)2391 size_t ctdb_node_flag_change_len(struct ctdb_node_flag_change *in)
2392 {
2393 	return ctdb_uint32_len(&in->pnn) +
2394 		ctdb_uint32_len(&in->new_flags) +
2395 		ctdb_uint32_len(&in->old_flags);
2396 }
2397 
ctdb_node_flag_change_push(struct ctdb_node_flag_change * in,uint8_t * buf,size_t * npush)2398 void ctdb_node_flag_change_push(struct ctdb_node_flag_change *in,
2399 				uint8_t *buf, size_t *npush)
2400 {
2401 	size_t offset = 0, np;
2402 
2403 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
2404 	offset += np;
2405 
2406 	ctdb_uint32_push(&in->new_flags, buf+offset, &np);
2407 	offset += np;
2408 
2409 	ctdb_uint32_push(&in->old_flags, buf+offset, &np);
2410 	offset += np;
2411 
2412 	*npush = offset;
2413 }
2414 
ctdb_node_flag_change_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_node_flag_change ** out,size_t * npull)2415 int ctdb_node_flag_change_pull(uint8_t *buf, size_t buflen,
2416 			       TALLOC_CTX *mem_ctx,
2417 			       struct ctdb_node_flag_change **out,
2418 			       size_t *npull)
2419 {
2420 	struct ctdb_node_flag_change *val;
2421 	size_t offset = 0, np;
2422 	int ret;
2423 
2424 	val = talloc(mem_ctx, struct ctdb_node_flag_change);
2425 	if (val == NULL) {
2426 		return ENOMEM;
2427 	}
2428 
2429 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
2430 	if (ret != 0) {
2431 		goto fail;
2432 	}
2433 	offset += np;
2434 
2435 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->new_flags,
2436 			       &np);
2437 	if (ret != 0) {
2438 		goto fail;
2439 	}
2440 	offset += np;
2441 
2442 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->old_flags,
2443 			       &np);
2444 	if (ret != 0) {
2445 		goto fail;
2446 	}
2447 	offset += np;
2448 
2449 	*out = val;
2450 	*npull = offset;
2451 	return 0;
2452 
2453 fail:
2454 	talloc_free(val);
2455 	return ret;
2456 }
2457 
ctdb_var_list_len(struct ctdb_var_list * in)2458 size_t ctdb_var_list_len(struct ctdb_var_list *in)
2459 {
2460 	uint32_t u32 = 0;
2461 	int i;
2462 
2463 	for (i=0; i<in->count; i++) {
2464 		u32 += ctdb_string_len(&in->var[i]);
2465 	}
2466 
2467 	return ctdb_uint32_len(&u32) + u32;
2468 }
2469 
ctdb_var_list_push(struct ctdb_var_list * in,uint8_t * buf,size_t * npush)2470 void ctdb_var_list_push(struct ctdb_var_list *in, uint8_t *buf, size_t *npush)
2471 {
2472 	size_t offset = 0, np;
2473 	uint32_t u32;
2474 	int i;
2475 	uint8_t sep = ':';
2476 
2477 	/* The length only corresponds to the payload size */
2478 	u32 = ctdb_var_list_len(in);
2479 	u32 -= ctdb_uint32_len(&u32);
2480 
2481 	ctdb_uint32_push(&u32, buf+offset, &np);
2482 	offset += np;
2483 
2484 	/* The variables are separated by ':' and the complete string is null
2485 	 * terminated.
2486 	 */
2487 	for (i=0; i<in->count; i++) {
2488 		ctdb_string_push(&in->var[i], buf+offset, &np);
2489 		offset += np;
2490 
2491 		if (i < in->count - 1) {
2492 			/* Replace '\0' with ':' */
2493 			ctdb_uint8_push(&sep, buf+offset-1, &np);
2494 		}
2495 	}
2496 
2497 	*npush = offset;
2498 }
2499 
ctdb_var_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_var_list ** out,size_t * npull)2500 int ctdb_var_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
2501 		       struct ctdb_var_list **out, size_t *npull)
2502 {
2503 	struct ctdb_var_list *val;
2504 	const char *str, **list;
2505 	char *s, *tok, *ptr = NULL;
2506 	size_t offset = 0, np;
2507 	uint32_t u32;
2508 	int ret;
2509 
2510 	val = talloc_zero(mem_ctx, struct ctdb_var_list);
2511 	if (val == NULL) {
2512 		return ENOMEM;
2513 	}
2514 
2515 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &u32, &np);
2516 	if (ret != 0) {
2517 		goto fail;
2518 	}
2519 	offset += np;
2520 
2521 	if (buflen-offset < u32) {
2522 		ret = EMSGSIZE;
2523 		goto fail;
2524 	}
2525 
2526 	ret = ctdb_string_pull(buf+offset, u32, val, &str, &np);
2527 	if (ret != 0) {
2528 		goto fail;
2529 	}
2530 	offset += np;
2531 
2532 	s = discard_const(str);
2533 	while ((tok = strtok_r(s, ":", &ptr)) != NULL) {
2534 		list = talloc_realloc(val, val->var, const char *,
2535 				      val->count+1);
2536 		if (list == NULL) {
2537 			ret = ENOMEM;
2538 			goto fail;
2539 		}
2540 
2541 		val->var = list;
2542 
2543 		s = talloc_strdup(val, tok);
2544 		if (s == NULL) {
2545 			ret = ENOMEM;
2546 			goto fail;
2547 		}
2548 
2549 		val->var[val->count] = s;
2550 		val->count += 1;
2551 		s = NULL;
2552 	}
2553 
2554 	talloc_free(discard_const(str));
2555 	*out = val;
2556 	*npull = offset;
2557 	return 0;
2558 
2559 fail:
2560 	talloc_free(val);
2561 	return ret;
2562 }
2563 
ctdb_tunable_list_len(struct ctdb_tunable_list * in)2564 size_t ctdb_tunable_list_len(struct ctdb_tunable_list *in)
2565 {
2566 	return ctdb_uint32_len(&in->max_redirect_count) +
2567 		ctdb_uint32_len(&in->seqnum_interval) +
2568 		ctdb_uint32_len(&in->control_timeout) +
2569 		ctdb_uint32_len(&in->traverse_timeout) +
2570 		ctdb_uint32_len(&in->keepalive_interval) +
2571 		ctdb_uint32_len(&in->keepalive_limit) +
2572 		ctdb_uint32_len(&in->recover_timeout) +
2573 		ctdb_uint32_len(&in->recover_interval) +
2574 		ctdb_uint32_len(&in->election_timeout) +
2575 		ctdb_uint32_len(&in->takeover_timeout) +
2576 		ctdb_uint32_len(&in->monitor_interval) +
2577 		ctdb_uint32_len(&in->tickle_update_interval) +
2578 		ctdb_uint32_len(&in->script_timeout) +
2579 		ctdb_uint32_len(&in->monitor_timeout_count) +
2580 		ctdb_uint32_len(&in->script_unhealthy_on_timeout) +
2581 		ctdb_uint32_len(&in->recovery_grace_period) +
2582 		ctdb_uint32_len(&in->recovery_ban_period) +
2583 		ctdb_uint32_len(&in->database_hash_size) +
2584 		ctdb_uint32_len(&in->database_max_dead) +
2585 		ctdb_uint32_len(&in->rerecovery_timeout) +
2586 		ctdb_uint32_len(&in->enable_bans) +
2587 		ctdb_uint32_len(&in->deterministic_public_ips) +
2588 		ctdb_uint32_len(&in->reclock_ping_period) +
2589 		ctdb_uint32_len(&in->no_ip_failback) +
2590 		ctdb_uint32_len(&in->disable_ip_failover) +
2591 		ctdb_uint32_len(&in->verbose_memory_names) +
2592 		ctdb_uint32_len(&in->recd_ping_timeout) +
2593 		ctdb_uint32_len(&in->recd_ping_failcount) +
2594 		ctdb_uint32_len(&in->log_latency_ms) +
2595 		ctdb_uint32_len(&in->reclock_latency_ms) +
2596 		ctdb_uint32_len(&in->recovery_drop_all_ips) +
2597 		ctdb_uint32_len(&in->verify_recovery_lock) +
2598 		ctdb_uint32_len(&in->vacuum_interval) +
2599 		ctdb_uint32_len(&in->vacuum_max_run_time) +
2600 		ctdb_uint32_len(&in->repack_limit) +
2601 		ctdb_uint32_len(&in->vacuum_limit) +
2602 		ctdb_uint32_len(&in->max_queue_depth_drop_msg) +
2603 		ctdb_uint32_len(&in->allow_unhealthy_db_read) +
2604 		ctdb_uint32_len(&in->stat_history_interval) +
2605 		ctdb_uint32_len(&in->deferred_attach_timeout) +
2606 		ctdb_uint32_len(&in->vacuum_fast_path_count) +
2607 		ctdb_uint32_len(&in->lcp2_public_ip_assignment) +
2608 		ctdb_uint32_len(&in->allow_client_db_attach) +
2609 		ctdb_uint32_len(&in->recover_pdb_by_seqnum) +
2610 		ctdb_uint32_len(&in->deferred_rebalance_on_node_add) +
2611 		ctdb_uint32_len(&in->fetch_collapse) +
2612 		ctdb_uint32_len(&in->hopcount_make_sticky) +
2613 		ctdb_uint32_len(&in->sticky_duration) +
2614 		ctdb_uint32_len(&in->sticky_pindown) +
2615 		ctdb_uint32_len(&in->no_ip_takeover) +
2616 		ctdb_uint32_len(&in->db_record_count_warn) +
2617 		ctdb_uint32_len(&in->db_record_size_warn) +
2618 		ctdb_uint32_len(&in->db_size_warn) +
2619 		ctdb_uint32_len(&in->pulldb_preallocation_size) +
2620 		ctdb_uint32_len(&in->no_ip_host_on_all_disabled) +
2621 		ctdb_uint32_len(&in->samba3_hack) +
2622 		ctdb_uint32_len(&in->mutex_enabled) +
2623 		ctdb_uint32_len(&in->lock_processes_per_db) +
2624 		ctdb_uint32_len(&in->rec_buffer_size_limit) +
2625 		ctdb_uint32_len(&in->queue_buffer_size) +
2626 		ctdb_uint32_len(&in->ip_alloc_algorithm) +
2627 		ctdb_uint32_len(&in->allow_mixed_versions);
2628 }
2629 
ctdb_tunable_list_push(struct ctdb_tunable_list * in,uint8_t * buf,size_t * npush)2630 void ctdb_tunable_list_push(struct ctdb_tunable_list *in, uint8_t *buf,
2631 			    size_t *npush)
2632 {
2633 	size_t offset = 0, np;
2634 
2635 	ctdb_uint32_push(&in->max_redirect_count, buf+offset, &np);
2636 	offset += np;
2637 
2638 	ctdb_uint32_push(&in->seqnum_interval, buf+offset, &np);
2639 	offset += np;
2640 
2641 	ctdb_uint32_push(&in->control_timeout, buf+offset, &np);
2642 	offset += np;
2643 
2644 	ctdb_uint32_push(&in->traverse_timeout, buf+offset, &np);
2645 	offset += np;
2646 
2647 	ctdb_uint32_push(&in->keepalive_interval, buf+offset, &np);
2648 	offset += np;
2649 
2650 	ctdb_uint32_push(&in->keepalive_limit, buf+offset, &np);
2651 	offset += np;
2652 
2653 	ctdb_uint32_push(&in->recover_timeout, buf+offset, &np);
2654 	offset += np;
2655 
2656 	ctdb_uint32_push(&in->recover_interval, buf+offset, &np);
2657 	offset += np;
2658 
2659 	ctdb_uint32_push(&in->election_timeout, buf+offset, &np);
2660 	offset += np;
2661 
2662 	ctdb_uint32_push(&in->takeover_timeout, buf+offset, &np);
2663 	offset += np;
2664 
2665 	ctdb_uint32_push(&in->monitor_interval, buf+offset, &np);
2666 	offset += np;
2667 
2668 	ctdb_uint32_push(&in->tickle_update_interval, buf+offset, &np);
2669 	offset += np;
2670 
2671 	ctdb_uint32_push(&in->script_timeout, buf+offset, &np);
2672 	offset += np;
2673 
2674 	ctdb_uint32_push(&in->monitor_timeout_count, buf+offset, &np);
2675 	offset += np;
2676 
2677 	ctdb_uint32_push(&in->script_unhealthy_on_timeout, buf+offset, &np);
2678 	offset += np;
2679 
2680 	ctdb_uint32_push(&in->recovery_grace_period, buf+offset, &np);
2681 	offset += np;
2682 
2683 	ctdb_uint32_push(&in->recovery_ban_period, buf+offset, &np);
2684 	offset += np;
2685 
2686 	ctdb_uint32_push(&in->database_hash_size, buf+offset, &np);
2687 	offset += np;
2688 
2689 	ctdb_uint32_push(&in->database_max_dead, buf+offset, &np);
2690 	offset += np;
2691 
2692 	ctdb_uint32_push(&in->rerecovery_timeout, buf+offset, &np);
2693 	offset += np;
2694 
2695 	ctdb_uint32_push(&in->enable_bans, buf+offset, &np);
2696 	offset += np;
2697 
2698 	ctdb_uint32_push(&in->deterministic_public_ips, buf+offset, &np);
2699 	offset += np;
2700 
2701 	ctdb_uint32_push(&in->reclock_ping_period, buf+offset, &np);
2702 	offset += np;
2703 
2704 	ctdb_uint32_push(&in->no_ip_failback, buf+offset, &np);
2705 	offset += np;
2706 
2707 	ctdb_uint32_push(&in->disable_ip_failover, buf+offset, &np);
2708 	offset += np;
2709 
2710 	ctdb_uint32_push(&in->verbose_memory_names, buf+offset, &np);
2711 	offset += np;
2712 
2713 	ctdb_uint32_push(&in->recd_ping_timeout, buf+offset, &np);
2714 	offset += np;
2715 
2716 	ctdb_uint32_push(&in->recd_ping_failcount, buf+offset, &np);
2717 	offset += np;
2718 
2719 	ctdb_uint32_push(&in->log_latency_ms, buf+offset, &np);
2720 	offset += np;
2721 
2722 	ctdb_uint32_push(&in->reclock_latency_ms, buf+offset, &np);
2723 	offset += np;
2724 
2725 	ctdb_uint32_push(&in->recovery_drop_all_ips, buf+offset, &np);
2726 	offset += np;
2727 
2728 	ctdb_uint32_push(&in->verify_recovery_lock, buf+offset, &np);
2729 	offset += np;
2730 
2731 	ctdb_uint32_push(&in->vacuum_interval, buf+offset, &np);
2732 	offset += np;
2733 
2734 	ctdb_uint32_push(&in->vacuum_max_run_time, buf+offset, &np);
2735 	offset += np;
2736 
2737 	ctdb_uint32_push(&in->repack_limit, buf+offset, &np);
2738 	offset += np;
2739 
2740 	ctdb_uint32_push(&in->vacuum_limit, buf+offset, &np);
2741 	offset += np;
2742 
2743 	ctdb_uint32_push(&in->max_queue_depth_drop_msg, buf+offset, &np);
2744 	offset += np;
2745 
2746 	ctdb_uint32_push(&in->allow_unhealthy_db_read, buf+offset, &np);
2747 	offset += np;
2748 
2749 	ctdb_uint32_push(&in->stat_history_interval, buf+offset, &np);
2750 	offset += np;
2751 
2752 	ctdb_uint32_push(&in->deferred_attach_timeout, buf+offset, &np);
2753 	offset += np;
2754 
2755 	ctdb_uint32_push(&in->vacuum_fast_path_count, buf+offset, &np);
2756 	offset += np;
2757 
2758 	ctdb_uint32_push(&in->lcp2_public_ip_assignment, buf+offset, &np);
2759 	offset += np;
2760 
2761 	ctdb_uint32_push(&in->allow_client_db_attach, buf+offset, &np);
2762 	offset += np;
2763 
2764 	ctdb_uint32_push(&in->recover_pdb_by_seqnum, buf+offset, &np);
2765 	offset += np;
2766 
2767 	ctdb_uint32_push(&in->deferred_rebalance_on_node_add, buf+offset, &np);
2768 	offset += np;
2769 
2770 	ctdb_uint32_push(&in->fetch_collapse, buf+offset, &np);
2771 	offset += np;
2772 
2773 	ctdb_uint32_push(&in->hopcount_make_sticky, buf+offset, &np);
2774 	offset += np;
2775 
2776 	ctdb_uint32_push(&in->sticky_duration, buf+offset, &np);
2777 	offset += np;
2778 
2779 	ctdb_uint32_push(&in->sticky_pindown, buf+offset, &np);
2780 	offset += np;
2781 
2782 	ctdb_uint32_push(&in->no_ip_takeover, buf+offset, &np);
2783 	offset += np;
2784 
2785 	ctdb_uint32_push(&in->db_record_count_warn, buf+offset, &np);
2786 	offset += np;
2787 
2788 	ctdb_uint32_push(&in->db_record_size_warn, buf+offset, &np);
2789 	offset += np;
2790 
2791 	ctdb_uint32_push(&in->db_size_warn, buf+offset, &np);
2792 	offset += np;
2793 
2794 	ctdb_uint32_push(&in->pulldb_preallocation_size, buf+offset, &np);
2795 	offset += np;
2796 
2797 	ctdb_uint32_push(&in->no_ip_host_on_all_disabled, buf+offset, &np);
2798 	offset += np;
2799 
2800 	ctdb_uint32_push(&in->samba3_hack, buf+offset, &np);
2801 	offset += np;
2802 
2803 	ctdb_uint32_push(&in->mutex_enabled, buf+offset, &np);
2804 	offset += np;
2805 
2806 	ctdb_uint32_push(&in->lock_processes_per_db, buf+offset, &np);
2807 	offset += np;
2808 
2809 	ctdb_uint32_push(&in->rec_buffer_size_limit, buf+offset, &np);
2810 	offset += np;
2811 
2812 	ctdb_uint32_push(&in->queue_buffer_size, buf+offset, &np);
2813 	offset += np;
2814 
2815 	ctdb_uint32_push(&in->ip_alloc_algorithm, buf+offset, &np);
2816 	offset += np;
2817 
2818 	ctdb_uint32_push(&in->allow_mixed_versions, buf+offset, &np);
2819 	offset += np;
2820 
2821 	*npush = offset;
2822 }
2823 
ctdb_tunable_list_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_tunable_list * out,size_t * npull)2824 static int ctdb_tunable_list_pull_elems(uint8_t *buf, size_t buflen,
2825 					TALLOC_CTX *mem_ctx,
2826 					struct ctdb_tunable_list *out,
2827 					size_t *npull)
2828 {
2829 	size_t offset = 0, np;
2830 	int ret;
2831 
2832 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2833 			       &out->max_redirect_count, &np);
2834 	if (ret != 0) {
2835 		return ret;
2836 	}
2837 	offset += np;
2838 
2839 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2840 			       &out->seqnum_interval, &np);
2841 	if (ret != 0) {
2842 		return ret;
2843 	}
2844 	offset += np;
2845 
2846 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2847 			       &out->control_timeout, &np);
2848 	if (ret != 0) {
2849 		return ret;
2850 	}
2851 	offset += np;
2852 
2853 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2854 			       &out->traverse_timeout, &np);
2855 	if (ret != 0) {
2856 		return ret;
2857 	}
2858 	offset += np;
2859 
2860 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2861 			       &out->keepalive_interval, &np);
2862 	if (ret != 0) {
2863 		return ret;
2864 	}
2865 	offset += np;
2866 
2867 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2868 			       &out->keepalive_limit, &np);
2869 	if (ret != 0) {
2870 		return ret;
2871 	}
2872 	offset += np;
2873 
2874 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2875 			       &out->recover_timeout, &np);
2876 	if (ret != 0) {
2877 		return ret;
2878 	}
2879 	offset += np;
2880 
2881 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2882 			       &out->recover_interval, &np);
2883 	if (ret != 0) {
2884 		return ret;
2885 	}
2886 	offset += np;
2887 
2888 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2889 			       &out->election_timeout, &np);
2890 	if (ret != 0) {
2891 		return ret;
2892 	}
2893 	offset += np;
2894 
2895 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2896 			       &out->takeover_timeout, &np);
2897 	if (ret != 0) {
2898 		return ret;
2899 	}
2900 	offset += np;
2901 
2902 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2903 			       &out->monitor_interval, &np);
2904 	if (ret != 0) {
2905 		return ret;
2906 	}
2907 	offset += np;
2908 
2909 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2910 			       &out->tickle_update_interval, &np);
2911 	if (ret != 0) {
2912 		return ret;
2913 	}
2914 	offset += np;
2915 
2916 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2917 			       &out->script_timeout, &np);
2918 	if (ret != 0) {
2919 		return ret;
2920 	}
2921 	offset += np;
2922 
2923 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2924 			       &out->monitor_timeout_count, &np);
2925 	if (ret != 0) {
2926 		return ret;
2927 	}
2928 	offset += np;
2929 
2930 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2931 			       &out->script_unhealthy_on_timeout, &np);
2932 	if (ret != 0) {
2933 		return ret;
2934 	}
2935 	offset += np;
2936 
2937 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2938 			       &out->recovery_grace_period, &np);
2939 	if (ret != 0) {
2940 		return ret;
2941 	}
2942 	offset += np;
2943 
2944 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2945 			       &out->recovery_ban_period, &np);
2946 	if (ret != 0) {
2947 		return ret;
2948 	}
2949 	offset += np;
2950 
2951 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2952 			       &out->database_hash_size, &np);
2953 	if (ret != 0) {
2954 		return ret;
2955 	}
2956 	offset += np;
2957 
2958 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2959 			       &out->database_max_dead, &np);
2960 	if (ret != 0) {
2961 		return ret;
2962 	}
2963 	offset += np;
2964 
2965 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2966 			       &out->rerecovery_timeout, &np);
2967 	if (ret != 0) {
2968 		return ret;
2969 	}
2970 	offset += np;
2971 
2972 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2973 			       &out->enable_bans, &np);
2974 	if (ret != 0) {
2975 		return ret;
2976 	}
2977 	offset += np;
2978 
2979 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2980 			       &out->deterministic_public_ips, &np);
2981 	if (ret != 0) {
2982 		return ret;
2983 	}
2984 	offset += np;
2985 
2986 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2987 			       &out->reclock_ping_period, &np);
2988 	if (ret != 0) {
2989 		return ret;
2990 	}
2991 	offset += np;
2992 
2993 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
2994 			       &out->no_ip_failback, &np);
2995 	if (ret != 0) {
2996 		return ret;
2997 	}
2998 	offset += np;
2999 
3000 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3001 			       &out->disable_ip_failover, &np);
3002 	if (ret != 0) {
3003 		return ret;
3004 	}
3005 	offset += np;
3006 
3007 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3008 			       &out->verbose_memory_names, &np);
3009 	if (ret != 0) {
3010 		return ret;
3011 	}
3012 	offset += np;
3013 
3014 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3015 			       &out->recd_ping_timeout, &np);
3016 	if (ret != 0) {
3017 		return ret;
3018 	}
3019 	offset += np;
3020 
3021 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3022 			       &out->recd_ping_failcount, &np);
3023 	if (ret != 0) {
3024 		return ret;
3025 	}
3026 	offset += np;
3027 
3028 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3029 			       &out->log_latency_ms, &np);
3030 	if (ret != 0) {
3031 		return ret;
3032 	}
3033 	offset += np;
3034 
3035 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3036 			       &out->reclock_latency_ms, &np);
3037 	if (ret != 0) {
3038 		return ret;
3039 	}
3040 	offset += np;
3041 
3042 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3043 			       &out->recovery_drop_all_ips, &np);
3044 	if (ret != 0) {
3045 		return ret;
3046 	}
3047 	offset += np;
3048 
3049 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3050 			       &out->verify_recovery_lock, &np);
3051 	if (ret != 0) {
3052 		return ret;
3053 	}
3054 	offset += np;
3055 
3056 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3057 			       &out->vacuum_interval, &np);
3058 	if (ret != 0) {
3059 		return ret;
3060 	}
3061 	offset += np;
3062 
3063 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3064 			       &out->vacuum_max_run_time, &np);
3065 	if (ret != 0) {
3066 		return ret;
3067 	}
3068 	offset += np;
3069 
3070 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3071 			       &out->repack_limit, &np);
3072 	if (ret != 0) {
3073 		return ret;
3074 	}
3075 	offset += np;
3076 
3077 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3078 			       &out->vacuum_limit, &np);
3079 	if (ret != 0) {
3080 		return ret;
3081 	}
3082 	offset += np;
3083 
3084 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3085 			       &out->max_queue_depth_drop_msg, &np);
3086 	if (ret != 0) {
3087 		return ret;
3088 	}
3089 	offset += np;
3090 
3091 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3092 			       &out->allow_unhealthy_db_read, &np);
3093 	if (ret != 0) {
3094 		return ret;
3095 	}
3096 	offset += np;
3097 
3098 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3099 			       &out->stat_history_interval, &np);
3100 	if (ret != 0) {
3101 		return ret;
3102 	}
3103 	offset += np;
3104 
3105 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3106 			       &out->deferred_attach_timeout, &np);
3107 	if (ret != 0) {
3108 		return ret;
3109 	}
3110 	offset += np;
3111 
3112 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3113 			       &out->vacuum_fast_path_count, &np);
3114 	if (ret != 0) {
3115 		return ret;
3116 	}
3117 	offset += np;
3118 
3119 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3120 			       &out->lcp2_public_ip_assignment, &np);
3121 	if (ret != 0) {
3122 		return ret;
3123 	}
3124 	offset += np;
3125 
3126 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3127 			       &out->allow_client_db_attach, &np);
3128 	if (ret != 0) {
3129 		return ret;
3130 	}
3131 	offset += np;
3132 
3133 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3134 			       &out->recover_pdb_by_seqnum, &np);
3135 	if (ret != 0) {
3136 		return ret;
3137 	}
3138 	offset += np;
3139 
3140 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3141 			       &out->deferred_rebalance_on_node_add, &np);
3142 	if (ret != 0) {
3143 		return ret;
3144 	}
3145 	offset += np;
3146 
3147 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3148 			       &out->fetch_collapse, &np);
3149 	if (ret != 0) {
3150 		return ret;
3151 	}
3152 	offset += np;
3153 
3154 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3155 			       &out->hopcount_make_sticky, &np);
3156 	if (ret != 0) {
3157 		return ret;
3158 	}
3159 	offset += np;
3160 
3161 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3162 			       &out->sticky_duration, &np);
3163 	if (ret != 0) {
3164 		return ret;
3165 	}
3166 	offset += np;
3167 
3168 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3169 			       &out->sticky_pindown, &np);
3170 	if (ret != 0) {
3171 		return ret;
3172 	}
3173 	offset += np;
3174 
3175 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3176 			       &out->no_ip_takeover, &np);
3177 	if (ret != 0) {
3178 		return ret;
3179 	}
3180 	offset += np;
3181 
3182 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3183 			       &out->db_record_count_warn, &np);
3184 	if (ret != 0) {
3185 		return ret;
3186 	}
3187 	offset += np;
3188 
3189 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3190 			       &out->db_record_size_warn, &np);
3191 	if (ret != 0) {
3192 		return ret;
3193 	}
3194 	offset += np;
3195 
3196 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3197 			       &out->db_size_warn, &np);
3198 	if (ret != 0) {
3199 		return ret;
3200 	}
3201 	offset += np;
3202 
3203 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3204 			       &out->pulldb_preallocation_size, &np);
3205 	if (ret != 0) {
3206 		return ret;
3207 	}
3208 	offset += np;
3209 
3210 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3211 			       &out->no_ip_host_on_all_disabled, &np);
3212 	if (ret != 0) {
3213 		return ret;
3214 	}
3215 	offset += np;
3216 
3217 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3218 			       &out->samba3_hack, &np);
3219 	if (ret != 0) {
3220 		return ret;
3221 	}
3222 	offset += np;
3223 
3224 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3225 			       &out->mutex_enabled, &np);
3226 	if (ret != 0) {
3227 		return ret;
3228 	}
3229 	offset += np;
3230 
3231 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3232 			       &out->lock_processes_per_db, &np);
3233 	if (ret != 0) {
3234 		return ret;
3235 	}
3236 	offset += np;
3237 
3238 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3239 			       &out->rec_buffer_size_limit, &np);
3240 	if (ret != 0) {
3241 		return ret;
3242 	}
3243 	offset += np;
3244 
3245 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3246 			       &out->queue_buffer_size, &np);
3247 	if (ret != 0) {
3248 		return ret;
3249 	}
3250 	offset += np;
3251 
3252 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3253 			       &out->ip_alloc_algorithm, &np);
3254 	if (ret != 0) {
3255 		return ret;
3256 	}
3257 	offset += np;
3258 
3259 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
3260 			       &out->allow_mixed_versions, &np);
3261 	if (ret != 0) {
3262 		return ret;
3263 	}
3264 	offset += np;
3265 
3266 	*npull = offset;
3267 	return 0;
3268 }
3269 
ctdb_tunable_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_tunable_list ** out,size_t * npull)3270 int ctdb_tunable_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3271 			   struct ctdb_tunable_list **out, size_t *npull)
3272 {
3273 	struct ctdb_tunable_list *val;
3274 	size_t np;
3275 	int ret;
3276 
3277 	val = talloc(mem_ctx, struct ctdb_tunable_list);
3278 	if (val == NULL) {
3279 		return ENOMEM;
3280 	}
3281 
3282 	ret = ctdb_tunable_list_pull_elems(buf, buflen, val, val, &np);
3283 	if (ret != 0) {
3284 		talloc_free(val);
3285 		return ret;
3286 	}
3287 
3288 	*out = val;
3289 	*npull = np;
3290 	return 0;
3291 }
3292 
ctdb_tickle_list_len(struct ctdb_tickle_list * in)3293 size_t ctdb_tickle_list_len(struct ctdb_tickle_list *in)
3294 {
3295 	size_t len;
3296 
3297 	len = ctdb_sock_addr_len(&in->addr) +
3298 		ctdb_uint32_len(&in->num);
3299 	if (in->num > 0) {
3300 		len += in->num * ctdb_connection_len(&in->conn[0]);
3301 	}
3302 
3303 	return len;
3304 }
3305 
ctdb_tickle_list_push(struct ctdb_tickle_list * in,uint8_t * buf,size_t * npush)3306 void ctdb_tickle_list_push(struct ctdb_tickle_list *in, uint8_t *buf,
3307 			   size_t *npush)
3308 {
3309 	size_t offset = 0, np;
3310 	uint32_t i;
3311 
3312 	ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3313 	offset += np;
3314 
3315 	ctdb_uint32_push(&in->num, buf+offset, &np);
3316 	offset += np;
3317 
3318 	for (i=0; i<in->num; i++) {
3319 		ctdb_connection_push(&in->conn[i], buf+offset, &np);
3320 		offset += np;
3321 	}
3322 
3323 	*npush = offset;
3324 }
3325 
ctdb_tickle_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_tickle_list ** out,size_t * npull)3326 int ctdb_tickle_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3327 			   struct ctdb_tickle_list **out, size_t *npull)
3328 {
3329 	struct ctdb_tickle_list *val;
3330 	size_t offset = 0, np;
3331 	uint32_t i;
3332 	int ret;
3333 
3334 	val = talloc(mem_ctx, struct ctdb_tickle_list);
3335 	if (val == NULL) {
3336 		return ENOMEM;
3337 	}
3338 
3339 	ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, val,
3340 					&val->addr, &np);
3341 	if (ret != 0) {
3342 		goto fail;
3343 	}
3344 	offset += np;
3345 
3346 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
3347 	if (ret != 0) {
3348 		goto fail;
3349 	}
3350 	offset += np;
3351 
3352 	if (val->num == 0) {
3353 		val->conn = NULL;
3354 		goto done;
3355 	}
3356 
3357 	val->conn = talloc_array(val, struct ctdb_connection, val->num);
3358 	if (val->conn == NULL) {
3359 		ret = ENOMEM;
3360 		goto fail;
3361 	}
3362 
3363 	for (i=0; i<val->num; i++) {
3364 		ret = ctdb_connection_pull_elems(buf+offset, buflen-offset,
3365 						 val, &val->conn[i], &np);
3366 		if (ret != 0) {
3367 			goto fail;
3368 		}
3369 		offset += np;
3370 	}
3371 
3372 done:
3373 	*out = val;
3374 	*npull = offset;
3375 	return 0;
3376 
3377 fail:
3378 	talloc_free(val);
3379 	return ret;
3380 }
3381 
ctdb_addr_info_len(struct ctdb_addr_info * in)3382 size_t ctdb_addr_info_len(struct ctdb_addr_info *in)
3383 {
3384 	return ctdb_sock_addr_len(&in->addr) +
3385 		ctdb_uint32_len(&in->mask) +
3386 		ctdb_stringn_len(&in->iface);
3387 }
3388 
ctdb_addr_info_push(struct ctdb_addr_info * in,uint8_t * buf,size_t * npush)3389 void ctdb_addr_info_push(struct ctdb_addr_info *in, uint8_t *buf,
3390 			 size_t *npush)
3391 {
3392 	size_t offset = 0, np;
3393 
3394 	ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3395 	offset += np;
3396 
3397 	ctdb_uint32_push(&in->mask, buf+offset, &np);
3398 	offset += np;
3399 
3400 	ctdb_stringn_push(&in->iface, buf+offset, &np);
3401 	offset += np;
3402 
3403 	*npush = offset;
3404 }
3405 
ctdb_addr_info_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_addr_info ** out,size_t * npull)3406 int ctdb_addr_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3407 			struct ctdb_addr_info **out, size_t *npull)
3408 {
3409 	struct ctdb_addr_info *val;
3410 	size_t offset = 0, np;
3411 	int ret;
3412 
3413 	val = talloc(mem_ctx, struct ctdb_addr_info);
3414 	if (val == NULL) {
3415 		return ENOMEM;
3416 	}
3417 
3418 	ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, val,
3419 					&val->addr, &np);
3420 	if (ret != 0) {
3421 		goto fail;
3422 	}
3423 	offset += np;
3424 
3425 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->mask, &np);
3426 	if (ret != 0) {
3427 		goto fail;
3428 	}
3429 	offset += np;
3430 
3431 	ret = ctdb_stringn_pull(buf+offset, buflen-offset, val, &val->iface,
3432 				&np);
3433 	if (ret != 0) {
3434 		goto fail;
3435 	}
3436 	offset += np;
3437 
3438 	*out = val;
3439 	*npull = offset;
3440 	return 0;
3441 
3442 fail:
3443 	talloc_free(val);
3444 	return ret;
3445 }
3446 
ctdb_transdb_len(struct ctdb_transdb * in)3447 size_t ctdb_transdb_len(struct ctdb_transdb *in)
3448 {
3449 	return ctdb_uint32_len(&in->db_id) +
3450 		ctdb_uint32_len(&in->tid);
3451 }
3452 
ctdb_transdb_push(struct ctdb_transdb * in,uint8_t * buf,size_t * npush)3453 void ctdb_transdb_push(struct ctdb_transdb *in, uint8_t *buf, size_t *npush)
3454 {
3455 	size_t offset = 0, np;
3456 
3457 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
3458 	offset += np;
3459 
3460 	ctdb_uint32_push(&in->tid, buf+offset, &np);
3461 	offset += np;
3462 
3463 	*npush = offset;
3464 }
3465 
ctdb_transdb_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_transdb ** out,size_t * npull)3466 int ctdb_transdb_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3467 		     struct ctdb_transdb **out, size_t *npull)
3468 {
3469 	struct ctdb_transdb *val;
3470 	size_t offset = 0, np;
3471 	int ret;
3472 
3473 	val = talloc(mem_ctx, struct ctdb_transdb);
3474 	if (val == NULL) {
3475 		return ENOMEM;
3476 	}
3477 
3478 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
3479 	if (ret != 0) {
3480 		goto fail;
3481 	}
3482 	offset += np;
3483 
3484 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->tid, &np);
3485 	if (ret != 0) {
3486 		goto fail;
3487 	}
3488 	offset += np;
3489 
3490 	*out = val;
3491 	*npull = offset;
3492 	return 0;
3493 
3494 fail:
3495 	talloc_free(val);
3496 	return ret;
3497 }
3498 
ctdb_uptime_len(struct ctdb_uptime * in)3499 size_t ctdb_uptime_len(struct ctdb_uptime *in)
3500 {
3501 	return ctdb_timeval_len(&in->current_time) +
3502 		ctdb_timeval_len(&in->ctdbd_start_time) +
3503 		ctdb_timeval_len(&in->last_recovery_started) +
3504 		ctdb_timeval_len(&in->last_recovery_finished);
3505 }
3506 
ctdb_uptime_push(struct ctdb_uptime * in,uint8_t * buf,size_t * npush)3507 void ctdb_uptime_push(struct ctdb_uptime *in, uint8_t *buf, size_t *npush)
3508 {
3509 	size_t offset = 0, np;
3510 
3511 	ctdb_timeval_push(&in->current_time, buf+offset, &np);
3512 	offset += np;
3513 
3514 	ctdb_timeval_push(&in->ctdbd_start_time, buf+offset, &np);
3515 	offset += np;
3516 
3517 	ctdb_timeval_push(&in->last_recovery_started, buf+offset, &np);
3518 	offset += np;
3519 
3520 	ctdb_timeval_push(&in->last_recovery_finished, buf+offset, &np);
3521 	offset += np;
3522 
3523 	*npush = offset;
3524 }
3525 
ctdb_uptime_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_uptime ** out,size_t * npull)3526 int ctdb_uptime_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3527 		     struct ctdb_uptime **out, size_t *npull)
3528 {
3529 	struct ctdb_uptime *val;
3530 	size_t offset = 0, np;
3531 	int ret;
3532 
3533 	val = talloc(mem_ctx, struct ctdb_uptime);
3534 	if (val == NULL) {
3535 		return ENOMEM;
3536 	}
3537 
3538 	ret = ctdb_timeval_pull(buf+offset, buflen-offset, &val->current_time,
3539 				&np);
3540 	if (ret != 0) {
3541 		goto fail;
3542 	}
3543 	offset += np;
3544 
3545 	ret = ctdb_timeval_pull(buf+offset, buflen-offset,
3546 				&val->ctdbd_start_time, &np);
3547 	if (ret != 0) {
3548 		goto fail;
3549 	}
3550 	offset += np;
3551 
3552 	ret = ctdb_timeval_pull(buf+offset, buflen-offset,
3553 				&val->last_recovery_started, &np);
3554 	if (ret != 0) {
3555 		goto fail;
3556 	}
3557 	offset += np;
3558 
3559 	ret = ctdb_timeval_pull(buf+offset, buflen-offset,
3560 				&val->last_recovery_finished, &np);
3561 	if (ret != 0) {
3562 		goto fail;
3563 	}
3564 	offset += np;
3565 
3566 	*out = val;
3567 	*npull = offset;
3568 	return 0;
3569 
3570 fail:
3571 	talloc_free(val);
3572 	return ret;
3573 }
3574 
ctdb_public_ip_len(struct ctdb_public_ip * in)3575 size_t ctdb_public_ip_len(struct ctdb_public_ip *in)
3576 {
3577 	return ctdb_uint32_len(&in->pnn) +
3578 		ctdb_sock_addr_len(&in->addr);
3579 }
3580 
ctdb_public_ip_push(struct ctdb_public_ip * in,uint8_t * buf,size_t * npush)3581 void ctdb_public_ip_push(struct ctdb_public_ip *in, uint8_t *buf,
3582 			 size_t *npush)
3583 {
3584 	size_t offset = 0, np;
3585 
3586 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
3587 	offset += np;
3588 
3589 	ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3590 	offset += np;
3591 
3592 	*npush = offset;
3593 }
3594 
ctdb_public_ip_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_public_ip * out,size_t * npull)3595 static int ctdb_public_ip_pull_elems(uint8_t *buf, size_t buflen,
3596 				     TALLOC_CTX *mem_ctx,
3597 				     struct ctdb_public_ip *out, size_t *npull)
3598 {
3599 	size_t offset = 0, np;
3600 	int ret;
3601 
3602 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->pnn, &np);
3603 	if (ret != 0) {
3604 		return ret;
3605 	}
3606 	offset += np;
3607 
3608 	ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, mem_ctx,
3609 					&out->addr, &np);
3610 	if (ret != 0) {
3611 		return ret;
3612 	}
3613 	offset += np;
3614 
3615 	*npull = offset;
3616 	return 0;
3617 }
3618 
ctdb_public_ip_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_public_ip ** out,size_t * npull)3619 int ctdb_public_ip_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3620 			struct ctdb_public_ip **out, size_t *npull)
3621 {
3622 	struct ctdb_public_ip *val;
3623 	size_t np;
3624 	int ret;
3625 
3626 	val = talloc(mem_ctx, struct ctdb_public_ip);
3627 	if (val == NULL) {
3628 		return ENOMEM;
3629 	}
3630 
3631 	ret = ctdb_public_ip_pull_elems(buf, buflen, val, val, &np);
3632 	if (ret != 0) {
3633 		TALLOC_FREE(val);
3634 		return ret;
3635 	}
3636 
3637 	*out = val;
3638 	*npull = np;
3639 	return ret;
3640 }
3641 
ctdb_public_ip_list_len(struct ctdb_public_ip_list * in)3642 size_t ctdb_public_ip_list_len(struct ctdb_public_ip_list *in)
3643 {
3644 	size_t len;
3645 
3646 	len = ctdb_uint32_len(&in->num);
3647 	if (in->num > 0) {
3648 		len += in->num * ctdb_public_ip_len(&in->ip[0]);
3649 	}
3650 
3651 	return len;
3652 }
3653 
ctdb_public_ip_list_push(struct ctdb_public_ip_list * in,uint8_t * buf,size_t * npush)3654 void ctdb_public_ip_list_push(struct ctdb_public_ip_list *in, uint8_t *buf,
3655 			      size_t *npush)
3656 {
3657 	size_t offset = 0, np;
3658 	uint32_t i;
3659 
3660 	ctdb_uint32_push(&in->num, buf+offset, &np);
3661 	offset += np;
3662 
3663 	for (i=0; i<in->num; i++) {
3664 		ctdb_public_ip_push(&in->ip[i], buf+offset, &np);
3665 		offset += np;
3666 	}
3667 
3668 	*npush = offset;
3669 }
3670 
ctdb_public_ip_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_public_ip_list ** out,size_t * npull)3671 int ctdb_public_ip_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3672 			     struct ctdb_public_ip_list **out, size_t *npull)
3673 {
3674 	struct ctdb_public_ip_list *val;
3675 	size_t offset = 0, np;
3676 	uint32_t i;
3677 	int ret;
3678 
3679 	val = talloc(mem_ctx, struct ctdb_public_ip_list);
3680 	if (val == NULL) {
3681 		return ENOMEM;
3682 	}
3683 
3684 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
3685 	if (ret != 0) {
3686 		goto fail;
3687 	}
3688 	offset += np;
3689 
3690 	if (val->num == 0) {
3691 		val->ip = NULL;
3692 		goto done;
3693 	}
3694 
3695 	val->ip = talloc_array(val, struct ctdb_public_ip, val->num);
3696 	if (val->ip == NULL) {
3697 		ret = ENOMEM;
3698 		goto fail;
3699 	}
3700 
3701 	for (i=0; i<val->num; i++) {
3702 		ret = ctdb_public_ip_pull_elems(buf+offset, buflen-offset,
3703 						val->ip, &val->ip[i], &np);
3704 		if (ret != 0) {
3705 			goto fail;
3706 		}
3707 		offset += np;
3708 	}
3709 
3710 done:
3711 	*out = val;
3712 	*npull = offset;
3713 	return 0;
3714 
3715 fail:
3716 	talloc_free(val);
3717 	return ret;
3718 }
3719 
ctdb_node_and_flags_len(struct ctdb_node_and_flags * in)3720 size_t ctdb_node_and_flags_len(struct ctdb_node_and_flags *in)
3721 {
3722 	return ctdb_uint32_len(&in->pnn) +
3723 		ctdb_uint32_len(&in->flags) +
3724 		ctdb_sock_addr_len(&in->addr);
3725 }
3726 
ctdb_node_and_flags_push(struct ctdb_node_and_flags * in,uint8_t * buf,size_t * npush)3727 void ctdb_node_and_flags_push(struct ctdb_node_and_flags *in, uint8_t *buf,
3728 			      size_t *npush)
3729 {
3730 	size_t offset = 0, np;
3731 
3732 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
3733 	offset += np;
3734 
3735 	ctdb_uint32_push(&in->flags, buf+offset, &np);
3736 	offset += np;
3737 
3738 	ctdb_sock_addr_push(&in->addr, buf+offset, &np);
3739 	offset += np;
3740 
3741 	*npush = offset;
3742 }
3743 
ctdb_node_and_flags_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_node_and_flags * out,size_t * npull)3744 static int ctdb_node_and_flags_pull_elems(uint8_t *buf, size_t buflen,
3745 					  TALLOC_CTX *mem_ctx,
3746 					  struct ctdb_node_and_flags *out,
3747 					  size_t *npull)
3748 {
3749 	size_t offset = 0, np;
3750 	int ret;
3751 
3752 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->pnn, &np);
3753 	if (ret != 0) {
3754 		return ret;
3755 	}
3756 	offset += np;
3757 
3758 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->flags, &np);
3759 	if (ret != 0) {
3760 		return ret;
3761 	}
3762 	offset += np;
3763 
3764 	ret = ctdb_sock_addr_pull_elems(buf+offset, buflen-offset, mem_ctx,
3765 					&out->addr, &np);
3766 	if (ret != 0) {
3767 		return ret;
3768 	}
3769 	offset += np;
3770 
3771 	*npull = offset;
3772 	return 0;
3773 }
3774 
ctdb_node_and_flags_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_node_and_flags ** out,size_t * npull)3775 int ctdb_node_and_flags_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3776 			      struct ctdb_node_and_flags **out, size_t *npull)
3777 {
3778 	struct ctdb_node_and_flags *val;
3779 	size_t np;
3780 	int ret;
3781 
3782 	val = talloc(mem_ctx, struct ctdb_node_and_flags);
3783 	if (val == NULL) {
3784 		return ENOMEM;
3785 	}
3786 
3787 	ret = ctdb_node_and_flags_pull_elems(buf, buflen, val, val, &np);
3788 	if (ret != 0) {
3789 		TALLOC_FREE(val);
3790 		return ret;
3791 	}
3792 
3793 	*out = val;
3794 	*npull = np;
3795 	return ret;
3796 }
3797 
ctdb_node_map_len(struct ctdb_node_map * in)3798 size_t ctdb_node_map_len(struct ctdb_node_map *in)
3799 {
3800 	size_t len;
3801 
3802 	len = ctdb_uint32_len(&in->num);
3803 	if (in->num > 0) {
3804 		len += in->num * ctdb_node_and_flags_len(&in->node[0]);
3805 	}
3806 
3807 	return len;
3808 }
3809 
ctdb_node_map_push(struct ctdb_node_map * in,uint8_t * buf,size_t * npush)3810 void ctdb_node_map_push(struct ctdb_node_map *in, uint8_t *buf, size_t *npush)
3811 {
3812 	size_t offset = 0, np;
3813 	uint32_t i;
3814 
3815 	ctdb_uint32_push(&in->num, buf+offset, &np);
3816 	offset += np;
3817 
3818 	for (i=0; i<in->num; i++) {
3819 		ctdb_node_and_flags_push(&in->node[i], buf+offset, &np);
3820 		offset += np;
3821 	}
3822 
3823 	*npush = offset;
3824 }
3825 
ctdb_node_map_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_node_map ** out,size_t * npull)3826 int ctdb_node_map_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3827 		       struct ctdb_node_map **out, size_t *npull)
3828 {
3829 	struct ctdb_node_map *val;
3830 	size_t offset = 0, np;
3831 	uint32_t i;
3832 	int ret;
3833 
3834 	val = talloc(mem_ctx, struct ctdb_node_map);
3835 	if (val == NULL) {
3836 		return ENOMEM;
3837 	}
3838 
3839 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
3840 	if (ret != 0) {
3841 		goto fail;
3842 	}
3843 	offset += np;
3844 
3845 	if (val->num == 0) {
3846 		val->node = NULL;
3847 		goto done;
3848 	}
3849 
3850 	val->node = talloc_array(val, struct ctdb_node_and_flags, val->num);
3851 	if (val->node == NULL) {
3852 		ret = ENOMEM;
3853 		goto fail;
3854 	}
3855 
3856 	for (i=0; i<val->num; i++) {
3857 		ret = ctdb_node_and_flags_pull_elems(buf+offset,
3858 						     buflen-offset,
3859 						     val->node, &val->node[i],
3860 						     &np);
3861 		if (ret != 0) {
3862 			goto fail;
3863 		}
3864 		offset += np;
3865 	}
3866 
3867 done:
3868 	*out = val;
3869 	*npull = offset;
3870 	return 0;
3871 
3872 fail:
3873 	talloc_free(val);
3874 	return ret;
3875 }
3876 
ctdb_script_len(struct ctdb_script * in)3877 size_t ctdb_script_len(struct ctdb_script *in)
3878 {
3879 	return ctdb_chararray_len(in->name, MAX_SCRIPT_NAME+1) +
3880 		ctdb_timeval_len(&in->start) +
3881 		ctdb_timeval_len(&in->finished) +
3882 		ctdb_int32_len(&in->status) +
3883 		ctdb_chararray_len(in->output, MAX_SCRIPT_OUTPUT+1) +
3884 		ctdb_padding_len(4);
3885 }
3886 
ctdb_script_push(struct ctdb_script * in,uint8_t * buf,size_t * npush)3887 void ctdb_script_push(struct ctdb_script *in, uint8_t *buf, size_t *npush)
3888 {
3889 	size_t offset = 0, np;
3890 
3891 	ctdb_chararray_push(in->name, MAX_SCRIPT_NAME+1, buf+offset, &np);
3892 	offset += np;
3893 
3894 	ctdb_timeval_push(&in->start, buf+offset, &np);
3895 	offset += np;
3896 
3897 	ctdb_timeval_push(&in->finished, buf+offset, &np);
3898 	offset += np;
3899 
3900 	ctdb_int32_push(&in->status, buf+offset, &np);
3901 	offset += np;
3902 
3903 	ctdb_chararray_push(in->output, MAX_SCRIPT_OUTPUT+1, buf+offset, &np);
3904 	offset += np;
3905 
3906 	ctdb_padding_push(4, buf+offset, &np);
3907 	offset += np;
3908 
3909 	*npush = offset;
3910 }
3911 
ctdb_script_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_script * out,size_t * npull)3912 static int ctdb_script_pull_elems(uint8_t *buf, size_t buflen,
3913 				  TALLOC_CTX *mem_ctx,
3914 				  struct ctdb_script *out, size_t *npull)
3915 {
3916 	size_t offset = 0, np;
3917 	int ret;
3918 
3919 	ret = ctdb_chararray_pull(buf+offset, buflen-offset,
3920 				  out->name, MAX_SCRIPT_NAME+1, &np);
3921 	if (ret != 0) {
3922 		return ret;
3923 	}
3924 	offset += np;
3925 
3926 	ret = ctdb_timeval_pull(buf+offset, buflen-offset, &out->start, &np);
3927 	if (ret != 0) {
3928 		return ret;
3929 	}
3930 	offset += np;
3931 
3932 	ret = ctdb_timeval_pull(buf+offset, buflen-offset, &out->finished,
3933 				&np);
3934 	if (ret != 0) {
3935 		return ret;
3936 	}
3937 	offset += np;
3938 
3939 	ret = ctdb_int32_pull(buf+offset, buflen-offset, &out->status, &np);
3940 	if (ret != 0) {
3941 		return ret;
3942 	}
3943 	offset += np;
3944 
3945 	ret = ctdb_chararray_pull(buf+offset, buflen-offset,
3946 				  out->output, MAX_SCRIPT_OUTPUT+1, &np);
3947 	if (ret != 0) {
3948 		return ret;
3949 	}
3950 	offset += np;
3951 
3952 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
3953 	if (ret != 0) {
3954 		return ret;
3955 	}
3956 	offset += np;
3957 
3958 	*npull = offset;
3959 	return 0;
3960 }
3961 
ctdb_script_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_script ** out,size_t * npull)3962 int ctdb_script_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
3963 		     struct ctdb_script **out, size_t *npull)
3964 {
3965 	struct ctdb_script *val;
3966 	size_t np;
3967 	int ret;
3968 
3969 	val = talloc(mem_ctx, struct ctdb_script);
3970 	if (val == NULL) {
3971 		return ENOMEM;
3972 	}
3973 
3974 	ret = ctdb_script_pull_elems(buf, buflen, val, val, &np);
3975 	if (ret != 0) {
3976 		TALLOC_FREE(val);
3977 		return ret;
3978 	}
3979 
3980 	*out = val;
3981 	*npull = np;
3982 	return ret;
3983 }
3984 
ctdb_script_list_len(struct ctdb_script_list * in)3985 size_t ctdb_script_list_len(struct ctdb_script_list *in)
3986 {
3987 	size_t len;
3988 
3989 	if (in == NULL) {
3990 		return 0;
3991 	}
3992 
3993 	len = ctdb_uint32_len(&in->num_scripts) + ctdb_padding_len(4);
3994 	if (in->num_scripts > 0) {
3995 		len += in->num_scripts * ctdb_script_len(&in->script[0]);
3996 	}
3997 
3998 	return len;
3999 }
4000 
ctdb_script_list_push(struct ctdb_script_list * in,uint8_t * buf,size_t * npush)4001 void ctdb_script_list_push(struct ctdb_script_list *in, uint8_t *buf,
4002 			   size_t *npush)
4003 {
4004 	size_t offset = 0, np;
4005 	uint32_t i;
4006 
4007 	if (in == NULL) {
4008 		*npush = 0;
4009 		return;
4010 	}
4011 
4012 	ctdb_uint32_push(&in->num_scripts, buf+offset, &np);
4013 	offset += np;
4014 
4015 	ctdb_padding_push(4, buf+offset, &np);
4016 	offset += np;
4017 
4018 	for (i=0; i<in->num_scripts; i++) {
4019 		ctdb_script_push(&in->script[i], buf+offset, &np);
4020 		offset += np;
4021 	}
4022 
4023 	*npush = offset;
4024 }
4025 
ctdb_script_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_script_list ** out,size_t * npull)4026 int ctdb_script_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4027 			  struct ctdb_script_list **out, size_t *npull)
4028 {
4029 	struct ctdb_script_list *val;
4030 	size_t offset = 0, np;
4031 	uint32_t i;
4032 	int ret;
4033 
4034 	/* If event scripts have never been run, the result will be NULL */
4035 	if (buflen == 0) {
4036 		val = NULL;
4037 		goto done;
4038 	}
4039 
4040 	val = talloc(mem_ctx, struct ctdb_script_list);
4041 	if (val == NULL) {
4042 		return ENOMEM;
4043 	}
4044 
4045 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num_scripts,
4046 			       &np);
4047 	if (ret != 0) {
4048 		goto fail;
4049 	}
4050 	offset += np;
4051 
4052 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4053 	if (ret != 0) {
4054 		goto fail;
4055 	}
4056 	offset += np;
4057 
4058 	if (val->num_scripts == 0) {
4059 		val->script = NULL;
4060 		goto done;
4061 	}
4062 
4063 	val->script = talloc_array(val, struct ctdb_script, val->num_scripts);
4064 	if (val->script == NULL) {
4065 		ret = ENOMEM;
4066 		goto fail;
4067 	}
4068 
4069 	for (i=0; i<val->num_scripts; i++) {
4070 		ret = ctdb_script_pull_elems(buf+offset, buflen-offset,
4071 					     val, &val->script[i], &np);
4072 		if (ret != 0) {
4073 			goto fail;
4074 		}
4075 		offset += np;
4076 	}
4077 
4078 done:
4079 	*out = val;
4080 	*npull = offset;
4081 	return 0;
4082 
4083 fail:
4084 	talloc_free(val);
4085 	return ret;
4086 }
4087 
ctdb_ban_state_len(struct ctdb_ban_state * in)4088 size_t ctdb_ban_state_len(struct ctdb_ban_state *in)
4089 {
4090 	return ctdb_uint32_len(&in->pnn) +
4091 		ctdb_uint32_len(&in->time);
4092 }
4093 
ctdb_ban_state_push(struct ctdb_ban_state * in,uint8_t * buf,size_t * npush)4094 void ctdb_ban_state_push(struct ctdb_ban_state *in, uint8_t *buf,
4095 			 size_t *npush)
4096 {
4097 	size_t offset = 0, np;
4098 
4099 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
4100 	offset += np;
4101 
4102 	ctdb_uint32_push(&in->time, buf+offset, &np);
4103 	offset += np;
4104 
4105 	*npush = offset;
4106 }
4107 
ctdb_ban_state_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_ban_state ** out,size_t * npull)4108 int ctdb_ban_state_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4109 			struct ctdb_ban_state **out, size_t *npull)
4110 {
4111 	struct ctdb_ban_state *val;
4112 	size_t offset = 0, np;
4113 	int ret;
4114 
4115 	val = talloc(mem_ctx, struct ctdb_ban_state);
4116 	if (val == NULL) {
4117 		return ENOMEM;
4118 	}
4119 
4120 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
4121 	if (ret != 0) {
4122 		goto fail;
4123 	}
4124 	offset += np;
4125 
4126 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->time, &np);
4127 	if (ret != 0) {
4128 		goto fail;
4129 	}
4130 	offset += np;
4131 
4132 	*out = val;
4133 	*npull = offset;
4134 	return 0;
4135 
4136 fail:
4137 	talloc_free(val);
4138 	return ret;
4139 }
4140 
ctdb_notify_data_len(struct ctdb_notify_data * in)4141 size_t ctdb_notify_data_len(struct ctdb_notify_data *in)
4142 {
4143 	return ctdb_uint64_len(&in->srvid) +
4144 		ctdb_tdb_datan_len(&in->data);
4145 }
4146 
ctdb_notify_data_push(struct ctdb_notify_data * in,uint8_t * buf,size_t * npush)4147 void ctdb_notify_data_push(struct ctdb_notify_data *in, uint8_t *buf,
4148 			   size_t *npush)
4149 {
4150 	size_t offset = 0, np;
4151 
4152 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
4153 	offset += np;
4154 
4155 	ctdb_tdb_datan_push(&in->data, buf+offset, &np);
4156 	offset += np;
4157 
4158 	*npush = offset;
4159 }
4160 
ctdb_notify_data_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_notify_data ** out,size_t * npull)4161 int ctdb_notify_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4162 			  struct ctdb_notify_data **out, size_t *npull)
4163 {
4164 	struct ctdb_notify_data *val;
4165 	size_t offset = 0, np;
4166 	int ret;
4167 
4168 	val = talloc(mem_ctx, struct ctdb_notify_data);
4169 	if (val == NULL) {
4170 		return ENOMEM;
4171 	}
4172 
4173 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
4174 	if (ret != 0) {
4175 		goto fail;
4176 	}
4177 	offset += np;
4178 
4179 	ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, val, &val->data,
4180 				  &np);
4181 	if (ret != 0) {
4182 		goto fail;
4183 	}
4184 	offset += np;
4185 
4186 	*out = val;
4187 	*npull = offset;
4188 	return 0;
4189 
4190 fail:
4191 	talloc_free(val);
4192 	return ret;
4193 }
4194 
ctdb_iface_len(struct ctdb_iface * in)4195 size_t ctdb_iface_len(struct ctdb_iface *in)
4196 {
4197 	return ctdb_chararray_len(in->name, CTDB_IFACE_SIZE+2) +
4198 		ctdb_uint16_len(&in->link_state) +
4199 		ctdb_uint32_len(&in->references);
4200 }
4201 
ctdb_iface_push(struct ctdb_iface * in,uint8_t * buf,size_t * npush)4202 void ctdb_iface_push(struct ctdb_iface *in, uint8_t *buf, size_t *npush)
4203 {
4204 	size_t offset = 0, np;
4205 
4206 	ctdb_chararray_push(in->name, CTDB_IFACE_SIZE+2, buf+offset, &np);
4207 	offset += np;
4208 
4209 	ctdb_uint16_push(&in->link_state, buf+offset, &np);
4210 	offset += np;
4211 
4212 	ctdb_uint32_push(&in->references, buf+offset, &np);
4213 	offset += np;
4214 
4215 	*npush = offset;
4216 }
4217 
ctdb_iface_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_iface * out,size_t * npull)4218 static int ctdb_iface_pull_elems(uint8_t *buf, size_t buflen,
4219 				 TALLOC_CTX *mem_ctx,
4220 				 struct ctdb_iface *out, size_t *npull)
4221 {
4222 	size_t offset = 0, np;
4223 	int ret;
4224 
4225 	ret = ctdb_chararray_pull(buf+offset, buflen-offset,
4226 				  out->name, CTDB_IFACE_SIZE+2, &np);
4227 	if (ret != 0) {
4228 		return ret;
4229 	}
4230 	offset += np;
4231 
4232 	ret = ctdb_uint16_pull(buf+offset, buflen-offset, &out->link_state,
4233 			       &np);
4234 	if (ret != 0) {
4235 		return ret;
4236 	}
4237 	offset += np;
4238 
4239 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->references,
4240 			       &np);
4241 	if (ret != 0) {
4242 		return ret;
4243 	}
4244 	offset += np;
4245 
4246 	*npull = offset;
4247 	return 0;
4248 }
4249 
ctdb_iface_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_iface ** out,size_t * npull)4250 int ctdb_iface_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4251 		    struct ctdb_iface **out, size_t *npull)
4252 {
4253 	struct ctdb_iface *val;
4254 	size_t np;
4255 	int ret;
4256 
4257 	val = talloc(mem_ctx, struct ctdb_iface);
4258 	if (val == NULL) {
4259 		return ENOMEM;
4260 	}
4261 
4262 	ret = ctdb_iface_pull_elems(buf, buflen, val, val, &np);
4263 	if (ret != 0) {
4264 		talloc_free(val);
4265 		return ret;
4266 	}
4267 
4268 	*out = val;
4269 	*npull = np;
4270 	return ret;
4271 }
4272 
ctdb_iface_list_len(struct ctdb_iface_list * in)4273 size_t ctdb_iface_list_len(struct ctdb_iface_list *in)
4274 {
4275 	size_t len;
4276 
4277 	len = ctdb_uint32_len(&in->num);
4278 	if (in->num > 0) {
4279 		len += in->num * ctdb_iface_len(&in->iface[0]);
4280 	}
4281 
4282 	return len;
4283 }
4284 
ctdb_iface_list_push(struct ctdb_iface_list * in,uint8_t * buf,size_t * npush)4285 void ctdb_iface_list_push(struct ctdb_iface_list *in, uint8_t *buf,
4286 			  size_t *npush)
4287 {
4288 	size_t offset = 0, np;
4289 	uint32_t i;
4290 
4291 	ctdb_uint32_push(&in->num, buf+offset, &np);
4292 	offset += np;
4293 
4294 	for (i=0; i<in->num; i++) {
4295 		ctdb_iface_push(&in->iface[i], buf+offset, &np);
4296 		offset += np;
4297 	}
4298 
4299 	*npush = offset;
4300 }
4301 
ctdb_iface_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_iface_list ** out,size_t * npull)4302 int ctdb_iface_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4303 			 struct ctdb_iface_list **out, size_t *npull)
4304 {
4305 	struct ctdb_iface_list *val;
4306 	size_t offset = 0, np;
4307 	uint32_t i;
4308 	int ret;
4309 
4310 	val = talloc(mem_ctx, struct ctdb_iface_list);
4311 	if (val == NULL) {
4312 		return ENOMEM;
4313 	}
4314 
4315 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num, &np);
4316 	if (ret != 0) {
4317 		goto fail;
4318 	}
4319 	offset += np;
4320 
4321 	if (val->num == 0) {
4322 		val->iface = NULL;
4323 		goto done;
4324 	}
4325 
4326 	val->iface = talloc_array(val, struct ctdb_iface, val->num);
4327 	if (val->iface == NULL) {
4328 		ret = ENOMEM;
4329 		goto fail;
4330 	}
4331 
4332 	for (i=0; i<val->num; i++) {
4333 		ret = ctdb_iface_pull_elems(buf+offset, buflen-offset,
4334 					    val, &val->iface[i], &np);
4335 		if (ret != 0) {
4336 			goto fail;
4337 		}
4338 		offset += np;
4339 	}
4340 
4341 done:
4342 	*out = val;
4343 	*npull = offset;
4344 	return 0;
4345 
4346 fail:
4347 	talloc_free(val);
4348 	return ret;
4349 }
4350 
ctdb_public_ip_info_len(struct ctdb_public_ip_info * in)4351 size_t ctdb_public_ip_info_len(struct ctdb_public_ip_info *in)
4352 {
4353 	return ctdb_public_ip_len(&in->ip) +
4354 		ctdb_uint32_len(&in->active_idx) +
4355 		ctdb_iface_list_len(in->ifaces);
4356 }
4357 
ctdb_public_ip_info_push(struct ctdb_public_ip_info * in,uint8_t * buf,size_t * npush)4358 void ctdb_public_ip_info_push(struct ctdb_public_ip_info *in, uint8_t *buf,
4359 			      size_t  *npush)
4360 {
4361 	size_t offset = 0, np;
4362 
4363 	ctdb_public_ip_push(&in->ip, buf+offset, &np);
4364 	offset += np;
4365 
4366 	ctdb_uint32_push(&in->active_idx, buf+offset, &np);
4367 	offset += np;
4368 
4369 	ctdb_iface_list_push(in->ifaces, buf+offset, &np);
4370 	offset += np;
4371 
4372 	*npush = offset;
4373 }
4374 
ctdb_public_ip_info_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_public_ip_info ** out,size_t * npull)4375 int ctdb_public_ip_info_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4376 			     struct ctdb_public_ip_info **out, size_t *npull)
4377 {
4378 	struct ctdb_public_ip_info *val;
4379 	size_t offset = 0, np;
4380 	int ret;
4381 
4382 	val = talloc(mem_ctx, struct ctdb_public_ip_info);
4383 	if (val == NULL) {
4384 		return ENOMEM;
4385 	}
4386 
4387 	ret = ctdb_public_ip_pull_elems(buf+offset, buflen-offset, val,
4388 					&val->ip, &np);
4389 	if (ret != 0) {
4390 		goto fail;
4391 	}
4392 	offset += np;
4393 
4394 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->active_idx,
4395 			       &np);
4396 	if (ret != 0) {
4397 		goto fail;
4398 	}
4399 	offset += np;
4400 
4401 	ret = ctdb_iface_list_pull(buf+offset, buflen-offset, val,
4402 				   &val->ifaces, &np);
4403 	if (ret != 0) {
4404 		goto fail;
4405 	}
4406 	offset += np;
4407 
4408 	*out = val;
4409 	*npull = offset;
4410 	return 0;
4411 
4412 fail:
4413 	talloc_free(val);
4414 	return ret;
4415 }
4416 
ctdb_key_data_len(struct ctdb_key_data * in)4417 size_t ctdb_key_data_len(struct ctdb_key_data *in)
4418 {
4419 	return ctdb_uint32_len(&in->db_id) +
4420 		ctdb_padding_len(4) +
4421 		ctdb_ltdb_header_len(&in->header) +
4422 		ctdb_tdb_datan_len(&in->key);
4423 }
4424 
ctdb_key_data_push(struct ctdb_key_data * in,uint8_t * buf,size_t * npush)4425 void ctdb_key_data_push(struct ctdb_key_data *in, uint8_t *buf, size_t *npush)
4426 {
4427 	size_t offset = 0, np;
4428 
4429 	ctdb_uint32_push(&in->db_id, buf+offset, &np);
4430 	offset += np;
4431 
4432 	ctdb_padding_push(4, buf+offset, &np);
4433 	offset += np;
4434 
4435 	ctdb_ltdb_header_push(&in->header, buf+offset, &np);
4436 	offset += np;
4437 
4438 	ctdb_tdb_datan_push(&in->key, buf+offset, &np);
4439 	offset += np;
4440 
4441 	*npush = offset;
4442 }
4443 
ctdb_key_data_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_key_data ** out,size_t * npull)4444 int ctdb_key_data_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4445 		       struct ctdb_key_data **out, size_t *npull)
4446 {
4447 	struct ctdb_key_data *val;
4448 	size_t offset = 0, np;
4449 	int ret;
4450 
4451 	val = talloc(mem_ctx, struct ctdb_key_data);
4452 	if (val == NULL) {
4453 		return ENOMEM;
4454 	}
4455 
4456 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->db_id, &np);
4457 	if (ret != 0) {
4458 		goto fail;
4459 	}
4460 	offset += np;
4461 
4462 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4463 	if (ret != 0) {
4464 		goto fail;
4465 	}
4466 	offset += np;
4467 
4468 	ret = ctdb_ltdb_header_pull(buf+offset, buflen-offset, &val->header,
4469 				    &np);
4470 	if (ret != 0) {
4471 		goto fail;
4472 	}
4473 	offset += np;
4474 
4475 	ret = ctdb_tdb_datan_pull(buf+offset, buflen-offset, val, &val->key,
4476 				  &np);
4477 	if (ret != 0) {
4478 		goto fail;
4479 	}
4480 	offset += np;
4481 
4482 	*out = val;
4483 	*npull = offset;
4484 	return 0;
4485 
4486 fail:
4487 	talloc_free(val);
4488 	return ret;
4489 }
4490 
4491 /* In the tdb_data structure marshalling, we are only interested in dsize.
4492  * The dptr value is ignored.  The actual tdb_data blob is stored separately.
4493  *
4494  * This is only required for ctdb_db_statistics and will be dropped in future.
4495  */
4496 
tdb_data_struct_len(TDB_DATA * data)4497 static size_t tdb_data_struct_len(TDB_DATA *data)
4498 {
4499 	return sizeof(void *) + sizeof(size_t);
4500 }
4501 
tdb_data_struct_push(TDB_DATA * data,uint8_t * buf,size_t * npush)4502 static void tdb_data_struct_push(TDB_DATA *data, uint8_t *buf, size_t *npush)
4503 {
4504 	size_t offset = 0;
4505 
4506 	memcpy(buf+offset, &data->dptr, sizeof(void *));
4507 	offset += sizeof(void *);
4508 
4509 	memcpy(buf+offset, &data->dsize, sizeof(size_t));
4510 	offset += sizeof(size_t);
4511 
4512 	*npush = offset;
4513 }
4514 
tdb_data_struct_pull(uint8_t * buf,size_t buflen,TDB_DATA * data,size_t * npull)4515 static int tdb_data_struct_pull(uint8_t *buf, size_t buflen, TDB_DATA *data,
4516 				size_t *npull)
4517 {
4518 	size_t offset = 0;
4519 	void *ptr;
4520 
4521 	if (buflen-offset < sizeof(void *)) {
4522 		return EMSGSIZE;
4523 	}
4524 
4525 	memcpy(&ptr, buf+offset, sizeof(void *));
4526 	offset += sizeof(void *);
4527 	data->dptr = NULL;
4528 
4529 	if (buflen-offset < sizeof(size_t)) {
4530 		return EMSGSIZE;
4531 	}
4532 
4533 	memcpy(&data->dsize, buf+offset, sizeof(size_t));
4534 	offset += sizeof(size_t);
4535 
4536 	*npull = offset;
4537 	return 0;
4538 }
4539 
ctdb_db_statistics_len(struct ctdb_db_statistics * in)4540 size_t ctdb_db_statistics_len(struct ctdb_db_statistics *in)
4541 {
4542 	TDB_DATA data = { 0 };
4543 	size_t len;
4544 	uint32_t u32 = 0;
4545 	int i;
4546 
4547 	len = ctdb_uint32_len(&in->locks.num_calls) +
4548 		ctdb_uint32_len(&in->locks.num_current) +
4549 		ctdb_uint32_len(&in->locks.num_pending) +
4550 		ctdb_uint32_len(&in->locks.num_failed) +
4551 		ctdb_latency_counter_len(&in->locks.latency) +
4552 		MAX_COUNT_BUCKETS *
4553 			ctdb_uint32_len(&in->locks.buckets[0]) +
4554 		ctdb_latency_counter_len(&in->vacuum.latency) +
4555 		ctdb_uint32_len(&in->db_ro_delegations) +
4556 		ctdb_uint32_len(&in->db_ro_revokes) +
4557 		MAX_COUNT_BUCKETS *
4558 			ctdb_uint32_len(&in->hop_count_bucket[0]) +
4559 		ctdb_uint32_len(&in->num_hot_keys) +
4560 		ctdb_padding_len(4) +
4561 		MAX_HOT_KEYS *
4562 			(ctdb_uint32_len(&u32) + ctdb_padding_len(4) +
4563 			 tdb_data_struct_len(&data));
4564 
4565 	for (i=0; i<MAX_HOT_KEYS; i++) {
4566 		len += ctdb_tdb_data_len(&in->hot_keys[i].key);
4567 	}
4568 
4569 	return len;
4570 }
4571 
ctdb_db_statistics_push(struct ctdb_db_statistics * in,uint8_t * buf,size_t * npush)4572 void ctdb_db_statistics_push(struct ctdb_db_statistics *in, uint8_t *buf,
4573 			     size_t *npush)
4574 {
4575 	size_t offset = 0, np;
4576 	uint32_t num_hot_keys;
4577 	int i;
4578 
4579 	ctdb_uint32_push(&in->locks.num_calls, buf+offset, &np);
4580 	offset += np;
4581 
4582 	ctdb_uint32_push(&in->locks.num_current, buf+offset, &np);
4583 	offset += np;
4584 
4585 	ctdb_uint32_push(&in->locks.num_pending, buf+offset, &np);
4586 	offset += np;
4587 
4588 	ctdb_uint32_push(&in->locks.num_failed, buf+offset, &np);
4589 	offset += np;
4590 
4591 	ctdb_latency_counter_push(&in->locks.latency, buf+offset, &np);
4592 	offset += np;
4593 
4594 	for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4595 		ctdb_uint32_push(&in->locks.buckets[i], buf+offset, &np);
4596 		offset += np;
4597 	}
4598 
4599 	ctdb_latency_counter_push(&in->vacuum.latency, buf+offset, &np);
4600 	offset += np;
4601 
4602 	ctdb_uint32_push(&in->db_ro_delegations, buf+offset, &np);
4603 	offset += np;
4604 
4605 	ctdb_uint32_push(&in->db_ro_revokes, buf+offset, &np);
4606 	offset += np;
4607 
4608 	for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4609 		ctdb_uint32_push(&in->hop_count_bucket[i], buf+offset, &np);
4610 		offset += np;
4611 	}
4612 
4613 	num_hot_keys = MAX_HOT_KEYS;
4614 	ctdb_uint32_push(&num_hot_keys, buf+offset, &np);
4615 	offset += np;
4616 
4617 	ctdb_padding_push(4, buf+offset, &np);
4618 	offset += np;
4619 
4620 	for (i=0; i<MAX_HOT_KEYS; i++) {
4621 		ctdb_uint32_push(&in->hot_keys[i].count, buf+offset, &np);
4622 		offset += np;
4623 
4624 		ctdb_padding_push(4, buf+offset, &np);
4625 		offset += np;
4626 
4627 		tdb_data_struct_push(&in->hot_keys[i].key, buf+offset, &np);
4628 		offset += np;
4629 	}
4630 
4631 	for (i=0; i<MAX_HOT_KEYS; i++) {
4632 		ctdb_tdb_data_push(&in->hot_keys[i].key, buf+offset, &np);
4633 		offset += np;
4634 	}
4635 
4636 	*npush = offset;
4637 }
4638 
ctdb_db_statistics_pull_elems(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_db_statistics * out,size_t * npull)4639 static int ctdb_db_statistics_pull_elems(uint8_t *buf, size_t buflen,
4640 					 TALLOC_CTX *mem_ctx,
4641 					 struct ctdb_db_statistics *out,
4642 					 size_t *npull)
4643 {
4644 	size_t offset = 0, np;
4645 	int ret, i;
4646 
4647 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4648 			       &out->locks.num_calls, &np);
4649 	if (ret != 0) {
4650 		return ret;
4651 	}
4652 	offset += np;
4653 
4654 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4655 			       &out->locks.num_current, &np);
4656 	if (ret != 0) {
4657 		return ret;
4658 	}
4659 	offset += np;
4660 
4661 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4662 			       &out->locks.num_pending, &np);
4663 	if (ret != 0) {
4664 		return ret;
4665 	}
4666 	offset += np;
4667 
4668 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4669 			       &out->locks.num_failed, &np);
4670 	if (ret != 0) {
4671 		return ret;
4672 	}
4673 	offset += np;
4674 
4675 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
4676 					&out->locks.latency, &np);
4677 	if (ret != 0) {
4678 		return ret;
4679 	}
4680 	offset += np;
4681 
4682 	for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4683 		ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4684 				       &out->locks.buckets[i], &np);
4685 		if (ret != 0) {
4686 			return ret;
4687 		}
4688 		offset += np;
4689 	}
4690 
4691 	ret = ctdb_latency_counter_pull(buf+offset, buflen-offset,
4692 					&out->vacuum.latency, &np);
4693 	if (ret != 0) {
4694 		return ret;
4695 	}
4696 	offset += np;
4697 
4698 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4699 			       &out->db_ro_delegations, &np);
4700 	if (ret != 0) {
4701 		return ret;
4702 	}
4703 	offset += np;
4704 
4705 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4706 			       &out->db_ro_revokes, &np);
4707 	if (ret != 0) {
4708 		return ret;
4709 	}
4710 	offset += np;
4711 
4712 	for (i=0; i<MAX_COUNT_BUCKETS; i++) {
4713 		ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4714 				       &out->hop_count_bucket[i], &np);
4715 		if (ret != 0) {
4716 			return ret;
4717 		}
4718 		offset += np;
4719 	}
4720 
4721 	ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4722 			       &out->num_hot_keys, &np);
4723 	if (ret != 0) {
4724 		return ret;
4725 	}
4726 	offset += np;
4727 
4728 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4729 	if (ret != 0) {
4730 		return ret;
4731 	}
4732 	offset += np;
4733 
4734 	for (i=0; i<MAX_HOT_KEYS; i++) {
4735 		ret = ctdb_uint32_pull(buf+offset, buflen-offset,
4736 				       &out->hot_keys[i].count, &np);
4737 		if (ret != 0) {
4738 			return ret;
4739 		}
4740 		offset += np;
4741 
4742 		ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4743 		if (ret != 0) {
4744 			return ret;
4745 		}
4746 		offset += np;
4747 
4748 		ret = tdb_data_struct_pull(buf+offset, buflen-offset,
4749 					   &out->hot_keys[i].key, &np);
4750 		if (ret != 0) {
4751 			return ret;
4752 		}
4753 		offset += np;
4754 	}
4755 
4756 	for (i=0; i<MAX_HOT_KEYS; i++) {
4757 		ret = ctdb_tdb_data_pull(buf+offset,
4758 					 out->hot_keys[i].key.dsize,
4759 					 out, &out->hot_keys[i].key, &np);
4760 		if (ret != 0) {
4761 			return ret;
4762 		}
4763 		offset += np;
4764 	}
4765 
4766 	*npull = offset;
4767 	return 0;
4768 }
4769 
ctdb_db_statistics_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_db_statistics ** out,size_t * npull)4770 int ctdb_db_statistics_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4771 			    struct ctdb_db_statistics **out, size_t *npull)
4772 {
4773 	struct ctdb_db_statistics *val;
4774 	size_t np;
4775 	int ret;
4776 
4777 	val = talloc(mem_ctx, struct ctdb_db_statistics);
4778 	if (val == NULL) {
4779 		return ENOMEM;
4780 	}
4781 
4782 	ret = ctdb_db_statistics_pull_elems(buf, buflen, val, val, &np);
4783 	if (ret != 0) {
4784 		talloc_free(val);
4785 		return ret;
4786 	}
4787 
4788 	*out = val;
4789 	*npull = np;
4790 	return 0;
4791 }
4792 
ctdb_pid_srvid_len(struct ctdb_pid_srvid * in)4793 size_t ctdb_pid_srvid_len(struct ctdb_pid_srvid *in)
4794 {
4795 	return ctdb_pid_len(&in->pid) +
4796 		ctdb_uint64_len(&in->srvid);
4797 }
4798 
ctdb_pid_srvid_push(struct ctdb_pid_srvid * in,uint8_t * buf,size_t * npush)4799 void ctdb_pid_srvid_push(struct ctdb_pid_srvid *in, uint8_t *buf,
4800 			 size_t *npush)
4801 {
4802 	size_t offset = 0, np;
4803 
4804 	ctdb_pid_push(&in->pid, buf+offset, &np);
4805 	offset += np;
4806 
4807 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
4808 	offset += np;
4809 
4810 	*npush = offset;
4811 }
4812 
ctdb_pid_srvid_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_pid_srvid ** out,size_t * npull)4813 int ctdb_pid_srvid_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4814 			struct ctdb_pid_srvid **out, size_t *npull)
4815 {
4816 	struct ctdb_pid_srvid *val;
4817 	size_t offset = 0, np;
4818 	int ret;
4819 
4820 	val = talloc(mem_ctx, struct ctdb_pid_srvid);
4821 	if (val == NULL) {
4822 		return ENOMEM;
4823 	}
4824 
4825 	ret = ctdb_pid_pull(buf+offset, buflen-offset, &val->pid, &np);
4826 	if (ret != 0) {
4827 		goto fail;
4828 	}
4829 	offset += np;
4830 
4831 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
4832 	if (ret != 0) {
4833 		goto fail;
4834 	}
4835 	offset += np;
4836 
4837 	*out = val;
4838 	*npull = offset;
4839 	return 0;
4840 
4841 fail:
4842 	talloc_free(val);
4843 	return ret;
4844 }
4845 
ctdb_election_message_len(struct ctdb_election_message * in)4846 size_t ctdb_election_message_len(struct ctdb_election_message *in)
4847 {
4848 	return ctdb_uint32_len(&in->num_connected) +
4849 		ctdb_padding_len(4) +
4850 		ctdb_timeval_len(&in->priority_time) +
4851 		ctdb_uint32_len(&in->pnn) +
4852 		ctdb_uint32_len(&in->node_flags);
4853 }
4854 
ctdb_election_message_push(struct ctdb_election_message * in,uint8_t * buf,size_t * npush)4855 void ctdb_election_message_push(struct ctdb_election_message *in,
4856 				uint8_t *buf, size_t *npush)
4857 {
4858 	size_t offset = 0, np;
4859 
4860 	ctdb_uint32_push(&in->num_connected, buf+offset, &np);
4861 	offset += np;
4862 
4863 	ctdb_padding_push(4, buf+offset, &np);
4864 	offset += np;
4865 
4866 	ctdb_timeval_push(&in->priority_time, buf+offset, &np);
4867 	offset += np;
4868 
4869 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
4870 	offset += np;
4871 
4872 	ctdb_uint32_push(&in->node_flags, buf+offset, &np);
4873 	offset += np;
4874 
4875 	*npush = offset;
4876 }
4877 
ctdb_election_message_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_election_message ** out,size_t * npull)4878 int ctdb_election_message_pull(uint8_t *buf, size_t buflen,
4879 			       TALLOC_CTX *mem_ctx,
4880 			       struct ctdb_election_message **out,
4881 			       size_t *npull)
4882 {
4883 	struct ctdb_election_message *val;
4884 	size_t offset = 0, np;
4885 	int ret;
4886 
4887 	val = talloc(mem_ctx, struct ctdb_election_message);
4888 	if (val == NULL) {
4889 		return ENOMEM;
4890 	}
4891 
4892 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->num_connected,
4893 			       &np);
4894 	if (ret != 0) {
4895 		goto fail;
4896 	}
4897 	offset += np;
4898 
4899 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4900 	if (ret != 0) {
4901 		goto fail;
4902 	}
4903 	offset += np;
4904 
4905 	ret = ctdb_timeval_pull(buf+offset, buflen-offset,
4906 				&val->priority_time, &np);
4907 	if (ret != 0) {
4908 		goto fail;
4909 	}
4910 	offset += np;
4911 
4912 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
4913 	if (ret != 0) {
4914 		goto fail;
4915 	}
4916 	offset += np;
4917 
4918 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->node_flags,
4919 			       &np);
4920 	if (ret != 0) {
4921 		goto fail;
4922 	}
4923 	offset += np;
4924 
4925 	*out = val;
4926 	*npull = offset;
4927 	return 0;
4928 
4929 fail:
4930 	talloc_free(val);
4931 	return ret;
4932 }
4933 
ctdb_srvid_message_len(struct ctdb_srvid_message * in)4934 size_t ctdb_srvid_message_len(struct ctdb_srvid_message *in)
4935 {
4936 	return ctdb_uint32_len(&in->pnn) +
4937 		ctdb_padding_len(4) +
4938 		ctdb_uint64_len(&in->srvid);
4939 }
4940 
ctdb_srvid_message_push(struct ctdb_srvid_message * in,uint8_t * buf,size_t * npush)4941 void ctdb_srvid_message_push(struct ctdb_srvid_message *in, uint8_t *buf,
4942 			     size_t *npush)
4943 {
4944 	size_t offset = 0, np;
4945 
4946 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
4947 	offset += np;
4948 
4949 	ctdb_padding_push(4, buf+offset, &np);
4950 	offset += np;
4951 
4952 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
4953 	offset += np;
4954 
4955 	*npush = offset;
4956 }
4957 
ctdb_srvid_message_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_srvid_message ** out,size_t * npull)4958 int ctdb_srvid_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
4959 			    struct ctdb_srvid_message **out, size_t *npull)
4960 {
4961 	struct ctdb_srvid_message *val;
4962 	size_t offset = 0, np;
4963 	int ret;
4964 
4965 	val = talloc(mem_ctx, struct ctdb_srvid_message);
4966 	if (val == NULL) {
4967 		return ENOMEM;
4968 	}
4969 
4970 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
4971 	if (ret != 0) {
4972 		goto fail;
4973 	}
4974 	offset += np;
4975 
4976 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
4977 	if (ret != 0) {
4978 		goto fail;
4979 	}
4980 	offset += np;
4981 
4982 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
4983 	if (ret != 0) {
4984 		goto fail;
4985 	}
4986 	offset += np;
4987 
4988 	*out = val;
4989 	*npull = offset;
4990 	return 0;
4991 
4992 fail:
4993 	talloc_free(val);
4994 	return ret;
4995 }
4996 
ctdb_disable_message_len(struct ctdb_disable_message * in)4997 size_t ctdb_disable_message_len(struct ctdb_disable_message *in)
4998 {
4999 	return ctdb_uint32_len(&in->pnn) +
5000 		ctdb_padding_len(4) +
5001 		ctdb_uint64_len(&in->srvid) +
5002 		ctdb_uint32_len(&in->timeout) +
5003 		ctdb_padding_len(4);
5004 }
5005 
ctdb_disable_message_push(struct ctdb_disable_message * in,uint8_t * buf,size_t * npush)5006 void ctdb_disable_message_push(struct ctdb_disable_message *in, uint8_t *buf,
5007 			       size_t *npush)
5008 {
5009 	size_t offset = 0, np;
5010 
5011 	ctdb_uint32_push(&in->pnn, buf+offset, &np);
5012 	offset += np;
5013 
5014 	ctdb_padding_push(4, buf+offset, &np);
5015 	offset += np;
5016 
5017 	ctdb_uint64_push(&in->srvid, buf+offset, &np);
5018 	offset += np;
5019 
5020 	ctdb_uint32_push(&in->timeout, buf+offset, &np);
5021 	offset += np;
5022 
5023 	ctdb_padding_push(4, buf+offset, &np);
5024 	offset += np;
5025 
5026 	*npush = offset;
5027 }
5028 
ctdb_disable_message_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_disable_message ** out,size_t * npull)5029 int ctdb_disable_message_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
5030 			      struct ctdb_disable_message **out,
5031 			      size_t *npull)
5032 {
5033 	struct ctdb_disable_message *val;
5034 	size_t offset = 0, np;
5035 	int ret;
5036 
5037 	val = talloc(mem_ctx, struct ctdb_disable_message);
5038 	if (val == NULL) {
5039 		return ENOMEM;
5040 	}
5041 
5042 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->pnn, &np);
5043 	if (ret != 0) {
5044 		goto fail;
5045 	}
5046 	offset += np;
5047 
5048 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5049 	if (ret != 0) {
5050 		goto fail;
5051 	}
5052 	offset += np;
5053 
5054 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &val->srvid, &np);
5055 	if (ret != 0) {
5056 		goto fail;
5057 	}
5058 	offset += np;
5059 
5060 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &val->timeout, &np);
5061 	if (ret != 0) {
5062 		goto fail;
5063 	}
5064 	offset += np;
5065 
5066 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5067 	if (ret != 0) {
5068 		goto fail;
5069 	}
5070 	offset += np;
5071 
5072 	*out = val;
5073 	*npull = offset;
5074 	return 0;
5075 
5076 fail:
5077 	talloc_free(val);
5078 	return ret;
5079 }
5080 
ctdb_server_id_len(struct ctdb_server_id * in)5081 size_t ctdb_server_id_len(struct ctdb_server_id *in)
5082 {
5083 	return ctdb_uint64_len(&in->pid) +
5084 		ctdb_uint32_len(&in->task_id) +
5085 		ctdb_uint32_len(&in->vnn) +
5086 		ctdb_uint64_len(&in->unique_id);
5087 }
5088 
ctdb_server_id_push(struct ctdb_server_id * in,uint8_t * buf,size_t * npush)5089 void ctdb_server_id_push(struct ctdb_server_id *in, uint8_t *buf,
5090 			 size_t *npush)
5091 {
5092 	size_t offset = 0, np;
5093 
5094 	ctdb_uint64_push(&in->pid, buf+offset, &np);
5095 	offset += np;
5096 
5097 	ctdb_uint32_push(&in->task_id, buf+offset, &np);
5098 	offset += np;
5099 
5100 	ctdb_uint32_push(&in->vnn, buf+offset, &np);
5101 	offset += np;
5102 
5103 	ctdb_uint64_push(&in->unique_id, buf+offset, &np);
5104 	offset += np;
5105 
5106 	*npush = offset;
5107 }
5108 
ctdb_server_id_pull(uint8_t * buf,size_t buflen,struct ctdb_server_id * out,size_t * npull)5109 int ctdb_server_id_pull(uint8_t *buf, size_t buflen,
5110 			struct ctdb_server_id *out, size_t *npull)
5111 {
5112 	size_t offset = 0, np;
5113 	int ret;
5114 
5115 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &out->pid, &np);
5116 	if (ret != 0) {
5117 		return ret;
5118 	}
5119 	offset += np;
5120 
5121 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->task_id, &np);
5122 	if (ret != 0) {
5123 		return ret;
5124 	}
5125 	offset += np;
5126 
5127 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->vnn, &np);
5128 	if (ret != 0) {
5129 		return ret;
5130 	}
5131 	offset += np;
5132 
5133 	ret = ctdb_uint64_pull(buf+offset, buflen-offset, &out->unique_id,
5134 			       &np);
5135 	if (ret != 0) {
5136 		return ret;
5137 	}
5138 	offset += np;
5139 
5140 	*npull = offset;
5141 	return 0;
5142 }
5143 
ctdb_g_lock_len(struct ctdb_g_lock * in)5144 size_t ctdb_g_lock_len(struct ctdb_g_lock *in)
5145 {
5146 	return ctdb_uint32_len(&in->type) +
5147 		ctdb_padding_len(4) +
5148 		ctdb_server_id_len(&in->sid);
5149 }
5150 
ctdb_g_lock_push(struct ctdb_g_lock * in,uint8_t * buf,size_t * npush)5151 void ctdb_g_lock_push(struct ctdb_g_lock *in, uint8_t *buf, size_t *npush)
5152 {
5153 	size_t offset = 0, np;
5154 	uint32_t type;
5155 
5156 	type = in->type;
5157 	ctdb_uint32_push(&type, buf+offset, &np);
5158 	offset += np;
5159 
5160 	ctdb_padding_push(4, buf+offset, &np);
5161 	offset += np;
5162 
5163 	ctdb_server_id_push(&in->sid, buf+offset, &np);
5164 	offset += np;
5165 
5166 	*npush = offset;
5167 }
5168 
ctdb_g_lock_pull(uint8_t * buf,size_t buflen,struct ctdb_g_lock * out,size_t * npull)5169 int ctdb_g_lock_pull(uint8_t *buf, size_t buflen, struct ctdb_g_lock *out,
5170 		     size_t *npull)
5171 {
5172 	size_t offset = 0, np;
5173 	int ret;
5174 	uint32_t type;
5175 
5176 	ret = ctdb_uint32_pull(buf+offset, buflen-offset, &type, &np);
5177 	if (ret != 0) {
5178 		return ret;
5179 	}
5180 	offset += np;
5181 
5182 	if (type == 0) {
5183 		out->type = CTDB_G_LOCK_READ;
5184 	} else if (type == 1) {
5185 		out->type = CTDB_G_LOCK_WRITE;
5186 	} else {
5187 		return EPROTO;
5188 	}
5189 
5190 	ret = ctdb_padding_pull(buf+offset, buflen-offset, 4, &np);
5191 	if (ret != 0) {
5192 		return ret;
5193 	}
5194 	offset += np;
5195 
5196 	ret = ctdb_server_id_pull(buf+offset, buflen-offset, &out->sid, &np);
5197 	if (ret != 0) {
5198 		return ret;
5199 	}
5200 	offset += np;
5201 
5202 	*npull = offset;
5203 	return 0;
5204 }
5205 
ctdb_g_lock_list_len(struct ctdb_g_lock_list * in)5206 size_t ctdb_g_lock_list_len(struct ctdb_g_lock_list *in)
5207 {
5208 	size_t len = 0;
5209 
5210 	if (in->num > 0) {
5211 		len += in->num * ctdb_g_lock_len(&in->lock[0]);
5212 	}
5213 
5214 	return len;
5215 }
5216 
ctdb_g_lock_list_push(struct ctdb_g_lock_list * in,uint8_t * buf,size_t * npush)5217 void ctdb_g_lock_list_push(struct ctdb_g_lock_list *in, uint8_t *buf,
5218 			   size_t *npush)
5219 {
5220 	size_t offset = 0, np;
5221 	uint32_t i;
5222 
5223 	for (i=0; i<in->num; i++) {
5224 		ctdb_g_lock_push(&in->lock[i], buf+offset, &np);
5225 		offset += np;
5226 	}
5227 
5228 	*npush = offset;
5229 }
5230 
ctdb_g_lock_list_pull(uint8_t * buf,size_t buflen,TALLOC_CTX * mem_ctx,struct ctdb_g_lock_list ** out,size_t * npull)5231 int ctdb_g_lock_list_pull(uint8_t *buf, size_t buflen, TALLOC_CTX *mem_ctx,
5232 			  struct ctdb_g_lock_list **out, size_t *npull)
5233 {
5234 	struct ctdb_g_lock_list *val;
5235 	struct ctdb_g_lock lock = { 0 };
5236 	size_t offset = 0, np;
5237 	uint32_t i;
5238 	int ret;
5239 
5240 	val = talloc(mem_ctx, struct ctdb_g_lock_list);
5241 	if (val == NULL) {
5242 		return ENOMEM;
5243 	}
5244 
5245 	if (buflen == 0) {
5246 		val->lock = NULL;
5247 		val->num = 0;
5248 		goto done;
5249 	}
5250 
5251 	val->num = buflen / ctdb_g_lock_len(&lock);
5252 
5253 	val->lock = talloc_array(val, struct ctdb_g_lock, val->num);
5254 	if (val->lock == NULL) {
5255 		ret = ENOMEM;
5256 		goto fail;
5257 	}
5258 
5259 	for (i=0; i<val->num; i++) {
5260 		ret = ctdb_g_lock_pull(buf+offset, buflen-offset,
5261 				       &val->lock[i], &np);
5262 		if (ret != 0) {
5263 			goto fail;
5264 		}
5265 		offset += np;
5266 	}
5267 
5268 done:
5269 	*out = val;
5270 	*npull = offset;
5271 	return 0;
5272 
5273 fail:
5274 	talloc_free(val);
5275 	return ret;
5276 }
5277