[svn.haxx.se] · SVN Dev · SVN Users · SVN Org · TSVN Dev · TSVN Users · Subclipse Dev · Subclipse Users · this month's index

Re: [PATCH] Hotcopy fix

From: D.J. Heap <dj_at_shadyvale.net>
Date: 2005-05-10 04:10:17 CEST

New version of the patch -- only change is the new test. If there are no
objections I'll commit it in a day or two.

Log:
Fix hotcopy command's handling of the db/format file and the locks table.

In BDB repositories, the format file was never being copied. In FSFS
repositories, the format file was always being copied which would
fail on old repositories where that file did not exist.

Additionally, the locks table was never being copied in FSFS
repositories.

* subversion/libsvn_fs_base/fs.c
    (base_hotcopy): Copy the db/format file if it exists.

* subversion/libsvn_fs_fs/fs_fs.c
    (copy_locks_table): New function to copy the locks table while holding
    the repository write lock.
    (svn_fs_fs__hotcopy): Copy the db/format file and locks table if they
    exist.

* subversion/tests/clients/cmdline/svnadmin_tests.py
    (hotcopy_format): New test.

Index: subversion/libsvn_fs_base/fs.c
===================================================================
--- subversion/libsvn_fs_base/fs.c (revision 14667)
+++ subversion/libsvn_fs_base/fs.c (working copy)
@@ -1126,6 +1126,8 @@
   svn_error_t *err;
   u_int32_t pagesize;
   svn_boolean_t log_autoremove = FALSE;
+ svn_node_kind_t kind;
+ const char* format_path;
 
   /* If using DB 4.2 or later, note whether the DB_LOG_AUTOREMOVE
      feature is on. If it is, we have a potential race condition:
@@ -1137,6 +1139,13 @@
                             src_path, pool));
 #endif
 
+ /* Copy the format file if it exists -- it is assumed to be format 1
+ if it does not exist. */
+ format_path = svn_path_join (src_path, FORMAT_FILE, pool);
+ SVN_ERR (svn_io_check_path (format_path, &kind, pool));
+ if ( kind == svn_node_file )
+ SVN_ERR (svn_io_dir_file_copy (src_path, dest_path, FORMAT_FILE, pool));
+
   /* Copy the DB_CONFIG file. */
   SVN_ERR (svn_io_dir_file_copy (src_path, dest_path, "DB_CONFIG", pool));
 
Index: subversion/tests/clients/cmdline/svnadmin_tests.py
===================================================================
--- subversion/tests/clients/cmdline/svnadmin_tests.py (revision 14667)
+++ subversion/tests/clients/cmdline/svnadmin_tests.py (working copy)
@@ -317,7 +317,35 @@
   if origerr or backerr or origout != backout:
     raise svntest.Failure
 
+#----------------------------------------------------------------------
 
+def hotcopy_format(sbox):
+ "'svnadmin hotcopy' checking db/format file"
+ sbox.build()
+
+ backup_dir, backup_url = sbox.add_repo_path('backup')
+ output, errput = svntest.main.run_svnadmin("hotcopy", sbox.repo_dir,
+ backup_dir)
+ if errput:
+ print "Error: hotcopy failed"
+ raise svntest.Failure
+
+ # verify that the db/format files are the same
+ fp = open(os.path.join(sbox.repo_dir, "db", "format"))
+ contents1 = fp.read()
+ fp.close()
+
+ fp2 = open(os.path.join(backup_dir, "db", "format"))
+ contents2 = fp2.read()
+ fp2.close()
+
+ if contents1 != contents2:
+ print "Error: db/format file contents do not match after hotcopy"
+ raise svntest.Failure
+
+
+
+
 ########################################################################
 # Run the tests
 
@@ -331,6 +359,7 @@
               dump_move_dir_modify_child,
               dump_quiet,
               hotcopy_dot,
+ hotcopy_format,
              ]
 
 if __name__ == '__main__':
