[SCM] CTDB repository - branch master updated - ctdb-1.0.93-11-gb2ce8b9

Ronnie Sahlberg sahlberg at samba.org
Sun Oct 11 23:50:12 MDT 2009


The branch, master has been updated
       via  b2ce8b900a7d00944c84e0574fea5b371064a06d (commit)
       via  46194e87e189521375b39b4ef33da2b493429fd8 (commit)
       via  e8d692590da1070c87a4144031e3306d190ebed2 (commit)
       via  0cb3d33caa42ed783e03bc825b181dde4cf63616 (commit)
       via  465dc95fef0ff6651ff49fa94e4cf2ebd1036ac4 (commit)
       via  ca6d045e419f308f57e74d4c978907afb05ddb85 (commit)
       via  67741c0ee01916d94cace8e9462ef02507e06078 (commit)
       via  dd122351efaeef5475cdec111eb900110d83ec35 (commit)
      from  687535b51622d1fac7ccb38fa640bf1febd69fd8 (commit)

http://gitweb.samba.org/?p=sahlberg/ctdb.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit b2ce8b900a7d00944c84e0574fea5b371064a06d
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Oct 12 16:48:05 2009 +1100

    add a new control for explicitely cancelling recovery transactions, i.e. the
    transactions we start across all tdb databased during the recovery.
    
    this allows us to properly clean up and delete these tdb transactions on a
    recovery failure.

commit 46194e87e189521375b39b4ef33da2b493429fd8
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Oct 12 13:06:16 2009 +1100

    allow setting the recmode even when not completely frozen.
    we sometimes have to do this when we want to trigger a recovery

commit e8d692590da1070c87a4144031e3306d190ebed2
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Oct 12 12:08:39 2009 +1100

    initial attempt at freezing databases in priority order

commit 0cb3d33caa42ed783e03bc825b181dde4cf63616
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Oct 12 09:22:17 2009 +1100

    uptade the freeze/thaw commands to be able to send the requested database priority to freeze/thaw to the daemon.
    
    this is encoded in the srvid field of the request header

commit 465dc95fef0ff6651ff49fa94e4cf2ebd1036ac4
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Sat Oct 10 16:28:20 2009 +1100

    during recovery, update all remote nodes so they use the same priorities
    for the databases as this node.

commit ca6d045e419f308f57e74d4c978907afb05ddb85
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Sat Oct 10 15:04:18 2009 +1100

    add a control to read the db priority from a database

commit 67741c0ee01916d94cace8e9462ef02507e06078
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Sat Oct 10 14:26:09 2009 +1100

    add a control to set a database priority. Let newly created databases default to priority 1.
    
    database priorities will be used to control in which order databases are locked during recovery in.

commit dd122351efaeef5475cdec111eb900110d83ec35
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Sat Oct 10 13:55:11 2009 +1100

    verify the DISABLED flag and compare with the previous flag we have registered for that node and not what the node says is the difference.
    
    this prevents a situation where the remove node may cause spurious ip reallocations.

-----------------------------------------------------------------------

Summary of changes:
 client/ctdb_client.c      |   91 ++++++++++++++++--
 include/ctdb.h            |   13 +++-
 include/ctdb_private.h    |   18 +++-
 server/ctdb_control.c     |   25 +++++-
 server/ctdb_daemon.c      |    2 +-
 server/ctdb_freeze.c      |  227 +++++++++++++++++++++++++++++++--------------
 server/ctdb_ltdb_server.c |   24 +++++
 server/ctdb_monitor.c     |    9 ++-
 server/ctdb_recover.c     |   99 +++++++++++--------
 server/ctdb_recoverd.c    |  121 ++++++++++++++++++++-----
 tools/ctdb.c              |  108 ++++++++++++++++++----
 11 files changed, 564 insertions(+), 173 deletions(-)


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index b8cc301..0948d41 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -1910,9 +1910,9 @@ int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t
   async freeze send control
  */
 struct ctdb_client_control_state *
-ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode)
+ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct timeval timeout, uint32_t destnode, uint32_t priority)
 {
-	return ctdb_control_send(ctdb, destnode, 0, 
+	return ctdb_control_send(ctdb, destnode, priority, 
 			   CTDB_CONTROL_FREEZE, 0, tdb_null, 
 			   mem_ctx, &timeout, NULL);
 }
@@ -1935,30 +1935,43 @@ int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, struct
 }
 
 /*
-  freeze a node
+  freeze databases of a certain priority
  */
