xref: /dragonfly/test/stress/stress2/misc/fpclone.sh (revision 36a3d1d6)
1#!/bin/sh
2
3#
4# Copyright (c) 2008 Peter Holm <pho@FreeBSD.org>
5# All rights reserved.
6#
7# Redistribution and use in source and binary forms, with or without
8# modification, are permitted provided that the following conditions
9# are met:
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.
15#
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
26# SUCH DAMAGE.
27#
28# $FreeBSD$
29#
30
31# Test scenario by kib@freebsd.org
32
33# Test of
34
35[ `id -u ` -ne 0 ] && echo "Must be root!" && exit 1
36
37. ../default.cfg
38
39odir=`pwd`
40dir=$RUNDIR/fpclone
41[ ! -d $dir ] && mkdir -p $dir
42
43cd $dir
44cat > Makefile <<EOF
45KMOD= fpclone
46SRCS= fpclone.c
47
48.include <bsd.kmod.mk>
49EOF
50
51sed '1,/^EOF2/d' < $odir/$0 > fpclone.c
52make
53kldload $dir/fpclone.ko
54
55cd $odir
56for i in `jot 10`; do
57	dd if=/dev/fpclone bs=1m count=10 > /dev/null 2>&1 &
58done
59
60export runRUNTIME=2m
61cd /home/pho/stress2; ./run.sh pty.cfg
62
63for i in `jot 10`; do
64	wait
65done
66kldstat
67dd if=/dev/fpclone bs=1m count=1k > /dev/null 2>&1 &
68kldunload $dir/fpclone.ko
69rm -rf $dir
70exit
71
72EOF2
73/* $FreeBSD$ */
74
75#include <sys/param.h>
76#include <sys/systm.h>
77#include <sys/kernel.h>
78#include <sys/module.h>
79#include <sys/conf.h>
80#include <sys/uio.h>
81#include <sys/malloc.h>
82
83typedef       void (*cdevpriv_dtr_t)(void *data);
84int   devfs_get_cdevpriv(void **datap);
85int   devfs_set_cdevpriv(void *priv, cdevpriv_dtr_t dtr);
86void  devfs_clear_cdevpriv(void);
87void  devfs_fpdrop(struct file *fp);  /* XXX This is not public KPI */
88
89
90static d_open_t		fpclone_open;
91static d_close_t	fpclone_close;
92static d_read_t		fpclone_read;
93
94static struct cdevsw fpclone_cdevsw = {
95	.d_open =	fpclone_open,
96	.d_close =	fpclone_close,
97	.d_read =	fpclone_read,
98	.d_name =	"fpclone",
99	.d_version =	D_VERSION,
100	.d_flags =	D_TRACKCLOSE
101};
102
103MALLOC_DEFINE(M_FPCLONESC, "fpclone memory", "fpclone memory");
104
105struct fpclone_sc
106{
107	int pos;
108};
109
110static struct cdev *fpclone_dev;
111static struct mtx me;
112
113static void
114fpclone_cdevpriv_dtr(void *data)
115{
116	free(data, M_FPCLONESC);
117}
118
119static int
120fpclone_open(struct cdev *dev, int oflags, int devtype, d_thread_t *td)
121{
122	struct fpclone_sc *sc;
123	int error;
124
125	sc = malloc(sizeof(struct fpclone_sc), M_FPCLONESC,
126	         M_WAITOK | M_ZERO);
127	error = devfs_set_cdevpriv(sc, fpclone_cdevpriv_dtr);
128	if (error)
129		fpclone_cdevpriv_dtr(sc);
130	return (error);
131}
132
133static int
134fpclone_close(struct cdev *dev, int fflag, int devtype, d_thread_t *td)
135{
136
137	devfs_clear_cdevpriv();
138	return (0);
139}
140
141static char rdata[] = "fpclone sample data string\n";
142
143static int
144fpclone_read(struct cdev *dev, struct uio *uio, int ioflag)
145{
146	struct fpclone_sc *sc;
147	int rv, amnt, svpos, error;
148
149	error = devfs_get_cdevpriv((void **)&sc);
150	if (error)
151		return (error);
152
153	rv = 0;
154	while (uio->uio_resid > 0) {
155		svpos = sc->pos;
156		amnt = MIN(uio->uio_resid, sizeof(rdata) - svpos);
157		rv = uiomove(rdata + svpos, amnt, uio);
158		if (rv != 0)
159			break;
160		mtx_lock(&me);
161		sc->pos += amnt;
162		sc->pos %= sizeof(rdata);
163		mtx_unlock(&me);
164	}
165	return (rv);
166}
167
168static int
169fpclone_modevent(module_t mod, int what, void *arg)
170{
171	switch (what) {
172        case MOD_LOAD:
173		mtx_init(&me, "fp_ref", NULL, MTX_DEF);
174		fpclone_dev = make_dev(&fpclone_cdevsw, 0, 0, 0, 0666,
175		    "fpclone");
176		return(0);
177
178        case MOD_UNLOAD:
179		destroy_dev(fpclone_dev);
180		mtx_destroy(&me);
181		return (0);
182
183        default:
184		break;
185	}
186
187	return (0);
188}
189
190moduledata_t fpclone_mdata = {
191	"fpclone",
192	fpclone_modevent,
193	NULL
194};
195
196DECLARE_MODULE(fpclone, fpclone_mdata, SI_SUB_DRIVERS, SI_ORDER_MIDDLE);
197MODULE_VERSION(fpclone, 1);
198