Bug 212318 - sysutils/fusefs-libs: fails to unmount due to a uniq dev node
Summary: sysutils/fusefs-libs: fails to unmount due to a uniq dev node
Status: Closed Overcome By Events
Alias: None
Product: Ports & Packages
Classification: Unclassified
Component: Individual Port(s) (show other bugs)
Version: Latest
Hardware: Any Any
: --- Affects Some People
Assignee: freebsd-ports-bugs (Nobody)
Depends on:
Reported: 2016-09-01 21:37 UTC by Ben RUBSON
Modified: 2018-08-10 08:38 UTC (History)
7 users (show)

See Also:
bugzilla: maintainer-feedback? (brendan+freebsd)


Note You need to log in before you can comment on or make changes to this bug.
Description Ben RUBSON 2016-09-01 21:37:35 UTC

I found a bug with fusefs.

In function fuse_unmount_compat22, the following command is used to find out the device to unmount :
/usr/bin/fstat /dev/fuse*

Here is its output with FreeBSD 11.0-RC2 :

# fstat /dev/fuse*
USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W NAME
user1    encfs      15513    4 /dev         60 crw-rw----    fuse rw  /dev/fuse
user2    encfs      15504    4 /dev         60 crw-rw----    fuse rw  /dev/fuse
user3    encfs      15456    4 /dev         60 crw-rw----    fuse rw  /dev/fuse
user4    encfs      15431    4 /dev         60 crw-rw----    fuse rw  /dev/fuse

As you can see all users use the same dev node /dev/fuse.
So when unmounting, user3 will get for example the following message :
umount: unmount of /home/user2/encfs failed: Operation not permitted

I'm not sure where is the issue, if we should expect a uniq dev node per mounted FS, or if the unmount command is to correct.

Many thanks for your help !

Comment 1 Melvyn Sopacua 2016-09-05 10:01:05 UTC
Operation not permitted hints at the cause: are you unmounting the device as root or as the same user that mounted the node? I have no issues unmounting multiple fuse devices on 10.3.
Comment 2 Ben RUBSON 2016-09-05 17:20:33 UTC
Thank you for your feedback Melvyn.

Every mount/unmount is done by users themselves, not by root.
Look, in my example, when user3 tries to unmount, fuse tries to unmount FS of another user (user2 in my example).
I think fuse tries to unmount the last one mounted.
I think the bug is due to the fact that all FSs share the same /dev/fuse node.

Do you have several fuse dev nodes on 10.3, one per fuse FS mounted ? (/dev/fuse0, /dev/fuse1, dev/fuse2...)
Comment 3 Melvyn Sopacua 2016-12-21 10:47:10 UTC
I have several nodes all using /dev/fuse, but I'm using an rc.d script to mount/unmount them, which is run by root. My unmounting part is this:

ntfsmount_unmount() {
        # We can't check this, since mount -p with path argument only checks
        # nodes in fstab(5).
        #       if /sbin/mount -p ${ntfsmount_mountpoint} >/dev/null 2>&1
        # So we need to envoke mount -p without argument and grep for the
        # mountpoint instead.
        if check_is_mounted ${ntfsmount_mountpoint}
                /sbin/umount ${ntfsmount_mountpoint}

check_is_mounted() {
        local mp is_mounted

        is_mounted=`/sbin/mount -p|sed -ne "s,^/dev/fuse.*[[:space:]]\(${mp}\)[[:space:]].*$,\\1,p"`
        if [ ! -z "${is_mounted}" -a x"${is_mounted}" = x"${mp}" ]
                return 0
        return 1

This does the right thing for me. As for the code you've shown, it seems like a bug to use fstat, as you can never get the path it is mounted *on* from that.
Comment 4 Ben RUBSON 2016-12-21 11:05:37 UTC
Thank you for your feedback Melvyn !

What do the following command return when you have several fuse mounted ?
ls -l /dev/fuse*
fstat /dev/fuse*
uname -a

Thank you again !
Comment 5 Ben RUBSON 2016-12-21 11:06:22 UTC
Well uname -r is enough :)
Comment 6 martin 2016-12-21 14:39:17 UTC
(In reply to Ben RUBSON from comment #0)

What is calling fuse_unmount_compat22?

I think newly compiled code should end up calling fuse_kern_unmount, which should be fixed by files/patch-lib_mount_bsd.c.
Comment 7 Ben RUBSON 2016-12-21 16:01:08 UTC
encfs is calling fuse_unmount_compat22 :
Comment 8 Melvyn Sopacua 2016-12-21 16:05:17 UTC
(In reply to Ben RUBSON from comment #4)
ls -l /dev/fuse*
crw-rw----  1 root  staff  0x3a Dec 21 16:58 /dev/fuse

sudo fstat /dev/fuse
USER     CMD          PID   FD MOUNT      INUM MODE         SZ|DV R/W NAME
root     ntfs-3g     1272    4 /dev         58 crw-rw----    fuse rw  /dev/fuse
root     ntfs-3g     1255    4 /dev         58 crw-rw----    fuse rw  /dev/fuse

% mount -p|grep '^/dev/fuse'
/dev/fuse               /home/melvyn/Music/Windisk fusefs       ro,sync        0 0
/dev/fuse               /home/melvyn/win7       fusefs  ro,sync         0 0

% pkg query '%n-%v' sysutils/fusefs-libs

% uname -r
Comment 9 martin 2016-12-21 20:34:10 UTC
(In reply to Ben RUBSON from comment #7)

Yuck, looks like fuse_unmount_compat22 needs to be patched to just call unmount(mountpoint, MNT_FORCE) as well then.
Comment 10 Ben RUBSON 2016-12-27 17:30:51 UTC
Yep I think so too.
I also just saw that fuse_unmount_compat22 has gone from libfuse 3.0.
Comment 11 Ben RUBSON 2017-01-25 10:02:39 UTC
(In reply to martin from comment #6)
(In reply to Ben RUBSON from comment #7)

As a workaround for encfs, I submitted a PR to avoid using (deprecated) fuse_unmount_compat22.

For others, fuse_unmount_compat22 should still need to be patched, of they would need to use an alternate unmount method/function.
Comment 12 Walter Schwarzenfeld freebsd_triage 2018-02-10 14:45:15 UTC
Any news here?
Comment 13 Ben RUBSON 2018-02-10 14:57:22 UTC
Can't your fuse program simply use fuse_unmount(mountpoint, NULL) instead of fuse_unmount_compat22(mountpoint) ?
(as we did here : https://github.com/vgough/encfs/pull/293)
Comment 14 Conrad Meyer freebsd_committer 2018-08-10 08:38:14 UTC
Either the compat22 routine was removed, or its use should be avoided, or if that absolutely fails maybe it can be patched not to be broken.  Unclear if anything is still tripping over this broken path anymore.  Sounds like encfs was fixed not to use it and fusefs-libs may have removed it too.