Date: Tue, 19 Feb 2013 20:59:15 -0700 From: Jamie Gritton <jamie@FreeBSD.org> To: fs@FreeBSD.org Subject: mount/kldload race Message-ID: <51244A13.8030907@FreeBSD.org>
next in thread | raw e-mail | index | archive | help
This is a multi-part message in MIME format.
--------------080501010405030304090106
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Perhaps most people don't try to mount a bunch of filesystems at the
same time, at least not those that depend on kernel modules. But it
turns out that's going to be a pretty common situation with jails and
nullfs. And I found that when attempting such a feat will cause most of
these simultaneous mounts to fail with ENODEV.
It turns out that the problem is a race in vfs_byname_kld(). First it'll
see if the fstype is loaded, and if it isn't then it will load the
module. But if the module is loaded by a different process between those
two points, the resulting EEXIST from kern_kldload() will make
vfs_byname_kld() error out.
The fix is pretty simple: don't treat EEXIST as an error. By going on,
and rechecking for the fstype, the filesystem can be mounted while still
allowing any "real" error to be caught. I'm including a small patch that
will accomplish this, and I'd appreciate a quick look by anyone who's
familiar with this part of things before I commit it.
- Jamie
--------------080501010405030304090106
Content-Type: text/plain;
name="vfs_init.diff"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="vfs_init.diff"
Index: sys/kern/vfs_init.c
===================================================================
--- sys/kern/vfs_init.c (revision 247000)
+++ sys/kern/vfs_init.c (working copy)
@@ -130,13 +130,18 @@
/* Try to load the respective module. */
*error = kern_kldload(td, fstype, &fileid);
+ if (*error == EEXIST) {
+ *error = 0;
+ fileid = 0;
+ }
if (*error)
return (NULL);
/* Look up again to see if the VFS was loaded. */
vfsp = vfs_byname(fstype);
if (vfsp == NULL) {
- (void)kern_kldunload(td, fileid, LINKER_UNLOAD_FORCE);
+ if (fileid != 0)
+ (void)kern_kldunload(td, fileid, LINKER_UNLOAD_FORCE);
*error = ENODEV;
return (NULL);
}
--------------080501010405030304090106--
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?51244A13.8030907>
