Merge pull request #904 from bsbernd/s-bit-fusermount

Add back s-bit for compiled fusermount
This commit is contained in:
Bernd Schubert 2024-03-20 13:30:12 +01:00 committed by GitHub
commit 694f3d5231
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 117 additions and 47 deletions

View File

@ -73,7 +73,10 @@ nevertheless want to adjust them, you can do so with the
*meson configure* command:
$ meson configure # list options
$ meson configure -D disable-mtab=true # set an option
$ meson configure -D disable-mtab=true # set an optionq
$ # ensure all meson options are applied to the final build system
$ meson setup --reconfigure ../
To build, test, and install libfuse, you then use Ninja:

View File

@ -33,6 +33,7 @@
#include <time.h>
#include <pthread.h>
#include <poll.h>
#include <stdbool.h>
/*
* fsel_open_mask is used to limit the number of opens to 1 per file.
@ -51,6 +52,9 @@ static pthread_mutex_t fsel_mutex; /* protects notify_mask and cnt array */
static unsigned fsel_poll_notify_mask; /* poll notification scheduled? */
static struct fuse_pollhandle *fsel_poll_handle[FSEL_FILES]; /* poll notify handles */
static unsigned fsel_cnt[FSEL_FILES]; /* nbytes stored in each file */
static _Atomic bool fsel_stop = false;
static pthread_t fsel_producer_thread;
static int fsel_path_index(const char *path)
{
@ -61,6 +65,15 @@ static int fsel_path_index(const char *path)
return ch <= '9' ? ch - '0' : ch - 'A' + 10;
}
static void fsel_destroy(void *private_data)
{
(void)private_data;
fsel_stop = true;
pthread_join(fsel_producer_thread, NULL);
}
static int fsel_getattr(const char *path, struct stat *stbuf,
struct fuse_file_info *fi)
{
@ -205,6 +218,7 @@ static int fsel_poll(const char *path, struct fuse_file_info *fi,
}
static const struct fuse_operations fsel_oper = {
.destroy = fsel_destroy,
.getattr = fsel_getattr,
.readdir = fsel_readdir,
.open = fsel_open,
@ -220,7 +234,7 @@ static void *fsel_producer(void *data)
(void) data;
while (1) {
while (!fsel_stop) {
int i, t;
pthread_mutex_lock(&fsel_mutex);
@ -263,7 +277,6 @@ static void *fsel_producer(void *data)
int main(int argc, char *argv[])
{
pthread_t producer;
pthread_attr_t attr;
int ret;
@ -279,7 +292,7 @@ int main(int argc, char *argv[])
return 1;
}
errno = pthread_create(&producer, &attr, fsel_producer, NULL);
errno = pthread_create(&fsel_producer_thread, &attr, fsel_producer, NULL);
if (errno) {
perror("pthread_create");
return 1;
@ -287,8 +300,5 @@ int main(int argc, char *argv[])
ret = fuse_main(argc, argv, &fsel_oper, NULL);
pthread_cancel(producer);
pthread_join(producer, NULL);
return ret;
}

View File

@ -16,15 +16,30 @@
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <execinfo.h>
static struct fuse_session *fuse_instance;
static void dump_stack(void)
{
#ifdef HAVE_BACKTRACE
const size_t backtrace_sz = 1024 * 1024;
void* backtrace_buffer[backtrace_sz];
int err_fd = fileno(stderr);
int trace_len = backtrace(backtrace_buffer, backtrace_sz);
backtrace_symbols_fd(backtrace_buffer, trace_len, err_fd);
#endif
}
static void exit_handler(int sig)
{
if (fuse_instance) {
fuse_session_exit(fuse_instance);
if(sig <= 0) {
fuse_log(FUSE_LOG_ERR, "assertion error: signal value <= 0\n");
dump_stack();
abort();
}
fuse_instance->error = sig;

View File

@ -61,6 +61,8 @@ private_cfg.set('HAVE_SETXATTR',
cc.has_function('setxattr', prefix: '#include <sys/xattr.h>'))
private_cfg.set('HAVE_ICONV',
cc.has_function('iconv', prefix: '#include <iconv.h>'))
private_cfg.set('HAVE_BACKTRACE',
cc.has_function('backtrace', prefix: '#include <execinfo.h>'))
# Test if structs have specific member
private_cfg.set('HAVE_STRUCT_STAT_ST_ATIM',

View File

@ -1,8 +1,8 @@
#!/bin/bash
#!/bin/bash -x
set -e
TEST_CMD="python3 -m pytest --maxfail=99 test/"
TEST_CMD="pytest -v --maxfail=1 --log-level=DEBUG --log-cli-level=DEBUG test/"
SAN="-Db_sanitize=address,undefined"
# not default
@ -30,38 +30,48 @@ export LSAN_OPTIONS="suppressions=$(pwd)/lsan_suppress.txt"
export ASAN_OPTIONS="detect_leaks=1"
export CC
# Standard build
for CC in gcc gcc-9 gcc-10 clang; do
echo "=== Building with ${CC} ==="
mkdir build-${CC}; pushd build-${CC}
if [ "${CC}" == "clang" ]; then
export CXX="clang++"
export TEST_WITH_VALGRIND=false
else
export TEST_WITH_VALGRIND=true
fi
if [ ${CC} == 'gcc-7' ]; then
build_opts='-D b_lundef=false'
else
build_opts=''
fi
if [ ${CC} == 'gcc-10' ]; then
build_opts='-Dc_args=-flto=auto'
else
build_opts=''
fi
meson setup -Dprefix=${PREFIX_DIR} -D werror=true ${build_opts} "${SOURCE_DIR}" || (cat meson-logs/meson-log.txt; false)
ninja
sudo ninja install
non_sanitized_build()
(
echo "Standard build (without sanitizers)"
for CC in gcc gcc-9 gcc-10 clang; do
echo "=== Building with ${CC} ==="
mkdir build-${CC}; pushd build-${CC}
if [ "${CC}" == "clang" ]; then
export CXX="clang++"
export TEST_WITH_VALGRIND=false
else
unset CXX
export TEST_WITH_VALGRIND=true
fi
if [ ${CC} == 'gcc-7' ]; then
build_opts='-D b_lundef=false'
else
build_opts=''
fi
if [ ${CC} == 'gcc-10' ]; then
build_opts='-Dc_args=-flto=auto'
else
build_opts=''
fi
# libfuse will first try the install path and then system defaults
sudo chmod 4755 ${PREFIX_DIR}/bin/fusermount3
meson setup -Dprefix=${PREFIX_DIR} -D werror=true ${build_opts} "${SOURCE_DIR}" || (cat meson-logs/meson-log.txt; false)
ninja
sudo ninja install
${TEST_CMD}
popd
rm -fr build-${CC}
sudo rm -fr ${PREFIX_DIR}
done
# libfuse will first try the install path and then system defaults
sudo chmod 4755 ${PREFIX_DIR}/bin/fusermount3
# also needed for some of the tests
sudo chown root:root util/fusermount3
sudo chmod 4755 util/fusermount3
${TEST_CMD}
popd
rm -fr build-${CC}
sudo rm -fr ${PREFIX_DIR}
done
)
sanitized_build()
(
@ -78,11 +88,24 @@ sanitized_build()
# bug, cf. https://groups.google.com/forum/#!topic/mesonbuild/tgEdAXIIdC4
meson configure -D b_lundef=false
meson configure
# additional options
if [ -n "$@" ]; then
meson configure "$@"
fi
# print all options
meson configure --no-pager
# reconfigure to ensure it uses all additional options
meson setup --reconfigure "${SOURCE_DIR}"
ninja
sudo ninja install
sudo chmod 4755 ${PREFIX_DIR}/bin/fusermount3
# also needed for some of the tests
sudo chown root:root util/fusermount3
sudo chmod 4755 util/fusermount3
# Test as root and regular user
sudo ${TEST_CMD}
# Cleanup temporary files (since they are now owned by root)
@ -96,15 +119,17 @@ sanitized_build()
)
# Sanitized build
CC=clang
CXX=clang++
export CC=clang
export CXX=clang++
TEST_WITH_VALGRIND=false
sanitized_build $SAN
sanitized_build
# Sanitized build without libc versioned symbols
CC=clang
CXX=clang++
sanitized_build
export CC=clang
export CXX=clang++
sanitized_build "-Ddisable-libc-symbol-version=true"
non_sanitized_build
# Documentation.
(cd "${SOURCE_DIR}"; doxygen doc/Doxyfile)

View File

@ -2,3 +2,5 @@
addopts = --verbose --assert=rewrite --tb=native -x -r a
markers =
uses_fuse: Indicates that FUSE is supported.
log_cli=true
faulthandler_timeout=60

View File

@ -9,10 +9,11 @@ import subprocess
import pytest
import platform
import sys
import os
from looseversion import LooseVersion
from util import (wait_for_mount, umount, cleanup, base_cmdline,
safe_sleep, basename, fuse_test_marker, fuse_caps,
fuse_proto)
fuse_proto, create_tmpdir)
from os.path import join as pjoin
import os.path
@ -29,6 +30,9 @@ def test_write_cache(tmpdir, writeback, output_checker):
# deadlock in valgrind, it probably assumes that until close() returns,
# control does not come to the program.
mnt_dir = str(tmpdir)
print("mnt_dir: '" + mnt_dir + "'")
create_tmpdir(mnt_dir)
cmdline = [ pjoin(basename, 'test', 'test_write_cache'),
mnt_dir ]
if writeback:
@ -50,6 +54,7 @@ if fuse_proto >= (7,15):
@pytest.mark.parametrize("notify", (True, False))
def test_notify1(tmpdir, name, notify, output_checker):
mnt_dir = str(tmpdir)
create_tmpdir(mnt_dir)
cmdline = base_cmdline + \
[ pjoin(basename, 'example', name),
'-f', '--update-interval=1', mnt_dir ]
@ -70,6 +75,7 @@ def test_notify1(tmpdir, name, notify, output_checker):
else:
assert read1 == read2
except:
print("Failure in notify test: '" + str(cmdline) + "'")
cleanup(mount_process, mnt_dir)
raise
else:
@ -80,6 +86,7 @@ def test_notify1(tmpdir, name, notify, output_checker):
@pytest.mark.parametrize("notify", (True, False))
def test_notify_file_size(tmpdir, notify, output_checker):
mnt_dir = str(tmpdir)
create_tmpdir(mnt_dir)
cmdline = base_cmdline + \
[ pjoin(basename, 'example', 'invalidate_path'),
'-f', '--update-interval=1', mnt_dir ]

View File

@ -151,6 +151,12 @@ def powerset(iterable):
return itertools.chain.from_iterable(
itertools.combinations(s, r) for r in range(len(s)+1))
def create_tmpdir(mnt_dir):
if not os.path.exists(mnt_dir):
print("makedirs: '" + mnt_dir + "'")
os.makedirs(mnt_dir)
else:
print("mnt_dir exists: '" + mnt_dir + "'")
# Use valgrind if requested
if os.environ.get('TEST_WITH_VALGRIND', 'no').lower().strip() \