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 "system/network.h"
21 #include "system/filesys.h"
22 #include "system/wait.h"
27 #include "lib/tdb_wrap/tdb_wrap.h"
28 #include "lib/util/dlinklist.h"
29 #include "lib/util/debug.h"
31 #include "ctdb_private.h"
33 #include "common/rb_tree.h"
34 #include "common/common.h"
35 #include "common/logging.h"
38 * Cancel a transaction on database
40 static int db_transaction_cancel_handler(struct ctdb_db_context
*ctdb_db
,
45 tdb_add_flags(ctdb_db
->ltdb
->tdb
, TDB_NOLOCK
);
46 ret
= tdb_transaction_cancel(ctdb_db
->ltdb
->tdb
);
48 DEBUG(DEBUG_ERR
, ("Failed to cancel transaction for db %s\n",
51 tdb_remove_flags(ctdb_db
->ltdb
->tdb
, TDB_NOLOCK
);
56 * Start a transaction on database
58 static int db_transaction_start_handler(struct ctdb_db_context
*ctdb_db
,
61 bool freeze_transaction_started
= *(bool *)private_data
;
64 tdb_add_flags(ctdb_db
->ltdb
->tdb
, TDB_NOLOCK
);
65 if (freeze_transaction_started
) {
66 ret
= tdb_transaction_cancel(ctdb_db
->ltdb
->tdb
);
69 ("Failed to cancel transaction for db %s\n",
73 ret
= tdb_transaction_start(ctdb_db
->ltdb
->tdb
);
74 tdb_remove_flags(ctdb_db
->ltdb
->tdb
, TDB_NOLOCK
);
76 DEBUG(DEBUG_ERR
, ("Failed to start transaction for db %s\n",
84 * Commit a transaction on database
86 static int db_transaction_commit_handler(struct ctdb_db_context
*ctdb_db
,
89 int healthy_nodes
= *(int *)private_data
;
92 tdb_add_flags(ctdb_db
->ltdb
->tdb
, TDB_NOLOCK
);
93 ret
= tdb_transaction_commit(ctdb_db
->ltdb
->tdb
);
94 tdb_remove_flags(ctdb_db
->ltdb
->tdb
, TDB_NOLOCK
);
96 DEBUG(DEBUG_ERR
, ("Failed to commit transaction for db %s\n",
101 ret
= ctdb_update_persistent_health(ctdb_db
->ctdb
, ctdb_db
, NULL
,
104 DEBUG(DEBUG_ERR
, ("Failed to update persistent health for db %s\n",
110 /* a list of control requests waiting for db freeze */
111 struct ctdb_db_freeze_waiter
{
112 struct ctdb_db_freeze_waiter
*next
, *prev
;
113 struct ctdb_context
*ctdb
;
118 /* a handle to a db freeze lock child process */
119 struct ctdb_db_freeze_handle
{
120 struct ctdb_db_context
*ctdb_db
;
121 struct lock_request
*lreq
;
122 struct ctdb_db_freeze_waiter
*waiters
;
126 * Called when freeing database freeze handle
128 static int ctdb_db_freeze_handle_destructor(struct ctdb_db_freeze_handle
*h
)
130 struct ctdb_db_context
*ctdb_db
= h
->ctdb_db
;
132 DEBUG(DEBUG_ERR
, ("Release freeze handle for db %s\n",
135 /* Cancel any pending transactions */
136 if (ctdb_db
->freeze_transaction_started
) {
137 db_transaction_cancel_handler(ctdb_db
, NULL
);
138 ctdb_db
->freeze_transaction_started
= false;
140 ctdb_db
->freeze_mode
= CTDB_FREEZE_NONE
;
141 ctdb_db
->freeze_handle
= NULL
;
143 talloc_free(h
->lreq
);
148 * Called when a database is frozen
150 static void ctdb_db_freeze_handler(void *private_data
, bool locked
)
152 struct ctdb_db_freeze_handle
*h
= talloc_get_type_abort(
153 private_data
, struct ctdb_db_freeze_handle
);
154 struct ctdb_db_freeze_waiter
*w
;
156 if (h
->ctdb_db
->freeze_mode
== CTDB_FREEZE_FROZEN
) {
157 DEBUG(DEBUG_ERR
, ("Freeze db child died - unfreezing\n"));
158 h
->ctdb_db
->freeze_mode
= CTDB_FREEZE_NONE
;
164 DEBUG(DEBUG_ERR
, ("Failed to get db lock for %s\n",
165 h
->ctdb_db
->db_name
));
166 h
->ctdb_db
->freeze_mode
= CTDB_FREEZE_NONE
;
171 h
->ctdb_db
->freeze_mode
= CTDB_FREEZE_FROZEN
;
173 /* notify the waiters */
174 while ((w
= h
->waiters
) != NULL
) {
176 DLIST_REMOVE(h
->waiters
, w
);
182 * Start freeze process for a database
184 static void ctdb_start_db_freeze(struct ctdb_db_context
*ctdb_db
)
186 struct ctdb_db_freeze_handle
*h
;
188 if (ctdb_db
->freeze_mode
== CTDB_FREEZE_FROZEN
) {
192 if (ctdb_db
->freeze_handle
!= NULL
) {
196 DEBUG(DEBUG_ERR
, ("Freeze db: %s\n", ctdb_db
->db_name
));
198 ctdb_stop_vacuuming(ctdb_db
->ctdb
);
200 h
= talloc_zero(ctdb_db
, struct ctdb_db_freeze_handle
);
201 CTDB_NO_MEMORY_FATAL(ctdb_db
->ctdb
, h
);
203 h
->ctdb_db
= ctdb_db
;
204 h
->lreq
= ctdb_lock_db(h
, ctdb_db
, false, ctdb_db_freeze_handler
, h
);
205 CTDB_NO_MEMORY_FATAL(ctdb_db
->ctdb
, h
->lreq
);
206 talloc_set_destructor(h
, ctdb_db_freeze_handle_destructor
);
208 ctdb_db
->freeze_handle
= h
;
209 ctdb_db
->freeze_mode
= CTDB_FREEZE_PENDING
;
213 * Reply to a waiter for db freeze
215 static int ctdb_db_freeze_waiter_destructor(struct ctdb_db_freeze_waiter
*w
)
217 /* 'c' pointer is talloc_memdup(), so cannot use talloc_get_type */
218 struct ctdb_req_control_old
*c
=
219 (struct ctdb_req_control_old
*)w
->private_data
;
221 ctdb_request_control_reply(w
->ctdb
, c
, NULL
, w
->status
, NULL
);
228 int32_t ctdb_control_db_freeze(struct ctdb_context
*ctdb
,
229 struct ctdb_req_control_old
*c
,
233 struct ctdb_db_context
*ctdb_db
;
234 struct ctdb_db_freeze_waiter
*w
;
236 ctdb_db
= find_ctdb_db(ctdb
, db_id
);
237 if (ctdb_db
== NULL
) {
238 DEBUG(DEBUG_ERR
, ("Freeze db for unknown dbid 0x%08x\n", db_id
));
242 if (ctdb_db
->freeze_mode
== CTDB_FREEZE_FROZEN
) {
243 DEBUG(DEBUG_ERR
, ("Freeze db: %s frozen\n", ctdb_db
->db_name
));
247 ctdb_start_db_freeze(ctdb_db
);
249 /* add ourselves to the list of waiters */
250 w
= talloc(ctdb_db
->freeze_handle
, struct ctdb_db_freeze_waiter
);
251 CTDB_NO_MEMORY(ctdb
, w
);
253 w
->private_data
= talloc_steal(w
, c
);
255 talloc_set_destructor(w
, ctdb_db_freeze_waiter_destructor
);
256 DLIST_ADD(ctdb_db
->freeze_handle
->waiters
, w
);
265 int32_t ctdb_control_db_thaw(struct ctdb_context
*ctdb
, uint32_t db_id
)
267 struct ctdb_db_context
*ctdb_db
;
269 ctdb_db
= find_ctdb_db(ctdb
, db_id
);
270 if (ctdb_db
== NULL
) {
271 DEBUG(DEBUG_ERR
, ("Thaw db for unknown dbid 0x%08x\n", db_id
));
275 DEBUG(DEBUG_ERR
, ("Thaw db: %s generation %u\n", ctdb_db
->db_name
,
276 ctdb_db
->generation
));
278 TALLOC_FREE(ctdb_db
->freeze_handle
);
279 ctdb_call_resend_db(ctdb_db
);
285 a list of control requests waiting for a freeze lock child to get
288 struct ctdb_freeze_waiter
{
289 struct ctdb_freeze_waiter
*next
, *prev
;
290 struct ctdb_context
*ctdb
;
291 struct ctdb_req_control_old
*c
;
296 /* a handle to a freeze lock child process */
297 struct ctdb_freeze_handle
{
298 struct ctdb_context
*ctdb
;
300 unsigned int num_total
, num_locked
, num_failed
;
301 struct ctdb_freeze_waiter
*waiters
;
304 static int db_thaw(struct ctdb_db_context
*ctdb_db
, void *private_data
)
306 talloc_free(ctdb_db
->freeze_handle
);
311 destroy a freeze handle
313 static int ctdb_freeze_handle_destructor(struct ctdb_freeze_handle
*h
)
315 struct ctdb_context
*ctdb
= h
->ctdb
;
317 DEBUG(DEBUG_ERR
,("Release freeze handle for prio %u\n", h
->priority
));
319 /* cancel any pending transactions */
320 if (ctdb
->freeze_transaction_started
) {
321 ctdb_db_prio_iterator(ctdb
, h
->priority
,
322 db_transaction_cancel_handler
, NULL
);
323 ctdb
->freeze_transaction_started
= false;
326 ctdb_db_prio_iterator(ctdb
, h
->priority
, db_thaw
, NULL
);
328 ctdb
->freeze_mode
[h
->priority
] = CTDB_FREEZE_NONE
;
329 ctdb
->freeze_handles
[h
->priority
] = NULL
;
335 called when the child writes its status to us
337 static void ctdb_freeze_lock_handler(void *private_data
, bool locked
)
339 struct ctdb_freeze_handle
*h
= talloc_get_type_abort(private_data
,
340 struct ctdb_freeze_handle
);
341 struct ctdb_freeze_waiter
*w
;
343 if (h
->ctdb
->freeze_mode
[h
->priority
] == CTDB_FREEZE_FROZEN
) {
344 DEBUG(DEBUG_INFO
,("freeze child died - unfreezing\n"));
350 DEBUG(DEBUG_ERR
,("Failed to get locks in ctdb_freeze_child\n"));
351 /* we didn't get the locks - destroy the handle */
356 h
->ctdb
->freeze_mode
[h
->priority
] = CTDB_FREEZE_FROZEN
;
358 /* notify the waiters */
359 if (h
!= h
->ctdb
->freeze_handles
[h
->priority
]) {
360 DEBUG(DEBUG_ERR
,("lockwait finished but h is not linked\n"));
362 while ((w
= h
->waiters
)) {
364 DLIST_REMOVE(h
->waiters
, w
);
370 * When single database is frozen
372 static int db_freeze_waiter_destructor(struct ctdb_db_freeze_waiter
*w
)
374 struct ctdb_freeze_handle
*h
= talloc_get_type_abort(
375 w
->private_data
, struct ctdb_freeze_handle
);
377 if (w
->status
== 0) {
383 /* Call ctdb_freeze_lock_handler() only when the status of all
384 * databases is known.
386 if (h
->num_locked
+ h
->num_failed
== h
->num_total
) {
389 if (h
->num_locked
== h
->num_total
) {
394 ctdb_freeze_lock_handler(h
, locked
);
400 * Count the number of databases
402 static int db_count(struct ctdb_db_context
*ctdb_db
, void *private_data
)
404 int *count
= (int *)private_data
;
412 * Freeze a single database
414 static int db_freeze(struct ctdb_db_context
*ctdb_db
, void *private_data
)
416 struct ctdb_freeze_handle
*h
= talloc_get_type_abort(
417 private_data
, struct ctdb_freeze_handle
);
418 struct ctdb_db_freeze_waiter
*w
;
420 ctdb_start_db_freeze(ctdb_db
);
422 w
= talloc(ctdb_db
->freeze_handle
, struct ctdb_db_freeze_waiter
);
423 CTDB_NO_MEMORY(h
->ctdb
, w
);
427 talloc_set_destructor(w
, db_freeze_waiter_destructor
);
429 if (ctdb_db
->freeze_mode
== CTDB_FREEZE_FROZEN
) {
430 /* Early return if already frozen */
436 DLIST_ADD(ctdb_db
->freeze_handle
->waiters
, w
);
442 start the freeze process for a certain priority
444 static void ctdb_start_freeze(struct ctdb_context
*ctdb
, uint32_t priority
)
446 struct ctdb_freeze_handle
*h
;
449 if ((priority
< 1) || (priority
> NUM_DB_PRIORITIES
)) {
450 DEBUG(DEBUG_ERR
,(__location__
" Invalid db priority : %u\n", priority
));
451 ctdb_fatal(ctdb
, "Internal error");
454 if (ctdb
->freeze_mode
[priority
] == CTDB_FREEZE_FROZEN
) {
458 * Check if all the databases are frozen
460 * It's possible that the databases can get attached after
461 * initial freeze. This typically happens during startup as
462 * CTDB will only attach persistent databases and go in to
463 * startup freeze. The recovery master during recovery will
464 * attach all the missing databases.
467 h
= ctdb
->freeze_handles
[priority
];
469 ctdb
->freeze_mode
[priority
] = CTDB_FREEZE_NONE
;
473 ret
= ctdb_db_prio_iterator(ctdb
, priority
, db_count
, &count
);
475 TALLOC_FREE(ctdb
->freeze_handles
[priority
]);
476 ctdb
->freeze_mode
[priority
] = CTDB_FREEZE_NONE
;
480 if (count
!= h
->num_total
) {
481 DEBUG(DEBUG_ERR
, ("Freeze priority %u: incremental\n",
484 h
->num_total
= count
;
488 ctdb
->freeze_mode
[priority
] = CTDB_FREEZE_PENDING
;
490 ret
= ctdb_db_prio_iterator(ctdb
, priority
,
493 TALLOC_FREE(ctdb
->freeze_handles
[priority
]);
494 ctdb
->freeze_mode
[priority
] = CTDB_FREEZE_NONE
;
500 if (ctdb
->freeze_handles
[priority
] != NULL
) {
501 /* already trying to freeze */
505 DEBUG(DEBUG_ERR
, ("Freeze priority %u\n", priority
));
507 /* Stop any vacuuming going on: we don't want to wait. */
508 ctdb_stop_vacuuming(ctdb
);
510 /* create freeze lock children for each database */
511 h
= talloc_zero(ctdb
, struct ctdb_freeze_handle
);
512 CTDB_NO_MEMORY_FATAL(ctdb
, h
);
514 h
->priority
= priority
;
515 talloc_set_destructor(h
, ctdb_freeze_handle_destructor
);
516 ctdb
->freeze_handles
[priority
] = h
;
518 ret
= ctdb_db_prio_iterator(ctdb
, priority
, db_count
, &h
->num_total
);
524 ctdb
->freeze_mode
[priority
] = CTDB_FREEZE_PENDING
;
526 ret
= ctdb_db_prio_iterator(ctdb
, priority
, db_freeze
, h
);
532 if (h
->num_total
== 0) {
533 ctdb
->freeze_mode
[priority
] = CTDB_FREEZE_FROZEN
;
538 destroy a waiter for a freeze mode change
540 static int ctdb_freeze_waiter_destructor(struct ctdb_freeze_waiter
*w
)
542 ctdb_request_control_reply(w
->ctdb
, w
->c
, NULL
, w
->status
, NULL
);
549 int32_t ctdb_control_freeze(struct ctdb_context
*ctdb
, struct ctdb_req_control_old
*c
, bool *async_reply
)
551 struct ctdb_freeze_waiter
*w
;
554 priority
= (uint32_t)c
->srvid
;
557 DEBUG(DEBUG_ERR
,("Freeze priority 0 requested, remapping to priority 1\n"));
561 if ((priority
< 1) || (priority
> NUM_DB_PRIORITIES
)) {
562 DEBUG(DEBUG_ERR
,(__location__
" Invalid db priority : %u\n", priority
));
566 ctdb_start_freeze(ctdb
, priority
);
568 if (ctdb
->freeze_mode
[priority
] == CTDB_FREEZE_FROZEN
) {
569 DEBUG(DEBUG_ERR
, ("Freeze priority %u: frozen\n", priority
));
570 /* we're already frozen */
574 if (ctdb
->freeze_handles
[priority
] == NULL
) {
575 DEBUG(DEBUG_ERR
,("No freeze lock handle when adding a waiter\n"));
579 /* If there are no databases, we are done. */
580 if (ctdb
->freeze_handles
[priority
]->num_total
== 0) {
584 /* add ourselves to list of waiters */
585 w
= talloc(ctdb
->freeze_handles
[priority
], struct ctdb_freeze_waiter
);
586 CTDB_NO_MEMORY(ctdb
, w
);
588 w
->c
= talloc_steal(w
, c
);
589 w
->priority
= priority
;
591 talloc_set_destructor(w
, ctdb_freeze_waiter_destructor
);
592 DLIST_ADD(ctdb
->freeze_handles
[priority
]->waiters
, w
);
594 /* we won't reply till later */
600 static int db_freeze_block(struct ctdb_db_context
*ctdb_db
, void *private_data
)
602 struct tevent_context
*ev
= (struct tevent_context
*)private_data
;
604 ctdb_start_db_freeze(ctdb_db
);
606 while (ctdb_db
->freeze_mode
== CTDB_FREEZE_PENDING
) {
607 tevent_loop_once(ev
);
610 if (ctdb_db
->freeze_mode
!= CTDB_FREEZE_FROZEN
) {
618 block until we are frozen, used during daemon startup
620 bool ctdb_blocking_freeze(struct ctdb_context
*ctdb
)
624 ret
= ctdb_db_iterator(ctdb
, db_freeze_block
, ctdb
->ev
);
633 static void thaw_priority(struct ctdb_context
*ctdb
, uint32_t priority
)
635 DEBUG(DEBUG_ERR
,("Thawing priority %u\n", priority
));
637 /* cancel any pending transactions */
638 if (ctdb
->freeze_transaction_started
) {
639 ctdb_db_prio_iterator(ctdb
, priority
,
640 db_transaction_cancel_handler
, NULL
);
641 ctdb
->freeze_transaction_started
= false;
644 ctdb_db_prio_iterator(ctdb
, priority
, db_thaw
, NULL
);
645 TALLOC_FREE(ctdb
->freeze_handles
[priority
]);
651 int32_t ctdb_control_thaw(struct ctdb_context
*ctdb
, uint32_t priority
,
654 if (priority
> NUM_DB_PRIORITIES
) {
655 DEBUG(DEBUG_ERR
,(__location__
" Invalid db priority : %u\n",
660 if (check_recmode
&& ctdb
->recovery_mode
== CTDB_RECOVERY_ACTIVE
) {
661 DEBUG(DEBUG_ERR
, ("Failing to thaw databases while "
662 "recovery is active\n"));
668 for (i
=1;i
<=NUM_DB_PRIORITIES
; i
++) {
669 thaw_priority(ctdb
, i
);
672 thaw_priority(ctdb
, priority
);
675 ctdb_call_resend_all(ctdb
);
680 * Database transaction wrappers
682 * These functions are wrappers around transaction start/cancel/commit handlers.
685 struct db_start_transaction_state
{
686 uint32_t transaction_id
;
687 bool transaction_started
;
690 static int db_start_transaction(struct ctdb_db_context
*ctdb_db
,
693 struct db_start_transaction_state
*state
=
694 (struct db_start_transaction_state
*)private_data
;
696 bool transaction_started
;
698 if (ctdb_db
->freeze_mode
!= CTDB_FREEZE_FROZEN
) {
700 ("Database %s not frozen, cannot start transaction\n",
705 transaction_started
= state
->transaction_started
&
706 ctdb_db
->freeze_transaction_started
;
708 ret
= db_transaction_start_handler(ctdb_db
,
709 &transaction_started
);
714 ctdb_db
->freeze_transaction_started
= true;
715 ctdb_db
->freeze_transaction_id
= state
->transaction_id
;
720 static int db_cancel_transaction(struct ctdb_db_context
*ctdb_db
,
725 ret
= db_transaction_cancel_handler(ctdb_db
, private_data
);
730 ctdb_db
->freeze_transaction_started
= false;
735 struct db_commit_transaction_state
{
736 uint32_t transaction_id
;
740 static int db_commit_transaction(struct ctdb_db_context
*ctdb_db
,
743 struct db_commit_transaction_state
*state
=
744 (struct db_commit_transaction_state
*)private_data
;
747 if (ctdb_db
->freeze_mode
!= CTDB_FREEZE_FROZEN
) {
749 ("Database %s not frozen, cannot commit transaction\n",
754 if (!ctdb_db
->freeze_transaction_started
) {
755 DEBUG(DEBUG_ERR
, ("Transaction not started on %s\n",
760 if (ctdb_db
->freeze_transaction_id
!= state
->transaction_id
) {
762 ("Incorrect transaction commit id 0x%08x for %s\n",
763 state
->transaction_id
, ctdb_db
->db_name
));
767 ret
= db_transaction_commit_handler(ctdb_db
, &state
->healthy_nodes
);
772 ctdb_db
->freeze_transaction_started
= false;
773 ctdb_db
->freeze_transaction_id
= 0;
774 ctdb_db
->generation
= state
->transaction_id
;
779 * Start a transaction on a database - used for db recovery
781 int32_t ctdb_control_db_transaction_start(struct ctdb_context
*ctdb
,
784 struct ctdb_transdb
*w
=
785 (struct ctdb_transdb
*)indata
.dptr
;
786 struct ctdb_db_context
*ctdb_db
;
787 struct db_start_transaction_state state
;
789 ctdb_db
= find_ctdb_db(ctdb
, w
->db_id
);
790 if (ctdb_db
== NULL
) {
792 ("Transaction start for unknown dbid 0x%08x\n",
797 state
.transaction_id
= w
->tid
;
798 state
.transaction_started
= true;
800 return db_start_transaction(ctdb_db
, &state
);
804 * Cancel a transaction on a database - used for db recovery
806 int32_t ctdb_control_db_transaction_cancel(struct ctdb_context
*ctdb
,
809 uint32_t db_id
= *(uint32_t *)indata
.dptr
;
810 struct ctdb_db_context
*ctdb_db
;
812 ctdb_db
= find_ctdb_db(ctdb
, db_id
);
813 if (ctdb_db
== NULL
) {
815 ("Transaction cancel for unknown dbid 0x%08x\n", db_id
));
819 DEBUG(DEBUG_ERR
, ("Recovery db transaction cancelled for %s\n",
822 return db_cancel_transaction(ctdb_db
, NULL
);
826 * Commit a transaction on a database - used for db recovery
828 int32_t ctdb_control_db_transaction_commit(struct ctdb_context
*ctdb
,
831 struct ctdb_transdb
*w
=
832 (struct ctdb_transdb
*)indata
.dptr
;
833 struct ctdb_db_context
*ctdb_db
;
834 struct db_commit_transaction_state state
;
835 int healthy_nodes
, i
;
837 ctdb_db
= find_ctdb_db(ctdb
, w
->db_id
);
838 if (ctdb_db
== NULL
) {
840 ("Transaction commit for unknown dbid 0x%08x\n",
846 for (i
=0; i
< ctdb
->num_nodes
; i
++) {
847 if (ctdb
->nodes
[i
]->flags
== 0) {
852 state
.transaction_id
= w
->tid
;
853 state
.healthy_nodes
= healthy_nodes
;
855 return db_commit_transaction(ctdb_db
, &state
);
859 start a transaction on all databases - used for recovery
861 int32_t ctdb_control_transaction_start(struct ctdb_context
*ctdb
, uint32_t id
)
863 struct db_start_transaction_state state
;
866 if (!ctdb_db_all_frozen(ctdb
)) {
867 DEBUG(DEBUG_ERR
, (__location__
868 " failing transaction start while not frozen\n"));
872 state
.transaction_id
= id
;
873 state
.transaction_started
= ctdb
->freeze_transaction_started
;
875 ret
= ctdb_db_iterator(ctdb
, db_start_transaction
, &state
);
880 ctdb
->freeze_transaction_started
= true;
881 ctdb
->freeze_transaction_id
= id
;
887 cancel a transaction for all databases - used for recovery
889 int32_t ctdb_control_transaction_cancel(struct ctdb_context
*ctdb
)
891 DEBUG(DEBUG_ERR
,(__location__
" recovery transaction cancelled called\n"));
893 ctdb_db_iterator(ctdb
, db_cancel_transaction
, NULL
);
895 ctdb
->freeze_transaction_started
= false;
901 commit transactions on all databases
903 int32_t ctdb_control_transaction_commit(struct ctdb_context
*ctdb
, uint32_t id
)
905 struct db_commit_transaction_state state
;
907 int healthy_nodes
= 0;
910 if (!ctdb_db_all_frozen(ctdb
)) {
911 DEBUG(DEBUG_ERR
, (__location__
912 " failing transaction commit while not frozen\n"));
916 if (!ctdb
->freeze_transaction_started
) {
917 DEBUG(DEBUG_ERR
,(__location__
" transaction not started\n"));
921 if (id
!= ctdb
->freeze_transaction_id
) {
922 DEBUG(DEBUG_ERR
,(__location__
" incorrect transaction id 0x%x in commit\n", id
));
926 DEBUG(DEBUG_DEBUG
,(__location__
" num_nodes[%d]\n", ctdb
->num_nodes
));
927 for (i
=0; i
< ctdb
->num_nodes
; i
++) {
928 DEBUG(DEBUG_DEBUG
,(__location__
" node[%d].flags[0x%X]\n",
929 i
, ctdb
->nodes
[i
]->flags
));
930 if (ctdb
->nodes
[i
]->flags
== 0) {
934 DEBUG(DEBUG_INFO
,(__location__
" healthy_nodes[%d]\n", healthy_nodes
));
936 state
.transaction_id
= id
;
937 state
.healthy_nodes
= healthy_nodes
;
939 ret
= ctdb_db_iterator(ctdb
, db_commit_transaction
, &state
);
941 DEBUG(DEBUG_ERR
, ("Cancel all transactions\n"));
945 ctdb
->freeze_transaction_started
= false;
946 ctdb
->freeze_transaction_id
= 0;
951 /* cancel any pending transactions */
952 ctdb_db_iterator(ctdb
, db_cancel_transaction
, NULL
);
953 ctdb
->freeze_transaction_started
= false;
959 wipe a database - only possible when in a frozen transaction
961 int32_t ctdb_control_wipe_database(struct ctdb_context
*ctdb
, TDB_DATA indata
)
963 struct ctdb_transdb w
= *(struct ctdb_transdb
*)indata
.dptr
;
964 struct ctdb_db_context
*ctdb_db
;
966 ctdb_db
= find_ctdb_db(ctdb
, w
.db_id
);
968 DEBUG(DEBUG_ERR
,(__location__
" Unknown db 0x%x\n", w
.db_id
));
972 if (ctdb_db
->freeze_mode
!= CTDB_FREEZE_FROZEN
) {
973 DEBUG(DEBUG_ERR
,(__location__
" Failed transaction_start while not frozen\n"));
977 if (!ctdb_db
->freeze_transaction_started
) {
978 DEBUG(DEBUG_ERR
,(__location__
" transaction not started\n"));
982 if (w
.tid
!= ctdb_db
->freeze_transaction_id
) {
983 DEBUG(DEBUG_ERR
,(__location__
" incorrect transaction id 0x%x in commit\n", w
.tid
));
987 if (tdb_wipe_all(ctdb_db
->ltdb
->tdb
) != 0) {
988 DEBUG(DEBUG_ERR
,(__location__
" Failed to wipe database for db '%s'\n",
993 if (!ctdb_db
->persistent
) {
994 talloc_free(ctdb_db
->delete_queue
);
995 ctdb_db
->delete_queue
= trbt_create(ctdb_db
, 0);
996 if (ctdb_db
->delete_queue
== NULL
) {
997 DEBUG(DEBUG_ERR
, (__location__
" Failed to re-create "
998 "the vacuum tree.\n"));
1006 bool ctdb_db_frozen(struct ctdb_db_context
*ctdb_db
)
1008 if (ctdb_db
->freeze_mode
!= CTDB_FREEZE_FROZEN
) {
1015 bool ctdb_db_prio_frozen(struct ctdb_context
*ctdb
, uint32_t priority
)
1017 if (priority
== 0) {
1020 if (priority
> NUM_DB_PRIORITIES
) {
1021 DEBUG(DEBUG_ERR
, ("Invalid DB priority specified\n"));
1025 if (ctdb
->freeze_mode
[priority
] != CTDB_FREEZE_FROZEN
) {
1032 bool ctdb_db_all_frozen(struct ctdb_context
*ctdb
)
1036 for (i
=1; i
<=NUM_DB_PRIORITIES
; i
++) {
1037 if (ctdb
->freeze_mode
[i
] != CTDB_FREEZE_FROZEN
) {