You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by pb...@apache.org on 2012/08/28 02:29:21 UTC

svn commit: r1377920 - in /subversion/branches/inheritable-props: ./ subversion/libsvn_ra_serf/commit.c subversion/libsvn_ra_serf/ra_serf.h subversion/libsvn_repos/repos.c

Author: pburba
Date: Tue Aug 28 00:29:21 2012
New Revision: 1377920

URL: http://svn.apache.org/viewvc?rev=1377920&view=rev
Log:
On the inheritable-props branch: Sync with ^/subversion/trunk through
r1377919.

Modified:
    subversion/branches/inheritable-props/   (props changed)
    subversion/branches/inheritable-props/subversion/libsvn_ra_serf/commit.c
    subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h
    subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c

Propchange: subversion/branches/inheritable-props/
------------------------------------------------------------------------------
  Merged /subversion/trunk:r1376886-1377919

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/commit.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/commit.c?rev=1377920&r1=1377919&r2=1377920&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/commit.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/commit.c Tue Aug 28 00:29:21 2012
@@ -321,6 +321,49 @@ checkout_node(const char **working_url,
 }
 
 
+/* This is a wrapper around checkout_node() (which see for
+   documentation) which simply retries the CHECKOUT request when it
+   fails due to an SVN_ERR_APMOD_BAD_BASELINE error return from the
+   server.
+
+   See http://subversion.tigris.org/issues/show_bug.cgi?id=4127 for
+   details.
+*/
+static svn_error_t *
+retry_checkout_node(const char **working_url,
+                    const commit_context_t *commit_ctx,
+                    const char *node_url,
+                    apr_pool_t *result_pool,
+                    apr_pool_t *scratch_pool)
+{
+  svn_error_t *err = SVN_NO_ERROR;
+  int retry_count = 5; /* Magic, arbitrary number. */
+
+  do
+    {
+      svn_error_clear(err);
+
+      err = checkout_node(working_url, commit_ctx, node_url,
+                          result_pool, scratch_pool);
+
+      /* There's a small chance of a race condition here if Apache is
+         experiencing heavy commit concurrency or if the network has
+         long latency.  It's possible that the value of HEAD changed
+         between the time we fetched the latest baseline and the time
+         we try to CHECKOUT that baseline.  If that happens, Apache
+         will throw us a BAD_BASELINE error (deltaV says you can only
+         checkout the latest baseline).  We just ignore that specific
+         error and retry a few times, asking for the latest baseline
+         again. */
+      if (err && (err->apr_err != SVN_ERR_APMOD_BAD_BASELINE))
+        return err;
+    }
+  while (err && retry_count--);
+
+  return err;
+}
+
+
 static svn_error_t *
 checkout_dir(dir_context_t *dir,
              apr_pool_t *scratch_pool)
@@ -366,8 +409,8 @@ checkout_dir(dir_context_t *dir,
     }
 
   /* Checkout our directory into the activity URL now. */
-  err = checkout_node(working, dir->commit, checkout_url,
-                      dir->pool, scratch_pool);
+  err = retry_checkout_node(working, dir->commit, checkout_url,
+                            dir->pool, scratch_pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_CONFLICT)
@@ -504,8 +547,8 @@ checkout_file(file_context_t *file,
                           NULL, scratch_pool, scratch_pool));
 
   /* Checkout our file into the activity URL now. */
-  err = checkout_node(&file->working_url, file->commit, checkout_url,
-                      file->pool, scratch_pool);
+  err = retry_checkout_node(&file->working_url, file->commit, checkout_url,
+                            file->pool, scratch_pool);
   if (err)
     {
       if (err->apr_err == SVN_ERR_FS_CONFLICT)
@@ -719,6 +762,46 @@ proppatch_walker(void *baton,
   return SVN_NO_ERROR;
 }
 
+/* Possible add the lock-token "If:" precondition header to HEADERS if
+   an examination of COMMIT_CTX and RELPATH indicates that this is the
+   right thing to do.
+
+   Generally speaking, if the client provided a lock token for
+   RELPATH, it's the right thing to do.  There is a notable instance
+   where this is not the case, however.  If the file at RELPATH was
+   explicitly deleted in this commit already, then mod_dav removed its
+   lock token when it fielded the DELETE request, so we don't want to
+   set the lock precondition again.  (See
+   http://subversion.tigris.org/issues/show_bug.cgi?id=3674 for details.)
+*/
+static svn_error_t *
+maybe_set_lock_token_header(serf_bucket_t *headers,
+                            commit_context_t *commit_ctx,
+                            const char *relpath,
+                            apr_pool_t *pool)
+{
+  const char *token;
+
+  if (! (relpath && commit_ctx->lock_tokens))
+    return SVN_NO_ERROR;
+
+  if (! apr_hash_get(commit_ctx->deleted_entries, relpath,
+                     APR_HASH_KEY_STRING))
+    {
+      token = apr_hash_get(commit_ctx->lock_tokens, relpath,
+                           APR_HASH_KEY_STRING);
+      if (token)
+        {
+          const char *token_header;
+
+          token_header = apr_pstrcat(pool, "(<", token, ">)", (char *)NULL);
+          serf_bucket_headers_set(headers, "If", token_header);
+        }
+    }
+  
+  return SVN_NO_ERROR;
+}
+
 static svn_error_t *
 setup_proppatch_headers(serf_bucket_t *headers,
                         void *baton,
@@ -733,22 +816,8 @@ setup_proppatch_headers(serf_bucket_t *h
                                            proppatch->base_revision));
     }
 
