xref: /dragonfly/test/stress/stress2/misc/cdevsw.sh (revision 86d7f5d3)
1*86d7f5d3SJohn Marino#!/bin/sh
2*86d7f5d3SJohn Marino
3*86d7f5d3SJohn Marino#
4*86d7f5d3SJohn Marino# Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
5*86d7f5d3SJohn Marino# All rights reserved.
6*86d7f5d3SJohn Marino#
7*86d7f5d3SJohn Marino# Redistribution and use in source and binary forms, with or without
8*86d7f5d3SJohn Marino# modification, are permitted provided that the following conditions
9*86d7f5d3SJohn Marino# are met:
10*86d7f5d3SJohn Marino# 1. Redistributions of source code must retain the above copyright
11*86d7f5d3SJohn Marino#    notice, this list of conditions and the following disclaimer.
12*86d7f5d3SJohn Marino# 2. Redistributions in binary form must reproduce the above copyright
13*86d7f5d3SJohn Marino#    notice, this list of conditions and the following disclaimer in the
14*86d7f5d3SJohn Marino#    documentation and/or other materials provided with the distribution.
15*86d7f5d3SJohn Marino#
16*86d7f5d3SJohn Marino# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17*86d7f5d3SJohn Marino# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18*86d7f5d3SJohn Marino# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19*86d7f5d3SJohn Marino# ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20*86d7f5d3SJohn Marino# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21*86d7f5d3SJohn Marino# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22*86d7f5d3SJohn Marino# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23*86d7f5d3SJohn Marino# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24*86d7f5d3SJohn Marino# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25*86d7f5d3SJohn Marino# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26*86d7f5d3SJohn Marino# SUCH DAMAGE.
27*86d7f5d3SJohn Marino#
28*86d7f5d3SJohn Marino# $FreeBSD$
29*86d7f5d3SJohn Marino#
30*86d7f5d3SJohn Marino
31*86d7f5d3SJohn Marino# Test scenario by kib@freebsd.org
32*86d7f5d3SJohn Marino
33*86d7f5d3SJohn Marino# Test of patch for Giant trick in cdevsw
34*86d7f5d3SJohn Marino
35*86d7f5d3SJohn Marinoexit 	# Test moved to fpclone*.sh
36*86d7f5d3SJohn Marino
37*86d7f5d3SJohn Marino[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
38*86d7f5d3SJohn Marino
39*86d7f5d3SJohn Marino. ../default.cfg
40*86d7f5d3SJohn Marino
41*86d7f5d3SJohn Marinoodir=`pwd`
42*86d7f5d3SJohn Marinodir=$RUNDIR/tclone
43*86d7f5d3SJohn Marino[ ! -d $dir ] && mkdir -p $dir
44*86d7f5d3SJohn Marino
45*86d7f5d3SJohn Marinocd $dir
46*86d7f5d3SJohn Marinocat > Makefile <<EOF
47*86d7f5d3SJohn MarinoKMOD= tclone
48*86d7f5d3SJohn MarinoSRCS= tclone.c
49*86d7f5d3SJohn Marino
50*86d7f5d3SJohn Marino.include <bsd.kmod.mk>
51*86d7f5d3SJohn MarinoEOF
52*86d7f5d3SJohn Marino
53*86d7f5d3SJohn Marinosed '1,/^EOF2/d' < $odir/$0 > tclone.c
54*86d7f5d3SJohn Marinomake
55*86d7f5d3SJohn Marinokldload $dir/tclone.ko
56*86d7f5d3SJohn Marino
57*86d7f5d3SJohn Marinocd $odir
58*86d7f5d3SJohn Marinodd if=/dev/tclone bs=1m count=5k > /dev/null 2>&1 &
59*86d7f5d3SJohn Marino
60*86d7f5d3SJohn Marinoexport runRUNTIME=2m
61*86d7f5d3SJohn Marinocd /home/pho/stress2; ./run.sh pty.cfg
62*86d7f5d3SJohn Marino
63*86d7f5d3SJohn Marinokldstat
64*86d7f5d3SJohn Marinokldunload $dir/tclone.ko
65*86d7f5d3SJohn Marinorm -rf $dir
66*86d7f5d3SJohn Marinoexit
67*86d7f5d3SJohn Marino
68*86d7f5d3SJohn MarinoEOF2
69*86d7f5d3SJohn Marino/* $FreeBSD$ */
70*86d7f5d3SJohn Marino
71*86d7f5d3SJohn Marino#include <sys/param.h>
72*86d7f5d3SJohn Marino#include <sys/systm.h>
73*86d7f5d3SJohn Marino#include <sys/kernel.h>
74*86d7f5d3SJohn Marino#include <sys/module.h>
75*86d7f5d3SJohn Marino#include <sys/conf.h>
76*86d7f5d3SJohn Marino#include <sys/uio.h>
77*86d7f5d3SJohn Marino#include <sys/malloc.h>
78*86d7f5d3SJohn Marino
79*86d7f5d3SJohn Marinostatic d_open_t		tclone_open;
80*86d7f5d3SJohn Marinostatic d_close_t	tclone_close;
81*86d7f5d3SJohn Marinostatic d_read_t		tclone_read;
82*86d7f5d3SJohn Marino
83*86d7f5d3SJohn Marinostatic struct cdevsw tclone_cdevsw = {
84*86d7f5d3SJohn Marino	.d_open =	tclone_open,
85*86d7f5d3SJohn Marino	.d_close =	tclone_close,
86*86d7f5d3SJohn Marino	.d_read =	tclone_read,
87*86d7f5d3SJohn Marino	.d_name =	"tclone",
88*86d7f5d3SJohn Marino	.d_version =	D_VERSION,
89*86d7f5d3SJohn Marino	.d_flags =	D_TRACKCLOSE|D_NEEDGIANT
90*86d7f5d3SJohn Marino};
91*86d7f5d3SJohn Marino
92*86d7f5d3SJohn Marinostatic eventhandler_tag tclone_ehtag;
93*86d7f5d3SJohn Marinostatic struct clonedevs *tclone_clones;
94*86d7f5d3SJohn Marino
95*86d7f5d3SJohn MarinoMALLOC_DEFINE(M_TCLONESC, "tclone memory", "tclone memory");
96*86d7f5d3SJohn Marino
97*86d7f5d3SJohn Marinostruct tclone_sc
98*86d7f5d3SJohn Marino{
99*86d7f5d3SJohn Marino	int pos;
100*86d7f5d3SJohn Marino};
101*86d7f5d3SJohn Marino
102*86d7f5d3SJohn Marinostatic void
103*86d7f5d3SJohn Marinotclone_clone(void *arg, struct ucred *cred,
104*86d7f5d3SJohn Marino	     char *name, int namelen, struct cdev **dev)
105*86d7f5d3SJohn Marino{
106*86d7f5d3SJohn Marino	int i, clone;
107*86d7f5d3SJohn Marino
108*86d7f5d3SJohn Marino	if (*dev != NULL)
109*86d7f5d3SJohn Marino		return;
110*86d7f5d3SJohn Marino	if (strcmp(name, "tclone") != 0)
111*86d7f5d3SJohn Marino		return;
112*86d7f5d3SJohn Marino
113*86d7f5d3SJohn Marino	clone = 0;
114*86d7f5d3SJohn Marino	do {
115*86d7f5d3SJohn Marino		i = clone_create(&tclone_clones, &tclone_cdevsw,
116*86d7f5d3SJohn Marino				 &clone, dev, 0);
117*86d7f5d3SJohn Marino		if (i == 0)
118*86d7f5d3SJohn Marino			clone++;
119*86d7f5d3SJohn Marino	} while ((clone <= CLONE_UNITMASK) && (i == 0));
120*86d7f5d3SJohn Marino
121*86d7f5d3SJohn Marino	if ((i != 0) && (clone <= CLONE_UNITMASK)) {
122*86d7f5d3SJohn Marino		*dev = make_dev_credf(MAKEDEV_REF,
123*86d7f5d3SJohn Marino		    &tclone_cdevsw, unit2minor(clone),
124*86d7f5d3SJohn Marino		    cred, UID_ROOT, GID_WHEEL, 0666,
125*86d7f5d3SJohn Marino		    "tclone.%u", clone);
126*86d7f5d3SJohn Marino		if (*dev != NULL) {
127*86d7f5d3SJohn Marino			(*dev)->si_flags |= SI_CHEAPCLONE;
128*86d7f5d3SJohn Marino			(*dev)->si_drv1 = (void *)1;
129*86d7f5d3SJohn Marino		}
130*86d7f5d3SJohn Marino	}
131*86d7f5d3SJohn Marino}
132*86d7f5d3SJohn Marino
133*86d7f5d3SJohn Marinostatic int
134*86d7f5d3SJohn Marinotclone_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
135*86d7f5d3SJohn Marino{
136*86d7f5d3SJohn Marino	int status;
137*86d7f5d3SJohn Marino
138*86d7f5d3SJohn Marino	if (!dev->si_drv2) {
139*86d7f5d3SJohn Marino		/* only allow one open() of this file */
140*86d7f5d3SJohn Marino		dev->si_drv2 = malloc(sizeof(struct tclone_sc), M_TCLONESC,
141*86d7f5d3SJohn Marino		    M_WAITOK | M_ZERO);
142*86d7f5d3SJohn Marino		status = 0;
143*86d7f5d3SJohn Marino	} else
144*86d7f5d3SJohn Marino		status = EBUSY;
145*86d7f5d3SJohn Marino
146*86d7f5d3SJohn Marino	if (status == 0) {
147*86d7f5d3SJohn Marino		/* XXX Fix me? (clear of SI_CHEAPCLONE) */
148*86d7f5d3SJohn Marino		dev->si_flags &= ~SI_CHEAPCLONE;
149*86d7f5d3SJohn Marino	}
150*86d7f5d3SJohn Marino
151*86d7f5d3SJohn Marino	return (status);
152*86d7f5d3SJohn Marino}
153*86d7f5d3SJohn Marino
154*86d7f5d3SJohn Marinostatic int
155*86d7f5d3SJohn Marinotclone_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
156*86d7f5d3SJohn Marino{
157*86d7f5d3SJohn Marino	void *x;
158*86d7f5d3SJohn Marino
159*86d7f5d3SJohn Marino	x = dev->si_drv2;
160*86d7f5d3SJohn Marino	dev->si_drv2 = &tclone_cdevsw;
161*86d7f5d3SJohn Marino	if (x != &tclone_cdevsw)
162*86d7f5d3SJohn Marino		free(x, M_TCLONESC);
163*86d7f5d3SJohn Marino	destroy_dev_sched(dev);
164*86d7f5d3SJohn Marino	return (0);
165*86d7f5d3SJohn Marino}
166*86d7f5d3SJohn Marino
167*86d7f5d3SJohn Marinostatic char rdata[] = "tclone sample data string\n";
168*86d7f5d3SJohn Marino
169*86d7f5d3SJohn Marinostatic int
170*86d7f5d3SJohn Marinotclone_read(struct cdev *dev, struct uio *uio, int ioflag)
171*86d7f5d3SJohn Marino{
172*86d7f5d3SJohn Marino	struct tclone_sc *sc;
173*86d7f5d3SJohn Marino	int rv, amnt;
174*86d7f5d3SJohn Marino
175*86d7f5d3SJohn Marino	sc = dev->si_drv2;
176*86d7f5d3SJohn Marino	rv = 0;
177*86d7f5d3SJohn Marino	while (uio->uio_resid > 0) {
178*86d7f5d3SJohn Marino		amnt = MIN(uio->uio_resid, sizeof(rdata) - sc->pos);
179*86d7f5d3SJohn Marino		rv = uiomove(rdata + sc->pos, amnt, uio);
180*86d7f5d3SJohn Marino		if (rv != 0)
181*86d7f5d3SJohn Marino			break;
182*86d7f5d3SJohn Marino		sc->pos += amnt;
183*86d7f5d3SJohn Marino		sc->pos %= sizeof(rdata);
184*86d7f5d3SJohn Marino	}
185*86d7f5d3SJohn Marino	return (rv);
186*86d7f5d3SJohn Marino}
187*86d7f5d3SJohn Marino
188*86d7f5d3SJohn Marinostatic int
189*86d7f5d3SJohn Marinotclone_modevent(module_t mod, int what, void *arg)
190*86d7f5d3SJohn Marino{
191*86d7f5d3SJohn Marino	switch (what) {
192*86d7f5d3SJohn Marino        case MOD_LOAD:
193*86d7f5d3SJohn Marino		clone_setup(&tclone_clones);
194*86d7f5d3SJohn Marino		tclone_ehtag = EVENTHANDLER_REGISTER(dev_clone,
195*86d7f5d3SJohn Marino						     tclone_clone, 0, 0);
196*86d7f5d3SJohn Marino		if (tclone_ehtag == NULL)
197*86d7f5d3SJohn Marino			return ENOMEM;
198*86d7f5d3SJohn Marino		return(0);
199*86d7f5d3SJohn Marino
200*86d7f5d3SJohn Marino        case MOD_UNLOAD:
201*86d7f5d3SJohn Marino		EVENTHANDLER_DEREGISTER(dev_clone, tclone_ehtag);
202*86d7f5d3SJohn Marino		drain_dev_clone_events();
203*86d7f5d3SJohn Marino		clone_cleanup(&tclone_clones);
204*86d7f5d3SJohn Marino		destroy_dev_drain(&tclone_cdevsw);
205*86d7f5d3SJohn Marino		return (0);
206*86d7f5d3SJohn Marino        default:
207*86d7f5d3SJohn Marino		break;
208*86d7f5d3SJohn Marino	}
209*86d7f5d3SJohn Marino
210*86d7f5d3SJohn Marino	return (0);
211*86d7f5d3SJohn Marino}
212*86d7f5d3SJohn Marino
213*86d7f5d3SJohn Marinomoduledata_t tclone_mdata = {
214*86d7f5d3SJohn Marino	"tclone",
215*86d7f5d3SJohn Marino	tclone_modevent,
216*86d7f5d3SJohn Marino	NULL
217*86d7f5d3SJohn Marino};
218*86d7f5d3SJohn Marino
219*86d7f5d3SJohn MarinoDECLARE_MODULE(tclone, tclone_mdata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
220*86d7f5d3SJohn MarinoMODULE_VERSION(tclone, 1);
221