Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 11 Apr 2001 19:15:28 +0200 (CEST)
From:      olli@fromme.com
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/26498: Fix for bug in union mounts (mout -o union)
Message-ID:  <200104111715.f3BHFST88472@monos.secnetix.net>

next in thread | raw e-mail | index | archive | help

>Number:         26498
>Category:       bin
>Synopsis:       Fix for bug in union mounts (mout -o union)
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Wed Apr 11 10:20:01 PDT 2001
>Closed-Date:
>Last-Modified:
>Originator:     Oliver Fromme
>Release:        FreeBSD 4.3-RC2-LEHMANNS
>Organization:
My head is still at the top, and the feets are at the bottom.
>Environment:

   The fix presented in this PR applies to 4-stable
   as well as 5-current.

>Description:

   When you mount a directory on top of another, using the
   "union" option to the mount command (I'm NOT talking
   about UNIONFS!), then all entries which are present in
   both directories appear twice, like this:
   
   $ ls -a
   .       ..      bar     bar1    baz     baz1    foo     foo1
   .       ..      bar     bar2    baz     baz2    foo     foo2
   
   It is particularly disturbing that "." and ".." appear
   twice, even if the directories are otherwise disjunct.
   
   Same problem with /usr/bin/find, /bin/sh (``echo *'')
   and all other tools that read and traverse directories.
   
   The culprit is in src/lib/libc/gen/opendir.c in the
   function __opendir2().  Look at the variable "unionstack"
   (near line 110).  It is correctly set to 1 in the case of
   a UNIONFS -- in this case the code removes duplicates.
   However, it doesn't handle the case of a union mount.

>How-To-Repeat:

   /*  Create two small vnode filesystems, /bin/sh syntax:  */

   for i in 0 1; do
           dd if=/dev/zero of=fs$i.vn bs=1m count=1
           vnconfig -s labels -c vn$i fs$i.vn
           disklabel -r -w vn$i auto
           newfs /dev/vn${i}c
   done

   /*  Mount them over each other:  */

   mkdir fs
   mount /dev/vn0c fs
   mount -o union /dev/vn1c fs

   ls -a
   .       .      ..      ..

   /*  Note that "." and ".." appear twice.  */

>Fix:

   The following patch fixes the problem by simply checking
   if the MNT_UNION flag is set in the statfs struct.
   The patch is against rev. 1.10 (4-stable as of 2000-04-10).

   I have had a look at the code in current, and the fix
   should be applicable there, too.  I haven't actually
   tested it, due to lack of a -current machine, but the
   fix is trivial enough for me to be sure that it should
   work.  :-)

   I have this code in production on a box with several
   jails, all of them containing union-mounted filesystems,
   and everything works fine.

   *phew*  Such a long PR for a one-line fix ...

--- src/lib/libc/gen/opendir.c.orig	Fri Jan 28 00:06:18 2000
+++ src/lib/libc/gen/opendir.c	Wed Apr 11 18:44:26 2001
@@ -110,7 +110,8 @@
 
 		if (fstatfs(fd, &sfb) < 0)
 			goto fail;
-		unionstack = !strcmp(sfb.f_fstypename, "union");
+		unionstack = !strcmp(sfb.f_fstypename, "union")
+		    || (sfb.f_flags & MNT_UNION);
 	} else {
 		unionstack = 0;
 	}
>Release-Note:
>Audit-Trail:
>Unformatted:

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200104111715.f3BHFST88472>