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

RE: svn rev 7611: FAIL (i386-unknown-freebsdelf5.0 static ra_local)

From: Sander Striker <striker_at_apache.org>
Date: 2003-11-03 13:24:01 CET

> From: Branko Cibej [mailto:brane@xbc.nu]
> Sent: Monday, November 03, 2003 8:01 AM

> brane@xbc.nu wrote:
>
> >BUILD: Revision 7611 on i386-unknown-freebsdelf5.0 static
> >
> >
> ...
>
> >Running all tests in merge_tests.py...FAILURE
> >
> >
> (fails everywhere else, too)
>
> I think this is a consequence of the move to use apr_tmp_dir_get in
> revision 7609. Both of my test machines have /tmp and /home on mounted
> on different volumes; now apr_file_renams on Unix just calls rename(2),
> which does not support cross-volume renames and returns EXDEV instead.
>
> I think this is an APR misfeature. The docs on apr_file_rename say that
> "Moving files or directories across devices may not be possible," but I
> think the workaround is so simple that APR should just implement it
> internally The Windows implementation of apr_file_rename does revert to
> copy+delete on cross-volume renames.
>
> Thoughts?

Something like this? (needs win32 counterpart)

Index: file_io/unix/open.c
===================================================================
RCS file: /home/cvs/apr/file_io/unix/open.c,v
retrieving revision 1.111
diff -u -r1.111 open.c
--- file_io/unix/open.c 19 Mar 2003 03:45:42 -0000 1.111
+++ file_io/unix/open.c 3 Nov 2003 12:18:47 -0000
@@ -216,7 +216,17 @@
                                           const char *to_path,
                                           apr_pool_t *p)
 {
+ apr_status_t rv;
+
     if (rename(from_path, to_path) != 0) {
+ if (errno == EXDEV) {
+ rv = apr_file_copy(from_path, to_path, APR_FILE_SOURCE_PERMS, p);
+ if (rv)
+ return rv;
+
+ return apr_file_remove(from_path, p);
+ }
+
         return errno;
     }
     return APR_SUCCESS;

And temporarily in Subversion, until APR with such a fix is released:

* subversion/libsvn_subr/io.c

  (file_copy): New helper function.

  (svn_io_copy_file): Use helper.

  (svn_io_rename_file): If rename isn't possible because it is cross filesystem,
    copy and delete instead. Use helper.

Index: subversion/libsvn_subr/io.c
===================================================================
--- subversion/libsvn_subr/io.c (revision 7614)
+++ subversion/libsvn_subr/io.c (working copy)
@@ -329,43 +329,26 @@
 ^L
 /*** Creating, copying and appending files. ***/

-svn_error_t *
-svn_io_copy_file (const char *src,
- const char *dst,
- svn_boolean_t copy_perms,
- apr_pool_t *pool)
+static svn_error_t *
+file_copy (const char *src,
+ const char *src_apr,
+ const char *dst,
+ const char *dst_apr,
+ svn_boolean_t copy_perms,
+ apr_pool_t *pool)
 {
- apr_file_t *d;
   apr_status_t apr_err;
- const char *src_apr, *dst_tmp_apr;
- const char *dst_tmp;

- SVN_ERR (svn_path_cstring_from_utf8 (&src_apr, src, pool));
-
- /* For atomicity, we translate to a tmp file and then rename the tmp
- file over the real destination. */
-
- SVN_ERR (svn_io_open_unique_file (&d, &dst_tmp, dst, ".tmp", FALSE, pool));
- SVN_ERR (svn_path_cstring_from_utf8 (&dst_tmp_apr, dst_tmp, pool));
-
- apr_err = apr_file_close (d);
+ apr_err = apr_file_copy (src_apr, dst_apr, APR_OS_DEFAULT, pool);
   if (apr_err)
- {
- return svn_error_createf
- (apr_err, NULL,
- "svn_io_copy_file: error closing '%s'", dst_tmp);
- }
-
- apr_err = apr_file_copy (src_apr, dst_tmp_apr, APR_OS_DEFAULT, pool);
- if (apr_err)
     return svn_error_createf
       (apr_err, NULL, "svn_io_copy_file: error copying '%s' to '%s'",
- src, dst_tmp);
+ src, dst);

   /* If copying perms, set the perms on dst_tmp now, so they will be
      atomically inherited in the upcoming rename. But note that we
      had to wait until now to set perms, because if they say
- read-only, then we'd have failed filling dst_tmp's contents. */
+ read-only, then we'd have failed filling dst's contents. */

   /* ### FIXME: apr_file_copy with perms may fail on Win32. We need a
      platform-specific implementation to get the permissions right. */
@@ -396,7 +379,7 @@
           (apr_err, NULL,
            "svn_io_copy_file: closing '%s' after reading perms", src);

- apr_err = apr_file_perms_set (dst_tmp_apr, finfo.protection);
+ apr_err = apr_file_perms_set (dst_apr, finfo.protection);

       /* We shouldn't be able to get APR_INCOMPLETE or APR_ENOTIMPL
          here under normal circumstances, because the perms themselves
@@ -409,11 +392,43 @@
         {
           return svn_error_createf
             (apr_err, NULL,
- "svn_io_copy_file: setting perms on '%s'", dst_tmp);
+ "svn_io_copy_file: setting perms on '%s'", dst);
         }
     }
 #endif /* ! SVN_WIN32 */

+ return SVN_NO_ERROR;
+}
+
+svn_error_t *
+svn_io_copy_file (const char *src,
+ const char *dst,
+ svn_boolean_t copy_perms,
+ apr_pool_t *pool)
+{
+ apr_file_t *d;
+ apr_status_t apr_err;
+ const char *src_apr, *dst_tmp_apr;
+ const char *dst_tmp;
+
+ SVN_ERR (svn_path_cstring_from_utf8 (&src_apr, src, pool));
+
+ /* For atomicity, we translate to a tmp file and then rename the tmp
+ file over the real destination. */
+
+ SVN_ERR (svn_io_open_unique_file (&d, &dst_tmp, dst, ".tmp", FALSE, pool));
+ SVN_ERR (svn_path_cstring_from_utf8 (&dst_tmp_apr, dst_tmp, pool));
+
+ apr_err = apr_file_close (d);
+ if (apr_err)
+ {
+ return svn_error_createf
+ (apr_err, NULL,
+ "svn_io_copy_file: error closing '%s'", dst_tmp);
+ }
+
+ SVN_ERR (file_copy (src, src_apr, dst_tmp, dst_tmp_apr, copy_perms, pool));
+
   return svn_io_file_rename (dst_tmp, dst, pool);
 }

@@ -1747,6 +1762,13 @@

   status = apr_file_rename (from_path_apr, to_path_apr, pool);

+ if (APR_STATUS_IS_EXDEV(status))
+ {
+ SVN_ERR (file_copy (from_path, from_path_apr, to_path, to_path_apr, TRUE, pool));
+ SVN_ERR (svn_io_remove_file (from_path, pool));
+ return SVN_NO_ERROR;
+ }
+
 #ifdef SVN_WIN32
   /*
     Windows is 'aided' by a number of types of applications that

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@subversion.tigris.org
For additional commands, e-mail: dev-help@subversion.tigris.org
Received on Mon Nov 3 13:24:47 2003

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