You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@subversion.apache.org by da...@apache.org on 2015/08/19 04:35:15 UTC
svn commit: r1696514 [9/10] - in /subversion/branches/patch-exec: ./
build/ac-macros/ notes/ subversion/bindings/javahl/native/
subversion/bindings/swig/ subversion/include/ subversion/include/private/
subversion/libsvn_client/ subversion/libsvn_fs_fs/...
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/cache-membuffer.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/cache-membuffer.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/cache-membuffer.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/cache-membuffer.c Wed Aug 19 02:35:12 2015
@@ -28,12 +28,14 @@
#include "svn_pools.h"
#include "svn_checksum.h"
#include "svn_private_config.h"
+#include "svn_hash.h"
#include "svn_string.h"
#include "svn_sorts.h" /* get the MIN macro */
#include "private/svn_atomic.h"
#include "private/svn_dep_compat.h"
#include "private/svn_mutex.h"
+#include "private/svn_subr_private.h"
#include "private/svn_string_private.h"
#include "cache.h"
@@ -117,6 +119,12 @@
* key length stored in the entry acts as an additional offset to find the
* actual item.
*
+ * Most keys are 16 bytes or less. We use the prefix indexes returned by
+ * a prefix_pool_t instance to uniquely identify the prefix in that case.
+ * Then the combination of prefix index and key stored in the fingerprint
+ * is then unique, too, and can never conflict. No full key construction,
+ * storage and comparison is needed in that case.
+ *
* All access to the cached data needs to be serialized. Because we want
* to scale well despite that bottleneck, we simply segment the cache into
* a number of independent caches (segments). Items will be multiplexed based
@@ -189,6 +197,10 @@
* entries with the same entry key. However unlikely, though, two different
* full keys (see full_key_t) may have the same entry key. That is a
* collision and at most one of them can be stored in the cache at any time.
+ *
+ * If the prefix is shared, which implies that the variable key part is no
+ * longer than 16 bytes, then there is a 1:1 mapping between full key and
+ * entry key.
*/
typedef struct entry_key_t
{
@@ -196,24 +208,182 @@ typedef struct entry_key_t
apr_uint64_t fingerprint[2];
/* Length of the full key. This value is aligned to ITEM_ALIGNMENT to
- * make sure the subsequent item content is properly aligned. */
+ * make sure the subsequent item content is properly aligned. If 0,
+ * PREFIX_KEY is implied to be != NO_INDEX. */
apr_size_t key_len;
+
+ /* Unique index of the shared key prefix, i.e. it's index within the
+ * prefix pool (see prefix_pool_t). NO_INDEX if the key prefix is not
+ * shared, otherwise KEY_LEN==0 is implied. */
+ apr_uint32_t prefix_idx;
} entry_key_t;
/* A full key, i.e. the combination of the cache's key prefix with some
* dynamic part appended to it. It also contains its ENTRY_KEY.
+ *
+ * If the ENTRY_KEY has a 1:1 mapping to the FULL_KEY, then the latter
+ * will be empty and remains unused.
*/
typedef struct full_key_t
{
/* Reduced form identifying the cache entry (if such an entry exists). */
entry_key_t entry_key;
- /* This contains the full combination. Note that the SIZE element may
- * be larger than ENTRY_KEY.KEY_LEN, but only the latter determines the
- * valid key size. */
+ /* If ENTRY_KEY is not a 1:1 mapping of the prefix + dynamic key
+ * combination, then this contains the full combination. Note that the
+ * SIZE element may be larger than ENTRY_KEY.KEY_LEN, but only the latter
+ * determines the valid key size. */
svn_membuf_t full_key;
} full_key_t;
+/* A limited capacity, thread-safe pool of unique C strings. Operations on
+ * this data structure are defined by prefix_pool_* functions. The only
+ * "public" member is VALUES (r/o access only).
+ */
+typedef struct prefix_pool_t
+{
+ /* Map C string to a pointer into VALUES with the same contents. */
+ apr_hash_t *map;
+
+ /* Pointer to an array of strings. These are the contents of this pool
+ * and each one of them is referenced by MAP. Valid indexes are 0 to
+ * VALUES_USED - 1. May be NULL if VALUES_MAX is 0. */
+ const char **values;
+
+ /* Number of used entries that VALUES may have. */
+ apr_uint32_t values_max;
+
+ /* Number of used entries in VALUES. Never exceeds VALUES_MAX. */
+ apr_uint32_t values_used;
+
+ /* Maximum number of bytes to allocate. */
+ apr_size_t bytes_max;
+
+ /* Number of bytes currently allocated. Should not exceed BYTES_MAX but
+ * the implementation may . */
+ apr_size_t bytes_used;
+
+ /* The serialization object. */
+ svn_mutex__t *mutex;
+} prefix_pool_t;
+
+/* Set *PREFIX_POOL to a new instance that tries to limit allocation to
+ * BYTES_MAX bytes. If MUTEX_REQUIRED is set and multi-threading is
+ * supported, serialize all access to the new instance. Allocate the
+ * object from *RESULT_POOL. */
+static svn_error_t *
+prefix_pool_create(prefix_pool_t **prefix_pool,
+ apr_size_t bytes_max,
+ svn_boolean_t mutex_required,
+ apr_pool_t *result_pool)
+{
+ enum
+ {
+ /* With 56 byes of overhead under 64 bits, we will probably never get
+ * substantially below this. If we accidentally do, we will simply
+ * run out of entries in the VALUES array before running out of
+ * allocated memory. */
+ ESTIMATED_BYTES_PER_ENTRY = 120,
+ };
+
+ /* Number of entries we are going to support. */
+ apr_size_t capacity = MIN(APR_UINT32_MAX,
+ bytes_max / ESTIMATED_BYTES_PER_ENTRY);
+
+ /* Construct the result struct. */
+ prefix_pool_t *result = apr_pcalloc(result_pool, sizeof(*result));
+ result->map = svn_hash__make(result_pool);
+
+ result->values = capacity
+ ? apr_pcalloc(result_pool, capacity * sizeof(const char *))
+ : NULL;
+ result->values_max = (apr_uint32_t)capacity;
+ result->values_used = 0;
+
+ result->bytes_max = bytes_max;
+ result->bytes_used = capacity * sizeof(svn_membuf_t);
+
+ SVN_ERR(svn_mutex__init(&result->mutex, mutex_required, result_pool));
+
+ /* Done. */
+ *prefix_pool = result;
+ return SVN_NO_ERROR;
+}
+
+/* Set *PREFIX_IDX to the offset in PREFIX_POOL->VALUES that contains the
+ * value PREFIX. If none exists, auto-insert it. If we can't due to
+ * capacity exhaustion, set *PREFIX_IDX to NO_INDEX.
+ * To be called by prefix_pool_get() only. */
+static svn_error_t *
+prefix_pool_get_internal(apr_uint32_t *prefix_idx,
+ prefix_pool_t *prefix_pool,
+ const char *prefix)
+{
+ enum
+ {
+ /* Size of an hash entry plus (max.) APR alignment loss.
+ *
+ * This may be slightly off if e.g. APR changes its internal data
+ * structures but that will translate in just a few percent (~10%)
+ * over-allocation. Memory consumption will still be capped.
+ */
+ OVERHEAD = 40 + 8
+ };
+
+ const char **value;
+ apr_size_t prefix_len = strlen(prefix);
+ apr_size_t bytes_needed;
+ apr_pool_t *pool;
+
+ /* Lookup. If we already know that prefix, return its index. */
+ value = apr_hash_get(prefix_pool->map, prefix, prefix_len);
+ if (value != NULL)
+ {
+ *prefix_idx = value - prefix_pool->values;
+ return SVN_NO_ERROR;
+ }
+
+ /* Capacity checks. */
+ if (prefix_pool->values_used == prefix_pool->values_max)
+ {
+ *prefix_idx = NO_INDEX;
+ return SVN_NO_ERROR;
+ }
+
+ bytes_needed = prefix_len + 1 + OVERHEAD;
+ if (prefix_pool->bytes_used + bytes_needed > prefix_pool->values_max)
+ {
+ *prefix_idx = NO_INDEX;
+ return SVN_NO_ERROR;
+ }
+
+ /* Add new entry. */
+ pool = apr_hash_pool_get(prefix_pool->map);
+
+ value = &prefix_pool->values[prefix_pool->values_used];
+ *value = apr_pstrndup(pool, prefix, prefix_len + 1);
+ apr_hash_set(prefix_pool->map, *value, prefix_len, value);
+
+ *prefix_idx = prefix_pool->values_used;
+ ++prefix_pool->values_used;
+ prefix_pool->bytes_used += bytes_needed;
+
+ return SVN_NO_ERROR;
+}
+
+/* Thread-safe wrapper around prefix_pool_get_internal. */
+static svn_error_t *
+prefix_pool_get(apr_uint32_t *prefix_idx,
+ prefix_pool_t *prefix_pool,
+ const char *prefix)
+{
+ SVN_MUTEX__WITH_LOCK(prefix_pool->mutex,
+ prefix_pool_get_internal(prefix_idx, prefix_pool,
+ prefix));
+
+ return SVN_NO_ERROR;
+}
+
/* Debugging / corruption detection support.
* If you define this macro, the getter functions will performed expensive
* checks on the item data, requested keys and entry types. If there is
@@ -263,13 +433,12 @@ typedef struct entry_tag_t
/* Initialize all members of TAG except for the content hash.
*/
static svn_error_t *store_key_part(entry_tag_t *tag,
- const full_key_t *prefix_key,
+ const char *prefix,
const void *key,
apr_size_t key_len,
- apr_pool_t *pool)
+ apr_pool_t *scratch_pool)
{
svn_checksum_t *checksum;
- const char *prefix = prefix_key->full_key.data;
apr_size_t prefix_len = strlen(prefix);
if (prefix_len > sizeof(tag->prefix_tail))
@@ -280,12 +449,16 @@ static svn_error_t *store_key_part(entry
SVN_ERR(svn_checksum(&checksum,
svn_checksum_md5,
+ prefix,
+ strlen(prefix),
+ scratch_pool));
+ memcpy(tag->prefix_hash, checksum->digest, sizeof(tag->prefix_hash));
+
+ SVN_ERR(svn_checksum(&checksum,
+ svn_checksum_md5,
key,
key_len,
- pool));
-
- memcpy(tag->prefix_hash, prefix_key->entry_key.fingerprint,
- sizeof(tag->prefix_hash));
+ scratch_pool));
memcpy(tag->key_hash, checksum->digest, sizeof(tag->key_hash));
memset(tag->prefix_tail, 0, sizeof(tag->key_hash));
@@ -346,7 +519,7 @@ static svn_error_t* assert_equal_tags(co
entry_tag_t *tag = &_tag; \
if (key) \
SVN_ERR(store_key_part(tag, \
- &cache->prefix, \
+ get_prefix_key(cache), \
key, \
cache->key_len == APR_HASH_KEY_STRING \
? strlen((const char *) key) \
@@ -521,6 +694,12 @@ struct svn_membuffer_t
and that all segments must / will report the same values here. */
apr_uint32_t segment_count;
+ /* Collection of prefixes shared among all instances accessing the
+ * same membuffer cache backend. If a prefix is contained in this
+ * pool then all cache instances using an equal prefix must actually
+ * use the one stored in this pool. */
+ prefix_pool_t *prefix_pool;
+
/* The dictionary, GROUP_SIZE * (group_count + spare_group_count)
* entries long. Never NULL.
*/
@@ -802,8 +981,8 @@ initialize_group(svn_membuffer_t *cache,
apr_uint32_t first_index =
(group_index / GROUP_INIT_GRANULARITY) * GROUP_INIT_GRANULARITY;
apr_uint32_t last_index = first_index + GROUP_INIT_GRANULARITY;
- if (last_index > cache->group_count)
- last_index = cache->group_count;
+ if (last_index > cache->group_count + cache->spare_group_count)
+ last_index = cache->group_count + cache->spare_group_count;
for (i = first_index; i < last_index; ++i)
{
@@ -1186,6 +1365,7 @@ entry_keys_match(const entry_key_t *lhs,
{
return (lhs->fingerprint[0] == rhs->fingerprint[0])
&& (lhs->fingerprint[1] == rhs->fingerprint[1])
+ && (lhs->prefix_idx == rhs->prefix_idx)
&& (lhs->key_len == rhs->key_len);
}
@@ -1248,7 +1428,8 @@ find_entry(svn_membuffer_t *cache,
/* If we want to preserve it, check that it is actual a match. */
if (!find_empty)
{
- /* If there is no full key to compare, we are done. */
+ /* If the full key is fully defined in prefix_id & mangeled
+ * key, we are done. */
if (!entry->key.key_len)
return entry;
@@ -1347,7 +1528,7 @@ find_entry(svn_membuffer_t *cache,
*/
for (i = 0; i < GROUP_SIZE; ++i)
if (entry != &to_shrink->entries[i])
- let_entry_age(cache, entry);
+ let_entry_age(cache, &to_shrink->entries[i]);
drop_entry(cache, entry);
}
@@ -1675,6 +1856,7 @@ svn_cache__membuffer_cache_create(svn_me
apr_pool_t *pool)
{
svn_membuffer_t *c;
+ prefix_pool_t *prefix_pool;
apr_uint32_t seg;
apr_uint32_t group_count;
@@ -1684,6 +1866,12 @@ svn_cache__membuffer_cache_create(svn_me
apr_uint64_t data_size;
apr_uint64_t max_entry_size;
+ /* Allocate 1% of the cache capacity to the prefix string pool.
+ */
+ SVN_ERR(prefix_pool_create(&prefix_pool, total_size / 100, thread_safe,
+ pool));
+ total_size -= total_size / 100;
+
/* Limit the total size (only relevant if we can address > 4GB)
*/
#if APR_SIZEOF_VOIDP > 4
@@ -1794,14 +1982,18 @@ svn_cache__membuffer_cache_create(svn_me
/* allocate buffers and initialize cache members
*/
c[seg].segment_count = (apr_uint32_t)segment_count;
+ c[seg].prefix_pool = prefix_pool;
c[seg].group_count = main_group_count;
c[seg].spare_group_count = spare_group_count;
c[seg].first_spare_group = NO_INDEX;
c[seg].max_spare_used = 0;
- c[seg].directory = apr_pcalloc(pool,
- group_count * sizeof(entry_group_t));
+ /* Allocate but don't clear / zero the directory because it would add
+ significantly to the server start-up time if the caches are large.
+ Group initialization will take care of that in stead. */
+ c[seg].directory = apr_palloc(pool,
+ group_count * sizeof(entry_group_t));
/* Allocate and initialize directory entries as "not initialized",
hence "unused" */
@@ -2581,11 +2773,11 @@ typedef struct svn_membuffer_cache_t
*/
svn_cache__deserialize_func_t deserializer;
- /* Prepend this byte sequence to any key passed to us.
+ /* Prepend this to any key passed to us.
* This makes our keys different from all keys used by svn_membuffer_cache_t
* instances that we don't want to share cached data with.
*/
- full_key_t prefix;
+ entry_key_t prefix;
/* length of the keys that will be passed to us through the
* svn_cache_t interface. May be APR_HASH_KEY_STRING.
@@ -2604,6 +2796,15 @@ typedef struct svn_membuffer_cache_t
svn_mutex__t *mutex;
} svn_membuffer_cache_t;
+/* Return the prefix key used by CACHE. */
+static const char *
+get_prefix_key(const svn_membuffer_cache_t *cache)
+{
+ return (cache->prefix.prefix_idx == NO_INDEX
+ ? cache->combined_key.full_key.data
+ : cache->membuffer->prefix_pool->values[cache->prefix.prefix_idx]);
+}
+
/* Basically calculate a hash value for KEY of length KEY_LEN, combine it
* with the CACHE->PREFIX and write the result in CACHE->COMBINED_KEY.
* This could replace combine_key() entirely but we actually use it only
@@ -2616,7 +2817,7 @@ combine_long_key(svn_membuffer_cache_t *
{
apr_uint32_t *digest_buffer;
char *key_copy;
- apr_size_t prefix_len = cache->prefix.entry_key.key_len;
+ apr_size_t prefix_len = cache->prefix.key_len;
apr_size_t aligned_key_len;
/* handle variable-length keys */
@@ -2640,9 +2841,9 @@ combine_long_key(svn_membuffer_cache_t *
/* Combine with prefix. */
cache->combined_key.entry_key.fingerprint[0]
- ^= cache->prefix.entry_key.fingerprint[0];
+ ^= cache->prefix.fingerprint[0];
cache->combined_key.entry_key.fingerprint[1]
- ^= cache->prefix.entry_key.fingerprint[1];
+ ^= cache->prefix.fingerprint[1];
}
/* Basically calculate a hash value for KEY of length KEY_LEN, combine it
@@ -2653,47 +2854,55 @@ combine_key(svn_membuffer_cache_t *cache
const void *key,
apr_ssize_t key_len)
{
- /* short, fixed-size keys are the most common case */
- if (key_len != APR_HASH_KEY_STRING && key_len <= 16)
- {
- const apr_size_t prefix_len = cache->prefix.entry_key.key_len;
+ /* copy of *key, padded with 0 */
+ apr_uint64_t data[2];
- /* Copy of *key, padded with 0.
- * We put it just behind the prefix already copied into the COMBINED_KEY.
- * The buffer space has been allocated when the cache was created. */
- apr_uint64_t *data = (void *)((char *)cache->combined_key.full_key.data +
- prefix_len);
- assert(prefix_len <= cache->combined_key.full_key.size - 16);
- cache->combined_key.entry_key.key_len = prefix_len + 16;
+ /* Do we have to compare full keys? */
+ if (cache->prefix.prefix_idx == NO_INDEX)
+ {
+ combine_long_key(cache, key, key_len);
+ return;
+ }
- data[0] = 0;
+ /* short, fixed-size keys are the most common case */
+ if (key_len == 16)
+ {
+ memcpy(data, key, 16);
+ }
+ else if (key_len == 8)
+ {
+ memcpy(data, key, 8);
data[1] = 0;
- memcpy(data, key, key_len);
-
- /* Scramble key DATA to spread the key space more evenly across the
- * cache segments and entry buckets. All of this shall be reversible
- * to prevent key collisions. So, we limit ourselves to xor and
- * permutations.
- *
- * As long as we compare the full combined key, the additional
- * fingerprint collisions introduced by a non-reversible scramble
- * would simply reduce the cache effectiveness.
- */
- data[1] = (data[1] << 27) | (data[1] >> 37);
- data[1] ^= data[0] & 0xffff;
- data[0] ^= data[1] & APR_UINT64_C(0xffffffffffff0000);
-
- /* combine with this cache's namespace */
- cache->combined_key.entry_key.fingerprint[0]
- = data[0] ^ cache->prefix.entry_key.fingerprint[0];
- cache->combined_key.entry_key.fingerprint[1]
- = data[1] ^ cache->prefix.entry_key.fingerprint[1];
}
else
{
- /* longer or variably sized keys */
- combine_long_key(cache, key, key_len);
+ assert(key_len != APR_HASH_KEY_STRING && key_len < 16);
+ data[0] = 0;
+ data[1] = 0;
+ memcpy(data, key, key_len);
}
+
+ /* Scramble key DATA to spread the key space more evenly across the
+ * cache segments and entry buckets. All of this shall be reversible
+ * to prevent key collisions. So, we limit ourselves to xor and
+ * permutations.
+ *
+ * Since the entry key must preserve the full key (prefix and KEY),
+ * the scramble must not introduce KEY collisions.
+ */
+ data[1] = (data[1] << 27) | (data[1] >> 37);
+ data[1] ^= data[0] & 0xffff;
+ data[0] ^= data[1] & APR_UINT64_C(0xffffffffffff0000);
+
+ /* Combine with this cache's prefix. This is reversible because the
+ * prefix is known through to the respective entry_key element. So,
+ * knowing entry_key.prefix_id, we can still reconstruct KEY (and the
+ * prefix key).
+ */
+ cache->combined_key.entry_key.fingerprint[0]
+ = data[0] ^ cache->prefix.fingerprint[0];
+ cache->combined_key.entry_key.fingerprint[1]
+ = data[1] ^ cache->prefix.fingerprint[1];
}
/* Implement svn_cache__vtable_t.get (not thread-safe)
@@ -2940,7 +3149,7 @@ svn_membuffer_cache_get_info(void *cache
/* cache front-end specific data */
- info->id = apr_pstrdup(result_pool, cache->prefix.full_key.data);
+ info->id = apr_pstrdup(result_pool, get_prefix_key(cache));
/* collect info from shared cache back-end */
@@ -3129,6 +3338,7 @@ svn_cache__create_membuffer_cache(svn_ca
const char *prefix,
apr_uint32_t priority,
svn_boolean_t thread_safe,
+ svn_boolean_t short_lived,
apr_pool_t *result_pool,
apr_pool_t *scratch_pool)
{
@@ -3159,28 +3369,50 @@ svn_cache__create_membuffer_cache(svn_ca
prefix_orig_len = strlen(prefix) + 1;
prefix_len = ALIGN_VALUE(prefix_orig_len);
- svn_membuf__create(&cache->prefix.full_key, prefix_len, result_pool);
- memcpy((char *)cache->prefix.full_key.data, prefix, prefix_orig_len);
- memset((char *)cache->prefix.full_key.data + prefix_orig_len, 0,
- prefix_len - prefix_orig_len);
-
/* Construct the folded prefix key. */
SVN_ERR(svn_checksum(&checksum,
svn_checksum_md5,
prefix,
strlen(prefix),
scratch_pool));
- memcpy(cache->prefix.entry_key.fingerprint, checksum->digest,
- sizeof(cache->prefix.entry_key.fingerprint));
- cache->prefix.entry_key.key_len = prefix_len;
-
- /* Initialize the combined key. Pre-allocate some extra room in the full
- * key such that we probably don't need to re-alloc. */
- cache->combined_key.entry_key = cache->prefix.entry_key;
- svn_membuf__create(&cache->combined_key.full_key, prefix_len + 200,
- result_pool);
- memcpy(cache->combined_key.full_key.data, cache->prefix.full_key.data,
- prefix_len);
+ memcpy(cache->prefix.fingerprint, checksum->digest,
+ sizeof(cache->prefix.fingerprint));
+ cache->prefix.key_len = prefix_len;
+
+ /* Fix-length keys of up to 16 bytes may be handled without storing the
+ * full key separately for each item. */
+ if ( (klen != APR_HASH_KEY_STRING)
+ && (klen <= sizeof(cache->combined_key.entry_key.fingerprint))
+ && !short_lived)
+ SVN_ERR(prefix_pool_get(&cache->prefix.prefix_idx,
+ membuffer->prefix_pool,
+ prefix));
+ else
+ cache->prefix.prefix_idx = NO_INDEX;
+
+ /* If key combining is not guaranteed to produce unique results, we have
+ * to handle full keys. Otherwise, leave it NULL. */
+ if (cache->prefix.prefix_idx == NO_INDEX)
+ {
+ /* Initialize the combined key. Pre-allocate some extra room in the
+ * full key such that we probably don't need to re-alloc. */
+ cache->combined_key.entry_key = cache->prefix;
+ svn_membuf__create(&cache->combined_key.full_key, prefix_len + 200,
+ result_pool);
+ memcpy((char *)cache->combined_key.full_key.data, prefix,
+ prefix_orig_len);
+ memset((char *)cache->combined_key.full_key.data + prefix_orig_len, 0,
+ prefix_len - prefix_orig_len);
+ }
+ else
+ {
+ /* Initialize the combined key. We will never have the full combined
+ * key, so leave it NULL and set its length to 0 to prevent access to
+ * it. Keep the fingerprint 0 as well b/c it will always be set anew
+ * by combine_key(). */
+ cache->combined_key.entry_key.prefix_idx = cache->prefix.prefix_idx;
+ cache->combined_key.entry_key.key_len = 0;
+ }
/* initialize the generic cache wrapper
*/
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/compress.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/compress.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/compress.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/compress.c Wed Aug 19 02:35:12 2015
@@ -31,6 +31,21 @@
#include "svn_private_config.h"
+const char *
+svn_zlib__compiled_version(void)
+{
+ static const char zlib_version_str[] = ZLIB_VERSION;
+
+ return zlib_version_str;
+}
+
+const char *
+svn_zlib__runtime_version(void)
+{
+ return zlibVersion();
+}
+
+
/* The zlib compressBound function was not exported until 1.2.0. */
#if ZLIB_VERNUM >= 0x1200
#define svnCompressBound(LEN) compressBound(LEN)
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/deprecated.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/deprecated.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/deprecated.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/deprecated.c Wed Aug 19 02:35:12 2015
@@ -1497,12 +1497,14 @@ svn_auth_get_keychain_ssl_client_cert_pw
#endif /* DARWIN */
#if !defined(WIN32)
+#ifdef SVN_HAVE_GPG_AGENT
void
svn_auth_get_gpg_agent_simple_provider(svn_auth_provider_object_t **provider,
apr_pool_t *pool)
{
svn_auth__get_gpg_agent_simple_provider(provider, pool);
}
+#endif /* SVN_HAVE_GPG_AGENT */
#endif /* !WIN32 */
svn_error_t *
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/io.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/io.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/io.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/io.c Wed Aug 19 02:35:12 2015
@@ -3888,7 +3888,7 @@ svn_io_write_atomic(const char *final_pa
scratch_pool));
}
-#if SVN_ON_POSIX
+#ifdef SVN_ON_POSIX
{
/* On POSIX, the file name is stored in the file's directory entry.
Hence, we need to fsync() that directory as well.
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/mergeinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/mergeinfo.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/mergeinfo.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/mergeinfo.c Wed Aug 19 02:35:12 2015
@@ -2359,7 +2359,7 @@ svn_mergeinfo__catalog_to_formatted_stri
svn_stringbuf_appendcstr(output_buf, "\n");
}
}
-#if SVN_DEBUG
+#ifdef SVN_DEBUG
else if (!catalog)
{
output_buf = svn_stringbuf_create(key_prefix ? key_prefix : "", pool);
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/mutex.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/mutex.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/mutex.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/mutex.c Wed Aug 19 02:35:12 2015
@@ -105,3 +105,13 @@ svn_mutex__unlock(svn_mutex__t *mutex,
return err;
}
+
+#if APR_HAS_THREADS
+
+apr_thread_mutex_t *
+svn_mutex__get(svn_mutex__t *mutex)
+{
+ return mutex->mutex;
+}
+
+#endif
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/stream.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/stream.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/stream.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/stream.c Wed Aug 19 02:35:12 2015
@@ -197,8 +197,12 @@ svn_error_t *
svn_stream_skip(svn_stream_t *stream, apr_size_t len)
{
if (stream->skip_fn == NULL)
- return svn_error_trace(
- skip_default_handler(stream->baton, len, stream->read_full_fn));
+ {
+ svn_read_fn_t read_fn = stream->read_full_fn ? stream->read_full_fn
+ : stream->read_fn;
+ return svn_error_trace(skip_default_handler(stream->baton, len,
+ read_fn));
+ }
return svn_error_trace(stream->skip_fn(stream->baton, len));
}
@@ -938,8 +942,9 @@ static svn_error_t *
data_available_handler_apr(void *baton, svn_boolean_t *data_available)
{
struct baton_apr *btn = baton;
- apr_pollfd_t pfd;
apr_status_t status;
+#if !defined(WIN32) || APR_FILES_AS_SOCKETS
+ apr_pollfd_t pfd;
int n;
pfd.desc_type = APR_POLL_FILE;
@@ -969,6 +974,24 @@ data_available_handler_apr(void *baton,
"failed")),
NULL);
}
+#else
+ HANDLE h;
+ DWORD dwAvail;
+ status = apr_os_file_get(&h, btn->file);
+
+ if (status)
+ return svn_error_wrap_apr(status, NULL);
+
+ if (PeekNamedPipe(h, NULL, 0, NULL, &dwAvail, NULL))
+ {
+ *data_available = (dwAvail > 0);
+ return SVN_NO_ERROR;
+ }
+
+ return svn_error_create(SVN_ERR_STREAM_NOT_SUPPORTED,
+ svn_error_wrap_apr(apr_get_os_error(), NULL),
+ _("Windows doesn't support polling on files"));
+#endif
}
static svn_boolean_t
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/sysinfo.c Wed Aug 19 02:35:12 2015
@@ -45,6 +45,7 @@
#include "svn_version.h"
#include "private/svn_sqlite.h"
+#include "private/svn_subr_private.h"
#include "sysinfo.h"
#include "svn_private_config.h"
@@ -125,7 +126,7 @@ const apr_array_header_t *
svn_sysinfo__linked_libs(apr_pool_t *pool)
{
svn_version_ext_linked_lib_t *lib;
- apr_array_header_t *array = apr_array_make(pool, 3, sizeof(*lib));
+ apr_array_header_t *array = apr_array_make(pool, 5, sizeof(*lib));
lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
lib->name = "APR";
@@ -142,6 +143,11 @@ svn_sysinfo__linked_libs(apr_pool_t *poo
#endif
lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
+ lib->name = "Expat";
+ lib->compiled_version = apr_pstrdup(pool, svn_xml__compiled_version());
+ lib->runtime_version = apr_pstrdup(pool, svn_xml__runtime_version());
+
+ lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
lib->name = "SQLite";
lib->compiled_version = apr_pstrdup(pool, svn_sqlite__compiled_version());
#ifdef SVN_SQLITE_INLINE
@@ -150,6 +156,11 @@ svn_sysinfo__linked_libs(apr_pool_t *poo
lib->runtime_version = apr_pstrdup(pool, svn_sqlite__runtime_version());
#endif
+ lib = &APR_ARRAY_PUSH(array, svn_version_ext_linked_lib_t);
+ lib->name = "ZLib";
+ lib->compiled_version = apr_pstrdup(pool, svn_zlib__compiled_version());
+ lib->runtime_version = apr_pstrdup(pool, svn_zlib__runtime_version());
+
return array;
}
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/temp_serializer.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/temp_serializer.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/temp_serializer.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/temp_serializer.c Wed Aug 19 02:35:12 2015
@@ -366,7 +366,7 @@ svn_temp_serializer__get(svn_temp_serial
* proper pointer value.
*/
void
-svn_temp_deserializer__resolve(void *buffer, void **ptr)
+svn_temp_deserializer__resolve(const void *buffer, void **ptr)
{
/* All pointers are stored as offsets to the buffer start
* (of the respective serialized sub-struct). */
Modified: subversion/branches/patch-exec/subversion/libsvn_subr/xml.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/libsvn_subr/xml.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/libsvn_subr/xml.c (original)
+++ subversion/branches/patch-exec/subversion/libsvn_subr/xml.c Wed Aug 19 02:35:12 2015
@@ -45,6 +45,28 @@
#error Expat is unusable -- it has been compiled for wide characters
#endif
+const char *
+svn_xml__compiled_version(void)
+{
+ static const char xml_version_str[] = APR_STRINGIFY(XML_MAJOR_VERSION)
+ "." APR_STRINGIFY(XML_MINOR_VERSION)
+ "." APR_STRINGIFY(XML_MICRO_VERSION);
+
+ return xml_version_str;
+}
+
+const char *
+svn_xml__runtime_version(void)
+{
+ const char *expat_version = XML_ExpatVersion();
+
+ if (!strncmp(expat_version, "expat_", 6))
+ expat_version += 6;
+
+ return expat_version;
+}
+
+
/* The private internals for a parser object. */
struct svn_xml_parser_t
{
Modified: subversion/branches/patch-exec/subversion/mod_authz_svn/mod_authz_svn.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/mod_authz_svn/mod_authz_svn.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/mod_authz_svn/mod_authz_svn.c (original)
+++ subversion/branches/patch-exec/subversion/mod_authz_svn/mod_authz_svn.c Wed Aug 19 02:35:12 2015
@@ -84,20 +84,18 @@ typedef struct authz_svn_config_rec {
const char *force_username_case;
} authz_svn_config_rec;
-#if AP_MODULE_MAGIC_AT_LEAST(20060110,0) /* version where
- ap_some_auth_required breaks */
-# if AP_MODULE_MAGIC_AT_LEAST(20120211,47) /* first version with
- force_authn hook and
- ap_some_authn_required() which
- allows us to work without
- ap_some_auth_required() */
+/* version where ap_some_auth_required breaks */
+#if AP_MODULE_MAGIC_AT_LEAST(20060110,0)
+/* first version with force_authn hook and ap_some_authn_required()
+ which allows us to work without ap_some_auth_required() */
+# if AP_MODULE_MAGIC_AT_LEAST(20120211,47) || defined(SVN_USE_FORCE_AUTHN)
# define USE_FORCE_AUTHN 1
# define IN_SOME_AUTHN_NOTE "authz_svn-in-some-authn"
# define FORCE_AUTHN_NOTE "authz_svn-force-authn"
# else
/* ap_some_auth_required() is busted and no viable alternative exists */
# ifndef SVN_ALLOW_BROKEN_HTTPD_AUTH
-# error This version of httpd has a security hole with mod_authz_svn
+# error This Apache httpd has broken auth (CVE-2015-3184)
# else
/* user wants to build anyway */
# define USE_FORCE_AUTHN 0
Modified: subversion/branches/patch-exec/subversion/mod_dav_svn/repos.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/mod_dav_svn/repos.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/mod_dav_svn/repos.c (original)
+++ subversion/branches/patch-exec/subversion/mod_dav_svn/repos.c Wed Aug 19 02:35:12 2015
@@ -2067,7 +2067,7 @@ parse_querystring(request_rec *r, const
return dav_svn__convert_err(serr, HTTP_INTERNAL_SERVER_ERROR,
"Couldn't trace history.", pool);
- newpath = apr_hash_get(locations, &working_rev, sizeof(svn_revnum_t));
+ newpath = apr_hash_get(locations, &working_rev, sizeof(working_rev));
if (! newpath)
return dav_svn__new_error(pool, HTTP_NOT_FOUND, 0, 0,
"path doesn't exist in that revision.");
Modified: subversion/branches/patch-exec/subversion/svn/help-cmd.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/svn/help-cmd.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/svn/help-cmd.c (original)
+++ subversion/branches/patch-exec/subversion/svn/help-cmd.c Wed Aug 19 02:35:12 2015
@@ -53,8 +53,9 @@ svn_cl__help(apr_getopt_t *os,
N_("usage: svn <subcommand> [options] [args]\n"
"Subversion command-line client.\n"
"Type 'svn help <subcommand>' for help on a specific subcommand.\n"
- "Type 'svn --version' to see the program version and RA modules\n"
- " or 'svn --version --quiet' to see just the version number.\n"
+ "Type 'svn --version' to see the program version and RA modules,\n"
+ " 'svn --version --verbose' to see dependency versions as well,\n"
+ " 'svn --version --quiet' to see just the version number.\n"
"\n"
"Most subcommands take file and/or directory arguments, recursing\n"
"on the directories. If no arguments are supplied to such a\n"
Modified: subversion/branches/patch-exec/subversion/svnadmin/svnadmin.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/svnadmin/svnadmin.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/svnadmin/svnadmin.c (original)
+++ subversion/branches/patch-exec/subversion/svnadmin/svnadmin.c Wed Aug 19 02:35:12 2015
@@ -166,11 +166,13 @@ static svn_opt_subcommand_t
subcommand_delrevprop,
subcommand_deltify,
subcommand_dump,
+ subcommand_dump_revprops,
subcommand_freeze,
subcommand_help,
subcommand_hotcopy,
subcommand_info,
subcommand_load,
+ subcommand_load_revprops,
subcommand_list_dblogs,
subcommand_list_unused_dblogs,
subcommand_lock,
@@ -392,6 +394,15 @@ static const svn_opt_subcommand_desc2_t
"changed in those revisions.)\n"),
{'r', svnadmin__incremental, svnadmin__deltas, 'q', 'M'} },
+ {"dump-revprops", subcommand_dump_revprops, {0}, N_
+ ("usage: svnadmin dump-revprops REPOS_PATH [-r LOWER[:UPPER]]\n\n"
+ "Dump the revision properties of filesystem to stdout in a 'dumpfile'\n"
+ "portable format, sending feedback to stderr. Dump revisions\n"
+ "LOWER rev through UPPER rev. If no revisions are given, dump the\n"
+ "properties for all revisions. If only LOWER is given, dump the\n"
+ "properties for that one revision.\n"),
+ {'r', 'q'} },
+
{"freeze", subcommand_freeze, {0}, N_
("usage: 1. svnadmin freeze REPOS_PATH PROGRAM [ARG...]\n"
" 2. svnadmin freeze -F FILE PROGRAM [ARG...]\n\n"
@@ -444,6 +455,15 @@ static const svn_opt_subcommand_desc2_t
svnadmin__use_pre_commit_hook, svnadmin__use_post_commit_hook,
svnadmin__parent_dir, svnadmin__bypass_prop_validation, 'M'} },
+ {"load-revprops", subcommand_load_revprops, {0}, N_
+ ("usage: svnadmin load-revprops REPOS_PATH\n\n"
+ "Read a 'dumpfile'-formatted stream from stdin, setting the revision\n"
+ "properties in the repository's filesystem. Revisions not found in the\n"
+ "repository will cause an error. Progress feedback is sent to stdout.\n"
+ "If --revision is specified, limit the loaded revisions to only those\n"
+ "in the dump stream whose revision numbers match the specified range.\n"),
+ {'q', 'r', svnadmin__force_uuid, svnadmin__bypass_prop_validation} },
+
{"lock", subcommand_lock, {0}, N_
("usage: svnadmin lock REPOS_PATH PATH USERNAME COMMENT-FILE [TOKEN]\n\n"
"Lock PATH by USERNAME setting comments from COMMENT-FILE.\n"
@@ -1139,6 +1159,12 @@ repos_notify_handler(void *baton,
}
return;
+ case svn_repos_notify_load_revprop_set:
+ svn_error_clear(svn_stream_printf(feedback_stream, scratch_pool,
+ _("Properties set on revision %ld.\n"),
+ notify->new_revision));
+ return;
+
default:
return;
}
@@ -1184,55 +1210,104 @@ recode_stream_create(FILE *std_stream, a
return rw_stream;
}
-
-/* This implements `svn_opt_subcommand_t'. */
+/* Read the min / max revision from the OPT_STATE, verify them against REPOS
+ and return them in *LOWER and *UPPER, respectively. Use SCRATCH_POOL
+ for temporary allocations. */
static svn_error_t *
-subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+get_dump_range(svn_revnum_t *lower,
+ svn_revnum_t *upper,
+ svn_repos_t *repos,
+ struct svnadmin_opt_state *opt_state,
+ apr_pool_t *scratch_pool)
{
- struct svnadmin_opt_state *opt_state = baton;
- svn_repos_t *repos;
svn_fs_t *fs;
- svn_stream_t *stdout_stream;
- svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
svn_revnum_t youngest;
- svn_stream_t *feedback_stream = NULL;
- /* Expect no more arguments. */
- SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+ *lower = SVN_INVALID_REVNUM;
+ *upper = SVN_INVALID_REVNUM;
- SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
fs = svn_repos_fs(repos);
- SVN_ERR(svn_fs_youngest_rev(&youngest, fs, pool));
+ SVN_ERR(svn_fs_youngest_rev(&youngest, fs, scratch_pool));
/* Find the revision numbers at which to start and end. */
- SVN_ERR(get_revnum(&lower, &opt_state->start_revision,
- youngest, repos, pool));
- SVN_ERR(get_revnum(&upper, &opt_state->end_revision,
- youngest, repos, pool));
+ SVN_ERR(get_revnum(lower, &opt_state->start_revision,
+ youngest, repos, scratch_pool));
+ SVN_ERR(get_revnum(upper, &opt_state->end_revision,
+ youngest, repos, scratch_pool));
/* Fill in implied revisions if necessary. */
- if (lower == SVN_INVALID_REVNUM)
+ if (*lower == SVN_INVALID_REVNUM)
{
- lower = 0;
- upper = youngest;
+ *lower = 0;
+ *upper = youngest;
}
- else if (upper == SVN_INVALID_REVNUM)
+ else if (*upper == SVN_INVALID_REVNUM)
{
- upper = lower;
+ *upper = *lower;
}
- if (lower > upper)
+ if (*lower > *upper)
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("First revision cannot be higher than second"));
+ return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_dump(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_stream_t *stdout_stream;
+ svn_revnum_t lower, upper;
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+ SVN_ERR(get_dump_range(&lower, &upper, repos, opt_state, pool));
+
SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
/* Progress feedback goes to STDERR, unless they asked to suppress it. */
if (! opt_state->quiet)
feedback_stream = recode_stream_create(stderr, pool);
- SVN_ERR(svn_repos_dump_fs3(repos, stdout_stream, lower, upper,
+ SVN_ERR(svn_repos_dump_fs4(repos, stdout_stream, lower, upper,
opt_state->incremental, opt_state->use_deltas,
+ TRUE, TRUE,
+ !opt_state->quiet ? repos_notify_handler : NULL,
+ feedback_stream, check_cancel, NULL, pool));
+
+ return SVN_NO_ERROR;
+}
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_dump_revprops(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_stream_t *stdout_stream;
+ svn_revnum_t lower, upper;
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+ SVN_ERR(get_dump_range(&lower, &upper, repos, opt_state, pool));
+
+ SVN_ERR(svn_stream_for_stdout(&stdout_stream, pool));
+
+ /* Progress feedback goes to STDERR, unless they asked to suppress it. */
+ if (! opt_state->quiet)
+ feedback_stream = recode_stream_create(stderr, pool);
+
+ SVN_ERR(svn_repos_dump_fs4(repos, stdout_stream, lower, upper,
+ FALSE, FALSE, TRUE, FALSE,
!opt_state->quiet ? repos_notify_handler : NULL,
feedback_stream, check_cancel, NULL, pool));
@@ -1374,43 +1449,57 @@ optrev_to_revnum(svn_revnum_t *revnum, c
return SVN_NO_ERROR;
}
-
-/* This implements `svn_opt_subcommand_t'. */
+/* Read the min / max revision from the OPT_STATE, verify them and return
+ them in *LOWER and *UPPER, respectively. */
static svn_error_t *
-subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+get_load_range(svn_revnum_t *lower,
+ svn_revnum_t *upper,
+ struct svnadmin_opt_state *opt_state)
{
- svn_error_t *err;
- struct svnadmin_opt_state *opt_state = baton;
- svn_repos_t *repos;
- svn_revnum_t lower = SVN_INVALID_REVNUM, upper = SVN_INVALID_REVNUM;
- svn_stream_t *stdin_stream;
- svn_stream_t *feedback_stream = NULL;
-
- /* Expect no more arguments. */
- SVN_ERR(parse_args(NULL, os, 0, 0, pool));
-
/* Find the revision numbers at which to start and end. We only
support a limited set of revision kinds: number and unspecified. */
- SVN_ERR(optrev_to_revnum(&lower, &opt_state->start_revision));
- SVN_ERR(optrev_to_revnum(&upper, &opt_state->end_revision));
+ SVN_ERR(optrev_to_revnum(lower, &opt_state->start_revision));
+ SVN_ERR(optrev_to_revnum(upper, &opt_state->end_revision));
/* Fill in implied revisions if necessary. */
- if ((upper == SVN_INVALID_REVNUM) && (lower != SVN_INVALID_REVNUM))
+ if ((*upper == SVN_INVALID_REVNUM) && (*lower != SVN_INVALID_REVNUM))
{
- upper = lower;
+ *upper = *lower;
}
- else if ((upper != SVN_INVALID_REVNUM) && (lower == SVN_INVALID_REVNUM))
+ else if ((*upper != SVN_INVALID_REVNUM) && (*lower == SVN_INVALID_REVNUM))
{
- lower = upper;
+ *lower = *upper;
}
/* Ensure correct range ordering. */
- if (lower > upper)
+ if (*lower > *upper)
{
return svn_error_create(SVN_ERR_CL_ARG_PARSING_ERROR, NULL,
_("First revision cannot be higher than second"));
}
+ return SVN_NO_ERROR;
+}
+
+
+/* This implements `svn_opt_subcommand_t'. */
+static svn_error_t *
+subcommand_load(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ svn_error_t *err;
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_revnum_t lower, upper;
+ svn_stream_t *stdin_stream;
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ /* Find the revision numbers at which to start and end. We only
+ support a limited set of revision kinds: number and unspecified. */
+ SVN_ERR(get_load_range(&lower, &upper, opt_state));
+
SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
/* Read the stream from STDIN. Users can redirect a file. */
@@ -1437,6 +1526,47 @@ subcommand_load(apr_getopt_t *os, void *
return err;
}
+static svn_error_t *
+subcommand_load_revprops(apr_getopt_t *os, void *baton, apr_pool_t *pool)
+{
+ svn_error_t *err;
+ struct svnadmin_opt_state *opt_state = baton;
+ svn_repos_t *repos;
+ svn_revnum_t lower, upper;
+ svn_stream_t *stdin_stream;
+
+ svn_stream_t *feedback_stream = NULL;
+
+ /* Expect no more arguments. */
+ SVN_ERR(parse_args(NULL, os, 0, 0, pool));
+
+ /* Find the revision numbers at which to start and end. We only
+ support a limited set of revision kinds: number and unspecified. */
+ SVN_ERR(get_load_range(&lower, &upper, opt_state));
+
+ SVN_ERR(open_repos(&repos, opt_state->repository_path, pool));
+
+ /* Read the stream from STDIN. Users can redirect a file. */
+ SVN_ERR(svn_stream_for_stdin(&stdin_stream, pool));
+
+ /* Progress feedback goes to STDOUT, unless they asked to suppress it. */
+ if (! opt_state->quiet)
+ feedback_stream = recode_stream_create(stdout, pool);
+
+ err = svn_repos_load_fs_revprops(repos, stdin_stream, lower, upper,
+ !opt_state->bypass_prop_validation,
+ opt_state->ignore_dates,
+ opt_state->quiet ? NULL
+ : repos_notify_handler,
+ feedback_stream, check_cancel, NULL, pool);
+ if (err && err->apr_err == SVN_ERR_BAD_PROPERTY_VALUE)
+ return svn_error_quick_wrap(err,
+ _("Invalid property value found in "
+ "dumpstream; consider repairing the source "
+ "or using --bypass-prop-validation while "
+ "loading."));
+ return err;
+}
/* This implements `svn_opt_subcommand_t'. */
static svn_error_t *
Modified: subversion/branches/patch-exec/subversion/svndumpfilter/svndumpfilter.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/svndumpfilter/svndumpfilter.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/svndumpfilter/svndumpfilter.c (original)
+++ subversion/branches/patch-exec/subversion/svndumpfilter/svndumpfilter.c Wed Aug 19 02:35:12 2015
@@ -640,7 +640,7 @@ new_node_record(void **node_baton,
cf_orig_rev = SVN_STR_TO_REV(val);
cf_renum_val = apr_hash_get(pb->renumber_history,
&cf_orig_rev,
- sizeof(svn_revnum_t));
+ sizeof(cf_orig_rev));
if (! (cf_renum_val && SVN_IS_VALID_REVNUM(cf_renum_val->rev)))
return svn_error_createf
(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
@@ -730,14 +730,14 @@ adjust_mergeinfo(svn_string_t **final_va
svn_merge_range_t *);
revmap_start = apr_hash_get(pb->renumber_history,
- &range->start, sizeof(svn_revnum_t));
+ &range->start, sizeof(range->start));
if (! (revmap_start && SVN_IS_VALID_REVNUM(revmap_start->rev)))
return svn_error_createf
(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
_("No valid revision range 'start' in filtered stream"));
revmap_end = apr_hash_get(pb->renumber_history,
- &range->end, sizeof(svn_revnum_t));
+ &range->end, sizeof(range->end));
if (! (revmap_end && SVN_IS_VALID_REVNUM(revmap_end->rev)))
return svn_error_createf
(SVN_ERR_NODE_UNEXPECTED_KIND, NULL,
Modified: subversion/branches/patch-exec/subversion/svnrdump/load_editor.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/svnrdump/load_editor.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/svnrdump/load_editor.c (original)
+++ subversion/branches/patch-exec/subversion/svnrdump/load_editor.c Wed Aug 19 02:35:12 2015
@@ -167,8 +167,7 @@ set_revision_mapping(apr_hash_t *rev_map
sizeof(svn_revnum_t) * 2);
mapped_revs[0] = from_rev;
mapped_revs[1] = to_rev;
- apr_hash_set(rev_map, mapped_revs,
- sizeof(svn_revnum_t), mapped_revs + 1);
+ apr_hash_set(rev_map, mapped_revs, sizeof(*mapped_revs), mapped_revs + 1);
}
/* Return the revision to which FROM_REV maps in REV_MAP, or
Modified: subversion/branches/patch-exec/subversion/svnserve/svnserve.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/svnserve/svnserve.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/svnserve/svnserve.c (original)
+++ subversion/branches/patch-exec/subversion/svnserve/svnserve.c Wed Aug 19 02:35:12 2015
@@ -211,6 +211,17 @@ void winservice_notify_stop(void)
#define SVNSERVE_OPT_MAX_THREADS 272
#define SVNSERVE_OPT_BLOCK_READ 273
+/* Text macro because we can't use #ifdef sections inside a N_("...")
+ macro expansion. */
+#ifdef CONNECTION_HAVE_THREAD_OPTION
+#define ONLY_AVAILABLE_WITH_THEADS \
+ "\n" \
+ " "\
+ "[used only with --threads]"
+#else
+#define ONLY_AVAILABLE_WITH_THEADS ""
+#endif
+
static const apr_getopt_option_t svnserve__options[] =
{
{"daemon", 'd', 0, N_("daemon mode")},
@@ -317,22 +328,22 @@ static const apr_getopt_option_t svnserv
* ### this option never exists when --service exists. */
{"threads", 'T', 0, N_("use threads instead of fork "
"[mode: daemon]")},
+#endif
+#if APR_HAS_THREADS
{"min-threads", SVNSERVE_OPT_MIN_THREADS, 1,
N_("Minimum number of server threads, even if idle.\n"
" "
"Capped to max-threads; minimum value is 0.\n"
" "
- "Default is 1.\n"
- " "
- "[used only with --threads]")},
+ "Default is 1."
+ ONLY_AVAILABLE_WITH_THEADS)},
{"max-threads", SVNSERVE_OPT_MAX_THREADS, 1,
N_("Maximum number of server threads, even if there\n"
" "
"are more connections. Minimum value is 1.\n"
" "
- "Default is " APR_STRINGIFY(THREADPOOL_MAX_SIZE) ".\n"
- " "
- "[used only with --threads]")},
+ "Default is " APR_STRINGIFY(THREADPOOL_MAX_SIZE) "."
+ ONLY_AVAILABLE_WITH_THEADS)},
#endif
{"foreground", SVNSERVE_OPT_FOREGROUND, 0,
N_("run in foreground (useful for debugging)\n"
Modified: subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout (original)
+++ subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn--help_stdout Wed Aug 19 02:35:12 2015
@@ -1,8 +1,9 @@
usage: svn <subcommand> [options] [args]
Subversion command-line client.
Type 'svn help <subcommand>' for help on a specific subcommand.
-Type 'svn --version' to see the program version and RA modules
- or 'svn --version --quiet' to see just the version number.
+Type 'svn --version' to see the program version and RA modules,
+ 'svn --version --verbose' to see dependency versions as well,
+ 'svn --version --quiet' to see just the version number.
Most subcommands take file and/or directory arguments, recursing
on the directories. If no arguments are supplied to such a
Modified: subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout (original)
+++ subversion/branches/patch-exec/subversion/tests/cmdline/getopt_tests_data/svn_help_stdout Wed Aug 19 02:35:12 2015
@@ -1,8 +1,9 @@
usage: svn <subcommand> [options] [args]
Subversion command-line client.
Type 'svn help <subcommand>' for help on a specific subcommand.
-Type 'svn --version' to see the program version and RA modules
- or 'svn --version --quiet' to see just the version number.
+Type 'svn --version' to see the program version and RA modules,
+ 'svn --version --verbose' to see dependency versions as well,
+ 'svn --version --quiet' to see just the version number.
Most subcommands take file and/or directory arguments, recursing
on the directories. If no arguments are supplied to such a
Modified: subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py (original)
+++ subversion/branches/patch-exec/subversion/tests/cmdline/patch_tests.py Wed Aug 19 02:35:12 2015
@@ -2996,11 +2996,11 @@ def patch_git_empty_files(sbox):
"Index: new\n",
"===================================================================\n",
"diff --git a/new b/new\n",
- "new file mode 10644\n",
+ "new file mode 100644\n",
"Index: iota\n",
"===================================================================\n",
"diff --git a/iota b/iota\n",
- "deleted file mode 10644\n",
+ "deleted file mode 100644\n",
]
svntest.main.file_write(patch_file_path, ''.join(unidiff_patch))
Modified: subversion/branches/patch-exec/subversion/tests/cmdline/svnadmin_tests.py
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/cmdline/svnadmin_tests.py?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/cmdline/svnadmin_tests.py (original)
+++ subversion/branches/patch-exec/subversion/tests/cmdline/svnadmin_tests.py Wed Aug 19 02:35:12 2015
@@ -2743,7 +2743,10 @@ def verify_quickly(sbox):
"verify quickly using metadata"
sbox.build(create_wc = False)
- rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
+ if svntest.main.is_fs_type_fsfs():
+ rev_file = open(fsfs_file(sbox.repo_dir, 'revs', '1'), 'r+b')
+ else:
+ rev_file = open(fsfs_file(sbox.repo_dir, 'revs', 'r1'), 'r+b')
# set new contents
rev_file.seek(8)
Modified: subversion/branches/patch-exec/subversion/tests/cmdline/svntest/verify.py
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/cmdline/svntest/verify.py?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/cmdline/svntest/verify.py (original)
+++ subversion/branches/patch-exec/subversion/tests/cmdline/svntest/verify.py Wed Aug 19 02:35:12 2015
@@ -853,7 +853,7 @@ def make_git_diff_header(target_path, re
if add:
output.extend([
"diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
- "new file mode 10644\n",
+ "new file mode 100644\n",
])
if text_changes:
output.extend([
@@ -863,7 +863,7 @@ def make_git_diff_header(target_path, re
elif delete:
output.extend([
"diff --git a/" + repos_relpath + " b/" + repos_relpath + "\n",
- "deleted file mode 10644\n",
+ "deleted file mode 100644\n",
])
if text_changes:
output.extend([
Modified: subversion/branches/patch-exec/subversion/tests/libsvn_fs/fs-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_fs/fs-test.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/libsvn_fs/fs-test.c (original)
+++ subversion/branches/patch-exec/subversion/tests/libsvn_fs/fs-test.c Wed Aug 19 02:35:12 2015
@@ -5345,20 +5345,20 @@ test_fs_info_format(const svn_test_opts_
int fs_format;
svn_version_t *supports_version;
svn_version_t v1_5_0 = {1, 5, 0, ""};
- svn_version_t v1_9_0 = {1, 9, 0, ""};
+ svn_version_t v1_10_0 = {1, 10, 0, ""};
svn_test_opts_t opts2;
svn_boolean_t is_fsx = strcmp(opts->fs_type, "fsx") == 0;
opts2 = *opts;
- opts2.server_minor_version = is_fsx ? 9 : 5;
+ opts2.server_minor_version = is_fsx ? 10 : 5;
SVN_ERR(svn_test__create_fs(&fs, "test-fs-format-info", &opts2, pool));
SVN_ERR(svn_fs_info_format(&fs_format, &supports_version, fs, pool, pool));
if (is_fsx)
{
- SVN_TEST_ASSERT(fs_format == 1);
- SVN_TEST_ASSERT(svn_ver_equal(supports_version, &v1_9_0));
+ SVN_TEST_ASSERT(fs_format == 2);
+ SVN_TEST_ASSERT(svn_ver_equal(supports_version, &v1_10_0));
}
else
{
Propchange: subversion/branches/patch-exec/subversion/tests/libsvn_fs_x/
('svn:mergeinfo' removed)
Modified: subversion/branches/patch-exec/subversion/tests/libsvn_fs_x/fs-x-pack-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_fs_x/fs-x-pack-test.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/libsvn_fs_x/fs-x-pack-test.c (original)
+++ subversion/branches/patch-exec/subversion/tests/libsvn_fs_x/fs-x-pack-test.c Wed Aug 19 02:35:12 2015
@@ -25,6 +25,7 @@
#include <apr_pools.h>
#include "../svn_test.h"
+#include "../../libsvn_fs_x/batch_fsync.h"
#include "../../libsvn_fs_x/fs.h"
#include "../../libsvn_fs_x/reps.h"
@@ -657,8 +658,8 @@ recover_fully_packed(const svn_test_opts
/* Now, delete the youngest revprop file, and recover again. This
time we want to see an error! */
SVN_ERR(svn_io_remove_file2(
- svn_dirent_join_many(pool, REPO_NAME, PATH_REVPROPS_DIR,
- apr_psprintf(pool, "%ld/%ld",
+ svn_dirent_join_many(pool, REPO_NAME, PATH_REVS_DIR,
+ apr_psprintf(pool, "%ld/p%ld",
after_rev / SHARD_SIZE,
after_rev),
SVN_VA_NULL),
@@ -844,6 +845,93 @@ pack_shard_size_one(const svn_test_opts_
#undef SHARD_SIZE
#undef MAX_REV
/* ------------------------------------------------------------------------ */
+#define REPO_NAME "test-repo-fsx-batch-fsync"
+static svn_error_t *
+test_batch_fsync(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ const char *abspath;
+ svn_fs_x__batch_fsync_t *batch;
+ int i;
+
+ /* Disable this test for non FSX backends because it has no relevance to
+ * them. */
+ if (strcmp(opts->fs_type, "fsx") != 0)
+ return svn_error_create(SVN_ERR_TEST_SKIPPED, NULL,
+ "this will test FSX repositories only");
+
+ /* Create an empty working directory and let it be cleaned up by the test
+ * harness. */
+ SVN_ERR(svn_dirent_get_absolute(&abspath, REPO_NAME, pool));
+
+ SVN_ERR(svn_io_remove_dir2(abspath, TRUE, NULL, NULL, pool));
+ SVN_ERR(svn_io_make_dir_recursively(abspath, pool));
+ svn_test_add_dir_cleanup(abspath);
+
+ /* Initialize infrastructure with a pool that lives as long as this
+ * application. */
+ SVN_ERR(svn_fs_x__batch_fsync_init());
+
+ /* We use and re-use the same batch object throughout this test. */
+ SVN_ERR(svn_fs_x__batch_fsync_create(&batch, pool));
+
+ /* The working directory is new. */
+ SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, abspath, pool));
+
+ /* 1st run: Has to fire up worker threads etc. */
+ for (i = 0; i < 10; ++i)
+ {
+ apr_file_t *file;
+ const char *path = svn_dirent_join(abspath,
+ apr_psprintf(pool, "file%i", i),
+ pool);
+ apr_size_t len = strlen(path);
+
+ SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, pool));
+ SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, path, pool));
+
+ SVN_ERR(svn_io_file_write(file, path, &len, pool));
+ }
+
+ SVN_ERR(svn_fs_x__batch_fsync_run(batch, pool));
+
+ /* 2nd run: Running a batch must leave the container in an empty,
+ * re-usable state. Hence, try to re-use it. */
+ for (i = 0; i < 10; ++i)
+ {
+ apr_file_t *file;
+ const char *path = svn_dirent_join(abspath,
+ apr_psprintf(pool, "new%i", i),
+ pool);
+ apr_size_t len = strlen(path);
+
+ SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, pool));
+ SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, path, pool));
+
+ SVN_ERR(svn_io_file_write(file, path, &len, pool));
+ }
+
+ SVN_ERR(svn_fs_x__batch_fsync_run(batch, pool));
+
+ /* 3rd run: Schedule but don't execute. POOL cleanup shall not fail. */
+ for (i = 0; i < 10; ++i)
+ {
+ apr_file_t *file;
+ const char *path = svn_dirent_join(abspath,
+ apr_psprintf(pool, "another%i", i),
+ pool);
+ apr_size_t len = strlen(path);
+
+ SVN_ERR(svn_fs_x__batch_fsync_open_file(&file, batch, path, pool));
+ SVN_ERR(svn_fs_x__batch_fsync_new_path(batch, path, pool));
+
+ SVN_ERR(svn_io_file_write(file, path, &len, pool));
+ }
+
+ return SVN_NO_ERROR;
+}
+#undef REPO_NAME
+/* ------------------------------------------------------------------------ */
/* The test table. */
@@ -876,6 +964,8 @@ static struct svn_test_descriptor_t test
"test representations container"),
SVN_TEST_OPTS_PASS(pack_shard_size_one,
"test packing with shard size = 1"),
+ SVN_TEST_OPTS_PASS(test_batch_fsync,
+ "test batch fsync"),
SVN_TEST_NULL
};
Modified: subversion/branches/patch-exec/subversion/tests/libsvn_ra/ra-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_ra/ra-test.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/libsvn_ra/ra-test.c (original)
+++ subversion/branches/patch-exec/subversion/tests/libsvn_ra/ra-test.c Wed Aug 19 02:35:12 2015
@@ -332,15 +332,16 @@ static svn_error_t *
check_tunnel_callback_test(const svn_test_opts_t *opts,
apr_pool_t *pool)
{
- tunnel_baton_t b = { TUNNEL_MAGIC };
+ tunnel_baton_t *b = apr_pcalloc(pool, sizeof(*b));
svn_ra_callbacks2_t *cbtable;
svn_ra_session_t *session;
- svn_error_t *err;
+
+ b->magic = TUNNEL_MAGIC;
SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
cbtable->check_tunnel_func = check_tunnel;
cbtable->open_tunnel_func = open_tunnel;
- cbtable->tunnel_baton = &b;
+ cbtable->tunnel_baton = b;
SVN_ERR(svn_cmdline_create_auth_baton2(&cbtable->auth_baton,
TRUE /* non_interactive */,
"jrandom", "rayjandom",
@@ -350,12 +351,12 @@ check_tunnel_callback_test(const svn_tes
FALSE, FALSE, FALSE, FALSE,
NULL, NULL, NULL, pool));
- b.last_check = TRUE;
- err = svn_ra_open4(&session, NULL, "svn+foo://localhost/no-repo",
- NULL, cbtable, NULL, NULL, pool);
- svn_error_clear(err);
- SVN_TEST_ASSERT(err);
- SVN_TEST_ASSERT(!b.last_check);
+ b->last_check = TRUE;
+ SVN_TEST_ASSERT_ERROR(svn_ra_open4(&session, NULL,
+ "svn+foo://localhost/no-repo",
+ NULL, cbtable, NULL, NULL, pool),
+ SVN_ERR_RA_CANNOT_CREATE_SESSION);
+ SVN_TEST_ASSERT(!b->last_check);
return SVN_NO_ERROR;
}
@@ -363,14 +364,15 @@ static svn_error_t *
tunnel_callback_test(const svn_test_opts_t *opts,
apr_pool_t *pool)
{
- tunnel_baton_t b = { TUNNEL_MAGIC };
+ tunnel_baton_t *b = apr_pcalloc(pool, sizeof(*b));
apr_pool_t *scratch_pool = svn_pool_create(pool);
const char *url;
svn_ra_callbacks2_t *cbtable;
svn_ra_session_t *session;
- svn_error_t *err;
const char tunnel_repos_name[] = "test-repo-tunnel";
+ b->magic = TUNNEL_MAGIC;
+
SVN_ERR(svn_test__create_repos(NULL, tunnel_repos_name, opts, scratch_pool));
/* Immediately close the repository to avoid race condition with svnserve
@@ -382,7 +384,7 @@ tunnel_callback_test(const svn_test_opts
SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
cbtable->check_tunnel_func = check_tunnel;
cbtable->open_tunnel_func = open_tunnel;
- cbtable->tunnel_baton = &b;
+ cbtable->tunnel_baton = b;
SVN_ERR(svn_cmdline_create_auth_baton2(&cbtable->auth_baton,
TRUE /* non_interactive */,
"jrandom", "rayjandom",
@@ -392,20 +394,13 @@ tunnel_callback_test(const svn_test_opts
FALSE, FALSE, FALSE, FALSE,
NULL, NULL, NULL, pool));
- b.last_check = FALSE;
- err = svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL,
- scratch_pool);
- if (err && err->apr_err == SVN_ERR_TEST_FAILED)
- {
- svn_handle_error2(err, stderr, FALSE, "svn_tests: ");
- svn_error_clear(err);
- return SVN_NO_ERROR;
- }
- SVN_ERR(err);
- SVN_TEST_ASSERT(b.last_check);
- SVN_TEST_ASSERT(b.open_count > 0);
+ b->last_check = FALSE;
+ SVN_ERR(svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL,
+ scratch_pool));
+ SVN_TEST_ASSERT(b->last_check);
+ SVN_TEST_ASSERT(b->open_count > 0);
svn_pool_destroy(scratch_pool);
- SVN_TEST_ASSERT(b.open_count == 0);
+ SVN_TEST_ASSERT(b->open_count == 0);
return SVN_NO_ERROR;
}
@@ -1517,6 +1512,66 @@ ra_list_has_props(const svn_test_opts_t
return SVN_NO_ERROR;
}
+/* Test ra_svn tunnel editor handling, including polling. */
+
+static svn_error_t *
+tunnel_run_checkout(const svn_test_opts_t *opts,
+ apr_pool_t *pool)
+{
+ tunnel_baton_t *b = apr_pcalloc(pool, sizeof(*b));
+ apr_pool_t *scratch_pool = svn_pool_create(pool);
+ const char *url;
+ svn_ra_callbacks2_t *cbtable;
+ svn_ra_session_t *session;
+ const char tunnel_repos_name[] = "test-run_checkout";
+ svn_ra_reporter3_t *reporter;
+ void *report_baton;
+
+ b->magic = TUNNEL_MAGIC;
+
+ SVN_ERR(svn_test__create_repos(NULL, tunnel_repos_name, opts, scratch_pool));
+
+ /* Immediately close the repository to avoid race condition with svnserve
+ (and then the cleanup code) with BDB when our pool is cleared. */
+ svn_pool_clear(scratch_pool);
+
+ url = apr_pstrcat(pool, "svn+test://localhost/", tunnel_repos_name,
+ SVN_VA_NULL);
+ SVN_ERR(svn_ra_create_callbacks(&cbtable, pool));
+ cbtable->check_tunnel_func = check_tunnel;
+ cbtable->open_tunnel_func = open_tunnel;
+ cbtable->tunnel_baton = b;
+ SVN_ERR(svn_cmdline_create_auth_baton2(&cbtable->auth_baton,
+ TRUE /* non_interactive */,
+ "jrandom", "rayjandom",
+ NULL,
+ TRUE /* no_auth_cache */,
+ FALSE /* trust_server_cert */,
+ FALSE, FALSE, FALSE, FALSE,
+ NULL, NULL, NULL, pool));
+
+ b->last_check = FALSE;
+
+ SVN_ERR(svn_ra_open4(&session, NULL, url, NULL, cbtable, NULL, NULL,
+ scratch_pool));
+
+ SVN_ERR(commit_changes(session, pool));
+
+ SVN_ERR(svn_ra_do_update3(session,
+ &reporter, &report_baton,
+ 1, "",
+ svn_depth_infinity, FALSE, FALSE,
+ svn_delta_default_editor(pool), NULL,
+ pool, pool));
+
+ SVN_ERR(reporter->set_path(report_baton, "", 0, svn_depth_infinity, FALSE,
+ NULL, pool));
+
+ SVN_ERR(reporter->finish_report(report_baton, pool));
+
+ return SVN_NO_ERROR;
+}
+
/* The test table. */
@@ -1547,6 +1602,8 @@ static struct svn_test_descriptor_t test
"check how ra layers handle errors from callbacks"),
SVN_TEST_OPTS_PASS(ra_list_has_props,
"check list has_props performance"),
+ SVN_TEST_OPTS_PASS(tunnel_run_checkout,
+ "verify checkout over a tunnel"),
SVN_TEST_NULL
};
Modified: subversion/branches/patch-exec/subversion/tests/libsvn_repos/dump-load-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_repos/dump-load-test.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/libsvn_repos/dump-load-test.c (original)
+++ subversion/branches/patch-exec/subversion/tests/libsvn_repos/dump-load-test.c Wed Aug 19 02:35:12 2015
@@ -76,8 +76,8 @@ test_dump_bad_props(svn_stringbuf_t **du
SVN_TEST_ASSERT(SVN_IS_VALID_REVNUM(youngest_rev));
/* Test that a dump completes without error. */
- SVN_ERR(svn_repos_dump_fs3(repos, stream, start_rev, end_rev,
- FALSE, FALSE,
+ SVN_ERR(svn_repos_dump_fs4(repos, stream, start_rev, end_rev,
+ FALSE, FALSE, TRUE, TRUE,
notify_func, notify_baton,
NULL, NULL,
pool));
Modified: subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c (original)
+++ subversion/branches/patch-exec/subversion/tests/libsvn_repos/repos-test.c Wed Aug 19 02:35:12 2015
@@ -750,8 +750,7 @@ check_locations_info(apr_hash_t *locatio
unsigned int i;
for (i = 0; info->rev != 0; ++i, ++info)
{
- const char *p = apr_hash_get(locations, &info->rev, sizeof
- (svn_revnum_t));
+ const char *p = apr_hash_get(locations, &info->rev, sizeof(info->rev));
if (!p)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
"Missing path for revision %ld", info->rev);
@@ -2999,7 +2998,7 @@ file_rev_handler(void *baton, const char
{
apr_hash_t *ht = baton;
const char *author;
- file_revs_t *file_rev = apr_hash_get(ht, &rev, sizeof(svn_revnum_t));
+ file_revs_t *file_rev = apr_hash_get(ht, &rev, sizeof(rev));
if (!file_rev)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
@@ -3017,7 +3016,7 @@ file_rev_handler(void *baton, const char
/* Remove this revision from this list so we'll be able to verify that we
have seen all expected revisions. */
- apr_hash_set(ht, &rev, sizeof(svn_revnum_t), NULL);
+ apr_hash_set(ht, &rev, sizeof(rev), NULL);
return SVN_NO_ERROR;
}
@@ -3055,16 +3054,16 @@ test_get_file_revs(const svn_test_opts_t
for (i = 0; i < sizeof(trunk_results) / sizeof(trunk_results[0]); i++)
apr_hash_set(ht_trunk_results, &trunk_results[i].rev,
- sizeof(svn_revnum_t), &trunk_results[i]);
+ sizeof(trunk_results[i].rev), &trunk_results[i]);
for (i = 0; i < sizeof(branch_results) / sizeof(branch_results[0]); i++)
apr_hash_set(ht_branch_results, &branch_results[i].rev,
- sizeof(svn_revnum_t), &branch_results[i]);
+ sizeof(branch_results[i].rev), &branch_results[i]);
for (i = 0; i < sizeof(trunk_results) / sizeof(trunk_results[0]); i++)
if (!trunk_results[i].result_of_merge)
apr_hash_set(ht_reverse_results, &trunk_results[i].rev,
- sizeof(svn_revnum_t), &trunk_results[i]);
+ sizeof(trunk_results[i].rev), &trunk_results[i]);
/* Check for feature support */
if (opts->server_minor_version && (opts->server_minor_version < 5))
@@ -3680,7 +3679,7 @@ verify_locations(apr_hash_t *actual,
for (hi = apr_hash_first(pool, expected); hi; hi = apr_hash_next(hi))
{
const svn_revnum_t *rev = apr_hash_this_key(hi);
- const char *path = apr_hash_get(actual, rev, sizeof(svn_revnum_t));
+ const char *path = apr_hash_get(actual, rev, sizeof(*rev));
if (!path)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
@@ -3696,7 +3695,7 @@ verify_locations(apr_hash_t *actual,
for (hi = apr_hash_first(pool, actual); hi; hi = apr_hash_next(hi))
{
const svn_revnum_t *rev = apr_hash_this_key(hi);
- const char *path = apr_hash_get(expected, rev, sizeof(svn_revnum_t));
+ const char *path = apr_hash_get(expected, rev, sizeof(*rev));
if (!path)
return svn_error_createf(SVN_ERR_TEST_FAILED, NULL,
@@ -3723,7 +3722,7 @@ set_expected(apr_hash_t *expected,
{
svn_revnum_t *rp = apr_palloc(pool, sizeof(svn_revnum_t));
*rp = rev;
- apr_hash_set(expected, rp, sizeof(svn_revnum_t), path);
+ apr_hash_set(expected, rp, sizeof(*rp), path);
}
static svn_error_t *
Modified: subversion/branches/patch-exec/subversion/tests/libsvn_subr/cache-test.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/subversion/tests/libsvn_subr/cache-test.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/subversion/tests/libsvn_subr/cache-test.c (original)
+++ subversion/branches/patch-exec/subversion/tests/libsvn_subr/cache-test.c Wed Aug 19 02:35:12 2015
@@ -221,6 +221,7 @@ test_membuffer_cache_basic(apr_pool_t *p
"cache:",
SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
FALSE,
+ FALSE,
pool, pool));
return basic_cache_test(cache, FALSE, pool);
@@ -278,6 +279,7 @@ test_membuffer_serializer_error_handling
"cache:",
SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
FALSE,
+ FALSE,
pool, pool));
SVN_ERR(svn_cache__set(cache, "twenty", &twenty, pool));
@@ -307,6 +309,7 @@ test_membuffer_serializer_error_handling
"cache:",
SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
FALSE,
+ FALSE,
pool, pool));
/* Store one entry in cache. */
@@ -393,6 +396,7 @@ test_membuffer_cache_clearing(apr_pool_t
"cache:",
SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY,
FALSE,
+ FALSE,
pool, pool));
/* Initially, the cache is empty. */
@@ -440,6 +444,51 @@ test_membuffer_cache_clearing(apr_pool_t
return SVN_NO_ERROR;
}
+/* Implements svn_iter_apr_hash_cb_t. */
+static svn_error_t *
+null_cache_iter_func(void *baton,
+ const void *key,
+ apr_ssize_t klen,
+ void *val,
+ apr_pool_t *pool)
+{
+ /* shall never be called */
+ return svn_error_create(SVN_ERR_TEST_FAILED, NULL, "should not be called");
+}
+
+static svn_error_t *
+test_null_cache(apr_pool_t *pool)
+{
+ svn_boolean_t found, done;
+ int *data = NULL;
+ svn_cache__info_t info;
+
+ svn_cache__t *cache;
+ SVN_ERR(svn_cache__create_null(&cache, "test-dummy", pool));
+
+ /* Can't cache anything. */
+ SVN_TEST_ASSERT(svn_cache__is_cachable(cache, 0) == FALSE);
+ SVN_TEST_ASSERT(svn_cache__is_cachable(cache, 1) == FALSE);
+
+ /* No point in adding data. */
+ SVN_ERR(svn_cache__set(cache, "data", &data, pool));
+ SVN_ERR(svn_cache__get((void **)&data, &found, cache, "data", pool));
+ SVN_TEST_ASSERT(found == FALSE);
+
+ SVN_ERR(svn_cache__has_key(&found, cache, "data", pool));
+ SVN_TEST_ASSERT(found == FALSE);
+
+ /* Iteration "works" but is a no-op. */
+ SVN_ERR(svn_cache__iter(&done, cache, null_cache_iter_func, NULL, pool));
+ SVN_TEST_ASSERT(done);
+
+ /* It shall know its name. */
+ SVN_ERR(svn_cache__get_info(cache, &info, TRUE, pool));
+ SVN_TEST_STRING_ASSERT(info.id, "test-dummy");
+
+ return SVN_NO_ERROR;
+}
+
static svn_error_t *
test_membuffer_unaligned_string_keys(apr_pool_t *pool)
{
@@ -462,7 +511,7 @@ test_membuffer_unaligned_string_keys(apr
SVN_ERR(svn_cache__create_membuffer_cache(
&cache, membuffer, serialize_revnum, deserialize_revnum,
APR_HASH_KEY_STRING, unaligned_prefix,
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY, FALSE,
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY, FALSE, FALSE,
pool, pool));
SVN_ERR(svn_cache__set(cache, unaligned_key, &fifty, pool));
@@ -513,7 +562,7 @@ test_membuffer_unaligned_fixed_keys(apr_
&cache, membuffer, serialize_revnum, deserialize_revnum,
8 /* klen*/,
unaligned_prefix,
- SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY, FALSE,
+ SVN_CACHE__MEMBUFFER_DEFAULT_PRIORITY, FALSE, FALSE,
pool, pool));
SVN_ERR(svn_cache__set(cache, unaligned_key, &fifty, pool));
@@ -541,6 +590,7 @@ test_membuffer_unaligned_fixed_keys(apr_
return SVN_NO_ERROR;
}
+
/* The test table. */
static int max_threads = 1;
@@ -560,6 +610,8 @@ static struct svn_test_descriptor_t test
"test for error handling in membuffer svn_cache"),
SVN_TEST_PASS2(test_membuffer_cache_clearing,
"test clearing a membuffer svn_cache"),
+ SVN_TEST_PASS2(test_null_cache,
+ "basic null svn_cache test"),
SVN_TEST_PASS2(test_membuffer_unaligned_string_keys,
"test membuffer cache with unaligned string keys"),
SVN_TEST_PASS2(test_membuffer_unaligned_fixed_keys,
Modified: subversion/branches/patch-exec/tools/buildbot/slaves/svn-sparc-solaris/svncheck.sh
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/tools/buildbot/slaves/svn-sparc-solaris/svncheck.sh?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/tools/buildbot/slaves/svn-sparc-solaris/svncheck.sh (original)
+++ subversion/branches/patch-exec/tools/buildbot/slaves/svn-sparc-solaris/svncheck.sh Wed Aug 19 02:35:12 2015
@@ -28,7 +28,7 @@ cd ../obj
LD_PRELOAD_64=/export/home/wandisco/buildbot/install/lib/preloadable_libiconv.so
export LD_PRELOAD_64
-if [ $SVN_VER_MINOR -eq 9 ]; then
+if [ $SVN_VER_MINOR -ge 9 ]; then
echo "============ make svnserveautocheck"
make svnserveautocheck CLEANUP=1 PARALLEL=30 THREADED=1 || exit $?
else
Modified: subversion/branches/patch-exec/tools/client-side/bash_completion
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/tools/client-side/bash_completion?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/tools/client-side/bash_completion (original)
+++ subversion/branches/patch-exec/tools/client-side/bash_completion Wed Aug 19 02:35:12 2015
@@ -423,6 +423,7 @@ _svn()
else
# show schemas
COMPREPLY=( $(compgen -W "$urlSchemas" -- $cur) )
+ compopt -o nospace
return
fi
fi
@@ -440,10 +441,12 @@ _svn()
elif [[ "$here" == */trunk* ]] ; then
# we guess that it is a merge from a branch
COMPREPLY=( $(compgen -W ${here/\/trunk*/\/branches\/} -- $cur ) )
+ compopt -o nospace
return 0
else
# no se, let us suggest the repository root...
- COMPREPLY=( $(compgen -W $(_svn_info Root) -- $cur ) )
+ COMPREPLY=( $(compgen -W $(_svn_info Root)/ -- $cur ) )
+ compopt -o nospace
return 0
fi
elif [[ $URL == */branches/* && $here == */trunk* && \
Modified: subversion/branches/patch-exec/tools/dev/fsfs-access-map.c
URL: http://svn.apache.org/viewvc/subversion/branches/patch-exec/tools/dev/fsfs-access-map.c?rev=1696514&r1=1696513&r2=1696514&view=diff
==============================================================================
--- subversion/branches/patch-exec/tools/dev/fsfs-access-map.c (original)
+++ subversion/branches/patch-exec/tools/dev/fsfs-access-map.c Wed Aug 19 02:35:12 2015
@@ -225,7 +225,7 @@ open_file(const char *name, int handle)
*key = handle;
handle_info = apr_pcalloc(pool, sizeof(*handle_info));
- apr_hash_set(handles, key, sizeof(handle), handle_info);
+ apr_hash_set(handles, key, sizeof(*key), handle_info);
}
/* link handle to file */