mirror of
https://github.com/libfuse/libfuse.git
synced 2024-12-03 00:54:15 +08:00
6972376812
* Make sure all global symbols are prefixed with "fuse_" or "cuse_" * Released 2.8.0
420 lines
15 KiB
Plaintext
420 lines
15 KiB
Plaintext
This was generated on 2006/10/17 from
|
|
|
|
http://sourceforge.net/apps/mediawiki/fuse/index.php?title=FAQ
|
|
|
|
For an up to date version please see the above page. You can also add
|
|
new entries there.
|
|
|
|
General
|
|
=======
|
|
|
|
How can I umount a filesystem?
|
|
------------------------------
|
|
|
|
FUSE filesystems can be unmounted either with:
|
|
|
|
umount mountpoint
|
|
|
|
or
|
|
|
|
fusermount -u mountpoint
|
|
|
|
The later does not need root privileges if the filesystem was mounted by the
|
|
user doing the unmounting.
|
|
|
|
What's the difference between FUSE and LUFS?
|
|
--------------------------------------------
|
|
|
|
The main difference between them is that in LUFS the filesystem is a
|
|
shared object (.so) which is loaded by lufsmount, and in FUSE the
|
|
filesystem is a separate executable, which uses the fuse library. The
|
|
actual API is very similar, and there's a translator, that can load
|
|
LUFS modules and run them using the FUSE kernel module (see the lufis
|
|
package on the FUSE page).
|
|
|
|
Another difference is that LUFS does some caching of directories and
|
|
file attributes. FUSE does not do this, so it provides a 'thinner'
|
|
interface.
|
|
|
|
By now LUFS development seems to have completely ceased.
|
|
|
|
Why is it called FUSE? There's a ZX Spectrum emulator called Fuse too.
|
|
----------------------------------------------------------------------
|
|
|
|
At the time of christening it, the author of FUSE (the filesystem)
|
|
hadn't heard of Fuse (the Speccy emulator). Which is ironic, since he
|
|
knew Philip Kendall, the author of that other Fuse from earlier times.
|
|
Btw. the author of FUSE (the filesystem) also created a Speccy
|
|
emulator called Spectemu.
|
|
|
|
The name wanted to be a clever acronym for "Filesystem in USErspace",
|
|
but it turned out to be an unfortunate choice. The author has since
|
|
vowed never to name a project after a common term, not even anything
|
|
found more than a handful of times on Google.
|
|
|
|
Is it possible to mount a fuse filesystem from fstab?
|
|
-----------------------------------------------------
|
|
|
|
Yes, from version 2.4.0 this is possible. The filesystem must adhere
|
|
to some rules about command line options to be able to work this way.
|
|
Here's an example of mounting an sshfs filesystem:
|
|
|
|
sshfs#user@host:/ /mnt/host fuse defaults 0 0
|
|
|
|
The mounting is performed by the /sbin/mount.fuse helper script. In
|
|
this example the FUSE-linked binary must be called sshfs and must
|
|
reside somewhere in $PATH.
|
|
|
|
Licensing issues
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
Under what license is FUSE released?
|
|
------------------------------------
|
|
|
|
The kernel part is released under the GNU GPL.
|
|
|
|
Libfuse is released under the GNU LGPLv2.
|
|
|
|
All other parts (examples, fusermount, etc) are released under the GNU
|
|
GPL.
|
|
|
|
Under what conditions may I modify or distribute FUSE?
|
|
------------------------------------------------------
|
|
|
|
See the files COPYING and COPYING.LIB in the distribution.
|
|
|
|
More information can be found at http://www.gnu.org/licenses/
|
|
|
|
Under what conditions may I distribute a filesystem which uses libfuse?
|
|
-----------------------------------------------------------------------
|
|
|
|
See COPYING.LIB in the distribution.
|
|
|
|
In simple terms as long as you are linking dynamically (the default)
|
|
there are no limitations on linking with libfuse. For example you may
|
|
distribute the filesystem itself in binary form, without source code,
|
|
under any propriatery license.
|
|
|
|
Under what conditions may I distribute a filesystem that uses the raw
|
|
---------------------------------------------------------------------
|
|
kernel interface of FUSE?
|
|
-------------------------
|
|
|
|
There are no restrictions whatsoever for using the raw kernel interface.
|
|
|
|
API
|
|
===
|
|
|
|
Which method is called on the close() system call?
|
|
--------------------------------------------------
|
|
|
|
flush() and possibly release(). For details see the documentation of
|
|
these methods in <fuse.h>
|
|
|
|
Wouldn't it be simpler if there were a single close() method?
|
|
-------------------------------------------------------------
|
|
|
|
No, because the relationship between the close() system call and the
|
|
release of the file (the opposite of open) is not as simple as people
|
|
tend to imagine. UNIX allows open files to acquire multiple
|
|
references
|
|
|
|
* after fork() two processes refer to the same open file
|
|
|
|
* dup() and dup2() make another file descriptor refer to the same
|
|
file
|
|
|
|
* mmap() makes a memory mapping refer to an open file
|
|
|
|
This means, that for a single open() system call, there could be more
|
|
than one close() and possibly munmap() calls until the open file is
|
|
finally released.
|
|
|
|
Can I return an error from release()?
|
|
-------------------------------------
|
|
|
|
No, it's not possible.
|
|
|
|
If you need to return errors on close, you must do that from flush().
|
|
|
|
How do I know which is the last flush() before release()?
|
|
---------------------------------------------------------
|
|
|
|
You can't. All flush() calls should be treated equally. Anyway it
|
|
wouldn't be worth optimizing away non-final flushes, since it's fairly
|
|
rare to have multiple write-flush sequences on an open file.
|
|
|
|
Why doesn't FUSE forward ioctl() calls to the filesystem?
|
|
---------------------------------------------------------
|
|
|
|
Because it's not possible: data passed to ioctl() doesn't have a well
|
|
defined length and structure like read() and write(). Consider using
|
|
getxattr() and setxattr() instead.
|
|
|
|
Is there a way to know the uid, gid or pid of the process performing
|
|
--------------------------------------------------------------------
|
|
the operation?
|
|
--------------
|
|
|
|
Yes: fuse_get_context()->uid, etc.
|
|
|
|
How should threads be started?
|
|
------------------------------
|
|
|
|
Miscellaneous threads should be started from the init() method.
|
|
Threads started before fuse_main() will exit when the process goes
|
|
into the background.
|
|
|
|
Is it possible to store a pointer to private data in the
|
|
--------------------------------------------------------
|
|
fuse_file_info structure?
|
|
-------------------------
|
|
|
|
Yes, the 'fh' filed is for this purpose. This filed may be set in the
|
|
open() and create() methods, and is available in all other methods
|
|
having a struct fuse_file_info parameter. Note, that changing the
|
|
value of 'fh' in any other method as open() or create() will have no
|
|
affect.
|
|
|
|
Since the type of 'fh' is unsigned long, you need to use casts when
|
|
storing and retrieving a pointer. Under Linux (and most other
|
|
architectures) an unsigned long will be able to hold a pointer.
|
|
|
|
This could have been done with a union of 'void *' and 'unsigned long'
|
|
but that would not have been any more type safe as having to use
|
|
explicit casts. The recommended type safe solution is to write a
|
|
small inline function that retrieves the pointer from the
|
|
fuse_file_info structure.
|
|
|
|
Problems
|
|
========
|
|
|
|
Version problems
|
|
~~~~~~~~~~~~~~~~
|
|
|
|
Why do I get Connection Refused after mounting?
|
|
-----------------------------------------------
|
|
|
|
Library is too old (< 2.3.0)
|
|
|
|
You can check which version of the library is being used by foofs by
|
|
doing 'ldd path_to_foofs'. It will return something like this
|
|
|
|
libfuse.so.2 => /usr/local/lib/libfuse.so.2 (0xb7fc9000)
|
|
libpthread.so.0 => /lib/tls/libpthread.so.0 (0xb7fb9000)
|
|
libglib-2.0.so.0 => /usr/lib/libglib-2.0.so.0 (0xb7f39000)
|
|
libc.so.6 => /lib/tls/libc.so.6 (0xb7e04000)
|
|
|
|
Then do 'ls -l path_to_libfuse'
|
|
|
|
> ls -l /usr/local/lib/libfuse.so.2
|
|
lrwxrwxrwx 1 root root 16 Sep 26 13:41 /usr/local/lib/libfuse.so.2 -> libfuse.so.2.2.1
|
|
|
|
Why does fusermount fail with an Unknown option error?
|
|
------------------------------------------------------
|
|
|
|
Errors like 'fusermount: Unknown option -o' or 'fusermount: Unknown
|
|
option --' mean, that an old version of fusermount is being used. You
|
|
can check by doing 'which fusermount'.
|
|
|
|
If you installed FUSE from source, then this is probably because there
|
|
exists a binary package on your system which also contains a
|
|
fusermount program, and is found first in the path, e.g. in
|
|
/usr/bin/fusermount.
|
|
|
|
The solution is to remove the binary package.
|
|
|
|
Installation problems
|
|
~~~~~~~~~~~~~~~~~~~~~
|
|
|
|
Why is there an error loading shared libraries?
|
|
-----------------------------------------------
|
|
|
|
If you get the following error when starting a FUSE-based filesystem:
|
|
|
|
foofs: error while loading shared libraries: libfuse.so.2:
|
|
cannot open shared object file: No such file or directory
|
|
|
|
check /etc/ld.so.conf for a line containing '/usr/local/lib'. If it's
|
|
missing, add it, and run ldconfig afterwards.
|
|
|
|
Why doesn't mounting as user work if installing FUSE from a package?
|
|
--------------------------------------------------------------------
|
|
|
|
Distributions often package 'fusermount' without the suid bit, or only
|
|
executable to the 'fuse' group.
|
|
|
|
This results in the following message, when trying to mount a
|
|
filesystem as an unprivileged user:
|
|
|
|
fusermount: mount failed: Operation not permitted
|
|
|
|
The simplest solution is to change the mode of 'fusermount':
|
|
|
|
chmod 4755 /usr/bin/fusermount
|
|
|
|
Note, you may have to do this after each upgrade.
|
|
|
|
Other problems
|
|
~~~~~~~~~~~~~~
|
|
|
|
Why are some bytes zeroed when reading a file?
|
|
----------------------------------------------
|
|
|
|
This happens if the filesystem returns a short count from the read()
|
|
method. If the file wasn't opened in direct I/O mode, the read()
|
|
method must return exactly the requested number of bytes, unless it's
|
|
the end of the file.
|
|
|
|
If the file was opened in direct I/O mode (with direct_io mount
|
|
option, or by setting the direct_io field of fuse_file_info at open)
|
|
the read can return a smaller value than requested. In this case the
|
|
end of file can be signalled by returning zero.
|
|
|
|
What do I do if /dev/fuse does not exist?
|
|
-----------------------------------------
|
|
|
|
Maybe the FUSE module is not loaded. As root, try:
|
|
|
|
modprobe fuse
|
|
|
|
If nothing changes, as root run:
|
|
|
|
mknod /dev/fuse c 10 229
|
|
|
|
What do I do if you don't have access to /dev/fuse?
|
|
---------------------------------------------------
|
|
|
|
As root run:
|
|
|
|
chmod o+rw /dev/fuse
|
|
|
|
Remember that this will allow ordinary users to mount their own user
|
|
space filesystems.
|
|
|
|
If that's not what you want then use different permissions.
|
|
|
|
Why does cp return operation not permitted when copying a file with no
|
|
----------------------------------------------------------------------
|
|
write permissions for the owner?
|
|
--------------------------------
|
|
|
|
"cp" calls open(2) with read-only permissions and O_CREAT, the purpose
|
|
being to atomically obtain a read/write file handle and make the file
|
|
read-only. Unfortunately, this does not work very well in fuse, since
|
|
you first get a mknod, and then an open call. At the time of open,
|
|
you can't distinguish easily wether this is the first open issued by
|
|
cp, or another process trying to write a read-only file.
|
|
|
|
Defining the 'create' method solves this problem, however this
|
|
requires a Linux kernel version of at least 2.6.15 and libfuse version
|
|
2.5 or greater (on FreeBSD you'll need fuse4bsd-0.3.0-pre1 or newer
|
|
for this).
|
|
|
|
There can be other workarounds, however the easy one is to use the
|
|
"default_permissions" mount option, and to avoid checking permissions
|
|
on open. If you store files on a filesystem, this can get tricky
|
|
because you will have to change the file mode to allow writing. Using
|
|
the stateful API (i.e. returning an handle on open) will simplify
|
|
things. In this case, and using "-o default_permissions", when
|
|
implementing the open call you have to:
|
|
|
|
1. check if the open is in write mode (i.e. mode has O_RDWR or
|
|
O_WRONLY)
|
|
|
|
2. in that case (in mutual exclusion with other open, getattr
|
|
etc. calls on the same file) change the mode from "M" to "M OR
|
|
0o200"
|
|
|
|
3. open the file, change back the mode even in case of errors, and
|
|
return the obtained handle
|
|
|
|
Why doesn't find work on my filesystem?
|
|
---------------------------------------
|
|
|
|
The st_nlink member must be set correctly for directories to make find
|
|
work. If it's not set correctly the -noleaf option of find can be
|
|
used to make it ignore the hard link count (see man find).
|
|
|
|
The correct value of st_nlink for directories is NSUB + 2. Where NSUB
|
|
is the number of subdirectories. NOTE: regular-file/symlink/etc
|
|
entries do not count into NSUB, only directories.
|
|
|
|
If calculating NSUB is hard, the filesystem can set st_nlink of
|
|
directories to 1, and find will still work. This is not documented
|
|
behavior of find, and it's not clear whether this is intended or just
|
|
by accident. But for example the NTFS filesysem relies on this, so
|
|
it's unlikely that this "feature" will go away.
|
|
|
|
What is the reason for IO errors?
|
|
---------------------------------
|
|
|
|
The kernel part of FUSE returns the EIO error value, whenever the
|
|
userspace filesystem sends a "bad" reply. Sometimes these are
|
|
unavoidable, and not necessarily a fault of the filesystem. Possible
|
|
causes of this are (non-exhaustive)
|
|
|
|
* the filesystem returned a short count on write()
|
|
|
|
* the type of the file has changed (e.g. a directory suddenly
|
|
became a symlink)
|
|
|
|
* a directory entry contained a filename that was too long (no,
|
|
ENAMETOOLONG is not the right error here)
|
|
|
|
* the same node ID value was used for two different directories
|
|
(i.e. hard-linked directories are not allowed)
|
|
|
|
* In the GETATTR function, st_mode needs to have a valid filetype
|
|
bit set, like S_IFREG or S_IFDIR, see the stat manual for more
|
|
|
|
* You are running a 64 bit kernel but using a 32 bit libfuse. In this case
|
|
you will need to install a 64 bit version of the FUSE userspace library,
|
|
64 bit versions of all of the FUSE filesystems or language bindings that
|
|
link to it, and 64 bit versions of all of their dependancies. Your
|
|
distribution may provide 64 bit versions of the basic dependancies like
|
|
libc even in its 32 bit environment
|
|
|
|
Misc
|
|
====
|
|
|
|
Can the filesystem ask a question on the terminal of the user?
|
|
--------------------------------------------------------------
|
|
|
|
It would not be possible generally speaking, since it might not be an
|
|
interactive program but rather a daemon, or a GUI program doing the
|
|
operation. However you should be able to get the PID for the caller,
|
|
and by looking in /proc you should be able to find the process tty or
|
|
something similar.
|
|
|
|
But this is not recommended. You should rather think about solving
|
|
this another way.
|
|
|
|
If a filesystem is mounted over a directory, how can I access the old
|
|
---------------------------------------------------------------------
|
|
contents?
|
|
---------
|
|
|
|
There are two possibilities:
|
|
|
|
The first is to use 'mount --bind DIR TMPDIR' to create a copy of the
|
|
namespace under DIR. After mounting the FUSE filesystem over DIR,
|
|
files can still be accessed through TMDIR. This needs root privileges.
|
|
|
|
The second is to set the working directory to DIR after mounting the FUSE
|
|
filesystem. For example before fuse_main() do
|
|
|
|
save_dir = open(DIR, O_RDONLY);
|
|
|
|
And from the init() method do
|
|
|
|
fchdir(save_dir);
|
|
close(save_dir);
|
|
|
|
Then access the files with relative paths (with newer LIBC versions
|
|
the *at() functions may also be used instead of changing the CWD).
|
|
|
|
This method doesn't need root privileges, but only works on Linux
|
|
(FreeBSD does path resolving in a different way), and it's not even
|
|
guaranteed to work on future Linux versions.
|