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 58 static struct module_info wcminfo = { 59 STRREDIR_MODID, 60 STRREDIR_MOD, 61 0, 62 INFPSZ, 63 5120, 64 1024 65 }; 66 67 static struct qinit wcmrinit = { 68 wcmrput, /* put */ 69 NULL, /* service */ 70 wcmopen, /* open */ 71 wcmclose, /* close */ 72 NULL, /* qadmin */ 73 &wcminfo, 74 NULL /* mstat */ 75 }; 76 77 static struct qinit wcmwinit = { 78 (int (*)())putnext, /* put */ 79 NULL, /* service */ 80 wcmopen, /* open */ 81 wcmclose, /* close */ 82 NULL, /* qadmin */ 83 &wcminfo, 84 NULL /* mstat */ 85 }; 86 87 static struct streamtab redirminfo = { 88 &wcmrinit, 89 &wcmwinit, 90 NULL, 91 NULL 92 }; 93 94 static struct fmodsw fsw = { 95 "redirmod", 96 &redirminfo, 97 D_MP 98 }; 99 100 static struct modlstrmod modlstrmod = { 101 &mod_strmodops, 102 "redirection module", 103 &fsw 104 }; 105 106 static struct modlinkage modlinkage = { 107 MODREV_1, { &modlstrmod, NULL } 108 }; 109 110 int 111 _init() 112 { 113 return (mod_install(&modlinkage)); 114 } 115 116 int 117 _fini() 118 { 119 return (EBUSY); 120 } 121 122 int 123 _info(struct modinfo *modinfop) 124 { 125 return (mod_info(&modlinkage, modinfop)); 126 } 127 128 /* ARGSUSED */ 129 static int 130 wcmopen(queue_t *q, dev_t *dev, int flag, int sflag, cred_t *cred) 131 { 132 if (sflag != MODOPEN) 133 return (EINVAL); 134 qprocson(q); 135 return (0); 136 } 137 138 /* ARGSUSED */ 139 static int 140 wcmclose(queue_t *q, int flag, cred_t *cred) 141 { 142 qprocsoff(q); 143 srpop(q->q_stream->sd_vnode, B_TRUE); 144 return (0); 145 } 146 147 /* 148 * Upstream messages are passed unchanged. 149 * If a hangup occurs the target is no longer usable, so deprecate it. 150 */ 151 static int 152 wcmrput(queue_t *q, mblk_t *mp) 153 { 154 if (DB_TYPE(mp) == M_HANGUP) 155 /* Don't block waiting for outstanding operations to complete */ 156 srpop(q->q_stream->sd_vnode, B_FALSE); 157 putnext(q, mp); 158 return (0); 159 }