Commit Graph

133 Commits

Author SHA1 Message Date
Bernd Schubert
58f85bfa9b
Add in the libfuse version a program was compiled with (#942)
The API stays the same, the libfuse version comes from
inlined functions, which are defined fuse_lowlevel.h
and fuse.h. As these inlined functions are defined in the header
files they get added into the application, similar as if these
were preprocessor macros.
Macro vs inlined function is then just a style issue - I personally
prefer the latter.

fuse_session_new() -> static inlinei, in the application
_fuse_session_new -> inside of libfuse

fuse_new() -> static inline, in the application
_fuse_new() -> inside of libfuse

Note: Entirely untested is the fuse 30 api - we need a test
for it. And we do not have any ABI tests at all.

Signed-off-by: Bernd Schubert <bernd.schubert@fastmail.fm>
2024-05-13 12:32:06 +02:00
Sarath Lakshman
ab5ca07af0 Fix max_threads command line parameter propagation
The fuse_main_real() method doesn't apply the max_threads parameter
parsed through the commandline arguments. This commit fixes the wiring
of max_threads argument.
2023-03-11 17:06:21 +00:00
Bernd Schubert
2da03e3898 Avoid max-idle threads warning
If a program with API before 312 did not set
max_idle_threads the new default from
fuse_parse_cmdline_312() is applied, which sets
UINT_MAX (-1).

Later in compat fuse_session_loop_mt_32 the old
config v1 struct is converted and that conversion
prints a warning if the default unset value was used.

This could have also happened to programs using the current
API, which just apply values struct fuse_cmdline_opts,
without checking if the defaults are set.
2023-02-20 10:14:17 +00:00
Bernd Schubert
db35a37def Install a the configure_file (config.h) and use in headers
This addresses: https://github.com/libfuse/libfuse/issues/724

HAVE_LIBC_VERSIONED_SYMBOLS configures the library if to use
versioned symbols and is set at meson configuration time.
External filesystems (the main target, actually)
include fuse headers and the preprocessor
then acts on HAVE_LIBC_VERSIONED_SYMBOLS. Problem was now that
'config.h' was not distributed with libfuse and so
HAVE_LIBC_VERSIONED_SYMBOLS was never defined with external
tools and the preprocessor did the wrong decision.

This commit also increases the the minimal meson version,
as this depends on meson feature only available in 0.50

<quote 'meson' >
WARNING: Project specifies a minimum meson_
version '>= 0.42' but uses features which were added
 in newer versions:
 * 0.50.0: {'install arg in configure_file'}
</quote>

Additionally the config file has been renamed to "fuse_config.h"
to avoid clashes - 'config.h' is not very specific.
2023-01-28 09:35:34 +00:00
Bernd Schubert
f212ec0870 Fix ublic/apple build for the fuse_parse_cmdline ABI symbol
For __APPLE__ and __ULIBC__, which are assumed to not support
versioned symbols, helper.c has a compat ABI symbol for
fuse_parse_cmdline(). However that ABI symbol was conflicting
with the API macro (which redirects to the right API function
for recompilations against current libfuse).
Additionally the parameter 'opts' had a typo and was called
'out_opts'.
2023-01-04 15:27:21 +00:00
Bernd Schubert
b1290d4c09 Fix the fuse_parse_cmdline@FUSE_3.0 ABI compat symbol
There was a simple typo and sym1 didn't match the function name
with the older __asm__(".symver " sym1 "," sym2) way to define
ABI compatibility. 
Witht the newer "__attribute__ ((symver (sym2)))" sym1 is not used
at all and in manual testing the issue didn't come up therefore.
2022-09-11 19:29:33 +01:00
Bernd Schubert
af5710e7a3 fuse-loop/fuse_do_work: Avoid lots of thread creations/destructions
On benchmarking metadata operations with a single threaded bonnie++
and "max_idle_threads" limited to 1, 'top' was showing suspicious
160% cpu usage.
Profiling the system with flame graphs showed that an astonishing
amount of CPU time was spent in thread creation and destruction.

After verifying the code it turned out that fuse_do_work() was
creating a new thread every time all existing idle threads
were already busy. And then just a few lines later after processing
the current request it noticed that it had created too many threads
and destructed the current thread. I.e. there was a thread
creation/destruction ping-pong.

Code is changed to only create new threads if the max number of
threads is not reached.

Furthermore, thread destruction is disabled, as creation/destruction
is expensive in general.

With this change cpu usage of passthrough_hp went from ~160% to
~80% (with different values of max_idle_threads). And bonnie
values got approximately faster by 90%. This is a with single
threaded bonnie++
bonnie++ -x 4 -q -s0  -d <path> -n 30:1:1:10 -r 0

Without this patch, using the default max_idle_threads=10 and just
a single bonnie++ the thread creation/destruction code path is not
triggered.  Just one libfuse and one application thread is just
a corner case - the requirement for the issue was just
n-application-threads >= max_idle_threads.


Signed-off-by: Bernd Schubert <bschubert@ddn.com>
2022-09-04 13:07:15 +01:00
Bernd Schubert
30a126c5f9 API update for fuse_loop_config additions
struct fuse_loop_config was passed as a plain struct, without any
version identifer. This had two implications

1) Any addition of new parameters required a FUSE_SYMVER for
fuse_session_loop_mt() and fuse_loop_mt() as otherwise a read
beyond end-of previous struct size might have happened.

