The branch, master has been updated
       via  5c5111c s3-ctdb: Enable CTDB readonly support only if CTDB supports 
it
       via  5bda068 dbwrap_ctdb: only fetch a read-only copy if we had a record 
already.
       via  67bb5ab ctdbd_conn: fetch read-only copies of records.
       via  a3e6f55 dbwrap_ctdb: handle read-only records.
      from  c23b2bd selftest: remove unused config.h check

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


- Log -----------------------------------------------------------------
commit 5c5111ca0319ad3fdd2c27a0bd3c06b576921d08
Author: Amitay Isaacs <[email protected]>
Date:   Tue Feb 21 17:30:53 2012 +1100

    s3-ctdb: Enable CTDB readonly support only if CTDB supports it
    
    Autobuild-User: Amitay Isaacs <[email protected]>
    Autobuild-Date: Mon Mar  5 02:47:36 CET 2012 on sn-devel-104

commit 5bda06877303b4ac01081b12f889db1409c0a6f6
Author: Rusty Russell <[email protected]>
Date:   Fri Feb 3 11:00:54 2012 +1100

    dbwrap_ctdb: only fetch a read-only copy if we had a record already.
    
    Because revoking read-only copies of records is expensive, we only
    want ctdbd to do it for high-turnover records.  A basic heuristic is
    that if we don't find a local copy of the record, don't ask for a
    read-only copy.
    
    The fetch itself will cause ctdbd to migrate the record, so eventually
    we will have a local copy.  Next time it gets migrated away, we'll
    call ctdbd_fetch() with local_copy = true.
    
    Signed-off-by: Rusty Russell <[email protected]>

commit 67bb5abe81dc64758a792060673b923cd77a018a
Author: Rusty Russell <[email protected]>
Date:   Fri Feb 3 10:54:53 2012 +1100

    ctdbd_conn: fetch read-only copies of records.
    
    This means we try to get a read-only copy of a record, which we can
    then place in the local tdb.
    
    Signed-off-by: Rusty Russell <[email protected]>

commit a3e6f550657f2b71634ae87f0d8c7bd9e6eef921
Author: Rusty Russell <[email protected]>
Date:   Fri Feb 3 10:53:27 2012 +1100

    dbwrap_ctdb: handle read-only records.
    
    The new read-only record flags make determining if we can use a record
    a bit more complex, so extract it into its own function.
    
    The OLD logic was:
    1) If the record doesn't exist, we can't use it.
    2) If we are the dmaster for the record, we can use it.
    
    The new logic is:
    1) If the record doesn't exist, we can't use it.
    2) If we are the dmaster for the record, we can use it IF we only
       want read-only access, OR there are no read-only delegations.
    3) If we are not dmaster, we can only use it if we want read-only
       access and it is marked as a read-only copy.
    
    This logic is unused until the next patches which begin to ask
    for read-only copies of records.
    
    Signed-off-by: Rusty Russell <[email protected]>

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

Summary of changes:
 source3/configure.in             |   28 ++++++++++++++++++++++
 source3/include/ctdbd_conn.h     |    3 +-
 source3/lib/ctdbd_conn.c         |   14 ++++++++--
 source3/lib/dbwrap/dbwrap_ctdb.c |   48 +++++++++++++++++++++++++++++--------
 4 files changed, 78 insertions(+), 15 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/configure.in b/source3/configure.in
index 937867d..8c069a0 100644
--- a/source3/configure.in
+++ b/source3/configure.in
@@ -5612,6 +5612,34 @@ if test "x$have_cluster_support" = "xyes" ; then
        fi
 fi
 
+AC_ARG_ENABLE([ctdb-readonly-records],
+       AS_HELP_STRING([--enable-ctdb-readonly-records],
+               [Turn on CTDB readonly records support (default=yes)]),
+       [want_ctdb_readonly=$enableval],
+       [want_ctdb_readonly=yes])
+
+if test "x$have_cluster_support" = "xyes" -a "x$want_ctdb_readonly" = "xyes" ; 
then
+       AC_HAVE_DECL(CTDB_WANT_READONLY,[
+       #include "confdefs.h"
+       #define NO_CONFIG_H
+       #include "replace.h"
+       #include "system/wait.h"
+       #include "system/network.h"
+       #include <talloc.h>
+       #include <tdb.h>
+       #include <ctdb.h>
+       ])
+
+       if test "x$ac_cv_have_CTDB_WANT_READONLY_decl" != "xyes" ; then
+               if test "x$enable_old_ctdb" = "xyes" ; then
+                       AC_MSG_WARN([ignoring missing READONLY support 
(--enable-old-ctdb)])
+               else
+                       ctdb_broken="support for CTDB readonly records missing"
+                       have_cluster_support=no
+               fi
+       fi
+fi
+
 if test "x$have_cluster_support" = "xyes" ; then
        # In ctdb 1.0.57, ctdb_control_tcp was temporarily renamed
        # to ctdb_tcp_client.
diff --git a/source3/include/ctdbd_conn.h b/source3/include/ctdbd_conn.h
index 9a3c27c..2035e8d 100644
--- a/source3/include/ctdbd_conn.h
+++ b/source3/include/ctdbd_conn.h
@@ -60,7 +60,8 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, uint32 
db_id,
                       TDB_DATA key);
 
 NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
