summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authordd <dd@FreeBSD.org>2001-11-24 15:10:53 +0000
committerdd <dd@FreeBSD.org>2001-11-24 15:10:53 +0000
commitc862b766f821c82c5ae19ba4e9dfe7bad08549b5 (patch)
treea04432674c2f72c024eba2166cc234072f738c9e /sys
parent7cb716c1004b287a9a7098af4cadbc6e9efc0c2e (diff)
downloadFreeBSD-src-c862b766f821c82c5ae19ba4e9dfe7bad08549b5.zip
FreeBSD-src-c862b766f821c82c5ae19ba4e9dfe7bad08549b5.tar.gz
Create a snpbasedev variable which holds a reference to the first snp
device cloned, and assign all further devices to depend on it. This allows us to call dev_depends() on it at module unload time to get rid of /dev/snp* (in the devfs case, anyway). For this to work, we must not destroy the device at close time. [Idea stolen from if_tun.] The above has the following sideaffects: (a) The snp device used by watch(8) will remain after watch(8) exits. This is probably how it should have been all along, and how it was before devfs came along. (b) Module unload doesn't panic if there are any /dev/snp* devices which haven't been used (and thus previously destroyed). Thus, we can reenable the unload functionality disabled in rev. 1.65. PR: 32012
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/snp/snp.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/sys/dev/snp/snp.c b/sys/dev/snp/snp.c
index b8343a9..e6cf797 100644
--- a/sys/dev/snp/snp.c
+++ b/sys/dev/snp/snp.c
@@ -103,6 +103,7 @@ static MALLOC_DEFINE(M_SNP, "snp", "Snoop device data");
* module load time.
*/
static int snooplinedisc;
+static udev_t snpbasedev = NOUDEV;
static LIST_HEAD(, snoop) snp_sclist = LIST_HEAD_INITIALIZER(&snp_sclist);
@@ -465,7 +466,6 @@ snpclose(dev, flags, fmt, td)
free(snp->snp_buf, M_SNP);
snp->snp_flags &= ~SNOOP_OPEN;
dev->si_drv1 = NULL;
- destroy_dev(dev);
return (snp_detach(snp));
}
@@ -614,6 +614,12 @@ snp_clone(arg, name, namelen, dev)
return;
*dev = make_dev(&snp_cdevsw, unit2minor(u), UID_ROOT, GID_WHEEL, 0600,
"snp%d", u);
+ if (snpbasedev == NOUDEV)
+ snpbasedev = (*dev)->si_udev;
+ else {
+ (*dev)->si_flags |= SI_CHEAPCLONE;
+ dev_depends(udev2dev(snpbasedev, 0), *dev);
+ }
}
static int
@@ -632,11 +638,11 @@ snp_modevent(mod, type, data)
cdevsw_add(&snp_cdevsw);
break;
case MOD_UNLOAD:
- /* XXX: temporarily prevent unload due to bugs in unloading. */
- return (EBUSY);
if (!LIST_EMPTY(&snp_sclist))
return (EBUSY);
EVENTHANDLER_DEREGISTER(dev_clone, eh_tag);
+ if (snpbasedev != NOUDEV)
+ destroy_dev(udev2dev(snpbasedev, 0));
ldisc_deregister(snooplinedisc);
cdevsw_remove(&snp_cdevsw);
break;
OpenPOWER on IntegriCloud