2 ctdb_control protocol code
4 Copyright (C) Andrew Tridgell 2007
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, see <http://www.gnu.org/licenses/>.
20 #include "lib/events/events.h"
21 #include "lib/tdb/include/tdb.h"
22 #include "system/network.h"
23 #include "system/filesys.h"
24 #include "system/wait.h"
25 #include "../include/ctdb_private.h"
26 #include "lib/util/dlinklist.h"
30 struct ctdb_control_state {
31 struct ctdb_context *ctdb;
33 ctdb_control_callback_fn_t callback;
40 dump talloc memory hierarchy, returning it as a blob to the client
42 int32_t ctdb_dump_memory(struct ctdb_context *ctdb, TDB_DATA *outdata)
44 /* dump to a file, then send the file as a blob */
49 DEBUG(DEBUG_ERR,(__location__ " Unable to open tmpfile - %s\n", strerror(errno)));
52 talloc_report_full(NULL, f);
55 outdata->dptr = talloc_size(outdata, fsize);
56 CTDB_NO_MEMORY(ctdb, outdata->dptr);
57 outdata->dsize = fread(outdata->dptr, 1, fsize, f);
59 if (outdata->dsize != fsize) {
60 DEBUG(DEBUG_ERR,(__location__ " Unable to read tmpfile\n"));
68 process a control request
70 static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
71 struct ctdb_req_control *c,
73 TDB_DATA *outdata, uint32_t srcnode,
74 const char **errormsg,
77 uint32_t opcode = c->opcode;
78 uint64_t srvid = c->srvid;
79 uint32_t client_id = c->client_id;
82 case CTDB_CONTROL_PROCESS_EXISTS: {
83 CHECK_CONTROL_DATA_SIZE(sizeof(pid_t));
84 return ctdb_control_process_exists(ctdb, *(pid_t *)indata.dptr);
87 case CTDB_CONTROL_SET_DEBUG: {
88 CHECK_CONTROL_DATA_SIZE(sizeof(int32_t));
89 LogLevel = *(int32_t *)indata.dptr;
93 case CTDB_CONTROL_GET_DEBUG: {
94 CHECK_CONTROL_DATA_SIZE(0);
95 outdata->dptr = (uint8_t *)&LogLevel;
96 outdata->dsize = sizeof(LogLevel);
100 case CTDB_CONTROL_STATISTICS: {
102 CHECK_CONTROL_DATA_SIZE(0);
103 ctdb->statistics.memory_used = talloc_total_size(NULL);
104 ctdb->statistics.frozen = 0;
105 for (i=1; i<= NUM_DB_PRIORITIES; i++) {
106 if (ctdb->freeze_mode[i] == CTDB_FREEZE_FROZEN) {
107 ctdb->statistics.frozen = 1;
110 ctdb->statistics.recovering = (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE);
111 outdata->dptr = (uint8_t *)&ctdb->statistics;
112 outdata->dsize = sizeof(ctdb->statistics);
116 case CTDB_CONTROL_GET_ALL_TUNABLES: {
117 CHECK_CONTROL_DATA_SIZE(0);
118 outdata->dptr = (uint8_t *)&ctdb->tunable;
119 outdata->dsize = sizeof(ctdb->tunable);
123 case CTDB_CONTROL_DUMP_MEMORY: {
124 CHECK_CONTROL_DATA_SIZE(0);
125 return ctdb_dump_memory(ctdb, outdata);
128 case CTDB_CONTROL_STATISTICS_RESET: {
129 CHECK_CONTROL_DATA_SIZE(0);
130 ZERO_STRUCT(ctdb->statistics);
134 case CTDB_CONTROL_GETVNNMAP:
135 return ctdb_control_getvnnmap(ctdb, opcode, indata, outdata);
137 case CTDB_CONTROL_GET_DBMAP:
138 return ctdb_control_getdbmap(ctdb, opcode, indata, outdata);
140 case CTDB_CONTROL_GET_NODEMAPv4:
141 return ctdb_control_getnodemapv4(ctdb, opcode, indata, outdata);
143 case CTDB_CONTROL_GET_NODEMAP:
144 return ctdb_control_getnodemap(ctdb, opcode, indata, outdata);
146 case CTDB_CONTROL_RELOAD_NODES_FILE:
147 CHECK_CONTROL_DATA_SIZE(0);
148 return ctdb_control_reload_nodes_file(ctdb, opcode);
150 case CTDB_CONTROL_SETVNNMAP:
151 return ctdb_control_setvnnmap(ctdb, opcode, indata, outdata);
153 case CTDB_CONTROL_PULL_DB:
154 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_pulldb));
155 return ctdb_control_pull_db(ctdb, indata, outdata);
157 case CTDB_CONTROL_SET_DMASTER:
158 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_set_dmaster));
159 return ctdb_control_set_dmaster(ctdb, indata);
161 case CTDB_CONTROL_PUSH_DB:
162 return ctdb_control_push_db(ctdb, indata);
164 case CTDB_CONTROL_GET_RECMODE: {
165 return ctdb->recovery_mode;
168 case CTDB_CONTROL_SET_RECMASTER: {
169 return ctdb_control_set_recmaster(ctdb, opcode, indata);
172 case CTDB_CONTROL_GET_RECMASTER:
173 return ctdb->recovery_master;
175 case CTDB_CONTROL_GET_PID:
178 case CTDB_CONTROL_GET_PNN:
181 case CTDB_CONTROL_PING:
182 CHECK_CONTROL_DATA_SIZE(0);
183 return ctdb->statistics.num_clients;
185 case CTDB_CONTROL_GET_DBNAME: {
187 struct ctdb_db_context *ctdb_db;
189 CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
190 db_id = *(uint32_t *)indata.dptr;
191 ctdb_db = find_ctdb_db(ctdb, db_id);
192 if (ctdb_db == NULL) return -1;
193 outdata->dptr = discard_const(ctdb_db->db_name);
194 outdata->dsize = strlen(ctdb_db->db_name)+1;
198 case CTDB_CONTROL_GETDBPATH: {
200 struct ctdb_db_context *ctdb_db;
202 CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
203 db_id = *(uint32_t *)indata.dptr;
204 ctdb_db = find_ctdb_db(ctdb, db_id);
205 if (ctdb_db == NULL) return -1;
206 outdata->dptr = discard_const(ctdb_db->db_path);
207 outdata->dsize = strlen(ctdb_db->db_path)+1;
211 case CTDB_CONTROL_DB_ATTACH:
212 return ctdb_control_db_attach(ctdb, indata, outdata, srvid, false);
214 case CTDB_CONTROL_DB_ATTACH_PERSISTENT:
215 return ctdb_control_db_attach(ctdb, indata, outdata, srvid, true);
217 case CTDB_CONTROL_SET_CALL: {
218 struct ctdb_control_set_call *sc =
219 (struct ctdb_control_set_call *)indata.dptr;
220 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_set_call));
221 return ctdb_daemon_set_call(ctdb, sc->db_id, sc->fn, sc->id);
224 case CTDB_CONTROL_TRAVERSE_START:
225 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
226 return ctdb_control_traverse_start(ctdb, indata, outdata, srcnode, client_id);
228 case CTDB_CONTROL_TRAVERSE_ALL:
229 return ctdb_control_traverse_all(ctdb, indata, outdata);
231 case CTDB_CONTROL_TRAVERSE_DATA:
232 return ctdb_control_traverse_data(ctdb, indata, outdata);
234 case CTDB_CONTROL_TRAVERSE_KILL:
235 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_traverse_start));
236 return ctdb_control_traverse_kill(ctdb, indata, outdata, srcnode);
238 case CTDB_CONTROL_REGISTER_SRVID:
239 return daemon_register_message_handler(ctdb, client_id, srvid);
241 case CTDB_CONTROL_DEREGISTER_SRVID:
242 return daemon_deregister_message_handler(ctdb, client_id, srvid);
244 case CTDB_CONTROL_ENABLE_SEQNUM:
245 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
246 return ctdb_ltdb_enable_seqnum(ctdb, *(uint32_t *)indata.dptr);
248 case CTDB_CONTROL_UPDATE_SEQNUM:
249 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
250 return ctdb_ltdb_update_seqnum(ctdb, *(uint32_t *)indata.dptr, srcnode);
252 case CTDB_CONTROL_FREEZE:
253 CHECK_CONTROL_DATA_SIZE(0);
254 return ctdb_control_freeze(ctdb, c, async_reply);
256 case CTDB_CONTROL_THAW:
257 CHECK_CONTROL_DATA_SIZE(0);
258 return ctdb_control_thaw(ctdb, (uint32_t)c->srvid);
260 case CTDB_CONTROL_SET_RECMODE:
261 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
262 return ctdb_control_set_recmode(ctdb, c, indata, async_reply, errormsg);
264 case CTDB_CONTROL_GET_MONMODE:
265 CHECK_CONTROL_DATA_SIZE(0);
266 return ctdb_monitoring_mode(ctdb);
268 case CTDB_CONTROL_ENABLE_MONITOR:
269 CHECK_CONTROL_DATA_SIZE(0);
270 ctdb_enable_monitoring(ctdb);
273 case CTDB_CONTROL_RUN_EVENTSCRIPTS:
274 return ctdb_run_eventscripts(ctdb, c, indata, async_reply);
276 case CTDB_CONTROL_DISABLE_MONITOR:
277 CHECK_CONTROL_DATA_SIZE(0);
278 ctdb_disable_monitoring(ctdb);
281 case CTDB_CONTROL_SHUTDOWN:
282 ctdb_stop_recoverd(ctdb);
283 ctdb_stop_keepalive(ctdb);
284 ctdb_stop_monitoring(ctdb);
285 ctdb_release_all_ips(ctdb);
286 if (ctdb->methods != NULL) {
287 ctdb->methods->shutdown(ctdb);
289 ctdb_event_script(ctdb, CTDB_EVENT_SHUTDOWN);
290 DEBUG(DEBUG_NOTICE,("Received SHUTDOWN command. Stopping CTDB daemon.\n"));
293 case CTDB_CONTROL_TAKEOVER_IPv4:
294 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ipv4));
295 return ctdb_control_takeover_ipv4(ctdb, c, indata, async_reply);
297 case CTDB_CONTROL_TAKEOVER_IP:
298 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip));
299 return ctdb_control_takeover_ip(ctdb, c, indata, async_reply);
301 case CTDB_CONTROL_RELEASE_IPv4:
302 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ipv4));
303 return ctdb_control_release_ipv4(ctdb, c, indata, async_reply);
305 case CTDB_CONTROL_RELEASE_IP:
306 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_public_ip));
307 return ctdb_control_release_ip(ctdb, c, indata, async_reply);
309 case CTDB_CONTROL_GET_PUBLIC_IPSv4:
310 CHECK_CONTROL_DATA_SIZE(0);
311 return ctdb_control_get_public_ipsv4(ctdb, c, outdata);
313 case CTDB_CONTROL_GET_PUBLIC_IPS:
314 CHECK_CONTROL_DATA_SIZE(0);
315 return ctdb_control_get_public_ips(ctdb, c, outdata);
317 case CTDB_CONTROL_TCP_CLIENT:
318 return ctdb_control_tcp_client(ctdb, client_id, indata);
320 case CTDB_CONTROL_STARTUP:
321 CHECK_CONTROL_DATA_SIZE(0);
322 return ctdb_control_startup(ctdb, srcnode);
324 case CTDB_CONTROL_TCP_ADD:
325 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_tcp_vnn));
326 return ctdb_control_tcp_add(ctdb, indata);
328 case CTDB_CONTROL_SET_TUNABLE:
329 return ctdb_control_set_tunable(ctdb, indata);
331 case CTDB_CONTROL_GET_TUNABLE:
332 return ctdb_control_get_tunable(ctdb, indata, outdata);
334 case CTDB_CONTROL_LIST_TUNABLES:
335 return ctdb_control_list_tunables(ctdb, outdata);
337 case CTDB_CONTROL_MODIFY_FLAGS:
338 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_node_flag_change));
339 return ctdb_control_modflags(ctdb, indata);
341 case CTDB_CONTROL_KILL_TCP:
342 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_killtcp));
343 return ctdb_control_kill_tcp(ctdb, indata);
345 case CTDB_CONTROL_GET_TCP_TICKLE_LIST:
346 CHECK_CONTROL_DATA_SIZE(sizeof(ctdb_sock_addr));
347 return ctdb_control_get_tcp_tickle_list(ctdb, indata, outdata);
349 case CTDB_CONTROL_SET_TCP_TICKLE_LIST:
350 /* data size is verified in the called function */
351 return ctdb_control_set_tcp_tickle_list(ctdb, indata);
353 case CTDB_CONTROL_REGISTER_SERVER_ID:
354 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
355 return ctdb_control_register_server_id(ctdb, client_id, indata);
357 case CTDB_CONTROL_UNREGISTER_SERVER_ID:
358 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
359 return ctdb_control_unregister_server_id(ctdb, indata);
361 case CTDB_CONTROL_CHECK_SERVER_ID:
362 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_server_id));
363 return ctdb_control_check_server_id(ctdb, indata);
365 case CTDB_CONTROL_GET_SERVER_ID_LIST:
366 CHECK_CONTROL_DATA_SIZE(0);
367 return ctdb_control_get_server_id_list(ctdb, outdata);
369 case CTDB_CONTROL_PERSISTENT_STORE:
370 return ctdb_control_persistent_store(ctdb, c, indata, async_reply);
372 case CTDB_CONTROL_UPDATE_RECORD:
373 return ctdb_control_update_record(ctdb, c, indata, async_reply);
375 case CTDB_CONTROL_SEND_GRATIOUS_ARP:
376 return ctdb_control_send_gratious_arp(ctdb, indata);
378 case CTDB_CONTROL_TRANSACTION_START:
379 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
380 return ctdb_control_transaction_start(ctdb, *(uint32_t *)indata.dptr);
382 case CTDB_CONTROL_TRANSACTION_COMMIT:
383 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
384 return ctdb_control_transaction_commit(ctdb, *(uint32_t *)indata.dptr);
386 case CTDB_CONTROL_WIPE_DATABASE:
387 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_control_wipe_database));
388 return ctdb_control_wipe_database(ctdb, indata);
390 case CTDB_CONTROL_UPTIME:
391 return ctdb_control_uptime(ctdb, outdata);
393 case CTDB_CONTROL_START_RECOVERY:
394 return ctdb_control_start_recovery(ctdb, c, async_reply);
396 case CTDB_CONTROL_END_RECOVERY:
397 return ctdb_control_end_recovery(ctdb, c, async_reply);
399 case CTDB_CONTROL_TRY_DELETE_RECORDS:
400 return ctdb_control_try_delete_records(ctdb, indata, outdata);
402 case CTDB_CONTROL_ADD_PUBLIC_IP:
403 return ctdb_control_add_public_address(ctdb, indata);
405 case CTDB_CONTROL_DEL_PUBLIC_IP:
406 return ctdb_control_del_public_address(ctdb, indata);
408 case CTDB_CONTROL_GET_CAPABILITIES:
409 return ctdb_control_get_capabilities(ctdb, outdata);
411 case CTDB_CONTROL_START_PERSISTENT_UPDATE:
412 return ctdb_control_start_persistent_update(ctdb, c, indata);
414 case CTDB_CONTROL_CANCEL_PERSISTENT_UPDATE:
415 return ctdb_control_cancel_persistent_update(ctdb, c, indata);
417 case CTDB_CONTROL_TRANS2_COMMIT:
418 case CTDB_CONTROL_TRANS2_COMMIT_RETRY:
419 return ctdb_control_trans2_commit(ctdb, c, indata, async_reply);
421 case CTDB_CONTROL_TRANS2_ERROR:
422 return ctdb_control_trans2_error(ctdb, c);
424 case CTDB_CONTROL_TRANS2_FINISHED:
425 return ctdb_control_trans2_finished(ctdb, c);
427 case CTDB_CONTROL_TRANS2_ACTIVE:
428 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
429 return ctdb_control_trans2_active(ctdb, c, *(uint32_t *)indata.dptr);
431 case CTDB_CONTROL_RECD_PING:
432 CHECK_CONTROL_DATA_SIZE(0);
433 return ctdb_control_recd_ping(ctdb);
435 case CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS:
436 CHECK_CONTROL_DATA_SIZE(0);
437 return ctdb_control_get_event_script_status(ctdb, outdata);
439 case CTDB_CONTROL_RECD_RECLOCK_LATENCY:
440 CHECK_CONTROL_DATA_SIZE(sizeof(double));
441 ctdb_reclock_latency(ctdb, "recd reclock", &ctdb->statistics.reclock.recd, *((double *)indata.dptr));
443 case CTDB_CONTROL_GET_RECLOCK_FILE:
444 CHECK_CONTROL_DATA_SIZE(0);
445 if (ctdb->recovery_lock_file != NULL) {
446 outdata->dptr = discard_const(ctdb->recovery_lock_file);
447 outdata->dsize = strlen(ctdb->recovery_lock_file) + 1;
450 case CTDB_CONTROL_SET_RECLOCK_FILE:
451 ctdb->tunable.verify_recovery_lock = 0;
452 if (ctdb->recovery_lock_file != NULL) {
453 talloc_free(ctdb->recovery_lock_file);
454 ctdb->recovery_lock_file = NULL;
456 if (indata.dsize > 0) {
457 ctdb->recovery_lock_file = talloc_strdup(ctdb, discard_const(indata.dptr));
458 ctdb->tunable.verify_recovery_lock = 1;
462 case CTDB_CONTROL_STOP_NODE:
463 CHECK_CONTROL_DATA_SIZE(0);
464 return ctdb_control_stop_node(ctdb, c, async_reply);
466 case CTDB_CONTROL_CONTINUE_NODE:
467 CHECK_CONTROL_DATA_SIZE(0);
468 return ctdb_control_continue_node(ctdb);
470 case CTDB_CONTROL_SET_NATGWSTATE: {
473 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
474 natgwstate = *(uint32_t *)indata.dptr;
475 if (natgwstate == 0) {
476 ctdb->capabilities &= ~CTDB_CAP_NATGW;
478 ctdb->capabilities |= CTDB_CAP_NATGW;
483 case CTDB_CONTROL_SET_LMASTERROLE: {
484 uint32_t lmasterrole;
486 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
487 lmasterrole = *(uint32_t *)indata.dptr;
488 if (lmasterrole == 0) {
489 ctdb->capabilities &= ~CTDB_CAP_LMASTER;
491 ctdb->capabilities |= CTDB_CAP_LMASTER;
496 case CTDB_CONTROL_SET_RECMASTERROLE: {
497 uint32_t recmasterrole;
499 CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));
500 recmasterrole = *(uint32_t *)indata.dptr;
501 if (recmasterrole == 0) {
502 ctdb->capabilities &= ~CTDB_CAP_RECMASTER;
504 ctdb->capabilities |= CTDB_CAP_RECMASTER;
509 case CTDB_CONTROL_ENABLE_SCRIPT:
510 return ctdb_control_enable_script(ctdb, indata);
512 case CTDB_CONTROL_DISABLE_SCRIPT:
513 return ctdb_control_disable_script(ctdb, indata);
515 case CTDB_CONTROL_SET_BAN_STATE:
516 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_ban_time));
517 return ctdb_control_set_ban_state(ctdb, indata);
519 case CTDB_CONTROL_GET_BAN_STATE:
520 CHECK_CONTROL_DATA_SIZE(0);
521 return ctdb_control_get_ban_state(ctdb, outdata);
523 case CTDB_CONTROL_SET_DB_PRIORITY:
524 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_db_priority));
525 return ctdb_control_set_db_priority(ctdb, indata);
527 case CTDB_CONTROL_GET_DB_PRIORITY: {
529 struct ctdb_db_context *ctdb_db;
531 CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
532 db_id = *(uint32_t *)indata.dptr;
533 ctdb_db = find_ctdb_db(ctdb, db_id);
534 if (ctdb_db == NULL) return -1;
535 return ctdb_db->priority;
538 case CTDB_CONTROL_TRANSACTION_CANCEL:
539 CHECK_CONTROL_DATA_SIZE(0);
540 return ctdb_control_transaction_cancel(ctdb);
542 case CTDB_CONTROL_REGISTER_NOTIFY:
543 return ctdb_control_register_notify(ctdb, client_id, indata);
545 case CTDB_CONTROL_DEREGISTER_NOTIFY:
546 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_client_notify_deregister));
547 return ctdb_control_deregister_notify(ctdb, client_id, indata);
549 case CTDB_CONTROL_GET_LOG:
550 CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_get_log_addr));
551 return ctdb_control_get_log(ctdb, indata);
553 case CTDB_CONTROL_CLEAR_LOG:
554 return ctdb_control_clear_log(ctdb);
557 DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
563 send a reply for a ctdb control
565 void ctdb_request_control_reply(struct ctdb_context *ctdb, struct ctdb_req_control *c,
566 TDB_DATA *outdata, int32_t status, const char *errormsg)
568 struct ctdb_reply_control *r;
571 /* some controls send no reply */
572 if (c->flags & CTDB_CTRL_FLAG_NOREPLY) {
576 len = offsetof(struct ctdb_reply_control, data) + (outdata?outdata->dsize:0);
578 len += strlen(errormsg);
580 r = ctdb_transport_allocate(ctdb, ctdb, CTDB_REPLY_CONTROL, len, struct ctdb_reply_control);
581 CTDB_NO_MEMORY_VOID(ctdb, r);
583 r->hdr.destnode = c->hdr.srcnode;
584 r->hdr.reqid = c->hdr.reqid;
586 r->datalen = outdata?outdata->dsize:0;
587 if (outdata && outdata->dsize) {
588 memcpy(&r->data[0], outdata->dptr, outdata->dsize);
591 r->errorlen = strlen(errormsg);
592 memcpy(&r->data[r->datalen], errormsg, r->errorlen);
595 ctdb_queue_packet_opcode(ctdb, &r->hdr, c->opcode);
601 called when a CTDB_REQ_CONTROL packet comes in
603 void ctdb_request_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
605 struct ctdb_req_control *c = (struct ctdb_req_control *)hdr;
606 TDB_DATA data, *outdata;
608 bool async_reply = False;
609 const char *errormsg = NULL;
611 data.dptr = &c->data[0];
612 data.dsize = c->datalen;
614 outdata = talloc_zero(c, TDB_DATA);
616 status = ctdb_control_dispatch(ctdb, c, data, outdata, hdr->srcnode,
617 &errormsg, &async_reply);
620 ctdb_request_control_reply(ctdb, c, outdata, status, errormsg);
625 called when a CTDB_REPLY_CONTROL packet comes in
627 void ctdb_reply_control(struct ctdb_context *ctdb, struct ctdb_req_header *hdr)
629 struct ctdb_reply_control *c = (struct ctdb_reply_control *)hdr;
631 struct ctdb_control_state *state;
632 const char *errormsg = NULL;
634 state = ctdb_reqid_find(ctdb, hdr->reqid, struct ctdb_control_state);
636 DEBUG(DEBUG_ERR,("pnn %u Invalid reqid %u in ctdb_reply_control\n",
637 ctdb->pnn, hdr->reqid));
641 if (hdr->reqid != state->reqid) {
642 /* we found a record but it was the wrong one */
643 DEBUG(DEBUG_ERR, ("Dropped orphaned control reply with reqid:%u\n", hdr->reqid));
647 data.dptr = &c->data[0];
648 data.dsize = c->datalen;
650 errormsg = talloc_strndup(state,
651 (char *)&c->data[c->datalen], c->errorlen);
654 /* make state a child of the packet, so it goes away when the packet
656 talloc_steal(hdr, state);
658 state->callback(ctdb, c->status, data, errormsg, state->private_data);
661 static int ctdb_control_destructor(struct ctdb_control_state *state)
663 ctdb_reqid_remove(state->ctdb, state->reqid);
668 handle a timeout of a control
670 static void ctdb_control_timeout(struct event_context *ev, struct timed_event *te,
671 struct timeval t, void *private_data)
673 struct ctdb_control_state *state = talloc_get_type(private_data, struct ctdb_control_state);
674 TALLOC_CTX *tmp_ctx = talloc_new(ev);
676 state->ctdb->statistics.timeouts.control++;
678 talloc_steal(tmp_ctx, state);
680 state->callback(state->ctdb, -1, tdb_null,
681 "ctdb_control timed out",
682 state->private_data);
683 talloc_free(tmp_ctx);
688 send a control message to a node
690 int ctdb_daemon_send_control(struct ctdb_context *ctdb, uint32_t destnode,
691 uint64_t srvid, uint32_t opcode, uint32_t client_id,
694 ctdb_control_callback_fn_t callback,
697 struct ctdb_req_control *c;
698 struct ctdb_control_state *state;
701 if (ctdb->methods == NULL) {
702 DEBUG(DEBUG_ERR,(__location__ " Failed to send control. Transport is DOWN\n"));
706 if (((destnode == CTDB_BROADCAST_VNNMAP) ||
707 (destnode == CTDB_BROADCAST_ALL) ||
708 (destnode == CTDB_BROADCAST_CONNECTED)) &&
709 !(flags & CTDB_CTRL_FLAG_NOREPLY)) {
710 DEBUG(DEBUG_CRIT,("Attempt to broadcast control without NOREPLY\n"));
714 if (destnode != CTDB_BROADCAST_VNNMAP &&
715 destnode != CTDB_BROADCAST_ALL &&
716 destnode != CTDB_BROADCAST_CONNECTED &&
717 (!ctdb_validate_pnn(ctdb, destnode) ||
718 (ctdb->nodes[destnode]->flags & NODE_FLAGS_DISCONNECTED))) {
719 if (!(flags & CTDB_CTRL_FLAG_NOREPLY)) {
720 callback(ctdb, -1, tdb_null, "ctdb_control to disconnected node", private_data);
725 /* the state is made a child of private_data if possible. This means any reply
726 will be discarded if the private_data goes away */
727 state = talloc(private_data?private_data:ctdb, struct ctdb_control_state);
728 CTDB_NO_MEMORY(ctdb, state);
730 state->reqid = ctdb_reqid_new(ctdb, state);
731 state->callback = callback;
732 state->private_data = private_data;
734 state->flags = flags;
736 talloc_set_destructor(state, ctdb_control_destructor);
738 len = offsetof(struct ctdb_req_control, data) + data.dsize;
739 c = ctdb_transport_allocate(ctdb, state, CTDB_REQ_CONTROL, len,
740 struct ctdb_req_control);
741 CTDB_NO_MEMORY(ctdb, c);
742 talloc_set_name_const(c, "ctdb_req_control packet");
744 c->hdr.destnode = destnode;
745 c->hdr.reqid = state->reqid;
747 c->client_id = client_id;
750 c->datalen = data.dsize;
752 memcpy(&c->data[0], data.dptr, data.dsize);
755 ctdb_queue_packet(ctdb, &c->hdr);
757 if (flags & CTDB_CTRL_FLAG_NOREPLY) {
762 if (ctdb->tunable.control_timeout) {
763 event_add_timed(ctdb->ev, state,
764 timeval_current_ofs(ctdb->tunable.control_timeout, 0),
765 ctdb_control_timeout, state);