-                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data);
+                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data,
+                    bool local_copy);
 
 NTSTATUS ctdbd_traverse(uint32 db_id,
                        void (*fn)(TDB_DATA key, TDB_DATA data,
diff --git a/source3/lib/ctdbd_conn.c b/source3/lib/ctdbd_conn.c
index 9c73002..b5c8280 100644
--- a/source3/lib/ctdbd_conn.c
+++ b/source3/lib/ctdbd_conn.c
@@ -1391,14 +1391,22 @@ NTSTATUS ctdbd_migrate(struct ctdbd_connection *conn, 
uint32 db_id,
 }
 
 /*
- * remotely fetch a record without locking it or forcing a migration
+ * remotely fetch a record (read-only)
  */
 NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, uint32 db_id,
-                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data)
+                    TDB_DATA key, TALLOC_CTX *mem_ctx, TDB_DATA *data,
+                    bool local_copy)
 {
        struct ctdb_req_call req;
        struct ctdb_reply_call *reply;
        NTSTATUS status;
+       uint32_t flags;
+
+#ifdef HAVE_CTDB_WANT_READONLY_DECL
+       flags = local_copy ? CTDB_WANT_READONLY : 0;
+#else
+       flags = 0;
+#endif
 
        ZERO_STRUCT(req);
 
@@ -1407,7 +1415,7 @@ NTSTATUS ctdbd_fetch(struct ctdbd_connection *conn, 
uint32 db_id,
        req.hdr.ctdb_version = CTDB_VERSION;
        req.hdr.operation    = CTDB_REQ_CALL;
        req.hdr.reqid        = ctdbd_next_reqid(conn);
-       req.flags            = 0;
+       req.flags            = flags;
        req.callid           = CTDB_FETCH_FUNC;
        req.db_id            = db_id;
        req.keylen           = key.dsize;
diff --git a/source3/lib/dbwrap/dbwrap_ctdb.c b/source3/lib/dbwrap/dbwrap_ctdb.c
index 3c1ab44..2e0146f 100644
--- a/source3/lib/dbwrap/dbwrap_ctdb.c
+++ b/source3/lib/dbwrap/dbwrap_ctdb.c
@@ -1001,6 +1001,31 @@ static int db_ctdb_record_destr(struct db_record* data)
        return 0;
 }
 
+/* Do I own this record? */
+static bool db_ctdb_own_record(TDB_DATA ctdb_data, bool read_only)
+{
+       struct ctdb_ltdb_header *hdr;
+
+       if (ctdb_data.dptr == NULL)
+               return false;
+
+       if (ctdb_data.dsize < sizeof(struct ctdb_ltdb_header))
+               return false;
+
+#ifdef HAVE_CTDB_WANT_READONLY_DECL
+       hdr = (struct ctdb_ltdb_header *)ctdb_data.dptr;
+       if (hdr->dmaster != get_my_vnn()) {
+               /* If we're not dmaster, it must be r/o copy. */
+               return read_only && (hdr->flags & CTDB_REC_RO_HAVE_READONLY);
+       }
+
+       /* If we want write access, noone can have r/o copies. */
+       return read_only || !(hdr->flags & CTDB_REC_RO_HAVE_DELEGATIONS);
+#else
+       return !read_only;
+#endif
+}
+
 static struct db_record *fetch_locked_internal(struct db_ctdb_ctx *ctx,
                                               TALLOC_CTX *mem_ctx,
                                               TDB_DATA key)
@@ -1064,9 +1089,7 @@ again:
         * take the shortcut and just return it.
         */
 
-       if ((ctdb_data.dptr == NULL) ||
-           (ctdb_data.dsize < sizeof(struct ctdb_ltdb_header)) ||
-           ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster != get_my_vnn()
+       if (!db_ctdb_own_record(ctdb_data, false)
 #if 0
            || (random() % 2 != 0)
 #endif
@@ -1077,10 +1100,11 @@ again:
 
                migrate_attempts += 1;
 
-               DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u)\n",
+               DEBUG(10, ("ctdb_data.dptr = %p, dmaster = %u (%u) %u\n",
                           ctdb_data.dptr, ctdb_data.dptr ?
                           ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster 
: -1,
-                          get_my_vnn()));
+                          get_my_vnn(),
+                          ((struct ctdb_ltdb_header *)ctdb_data.dptr)->flags));
 
                status = ctdbd_migrate(messaging_ctdbd_connection(), ctx->db_id,
                                       key);
@@ -1164,10 +1188,7 @@ static NTSTATUS db_ctdb_fetch(struct db_context *db, 
TALLOC_CTX *mem_ctx,
         * take the shortcut and just return it.
         * we bypass the dmaster check for persistent databases
         */
-       if ((ctdb_data.dptr != NULL) &&
-           (ctdb_data.dsize >= sizeof(struct ctdb_ltdb_header)) &&
-           ((struct ctdb_ltdb_header *)ctdb_data.dptr)->dmaster == 
get_my_vnn())
-       {
+       if (db_ctdb_own_record(ctdb_data, true)) {
                /* we are the dmaster - avoid the ctdb protocol op */
 
                data->dsize = ctdb_data.dsize - sizeof(struct ctdb_ltdb_header);
@@ -1186,9 +1207,14 @@ static NTSTATUS db_ctdb_fetch(struct db_context *db, 
TALLOC_CTX *mem_ctx,
 
        SAFE_FREE(ctdb_data.dptr);
 
-       /* we weren't able to get it locally - ask ctdb to fetch it for us */
+       /*
+        * We weren't able to get it locally - ask ctdb to fetch it for us.
+        * If we already had *something*, it's probably worth making a local
+        * read-only copy.
+        */
        status = ctdbd_fetch(messaging_ctdbd_connection(), ctx->db_id, key,
-                            mem_ctx, data);
+                            mem_ctx, data,
+                            ctdb_data.dsize >= sizeof(struct 
ctdb_ltdb_header));
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5, ("ctdbd_fetch failed: %s\n", nt_errstr(status)));
        }


-- 
Samba Shared Repository

Reply via email to