| This was generated on 2006/10/17 from |
| |
| http://fuse.sourceforge.net/wiki/index.php/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 LGPL. |
| |
| 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. |