2) Filesystems also might have been recompiled and the developer
might not have noticed the struct extensions and unexpected for
the developer (or people recomliling the code) uninitialized
parameters would have been passed.


Code is updated to have struct fuse_loop_config as an opaque/private
data type for file systems that want version 312
(FUSE_MAKE_VERSION(3, 12)). The deprecated fuse_loop_config_v1
is visible, but should not be used outside of internal
conversion functions

File systems that want version >= 32 < 312 get the previous
struct (through ifdefs) and the #define of fuse_loop_mt
and fuse_session_loop_mt ensures that these recompiled file
systems call into the previous API, which then converts
the struct. This is similar to existing compiled applications
when just libfuse updated, but binaries it is solved with
the FUSE_SYMVER ABI compact declarations.

Signed-off-by: Bernd Schubert <bschubert@ddn.com>
2022-09-04 13:07:15 +01:00
Stefan Hajnoczi
317181e8ea Introduce callback for logging
Introduce an API for custom log handler functions.  This allows libfuse
applications to send messages to syslog(3) or other logging systems.
See include/fuse_log.h for details.

Convert libfuse from fprintf(stderr, ...) to log_fuse(level, ...).  Most
messages are error messages with FUSE_LOG_ERR log level.  There are also
some debug messages which now use the FUSE_LOG_DEBUG log level.

Note that lib/mount_util.c is used by both libfuse and fusermount3.
Since fusermount3 does not link against libfuse, we cannot call
fuse_log() from lib/mount_util.c.  This file will continue to use
fprintf(stderr, ...) until someone figures out how to split it up.

Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
2019-09-04 15:59:18 +01:00
Mattias Nissler
da7c9b228a Add unprivileged option in mount.fuse3
The unprivileged option allows to run the FUSE file system process
without privileges by dropping capabilities and preventing them from
being re-acquired via setuid / fscaps etc. To accomplish this,
mount.fuse sets up the `/dev/fuse` file descriptor and mount itself
and passes the file descriptor via the `/dev/fd/%u` mountpoint syntax
to the FUSE file system.
2018-10-09 20:36:22 +01:00
Mattias Nissler
64e11073b9 Allow passing /dev/fuse file descriptor from parent process
This adds support for a mode of operation in which a privileged parent
process opens `/dev/fuse` and takes care of mounting. The FUSE file
system daemon can then run as an unprivileged child that merely
processes requests on the FUSE file descriptor, which get passed using
the special `/dev/fd/%u` syntax for the mountpoint parameter.

The main benefit is that no privileged operations need to be performed
by the FUSE file system daemon itself directly or indirectly, so the
FUSE process can run with fully unprivileged and mechanisms like
securebits and no_new_privs can be used to prevent subprocesses from
re-acquiring privilege via setuid, fscaps, etc. This reduces risk in
case the FUSE file system gets exploited by malicious file system
data.

Below is an example that illustrates this. Note that I'm using shell
for presentation purposes, the expectation is that the parent process
will implement the equivalent of the `mount -i` and `capsh` commands.

