xref: /illumos-gate/usr/src/uts/common/io/strredirm.c (revision b68ab351091d2aea3f72a011f64de12fb05fc833)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 
22 /*
23  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
24  * Use is subject to license terms.
25  */
26 
27 /*
28  * Redirection STREAMS module.
29  *
30  * This module is intended for use in conjunction with instantiations of the
31  * redirection driver.  Its purpose in life is to detect when the stream that
32  * it's pushed on is closed, thereupon calling back into the redirection
33  * driver so that the driver can cancel redirection to the stream.
34  * It passes all messages on unchanged, in both directions.
35  */
36 
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/errno.h>
40 #include <sys/stream.h>
41 #include <sys/stropts.h>
42 #include <sys/debug.h>
43 #include <sys/strredir.h>
44 #include <sys/strsubr.h>
45 #include <sys/strsun.h>
46 #include <sys/conf.h>
47 #include <sys/ddi.h>
48 #include <sys/sunddi.h>
49 #include <sys/modctl.h>
50 
51 /*
52  * Forward declarations for private routines.
53  */
54 static int	wcmopen(queue_t	*, dev_t *, int, int, cred_t *);
55 static int	wcmclose(queue_t *, int, cred_t *);
56 static int	wcmrput(queue_t *, mblk_t *);
57 static int	wcmwput(queue_t *, mblk_t *);
58 
59 static struct module_info	wcminfo = {
60 	STRREDIR_MODID,
61 	STRREDIR_MOD,
62 	0,
63 	INFPSZ,
64 	5120,
65 	1024
66 };
67 
68 static struct qinit	wcmrinit = {
69 	wcmrput,		/* put */
70 	NULL,			/* service */
71 	wcmopen,		/* open */
72 	wcmclose,		/* close */
73 	NULL,			/* qadmin */
74 	&wcminfo,
75 	NULL			/* mstat */
76 };
77 
78 static struct qinit	wcmwinit = {
79 	wcmwput,		/* put */
80 	NULL,			/* service */
81 	wcmopen,		/* open */
82 	wcmclose,		/* close */
83 	NULL,			/* qadmin */
84 	&wcminfo,
85 	NULL			/* mstat */
86 };
87 
88 static struct streamtab	redirminfo = {
89 	&wcmrinit,
90 	&wcmwinit,
91 	NULL,
92 	NULL
93 };
94 
95 static struct fmodsw fsw = {
96 	"redirmod",
97 	&redirminfo,
98 	D_MP
99 };
100 
101 static struct modlstrmod modlstrmod = {
102 	&mod_strmodops,
103 	"redirection module",
104 	&fsw
105 };
106 
107 static struct modlinkage modlinkage = {
108 	MODREV_1, &modlstrmod, NULL
109 };
110 
111 int
112 _init()
113 {
114 	return (mod_install(&modlinkage));
115 }
116 
117 int
118 _fini()
119 {
120 	return (EBUSY);
121 }
122 
123 int
124 _info(struct modinfo *modinfop)
125 {
126 	return (mod_info(&modlinkage, modinfop));
127 }
128 
129 /* ARGSUSED */
130 static int
131 wcmopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *cred)
132 {
133 	if (sflag != MODOPEN)
134 		return (EINVAL);
135 	qprocson(q);
136 	return (0);
137 }
138 
139 /* ARGSUSED */
140 static int
141 wcmclose(queue_t *q, int flag, cred_t *cred)
142 {
143 	qprocsoff(q);
144 	srpop(q->q_stream->sd_vnode, B_TRUE);
145 	return (0);
146 }
147 
148 /*
149  * Upstream messages are passed unchanged.
150  * If a hangup occurs the target is no longer usable, so deprecate it.
151  */
152 static int
153 wcmrput(queue_t *q, mblk_t *mp)
154 {
155 	if (DB_TYPE(mp) == M_HANGUP)
156 		/* Don't block waiting for outstanding operations to complete */
157 		srpop(q->q_stream->sd_vnode, B_FALSE);
158 	putnext(q, mp);
159 	return (0);
160 }
161 
162 static int
163 wcmwput(queue_t *q, mblk_t *mp)
164 {
165 	putnext(q, mp);
166 	return (0);
167 }
168