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
This commit is contained in:
Dima Dorfman 2001-11-24 15:10:53 +00:00
parent c798b36242
commit 2f7a385114

View file

@ -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;