Skip site navigation (1)Skip section navigation (2)
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>