[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