You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by ph...@apache.org on 2013/02/15 11:48:25 UTC

svn commit: r1446504 - in /subversion/trunk/subversion: include/svn_repos.h libsvn_repos/repos.c svnadmin/svnadmin.c

Author: philip
Date: Fri Feb 15 10:48:25 2013
New Revision: 1446504

URL: http://svn.apache.org/r1446504
Log:
Support freezing multiple repositories in libsvn_repos and
make svnadmin support both:

  svnadmin freeze repository command arguments...
  svnadmin freeze -F file_of_repositories command arguments...

* subversion/include/svn_repos.h
  (svn_repos_freeze): Change parameter to array.

* subversion/libsvn_repos/repos.c
  (struct freeze_baton_t): New.
  (multi_freeze): New.
  (svn_repos_freeze): Change parameter to array, call multi_freeze.

* subversion/svnadmin/svnadmin.c
  (options_table): Add -F.
  (cmd_table): Add -F to freeze.
  (subcommand_freeze): Handle one repository or a file of repositories.
  (sub_main): Parse -F, don't expect explict repository with -F.

Modified:
    subversion/trunk/subversion/include/svn_repos.h
    subversion/trunk/subversion/libsvn_repos/repos.c
    subversion/trunk/subversion/svnadmin/svnadmin.c

Modified: subversion/trunk/subversion/include/svn_repos.h
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/include/svn_repos.h?rev=1446504&r1=1446503&r2=1446504&view=diff
==============================================================================
--- subversion/trunk/subversion/include/svn_repos.h (original)
+++ subversion/trunk/subversion/include/svn_repos.h Fri Feb 15 10:48:25 2013
@@ -657,15 +657,17 @@ svn_repos_recover(const char *path,
                   apr_pool_t *pool);
 
 /**
- * Take an exclusive lock on @a path to prevent commits and then
- * invoke @a freeze_body passing @a baton.  The repository may be
- * readable by Subversion while frozen, or it may be unreadable,
- * depending on which FS backend the repository uses.
+ * Take an exclusive lock on each of the repositories in @a paths to
+ * prevent commits and then while holding all the locks invoke
+ * @a freeze_body passing @a baton.  The repositories may be readable
+ * by Subversion while frozen, or it may be unreadable, depending on
+ * which FS backend the repository uses.  Repositories are locked
+ * in array order from zero.
  *
  * @since New in 1.8.
  */
 svn_error_t *
-svn_repos_freeze(const char *path,
+svn_repos_freeze(apr_array_header_t *paths,
                  svn_error_t *(*freeze_body)(void *baton, apr_pool_t *pool),
                  void *baton,
                  apr_pool_t *pool);

Modified: subversion/trunk/subversion/libsvn_repos/repos.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/libsvn_repos/repos.c?rev=1446504&r1=1446503&r2=1446504&view=diff
==============================================================================
--- subversion/trunk/subversion/libsvn_repos/repos.c (original)
+++ subversion/trunk/subversion/libsvn_repos/repos.c Fri Feb 15 10:48:25 2013
@@ -1831,6 +1831,62 @@ svn_repos_recover4(const char *path,
   return SVN_NO_ERROR;
 }
 
+struct freeze_baton_t {
+  apr_array_header_t *paths;
+  int counter;
+  svn_error_t *(*freeze_body)(void *, apr_pool_t *);
+  void *baton;
+};
+
+static svn_error_t *
+multi_freeze(void *baton,
+             apr_pool_t *pool)
+{
+  struct freeze_baton_t *fb = baton;
+
+  if (fb->counter == fb->paths->nelts)
+    {
+      SVN_ERR(fb->freeze_body(fb->baton, pool));
+      return SVN_NO_ERROR;
+    }
+  else
+    {
+      /* Using a subpool as the only way to unlock the repos lock used
+         by BDB is to clear the pool used to take the lock. */
+      apr_pool_t *subpool = svn_pool_create(pool);
+      const char *path = APR_ARRAY_IDX(fb->paths, fb->counter, const char *);
+      svn_repos_t *repos;
+
+      ++fb->counter;
+
+      SVN_ERR(get_repos(&repos, path,
+                        TRUE  /* exclusive (only applies to BDB) */,
+                        FALSE /* non-blocking */,
+                        FALSE /* open-fs */,
+                        NULL, subpool));
+
+
+      if (strcmp(repos->fs_type, SVN_FS_TYPE_BDB) == 0)
+        {
+          svn_error_t *err = multi_freeze(fb, subpool);
+
+          svn_pool_destroy(subpool);
+
+          return err;
+        }
+      else
+        {
+          SVN_ERR(svn_fs_open(&repos->fs, repos->db_path, NULL, subpool));
+          SVN_ERR(svn_fs_freeze(svn_repos_fs(repos), multi_freeze, fb,
+                                subpool));
+        }
+
+      svn_pool_destroy(subpool);
+    }
+
+  return SVN_NO_ERROR;
+}
+
 /* For BDB we fall back on BDB's repos layer lock which means that the
    repository is unreadable while frozen.
 
@@ -1838,36 +1894,19 @@ svn_repos_recover4(const char *path,
    and an SQLite reserved lock which means the repository is readable
    while frozen. */
 svn_error_t *
-svn_repos_freeze(const char *path,
+svn_repos_freeze(apr_array_header_t *paths,
                  svn_error_t *(*freeze_body)(void *, apr_pool_t *),
                  void *baton,
                  apr_pool_t *pool)
 {
-  svn_repos_t *repos;
+  struct freeze_baton_t fb;
 
-  /* Using a subpool as the only way to unlock the repos lock used by
-     BDB is to clear the pool used to take the lock. */
-  apr_pool_t *subpool = svn_pool_create(pool);
-
-  SVN_ERR(get_repos(&repos, path,
-                    TRUE  /* exclusive */,
-                    FALSE /* non-blocking */,
-                    FALSE /* open-fs */,
-                    NULL, subpool));
-
-  if (strcmp(repos->fs_type, SVN_FS_TYPE_BDB) == 0)
-    {
-      svn_error_t *err = freeze_body(baton, subpool);
-      svn_pool_destroy(subpool);
-      return err;
-    }
-  else
-    {
-      SVN_ERR(svn_fs_open(&repos->fs, repos->db_path, NULL, subpool));
-      SVN_ERR(svn_fs_freeze(svn_repos_fs(repos), freeze_body, baton, subpool));
-    }
+  fb.paths = paths;
+  fb.counter = 0;
+  fb.freeze_body = freeze_body;
+  fb.baton = baton;
 
-  svn_pool_destroy(subpool);
+  SVN_ERR(multi_freeze(&fb, pool));
 
   return SVN_NO_ERROR;
 }

Modified: subversion/trunk/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1446504&r1=1446503&r2=1446504&view=diff
==============================================================================
--- subversion/trunk/subversion/svnadmin/svnadmin.c (original)
+++ subversion/trunk/subversion/svnadmin/svnadmin.c Fri Feb 15 10:48:25 2013
@@ -289,6 +289,8 @@ static const apr_getopt_option_t options
      N_("use repository format compatible with Subversion\n"
         "                             version ARG (\"1.5.5\", \"1.7\", etc.)")},
 
+    {"file", 'F', 1, N_("read repository paths from file ARG")},
+
     {NULL}
   };
 
