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