FreeBSD/contrib/subversion/subversion/libsvn_repos/repos.c
/* Make a copy of a repository with hot backup of fs. */
Make a copy of a repository with hot backup of fs.
Make a copy of a repository with hot backup of fs .
svn_error_t *
svn_repos_hotcopy3(const char *src_path,
                   const char *dst_path,
                   svn_boolean_t clean_logs,
                   svn_boolean_t incremental,
                   svn_repos_notify_func_t notify_func,
                   void *notify_baton,
                   svn_cancel_func_t cancel_func,
                   void *cancel_baton,
                   apr_pool_t *scratch_pool)
{
  svn_fs_hotcopy_notify_t fs_notify_func;
  struct fs_hotcopy_notify_baton_t fs_notify_baton;
  struct hotcopy_ctx_t hotcopy_context;
  const char *src_abspath;
  const char *dst_abspath;
  svn_repos_t *src_repos;
  svn_repos_t *dst_repos;
  svn_error_t *err;
  SVN_ERR(svn_dirent_get_absolute(&src_abspath, src_path, scratch_pool));
  SVN_ERR(svn_dirent_get_absolute(&dst_abspath, dst_path, scratch_pool));
  if (strcmp(src_abspath, dst_abspath) == 0)
    return svn_error_create(SVN_ERR_INCORRECT_PARAMS, NULL,
                             _("Hotcopy source and destination are equal"));
  SVN_ERR(get_repos(&src_repos, src_abspath,
                    FALSE, FALSE,
                    FALSE,    
                    NULL,
                    scratch_pool, scratch_pool));
  SVN_ERR(lock_db_logs_file(src_repos, clean_logs, scratch_pool));
  hotcopy_context.dest = dst_abspath;
  hotcopy_context.src_len = strlen(src_abspath);
  hotcopy_context.incremental = incremental;
  hotcopy_context.cancel_func = cancel_func;
  hotcopy_context.cancel_baton = cancel_baton;
  SVN_ERR(svn_io_dir_walk2(src_abspath,
                           0,
                           hotcopy_structure,
                           &hotcopy_context,
                           scratch_pool));
  dst_repos = create_svn_repos_t(dst_abspath, scratch_pool);
  dst_repos->fs_type = src_repos->fs_type;
  dst_repos->format = src_repos->format;
  err = create_locks(dst_repos, scratch_pool);
  if (err)
    {
      if (incremental && err->apr_err == SVN_ERR_DIR_NOT_EMPTY)
        svn_error_clear(err);
      else
        return svn_error_trace(err);
    }
  err = svn_io_dir_make_sgid(dst_repos->db_path, APR_OS_DEFAULT,
                             scratch_pool);
  if (err)
    {
      if (incremental && APR_STATUS_IS_EEXIST(err->apr_err))
        svn_error_clear(err);
      else
        return svn_error_trace(err);
    }
  SVN_ERR(lock_repos(dst_repos, TRUE, FALSE, scratch_pool));
  fs_notify_func = notify_func ? fs_hotcopy_notify : NULL;
  fs_notify_baton.notify_func = notify_func;
  fs_notify_baton.notify_baton = notify_baton;
  SVN_ERR(svn_fs_hotcopy3(src_repos->db_path, dst_repos->db_path,
                          clean_logs, incremental,
                          fs_notify_func, &fs_notify_baton,
                          cancel_func, cancel_baton, scratch_pool));
  return svn_io_write_version_file
          (svn_dirent_join(dst_repos->path, SVN_REPOS__FORMAT, scratch_pool),
           dst_repos->format, scratch_pool);
}
svn_error_t * svn_repos_hotcopy3 ( const char * src_path , const char * dst_path , svn_boolean_t clean_logs , svn_boolean_t incremental , svn_repos_notify_func_t notify_func , void * notify_baton , svn_cancel_func_t cancel_func , void * cancel_baton , apr_pool_t * scratch_pool ) { svn_fs_hotcopy_notify_t fs_notify_func ; struct fs_hotcopy_notify_baton_t fs_notify_baton ; struct hotcopy_ctx_t hotcopy_context ; const char * src_abspath ; const char * dst_abspath ; svn_repos_t * src_repos ; svn_repos_t * dst_repos ; svn_error_t * err ; SVN_ERR ( svn_dirent_get_absolute ( & src_abspath , src_path , scratch_pool ) ) ; SVN_ERR ( svn_dirent_get_absolute ( & dst_abspath , dst_path , scratch_pool ) ) ; if ( strcmp ( src_abspath , dst_abspath ) == 0 ) return svn_error_create ( SVN_ERR_INCORRECT_PARAMS , NULL , _ ( " " ) ) ; SVN_ERR ( get_repos ( & src_repos , src_abspath , FALSE , FALSE , FALSE , NULL , scratch_pool , scratch_pool ) ) ; SVN_ERR ( lock_db_logs_file ( src_repos , clean_logs , scratch_pool ) ) ; hotcopy_context . dest = dst_abspath ; hotcopy_context . src_len = strlen ( src_abspath ) ; hotcopy_context . incremental = incremental ; hotcopy_context . cancel_func = cancel_func ; hotcopy_context . cancel_baton = cancel_baton ; SVN_ERR ( svn_io_dir_walk2 ( src_abspath , 0 , hotcopy_structure , & hotcopy_context , scratch_pool ) ) ; dst_repos = create_svn_repos_t ( dst_abspath , scratch_pool ) ; dst_repos -> fs_type = src_repos -> fs_type ; dst_repos -> format = src_repos -> format ; err = create_locks ( dst_repos , scratch_pool ) ; if ( err ) { if ( incremental && err -> apr_err == SVN_ERR_DIR_NOT_EMPTY ) svn_error_clear ( err ) ; else return svn_error_trace ( err ) ; } err = svn_io_dir_make_sgid ( dst_repos -> db_path , APR_OS_DEFAULT , scratch_pool ) ; if ( err ) { if ( incremental && APR_STATUS_IS_EEXIST ( err -> apr_err ) ) svn_error_clear ( err ) ; else return svn_error_trace ( err ) ; } SVN_ERR ( lock_repos ( dst_repos , TRUE , FALSE , scratch_pool ) ) ; fs_notify_func = notify_func ? fs_hotcopy_notify : NULL ; fs_notify_baton . notify_func = notify_func ; fs_notify_baton . notify_baton = notify_baton ; SVN_ERR ( svn_fs_hotcopy3 ( src_repos -> db_path , dst_repos -> db_path , clean_logs , incremental , fs_notify_func , & fs_notify_baton , cancel_func , cancel_baton , scratch_pool ) ) ; return svn_io_write_version_file ( svn_dirent_join ( dst_repos -> path , SVN_REPOS__FORMAT , scratch_pool ) , dst_repos -> format , scratch_pool ) ; }
Make a copy of a repository with hot backup of fs.
Make a copy of a repository with hot backup of fs .
/* Try to open original repository */ /* don't try to open the db yet. */ /* If we are going to clean logs, then get an exclusive lock on
     db-logs.lock, to ensure that no one else will work with logs.

     If we are just copying, then get a shared lock to ensure that
     no one else will clean logs while we copying them */ /* Copy the repository to a new path, with exception of
     specially handled directories */ /* Prepare dst_repos object so that we may create locks,
     so that we may open repository */ /* Exclusively lock the new repository.
     No one should be accessing it at the moment */ /* Destination repository is ready.  Stamp it with a format number. */