Subject: bug#21372: closed (Re: bug#21372: [PATCH v4] df: fix prioritize real mounts over bind mounts)

From: [email-masked] (GNU bug Tracking System)
Date: Mon, 21 Sep 2015 22:45:05 +0000

Your bug report

#21372: df prioritizes some bind mounts over real ones.

which was filed against the coreutils package, has been closed.

The explanation is attached below, along with your original report.
If you require more details, please reply to [email-masked].

-- 
21372: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=21372
GNU Bug Tracking System
Contact [email-masked] with problems

Subject: Re: bug#21372: [PATCH v4] df: fix prioritize real mounts over bind mounts
From: Pádraig Brady <[email-masked]>
To: Dave Chiluk <[email-masked]>, [email-masked]
Date: Mon, 21 Sep 2015 23:44:53 +0100
List-Id: <debbugs-submit.debbugs.gnu.org>

On 21/09/15 21:04, Dave Chiluk wrote:
> Fixes an issue where bind mounts with shorter mount directories than the
> original mount are prioritized when running df.  The root cause of this
> is that /proc/self/mountinfo now lists the filesystem device with bind
> mounts rather than the source directory. With /etc/mtab the source
> device was listed as the originating directory so this was not an issue.
> 
> More information is available here.
> https://bugs.launchpad.net/ubuntu/+source/coreutils/+bug/1432871
> ---
>  src/df.c | 9 +++++++--
>  1 file changed, 7 insertions(+), 2 deletions(-)
> 
> diff --git a/src/df.c b/src/df.c
> index 2e541b9..4a3afa2 100644
> --- a/src/df.c
> +++ b/src/df.c
> @@ -652,9 +652,14 @@ filter_mount_list (bool devices_only)
>                else if ((strchr (me->me_devname, '/')
>                         /* let "real" devices with '/' in the name win.  */
>                          && ! strchr (devlist->me->me_devname, '/'))
> -                       /* let a shorter mountdir win.  */
> -                       || (strlen (devlist->me->me_mountdir)
> +                       /* let a shorter mountdir win. If it's mntroot is */
> +                       /* also shorter. i.e. not a bind mount. */
> +                       || ((strlen (devlist->me->me_mountdir)
>                             > strlen (me->me_mountdir))
> +                          && (devlist->me->me_mntroot == NULL
> +                             || me->me_mntroot == NULL
> +                             || (strlen (devlist->me->me_mntroot)
> +                                 >= strlen(me->me_mntroot))))
>                         /* let an entry overmounted on a new device win...  */
>                         || (! STREQ (devlist->me->me_devname, me->me_devname)
>                             /* ... but only when matching an existing mnt point,
> 

This logic looks correct thanks.
I'll adjust the comment a bit and maybe refactor
all the conditions to a single nearer_device_root boolean.

I'll push this later on,
with the associated gnulib update.

thanks,
Pádraig.

Subject: df prioritizes some bind mounts over real ones.
From: Dave Chiluk <[email-masked]>
To: [email-masked]
Date: Fri, 28 Aug 2015 15:42:44 -0500
List-Id: <debbugs-submit.debbugs.gnu.org>

With the recent move to /proc/self/mountinfo `df` now returns bind mounts
instead of the original mount when the directory being bound to is shorter than
the original mount destination.

For example:
 * $ mount
<snip>
192.168.1.2:/raid on /raid type nfs
/dev/sdc5 on /data type ext4 (rw)
<snip>

$ mount -o bind /data/a on /a type none (rw,bind)
$ mount -o bind /raid/temp on /b type none (rw,bind)

$df
Filesystem 1K-blocks Used Available Use% Mounted on
<snip>
192.168.1.2:/raid 449830616 229975284 196982196 54% /a
/dev/sdc5 7752072192 5581343744 1780023296 76% /b
</snip>

I'd expect to see the original mount prioritized over the bind mount. Like so.
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
<snip>
/dev/sdc5 449830616 229975284 196982196 54% /data
192.168.1.2:/raid 7752072192 5581438976 1779929088 76% /raid
<snip>

This is both mildly incorrect and misleading.  As the source device in both
cases isn't exactly what is being mounted at the destination directory.
Instead it is a subdir of the filesystem that is being mounted there.

I'm submitting patches to both gnulib and coreutils to correct this issue.

Thank you,
Dave Chiluk