[SCM] CTDB repository - branch 1.0.82 updated - ctdb-1.0.82-43-g5b470e7

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


The branch, 1.0.82 has been updated
       via  5b470e788f9c40f5b510e62fbfd1b990779f2c57 (commit)
       via  575210997f7e9aebc721d584b00bf7def15ab600 (commit)
       via  499e781b065f5195e021f33d428503b59b2189b8 (commit)
       via  a92210bc9572851df327862b325376d56470823c (commit)
       via  9bbce3e37e213080e974afea551e9147a43a44af (commit)
       via  17516689570e352d5df1b5a6bae3d7c7e4bb5662 (commit)
       via  808b4a6ed9f6122a958146ef6ac6665f0e75fe32 (commit)
       via  b315a6d0d98a4c9ed026223f529d58f11a6e7695 (commit)
       via  48ad4e096f2302786f5ec03fcbe721bab27ee0ad (commit)
      from  d872c19f9754e97b076a015ec3a61054bc4da4c7 (commit)

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


- Log -----------------------------------------------------------------
commit 5b470e788f9c40f5b510e62fbfd1b990779f2c57
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Mon Oct 12 13:56:27 2009 +1100

    new version 1.0.82-11

commit 575210997f7e9aebc721d584b00bf7def15ab600
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 499e781b065f5195e021f33d428503b59b2189b8
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 a92210bc9572851df327862b325376d56470823c
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 9bbce3e37e213080e974afea551e9147a43a44af
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 17516689570e352d5df1b5a6bae3d7c7e4bb5662
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 808b4a6ed9f6122a958146ef6ac6665f0e75fe32
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 b315a6d0d98a4c9ed026223f529d58f11a6e7695
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Thu Oct 8 20:03:54 2009 +1100

    version 1.0.82-10

commit 48ad4e096f2302786f5ec03fcbe721bab27ee0ad
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Thu Oct 8 16:45:25 2009 +1100

    if a node fails to become frozen during recovery, mark it up with as a culprit so it will soon get banned

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

Summary of changes:
 client/ctdb_client.c      |   92 ++++++++++++++++++--
 include/ctdb.h            |   15 +++-
 include/ctdb_private.h    |   17 +++-
 packaging/RPM/ctdb.spec   |    8 ++-
 server/ctdb_control.c     |   26 ++++++-
 server/ctdb_daemon.c      |    2 +-
 server/ctdb_freeze.c      |  202 +++++++++++++++++++++++++++++----------------
 server/ctdb_ltdb_server.c |   24 ++++++
 server/ctdb_monitor.c     |    9 ++-
 server/ctdb_recover.c     |   99 +++++++++++++---------
 server/ctdb_recoverd.c    |  114 ++++++++++++++++++++------
 tools/ctdb.c              |  108 ++++++++++++++++++++----
 12 files changed, 539 insertions(+), 177 deletions(-)


Changeset truncated at 500 lines:

diff --git a/client/ctdb_client.c b/client/ctdb_client.c
index fa6a990..e60a72e 100644
--- a/client/ctdb_client.c
+++ b/client/ctdb_client.c
@@ -1943,9 +1943,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);
 }
@@ -1968,30 +1968,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) {
@@ -2002,6 +2015,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
  */
@@ -2395,7 +2414,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) {
@@ -2888,6 +2907,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,
@@ -2913,7 +2933,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));
@@ -3636,3 +3656,55 @@ int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval
 
 	return 0;
 }
+
+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 866ba76..34d3080 100644
--- a/include/ctdb.h
+++ b/include/ctdb.h
@@ -453,14 +453,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);
@@ -636,4 +640,13 @@ int ctdb_ctrl_getscriptstatus(struct ctdb_context *ctdb,
 		    TALLOC_CTX *mem_ctx, struct ctdb_monitoring_wire **script_status);
 
 
+
+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 2e3b472..b033949 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -364,6 +364,7 @@ enum ctdb_freeze_mode {CTDB_FREEZE_NONE, CTDB_FREEZE_PENDING, CTDB_FREEZE_FROZEN
 /* This capability is set if CTDB_LVS_PUBLIC_IP is set */
 #define CTDB_CAP_LVS			0x00000004
 
+#define NUM_DB_PRIORITIES 3
 /* main state of the ctdb daemon */
 struct ctdb_context {
 	struct event_context *ev;
@@ -374,8 +375,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;
@@ -434,6 +437,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;
@@ -575,6 +579,8 @@ enum ctdb_controls {CTDB_CONTROL_PROCESS_EXISTS          = 0,
 		    CTDB_CONTROL_GET_EVENT_SCRIPT_STATUS = 96,
 		    CTDB_CONTROL_TRAVERSE_KILL		 = 97,
 		    CTDB_CONTROL_RECD_RECLOCK_LATENCY    = 98,
+		    CTDB_CONTROL_SET_DB_PRIORITY         = 111,
+		    CTDB_CONTROL_GET_DB_PRIORITY         = 112,
 };	
 
 /*
@@ -1169,7 +1175,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);
@@ -1308,7 +1314,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);
@@ -1403,6 +1409,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,
@@ -1449,4 +1456,6 @@ int ctdb_ctrl_report_recd_lock_latency(struct ctdb_context *ctdb, struct timeval
 
 int ctdb_vacuum_init(struct ctdb_db_context *ctdb_db);
 
+int32_t ctdb_control_set_db_priority(struct ctdb_context *ctdb, TDB_DATA indata);
+
 #endif
diff --git a/packaging/RPM/ctdb.spec b/packaging/RPM/ctdb.spec
index 68fc8b1..3699dbb 100644
--- a/packaging/RPM/ctdb.spec
+++ b/packaging/RPM/ctdb.spec
@@ -5,7 +5,7 @@ Vendor: Samba Team
 Packager: Samba Team <samba at samba.org>
 Name: ctdb
 Version: 1.0.82
-Release: 9
+Release: 11
 Epoch: 0
 License: GNU GPL version 3
 Group: System Environment/Daemons
@@ -133,6 +133,12 @@ fi
 %{_libdir}/pkgconfig/ctdb.pc
 
 %changelog
+* Mon Oct 12 2009 : Version 1.0.82-11
+ - Backport the "freeze databases by priority" from HEAD to handle
+   that samba now can hold a log on a database while requesting data
+   from a different database.
+* Thu Oct 10 2009 : Version 1.0.82-10
+ - Be very aggressive to ban nocdes that fails to freeze the databases
 * Fri Oct 2 2009 : Version 1.0.82-9
  - mark a pipe as close on exec
 * Fri Oct 2 2009 : Version 1.0.82-8
diff --git a/server/ctdb_control.c b/server/ctdb_control.c
index f9bd424..1574039 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));		
@@ -445,6 +451,22 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 		CHECK_CONTROL_DATA_SIZE(sizeof(double));
 		ctdb_reclock_latency(ctdb, "recd reclock", &ctdb->statistics.reclock.recd, *((double *)indata.dptr));
 		return 0;
+
+	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 1a94cfc..5c4655d 100644
--- a/server/ctdb_daemon.c
+++ b/server/ctdb_daemon.c
@@ -724,7 +724,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 6f99f8b..53a76f3 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 repository


More information about the samba-cvs mailing list