4 # Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
7 # Redistribution and use in source and binary forms, with or without
8 # modification, are permitted provided that the following conditions
10 # 1. Redistributions of source code must retain the above copyright
11 # notice, this list of conditions and the following disclaimer.
12 # 2. Redistributions in binary form must reproduce the above copyright
13 # notice, this list of conditions and the following disclaimer in the
14 # documentation and/or other materials provided with the distribution.
16 # THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 # IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 # ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 # FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 # DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 # OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 # Test scenario by kib@freebsd.org
33 # Test of patch for Giant trick in cdevsw
35 exit # Test moved to fpclone*.sh
37 [ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
43 [ ! -d $dir ] && mkdir -p $dir
50 .include <bsd.kmod.mk>
53 sed '1,/^EOF2/d' < $odir/$0 > tclone.c
55 kldload $dir/tclone.ko
58 dd if=/dev/tclone bs=1m count=5k > /dev/null 2>&1 &
61 cd /home/pho/stress2; ./run.sh pty.cfg
64 kldunload $dir/tclone.ko
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/kernel.h>
74 #include <sys/module.h>
77 #include <sys/malloc.h>
79 static d_open_t tclone_open;
80 static d_close_t tclone_close;
81 static d_read_t tclone_read;
83 static struct cdevsw tclone_cdevsw = {
84 .d_open = tclone_open,
85 .d_close = tclone_close,
86 .d_read = tclone_read,
88 .d_version = D_VERSION,
89 .d_flags = D_TRACKCLOSE|D_NEEDGIANT
92 static eventhandler_tag tclone_ehtag;
93 static struct clonedevs *tclone_clones;
95 MALLOC_DEFINE(M_TCLONESC, "tclone memory", "tclone memory");
103 tclone_clone(void *arg, struct ucred *cred,
104 char *name, int namelen, struct cdev **dev)
110 if (strcmp(name, "tclone") != 0)
115 i = clone_create(&tclone_clones, &tclone_cdevsw,
119 } while ((clone <= CLONE_UNITMASK) && (i == 0));
121 if ((i != 0) && (clone <= CLONE_UNITMASK)) {
122 *dev = make_dev_credf(MAKEDEV_REF,
123 &tclone_cdevsw, unit2minor(clone),
124 cred, UID_ROOT, GID_WHEEL, 0666,
127 (*dev)->si_flags |= SI_CHEAPCLONE;
128 (*dev)->si_drv1 = (void *)1;
134 tclone_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
139 /* only allow one open() of this file */
140 dev->si_drv2 = malloc(sizeof(struct tclone_sc), M_TCLONESC,
147 /* XXX Fix me? (clear of SI_CHEAPCLONE) */
148 dev->si_flags &= ~SI_CHEAPCLONE;
155 tclone_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
160 dev->si_drv2 = &tclone_cdevsw;
161 if (x != &tclone_cdevsw)
163 destroy_dev_sched(dev);
167 static char rdata[] = "tclone sample data string\n";
170 tclone_read(struct cdev *dev, struct uio *uio, int ioflag)
172 struct tclone_sc *sc;
177 while (uio->uio_resid > 0) {
178 amnt = MIN(uio->uio_resid, sizeof(rdata) - sc->pos);
179 rv = uiomove(rdata + sc->pos, amnt, uio);
183 sc->pos %= sizeof(rdata);
189 tclone_modevent(module_t mod, int what, void *arg)
193 clone_setup(&tclone_clones);
194 tclone_ehtag = EVENTHANDLER_REGISTER(dev_clone,
196 if (tclone_ehtag == NULL)
201 EVENTHANDLER_DEREGISTER(dev_clone, tclone_ehtag);
202 drain_dev_clone_events();
203 clone_cleanup(&tclone_clones);
204 destroy_dev_drain(&tclone_cdevsw);
213 moduledata_t tclone_mdata = {
219 DECLARE_MODULE(tclone, tclone_mdata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
220 MODULE_VERSION(tclone, 1);