2 CTDB protocol marshalling
4 Copyright (C) Amitay Isaacs 2015
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
21 #include "system/network.h"
27 #include "protocol_api.h"
28 #include "protocol_private.h"
30 struct ctdb_req_message_wire
{
31 struct ctdb_req_header hdr
;
37 static size_t ctdb_message_data_len(union ctdb_message_data
*mdata
,
43 case CTDB_SRVID_ELECTION
:
44 len
= ctdb_election_message_len(mdata
->election
);
47 case CTDB_SRVID_RECONFIGURE
:
50 case CTDB_SRVID_RELEASE_IP
:
51 len
= ctdb_string_len(mdata
->ipaddr
);
54 case CTDB_SRVID_TAKE_IP
:
55 len
= ctdb_string_len(mdata
->ipaddr
);
58 case CTDB_SRVID_SET_NODE_FLAGS
:
59 len
= ctdb_node_flag_change_len(mdata
->flag_change
);
62 case CTDB_SRVID_RECD_UPDATE_IP
:
63 len
= ctdb_public_ip_len(mdata
->pubip
);
66 case CTDB_SRVID_VACUUM_FETCH
:
67 len
= ctdb_rec_buffer_len(mdata
->recbuf
);
70 case CTDB_SRVID_DETACH_DATABASE
:
71 len
= ctdb_uint32_len(mdata
->db_id
);
74 case CTDB_SRVID_MEM_DUMP
:
75 len
= ctdb_srvid_message_len(mdata
->msg
);
78 case CTDB_SRVID_PUSH_NODE_FLAGS
:
79 len
= ctdb_node_flag_change_len(mdata
->flag_change
);
82 case CTDB_SRVID_RELOAD_NODES
:
85 case CTDB_SRVID_TAKEOVER_RUN
:
86 len
= ctdb_srvid_message_len(mdata
->msg
);
89 case CTDB_SRVID_REBALANCE_NODE
:
90 len
= ctdb_uint32_len(mdata
->pnn
);
93 case CTDB_SRVID_DISABLE_TAKEOVER_RUNS
:
94 len
= ctdb_disable_message_len(mdata
->disable
);
97 case CTDB_SRVID_DISABLE_RECOVERIES
:
98 len
= ctdb_disable_message_len(mdata
->disable
);
101 case CTDB_SRVID_DISABLE_IP_CHECK
:
102 len
= ctdb_uint32_len(mdata
->timeout
);
106 len
= ctdb_tdb_data_len(mdata
->data
);
113 static void ctdb_message_data_push(union ctdb_message_data
*mdata
,
114 uint64_t srvid
, uint8_t *buf
)
117 case CTDB_SRVID_ELECTION
:
118 ctdb_election_message_push(mdata
->election
, buf
);
121 case CTDB_SRVID_RECONFIGURE
:
124 case CTDB_SRVID_RELEASE_IP
:
125 ctdb_string_push(mdata
->ipaddr
, buf
);
128 case CTDB_SRVID_TAKE_IP
:
129 ctdb_string_push(mdata
->ipaddr
, buf
);
132 case CTDB_SRVID_SET_NODE_FLAGS
:
133 ctdb_node_flag_change_push(mdata
->flag_change
, buf
);
136 case CTDB_SRVID_RECD_UPDATE_IP
:
137 ctdb_public_ip_push(mdata
->pubip
, buf
);
140 case CTDB_SRVID_VACUUM_FETCH
:
141 ctdb_rec_buffer_push(mdata
->recbuf
, buf
);
144 case CTDB_SRVID_DETACH_DATABASE
:
145 ctdb_uint32_push(mdata
->db_id
, buf
);
148 case CTDB_SRVID_MEM_DUMP
:
149 ctdb_srvid_message_push(mdata
->msg
, buf
);
152 case CTDB_SRVID_PUSH_NODE_FLAGS
:
153 ctdb_node_flag_change_push(mdata
->flag_change
, buf
);
156 case CTDB_SRVID_RELOAD_NODES
:
159 case CTDB_SRVID_TAKEOVER_RUN
:
160 ctdb_srvid_message_push(mdata
->msg
, buf
);
163 case CTDB_SRVID_REBALANCE_NODE
:
164 ctdb_uint32_push(mdata
->pnn
, buf
);
167 case CTDB_SRVID_DISABLE_TAKEOVER_RUNS
:
168 ctdb_disable_message_push(mdata
->disable
, buf
);
171 case CTDB_SRVID_DISABLE_RECOVERIES
:
172 ctdb_disable_message_push(mdata
->disable
, buf
);
175 case CTDB_SRVID_DISABLE_IP_CHECK
:
176 ctdb_uint32_push(mdata
->timeout
, buf
);
180 ctdb_tdb_data_push(mdata
->data
, buf
);
185 static int ctdb_message_data_pull(uint8_t *buf
, size_t buflen
,
186 uint64_t srvid
, TALLOC_CTX
*mem_ctx
,
187 union ctdb_message_data
*mdata
)
192 case CTDB_SRVID_ELECTION
:
193 ret
= ctdb_election_message_pull(buf
, buflen
, mem_ctx
,
197 case CTDB_SRVID_RECONFIGURE
:
200 case CTDB_SRVID_RELEASE_IP
:
201 ret
= ctdb_string_pull(buf
, buflen
, mem_ctx
, &mdata
->ipaddr
);
204 case CTDB_SRVID_TAKE_IP
:
205 ret
= ctdb_string_pull(buf
, buflen
, mem_ctx
, &mdata
->ipaddr
);
208 case CTDB_SRVID_SET_NODE_FLAGS
:
209 ret
= ctdb_node_flag_change_pull(buf
, buflen
, mem_ctx
,
210 &mdata
->flag_change
);
213 case CTDB_SRVID_RECD_UPDATE_IP
:
214 ret
= ctdb_public_ip_pull(buf
, buflen
, mem_ctx
,
218 case CTDB_SRVID_VACUUM_FETCH
:
219 ret
= ctdb_rec_buffer_pull(buf
, buflen
, mem_ctx
,
223 case CTDB_SRVID_DETACH_DATABASE
:
224 ret
= ctdb_uint32_pull(buf
, buflen
, mem_ctx
, &mdata
->db_id
);
227 case CTDB_SRVID_MEM_DUMP
:
228 ret
= ctdb_srvid_message_pull(buf
, buflen
, mem_ctx
,
232 case CTDB_SRVID_PUSH_NODE_FLAGS
:
233 ret
= ctdb_node_flag_change_pull(buf
, buflen
, mem_ctx
,
234 &mdata
->flag_change
);
237 case CTDB_SRVID_RELOAD_NODES
:
240 case CTDB_SRVID_TAKEOVER_RUN
:
241 ret
= ctdb_srvid_message_pull(buf
, buflen
, mem_ctx
,
245 case CTDB_SRVID_REBALANCE_NODE
:
246 ret
= ctdb_uint32_pull(buf
, buflen
, mem_ctx
, &mdata
->pnn
);
249 case CTDB_SRVID_DISABLE_TAKEOVER_RUNS
:
250 ret
= ctdb_disable_message_pull(buf
, buflen
, mem_ctx
,
254 case CTDB_SRVID_DISABLE_RECOVERIES
:
255 ret
= ctdb_disable_message_pull(buf
, buflen
, mem_ctx
,
259 case CTDB_SRVID_DISABLE_IP_CHECK
:
260 ret
= ctdb_uint32_pull(buf
, buflen
, mem_ctx
, &mdata
->timeout
);
264 ret
= ctdb_tdb_data_pull(buf
, buflen
, mem_ctx
, &mdata
->data
);
271 int ctdb_req_message_push(struct ctdb_req_header
*h
,
272 struct ctdb_req_message
*message
,
274 uint8_t **pkt
, size_t *pkt_len
)
276 struct ctdb_req_message_wire
*wire
;
278 size_t length
, buflen
, datalen
;
281 datalen
= ctdb_message_data_len(&message
->data
, message
->srvid
);
282 length
= offsetof(struct ctdb_req_message_wire
, data
) + datalen
;
284 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
289 wire
= (struct ctdb_req_message_wire
*)buf
;
292 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
294 wire
->srvid
= message
->srvid
;
295 wire
->datalen
= datalen
;
296 ctdb_message_data_push(&message
->data
, message
->srvid
, wire
->data
);
303 int ctdb_req_message_pull(uint8_t *pkt
, size_t pkt_len
,
304 struct ctdb_req_header
*h
,
306 struct ctdb_req_message
*message
)
308 struct ctdb_req_message_wire
*wire
=
309 (struct ctdb_req_message_wire
*)pkt
;
313 length
= offsetof(struct ctdb_req_message_wire
, data
);
315 if (pkt_len
< length
) {
318 if (pkt_len
< length
+ wire
->datalen
) {
322 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
324 message
->srvid
= wire
->srvid
;
325 ret
= ctdb_message_data_pull(wire
->data
, wire
->datalen
, wire
->srvid
,
326 mem_ctx
, &message
->data
);
330 int ctdb_req_message_data_push(struct ctdb_req_header
*h
,
331 struct ctdb_req_message_data
*message
,
333 uint8_t **pkt
, size_t *pkt_len
)
335 struct ctdb_req_message_wire
*wire
;
337 size_t length
, buflen
;
340 length
= offsetof(struct ctdb_req_message_wire
, data
) +
343 ret
= allocate_pkt(mem_ctx
, length
, &buf
, &buflen
);
348 wire
= (struct ctdb_req_message_wire
*)buf
;
351 memcpy(&wire
->hdr
, h
, sizeof(struct ctdb_req_header
));
353 wire
->srvid
= message
->srvid
;
354 wire
->datalen
= message
->data
.dsize
;
355 if (message
->data
.dsize
> 0) {
356 memcpy(wire
->data
, message
->data
.dptr
, message
->data
.dsize
);
364 int ctdb_req_message_data_pull(uint8_t *pkt
, size_t pkt_len
,
365 struct ctdb_req_header
*h
,
367 struct ctdb_req_message_data
*message
)
369 struct ctdb_req_message_wire
*wire
=
370 (struct ctdb_req_message_wire
*)pkt
;
373 length
= offsetof(struct ctdb_req_message_wire
, data
);
375 if (pkt_len
< length
) {
378 if (pkt_len
< length
+ wire
->datalen
) {
382 memcpy(h
, &wire
->hdr
, sizeof(struct ctdb_req_header
));
384 message
->srvid
= wire
->srvid
;
385 message
->data
.dsize
= wire
->datalen
;
386 if (wire
->datalen
> 0) {
387 message
->data
.dptr
= talloc_memdup(mem_ctx
, wire
->data
,
389 if (message
->data
.dptr
== NULL
) {