[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Thu Oct 27 14:13:03 MDT 2011


The branch, master has been updated
       via  a29f7e6 s3-ctdb: Fix ctdb_read_req
       via  195ae03 s3-ctdb: Add debug to ctdb_processes_exist
       via  4a96b62 s3: Use serverids_exist in parse_share_modes
       via  37d7d52 s3: Add serverids_exist
       via  ba0171f s3: Add processes_exist
       via  c5cfc83 s3-ctdb: Make ctdbd_process_exists use ctdbd_processes_exist
       via  1c4fe39 s3-ctdb: Add ctdb_processes_exist
       via  c2edecf s3-ctdb: Allow ctdb_read_req to read any reqid
       via  2cf1347 s3-ctdb: Don't hand out 0 as reqid
       via  e5231a5 s3: Use talloc_tos() in parse_share_modes()
       via  22ccbf2 s3: Fix some nonempty blank lines
       via  4b9cc8f s3: Fix some type-punned warnings
      from  a0f7c99 s4:wscript - install the two missing files "dlz_bind9.so" and "named.conf.dlz"

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


- Log -----------------------------------------------------------------
commit a29f7e632f999af51a0e847331af4447b5710d8e
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Oct 27 15:21:29 2011 +0200

    s3-ctdb: Fix ctdb_read_req
    
    If a complete request has come in already before we consumed it, the
    ctdb_packet_fd_read_sync will block indefinitely. So always try packet_handler
    first and only if that fails due to insufficient data, read from the socket.
    
    Autobuild-User: Volker Lendecke <vlendec at samba.org>
    Autobuild-Date: Thu Oct 27 22:12:05 CEST 2011 on sn-devel-104

commit 195ae03950b8130b8c3caed65123c87882af595e
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 17:51:09 2011 +0200

    s3-ctdb: Add debug to ctdb_processes_exist

commit 4a96b629a69d06abe73490f03bf6d62cdda08cd6
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 13:43:07 2011 +0200

    s3: Use serverids_exist in parse_share_modes
    
    This is the main reason for the preceding commits. We need to reduce the number
    of round-trips to ctdb when checking the locking record entries for existence.
    Using the plural version of process_exists gets the number of round-trips to
    ctdb for process_exists down to 1.

commit 37d7d523589cfa69220b60a37abbb5aefb11f338
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 13:36:56 2011 +0200

    s3: Add serverids_exist

commit ba0171f72402d823abc86504c35312a29749f9b2
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 12:18:21 2011 +0200

    s3: Add processes_exist

commit c5cfc83a3e045d87e1fe73160523282eec2314ec
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 11:36:21 2011 +0200

    s3-ctdb: Make ctdbd_process_exists use ctdbd_processes_exist
    
    Not strictly necessary, but more code exercise is good

commit 1c4fe3903333e9fa24c375c95cfc52a608f9b27b
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Oct 23 21:38:54 2011 +0200

    s3-ctdb: Add ctdb_processes_exist
    
    This sends out a number of process_exists controls in parallel and collects the
    replies as they come in.

commit c2edecf6bd3df1be7b94cbe7dc29f308b9b1d8e0
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 10:58:25 2011 +0200

    s3-ctdb: Allow ctdb_read_req to read any reqid

commit 2cf1347211aab592437af81af312026151e578dd
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 10:56:32 2011 +0200

    s3-ctdb: Don't hand out 0 as reqid
    
    0 will be used as a wildcard reqid in ctdb_read_req

commit e5231a5976c67573f7883538cc5b76db724f8d57
Author: Volker Lendecke <vl at samba.org>
Date:   Wed Oct 26 13:54:55 2011 +0200

    s3: Use talloc_tos() in parse_share_modes()

commit 22ccbf2bd4f7788d45173c6780eec6f08f3d2f3e
Author: Volker Lendecke <vl at samba.org>
Date:   Sun Oct 23 20:56:08 2011 +0200

    s3: Fix some nonempty blank lines

commit 4b9cc8f8f9e108606fcbd78cc2226018cf622088
Author: Volker Lendecke <vl at samba.org>
Date:   Fri Oct 21 12:04:59 2011 +0200

    s3: Fix some type-punned warnings

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

Summary of changes:
 source3/include/ctdbd_conn.h |    9 ++-
 source3/include/proto.h      |    2 +
 source3/include/serverid.h   |    5 +
 source3/lib/ctdbd_conn.c     |  186 ++++++++++++++++++++++++++++++++----------
 source3/lib/serverid.c       |   34 ++++++++
 source3/lib/util.c           |   66 +++++++++++++++
 source3/locking/locking.c    |   26 ++++++-
 7 files changed, 281 insertions(+), 47 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h
index 3d71267..1d52577 100644
--- a/source3/include/ctdbd_conn.h
+++ b/source3/include/ctdbd_conn.h
@@ -2,17 +2,17 @@
    Unix SMB/CIFS implementation.
    Samba3 ctdb connection handling
    Copyright (C) Volker Lendecke 2007
-   
+
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
-   
+
    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.
-   
+
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
@@ -43,6 +43,9 @@ NTSTATUS ctdbd_messaging_send(struct ctdbd_connection *conn,
 
 bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32 vnn,
 			  pid_t pid);
+bool ctdb_processes_exist(struct ctdbd_connection *conn,
+			  const struct server_id *pids, int num_pids,
+			  bool *results);
 
 char *ctdbd_dbpath(struct ctdbd_connection *conn,
 		   TALLOC_CTX *mem_ctx, uint32_t db_id);
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 6ff2854..39a5d03 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -512,6 +512,8 @@ int interpret_protocol(const char *str,int def);
 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name);
 char *automount_lookup(TALLOC_CTX *ctx, const char *user_name);
 bool process_exists(const struct server_id pid);
