There are two ways to create a tun device, via devfs cloning or with
ifconfig. The latter is implemented by tun_clone_create() and the
former by tunclone(), which invokes tun_clone_create() via
if_clone_create(). Both of these functions were invoking dev_ref()
after creating the devfs_node(), but this was extraneous. tunclone()
does need to acquire an extra reference since this is required by the
dev_clone EVENTHANDLER interface contract, but it was already doing so
by specifying MAKEDEV_REF. Fix this by removing unnecessary refcount
acquisitions.
A second problem is with teardown in a VNET jail. A tun interface
created by device cloning will hold a credential reference for the jail,
which prevents it from being destroyed and in particular prevents VNET
SYSUNINITs from running. To fix this, we need to register a
PR_METHOD_REMOVE callback for jail teardown which, in a VNET jail,
destroys cloned interfaces. This way, jail teardown can proceed.
These bugs are noticeable with something like
- jail -c name=test vnet command=ls /dev/tun
- jls -vd
Without this patch, the jail gets stuck in the DYING state.
While here, add some comments and be sure to destroy a nascent mutex and
CV in an error path.