[SCM] CTDB repository - branch master updated - ctdb-1.0.105-57-g157807a

Ronnie Sahlberg sahlberg at samba.org
Tue Dec 1 20:06:57 MST 2009


The branch, master has been updated
       via  157807af72ed4f7314afbc9c19756f9787b92c15 (commit)
       via  f75d379377f5d4abbff2576ddc5d58d91dc53bf4 (commit)
      from  b4a7efa7e53e060a91dea0e8e57b116e2aeacebf (commit)

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


- Log -----------------------------------------------------------------
commit 157807af72ed4f7314afbc9c19756f9787b92c15
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Dec 2 13:58:27 2009 +1100

    Add a proper function to process a process-exist control in the daemon.
    
    This controls is only used by samba when samba wants to check if a subrecord held by a <node-id>:<smbd-pid> is still valid or if it can be reclaimed.
    
    If the node is banned or stopped, we kill the smbd process and return that the process does not exist to the caller. This allows us to recover subrecords from stopped/banned nodes where smbd is hung waiting for the databases to thaw.
    
    bz58185

commit f75d379377f5d4abbff2576ddc5d58d91dc53bf4
Author: Ronnie Sahlberg <ronniesahlberg at gmail.com>
Date:   Wed Dec 2 13:41:04 2009 +1100

    Add a double linked list to the ctdb_context to store a mapping between client pids and client structures.
    
    Add the mapping to the list everytime we accept() a new client connection
    and set it up to remove in the destructor when the client structure is freed.

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

Summary of changes:
 include/ctdb_private.h |    6 ++++
 server/ctdb_control.c  |    2 +-
 server/ctdb_daemon.c   |   72 +++++++++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 78 insertions(+), 2 deletions(-)


Changeset truncated at 500 lines:

diff --git a/include/ctdb_private.h b/include/ctdb_private.h
index 9a3c3e8..c074afa 100644
--- a/include/ctdb_private.h
+++ b/include/ctdb_private.h
@@ -459,6 +459,9 @@ struct ctdb_context {
 	struct ctdb_monitor_script_status_ctx *last_monitor_status_ctx;
 
 	TALLOC_CTX *banning_ctx;
+
+	/* mapping from pid to ctdb_client * */
+	struct ctdb_client_pid_list *client_pids;
 };
 
 struct ctdb_db_context {
@@ -1552,4 +1555,7 @@ struct ctdb_get_log_addr {
 int32_t ctdb_control_get_log(struct ctdb_context *ctdb, TDB_DATA addr);
 int32_t ctdb_control_clear_log(struct ctdb_context *ctdb);
 
+int32_t ctdb_control_process_exists(struct ctdb_context *ctdb, pid_t pid);
+struct ctdb_client *ctdb_find_client_by_pid(struct ctdb_context *ctdb, pid_t pid);
+
 #endif
diff --git a/server/ctdb_control.c b/server/ctdb_control.c
index 9a9b712..73853e3 100644
--- a/server/ctdb_control.c
+++ b/server/ctdb_control.c
@@ -81,7 +81,7 @@ static int32_t ctdb_control_dispatch(struct ctdb_context *ctdb,
 	switch (opcode) {
 	case CTDB_CONTROL_PROCESS_EXISTS: {
 		CHECK_CONTROL_DATA_SIZE(sizeof(pid_t));
-		return kill(*(pid_t *)indata.dptr, 0);
+		return ctdb_control_process_exists(ctdb, *(pid_t *)indata.dptr);
 	}
 
 	case CTDB_CONTROL_SET_DEBUG: {
diff --git a/server/ctdb_daemon.c b/server/ctdb_daemon.c
index 8d85e76..e5bdad0 100644
--- a/server/ctdb_daemon.c
+++ b/server/ctdb_daemon.c
@@ -29,6 +29,13 @@
 #include "../include/ctdb_private.h"
 #include <sys/socket.h>
 
+struct ctdb_client_pid_list {
+	struct ctdb_client_pid_list *next, *prev;
+	struct ctdb_context *ctdb;
+	pid_t pid;
+	struct ctdb_client *client;
+};
+
 static void daemon_incoming_packet(void *, struct ctdb_req_header *);
 
 static void print_exit_message(void)
@@ -530,6 +537,17 @@ static void ctdb_daemon_read_cb(uint8_t *data, size_t cnt, void *args)
 	daemon_incoming_packet(client, hdr);
 }
 
+
+static int ctdb_clientpid_destructor(struct ctdb_client_pid_list *client_pid)
+{
+	if (client_pid->ctdb->client_pids != NULL) {
+		DLIST_REMOVE(client_pid->ctdb->client_pids, client_pid);
+	}
+
+	return 0;
+}
+
+
 static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde, 
 			 uint16_t flags, void *private_data)
 {
@@ -538,6 +556,7 @@ static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde,
 	int fd;
 	struct ctdb_context *ctdb = talloc_get_type(private_data, struct ctdb_context);
 	struct ctdb_client *client;
+	struct ctdb_client_pid_list *client_pid;
 #ifdef _AIX
 	struct peercred_struct cr;
 	socklen_t crl = sizeof(struct peercred_struct);
@@ -571,12 +590,26 @@ static void ctdb_accept_client(struct event_context *ev, struct fd_event *fde,
 	client->fd = fd;
 	client->client_id = ctdb_reqid_new(ctdb, client);
 	client->pid = cr.pid;
-	ctdb->statistics.num_clients++;
+
+	client_pid = talloc(client, struct ctdb_client_pid_list);
+	if (client_pid == NULL) {
+		DEBUG(DEBUG_ERR,("Failed to allocate client pid structure\n"));
+		close(fd);
+		talloc_free(client);
+		return;
+	}		
+	client_pid->ctdb   = ctdb;
+	client_pid->pid    = cr.pid;
+	client_pid->client = client;
+
+	DLIST_ADD(ctdb->client_pids, client_pid);
 
 	client->queue = ctdb_queue_setup(ctdb, client, fd, CTDB_DS_ALIGNMENT, 
 					 ctdb_daemon_read_cb, client);
 
 	talloc_set_destructor(client, ctdb_client_destructor);
+	talloc_set_destructor(client_pid, ctdb_clientpid_destructor);
+	ctdb->statistics.num_clients++;
 }
 
 
@@ -1151,4 +1184,41 @@ int32_t ctdb_control_deregister_notify(struct ctdb_context *ctdb, uint32_t clien
 	return 0;
 }
 
+struct ctdb_client *ctdb_find_client_by_pid(struct ctdb_context *ctdb, pid_t pid)
+{
+	struct ctdb_client_pid_list *client_pid;
+
+	for (client_pid = ctdb->client_pids; client_pid; client_pid=client_pid->next) {
+		if (client_pid->pid == pid) {
+			return client_pid->client;
+		}
+	}
+	return NULL;
+}
+
 
+/* This control is used by samba when probing if a process (of a samba daemon)
+   exists on the node.
+   Samba does this when it needs/wants to check if a subrecord in one of the
+   databases is still valied, or if it is stale and can be removed.
+   If the node is in unhealthy or stopped state we just kill of the samba
+   process holding htis sub-record and return to the calling samba that
+   the process does not exist.
+   This allows us to forcefully recall subrecords registered by samba processes
+   on banned and stopped nodes.
+*/
+int32_t ctdb_control_process_exists(struct ctdb_context *ctdb, pid_t pid)
+{
+        struct ctdb_client *client;
+
+	if (ctdb->nodes[ctdb->pnn]->flags & (NODE_FLAGS_BANNED|NODE_FLAGS_STOPPED)) {
+		client = ctdb_find_client_by_pid(ctdb, pid);
+		if (client != NULL) {
+			DEBUG(DEBUG_NOTICE,(__location__ " Killing client with pid:%d on banned/stopped node\n", (int)pid));
+			talloc_free(client);
+		}
+		return -1;
+	}
+
+	return kill(pid, 0);
+}


-- 
CTDB repository


More information about the samba-cvs mailing list