+bool processes_exist(const struct server_id *pids, int num_pids,
+		     bool *results);
 const char *uidtoname(uid_t uid);
 char *gidtoname(gid_t gid);
 uid_t nametouid(const char *name);
diff --git a/source3/include/serverid.h b/source3/include/serverid.h
index 62bf638..babb21b 100644
--- a/source3/include/serverid.h
+++ b/source3/include/serverid.h
@@ -44,6 +44,11 @@ bool serverid_register_msg_flags(const struct server_id id, bool do_reg,
 bool serverid_exists(const struct server_id *id);
 
 /*
+ * Check existence of a list of server ids
+ */
+bool serverids_exist(const struct server_id *ids, int num_ids, bool *results);
+
+/*
  * Walk the list of server_ids registered
  */
 bool serverid_traverse(int (*fn)(struct db_record *rec,
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 21a417c..5c3b7c1 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -62,6 +62,15 @@ struct ctdbd_connection {
 	void *release_ip_priv;
 };
 
+static uint32_t ctdbd_next_reqid(struct ctdbd_connection *conn)
+{
+	conn->reqid += 1;
+	if (conn->reqid == 0) {
+		conn->reqid += 1;
+	}
+	return conn->reqid;
+}
+
 static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
 			      uint32_t vnn, uint32 opcode, 
 			      uint64_t srvid, uint32_t flags, TDB_DATA data, 
@@ -371,35 +380,29 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
 	struct req_pull_state state;
 	NTSTATUS status;
 
- again:
-
-	status = ctdb_packet_fd_read_sync(conn->pkt);
-
-	if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_BUSY)) {
-		/* EAGAIN */
-		goto again;
-	} else if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
-		/* EAGAIN */
-		goto again;
-	}
-
-	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, ("ctdb_packet_fd_read failed: %s\n", nt_errstr(status)));
-		cluster_fatal("ctdbd died\n");
-	}
-
  next_pkt:
-
 	ZERO_STRUCT(state);
 	state.mem_ctx = mem_ctx;
 
