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

[PATCH] Hotcopy fix

From: D.J. Heap <dj_at_shadyvale.net>
Date: 2005-05-09 05:58:37 CEST

Does this patch look rational? It behaves correctly for me in my testing so
far.

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.

Index: subversion/libsvn_fs_base/fs.c
===================================================================
--- subversion/libsvn_fs_base/fs.c (revision 14638)
+++ subversion/libsvn_fs_base/fs.c (working copy)
@@ -1124,6 +1124,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:
@@ -1135,6 +1137,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/libsvn_fs_fs/fs_fs.c
===================================================================
--- subversion/libsvn_fs_fs/fs_fs.c (revision 14638)
+++ 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 Mon May 9 05:59:24 2005

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