-int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
 {
 	TALLOC_CTX *tmp_ctx = talloc_new(ctdb);
 	struct ctdb_client_control_state *state;
 	int ret;
 
-	state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode);
+	state = ctdb_ctrl_freeze_send(ctdb, tmp_ctx, timeout, destnode, priority);
 	ret = ctdb_ctrl_freeze_recv(ctdb, tmp_ctx, state);
 	talloc_free(tmp_ctx);
 
 	return ret;
 }
 
+/* Freeze all databases */
+int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+	int i;
+
+	for (i=1; i<=NUM_DB_PRIORITIES; i++) {
+		if (ctdb_ctrl_freeze_priority(ctdb, timeout, destnode, i) != 0) {
+			return -1;
+		}
+	}
+	return 0;
+}
+
 /*
-  thaw a node
+  thaw databases of a certain priority
  */
-int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority)
 {
 	int ret;
 	int32_t res;
 
-	ret = ctdb_control(ctdb, destnode, 0, 
+	ret = ctdb_control(ctdb, destnode, priority, 
 			   CTDB_CONTROL_THAW, 0, tdb_null, 
 			   NULL, NULL, &res, &timeout, NULL);
 	if (ret != 0 || res != 0) {
@@ -1969,6 +1982,12 @@ int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t d
 	return 0;
 }
 
+/* thaw all databases */
+int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode)
+{
+	return ctdb_ctrl_thaw_priority(ctdb, timeout, destnode, 0);
+}
+
 /*
   get pnn of a node, or -1
  */
@@ -2363,7 +2382,7 @@ int ctdb_ctrl_modflags(struct ctdb_context *ctdb, struct timeval timeout, uint32
 	nodes = list_of_connected_nodes(ctdb, nodemap, tmp_ctx, true);
 
 	if (ctdb_client_async_control(ctdb, CTDB_CONTROL_MODIFY_FLAGS,
-					nodes,
+					nodes, 0,
 					timeout, false, data,
 					NULL, NULL,
 					NULL) != 0) {
@@ -2868,6 +2887,7 @@ int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *
 int ctdb_client_async_control(struct ctdb_context *ctdb,
 				enum ctdb_controls opcode,
 				uint32_t *nodes,
+				uint64_t srvid,
 				struct timeval timeout,
 				bool dont_log_errors,
 				TDB_DATA data,
@@ -2893,7 +2913,7 @@ int ctdb_client_async_control(struct ctdb_context *ctdb,
 	for (j=0; j<num_nodes; j++) {
 		uint32_t pnn = nodes[j];
 
-		state = ctdb_control_send(ctdb, pnn, 0, opcode, 
+		state = ctdb_control_send(ctdb, pnn, srvid, opcode, 
 					  0, data, async_data, &timeout, NULL);
 		if (state == NULL) {
 			DEBUG(DEBUG_ERR,(__location__ " Failed to call async control %u\n", (unsigned)opcode));
@@ -3944,3 +3964,54 @@ int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_
 }
 
 
+int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio)
+{
+	int ret;
+	int32_t res;
+	TDB_DATA data;
+	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+
+	data.dptr = (uint8_t*)db_prio;
+	data.dsize = sizeof(*db_prio);
+
+	ret = ctdb_control(ctdb, destnode, 0, 
+			   CTDB_CONTROL_SET_DB_PRIORITY, 0, data,
+			   tmp_ctx, NULL, &res, &timeout, NULL);
+	if (ret != 0 || res != 0) {
+		DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
+		talloc_free(tmp_ctx);
+		return -1;
+	}
+
+	talloc_free(tmp_ctx);
+
+	return 0;
+}
+
+int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority)
+{
+	int ret;
+	int32_t res;
+	TDB_DATA data;
+	TALLOC_CTX *tmp_ctx = talloc_new(NULL);
+
+	data.dptr = (uint8_t*)&db_id;
+	data.dsize = sizeof(db_id);
+
+	ret = ctdb_control(ctdb, destnode, 0, 
+			   CTDB_CONTROL_GET_DB_PRIORITY, 0, data,
+			   tmp_ctx, NULL, &res, &timeout, NULL);
+	if (ret != 0 || res < 0) {
+		DEBUG(DEBUG_ERR,(__location__ " ctdb_control for set_db_priority failed\n"));
+		talloc_free(tmp_ctx);
+		return -1;
+	}
+
+	if (priority) {
+		*priority = res;
+	}
+
+	talloc_free(tmp_ctx);
+
+	return 0;
+}
diff --git a/include/ctdb.h b/include/ctdb.h
index 23d73fb..b9a7685 100644
--- a/include/ctdb.h
+++ b/include/ctdb.h
@@ -456,14 +456,18 @@ int ctdb_ctrl_getpid(struct ctdb_context *ctdb, struct timeval timeout, uint32_t
 
 int ctdb_ctrl_freeze(struct ctdb_context *ctdb, struct timeval timeout, 
 			uint32_t destnode);
+int ctdb_ctrl_freeze_priority(struct ctdb_context *ctdb, struct timeval timeout, 
+			      uint32_t destnode, uint32_t priority);
 
 struct ctdb_client_control_state *
 ctdb_ctrl_freeze_send(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, 
-			struct timeval timeout, uint32_t destnode);
+		      struct timeval timeout, uint32_t destnode,
+		      uint32_t priority);
 
 int ctdb_ctrl_freeze_recv(struct ctdb_context *ctdb, TALLOC_CTX *mem_ctx, 
 			struct ctdb_client_control_state *state);
 
+int ctdb_ctrl_thaw_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t priority);
 int ctdb_ctrl_thaw(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode);
 
 int ctdb_ctrl_getpnn(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode);
@@ -674,5 +678,12 @@ struct ctdb_ban_time {
 int ctdb_ctrl_set_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_ban_time *bantime);
 int ctdb_ctrl_get_ban(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, TALLOC_CTX *mem_ctx, struct ctdb_ban_time **bantime);
 
+struct ctdb_db_priority {
+	uint32_t db_id;
+	uint32_t priority;
+};
+
+int ctdb_ctrl_set_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, struct ctdb_db_priority *db_prio);
+int ctdb_ctrl_get_db_priority(struct ctdb_context *ctdb, struct timeval timeout, uint32_t destnode, uint32_t db_id, uint32_t *priority);
 
 #endif
diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index a9b4e22..acaaf5f 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -371,6 +371,7 @@ enum ctdb_freeze_mode {CTDB_FREEZE_NONE, CTDB_FREEZE_PENDING, CTDB_FREEZE_FROZEN
 /* This capability is set if NATGW is enabled */
 #define CTDB_CAP_NATGW			0x00000008
 
+#define NUM_DB_PRIORITIES 3
 /* main state of the ctdb daemon */
 struct ctdb_context {
 	struct event_context *ev;
@@ -381,8 +382,10 @@ struct ctdb_context {
 	TALLOC_CTX *tickle_update_context;
 	TALLOC_CTX *keepalive_ctx;
 	struct ctdb_tunable tunable;
-	enum ctdb_freeze_mode freeze_mode;
-	struct ctdb_freeze_handle *freeze_handle;
+	enum ctdb_freeze_mode freeze_mode[NUM_DB_PRIORITIES+1];
+	struct ctdb_freeze_handle *freeze_handles[NUM_DB_PRIORITIES+1];
+	bool freeze_transaction_started;
+	uint32_t freeze_transaction_id;
 	struct ctdb_address address;
 	const char *name;
 	const char *db_directory;
@@ -441,6 +444,7 @@ struct ctdb_db_context {
 	struct ctdb_db_context *next, *prev;
 	struct ctdb_context *ctdb;
 	uint32_t db_id;
+	uint32_t priority;
 	bool persistent;
 	const char *db_name;
 	const char *db_path;
@@ -595,6 +599,9 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS          = 0,
 		    CTDB_CONTROL_DISABLE_SCRIPT          = 108,
 		    CTDB_CONTROL_SET_BAN_STATE           = 109,
 		    CTDB_CONTROL_GET_BAN_STATE           = 110,
+		    CTDB_CONTROL_SET_DB_PRIORITY         = 111,
+		    CTDB_CONTROL_GET_DB_PRIORITY         = 112,
+		    CTDB_CONTROL_TRANSACTION_CANCEL      = 113,
 };	
 
 /*
@@ -1189,7 +1196,7 @@ void ctdb_request_control_reply(struct ctdb_context *ctdb, struct ctdb_req_contr
 				TDB_DATA *outdata, int32_t status, const char *errormsg);
 
 int32_t ctdb_control_freeze(struct ctdb_context *ctdb, struct ctdb_req_control *c, bool *async_reply);
-int32_t ctdb_control_thaw(struct ctdb_context *ctdb);
+int32_t ctdb_control_thaw(struct ctdb_context *ctdb, uint32_t priority);
 
 int ctdb_start_recoverd(struct ctdb_context *ctdb);
 void ctdb_stop_recoverd(struct ctdb_context *ctdb);
@@ -1328,7 +1335,7 @@ int ctdb_ctrl_get_all_tunables(struct ctdb_context *ctdb,
 			       uint32_t destnode,
 			       struct ctdb_tunable *tunables);
 
-void ctdb_start_freeze(struct ctdb_context *ctdb);
+int ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority);
 
 bool parse_ip_mask(const char *s, const char *iface, ctdb_sock_addr *addr, unsigned *mask);
 bool parse_ip_port(const char *s, ctdb_sock_addr *addr);
@@ -1395,6 +1402,7 @@ int32_t ctdb_control_trans2_commit(struct ctdb_context *ctdb,
 
 int32_t ctdb_control_transaction_start(struct ctdb_context *ctdb, uint32_t id);
 int32_t ctdb_control_transaction_commit(struct ctdb_context *ctdb, uint32_t id);
+int32_t ctdb_control_transaction_cancel(struct ctdb_context *ctdb);
 int32_t ctdb_control_wipe_database(struct ctdb_context *ctdb, TDB_DATA indata);
 
 
@@ -1423,6 +1431,7 @@ int ctdb_client_async_wait(struct ctdb_context *ctdb, struct client_async_data *
 int ctdb_client_async_control(struct ctdb_context *ctdb,
 				enum ctdb_controls opcode,
 				uint32_t *nodes,
+			      	uint64_t srvid,
 				struct timeval timeout,
 				bool dont_log_errors,
 				TDB_DATA data,
@@ -1479,5 +1488,6 @@ int32_t ctdb_control_disable_script(struct ctdb_context *ctdb, TDB_DATA indata);
 
 int32_t ctdb_control_set_ban_state(struct ctdb_context *ctdb, TDB_DATA indata);
 int32_t ctdb_control_get_ban_state(struct ctdb_context *ctdb, TDB_DATA *outdata);
+int32_t ctdb_control_set_db_priority(struct ctdb_context *ctdb, TDB_DATA indata);
 
 #endif
diff --git a/server/ctdb_control.c b/server/ctdb_control.c
index 9521305..57641e7 100644
--- a/server/ctdb_control.c
+++ b/server/ctdb_control.c
@@ -98,9 +98,15 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 	}
 
 	case CTDB_CONTROL_STATISTICS: {
+		int i;
 		CHECK_CONTROL_DATA_SIZE(0);
 		ctdb->statistics.memory_used = talloc_total_size(NULL);
-		ctdb->statistics.frozen = (ctdb->freeze_mode == CTDB_FREEZE_FROZEN);
+		ctdb->statistics.frozen = 0;
+		for (i=1; i<= NUM_DB_PRIORITIES; i++) {
+			if (ctdb->freeze_mode[i] == CTDB_FREEZE_FROZEN) {
+				ctdb->statistics.frozen = 1;
+			}
+		}
 		ctdb->statistics.recovering = (ctdb->recovery_mode == CTDB_RECOVERY_ACTIVE);
 		outdata->dptr = (uint8_t *)&ctdb->statistics;
 		outdata->dsize = sizeof(ctdb->statistics);
@@ -249,7 +255,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 
 	case CTDB_CONTROL_THAW:
 		CHECK_CONTROL_DATA_SIZE(0);
-		return ctdb_control_thaw(ctdb);
+		return ctdb_control_thaw(ctdb, (uint32_t)c->srvid);
 
 	case CTDB_CONTROL_SET_RECMODE:
 		CHECK_CONTROL_DATA_SIZE(sizeof(uint32_t));		
@@ -526,6 +532,21 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 		CHECK_CONTROL_DATA_SIZE(0);
 		return ctdb_control_get_ban_state(ctdb, outdata);
 
+	case CTDB_CONTROL_SET_DB_PRIORITY:
+		CHECK_CONTROL_DATA_SIZE(sizeof(struct ctdb_db_priority));
+		return ctdb_control_set_db_priority(ctdb, indata);
+
+	case CTDB_CONTROL_GET_DB_PRIORITY: {
+		uint32_t db_id;
+		struct ctdb_db_context *ctdb_db;
+
+		CHECK_CONTROL_DATA_SIZE(sizeof(db_id));
+		db_id = *(uint32_t *)indata.dptr;
+		ctdb_db = find_ctdb_db(ctdb, db_id);
+		if (ctdb_db == NULL) return -1;
+		return ctdb_db->priority;
+	}
+
 	default:
 		DEBUG(DEBUG_CRIT,(__location__ " Unknown CTDB control opcode %u\n", opcode));
 		return -1;
diff --git a/server/ctdb_daemon.c b/server/ctdb_daemon.c
index fcfba66..0af3bc1 100644
--- a/server/ctdb_daemon.c
+++ b/server/ctdb_daemon.c
@@ -733,7 +733,7 @@ int ctdb_start_daemon(struct ctdb_context *ctdb, bool do_fork)
 	}
 
 	/* start frozen, then let the first election sort things out */
-	if (!ctdb_blocking_freeze(ctdb)) {
+	if (ctdb_blocking_freeze(ctdb)) {
 		ctdb_fatal(ctdb, "Failed to get initial freeze\n");
 	}
 
diff --git a/server/ctdb_freeze.c b/server/ctdb_freeze.c
index e39332e..da7272f 100644
--- a/server/ctdb_freeze.c
+++ b/server/ctdb_freeze.c
@@ -30,10 +30,14 @@
 /*
   lock all databases
  */
-static int ctdb_lock_all_databases(struct ctdb_context *ctdb)
+static int ctdb_lock_all_databases(struct ctdb_context *ctdb, uint32_t priority)
 {
 	struct ctdb_db_context *ctdb_db;
 	for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
+		if (ctdb_db->priority != priority) {
+			continue;
+		}
+		DEBUG(DEBUG_INFO,("locking database 0x%08x priority:%u %s\n", ctdb_db->db_id, ctdb_db->priority, ctdb_db->db_name));
 		if (tdb_lockall(ctdb_db->ltdb->tdb) != 0) {
 			return -1;
 		}
@@ -49,17 +53,17 @@ struct ctdb_freeze_waiter {
 	struct ctdb_freeze_waiter *next, *prev;
 	struct ctdb_context *ctdb;
 	struct ctdb_req_control *c;
+	uint32_t priority;
 	int32_t status;
 };
 
 /* a handle to a freeze lock child process */
 struct ctdb_freeze_handle {
 	struct ctdb_context *ctdb;
+	uint32_t priority;
 	pid_t child;
 	int fd;
 	struct ctdb_freeze_waiter *waiters;
-	bool transaction_started;
-	uint32_t transaction_id;
 };
 
 /*
@@ -70,9 +74,14 @@ static int ctdb_freeze_handle_destructor(struct ctdb_freeze_handle *h)
 	struct ctdb_context *ctdb = h->ctdb;
 	struct ctdb_db_context *ctdb_db;
 
+	DEBUG(DEBUG_ERR,("Release freeze handler for prio %u\n", h->priority));
+
 	/* cancel any pending transactions */
-	if (ctdb->freeze_handle && ctdb->freeze_handle->transaction_started) {
+	if (ctdb->freeze_transaction_started) {
 		for (ctdb_db=ctdb->db_list;ctdb_db;ctdb_db=ctdb_db->next) {
+			if (ctdb_db->priority != h->priority) {
+				continue;
+			}
 			tdb_add_flags(ctdb_db->ltdb->tdb, TDB_NOLOCK);
 			if (tdb_transaction_cancel(ctdb_db->ltdb->tdb) != 0) {
 				DEBUG(DEBUG_ERR,(__location__ " Failed to cancel transaction for db '%s'\n",
@@ -80,11 +89,11 @@ static int ctdb_freeze_handle_destructor(struct ctdb_freeze_handle *h)
 			}
 			tdb_remove_flags(ctdb_db->ltdb->tdb, TDB_NOLOCK);
 		}
-		ctdb->freeze_handle->transaction_started = false;
+		ctdb->freeze_transaction_started = false;
 	}
 
-	ctdb->freeze_mode = CTDB_FREEZE_NONE;
-	ctdb->freeze_handle = NULL;
+	ctdb->freeze_mode[h->priority]    = CTDB_FREEZE_NONE;
+	ctdb->freeze_handles[h->priority] = NULL;
 
 	kill(h->child, SIGKILL);
 	return 0;
@@ -100,11 +109,8 @@ static void ctdb_freeze_lock_handler(struct event_context *ev, struct fd_event *
 	int32_t status;
 	struct ctdb_freeze_waiter *w;
 
-	if (h->ctdb->freeze_mode == CTDB_FREEZE_FROZEN) {
+	if (h->ctdb->freeze_mode[h->priority] == CTDB_FREEZE_FROZEN) {
 		DEBUG(DEBUG_INFO,("freeze child died - unfreezing\n"));
-		if (h->ctdb->freeze_handle == h) {
-			h->ctdb->freeze_handle = NULL;
-		}
 		talloc_free(h);
 		return;
 	}
@@ -121,12 +127,12 @@ static void ctdb_freeze_lock_handler(struct event_context *ev, struct fd_event *
 		return;
 	}
 
-	h->ctdb->freeze_mode = CTDB_FREEZE_FROZEN;
+	h->ctdb->freeze_mode[h->priority] = CTDB_FREEZE_FROZEN;
 
 	/* notify the waiters */
-	while ((w = h->ctdb->freeze_handle->waiters)) {
+	while ((w = h->ctdb->freeze_handles[h->priority]->waiters)) {
 		w->status = status;
-		DLIST_REMOVE(h->ctdb->freeze_handle->waiters, w);
+		DLIST_REMOVE(h->ctdb->freeze_handles[h->priority]->waiters, w);
 		talloc_free(w);
 	}
 }
@@ -135,7 +141,7 @@ static void ctdb_freeze_lock_handler(struct event_context *ev, struct fd_event *
   create a child which gets locks on all the open databases, then calls the callback telling the parent
   that it is done
  */
-static struct ctdb_freeze_handle *ctdb_freeze_lock(struct ctdb_context *ctdb)
+static struct ctdb_freeze_handle *ctdb_freeze_lock(struct ctdb_context *ctdb, uint32_t priority)
 {
 	struct ctdb_freeze_handle *h;
 	int fd[2];
@@ -144,7 +150,8 @@ static struct ctdb_freeze_handle *ctdb_freeze_lock(struct ctdb_context *ctdb)
 	h = talloc_zero(ctdb, struct ctdb_freeze_handle);
 	CTDB_NO_MEMORY_NULL(ctdb, h);
 
-	h->ctdb = ctdb;
+	h->ctdb     = ctdb;
+	h->priority = priority;
 
 	/* use socketpair() instead of pipe() so we have bi-directional fds */
 	if (socketpair(AF_UNIX, SOCK_STREAM, 0, fd) != 0) {
@@ -165,7 +172,7 @@ static struct ctdb_freeze_handle *ctdb_freeze_lock(struct ctdb_context *ctdb)
 		int count = 0;
 		/* in the child */
 		close(fd[0]);
-		ret = ctdb_lock_all_databases(ctdb);
+		ret = ctdb_lock_all_databases(ctdb, priority);
 		if (ret != 0) {
 			_exit(0);
 		}
@@ -213,27 +220,34 @@ static struct ctdb_freeze_handle *ctdb_freeze_lock(struct ctdb_context *ctdb)
  */
 static int ctdb_freeze_waiter_destructor(struct ctdb_freeze_waiter *w)
 {
-	DLIST_REMOVE(w->ctdb->freeze_handle->waiters, w);
+	DLIST_REMOVE(w->ctdb->freeze_handles[w->priority]->waiters, w);
 	ctdb_request_control_reply(w->ctdb, w->c, NULL, w->status, NULL);
 	return 0;
 }
 
 /*
-  start the freeze process
+  start the freeze process for a certain priority
  */
-void ctdb_start_freeze(struct ctdb_context *ctdb)
+int ctdb_start_freeze(struct ctdb_context *ctdb, uint32_t priority)
 {
-	if (ctdb->freeze_mode == CTDB_FREEZE_FROZEN) {
+	if ((priority < 1) || (priority > NUM_DB_PRIORITIES)) {
+		DEBUG(DEBUG_ERR,(__location__ " Invalid db priority : %u\n", priority));
+		return -1;
+	}
+
+	if (ctdb->freeze_mode[priority] == CTDB_FREEZE_FROZEN) {
 		/* we're already frozen */
-		return;


-- 
CTDB repository


More information about the samba-cvs mailing list