```
\# example/hello can mount successfully with privilege
$ sudo sh -c "LD_LIBRARY_PATH=build/lib ./example/hello /mnt/tmp"
$ sudo cat /mnt/tmp/hello
Hello World!
$ sudo umount /mnt/tmp

\# example/hello fails to mount without privilege
$ sudo capsh --drop=all --secbits=0x2f -- -c 'LD_LIBRARY_PATH=build/lib ./example/hello -f /mnt/tmp'
fusermount3: mount failed: Operation not permitted

\# Passing FUSE file descriptor via /dev/fd/%u allows example/hello to work without privilege
$ sudo sh -c '
      exec 17<>/dev/fuse
      mount -i -o nodev,nosuid,noexec,fd=17,rootmode=40000,user_id=0,group_id=0 -t fuse hello /mnt/tmp
      capsh --drop=all --secbits=0x2f -- -c "LD_LIBRARY_PATH=build/lib example/hello /dev/fd/17"
    '
$ sudo cat /mnt/tmp/hello
Hello World!
$ sudo umount /mnt/tmp
```
2018-10-09 20:36:22 +01:00
Oded Arbel
8198eb4b6f return different non-zero error codes (#290)
Return different error codes from fuse_main()
2018-08-29 17:20:56 +01:00
Josh Soref
8157b4d9b9 Spelling (#223)
Fix spelling errors
2017-11-27 10:23:20 +00:00
Nikolaus Rath
f24673cc17 Don't use external symbol names in internal files
The fuse_session_loop_mt() and fuse_loop_mt() symbols are only visible
when linking against the shared object. The code in lib/, however, is
compiled *into* the shared object and should thus use the internal
names of these functions.

Surprisingly enough, the code still worked before - but only when link
time optimization was disabled.

Unfortunately, we still can't compile with LTO because it seems that
enabling LTO somehow makes the tagged symbols vanish.

Without lto, we have:

$ nm lib/libfuse3.so | grep fuse_new
0000000000011070 T fuse_new_30
0000000000010a00 t fuse_new_31
0000000000011070 T fuse_new@FUSE_3.0
0000000000010a00 T fuse_new@@FUSE_3.1

and with LTO:

$ nm lib/libfuse3.so | grep fuse_new
0000000000019a70 T fuse_new_30
0000000000019270 t fuse_new_31

See also issue #198.
2017-09-19 16:47:40 +01:00
Joseph Dodge
f12d9686d4 Add idle_threads mount option. 2017-08-24 15:17:01 +02:00
Nikolaus Rath
e71bb48557 Fix two compiler warnings. 2017-08-22 13:59:17 +02:00
userwithuid
811c808b1d directly call fuse_new_31() instead of fuse_new() internally
this fixes building with lto, which failed since commit 503e32d01e
2017-08-14 20:02:28 +02:00
Nikolaus Rath
5459e87fe6 Simplify and fix FreeBSD fsname handling
This should simplify the code a lot. It also corrects a bug in
that the (former) add_default_fsname() function actually set
the -osubtype option.
2017-08-03 17:21:06 +02:00
Baptiste Daroussin
8f3c800e15 FreeBSD: supprt fsname= option 2017-08-03 16:40:36 +02:00
Nikolaus Rath
e870a0427a Added public fuse_lib_help(), bumped minor version 2017-07-08 12:48:08 +02:00
Nikolaus Rath
30243ca7ad Accept zero value for fuse_conn_info options
This may not make sense for all options, but it's good practice.
2016-10-20 14:04:37 -07:00
Nikolaus Rath
04f1039df2 Cast to void where we deliberately ignore return values 2016-10-18 18:54:14 -07:00
Mihail Konev
a78ed2b3a3 Ignore some errors 2016-10-18 04:02:52 +00:00
Nikolaus Rath
199fc0f833 Inlined fuse_mount_help() into fuse_lowlevel_help().
Both the BSD and Linux implementation actually accept mostly the same
FUSE-specific mount options. Up to now, the BSD help function appended
the output of ``mount_fusefs --help``, but looking at
http://www.unix.com/man-page/freebsd/8/mount_fusefs/ this is likely more
confusing than helpful (since the user is not actually invoking
mount_fusefs directly, most of the options don't make sense).
2016-10-16 14:28:47 -07:00
Nikolaus Rath
b16650830d Make --help output more suitable for end-user
We now only list options that are potentially useful for an
end-user (and unlikely to accidentally break a file system). The full
list of FUSE options has been moved to the documentation of the
fuse_new() and fuse_session_new() functions.
2016-10-15 19:46:57 -07:00
Nikolaus Rath
d49f2e77b4 Unify handling of fuse_conn_info options
Instead of using command line options to modify struct fuse_conn_info
before and after calling the init() handler, we now give the file system
explicit control over this.
2016-10-15 16:49:23 -07:00
Nikolaus Rath
2bfa342cda Make -o clone_fd into a parameter of session_loop_mt().
This option really affects the behavior of the session loop, not the
low-level interface. Therefore, it does not belong in the fuse_session
object.
2016-10-13 10:35:12 -07:00
Nikolaus Rath
b69192b629 fuse_main(): extend support for printing help
There's now a way to inhibit the "usage" line (which actually got lost
in commit 225c12aebf), which makes it easier for simply file-systems
to generate good-looking --help output.
2016-10-10 09:41:17 -07:00
Nikolaus Rath
b5dace61f3 fuse_main_real(): use fuse_parse_cmdline(). 2016-10-09 22:39:28 -07:00
Nikolaus Rath
225c12aebf fuse_parse_cmdline(): do not print help/version text
The current behavior makes it difficult to add help for
additional options. With the change, this becomes a lot easier.
2016-10-09 22:03:07 -07:00
Nikolaus Rath
950398c4f6 Clarified purpose of helper.c, moved *version() to fuse.c 2016-10-04 19:34:19 -07:00
Nikolaus Rath
425db842ff Don't handle --help and --version in fuse_session_new().
Help and version messages can be generated using the new
fuse_lowlevel_help(), fuse_lowlevel_version(), fuse_mount_help(), and
fuse_mount_version() functions.

The fuse_parse_cmdline() function has been made more powerful
to do this automatically, and is now explicitly intended only
for low-level API users.

This is a code simplication patch. We don't have to parse for --help and
--version in quite as many places, and we no longer have a low-level
initialization function be responsible for the (super-high level) task
of printing a program usage message.

In the high-level API, we can now handle the command line parsing
earlier and avoid running other initialization code if we're just going
to abort later on.
2016-10-02 21:09:37 -07:00
Nikolaus Rath
b4c3478b16 Add section headings for --help output
Also, do not include "General options" in usage message.
2016-10-02 20:51:15 -07:00
Nikolaus Rath
5698ee09cf Turn struct fuse_chan into an implementation detail
The only struct fuse_chan that's accessible to the user application is
the "master" channel that is returned by fuse_mount and stored in struct
fuse_session.

When using the multi-threaded main loop with the "clone_fd" option, each
worker thread gets its own struct fuse_chan. However, none of these are
available to the user application, nor do they hold references to struct
fuse_session (the pointer is always null).

Therefore, any presence of struct fuse_chan can be removed
without loss of functionality by relying on struct fuse_session instead.

This reduces the number of API functions and removes a potential source
of confusion (since the new API no longer looks as if it might be
possible to add multiple channels to one session, or to share one
channel between multiple sessions).

Fixes issue #17.
2016-10-02 13:56:40 -07:00
Nikolaus Rath
50f5255a44 Introduce separate mount/umount functions for low-level API. 2016-10-02 10:51:34 -07:00
Nikolaus Rath
e20e5c9ae5 Improve documentation of argument parsing. 2016-10-01 11:24:46 -07:00
Hendrik Brueckner
81370fcdc2 libfuse/fuse_daemonize: wait until daemon child process is ready (#55)
Mounting a FUSE file system remotely using SSH in combination with
pseudo-terminal allocation (-t), results in "Transport endpoint is
not connected" errors when trying to access the file system contents.

For example:

  # ssh -t root@localhost  "cmsfs-fuse /dev/disk/by-path/ccw-0.0.0190 /CMSFS"
  Connection to localhost closed.
  # ls /CMSFS
  ls: cannot access '/CMSFS': Transport endpoint is not connected

The cmsfs-fuse main program (which can also be any other FUSE file
system) calls into the fuse_main() libfuse library function.
The fuse_main() function later calls fuse_daemonize() to fork the
daemon process to handle the FUSE file system I/O.

The fuse_daemonize() function calls fork() as usual.  The child
proceeds with setsid() and then redirecting its file descriptors
to /dev/null etc.  The parent process, simply exits.

The child's functions and the parent's exit creates a subtle race.
This is seen with an SSH connection.  The SSH command above calls
cmsfs-fuse on an allocated pseudo-terminal device (-t option).

If the parent exits, SSH receives the command completion and closes
the connection, that means, it closes the master side of the
pseudo-terminal.  This causes a HUP signal being sent to the process
group on the pseudo-terminal.  At this point in time, the child might
not have completed the setsid() call and, hence, becomes terminated.
Note that fuse daemon sets up its signal handlers after fuse_daemonize()
has completed.

Even if the child has the chance to disassociate from its parent process
group to become it's own process group with setsid(), the child still
has the pseudo-terminal opened as stdin, stdout, and stderr.  So the
pseudo-terminal still behave as controlling terminal and might cause a
SIGHUP at closing the the master side.

To solve the problem, the parent has to wait until the child (the fuse
daemon process) has completed its processing, that means, has become
its own process group with setsid() and closed any file descriptors
pointing to the pseudo-terminal.

Closes: #27

Reported-by: Ofer Baruch <oferba@il.ibm.com>
Reviewed-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Hendrik Brueckner <brueckner@linux.vnet.ibm.com>
2016-06-20 12:48:16 -07:00
Miklos Szeredi
386b1b6e3d Merge branch 'clone_fd' 2015-09-29 17:51:32 +02:00
Christopher Harrison
95e89c0c8a Canonicalised whitespace and added ChangeLog entry 2015-08-12 14:55:13 +01:00
Christopher Harrison
7d687b939d Added fuse_pkgversion function
Returns the full PACKAGE_VERSION string, per autoconf
2015-07-30 11:05:34 +01:00
Miklos Szeredi
1344908b6c libfuse: refcount fuse_chan objects
New functions: fuse_chan_get(), fuse_chan_put().  Removed function:
fuse_chan_destroy().
2015-05-18 16:55:20 +02:00
Miklos Szeredi
9ffe64abe1 Print help on stdout instead of stderr 2013-07-26 16:20:28 +02:00
Miklos Szeredi
f9a7c2b113 libfuse: remove session and chan abstractions
There's actually just one type of channel and session, so we don't need the
generic callback functions.
2013-06-21 18:20:23 +02:00
Miklos Szeredi
2bcfd55fc1 libfuse: replace fuse_session_next_chan
Replace fuse_session_next_chan() with fuse_session_chan(), as multiple
channels per session were never actually supported and probably never will.
2013-06-21 13:35:30 +02:00
Miklos Szeredi
af57c73304 libfuse: fix multiple close of device fd
- fuse_kern_unmount closes handle (e.g. 19)
- a thread in my process opens a file - the OS assigns newly freed
handle (i.e. 19)
- fuse_kern_chan_destroy closes the same handle (i.e. 19)
- a thread in my process opens another file - the OS assigns newly
freed handle (i.e. 19)
- * MAYHEM *

Reported by Dan Greenfield
2013-06-20 11:43:02 +02:00
Miklos Szeredi
4e602d6f0c remove real fuse_main() symbol 2013-02-22 14:30:22 +01:00
Miklos Szeredi
c52c3256a5 fuse_daemonize(): chdir to "/" even if not running in the background
for consistency.

Reported by Vladimir Rutsky
2013-02-19 14:14:40 +01:00
Miklos Szeredi
baef74043c libfuse: remove deprecated fuse_setup(), fuse_teardown() 2013-02-08 08:03:02 +01:00
Miklos Szeredi
cc1a1f4edd Remove compat functions 2012-07-19 19:02:42 +02:00
Miklos Szeredi
966d97b1f8 Remove old symbol versions 2012-07-19 18:47:51 +02:00