This is a read-only archive. Find the latest Linux articles, documentation, and answers at the new!

Feature: System Administration

Automounting FUSE filesystems

By Ben Martin on March 04, 2008 (4:00:00 PM)

Share    Print    Comments   

One of the main things that gets annoying with FUSE, or Filesystem in Userspace, is that it won't automatically mount a filesystem when you first attempt to access the filesystem. This means you must manually track mountpoints and specify what program to run in order to mount each FUSE filesystem. Placing the exact commands to mount each FUSE filesystem into shell scripts can make things a little easier, but with afuse, you can mount FUSE filesystems on demand without the need for any explicit mounting.

Afuse is packaged for Ubuntu Gutsy but not for other mainstream distributions. It requires fuse version 2.3 or later. Building afuse from source follows the standard ./configure; make; sudo make install procedure, after which you should find the afuse binary in your path.

The afuse command's two main options are mount_template and unmount_template. Afuse uses mount_template to specify how to mount a FUSE filesystem. mount_template takes two arguments: the root directory that is being mounted in %r, and the path where the FUSE filesystem should mount itself in %m. A limitation on the mount_template command is that it cannot require any user interaction, such as prompting for a password. The unmount_template is likely to be the same for many applications of afuse, with a good default being fusermount -u -z %m.

The example below shows a test session with the SSH FUSE filesystem, mounting my home directory on another server using sshfs:

$ cd ~ $ mkdir fuse $ cd ./fuse $ mkdir remote-homedir $ sshfs ben@otherserver:/home/ben remote-homedir

The following afuse setup will automatically mount the remote directory with sshfs whenever I access ~/fuse/ben@otherserver, meaning you can avoid typing all the commands above. In the afuse command you must supply both the mount and unmount templates; attempts to leave out the unmount command will fail:

afuse \ -o mount_template="sshfs %r:/ %m" \ -o unmount_template="fusermount -u -z %m" \ ~/fuse

The above setup works well when each FUSE filesystem type has its own top-level directory. For example, you might have ~/fuse/sshfs with all of your SSH FUSE filesystems mounted in it, and ~/fuse/obex with all of your OBEX FUSE filesystems. In that case you would run two different afuse filesystems, each knowing how to mount a single FUSE filesystem type.

If you issue the fusermount -u command to the filesystem that afuse itself is mounted on, that single command will make afuse unmount any FUSE filesystems that it had mounted for you.

The following commands set up automatic mounting of MySQL as a filesystem using MySQLfs and afuse. As detailed in an earlier article, MySQLfs takes the host and database to mount (and possibly the username and password to use when authenticating with MySQL) and mounts a MySQL database as a FUSE filesystem.

The mysqlfs command shown below manually mounts MySQL directly using the MySQLfs FUSE filesystem. The later afuse command allows you to mount any MySQL database servers by DNS name, attempting to mount the MySQLfs database on each server. For example, running ls ~/fuse/localhost would cause MySQLfs to be executed against a MySQL server running on the same machine.

$ mkdir ~/fuse/mysqlfs $ mysqlfs -ohost=localhost -odatabase=mysqlfs ~/fuse/mysqlfs $ ls -l ~/fuse/mysqlfs ... $ fusermount -u ~/fuse/mysqlfs ... $ rmdir ~/fuse/mysqlfs $ afuse -f \ -o mount_template="mysqlfs -ohost=%r -odatabase=mysqlfs %m" \ -o unmount_template="fusermount -u -z %m" \ ~/fuse

Initially I could not get MySQLfs to work without using the -f command-line option to afuse to force it to stay in the foreground. Finding out what is stopping a FUSE auto mount can be difficult. You cannot run strace on a FUSE filesystem, so such brute force attempts to see what system call has failed will not work. The failure in this case was MySQLfs not being happy with its log files and calling exit(1), but afuse will not normally let you know about this error when you are running it in daemon mode (the default). If you run afuse in the foreground so that you can see debug messages, then MySQLfs will actually operate correctly instead of exiting, so you will not be able to see the error message -- a Catch-22 situation.

To debug automatic mounts that are not working as expected, place the following code in afuse.c/do_mount() just after the existing system(mount_command) line but before mount_command is passed to free(). This will let you see what has happened to the FUSE mount even when afuse is not running with debug output or in the foreground:

