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 #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. 36 * It passes all messages on unchanged, in both directions. 37 */ 38 39 #include <sys/types.h> 40 #include <sys/param.h> 41 #include <sys/errno.h> 42 #include <sys/stream.h> 43 #include <sys/stropts.h> 44 #include <sys/debug.h> 45 #include <sys/strredir.h> 46 #include <sys/strsubr.h> 47 #include <sys/strsun.h> 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 *); 58 static int wcmrput(queue_t *, mblk_t *); 59 60 static struct module_info wcminfo = { 61 STRREDIR_MODID, 62 STRREDIR_MOD, 63 0, 64 INFPSZ, 65 5120, 66 1024 67 }; 68 69 static struct qinit wcmrinit = { 70 wcmrput, /* put */ 71 NULL, /* service */ 72 wcmopen, /* open */ 73 wcmclose, /* close */ 74 NULL, /* qadmin */ 75 &wcminfo, 76 NULL /* mstat */ 77 }; 78 79 static struct qinit wcmwinit = { 80 (int (*)())putnext, /* put */ 81 NULL, /* service */ 82 wcmopen, /* open */ 83 wcmclose, /* close */ 84 NULL, /* qadmin */ 85 &wcminfo, 86 NULL /* mstat */ 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, 99 D_MP 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 { 134 if (sflag != MODOPEN) 135 return (EINVAL); 136 qprocson(q); 137 return (0); 138 } 139 140 /* ARGSUSED */ 141 static int 142 wcmclose(queue_t *q, int flag, cred_t *cred) 143 { 144 qprocsoff(q); 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); 160 return (0); 161 }