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