cleanup.c revision 289166
1/* 2 * cleanup.c: handle cleaning up workqueue items 3 * 4 * ==================================================================== 5 * Licensed to the Apache Software Foundation (ASF) under one 6 * or more contributor license agreements. See the NOTICE file 7 * distributed with this work for additional information 8 * regarding copyright ownership. The ASF licenses this file 9 * to you under the Apache License, Version 2.0 (the 10 * "License"); you may not use this file except in compliance 11 * with the License. You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, 16 * software distributed under the License is distributed on an 17 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 18 * KIND, either express or implied. See the License for the 19 * specific language governing permissions and limitations 20 * under the License. 21 * ==================================================================== 22 */ 23 24 25 26#include <string.h> 27 28#include "svn_wc.h" 29#include "svn_error.h" 30#include "svn_pools.h" 31#include "svn_io.h" 32#include "svn_dirent_uri.h" 33 34#include "wc.h" 35#include "adm_files.h" 36#include "lock.h" 37#include "workqueue.h" 38 39#include "private/svn_wc_private.h" 40#include "svn_private_config.h" 41 42 43/*** Recursively do log things. ***/ 44 45/* */ 46static svn_error_t * 47can_be_cleaned(int *wc_format, 48 svn_wc__db_t *db, 49 const char *local_abspath, 50 apr_pool_t *scratch_pool) 51{ 52 SVN_ERR(svn_wc__internal_check_wc(wc_format, db, 53 local_abspath, FALSE, scratch_pool)); 54 55 /* a "version" of 0 means a non-wc directory */ 56 if (*wc_format == 0) 57 return svn_error_createf(SVN_ERR_WC_NOT_WORKING_COPY, NULL, 58 _("'%s' is not a working copy directory"), 59 svn_dirent_local_style(local_abspath, 60 scratch_pool)); 61 62 if (*wc_format < SVN_WC__WC_NG_VERSION) 63 return svn_error_create(SVN_ERR_WC_UNSUPPORTED_FORMAT, NULL, 64 _("Log format too old, please use " 65 "Subversion 1.6 or earlier")); 66 67 return SVN_NO_ERROR; 68} 69 70/* Dummy svn_wc_status_func4_t implementation */ 71static svn_error_t * 72status_dummy_callback(void *baton, 73 const char *local_abspath, 74 const svn_wc_status3_t *status, 75 apr_pool_t *scratch_pool) 76{ 77 return SVN_NO_ERROR; 78} 79 80/* */ 81static svn_error_t * 82cleanup_internal(svn_wc__db_t *db, 83 const char *dir_abspath, 84 svn_cancel_func_t cancel_func, 85 void *cancel_baton, 86 apr_pool_t *scratch_pool) 87{ 88 int wc_format; 89 svn_boolean_t is_wcroot; 90 const char *lock_abspath; 91 92 /* Can we even work with this directory? */ 93 SVN_ERR(can_be_cleaned(&wc_format, db, dir_abspath, scratch_pool)); 94 95 /* We cannot obtain a lock on a directory that's within a locked 96 subtree, so always run cleanup from the lock owner. */ 97 SVN_ERR(svn_wc__db_wclock_find_root(&lock_abspath, db, dir_abspath, 98 scratch_pool, scratch_pool)); 99 if (lock_abspath) 100 dir_abspath = lock_abspath; 101 SVN_ERR(svn_wc__db_wclock_obtain(db, dir_abspath, -1, TRUE, scratch_pool)); 102 103 /* Run our changes before the subdirectories. We may not have to recurse 104 if we blow away a subdir. */ 105 if (wc_format >= SVN_WC__HAS_WORK_QUEUE) 106 SVN_ERR(svn_wc__wq_run(db, dir_abspath, cancel_func, cancel_baton, 107 scratch_pool)); 108 109 SVN_ERR(svn_wc__db_is_wcroot(&is_wcroot, db, dir_abspath, scratch_pool)); 110 111#ifdef SVN_DEBUG 112 SVN_ERR(svn_wc__db_verify(db, dir_abspath, scratch_pool)); 113#endif 114 115 /* Perform these operations if we lock the entire working copy. 116 Note that we really need to check a wcroot value and not 117 svn_wc__check_wcroot() as that function, will just return true 118 once we start sharing databases with externals. 119 */ 120 if (is_wcroot) 121 { 122 /* Cleanup the tmp area of the admin subdir, if running the log has not 123 removed it! The logs have been run, so anything left here has no hope 124 of being useful. */ 125 SVN_ERR(svn_wc__adm_cleanup_tmp_area(db, dir_abspath, scratch_pool)); 126 127 /* Remove unreferenced pristine texts */ 128 SVN_ERR(svn_wc__db_pristine_cleanup(db, dir_abspath, scratch_pool)); 129 } 130 131 /* Instead of implementing a separate repair step here, use the standard 132 status walker's optimized implementation, which performs repairs when 133 there is a lock. */ 134 SVN_ERR(svn_wc__internal_walk_status(db, dir_abspath, svn_depth_infinity, 135 FALSE /* get_all */, 136 FALSE /* no_ignore */, 137 FALSE /* ignore_text_mods */, 138 NULL /* ignore patterns */, 139 status_dummy_callback, NULL, 140 cancel_func, cancel_baton, 141 scratch_pool)); 142 143 /* All done, toss the lock */ 144 SVN_ERR(svn_wc__db_wclock_release(db, dir_abspath, scratch_pool)); 145 146 return SVN_NO_ERROR; 147} 148 149 150/* ### possibly eliminate the WC_CTX parameter? callers really shouldn't 151 ### be doing anything *but* running a cleanup, and we need a special 152 ### DB anyway. ... *shrug* ... consider later. */ 153svn_error_t * 154svn_wc_cleanup3(svn_wc_context_t *wc_ctx, 155 const char *local_abspath, 156 svn_cancel_func_t cancel_func, 157 void *cancel_baton, 158 apr_pool_t *scratch_pool) 159{ 160 svn_wc__db_t *db; 161 162 SVN_ERR_ASSERT(svn_dirent_is_absolute(local_abspath)); 163 164 /* We need a DB that allows a non-empty work queue (though it *will* 165 auto-upgrade). We'll handle everything manually. */ 166 SVN_ERR(svn_wc__db_open(&db, 167 NULL /* ### config */, FALSE, FALSE, 168 scratch_pool, scratch_pool)); 169 170 SVN_ERR(cleanup_internal(db, local_abspath, cancel_func, cancel_baton, 171 scratch_pool)); 172 173 /* The DAV cache suffers from flakiness from time to time, and the 174 pre-1.7 prescribed workarounds aren't as user-friendly in WC-NG. */ 175 SVN_ERR(svn_wc__db_base_clear_dav_cache_recursive(db, local_abspath, 176 scratch_pool)); 177 178 SVN_ERR(svn_wc__db_vacuum(db, local_abspath, scratch_pool)); 179 180 /* We're done with this DB, so proactively close it. */ 181 SVN_ERR(svn_wc__db_close(db)); 182 183 return SVN_NO_ERROR; 184} 185