stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 1 | /* |
| 2 | * CDDL HEADER START |
| 3 | * |
| 4 | * The contents of this file are subject to the terms of the |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 5 | * Common Development and Distribution License (the "License"). |
| 6 | * You may not use this file except in compliance with the License. |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 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 | */ |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 21 | |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 22 | /* |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 23 | * Copyright 2006 Sun Microsystems, Inc. All rights reserved. |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 24 | * Use is subject to license terms. |
| 25 | */ |
| 26 | |
| 27 | #pragma ident "%Z%%M% %I% %E% SMI" |
| 28 | |
| 29 | /* |
| 30 | * Redirection STREAMS module. |
| 31 | * |
| 32 | * This module is intended for use in conjunction with instantiations of the |
| 33 | * redirection driver. Its purpose in life is to detect when the stream that |
| 34 | * it's pushed on is closed, thereupon calling back into the redirection |
| 35 | * driver so that the driver can cancel redirection to the stream. |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 36 | * It passes all messages on unchanged, in both directions. |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 37 | */ |
| 38 | |
| 39 | #include <sys/types.h> |
| 40 | #include <sys/param.h> |
| 41 | #include <sys/errno.h> |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 42 | #include <sys/stream.h> |
| 43 | #include <sys/stropts.h> |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 44 | #include <sys/debug.h> |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 45 | #include <sys/strredir.h> |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 46 | #include <sys/strsubr.h> |
ns92644 | e493d0f | 2006-08-02 08:27:50 -0700 | [diff] [blame] | 47 | #include <sys/strsun.h> |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 48 | #include <sys/conf.h> |
| 49 | #include <sys/ddi.h> |
| 50 | #include <sys/sunddi.h> |
| 51 | #include <sys/modctl.h> |
| 52 | |
| 53 | /* |
| 54 | * Forward declarations for private routines. |
| 55 | */ |
| 56 | static int wcmopen(queue_t *, dev_t *, int, int, cred_t *); |
| 57 | static int wcmclose(queue_t *, int, cred_t *); |
ns92644 | e493d0f | 2006-08-02 08:27:50 -0700 | [diff] [blame] | 58 | static int wcmrput(queue_t *, mblk_t *); |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 59 | |
| 60 | static struct module_info wcminfo = { |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 61 | STRREDIR_MODID, |
| 62 | STRREDIR_MOD, |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 63 | 0, |
| 64 | INFPSZ, |
| 65 | 5120, |
| 66 | 1024 |
| 67 | }; |
| 68 | |
| 69 | static struct qinit wcmrinit = { |
ns92644 | e493d0f | 2006-08-02 08:27:50 -0700 | [diff] [blame] | 70 | wcmrput, /* put */ |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 71 | NULL, /* service */ |
| 72 | wcmopen, /* open */ |
| 73 | wcmclose, /* close */ |
| 74 | NULL, /* qadmin */ |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 75 | &wcminfo, |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 76 | NULL /* mstat */ |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 77 | }; |
| 78 | |
| 79 | static struct qinit wcmwinit = { |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 80 | (int (*)())putnext, /* put */ |
| 81 | NULL, /* service */ |
| 82 | wcmopen, /* open */ |
| 83 | wcmclose, /* close */ |
| 84 | NULL, /* qadmin */ |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 85 | &wcminfo, |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 86 | NULL /* mstat */ |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 87 | }; |
| 88 | |
| 89 | static struct streamtab redirminfo = { |
| 90 | &wcmrinit, |
| 91 | &wcmwinit, |
| 92 | NULL, |
| 93 | NULL |
| 94 | }; |
| 95 | |
| 96 | static struct fmodsw fsw = { |
| 97 | "redirmod", |
| 98 | &redirminfo, |
edp | 8ec5a14 | 2006-04-28 18:39:47 -0700 | [diff] [blame] | 99 | D_MP |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 100 | }; |
| 101 | |
| 102 | static struct modlstrmod modlstrmod = { |
| 103 | &mod_strmodops, |
| 104 | "redirection module", |
| 105 | &fsw |
| 106 | }; |
| 107 | |
| 108 | static struct modlinkage modlinkage = { |
| 109 | MODREV_1, &modlstrmod, NULL |
| 110 | }; |
| 111 | |
| 112 | int |
| 113 | _init() |
| 114 | { |
| 115 | return (mod_install(&modlinkage)); |
| 116 | } |
| 117 | |
| 118 | int |
| 119 | _fini() |
| 120 | { |
| 121 | return (EBUSY); |
| 122 | } |
| 123 | |
| 124 | int |
| 125 | _info(struct modinfo *modinfop) |
| 126 | { |
| 127 | return (mod_info(&modlinkage, modinfop)); |
| 128 | } |
| 129 | |
| 130 | /* ARGSUSED */ |
| 131 | static int |
| 132 | wcmopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *cred) |
| 133 | { |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 134 | if (sflag != MODOPEN) |
| 135 | return (EINVAL); |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 136 | qprocson(q); |
| 137 | return (0); |
| 138 | } |
| 139 | |
| 140 | /* ARGSUSED */ |
| 141 | static int |
| 142 | wcmclose(queue_t *q, int flag, cred_t *cred) |
| 143 | { |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 144 | qprocsoff(q); |
ns92644 | e493d0f | 2006-08-02 08:27:50 -0700 | [diff] [blame] | 145 | srpop(q->q_stream->sd_vnode, B_TRUE); |
| 146 | return (0); |
| 147 | } |
| 148 | |
| 149 | /* |
| 150 | * Upstream messages are passed unchanged. |
| 151 | * If a hangup occurs the target is no longer usable, so deprecate it. |
| 152 | */ |
| 153 | static int |
| 154 | wcmrput(queue_t *q, mblk_t *mp) |
| 155 | { |
| 156 | if (DB_TYPE(mp) == M_HANGUP) |
| 157 | /* Don't block waiting for outstanding operations to complete */ |
| 158 | srpop(q->q_stream->sd_vnode, B_FALSE); |
| 159 | putnext(q, mp); |
stevel@tonic-gate | 7c478bd | 2005-06-14 00:00:00 -0700 | [diff] [blame] | 160 | return (0); |
| 161 | } |