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>