New upstream version 2022.7
This commit is contained in:
commit
0a29322640
82 files changed
+2820
-2348
No files matched your search
+7
-9
@@ -172,17 +172,9 @@ if test -n "${ASAN_OPTIONS:-}"; then
|
||||
BUILT_WITH_ASAN=1
|
||||
fi
|
||||
|
||||
CMD_PREFIX=""
|
||||
if test -n "${OT_TESTS_VALGRIND:-}"; then
|
||||
CMD_PREFIX="env G_SLICE=always-malloc OSTREE_SUPPRESS_SYNCFS=1 valgrind -q --error-exitcode=1 --leak-check=full --num-callers=30 --suppressions=${test_srcdir}/glib.supp --suppressions=${test_srcdir}/ostree.supp"
|
||||
else
|
||||
# In some cases the LD_PRELOAD may cause obscure problems,
|
||||
# e.g. right now it breaks for me with -fsanitize=address, so
|
||||
# let's allow users to skip it.
|
||||
if test -z "${OT_SKIP_READDIR_RAND:-}" && test -z "${BUILT_WITH_ASAN:-}"; then
|
||||
CMD_PREFIX="env LD_PRELOAD=${test_builddir}/libreaddir-rand.so"
|
||||
else
|
||||
CMD_PREFIX=""
|
||||
fi
|
||||
fi
|
||||
|
||||
if test -n "${OSTREE_UNINSTALLED:-}"; then
|
||||
@@ -622,6 +614,12 @@ skip_without_user_xattrs () {
|
||||
fi
|
||||
}
|
||||
|
||||
skip_without_sudo () {
|
||||
if test -z "${OSTREE_TEST_SUDO:-}"; then
|
||||
skip "this test needs sudo, skipping without OSTREE_TEST_SUDO being set"
|
||||
fi
|
||||
}
|
||||
|
||||
# Usage: if ! skip_one_without_whiteouts_devices; then ... more tests ...; fi
|
||||
skip_one_without_whiteouts_devices() {
|
||||
if ! can_create_whiteout_devices; then
|
||||
|
||||
@@ -1,208 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Colin Walters <walters@verbum.org>.
|
||||
*
|
||||
* SPDX-License-Identifier: LGPL-2.0+
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <glib.h>
|
||||
|
||||
/* Glibc uses readdir64 when _FILE_OFFSET_BITS == 64 as set by
|
||||
* AC_SYS_LARGEFILE on 32 bit systems.
|
||||
*/
|
||||
#if defined(_FILE_OFFSET_BITS) && (_FILE_OFFSET_BITS == 64)
|
||||
# define READDIR "readdir64"
|
||||
# define READDIR_R "readdir64_r"
|
||||
#else
|
||||
# define READDIR "readdir"
|
||||
# define READDIR_R "readdir_r"
|
||||
#endif
|
||||
|
||||
static GHashTable *direntcache;
|
||||
static GMutex direntcache_lock;
|
||||
static gsize initialized;
|
||||
|
||||
typedef struct {
|
||||
GPtrArray *entries;
|
||||
guint offset;
|
||||
} DirEntries;
|
||||
|
||||
static void
|
||||
dir_entries_free (gpointer data)
|
||||
{
|
||||
DirEntries *d = data;
|
||||
g_ptr_array_unref (d->entries);
|
||||
g_free (d);
|
||||
}
|
||||
|
||||
static DirEntries *
|
||||
dir_entries_new (void)
|
||||
{
|
||||
DirEntries *d = g_new0 (DirEntries, 1);
|
||||
d->entries = g_ptr_array_new_with_free_func (g_free);
|
||||
return d;
|
||||
}
|
||||
|
||||
static void
|
||||
ensure_initialized (void)
|
||||
{
|
||||
if (g_once_init_enter (&initialized))
|
||||
{
|
||||
direntcache = g_hash_table_new_full (NULL, NULL, NULL, dir_entries_free);
|
||||
g_mutex_init (&direntcache_lock);
|
||||
g_once_init_leave (&initialized, 1);
|
||||
}
|
||||
}
|
||||
|
||||
struct dirent *
|
||||
readdir (DIR *dirp)
|
||||
{
|
||||
struct dirent *(*real_readdir)(DIR *dirp) = dlsym (RTLD_NEXT, READDIR);
|
||||
struct dirent *ret;
|
||||
gboolean cache_another = TRUE;
|
||||
|
||||
ensure_initialized ();
|
||||
|
||||
/* The core idea here is that each time through the loop, we read a
|
||||
* directory entry. If there is one, we choose whether to cache it
|
||||
* or to return it. Because multiple entries can be cached,
|
||||
* ordering is randomized. Statistically, the order will still be
|
||||
* *weighted* towards the ordering returned from the
|
||||
* kernel/filesystem, but the goal here is just to provide some
|
||||
* randomness in order to trigger bugs, not to be perfectly random.
|
||||
*/
|
||||
while (cache_another)
|
||||
{
|
||||
DirEntries *de;
|
||||
|
||||
errno = 0;
|
||||
ret = real_readdir (dirp);
|
||||
if (ret == NULL && errno != 0)
|
||||
goto out;
|
||||
|
||||
g_mutex_lock (&direntcache_lock);
|
||||
de = g_hash_table_lookup (direntcache, dirp);
|
||||
if (ret)
|
||||
{
|
||||
if (g_random_boolean ())
|
||||
{
|
||||
struct dirent *copy;
|
||||
if (!de)
|
||||
{
|
||||
de = dir_entries_new ();
|
||||
g_hash_table_insert (direntcache, dirp, de);
|
||||
}
|
||||
copy = g_memdup (ret, sizeof (struct dirent));
|
||||
g_ptr_array_add (de->entries, copy);
|
||||
}
|
||||
else
|
||||
{
|
||||
cache_another = FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (de && de->offset < de->entries->len)
|
||||
{
|
||||
ret = de->entries->pdata[de->offset];
|
||||
de->offset++;
|
||||
}
|
||||
cache_another = FALSE;
|
||||
}
|
||||
g_mutex_unlock (&direntcache_lock);
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
closedir (DIR *dirp)
|
||||
{
|
||||
int (*real_closedir)(DIR *dirp) = dlsym (RTLD_NEXT, "closedir");
|
||||
|
||||
ensure_initialized ();
|
||||
|
||||
g_mutex_lock (&direntcache_lock);
|
||||
g_hash_table_remove (direntcache, dirp);
|
||||
g_mutex_unlock (&direntcache_lock);
|
||||
|
||||
return real_closedir (dirp);
|
||||
}
|
||||
|
||||
static void
|
||||
assert_no_cached_entries (DIR *dirp)
|
||||
{
|
||||
DirEntries *de;
|
||||
g_mutex_lock (&direntcache_lock);
|
||||
de = g_hash_table_lookup (direntcache, dirp);
|
||||
g_assert (!de || de->entries->len == 0);
|
||||
g_mutex_unlock (&direntcache_lock);
|
||||
}
|
||||
|
||||
void
|
||||
seekdir (DIR *dirp, long loc)
|
||||
{
|
||||
void (*real_seekdir)(DIR *dirp, long loc) = dlsym (RTLD_NEXT, "seekdir");
|
||||
|
||||
ensure_initialized ();
|
||||
|
||||
/* For now, crash if seekdir is called when we have cached entries.
|
||||
* If some app wants to use this and seekdir() we can implement it.
|
||||
*/
|
||||
assert_no_cached_entries (dirp);
|
||||
|
||||
real_seekdir (dirp, loc);
|
||||
}
|
||||
|
||||
void
|
||||
rewinddir (DIR *dirp)
|
||||
{
|
||||
void (*real_rewinddir)(DIR *dirp) = dlsym (RTLD_NEXT, "rewinddir");
|
||||
|
||||
ensure_initialized ();
|
||||
|
||||
/* Blow away the cache */
|
||||
g_mutex_lock (&direntcache_lock);
|
||||
g_hash_table_remove (direntcache, dirp);
|
||||
g_mutex_unlock (&direntcache_lock);
|
||||
|
||||
real_rewinddir (dirp);
|
||||
}
|
||||
|
||||
int
|
||||
readdir_r (DIR *dirp, struct dirent *entry, struct dirent **result)
|
||||
{
|
||||
int (*real_readdir_r)(DIR *dirp, struct dirent *entry, struct dirent **result) = dlsym (RTLD_NEXT, READDIR_R);
|
||||
|
||||
ensure_initialized ();
|
||||
|
||||
/* For now, assert that no one is mixing readdir_r() with readdir().
|
||||
* It'd be broken to do so, and very few programs use readdir_r()
|
||||
* anyways. */
|
||||
assert_no_cached_entries (dirp);
|
||||
|
||||
return real_readdir_r (dirp, entry, result);
|
||||
}
|
||||
@@ -9,7 +9,9 @@ set -euo pipefail
|
||||
mode="bare-split-xattrs"
|
||||
OSTREE="${CMD_PREFIX} ostree --repo=${test_tmpdir}/repo"
|
||||
|
||||
skip_without_sudo
|
||||
SUDO="sudo --non-interactive"
|
||||
|
||||
PRIVILEGED="false"
|
||||
if [ $(id -u) -eq 0 ]; then
|
||||
PRIVILEGED="true"
|
||||
|
||||
@@ -41,7 +41,7 @@ corrupt (GBytes *input)
|
||||
const guint8 *buf = g_bytes_get_data (input, &len);
|
||||
g_assert_cmpint (len, >, 0);
|
||||
g_assert_cmpint (len, <, G_MAXINT);
|
||||
g_autofree char *newbuf = g_memdup (buf, len);
|
||||
g_autofree char *newbuf = g_memdup2 (buf, len);
|
||||
g_assert (newbuf != NULL);
|
||||
int o = g_random_int_range (0, len);
|
||||
newbuf[o] = (newbuf[0] + 1);
|
||||
|
||||
@@ -30,11 +30,11 @@ mkdir testrepo-files
|
||||
cd testrepo-files
|
||||
echo first > firstfile
|
||||
cd ..
|
||||
${CMD_PREFIX} SOURCE_DATE_EPOCH='1234567890' ostree --repo=./testrepo commit -b env -s "env timestamp"
|
||||
if (${CMD_PREFIX} SOURCE_DATE_EPOCH='invalid' ostree --repo=./testrepo commit -b env -s "invalid timestamp") 2> commit-invalid.txt; then
|
||||
${CMD_PREFIX} env SOURCE_DATE_EPOCH='1234567890' ostree --repo=./testrepo commit -b env -s "env timestamp"
|
||||
if (${CMD_PREFIX} env SOURCE_DATE_EPOCH='invalid' ostree --repo=./testrepo commit -b env -s "invalid timestamp") 2> commit-invalid.txt; then
|
||||
assert_not_reached "commit with invalid timestamp succeeded"
|
||||
fi
|
||||
if (${CMD_PREFIX} SOURCE_DATE_EPOCH='12345678901234567890' ostree --repo=./testrepo commit -b env -s "overflowing timestamp") 2> commit-overflowing.txt; then
|
||||
if (${CMD_PREFIX} env SOURCE_DATE_EPOCH='12345678901234567890' ostree --repo=./testrepo commit -b env -s "overflowing timestamp") 2> commit-overflowing.txt; then
|
||||
assert_not_reached "commit with overflowing timestamp succeeded"
|
||||
fi
|
||||
${CMD_PREFIX} ostree --repo=./testrepo show env > show-env.txt
|
||||
|
||||
@@ -26,18 +26,32 @@ if has_gpgme; then
|
||||
COMMIT_SIGN="--gpg-homedir=${TEST_GPG_KEYHOME} --gpg-sign=${TEST_GPG_KEYID_1}"
|
||||
fi
|
||||
|
||||
echo "1..4"
|
||||
echo "1..6"
|
||||
|
||||
# Test pulling from a repo which gives error 500 (internal server error) a lot of the time.
|
||||
# Sanity check with no network retries and 500s given, pull should fail.
|
||||
rm ostree-srv httpd repo -rf
|
||||
setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-500s=99
|
||||
|
||||
pushd ${test_tmpdir}
|
||||
ostree_repo_init repo --mode=archive
|
||||
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
|
||||
assert_fail ${CMD_PREFIX} ostree --repo=repo pull --mirror origin --network-retries=0 main 2>err.txt
|
||||
assert_file_has_content err.txt "\(500.*Internal Server Error\)\|\(HTTP 500\)"
|
||||
|
||||
popd
|
||||
echo "ok no retries after a 500"
|
||||
|
||||
# Test pulling a repo which gives error 500 (internal server error) a lot of the time.
|
||||
rm ostree-srv httpd repo -rf
|
||||
setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-500s=50
|
||||
|
||||
pushd ${test_tmpdir}
|
||||
ostree_repo_init repo --mode=archive
|
||||
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
|
||||
for x in $(seq 200); do
|
||||
if ${CMD_PREFIX} ostree --repo=repo pull --mirror origin main 2>err.txt; then
|
||||
echo "Success on iteration ${x}"
|
||||
break;
|
||||
for x in $(seq 40); do
|
||||
if ${CMD_PREFIX} ostree --repo=repo pull --mirror origin --network-retries=2 main 2>err.txt; then
|
||||
echo "Success on iteration ${x}"
|
||||
break;
|
||||
fi
|
||||
assert_file_has_content err.txt "\(500.*Internal Server Error\)\|\(HTTP 500\)"
|
||||
done
|
||||
@@ -48,6 +62,24 @@ ${CMD_PREFIX} ostree --repo=repo rev-parse main
|
||||
popd
|
||||
echo "ok repeated pull after 500s"
|
||||
|
||||
# Test pulling a repo that gives 408s a lot of the time, with many network retries.
|
||||
rm ostree-srv httpd repo -rf
|
||||
setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-500s=50
|
||||
|
||||
pushd ${test_tmpdir}
|
||||
ostree_repo_init repo --mode=archive
|
||||
${CMD_PREFIX} ostree --repo=repo remote add --set=gpg-verify=false origin $(cat httpd-address)/ostree/gnomerepo
|
||||
|
||||
# We limit 500s above to 100, so 100 retries should be enough always.
|
||||
${CMD_PREFIX} ostree --repo=repo pull --mirror origin --network-retries=100 main
|
||||
echo "Success with big number of network retries"
|
||||
|
||||
${CMD_PREFIX} ostree --repo=repo fsck
|
||||
${CMD_PREFIX} ostree --repo=repo rev-parse main
|
||||
|
||||
popd
|
||||
echo "ok big number of retries with one 500s"
|
||||
|
||||
# Sanity check with no network retries and 408s given, pull should fail.
|
||||
rm ostree-srv httpd repo -rf
|
||||
setup_fake_remote_repo1 "archive" "${COMMIT_SIGN}" --random-408s=99
|
||||
|
||||
@@ -24,6 +24,7 @@ set -euo pipefail
|
||||
|
||||
. $(dirname $0)/libtest.sh
|
||||
|
||||
skip_without_sudo
|
||||
SUDO="sudo --non-interactive"
|
||||
|
||||
# Skip the test if a well-known USB stick is not available.
|
||||
|
||||
@@ -54,7 +54,7 @@ echo 'ok documented symbols'
|
||||
|
||||
# ONLY update this checksum in release commits!
|
||||
cat > released-sha256.txt <<EOF
|
||||
370e560e4044b17523d23b04e383539cd22eac7c3067b7324803129ceebd73f0 ${released_syms}
|
||||
d7b5a766b1607f7334e9b6f15385ad872879e336a160ae76336243e493f7ceab ${released_syms}
|
||||
EOF
|
||||
sha256sum -c released-sha256.txt
|
||||
|
||||
|
||||
Reference in new issue
Block a user