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 <[email protected]>
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 <[email protected]>
    Autobuild-Date: Thu Oct 27 22:12:05 CEST 2011 on sn-devel-104

commit 195ae03950b8130b8c3caed65123c87882af595e
Author: Volker Lendecke <[email protected]>
Date:   Wed Oct 26 17:51:09 2011 +0200

    s3-ctdb: Add debug to ctdb_processes_exist

commit 4a96b629a69d06abe73490f03bf6d62cdda08cd6
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
Date:   Wed Oct 26 13:36:56 2011 +0200

    s3: Add serverids_exist

commit ba0171f72402d823abc86504c35312a29749f9b2
Author: Volker Lendecke <[email protected]>
Date:   Wed Oct 26 12:18:21 2011 +0200

    s3: Add processes_exist

commit c5cfc83a3e045d87e1fe73160523282eec2314ec
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
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 <[email protected]>
Date:   Wed Oct 26 10:58:25 2011 +0200

    s3-ctdb: Allow ctdb_read_req to read any reqid

commit 2cf1347211aab592437af81af312026151e578dd
Author: Volker Lendecke <[email protected]>
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 <[email protected]>
Date:   Wed Oct 26 13:54:55 2011 +0200

    s3: Use talloc_tos() in parse_share_modes()

commit 22ccbf2bd4f7788d45173c6780eec6f08f3d2f3e
Author: Volker Lendecke <[email protected]>
Date:   Sun Oct 23 20:56:08 2011 +0200

    s3: Fix some nonempty blank lines

commit 4b9cc8f8f9e108606fcbd78cc2226018cf622088
Author: Volker Lendecke <[email protected]>
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

Reply via email to