-	if (!ctdb_packet_handler(conn->pkt, ctdb_req_complete, ctdb_req_pull,
-			    &state, &status)) {
+	while (!ctdb_packet_handler(conn->pkt, ctdb_req_complete,
+				    ctdb_req_pull, &state, &status)) {
 		/*
 		 * Not enough data
 		 */
-		DEBUG(10, ("not enough data from ctdb socket, retrying\n"));
-		goto again;
+		status = ctdb_packet_fd_read_sync(conn->pkt);
+
+		if (NT_STATUS_EQUAL(status, NT_STATUS_NETWORK_BUSY)) {
+			/* EAGAIN */
+			continue;
+		} else if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
+			/* EAGAIN */
+			continue;
+		}
+
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(0, ("packet_fd_read failed: %s\n", nt_errstr(status)));
+			cluster_fatal("ctdbd died\n");
+		}
 	}
 
 	if (!NT_STATUS_IS_OK(status)) {
@@ -490,12 +493,12 @@ static NTSTATUS ctdb_read_req(struct ctdbd_connection *conn, uint32 reqid,
 		goto next_pkt;
 	}
 
-	if (hdr->reqid != reqid) {
+	if ((reqid != 0) && (hdr->reqid != reqid)) {
 		/* we got the wrong reply */
 		DEBUG(0,("Discarding mismatched ctdb reqid %u should have "
 			 "been %u\n", hdr->reqid, reqid));
 		TALLOC_FREE(hdr);
-		goto again;
+		goto next_pkt;
 	}
 
 	*((void **)result) = talloc_move(mem_ctx, &hdr);
@@ -833,7 +836,7 @@ static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
 	req.hdr.ctdb_magic   = CTDB_MAGIC;
 	req.hdr.ctdb_version = CTDB_VERSION;
 	req.hdr.operation    = CTDB_REQ_CONTROL;
-	req.hdr.reqid        = ++conn->reqid;
+	req.hdr.reqid        = ctdbd_next_reqid(conn);
 	req.hdr.destnode     = vnn;
 	req.opcode           = opcode;
 	req.srvid            = srvid;
@@ -905,22 +908,121 @@ static NTSTATUS ctdbd_control(struct ctdbd_connection *conn,
  */
 bool ctdbd_process_exists(struct ctdbd_connection *conn, uint32 vnn, pid_t pid)
 {
+	struct server_id id;
+	bool result;
+
+	id.pid = pid;
+	id.vnn = vnn;
+
+	if (!ctdb_processes_exist(conn, &id, 1, &result)) {
+		DEBUG(10, ("ctdb_processes_exist failed\n"));
+		return false;
+	}
+	return result;
+}
+
+bool ctdb_processes_exist(struct ctdbd_connection *conn,
+			  const struct server_id *pids, int num_pids,
+			  bool *results)
+{
+	TALLOC_CTX *frame = talloc_stackframe();
+	int i, num_received;
 	NTSTATUS status;
-	TDB_DATA data;
-	int32_t cstatus;
+	uint32_t *reqids;
+	bool result = false;
 
-	data.dptr = (uint8_t*)&pid;
-	data.dsize = sizeof(pid);
+	reqids = talloc_array(talloc_tos(), uint32_t, num_pids);
+	if (reqids == NULL) {
+		goto fail;
+	}
 
-	status = ctdbd_control(conn, vnn, CTDB_CONTROL_PROCESS_EXISTS, 0, 0,
-			       data, NULL, NULL, &cstatus);
+	for (i=0; i<num_pids; i++) {
+		struct ctdb_req_control req;
+
+		results[i] = false;
+		reqids[i] = ctdbd_next_reqid(conn);
+
+		ZERO_STRUCT(req);
+
+		DEBUG(10, ("Requesting PID %d/%d, reqid=%d\n",
+			   (int)pids[i].vnn, (int)pids[i].pid,
+			   (int)reqids[i]));
+
+		req.hdr.length = offsetof(struct ctdb_req_control, data);
+		req.hdr.length += sizeof(pid_t);
+		req.hdr.ctdb_magic   = CTDB_MAGIC;
+		req.hdr.ctdb_version = CTDB_VERSION;
+		req.hdr.operation    = CTDB_REQ_CONTROL;
+		req.hdr.reqid        = reqids[i];
+		req.hdr.destnode     = pids[i].vnn;
+		req.opcode           = CTDB_CONTROL_PROCESS_EXISTS;
+		req.srvid            = 0;
+		req.datalen          = sizeof(pids[i].pid);
+		req.flags            = 0;
+
+		DEBUG(10, ("ctdbd_control: Sending ctdb packet\n"));
+		ctdb_packet_dump(&req.hdr);
+
+		status = ctdb_packet_send(
+			conn->pkt, 2,
+			data_blob_const(
+				&req, offsetof(struct ctdb_req_control, data)),
+			data_blob_const(&pids[i].pid, sizeof(pids[i].pid)));
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(10, ("ctdb_packet_send failed: %s\n",
+				   nt_errstr(status)));
+			goto fail;
+		}
+	}
+
+	status = ctdb_packet_flush(conn->pkt);
 	if (!NT_STATUS_IS_OK(status)) {
-		DEBUG(0, (__location__ " ctdb_control for process_exists "
-			  "failed\n"));
-		return False;
+		DEBUG(10, ("ctdb_packet_flush failed: %s\n",
+			   nt_errstr(status)));
+		goto fail;
+	}
+
+	num_received = 0;
+
+	while (num_received < num_pids) {
+		struct ctdb_reply_control *reply = NULL;
+		uint32_t reqid;
+
+		status = ctdb_read_req(conn, 0, talloc_tos(), (void *)&reply);
+		if (!NT_STATUS_IS_OK(status)) {
+			DEBUG(10, ("ctdb_read_req failed: %s\n",
+				   nt_errstr(status)));
+			goto fail;
+		}
+
+		if (reply->hdr.operation != CTDB_REPLY_CONTROL) {
+			DEBUG(10, ("Received invalid reply\n"));
+			goto fail;
+		}
+
+		reqid = reply->hdr.reqid;
+
+		DEBUG(10, ("Received reqid %d\n", (int)reqid));
+
+		for (i=0; i<num_pids; i++) {
+			if (reqid == reqids[i]) {
+				break;
+			}
+		}
+		if (i == num_pids) {
+			DEBUG(10, ("Received unknown record number %u\n",
+				   (unsigned)reqid));
+			goto fail;
+		}
+		results[i] = ((reply->status) == 0);
+		TALLOC_FREE(reply);
+		num_received += 1;
 	}
 
-	return cstatus == 0;
+	result = true;
+fail:
+	TALLOC_FREE(frame);
+	return result;
 }
 
 /*
@@ -1016,7 +1118,7 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32 db_id,
 	req.hdr.ctdb_magic   = CTDB_MAGIC;
 	req.hdr.ctdb_version = CTDB_VERSION;
 	req.hdr.operation    = CTDB_REQ_CALL;
-	req.hdr.reqid        = ++conn->reqid;
+	req.hdr.reqid        = ctdbd_next_reqid(conn);
 	req.flags            = CTDB_IMMEDIATE_MIGRATION;
 	req.callid           = CTDB_NULL_FUNC;
 	req.db_id            = db_id;
@@ -1078,7 +1180,7 @@ NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
 	req.hdr.ctdb_magic   = CTDB_MAGIC;
 	req.hdr.ctdb_version = CTDB_VERSION;
 	req.hdr.operation    = CTDB_REQ_CALL;
-	req.hdr.reqid        = ++conn->reqid;
+	req.hdr.reqid        = ctdbd_next_reqid(conn);
 	req.flags            = 0;
 	req.callid           = CTDB_FETCH_FUNC;
 	req.db_id            = db_id;
@@ -1225,7 +1327,7 @@ NTSTATUS ctdbd_traverse(uint32 db_id,
 
 	t.db_id = db_id;
 	t.srvid = conn->rand_srvid;
-	t.reqid = ++conn->reqid;
+	t.reqid = ctdbd_next_reqid(conn);
 
 	data.dptr = (uint8_t *)&t;
 	data.dsize = sizeof(t);
@@ -1359,15 +1461,15 @@ NTSTATUS ctdbd_register_ips(struct ctdbd_connection *conn,
 
 	switch (client.ss_family) {
 	case AF_INET:
-		p4.dest = *(struct sockaddr_in *)(void *)&server;
-		p4.src = *(struct sockaddr_in *)(void *)&client;
+		memcpy(&p4.dest, &server, sizeof(p4.dest));
+		memcpy(&p4.src, &client, sizeof(p4.src));
 		data.dptr = (uint8_t *)&p4;
 		data.dsize = sizeof(p4);
 		break;
 #ifdef HAVE_STRUCT_CTDB_CONTROL_TCP_ADDR
 	case AF_INET6:
-		p.dest.ip6 = *(struct sockaddr_in6 *)(void *)&server;
-		p.src.ip6 = *(struct sockaddr_in6 *)(void *)&client;
+		memcpy(&p.dest.ip6, &server, sizeof(p.dest.ip6));
+		memcpy(&p.src.ip6, &client, sizeof(p.src.ip6));
 		data.dptr = (uint8_t *)&p;
 		data.dsize = sizeof(p);
 		break;
diff --git a/source3/lib/serverid.c b/source3/lib/serverid.c
index b3b294f..274b44b 100644
--- a/source3/lib/serverid.c
+++ b/source3/lib/serverid.c
@@ -273,6 +273,40 @@ bool serverid_exists(const struct server_id *id)
 	return state.exists;
 }
 
+bool serverids_exist(const struct server_id *ids, int num_ids, bool *results)
+{
+	struct db_context *db;
+	int i;
+
+	if (!processes_exist(ids, num_ids, results)) {
+		return false;
+	}
+
+	db = serverid_db();
+	if (db == NULL) {
+		return false;
+	}
+
+	for (i=0; i<num_ids; i++) {
+		struct serverid_exists_state state;
+		struct serverid_key key;
+		TDB_DATA tdbkey;
+
+		if (!results[i]) {
+			continue;
+		}
+
+		serverid_fill_key(&ids[i], &key);
+		tdbkey = make_tdb_data((uint8_t *)&key, sizeof(key));
+
+		state.id = &ids[i];
+		state.exists = false;
+		dbwrap_parse_record(db, tdbkey, server_exists_parse, &state);
+		results[i] = state.exists;
+	}
+	return true;
+}
+
 static bool serverid_rec_parse(const struct db_record *rec,
 			       struct server_id *id, uint32_t *msg_flags)
 {
diff --git a/source3/lib/util.c b/source3/lib/util.c
index f547ec2..9b9d34c 100644
--- a/source3/lib/util.c
+++ b/source3/lib/util.c
@@ -657,6 +657,72 @@ bool process_exists(const struct server_id pid)
 #endif
 }
 
+bool processes_exist(const struct server_id *pids, int num_pids,
+		     bool *results)
+{
+	struct server_id *remote_pids = NULL;
+	int *remote_idx = NULL;
+	bool *remote_results = NULL;
+	int i, num_remote_pids;
+	bool result = false;
+
+	remote_pids = talloc_array(talloc_tos(), struct server_id, num_pids);
+	if (remote_pids == NULL) {
+		goto fail;
+	}
+	remote_idx = talloc_array(talloc_tos(), int, num_pids);
+	if (remote_idx == NULL) {
+		goto fail;
+	}
+	remote_results = talloc_array(talloc_tos(), bool, num_pids);
+	if (remote_results == NULL) {
+		goto fail;
+	}
+
+	num_remote_pids = 0;
+
+	for (i=0; i<num_pids; i++) {
+		if (procid_is_me(&pids[i])) {
+			results[i] = true;
+			continue;
+		}
+		if (procid_is_local(&pids[i])) {
+			results[i] = ((kill(pids[i].pid,0) == 0) ||
+				      (errno != ESRCH));
+			continue;
+		}
+
+		remote_pids[num_remote_pids] = pids[i];
+		remote_idx[num_remote_pids] = i;
+		num_remote_pids += 1;
+	}
+
+	if (num_remote_pids != 0) {
+#ifdef CLUSTER_SUPPORT
+		if (!ctdb_processes_exist(messaging_ctdbd_connection(),
+					  remote_pids, num_remote_pids,
+					  remote_results)) {
+			goto fail;
+		}
+#else
+		for (i=0; i<num_remote_pids; i++) {
+			remote_results[i] = false;
+		}
+#endif
+
+		for (i=0; i<num_remote_pids; i++) {
+			results[remote_idx[i]] = remote_results[i];
+		}
+	}
+
+	result = true;
+fail:
+	TALLOC_FREE(remote_results);
+	TALLOC_FREE(remote_idx);
+	TALLOC_FREE(remote_pids);
+	return result;
+}
+
 /*******************************************************************
  Convert a uid into a user name.
 ********************************************************************/
diff --git a/source3/locking/locking.c b/source3/locking/locking.c
index 38d8c09..1947b18 100644
--- a/source3/locking/locking.c
+++ b/source3/locking/locking.c
@@ -645,6 +645,8 @@ static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
 	struct locking_data data;
 	int delete_tokens_size;
 	int i;
+	struct server_id *pids;
+	bool *pid_exists;
 
 	if (dbuf.dsize < sizeof(struct locking_data)) {
 		smb_panic("parse_share_modes: buffer too short");
@@ -719,15 +721,33 @@ static bool parse_share_modes(const TDB_DATA dbuf, struct share_mode_lock *lck)
 	 * Ensure that each entry has a real process attached.
 	 */
 
+	pids = talloc_array(talloc_tos(), struct server_id,
+			    lck->num_share_modes);
+	if (pids == NULL) {
+		smb_panic("parse_share_modes: talloc_array failed");
+	}
+	pid_exists = talloc_array(talloc_tos(), bool, lck->num_share_modes);
+	if (pid_exists == NULL) {
+		smb_panic("parse_share_modes: talloc_array failed");
+	}
+
+	for (i=0; i<lck->num_share_modes; i++) {
+		pids[i] = lck->share_modes[i].pid;
+	}
+
+	if (!serverids_exist(pids, lck->num_share_modes, pid_exists)) {
+		smb_panic("parse_share_modes: serverids_exist failed");
+	}
+
 	for (i = 0; i < lck->num_share_modes; i++) {
 		struct share_mode_entry *entry_p = &lck->share_modes[i];
 		char *str = NULL;
 		if (DEBUGLEVEL >= 10) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list