Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 20 Mar 2013 22:14:17 +1100 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Doug Ambrisko <ambrisko@ambrisko.com>
Cc:        arch@FreeBSD.org
Subject:   Re: Increase the mount path to MAXPATHLEN?
Message-ID:  <20130320211433.F1007@besplex.bde.org>
In-Reply-To: <20130319201145.GA19260@ambrisko.com>
References:  <20130319201145.GA19260@ambrisko.com>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 19 Mar 2013, Doug Ambrisko wrote:

> At work we use lots of chroots and mount things within those chroots
> like dev, proc etc. so it looks like a running system.  We also do
> some trickery so that we chroot into different versions of FreeBSD
> and pull in some of the native binaries so things like mount, ps etc.
> work inside.  We will also create chroots inside that.  Since these
> things live in home directories and mount points can be in various
> tree's the mount points are getting pretty long.  It seems that
> checking before was weak and let some of these mount worked by accident
> in prior versions of FreeBSD.

Old versions worked correctly.  Presumably this was not accidental.

> Now there is better error checking and
> the mounts fail since it exceeds MNAMELEN which was 88.  I did notice

Now there is broken error checking.  Mounting is broken just because
the data structure (struct statfs) is incapable of holding the full
path length.  But often nothing needs to know the full path.  It is
used mainly by df to report mounted file systems, and 88 is already
too long for that.  df output on freefall is unreadable due to
filesystem name lengths of merely about 30.

File systems are also incapable of holding the full path length in
their super blocks.  This is used mainly for "last mounted on"
diagnostic messages in mount() and maybe fsck.  It would be even more
obviously broken to disallow mounting just because this data structure
is too small.  Despite its obvious brokenness, ext2fs does it, but
currently has no effect since although ext2fs's superblock limit is
smaller than 88, the check uses ext2fs's in-core superblock limit which
is larger than 88 though smaller than MAXPATHLEN.  The larger in-core
name is completely useless, since broken mount prevents it all being
used and the smaller superblock name prevents it being used usefully
(the precise sizes are 64 for the disk and 512 for in-core).  In ffs,
the sizes are 468 for the disk and in-core.  The broken mount prevents
most of the 468 from being used.

> before that sometimes unmount would unmount other things and could
> be an issues with multiple scripts running at the same time.  This
> doesn't seem to be a problem now.

Since the pathname reported by statfs() is now complete, it is unique.
The old version should have modified the truncated pathnames in some
way so that they are unique.  They would never match any pathname to
a mount point.  Actually, if they are unique then they can be used to
look up the non-truncated pathnames.

> I'd like to bump the mount point to support a larger value then
> MNAMELEN (88) and to some what avoid this problem in the future thought
> we should just use MAXPATHLEN.  I figure that once start hitting that
> limit probably a bunch of things are going to pop up.

The limited has been hittable for ~30 years, but rarely hit.  If it were
important, then it would have been expanded when statfs was expanded to
support 64-bit sizes on 32-bit systems.  Instead, the pathname arrays
have shrunk a bit since 4.4BSD where they had size 90.  Before that,
bits of the pathnames were bitten off to make space for more important
fields, and the array size was reduced to 80 in struct ostatfs.  THe
current struct statfs just unbites for these fields and expands back to
size 80.

Does using MAXPATHLEN even fix the problem?  Absolute pathnames much
longer than it can be constructed using relative paths starting in
a deep directory, or symlinks.  I think mount(2) handle relative paths,
but mount(8) uses realpath(3) and the latter is almost necessary for
making the pathnames returned by statfs() usable.  realpath() is broken
as designed.  It repeats the design errors of getwd() and only supports
pathname lengths of < {PATH_MAX}.  This "fixes" the problem that the
path length might be longer than that by not supporting such paths.

NetBSD "fixed" this long ago by keeping struct statfs unchanged but
deprecated, but using _VFS_MNAMELEN = 1024 in struct statvfs.  In FreeBSD,
statvfs() and struct statvfs are just minimal compatibility cruft, with
no names at all in the struct since names are nonstandard.

> This means we'll need to create new system calls for stat calls
> and compatibility.  It is a pain, since you need to build and install
> a new kernel before you can run code with the new values.  So there
> is some pain involved.  I've made this change locally on a system

Too much pain for me.  I still use statfs = ostatfs in sys/syscall.h
so that the same (statically linked) userland works on a range of
kernels going back to ones that don't have statfs.  But since I don't
use current userlands I don't really care.

Bruce



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