sysret = system(mount_command); { FILE* fp = fopen( "/tmp/afuse.log", "w+" ); fprintf( fp, "template:%s\n", user_options.mount_command_template ); fprintf( fp, "mp:%s\n", mount_point ); fprintf( fp, "rn:%s\n", root_name ); fprintf( fp, "mount_command:%s\n", mount_command ); fprintf( fp, "sysret: %.8x\n", sysret); fprintf( fp, "exitstat: %.8x\n", WEXITSTATUS(sysret)); fclose( fp ); } free(mount_command);

The solution for MySQLfs is to explicitly pass in the path that you would like MySQLfs to use for logging. The afuse command below works as expected:

$ afuse \ -o mount_template="mysqlfs -ohost=%r -odatabase=mysqlfs -ologfile=/tmp/mysqlfs.log %m" \ -o unmount_template="fusermount -u -z %m" \ ~/fuse $ ls -lh ~/fuse/localhost/ drwxrwxr-x 1 ben ben 0 2008-01-24 17:42 bonnie/ drwxrwx--- 1 ben ben 0 2008-01-12 13:24 guten/ -rw-r----- 1 ben ben 44M 2008-01-24 16:35 linux-2.6.23.tar.bz2

If you wish to have a mixture of different FUSE filesystems directly under ~/fuse be managed by a single afuse instance, you must use a shell script for at least the mount_template. For example, you might want some local 9p, Samba, and obex FUSE filesystems to be cobbled together in a single directory tree. This can be convenient when the filesystems offer a similar level of security and when you are less interested in the type of FUSE filesystem than its use. You might be more interested in seeing your smart phone, printer, and iCal files on a WebDAV share with meaningful names and less so in the actual FUSE filesystems that handle each format.

One way to manage afuse when you want different FUSE filesystems mounted is to create a fstab-like file and use a Perl script to manage the actual mounting. This ad hoc afuse fstab file contains lines with the format of top-level directory name and FUSE command to use.

For the example shown below, reading the localhost directory will cause MySQLfs to be mounted on the MySQL server running on localhost. Reading vfedora864prx1 will use sshfs to mount the server with that DNS name. The Perl script that follows afuse-fstab expects the directory name and FUSE mount point to be passed in as the first and second arguments. The logic of the script is simple: find the entry in the afuse-fstab that has the same directory name and use the rest of that line as the template to perform the FUSE mount. The script preserves the meaning of %r and %m in the FUSE auto mount that afuse itself would use, allowing the exact same command to be used in the fstab as would be directly used with afuse. The first substitution cuts off any non-space, non-forward-slash characters followed by optional white space. This removes the first part of the line that describes the directory name that should trigger the auto mount, leaving only the command to execute.

$ mkdir -p ~/etc $ cd ~/etc $ cat afuse-fstab localhost mysqlfs -ohost=%r -odatabase=mysqlfs -ologfile=/tmp/mysqlfs.log %m vfedora864prx1 sshfs %r:/ %m $ cat #!/usr/bin/perl -w $fstab="$ENV{HOME}/etc/afuse-fstab"; $afusedir=$ARGV[0]; $afuse_mountpoint=$ARGV[1]; print "afusedir:$afusedir\n"; print "afuse_mountpoint:$afuse_mountpoint\n"; open(FSTAB, $fstab ) or die("Can not open afuse-fstab at $fstab\n"); while( <FSTAB> ) { if( /^$afusedir/ ) { s/[^\s\/]+[\s]*//; s/%r/$afusedir/g; s/%m/$afuse_mountpoint/g; chomp; $cmd = $_; print "$cmd\n"; system($_) == 0 or die "execution of FUSE filesystem failed!\n" . "command:$cmd\n" . "reason:$?\n"; } }

With the afuse-fstab and Perl script in place you can tell afuse to use the Perl script for all mounting. Better still, shove the whole afuse invocation into a shell script so all you have to do is execute ~/ to have all FUSE automounting done.