-  if (proppatch->relpath && proppatch->commit->lock_tokens)
-    {
-      const char *token;
-
-      token = apr_hash_get(proppatch->commit->lock_tokens, proppatch->relpath,
-                           APR_HASH_KEY_STRING);
-
-      if (token)
-        {
-          const char *token_header;
-
-          token_header = apr_pstrcat(pool, "(<", token, ">)", (char *)NULL);
-
-          serf_bucket_headers_set(headers, "If", token_header);
-        }
-    }
+  SVN_ERR(maybe_set_lock_token_header(headers, proppatch->commit,
+                                      proppatch->relpath, pool));
 
   return SVN_NO_ERROR;
 }
@@ -951,22 +1020,8 @@ setup_put_headers(serf_bucket_t *headers
                               ctx->result_checksum);
     }
 
-  if (ctx->commit->lock_tokens)
-    {
-      const char *token;
-
-      token = apr_hash_get(ctx->commit->lock_tokens, ctx->relpath,
-                           APR_HASH_KEY_STRING);
-
-      if (token)
-        {
-          const char *token_header;
-
-          token_header = apr_pstrcat(pool, "(<", token, ">)", (char *)NULL);
-
-          serf_bucket_headers_set(headers, "If", token_header);
-        }
-    }
+  SVN_ERR(maybe_set_lock_token_header(headers, ctx->commit,
+                                      ctx->relpath, pool));
 
   return APR_SUCCESS;
 }

Modified: subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h?rev=1377920&r1=1377919&r2=1377920&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_ra_serf/ra_serf.h Tue Aug 28 00:29:21 2012
@@ -89,7 +89,9 @@ typedef struct svn_ra_serf__connection_t
 
 } svn_ra_serf__connection_t;
 
-/** Max. number of connctions we'll open to the server. */
+/** Max. number of connctions we'll open to the server. 
+ *  Note: minimum 2 connections are required for ra_serf to function correctly!
+ */
 #define MAX_NR_OF_CONNS 4
 
 /*

Modified: subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c?rev=1377920&r1=1377919&r2=1377920&view=diff
==============================================================================
--- subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c (original)
+++ subversion/branches/inheritable-props/subversion/libsvn_repos/repos.c Tue Aug 28 00:29:21 2012
@@ -330,6 +330,11 @@ create_hooks(svn_repos_t *repos, apr_poo
 "# e.g.: \"" SVN_RA_CAPABILITY_MERGEINFO ":some-other-capability\" "         \
   "(the order is undefined)."                                                NL
 "#"                                                                          NL
+"# Note: The TXN-NAME parameter is new in Subversion 1.8.  Prior to version" NL
+"# 1.8, the start-commit hook was invoked before the commit txn was even"    NL
+"# created, so the ability to inspect the commit txn and its metadata from"  NL
+"# within the start-commit hook was not possible."                           NL
+"# "                                                                         NL
 "# The list is self-reported by the client.  Therefore, you should not"      NL
 "# make security assumptions based on the capabilities list, nor should"     NL
 "# you assume that clients reliably report every capability they have."      NL
@@ -353,10 +358,6 @@ create_hooks(svn_repos_t *repos, apr_poo
 "# '"SCRIPT_NAME".bat' or '"SCRIPT_NAME".exe',"                              NL
 "# but the basic idea is the same."                                          NL
 "# "                                                                         NL
-"# COMPATIBILITY NOTE:  Prior to Subversion 1.8, the start-commit hook was"  NL
-"# invoked before the commit txn was even created, and it did not accept"    NL
-"# the TXN-NAME argument at all."                                            NL
-"# "                                                                         NL
 HOOKS_ENVIRONMENT_TEXT
 "# "                                                                         NL
 "# Here is an example hook script, for a Unix /bin/sh interpreter."          NL