@@ -336,9 +338,14 @@ static const svn_opt_subcommand_desc2_t 
   {'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M'} },
 
   {"freeze", subcommand_freeze, {0}, N_
-   ("usage: svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n\n"
-    "Run PROGRAM passing ARGS while holding a write-lock on REPOS_PATH.\n"),
-   {0} },
+   ("usage: 1. svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n"
+    "               2. svnadmin freeze -F FILE PROGRAM [ARG...]\n\n"
+    "1. Run PROGRAM passing ARGS while holding a write-lock on REPOS_PATH.\n"
+    "\n"
+    "2. Like 1 except all repositories listed in FILE are locked. The file\n"
+    "   format is repository paths separated by newlines.  Repositories are\n"
+    "   locked in the same order as they are listed in the file.\n"),
+   {'F'} },
 
   {"help", subcommand_help, {"?", "h"}, N_
    ("usage: svnadmin help [SUBCOMMAND...]\n\n"
@@ -506,6 +513,7 @@ struct svnadmin_opt_state
                                                        --force-uuid */
   apr_uint64_t memory_cache_size;                   /* --memory-cache-size M */
   const char *parent_dir;
+  svn_stringbuf_t *filedata;                        /* --file */
 
   const char *config_dir;    /* Overriding Configuration Directory */
 };
@@ -1028,6 +1036,7 @@ static svn_error_t *
 subcommand_freeze(apr_getopt_t *os, void *baton, apr_pool_t *pool)
 {
   struct svnadmin_opt_state *opt_state = baton;
+  apr_array_header_t *paths;
   apr_array_header_t *args;
   int i;
   struct freeze_baton_t b;
@@ -1038,13 +1047,25 @@ subcommand_freeze(apr_getopt_t *os, void
     return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, 0,
                             _("No program provided"));
 
+  if (!opt_state->filedata)
+    {
+      /* One repository on the command line. */
+      paths = apr_array_make(pool, 1, sizeof(const char *));
+      APR_ARRAY_PUSH(paths, const char *) = opt_state->repository_path;
+    }
+  else
+    {
+      /* All repositories in filedata. */
+      paths = svn_cstring_split(opt_state->filedata->data, "\n", FALSE, pool);
+    }
+
   b.command = APR_ARRAY_IDX(args, 0, const char *);
   b.args = apr_palloc(pool, sizeof(char *) * args->nelts + 1);
   for (i = 0; i < args->nelts; ++i)
     b.args[i] = APR_ARRAY_IDX(args, i, const char *);
   b.args[args->nelts] = NULL;
 
-  SVN_ERR(svn_repos_freeze(opt_state->repository_path, freeze_body, &b, pool));
+  SVN_ERR(svn_repos_freeze(paths, freeze_body, &b, pool));
 
   /* Make any non-zero status visible to the user. */
   if (b.status)
@@ -1902,6 +1923,7 @@ sub_main(int argc, const char *argv[], a
   int opt_id;
   apr_array_header_t *received_opts;
   int i;
+  svn_boolean_t dash_F_arg = FALSE;
 
   received_opts = apr_array_make(pool, SVN_OPT_MAX_OPTIONS, sizeof(int));
 
@@ -1981,6 +2003,11 @@ sub_main(int argc, const char *argv[], a
         opt_state.memory_cache_size
             = 0x100000 * apr_strtoi64(opt_arg, NULL, 0);
         break;
+      case 'F':
+        SVN_INT_ERR(svn_utf_cstring_to_utf8(&utf8_opt_arg, opt_arg, pool));
+        SVN_INT_ERR(svn_stringbuf_from_file2(&(opt_state.filedata),
+                                             utf8_opt_arg, pool));
+        dash_F_arg = TRUE;
       case svnadmin__version:
         opt_state.version = TRUE;
         break;
@@ -2146,9 +2173,11 @@ sub_main(int argc, const char *argv[], a
         }
     }
 
-  /* Every subcommand except `help' requires a second argument -- the
-     repository path.  Parse it out here and store it in opt_state. */
-  if (subcommand->cmd_func != subcommand_help)
+  /* Every subcommand except `help' and `freeze' with '-F' require a
+     second argument -- the repository path.  Parse it out here and
+     store it in opt_state. */
+  if (!(subcommand->cmd_func == subcommand_help
+        || (subcommand->cmd_func == subcommand_freeze && dash_F_arg)))
     {
       const char *repos_path = NULL;
 



Re: svn commit: r1446504 - in /subversion/trunk/subversion: include/svn_repos.h libsvn_repos/repos.c svnadmin/svnadmin.c

Posted by Philip Martin <ph...@wandisco.com>.
Ivan Zhakov <iv...@visualsvn.com> writes:

> This code does not handle CR LF which is standard on Windows. So
> 'svnadmin freeze -M' does not work on Windows. Changing code to:
> [[
> paths = svn_cstring_split(opt_state->filedata->data, "\n\r", TRUE, pool);
> ]]
>
> Fixes the problem. Btw it seems there is no tests for 'svnadmin freeze
> -M' case

'-F' rather than '-M'.

I've committed a \r fix.  This does mean admins can no longer use \r in
repository names inside the '-F' file but I don't believe that matters.
I've also improved the test.

-- 
Philip Martin | Subversion Committer
WANdisco // *Non-Stop Data*

Re: svn commit: r1446504 - in /subversion/trunk/subversion: include/svn_repos.h libsvn_repos/repos.c svnadmin/svnadmin.c

Posted by Ivan Zhakov <iv...@visualsvn.com>.
On 15 February 2013 14:48,  <ph...@apache.org> wrote:
> Author: philip
> Date: Fri Feb 15 10:48:25 2013
> New Revision: 1446504
>
> URL: http://svn.apache.org/r1446504
> Log:
> Support freezing multiple repositories in libsvn_repos and
> make svnadmin support both:
>
[..]

> Modified: subversion/trunk/subversion/svnadmin/svnadmin.c
> URL: http://svn.apache.org/viewvc/subversion/trunk/subversion/svnadmin/svnadmin.c?rev=1446504&r1=1446503&r2=1446504&view=diff
> ==============================================================================
> --- subversion/trunk/subversion/svnadmin/svnadmin.c (original)
> +++ subversion/trunk/subversion/svnadmin/svnadmin.c Fri Feb 15 10:48:25 2013
> @@ -289,6 +289,8 @@ static const apr_getopt_option_t options
[...]

> +  if (!opt_state->filedata)
> +    {
> +      /* One repository on the command line. */
> +      paths = apr_array_make(pool, 1, sizeof(const char *));
> +      APR_ARRAY_PUSH(paths, const char *) = opt_state->repository_path;
> +    }
> +  else
> +    {
> +      /* All repositories in filedata. */
> +      paths = svn_cstring_split(opt_state->filedata->data, "\n", FALSE, pool);
Hi Philip,

This code does not handle CR LF which is standard on Windows. So
'svnadmin freeze -M' does not work on Windows. Changing code to:
[[
paths = svn_cstring_split(opt_state->filedata->data, "\n\r", TRUE, pool);
]]

Fixes the problem. Btw it seems there is no tests for 'svnadmin freeze -M' case

> +    }
> +
[..]


-- 
Ivan Zhakov
CTO | VisualSVN | http://www.visualsvn.com