$ vi ~/ #!/bin/bash afuse \ -o mount_template="~/etc/ %r %m" \ -o unmount_template="fusermount -u -z %m" \ ~/fuse $ chmod +x ~/ $ ~/ $ l ~/fuse/localhost drwxrwxr-x 1 ben ben 0 2008-01-24 17:42 bonnie/ drwxrwx--- 1 ben ben 0 2008-01-12 13:24 guten/ -rw-r----- 1 ben ben 44M 2008-01-24 16:35 linux-2.6.23.tar.bz2 $ l ~/fuse/vfedora864prx1/home/ben total 36K drwxrwxr-x 1 ben ben 4.0K 2008-01-30 22:01 ben-homedir-on-prx1/ drwxr-xr-x 1 ben ben 4.0K 2007-12-20 21:33 Desktop/ ...

Ben Martin has been working on filesystems for more than 10 years. He completed his Ph.D. and now offers consulting services focused on libferris, filesystems, and search solutions.

Share    Print    Comments   


on Automounting FUSE filesystems

Note: Comments are owned by the poster. We are not responsible for their content.

How to autorun it?

Posted by: Anonymous [ip:] on March 04, 2008 07:24 PM
Thank you for your great article. I have a question. It seems afuse doesn't have any configuration files, so everything is lost when I shut down my computer. So how to autorun afuse command (for example for sshfs) after I log in? I want to access my file systems automatically either via SSH/console, or in KDE/GNOME sessions, so I need some universal method. Thanks


Automounting FUSE filesystems

Posted by: Anonymous [ip:] on March 04, 2008 11:09 PM
Should work by simply setting up the script to auto run after logging in, in the sessions menu (in gnome at least).



Posted by: Anonymous [ip:] on March 08, 2008 11:17 PM
no, putting it in Gnome sessions menu doesn't work. You should create a file Default in /etc/gdm/PostLogin
and include the following command there:
sudo -u $LOGNAME $HOME/

where is your afuse run script.


Automounting FUSE filesystems

Posted by: Anonymous [ip:] on March 04, 2008 11:23 PM
Thanks, good article. I do want to point out that afuse is in Debian unstable. Ubuntu is a Debian derivative; it's always nice to acknowledge the original source, because there is more to Linux than Ubuntu. Other Debian derivatives that pull from unstable sources should have afuse too.


Automounting FUSE filesystems

Posted by: Anonymous [ip:] on March 05, 2008 12:47 AM
Hi. Does anybody know how to mount some samba share (eg. smbmount //SHARE/j\$ ~/mount_point -o credentials=/home/lofas/creds). afuse removes '/j\$' because it thinks of it as sub-directory.


Re: Automounting FUSE filesystems

Posted by: Anonymous [ip:] on March 05, 2008 12:55 AM
Oh... I was just confused by %r %m parameters :). I simply don't use %r for samba shares.


Automounting FUSE filesystems

Posted by: Anonymous [ip:] on March 05, 2008 02:16 AM
But I'm confused why it opens so many connections...


Automounting FUSE filesystems

Posted by: Anonymous [ip:] on March 05, 2008 08:34 AM
Not to take a think away from the article. But it is possible to get this all into fstab. Below is an example I use to do a remote mount of a shared dir for multiple servers in our data centers. Oh and the lack of space s is exactly has it has to be to work. I'm mounting this on CentOS 5.1. The beauty of Linux, so many ways to reach a common goal. /usr/local/local_dir fuse rw,nosuid,nodev,max_read=65536,uid=502,gid=502,workaround=rename,no_readahead,cache=no,sshfs_sync,sync_read,allow_other,default_permissions 0 0



Posted by: Anonymous [ip:] on March 08, 2008 11:15 PM
Data center? Come on, this feature is for laptop users, not for server (where it is more reasonable to use fstab). But even on servers you have to be root to be able to automount via fstab. This is not good for sshfs. And if you put afuse in .bash_profile, it would be simplier to mount sshfs than using sshfs itself.



Posted by: Anonymous [ip:] on March 05, 2008 10:07 AM
I can confirm that I was also able to use FUSE automounting by simply placing the relevant entry into /etc/fstab file. I'll provide the exact line when I get to the machine but as far as I can remember it's very similar to the one in the post above.
Still, I find the article to be useful information.


This story has been archived. Comments can no longer be posted.

Tableless layout Validate XHTML 1.0 Strict Validate CSS Powered by Xaraya