1f608ad8ea1603fc9c0bb5ebd7e44e0af2853673
[vlendec/samba-autobuild/.git] / ctdb / protocol / protocol_event.c
1 /*
2    CTDB eventd protocol marshalling
3
4    Copyright (C) Amitay Isaacs  2016
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
25 #include "protocol.h"
26 #include "protocol_private.h"
27 #include "protocol_api.h"
28
29 static size_t ctdb_event_len(enum ctdb_event in)
30 {
31         uint32_t u32 = in;
32
33         return ctdb_uint32_len(&u32);
34 }
35
36 static void ctdb_event_push(enum ctdb_event in, uint8_t *buf, size_t *npush)
37 {
38         size_t np;
39         uint32_t u32 = in;
40
41         ctdb_uint32_push(&u32, buf, &np);
42
43         *npush = np;
44 }
45
46 static int ctdb_event_pull(uint8_t *buf, size_t buflen,
47                            TALLOC_CTX *mem_ctx, enum ctdb_event *out,
48                            size_t *npull)
49 {
50         uint32_t uint32_value;
51         enum ctdb_event value;
52         size_t np;
53         int ret;
54
55         ret = ctdb_uint32_pull(buf, buflen, &uint32_value, &np);
56         if (ret != 0) {
57                 return ret;
58         }
59
60         switch (uint32_value) {
61         case 0:
62                 value = CTDB_EVENT_INIT;
63                 break;
64
65         case 1:
66                 value = CTDB_EVENT_SETUP;
67                 break;
68
69         case 2:
70                 value = CTDB_EVENT_STARTUP;
71                 break;
72
73         case 3:
74                 value = CTDB_EVENT_START_RECOVERY;
75                 break;
76
77         case 4:
78                 value = CTDB_EVENT_RECOVERED;
79                 break;
80
81         case 5:
82                 value = CTDB_EVENT_TAKE_IP;
83                 break;
84
85         case 6:
86                 value = CTDB_EVENT_RELEASE_IP;
87                 break;
88
89         case 7:
90                 value = CTDB_EVENT_STOPPED;
91                 break;
92
93         case 8:
94                 value = CTDB_EVENT_MONITOR;
95                 break;
96
97         case 9:
98                 value = CTDB_EVENT_STATUS;
99                 break;
100
101         case 10:
102                 value = CTDB_EVENT_SHUTDOWN;
103                 break;
104
105         case 11:
106                 value = CTDB_EVENT_RELOAD;
107                 break;
108
109         case 12:
110                 value = CTDB_EVENT_UPDATE_IP;
111                 break;
112
113         case 13:
114                 value = CTDB_EVENT_IPREALLOCATED;
115                 break;
116
117         default:
118                 return EINVAL;
119         }
120
121         *out = value;
122         *npull = np;
123         return 0;
124 }
125
126 static size_t ctdb_event_command_len(enum ctdb_event_command in)
127 {
128         uint32_t u32 = in;
129
130         return ctdb_uint32_len(&u32);
131 }
132
133 static void ctdb_event_command_push(enum ctdb_event_command in, uint8_t *buf,
134                                     size_t *npush)
135 {
136         size_t np;
137         uint32_t u32 = in;
138
139         ctdb_uint32_push(&u32, buf, &np);
140
141         *npush = np;
142 }
143
144 static int ctdb_event_command_pull(uint8_t *buf, size_t buflen,
145                                    TALLOC_CTX *mem_ctx,
146                                    enum ctdb_event_command *out,
147                                    size_t *npull)
148 {
149         uint32_t uint32_value;
150         enum ctdb_event_command value;
151         size_t np;
152         int ret;
153
154         ret = ctdb_uint32_pull(buf, buflen, &uint32_value, &np);
155         if (ret != 0) {
156                 return ret;
157         }
158
159         switch (uint32_value) {
160         case 1:
161                 value = CTDB_EVENT_COMMAND_RUN;
162                 break;
163
164         case 2:
165                 value = CTDB_EVENT_COMMAND_STATUS;
166                 break;
167
168         case 3:
169                 value = CTDB_EVENT_COMMAND_SCRIPT_LIST;
170                 break;
171
172         case 4:
173                 value = CTDB_EVENT_COMMAND_SCRIPT_ENABLE;
174                 break;
175
176         case 5:
177                 value = CTDB_EVENT_COMMAND_SCRIPT_DISABLE;
178                 break;
179
180         default:
181                 return EINVAL;
182         }
183
184         *out = value;
185         *npull = np;
186         return 0;
187 }
188
189 static size_t ctdb_event_status_state_len(enum ctdb_event_status_state in)
190 {
191         uint32_t u32 = in;
192
193         return ctdb_uint32_len(&u32);
194 }
195
196 static void ctdb_event_status_state_push(enum ctdb_event_status_state in,
197                                          uint8_t *buf, size_t *npush)
198 {
199         size_t np;
200         uint32_t u32 = in;
201
202         ctdb_uint32_push(&u32, buf, &np);
203
204         *npush = np;
205 }
206
207 static int ctdb_event_status_state_pull(uint8_t *buf, size_t buflen,
208                                         TALLOC_CTX *mem_ctx,
209                                         enum ctdb_event_status_state *out,
210                                         size_t *npull)
211 {
212         uint32_t uint32_value;
213         enum ctdb_event_status_state value;
214         size_t np;
215         int ret;
216
217         ret = ctdb_uint32_pull(buf, buflen, &uint32_value, &np);
218         if (ret != 0) {
219                 return ret;
220         }
221
222         switch (uint32_value) {
223         case 1:
224                 value = CTDB_EVENT_LAST_RUN;
225                 break;
226
227         case 2:
228                 value = CTDB_EVENT_LAST_PASS;
229                 break;
230
231         case 3:
232                 value = CTDB_EVENT_LAST_FAIL;
233                 break;
234
235         default:
236                 return EINVAL;
237         }
238
239         *out = value;
240         *npull = np;
241         return 0;
242 }
243
244 static size_t ctdb_event_request_run_len(struct ctdb_event_request_run *in)
245 {
246         return ctdb_event_len(in->event) +
247                ctdb_uint32_len(&in->timeout) +
248                ctdb_stringn_len(&in->arg_str);
249 }
250
251 static void ctdb_event_request_run_push(struct ctdb_event_request_run *in,
252                                         uint8_t *buf, size_t *npush)
253 {
254         size_t offset = 0, np;
255
256         ctdb_event_push(in->event, buf, &np);
257         offset += np;
258
259         ctdb_uint32_push(&in->timeout, buf+offset, &np);
260         offset += np;
261
262         ctdb_stringn_push(&in->arg_str, buf+offset, &np);
263         offset += np;
264
265         *npush = offset;
266 }
267
268 static int ctdb_event_request_run_pull(uint8_t *buf, size_t buflen,
269                                        TALLOC_CTX *mem_ctx,
270                                        struct ctdb_event_request_run **out,
271                                        size_t *npull)
272 {
273         struct ctdb_event_request_run *rdata;
274         size_t offset = 0, np;
275         int ret;
276
277         rdata = talloc(mem_ctx, struct ctdb_event_request_run);
278         if (rdata == NULL) {
279                 return ENOMEM;
280         }
281
282         ret = ctdb_event_pull(buf, buflen, rdata, &rdata->event, &np);
283         if (ret != 0) {
284                 goto fail;
285         }
286         offset += np;
287
288         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &rdata->timeout,
289                                &np);
290         if (ret != 0) {
291                 goto fail;
292         }
293         offset += np;
294
295         ret = ctdb_stringn_pull(buf+offset, buflen-offset,
296                                 rdata, &rdata->arg_str, &np);
297         if (ret != 0) {
298                 goto fail;
299         }
300         offset += np;
301
302         *out = rdata;
303         *npull = offset;
304         return 0;
305
306 fail:
307         talloc_free(rdata);
308         return ret;
309 }
310
311 static size_t ctdb_event_request_status_len(
312                                 struct ctdb_event_request_status *in)
313 {
314         return ctdb_event_len(in->event) +
315                ctdb_event_status_state_len(in->state);
316 }
317
318 static void ctdb_event_request_status_push(
319                                 struct ctdb_event_request_status *in,
320                                 uint8_t *buf, size_t *npush)
321 {
322         size_t offset = 0, np;
323
324         ctdb_event_push(in->event, buf, &np);
325         offset += np;
326
327         ctdb_event_status_state_push(in->state, buf+offset, &np);
328         offset += np;
329
330         *npush = offset;
331 }
332
333 static int ctdb_event_request_status_pull(
334                                 uint8_t *buf, size_t buflen,
335                                 TALLOC_CTX *mem_ctx,
336                                 struct ctdb_event_request_status **out,
337                                 size_t *npull)
338 {
339         struct ctdb_event_request_status *rdata;
340         size_t offset = 0, np;
341         int ret;
342
343         rdata = talloc(mem_ctx, struct ctdb_event_request_status);
344         if (rdata == NULL) {
345                 return ENOMEM;
346         }
347
348         ret = ctdb_event_pull(buf, buflen, rdata, &rdata->event, &np);
349         if (ret != 0) {
350                 talloc_free(rdata);
351                 return ret;
352         }
353         offset += np;
354
355         ret = ctdb_event_status_state_pull(buf+offset, buflen-offset,
356                                            rdata, &rdata->state, &np);
357         if (ret != 0) {
358                 talloc_free(rdata);
359                 return ret;
360         }
361         offset += np;
362
363         *out = rdata;
364         *npull = offset;
365         return 0;
366 }
367
368 static size_t ctdb_event_request_script_enable_len(
369                                 struct ctdb_event_request_script_enable *in)
370 {
371         return ctdb_stringn_len(&in->script_name);
372 }
373
374 static void ctdb_event_request_script_enable_push(
375                                 struct ctdb_event_request_script_enable *in,
376                                 uint8_t *buf, size_t *npush)
377 {
378         size_t np;
379
380         ctdb_stringn_push(&in->script_name, buf, &np);
381
382         *npush = np;
383 }
384
385 static int ctdb_event_request_script_enable_pull(
386                                 uint8_t *buf, size_t buflen,
387                                 TALLOC_CTX *mem_ctx,
388                                 struct ctdb_event_request_script_enable **out,
389                                 size_t *npull)
390 {
391         struct ctdb_event_request_script_enable *rdata;
392         size_t np;
393         int ret;
394
395         rdata = talloc(mem_ctx, struct ctdb_event_request_script_enable);
396         if (rdata == NULL) {
397                 return ENOMEM;
398         }
399
400         ret = ctdb_stringn_pull(buf, buflen, rdata, &rdata->script_name, &np);
401         if (ret != 0) {
402                 talloc_free(rdata);
403                 return ret;
404         }
405
406         *out = rdata;
407         *npull = np;
408         return 0;
409 }
410
411 static size_t ctdb_event_request_script_disable_len(
412                                 struct ctdb_event_request_script_disable *in)
413 {
414         return ctdb_stringn_len(&in->script_name);
415 }
416
417 static void ctdb_event_request_script_disable_push(
418                                 struct ctdb_event_request_script_disable *in,
419                                 uint8_t *buf, size_t *npush)
420 {
421         size_t np;
422
423         ctdb_stringn_push(&in->script_name, buf, &np);
424
425         *npush = np;
426 }
427
428 static int ctdb_event_request_script_disable_pull(
429                                 uint8_t *buf, size_t buflen,
430                                 TALLOC_CTX *mem_ctx,
431                                 struct ctdb_event_request_script_disable **out,
432                                 size_t *npull)
433 {
434         struct ctdb_event_request_script_disable *rdata;
435         size_t np;
436         int ret;
437
438         rdata = talloc(mem_ctx, struct ctdb_event_request_script_disable);
439         if (rdata == NULL) {
440                 return ENOMEM;
441         }
442
443         ret = ctdb_stringn_pull(buf, buflen, rdata, &rdata->script_name, &np);
444         if (ret != 0) {
445                 talloc_free(rdata);
446                 return ret;
447         }
448
449         *out = rdata;
450         *npull = np;
451         return 0;
452 }
453
454 static size_t ctdb_event_request_data_len(struct ctdb_event_request_data *in)
455 {
456         size_t len = 0;
457
458         len += ctdb_event_command_len(in->command);
459
460         switch(in->command) {
461         case CTDB_EVENT_COMMAND_RUN:
462                 len += ctdb_event_request_run_len(in->data.run);
463                 break;
464
465         case CTDB_EVENT_COMMAND_STATUS:
466                 len += ctdb_event_request_status_len(in->data.status);
467                 break;
468
469         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
470                 break;
471
472         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
473                 len += ctdb_event_request_script_enable_len(
474                                                 in->data.script_enable);
475                 break;
476
477         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
478                 len += ctdb_event_request_script_disable_len(
479                                                 in->data.script_disable);
480                 break;
481         }
482
483         return len;
484 }
485
486 static void ctdb_event_request_data_push(struct ctdb_event_request_data *in,
487                                          uint8_t *buf, size_t *npush)
488 {
489         size_t offset = 0, np;
490
491         ctdb_event_command_push(in->command, buf, &np);
492         offset += np;
493
494         np = 0;
495         switch (in->command) {
496         case CTDB_EVENT_COMMAND_RUN:
497                 ctdb_event_request_run_push(in->data.run, buf+offset, &np);
498                 break;
499
500         case CTDB_EVENT_COMMAND_STATUS:
501                 ctdb_event_request_status_push(in->data.status, buf+offset,
502                                                &np);
503                 break;
504
505         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
506                 break;
507
508         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
509                 ctdb_event_request_script_enable_push(
510                                                 in->data.script_enable,
511                                                 buf+offset, &np);
512                 break;
513
514         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
515                 ctdb_event_request_script_disable_push(
516                                                 in->data.script_disable,
517                                                 buf+offset, &np);
518                 break;
519         }
520         offset += np;
521
522         *npush = offset;
523 }
524
525 static int ctdb_event_request_data_pull(uint8_t *buf, size_t buflen,
526                                         TALLOC_CTX *mem_ctx,
527                                         struct ctdb_event_request_data *out,
528                                         size_t *npull)
529 {
530         size_t offset = 0, np;
531         int ret;
532
533         ret = ctdb_event_command_pull(buf, buflen, mem_ctx, &out->command,
534                                       &np);
535         if (ret != 0) {
536                 return ret;
537         }
538         offset += np;
539
540         np = 0;
541         switch (out->command) {
542         case CTDB_EVENT_COMMAND_RUN:
543                 ret = ctdb_event_request_run_pull(buf+offset, buflen-offset,
544                                                   mem_ctx, &out->data.run,
545                                                   &np);
546                 break;
547
548         case CTDB_EVENT_COMMAND_STATUS:
549                 ret = ctdb_event_request_status_pull(
550                                                 buf+offset, buflen-offset,
551                                                 mem_ctx, &out->data.status,
552                                                 &np);
553                 break;
554
555         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
556                 ret = 0;
557                 break;
558
559         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
560                 ret = ctdb_event_request_script_enable_pull(
561                                                 buf+offset, buflen-offset,
562                                                 mem_ctx,
563                                                 &out->data.script_enable,
564                                                 &np);
565                 break;
566
567         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
568                 ret = ctdb_event_request_script_disable_pull(
569                                                 buf+offset, buflen-offset,
570                                                 mem_ctx,
571                                                 &out->data.script_disable,
572                                                 &np);
573                 break;
574         }
575
576         if (ret != 0) {
577                 return ret;
578         }
579
580         offset += np;
581
582         *npull = offset;
583         return 0;
584 }
585
586 static size_t ctdb_event_reply_status_len(struct ctdb_event_reply_status *in)
587 {
588         return ctdb_int32_len(&in->status) +
589                ctdb_script_list_len(in->script_list);
590 }
591
592 static void ctdb_event_reply_status_push(struct ctdb_event_reply_status *in,
593                                          uint8_t *buf, size_t *npush)
594 {
595         size_t offset = 0, np;
596
597         ctdb_int32_push(&in->status, buf, &np);
598         offset += np;
599
600         ctdb_script_list_push(in->script_list, buf+offset, &np);
601         offset += np;
602
603         *npush = offset;
604 }
605
606 static int ctdb_event_reply_status_pull(uint8_t *buf, size_t buflen,
607                                         TALLOC_CTX *mem_ctx,
608                                         struct ctdb_event_reply_status **out,
609                                         size_t *npull)
610 {
611         struct ctdb_event_reply_status *rdata;
612         size_t offset = 0, np;
613         int ret;
614
615         rdata = talloc(mem_ctx, struct ctdb_event_reply_status);
616         if (rdata == NULL) {
617                 return ENOMEM;
618         }
619
620         ret = ctdb_int32_pull(buf, buflen, &rdata->status, &np);
621         if (ret != 0) {
622                 talloc_free(rdata);
623                 return ret;
624         }
625         offset += np;
626
627         ret = ctdb_script_list_pull(buf+offset, buflen-offset,
628                                     rdata, &rdata->script_list, &np);
629         if (ret != 0) {
630                 talloc_free(rdata);
631                 return ret;
632         }
633         offset += np;
634
635         *out = rdata;
636         *npull = offset;
637         return 0;
638 }
639
640 static size_t ctdb_event_reply_script_list_len(
641                                 struct ctdb_event_reply_script_list *in)
642 {
643         return ctdb_script_list_len(in->script_list);
644 }
645
646 static void ctdb_event_reply_script_list_push(
647                                 struct ctdb_event_reply_script_list *in,
648                                 uint8_t *buf)
649 {
650         size_t np;
651
652         ctdb_script_list_push(in->script_list, buf, &np);
653 }
654
655 static int ctdb_event_reply_script_list_pull(
656                                 uint8_t *buf, size_t buflen,
657                                 TALLOC_CTX *mem_ctx,
658                                 struct ctdb_event_reply_script_list **out)
659 {
660         struct ctdb_event_reply_script_list *rdata;
661         size_t np;
662         int ret;
663
664         rdata = talloc(mem_ctx, struct ctdb_event_reply_script_list);
665         if (rdata == NULL) {
666                 return ENOMEM;
667         }
668
669         ret = ctdb_script_list_pull(buf, buflen, rdata, &rdata->script_list,
670                                     &np);
671         if (ret != 0) {
672                 talloc_free(rdata);
673                 return ret;
674         }
675
676         *out = rdata;
677         return 0;
678 }
679
680 static size_t ctdb_event_reply_data_len(struct ctdb_event_reply_data *in)
681 {
682         size_t len = 0;
683
684         len += ctdb_event_command_len(in->command);
685         len += ctdb_int32_len(&in->result);
686
687         switch (in->command) {
688         case CTDB_EVENT_COMMAND_RUN:
689                 break;
690
691         case CTDB_EVENT_COMMAND_STATUS:
692                 len += ctdb_event_reply_status_len(in->data.status);
693                 break;
694
695         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
696                 len += ctdb_event_reply_script_list_len(in->data.script_list);
697                 break;
698
699         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
700                 break;
701
702         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
703                 break;
704         }
705
706         return len;
707 }
708
709 static void ctdb_event_reply_data_push(struct ctdb_event_reply_data *in,
710                                        uint8_t *buf)
711 {
712         size_t offset = 0, np;
713
714         ctdb_event_command_push(in->command, buf, &np);
715         offset += np;
716
717         ctdb_int32_push(&in->result, buf+offset, &np);
718         offset += np;
719
720         switch (in->command) {
721         case CTDB_EVENT_COMMAND_RUN:
722                 break;
723
724         case CTDB_EVENT_COMMAND_STATUS:
725                 ctdb_event_reply_status_push(in->data.status, buf+offset, &np);
726                 break;
727
728         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
729                 ctdb_event_reply_script_list_push(in->data.script_list,
730                                                   buf+offset);
731                 break;
732
733         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
734                 break;
735
736         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
737                 break;
738         }
739 }
740
741 static int ctdb_event_reply_data_pull(uint8_t *buf, size_t buflen,
742                                       TALLOC_CTX *mem_ctx,
743                                       struct ctdb_event_reply_data *out)
744 {
745         size_t offset = 0, np;
746         int ret;
747
748         ret = ctdb_event_command_pull(buf, buflen, mem_ctx, &out->command,
749                                       &np);
750         if (ret != 0) {
751                 return ret;
752         }
753         offset += np;
754
755         ret = ctdb_int32_pull(buf+offset, buflen-offset, &out->result, &np);
756         if (ret != 0) {
757                 return ret;
758         }
759         offset += np;
760
761         switch (out->command) {
762         case CTDB_EVENT_COMMAND_RUN:
763                 break;
764
765         case CTDB_EVENT_COMMAND_STATUS:
766                 ret = ctdb_event_reply_status_pull(
767                                         buf+offset, buflen-offset,
768                                         mem_ctx, &out->data.status, &np);
769                 break;
770
771         case CTDB_EVENT_COMMAND_SCRIPT_LIST:
772                 ret = ctdb_event_reply_script_list_pull(
773                                         buf+offset, buflen-offset,
774                                         mem_ctx, &out->data.script_list);
775                 break;
776
777         case CTDB_EVENT_COMMAND_SCRIPT_ENABLE:
778                 break;
779
780         case CTDB_EVENT_COMMAND_SCRIPT_DISABLE:
781                 break;
782         }
783
784         if (ret != 0) {
785                 return ret;
786         }
787
788         return 0;
789 }
790
791 static size_t ctdb_event_header_len(struct ctdb_event_header *in)
792 {
793         return ctdb_uint32_len(&in->length) + ctdb_uint32_len(&in->reqid);
794 }
795
796 static void ctdb_event_header_push(struct ctdb_event_header *in, uint8_t *buf)
797 {
798         size_t offset = 0, np;
799
800         ctdb_uint32_push(&in->length, buf, &np);
801         offset += np;
802
803         ctdb_uint32_push(&in->reqid, buf+offset, &np);
804 }
805
806 static int ctdb_event_header_pull(uint8_t *buf, size_t buflen,
807                                   TALLOC_CTX *mem_ctx,
808                                   struct ctdb_event_header *out)
809 {
810         size_t offset = 0, np;
811         int ret;
812
813         ret = ctdb_uint32_pull(buf, buflen, &out->length, &np);
814         if (ret != 0) {
815                 return ret;
816         }
817         offset += np;
818
819         ret = ctdb_uint32_pull(buf+offset, buflen-offset, &out->reqid, &np);
820         if (ret != 0) {
821                 return ret;
822         }
823
824         return 0;
825 }
826
827 void ctdb_event_header_fill(struct ctdb_event_header *h, uint32_t reqid)
828 {
829         h->length = ctdb_event_header_len(h);
830         h->reqid = reqid;
831 }
832
833 size_t ctdb_event_request_len(struct ctdb_event_request *in)
834 {
835         return ctdb_event_header_len(&in->header) +
836                ctdb_event_request_data_len(&in->rdata);
837 }
838
839 int ctdb_event_request_push(struct ctdb_event_request *in,
840                             uint8_t *buf, size_t *buflen)
841 {
842         size_t len, offset = 0, np;
843
844         len = ctdb_event_request_len(in);
845         if (*buflen < len) {
846                 *buflen = len;
847                 return EMSGSIZE;
848         }
849
850         in->header.length = *buflen;
851
852         ctdb_event_header_push(&in->header, buf);
853         offset += ctdb_event_header_len(&in->header);
854
855         ctdb_event_request_data_push(&in->rdata, buf+offset, &np);
856
857         return 0;
858 }
859
860 int ctdb_event_request_pull(uint8_t *buf, size_t buflen,
861                             TALLOC_CTX *mem_ctx,
862                             struct ctdb_event_request *out)
863 {
864         size_t offset = 0, np;
865         int ret;
866
867         ret = ctdb_event_header_pull(buf, buflen, mem_ctx, &out->header);
868         if (ret != 0) {
869                 return ret;
870         }
871         offset += ctdb_event_header_len(&out->header);
872
873         ret = ctdb_event_request_data_pull(buf+offset, buflen-offset,
874                                            mem_ctx, &out->rdata, &np);
875         if (ret != 0) {
876                 return ret;
877         }
878
879         return 0;
880 }
881
882 size_t ctdb_event_reply_len(struct ctdb_event_reply *in)
883 {
884         return ctdb_event_header_len(&in->header) +
885                ctdb_event_reply_data_len(&in->rdata);
886 }
887
888 int ctdb_event_reply_push(struct ctdb_event_reply *in,
889                           uint8_t *buf, size_t *buflen)
890 {
891         size_t len, offset = 0;
892
893         len = ctdb_event_reply_len(in);
894         if (*buflen < len) {
895                 *buflen = len;
896                 return EMSGSIZE;
897         }
898
899         in->header.length = *buflen;
900
901         ctdb_event_header_push(&in->header, buf);
902         offset += ctdb_event_header_len(&in->header);
903
904         ctdb_event_reply_data_push(&in->rdata, buf+offset);
905
906         return 0;
907 }
908
909 int ctdb_event_reply_pull(uint8_t *buf, size_t buflen,
910                           TALLOC_CTX *mem_ctx,
911                           struct ctdb_event_reply *out)
912 {
913         size_t offset = 0;
914         int ret;
915
916         ret = ctdb_event_header_pull(buf, buflen, mem_ctx, &out->header);
917         if (ret != 0) {
918                 return ret;
919         }
920         offset += ctdb_event_header_len(&out->header);
921
922         ret = ctdb_event_reply_data_pull(buf+offset, buflen-offset,
923                                          mem_ctx, &out->rdata);
924         if (ret != 0) {
925                 return ret;
926         }
927
928         return 0;
929 }