Index: subversion/libsvn_fs_fs/fs_fs.c
===================================================================
--- subversion/libsvn_fs_fs/fs_fs.c (revision 14667)
+++ subversion/libsvn_fs_fs/fs_fs.c (working copy)
@@ -62,6 +62,7 @@
 #define PATH_REVS_DIR "revs" /* Directory of revisions */
 #define PATH_REVPROPS_DIR "revprops" /* Directory of revprops */
 #define PATH_TXNS_DIR "transactions" /* Directory of transactions */
+#define PATH_LOCKS_DIR "locks" /* Directory of locks */
 
 /* Names of special files and file extensions for transactions */
 #define PATH_CHANGES "changes" /* Records changes made so far */
@@ -338,17 +339,45 @@
   return SVN_NO_ERROR;
 }
 
+/* This is a baton struct for copy_locks_table used by hotcopy */
+struct copy_locks_baton
+{
+ const char *src_path;
+ const char *dst_path;
+};
+
+/* Copy the locks table for the hotcopy command if it exists. */
+static svn_error_t *copy_locks_table (void *baton,
+ apr_pool_t *pool)
+{
+ const char *src_subdir;
+ svn_node_kind_t kind;
+ struct copy_locks_baton *clb = (struct copy_locks_baton *) baton;
+ src_subdir = svn_path_join (clb->src_path, PATH_LOCKS_DIR, pool);
+ SVN_ERR (svn_io_check_path (src_subdir, &kind, pool));
+ if ( kind == svn_node_dir )
+ SVN_ERR (svn_io_copy_dir_recursively (src_subdir, clb->dst_path,
+ PATH_LOCKS_DIR, TRUE, NULL,
+ NULL, pool));
+ return SVN_NO_ERROR;
+}
+
 svn_error_t *
 svn_fs_fs__hotcopy (const char *src_path,
                     const char *dst_path,
                     apr_pool_t *pool)
 {
- const char *src_subdir, *dst_subdir;
+ const char *src_subdir, *dst_subdir, *format_path;
   svn_revnum_t youngest, rev;
   apr_pool_t *iterpool;
+ svn_node_kind_t kind;
 
- /* Copy the format file. */
- SVN_ERR (svn_io_dir_file_copy (src_path, dst_path, PATH_FORMAT, pool));
+ /* Copy the format file if it exists -- it is assumed to be format 1
+ if it does not exist. */
+ format_path = svn_path_join (src_path, PATH_FORMAT, pool);
+ SVN_ERR (svn_io_check_path (format_path, &kind, pool));
+ if ( kind == svn_node_file )
+ SVN_ERR (svn_io_dir_file_copy (src_path, dst_path, PATH_FORMAT, pool));
 
   /* Copy the current file. */
   SVN_ERR (svn_io_dir_file_copy (src_path, dst_path, PATH_CURRENT, pool));
@@ -396,10 +425,21 @@
   dst_subdir = svn_path_join (dst_path, PATH_TXNS_DIR, pool);
   SVN_ERR (svn_io_make_dir_recursively (dst_subdir, pool));
 
+ /* Now copy the locks table -- we need the repo's exclusive lock
+ to do this safely. */
+ {
+ svn_fs_t *fs;
+ struct copy_locks_baton clb;
+
+ clb.src_path = src_path;
+ clb.dst_path = dst_path;
+ SVN_ERR (svn_fs_open (&fs, src_path, NULL, pool));
+ SVN_ERR (svn_fs_fs__with_write_lock (fs, copy_locks_table, &clb, pool));
+ }
+
   return SVN_NO_ERROR;
 }
 
-
 svn_error_t *
 svn_fs_fs__youngest_rev (svn_revnum_t *youngest_p,
                          svn_fs_t *fs,

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Tue May 10 04:11:10 2005

This is an archived mail posted to the Subversion Dev mailing list.