Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Mar 1995 01:23:50 -0500 (EST)
From:      Wankle Rotary Engine <wpaul@skynet.ctr.columbia.edu>
To:        freebsd-hackers@FreeBSD.org
Subject:   mountd strangeness
Message-ID:  <199503270623.BAA04274@skynet.ctr.columbia.edu>

next in thread | raw e-mail | index | archive | help
There's a problem with mountd that needs to be fixed, only I'm not sure
I know how to do it. I'm hoping someone here can point me in the right
direction.

First, let me describe the problem. Assume you have an /etc/exports file 
that looks like this:

/sbin -ro host1 host2 host3
/etc/ppp -ro host1
/etc/mtree -ro host3

In this case, /sbin, /etc/mtree and /etc/ppp are all on the same filesystem.
(Nobody would really want to export these directories in the real world,
but that's not important.) This should allow host1 to access /sbin and
/etc/ppp, host2 to access only /sbin, and host3 to access /sbin and
/etc/mtree.

Unfortunately, this doesn't work: as soon as mountd goes to process the
second line in the file, it craps out with an error that says: "Can't
change attributes for /etc/ppp." The end result is that only the first
line is considered valid: the other two are rejected.

The reason it does this is because of what happens in do_mount(): the
code there spins backwards through the specified path until it finds
the root of the filesystem, then it does a mount() with the MNT_UPDATE
flag set to add the addresses of host1, host2 and host3 to the
export list for the mount point, which is held inside the kernel.
This export list is updated using a function called vfs_hang_addrlist()
in /sys/kern/vfs_subr.c. vfs_hang_addrlist() is called from vfs_export(),
which is itself called from ufs_mount().

vfs_hang_addrlist() is picky: if you ask it to add an address that's
already in the address list for a given mount point, it returns EPERM.
Meanwhile, do_mount() watches for EPERM and errors out if it finds it,
thinking that it's an indication of some horrible error.

And it will find it in my example, because /sbin, /etc/ppp and /etc/mtree
are all rooted in the same filesystem.

What happens is that the addresses for host1, host2 and host3 are already
in the export list for the root filesystem (/), so any attempt to export
any other subdirectories of the root filesystem to host1, host2 or host3
will fail.

In my opinion, this behavior is extremely bogus. Unfortunately, I'm not
sure how to fix it. My current inclination is to do this:

- Modify vfs_hang_addrlist() to return some other error value for the
  'address already exists' case. Having it return EPERM seems like a
  bad idea anyway. I don't know what to use in it's place though.
  EEXIST sounds reasonable.

First thing I have to do is figure out if it's safe to just swap EPERM
with EEXIST: I need to find the exact function that actually adds the
address, which is trickier than it sounds. I think it's in /sys/net/radix.c.
Then I have to see if changing the return value screws up anythine else.

The alternative is to have mountd watch for a different error value in
do_mount(). This has the advantage of not requiring any kernel changes,
but somehow it doesn't feel quite right.

Anyone have any particular perference in this matter? Anyone have any
better ideas?

Anyone? Anyone?

Beuller?

-Bill

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~T~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Bill Paul            (212) 854-6020 | System Manager
Work:         wpaul@ctr.columbia.edu | Center for Telecommunications Research
Home:  wpaul@skynet.ctr.columbia.edu | Columbia University, New York City
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The Møøse Illuminati: ignore it and be confused, or join it and be confusing!
~~~~~~~~ FreeBSD 2.1.0-Development #0: Tue Mar 14 11:11:25 EST 1995 ~~~~~~~~~



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