Print this page
14249 pseudo-terminal nomenclature should reflect POSIX
Change-Id: Ib4a3cef899ff4c71b09cb0dc6878863c5e8357bc
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/uts/common/io/zcons.c
+++ new/usr/src/uts/common/io/zcons.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
↓ open down ↓ |
22 lines elided |
↑ open up ↑ |
23 23 * Use is subject to license terms.
24 24 */
25 25
26 26
27 27 /*
28 28 * Zone Console Driver.
29 29 *
30 30 * This driver, derived from the pts/ptm drivers, is the pseudo console driver
31 31 * for system zones. Its implementation is straightforward. Each instance
32 32 * of the driver represents a global-zone/local-zone pair (this maps in a
33 - * straightforward way to the commonly used terminal notion of "master side"
34 - * and "slave side", and we use that terminology throughout).
33 + * straightforward way to the commonly used terminal notion of "manager side"
34 + * and "subsidiary side", and we use that terminology throughout).
35 35 *
36 36 * Instances of zcons are onlined as children of /pseudo/zconsnex@1/
37 37 * by zoneadmd in userland, using the devctl framework; thus the driver
38 38 * does not need to maintain any sort of "admin" node.
39 39 *
40 - * The driver shuttles I/O from master side to slave side and back. In a break
41 - * from the pts/ptm semantics, if one side is not open, I/O directed towards
42 - * it will simply be discarded. This is so that if zoneadmd is not holding
43 - * the master side console open (i.e. it has died somehow), processes in
44 - * the zone do not experience any errors and I/O to the console does not
40 + * The driver shuttles I/O from manager side to subsidiary side and back. In a
41 + * break from the pts/ptm semantics, if one side is not open, I/O directed
42 + * towards it will simply be discarded. This is so that if zoneadmd is not
43 + * holding the manager side console open (i.e. it has died somehow), processes
44 + * in the zone do not experience any errors and I/O to the console does not
45 45 * hang.
46 46 *
47 47 * TODO: we may want to revisit the other direction; i.e. we may want
48 48 * zoneadmd to be able to detect whether no zone processes are holding the
49 49 * console open, an unusual situation.
50 50 *
51 51 *
52 52 *
53 - * MASTER SIDE IOCTLS
53 + * MANAGER SIDE IOCTLS
54 54 *
55 - * The ZC_HOLDSLAVE and ZC_RELEASESLAVE ioctls instruct the master side of the
56 - * console to hold and release a reference to the slave side's vnode. They are
57 - * meant to be issued by zoneadmd after the console device node is created and
58 - * before it is destroyed so that the slave's STREAMS anchor, ptem, is
59 - * preserved when ttymon starts popping STREAMS modules from within the
60 - * associated zone. This guarantees that the zone console will always have
55 + * The ZC_HOLDSUBSID and ZC_RELEASESUBSID ioctls instruct the manager side of
56 + * the console to hold and release a reference to the subsidiary side's vnode.
57 + * They are meant to be issued by zoneadmd after the console device node is
58 + * created and before it is destroyed so that the subsidiary's STREAMS anchor,
59 + * ptem, is preserved when ttymon starts popping STREAMS modules from within
60 + * the associated zone. This guarantees that the zone console will always have
61 61 * terminal semantics while the zone is running.
62 62 *
63 63 * Here is the issue: the ptem module is anchored in the zone console
64 - * (slave side) so that processes within the associated non-global zone will
65 - * fail to pop it off, thus ensuring that the slave will retain terminal
66 - * semantics. When a process attempts to pop the anchor off of a stream, the
67 - * STREAMS subsystem checks whether the calling process' zone is the same as
68 - * that of the process that pushed the anchor onto the stream and cancels the
69 - * pop if they differ. zoneadmd used to hold an open file descriptor for the
70 - * slave while the associated non-global zone ran, thus ensuring that the
71 - * slave's STREAMS anchor would never be popped from within the non-global zone
72 - * (because zoneadmd runs in the global zone). However, this file descriptor
73 - * was removed to make zone console management more robust. sad(7D) is now
74 - * used to automatically set up the slave's STREAMS modules when the zone
75 - * console is freshly opened within the associated non-global zone. However,
76 - * when a process within the non-global zone freshly opens the zone console, the
77 - * anchor is pushed from within the non-global zone, making it possible for
78 - * processes within the non-global zone (e.g., ttymon) to pop the anchor and
79 - * destroy the zone console's terminal semantics.
64 + * (subsidiary side) so that processes within the associated non-global zone
65 + * will fail to pop it off, thus ensuring that the subsidiary will retain
66 + * terminal semantics. When a process attempts to pop the anchor off of a
67 + * stream, the STREAMS subsystem checks whether the calling process' zone is
68 + * the same as that of the process that pushed the anchor onto the stream and
69 + * cancels the pop if they differ. zoneadmd used to hold an open file
70 + * descriptor for the subsidiary while the associated non-global zone ran, thus
71 + * ensuring that the subsidiary's STREAMS anchor would never be popped from
72 + * within the non-global zone (because zoneadmd runs in the global zone).
73 + * However, this file descriptor was removed to make zone console management
74 + * more robust. sad(7D) is now used to automatically set up the subsidiary's
75 + * STREAMS modules when the zone console is freshly opened within the
76 + * associated non-global zone. However, when a process within the non-global
77 + * zone freshly opens the zone console, the anchor is pushed from within the
78 + * non-global zone, making it possible for processes within the non-global zone
79 + * (e.g., ttymon) to pop the anchor and destroy the zone console's terminal
80 + * semantics.
80 81 *
81 - * One solution is to make the zcons device hold the slave open while the
82 + * One solution is to make the zcons device hold the subsidiary open while the
82 83 * associated non-global zone runs so that the STREAMS anchor will always be
83 - * associated with the global zone. Unfortunately, the slave cannot be opened
84 - * from within the zcons driver because the driver is not reentrant: it has
85 - * an outer STREAMS perimeter. Therefore, the next best option is for zcons to
86 - * provide an ioctl interface to zoneadmd to manage holding and releasing
87 - * the slave side of the console. It is sufficient to hold the slave side's
88 - * vnode and bump the associated snode's reference count to preserve the slave's
89 - * STREAMS configuration while the associated zone runs, so that's what the
90 - * ioctls do.
84 + * associated with the global zone. Unfortunately, the subsidiary cannot be
85 + * opened from within the zcons driver because the driver is not reentrant: it
86 + * has an outer STREAMS perimeter. Therefore, the next best option is for
87 + * zcons to provide an ioctl interface to zoneadmd to manage holding and
88 + * releasing the subsidiary side of the console. It is sufficient to hold the
89 + * subsidiary side's vnode and bump the associated snode's reference count to
90 + * preserve the subsidiary's STREAMS configuration while the associated zone
91 + * runs, so that's what the ioctls do.
91 92 *
92 93 *
93 - * ZC_HOLDSLAVE
94 + * ZC_HOLDSUBSID
94 95 *
95 96 * This ioctl takes a file descriptor as an argument. It effectively gets a
96 - * reference to the slave side's minor node's vnode and bumps the associated
97 - * snode's reference count. The vnode reference is stored in the zcons device
98 - * node's soft state. This ioctl succeeds if the given file descriptor refers
99 - * to the slave side's minor node or if there is already a reference to the
100 - * slave side's minor node's vnode in the device's soft state.
97 + * reference to the subsidiary side's minor node's vnode and bumps the
98 + * associated snode's reference count. The vnode reference is stored in the
99 + * zcons device node's soft state. This ioctl succeeds if the given file
100 + * descriptor refers to the subsidiary side's minor node or if there is already
101 + * a reference to the subsidiary side's minor node's vnode in the device's soft
102 + * state.
101 103 *
102 104 *
103 - * ZC_RELEASESLAVE
105 + * ZC_RELEASESUBSID
104 106 *
105 107 * This ioctl takes a file descriptor as an argument. It effectively releases
106 108 * the vnode reference stored in the zcons device node's soft state (which was
107 - * previously acquired via ZC_HOLDSLAVE) and decrements the reference count of
109 + * previously acquired via ZC_HOLDSUBSID) and decrements the reference count of
108 110 * the snode associated with the vnode. This ioctl succeeds if the given file
109 - * descriptor refers to the slave side's minor node or if no reference to the
110 - * slave side's minor node's vnode is stored in the device's soft state.
111 + * descriptor refers to the subsidiary side's minor node or if no reference to
112 + * the subsidiary side's minor node's vnode is stored in the device's soft
113 + * state.
111 114 *
112 115 *
113 116 * Note that the file descriptor arguments for both ioctls must be cast to
114 117 * integers of pointer width.
115 118 *
116 119 * Here's how the dance between zcons and zoneadmd works:
117 120 *
118 121 * Zone boot:
119 122 * 1. While booting the zone, zoneadmd creates an instance of zcons.
120 - * 2. zoneadmd opens the master and slave sides of the new zone console
121 - * and issues the ZC_HOLDSLAVE ioctl on the master side, passing its
122 - * file descriptor for the slave side as the ioctl argument.
123 - * 3. zcons holds the slave side's vnode, bumps the snode's reference
123 + * 2. zoneadmd opens the manager and subsidiary sides of the new zone
124 + * console and issues the ZC_HOLDSUBSID ioctl on the manager side,
125 + * passing its file descriptor for the subsidiary side as the ioctl
126 + * argument.
127 + * 3. zcons holds the subsidiary side's vnode, bumps the snode's reference
124 128 * count, and stores a pointer to the vnode in the device's soft
125 129 * state.
126 - * 4. zoneadmd closes the master and slave sides and continues to boot
127 - * the zone.
130 + * 4. zoneadmd closes the manager and subsidiary sides and continues to
131 + * boot the zone.
128 132 *
129 133 * Zone halt:
130 - * 1. While halting the zone, zoneadmd opens the master and slave sides
131 - * of the zone's console and issues the ZC_RELEASESLAVE ioctl on the
132 - * master side, passing its file descriptor for the slave side as the
133 - * ioctl argument.
134 - * 2. zcons decrements the slave side's snode's reference count, releases
135 - * the slave's vnode, and eliminates its reference to the vnode in the
136 - * device's soft state.
137 - * 3. zoneadmd closes the master and slave sides.
134 + * 1. While halting the zone, zoneadmd opens the manager and subsidiary
135 + * sides of the zone's console and issues the ZC_RELEASESUBSID ioctl on
136 + * the manager side, passing its file descriptor for the subsidiary
137 + * side as the ioctl argument.
138 + * 2. zcons decrements the subsidiary side's snode's reference count,
139 + * releases the subsidiary's vnode, and eliminates its reference to the
140 + * vnode in the device's soft state.
141 + * 3. zoneadmd closes the manager and subsidiary sides.
138 142 * 4. zoneadmd destroys the zcons device and continues to halt the zone.
139 143 *
140 - * It is necessary for zoneadmd to hold the slave open while issuing
141 - * ZC_RELEASESLAVE because zcons might otherwise release the last reference to
142 - * the slave's vnode. If it does, then specfs will panic because it will expect
143 - * that the STREAMS configuration for the vnode was destroyed, which VN_RELE
144 - * doesn't do. Forcing zoneadmd to hold the slave open guarantees that zcons
145 - * won't release the vnode's last reference. zoneadmd will properly destroy the
146 - * vnode and the snode when it closes the file descriptor.
144 + * It is necessary for zoneadmd to hold the subsidiary open while issuing
145 + * ZC_RELEASESUBSID because zcons might otherwise release the last reference to
146 + * the subsidiary's vnode. If it does, then specfs will panic because it will
147 + * expect that the STREAMS configuration for the vnode was destroyed, which
148 + * VN_RELE doesn't do. Forcing zoneadmd to hold the subsidiary open guarantees
149 + * that zcons won't release the vnode's last reference. zoneadmd will properly
150 + * destroy the vnode and the snode when it closes the file descriptor.
147 151 *
148 - * Technically, any process that can access the master side can issue these
152 + * Technically, any process that can access the manager side can issue these
149 153 * ioctls, but they should be treated as private interfaces for zoneadmd.
150 154 */
151 155
152 156 #include <sys/types.h>
153 157 #include <sys/cmn_err.h>
154 158 #include <sys/conf.h>
155 159 #include <sys/cred.h>
156 160 #include <sys/ddi.h>
157 161 #include <sys/debug.h>
158 162 #include <sys/devops.h>
159 163 #include <sys/errno.h>
160 164 #include <sys/file.h>
161 165 #include <sys/kstr.h>
162 166 #include <sys/modctl.h>
163 167 #include <sys/param.h>
164 168 #include <sys/stat.h>
165 169 #include <sys/stream.h>
166 170 #include <sys/stropts.h>
167 171 #include <sys/strsun.h>
168 172 #include <sys/sunddi.h>
169 173 #include <sys/sysmacros.h>
170 174 #include <sys/systm.h>
171 175 #include <sys/types.h>
172 176 #include <sys/zcons.h>
173 177 #include <sys/vnode.h>
174 178 #include <sys/fs/snode.h>
175 179 #include <sys/zone.h>
176 180
177 181 static int zc_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
178 182 static int zc_attach(dev_info_t *, ddi_attach_cmd_t);
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
179 183 static int zc_detach(dev_info_t *, ddi_detach_cmd_t);
180 184
181 185 static int zc_open(queue_t *, dev_t *, int, int, cred_t *);
182 186 static int zc_close(queue_t *, int, cred_t *);
183 187 static int zc_wput(queue_t *, mblk_t *);
184 188 static int zc_rsrv(queue_t *);
185 189 static int zc_wsrv(queue_t *);
186 190
187 191 /*
188 192 * The instance number is encoded in the dev_t in the minor number; the lowest
189 - * bit of the minor number is used to track the master vs. slave side of the
190 - * virtual console. The rest of the bits in the minor number are the instance.
193 + * bit of the minor number is used to track the manager vs. subsidiary side of
194 + * the virtual console. The rest of the bits in the minor number are the
195 + * instance.
191 196 */
192 -#define ZC_MASTER_MINOR 0
193 -#define ZC_SLAVE_MINOR 1
197 +#define ZC_MANAGER_MINOR 0
198 +#define ZC_SUBSID_MINOR 1
194 199
195 200 #define ZC_INSTANCE(x) (getminor((x)) >> 1)
196 201 #define ZC_NODE(x) (getminor((x)) & 0x01)
197 202
198 203 /*
199 - * This macro converts a zc_state_t pointer to the associated slave minor node's
200 - * dev_t.
204 + * This macro converts a zc_state_t pointer to the associated subsidiary minor
205 + * node's dev_t.
201 206 */
202 -#define ZC_STATE_TO_SLAVEDEV(x) (makedevice(ddi_driver_major((x)->zc_devinfo), \
203 - (minor_t)(ddi_get_instance((x)->zc_devinfo) << 1 | ZC_SLAVE_MINOR)))
207 +#define ZC_STATE_TO_SUBDEV(x) (makedevice(ddi_driver_major((x)->zc_devinfo), \
208 + (minor_t)(ddi_get_instance((x)->zc_devinfo) << 1 | ZC_SUBSID_MINOR)))
204 209
205 210 int zcons_debug = 0;
206 211 #define DBG(a) if (zcons_debug) cmn_err(CE_NOTE, a)
207 212 #define DBG1(a, b) if (zcons_debug) cmn_err(CE_NOTE, a, b)
208 213
209 214
210 215 /*
211 216 * Zone Console Pseudo Terminal Module: stream data structure definitions
212 217 */
213 218 static struct module_info zc_info = {
214 219 31337, /* c0z we r hAx0rs */
215 220 "zcons",
216 221 0,
217 222 INFPSZ,
218 223 _TTY_BUFSIZ,
219 224 128
220 225 };
221 226
222 227 static struct qinit zc_rinit = {
223 228 NULL,
224 229 zc_rsrv,
225 230 zc_open,
226 231 zc_close,
227 232 NULL,
228 233 &zc_info,
229 234 NULL
230 235 };
231 236
232 237 static struct qinit zc_winit = {
233 238 zc_wput,
234 239 zc_wsrv,
235 240 NULL,
236 241 NULL,
237 242 NULL,
238 243 &zc_info,
239 244 NULL
240 245 };
241 246
242 247 static struct streamtab zc_tab_info = {
243 248 &zc_rinit,
244 249 &zc_winit,
245 250 NULL,
246 251 NULL
247 252 };
248 253
249 254 #define ZC_CONF_FLAG (D_MP | D_MTQPAIR | D_MTOUTPERIM | D_MTOCEXCL)
250 255
251 256 /*
252 257 * this will define (struct cb_ops cb_zc_ops) and (struct dev_ops zc_ops)
253 258 */
254 259 DDI_DEFINE_STREAM_OPS(zc_ops, nulldev, nulldev, zc_attach, zc_detach, nodev, \
255 260 zc_getinfo, ZC_CONF_FLAG, &zc_tab_info, ddi_quiesce_not_needed);
256 261
257 262 /*
258 263 * Module linkage information for the kernel.
259 264 */
260 265
261 266 static struct modldrv modldrv = {
262 267 &mod_driverops, /* Type of module (this is a pseudo driver) */
263 268 "Zone console driver", /* description of module */
264 269 &zc_ops /* driver ops */
↓ open down ↓ |
51 lines elided |
↑ open up ↑ |
265 270 };
266 271
267 272 static struct modlinkage modlinkage = {
268 273 MODREV_1,
269 274 &modldrv,
270 275 NULL
271 276 };
272 277
273 278 typedef struct zc_state {
274 279 dev_info_t *zc_devinfo;
275 - queue_t *zc_master_rdq;
276 - queue_t *zc_slave_rdq;
277 - vnode_t *zc_slave_vnode;
280 + queue_t *zc_manager_rdq;
281 + queue_t *zc_subsid_rdq;
282 + vnode_t *zc_subsid_vnode;
278 283 int zc_state;
279 284 } zc_state_t;
280 285
281 286 #define ZC_STATE_MOPEN 0x01
282 287 #define ZC_STATE_SOPEN 0x02
283 288
284 289 static void *zc_soft_state;
285 290
286 291 /*
287 - * List of STREAMS modules that should be pushed onto every slave instance.
292 + * List of STREAMS modules that should be pushed onto every subsidiary instance.
288 293 */
289 294 static char *zcons_mods[] = {
290 295 "ptem",
291 296 "ldterm",
292 297 "ttcompat",
293 298 NULL
294 299 };
295 300
296 301 int
297 302 _init(void)
298 303 {
299 304 int err;
300 305
301 306 if ((err = ddi_soft_state_init(&zc_soft_state,
302 307 sizeof (zc_state_t), 0)) != 0) {
303 308 return (err);
304 309 }
305 310
306 311 if ((err = mod_install(&modlinkage)) != 0)
307 312 ddi_soft_state_fini(zc_soft_state);
308 313
309 314 return (err);
310 315 }
311 316
312 317
313 318 int
314 319 _fini(void)
315 320 {
316 321 int err;
317 322
318 323 if ((err = mod_remove(&modlinkage)) != 0) {
319 324 return (err);
320 325 }
321 326
322 327 ddi_soft_state_fini(&zc_soft_state);
323 328 return (0);
324 329 }
325 330
326 331 int
327 332 _info(struct modinfo *modinfop)
328 333 {
329 334 return (mod_info(&modlinkage, modinfop));
330 335 }
331 336
332 337 static int
333 338 zc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
334 339 {
335 340 zc_state_t *zcs;
↓ open down ↓ |
38 lines elided |
↑ open up ↑ |
336 341 int instance;
337 342
338 343 if (cmd != DDI_ATTACH)
339 344 return (DDI_FAILURE);
340 345
341 346 instance = ddi_get_instance(dip);
342 347 if (ddi_soft_state_zalloc(zc_soft_state, instance) != DDI_SUCCESS)
343 348 return (DDI_FAILURE);
344 349
345 350 /*
346 - * Create the master and slave minor nodes.
351 + * Create the manager and subsidiary minor nodes.
347 352 */
348 - if ((ddi_create_minor_node(dip, ZCONS_SLAVE_NAME, S_IFCHR,
349 - instance << 1 | ZC_SLAVE_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE) ||
350 - (ddi_create_minor_node(dip, ZCONS_MASTER_NAME, S_IFCHR,
351 - instance << 1 | ZC_MASTER_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE)) {
353 + if ((ddi_create_minor_node(dip, ZCONS_SUBSIDIARY_NAME, S_IFCHR,
354 + instance << 1 | ZC_SUBSID_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE) ||
355 + (ddi_create_minor_node(dip, ZCONS_MANAGER_NAME, S_IFCHR,
356 + instance << 1 | ZC_MANAGER_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE)) {
352 357 ddi_remove_minor_node(dip, NULL);
353 358 ddi_soft_state_free(zc_soft_state, instance);
354 359 return (DDI_FAILURE);
355 360 }
356 361
357 362 VERIFY((zcs = ddi_get_soft_state(zc_soft_state, instance)) != NULL);
358 363 zcs->zc_devinfo = dip;
359 364 return (DDI_SUCCESS);
360 365 }
361 366
362 367 static int
363 368 zc_detach(dev_info_t *dip, ddi_detach_cmd_t cmd)
364 369 {
365 370 zc_state_t *zcs;
366 371 int instance;
367 372
368 373 if (cmd != DDI_DETACH)
369 374 return (DDI_FAILURE);
370 375
371 376 instance = ddi_get_instance(dip);
372 377 if ((zcs = ddi_get_soft_state(zc_soft_state, instance)) == NULL)
373 378 return (DDI_FAILURE);
374 379
375 380 if ((zcs->zc_state & ZC_STATE_MOPEN) ||
376 381 (zcs->zc_state & ZC_STATE_SOPEN)) {
377 382 DBG1("zc_detach: device (dip=%p) still open\n", (void *)dip);
378 383 return (DDI_FAILURE);
379 384 }
380 385
↓ open down ↓ |
19 lines elided |
↑ open up ↑ |
381 386 ddi_remove_minor_node(dip, NULL);
382 387 ddi_soft_state_free(zc_soft_state, instance);
383 388
384 389 return (DDI_SUCCESS);
385 390 }
386 391
387 392 /*
388 393 * zc_getinfo()
389 394 * getinfo(9e) entrypoint.
390 395 */
391 -/*ARGSUSED*/
392 396 static int
393 397 zc_getinfo(dev_info_t *dip, ddi_info_cmd_t infocmd, void *arg, void **result)
394 398 {
395 399 zc_state_t *zcs;
396 400 int instance = ZC_INSTANCE((dev_t)arg);
397 401
398 402 switch (infocmd) {
399 403 case DDI_INFO_DEVT2DEVINFO:
400 404 if ((zcs = ddi_get_soft_state(zc_soft_state, instance)) == NULL)
401 405 return (DDI_FAILURE);
402 406 *result = zcs->zc_devinfo;
↓ open down ↓ |
1 lines elided |
↑ open up ↑ |
403 407 return (DDI_SUCCESS);
404 408 case DDI_INFO_DEVT2INSTANCE:
405 409 *result = (void *)(uintptr_t)instance;
406 410 return (DDI_SUCCESS);
407 411 }
408 412 return (DDI_FAILURE);
409 413 }
410 414
411 415 /*
412 416 * Return the equivalent queue from the other side of the relationship.
413 - * e.g.: given the slave's write queue, return the master's write queue.
417 + * e.g.: given the subsidiary's write queue, return the manager's write queue.
414 418 */
415 419 static queue_t *
416 420 zc_switch(queue_t *qp)
417 421 {
418 422 zc_state_t *zcs = qp->q_ptr;
419 423 ASSERT(zcs != NULL);
420 424
421 - if (qp == zcs->zc_master_rdq)
422 - return (zcs->zc_slave_rdq);
423 - else if (OTHERQ(qp) == zcs->zc_master_rdq && zcs->zc_slave_rdq != NULL)
424 - return (OTHERQ(zcs->zc_slave_rdq));
425 - else if (qp == zcs->zc_slave_rdq)
426 - return (zcs->zc_master_rdq);
427 - else if (OTHERQ(qp) == zcs->zc_slave_rdq && zcs->zc_master_rdq != NULL)
428 - return (OTHERQ(zcs->zc_master_rdq));
429 - else
425 + if (qp == zcs->zc_manager_rdq) {
426 + return (zcs->zc_subsid_rdq);
427 + } else if (OTHERQ(qp) == zcs->zc_manager_rdq &&
428 + zcs->zc_subsid_rdq != NULL) {
429 + return (OTHERQ(zcs->zc_subsid_rdq));
430 + } else if (qp == zcs->zc_subsid_rdq) {
431 + return (zcs->zc_manager_rdq);
432 + } else if (OTHERQ(qp) == zcs->zc_subsid_rdq &&
433 + zcs->zc_manager_rdq != NULL) {
434 + return (OTHERQ(zcs->zc_manager_rdq));
435 + } else {
430 436 return (NULL);
437 + }
431 438 }
432 439
433 440 /*
434 441 * For debugging and outputting messages. Returns the name of the side of
435 442 * the relationship associated with this queue.
436 443 */
437 444 static const char *
438 445 zc_side(queue_t *qp)
439 446 {
440 447 zc_state_t *zcs = qp->q_ptr;
441 448 ASSERT(zcs != NULL);
442 449
443 - if (qp == zcs->zc_master_rdq ||
444 - OTHERQ(qp) == zcs->zc_master_rdq) {
445 - return ("master");
450 + if (qp == zcs->zc_manager_rdq ||
451 + OTHERQ(qp) == zcs->zc_manager_rdq) {
452 + return ("manager");
446 453 }
447 - ASSERT(qp == zcs->zc_slave_rdq || OTHERQ(qp) == zcs->zc_slave_rdq);
448 - return ("slave");
454 + ASSERT(qp == zcs->zc_subsid_rdq || OTHERQ(qp) == zcs->zc_subsid_rdq);
455 + return ("subsidiary");
449 456 }
450 457
451 -/*ARGSUSED*/
452 458 static int
453 -zc_master_open(zc_state_t *zcs,
459 +zc_manager_open(zc_state_t *zcs,
454 460 queue_t *rqp, /* pointer to the read side queue */
455 461 dev_t *devp, /* pointer to stream tail's dev */
456 462 int oflag, /* the user open(2) supplied flags */
457 463 int sflag, /* open state flag */
458 464 cred_t *credp) /* credentials */
459 465 {
460 466 mblk_t *mop;
461 467 struct stroptions *sop;
462 468
463 469 /*
464 - * Enforce exclusivity on the master side; the only consumer should
470 + * Enforce exclusivity on the manager side; the only consumer should
465 471 * be the zoneadmd for the zone.
466 472 */
467 473 if ((zcs->zc_state & ZC_STATE_MOPEN) != 0)
468 474 return (EBUSY);
469 475
470 476 if ((mop = allocb(sizeof (struct stroptions), BPRI_MED)) == NULL) {
471 - DBG("zc_master_open(): mop allocation failed\n");
477 + DBG("zc_manager_open(): mop allocation failed\n");
472 478 return (ENOMEM);
473 479 }
474 480
475 481 zcs->zc_state |= ZC_STATE_MOPEN;
476 482
477 483 /*
478 484 * q_ptr stores driver private data; stash the soft state data on both
479 485 * read and write sides of the queue.
480 486 */
481 487 WR(rqp)->q_ptr = rqp->q_ptr = zcs;
482 488 qprocson(rqp);
483 489
484 490 /*
485 - * Following qprocson(), the master side is fully plumbed into the
486 - * STREAM and may send/receive messages. Setting zcs->zc_master_rdq
487 - * will allow the slave to send messages to us (the master).
488 - * This cannot occur before qprocson() because the master is not
491 + * Following qprocson(), the manager side is fully plumbed into the
492 + * STREAM and may send/receive messages. Setting zcs->zc_manager_rdq
493 + * will allow the subsidiary to send messages to us (the manager).
494 + * This cannot occur before qprocson() because the manager is not
489 495 * ready to process them until that point.
490 496 */
491 - zcs->zc_master_rdq = rqp;
497 + zcs->zc_manager_rdq = rqp;
492 498
493 499 /*
494 500 * set up hi/lo water marks on stream head read queue and add
495 501 * controlling tty as needed.
496 502 */
497 503 mop->b_datap->db_type = M_SETOPTS;
498 504 mop->b_wptr += sizeof (struct stroptions);
499 505 sop = (struct stroptions *)(void *)mop->b_rptr;
500 506 if (oflag & FNOCTTY)
501 507 sop->so_flags = SO_HIWAT | SO_LOWAT;
502 508 else
503 509 sop->so_flags = SO_HIWAT | SO_LOWAT | SO_ISTTY;
504 510 sop->so_hiwat = _TTY_BUFSIZ;
505 511 sop->so_lowat = 256;
506 512 putnext(rqp, mop);
507 513
508 514 return (0);
509 515 }
510 516
511 -/*ARGSUSED*/
512 517 static int
513 -zc_slave_open(zc_state_t *zcs,
518 +zc_subsidiary_open(zc_state_t *zcs,
514 519 queue_t *rqp, /* pointer to the read side queue */
515 520 dev_t *devp, /* pointer to stream tail's dev */
516 521 int oflag, /* the user open(2) supplied flags */
517 522 int sflag, /* open state flag */
518 523 cred_t *credp) /* credentials */
519 524 {
520 525 mblk_t *mop;
521 526 struct stroptions *sop;
522 527 major_t major;
523 528 minor_t minor;
524 529 minor_t lastminor;
525 530 uint_t anchorindex;
526 531
527 532 /*
528 - * The slave side can be opened as many times as needed.
533 + * The subsidiary side can be opened as many times as needed.
529 534 */
530 535 if ((zcs->zc_state & ZC_STATE_SOPEN) != 0) {
531 536 ASSERT((rqp != NULL) && (WR(rqp)->q_ptr == zcs));
532 537 return (0);
533 538 }
534 539
535 540 /*
536 541 * Set up sad(7D) so that the necessary STREAMS modules will be in
537 542 * place. A wrinkle is that 'ptem' must be anchored
538 543 * in place (see streamio(7i)) because we always want the console to
539 544 * have terminal semantics.
540 545 */
541 - minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SLAVE_MINOR;
546 + minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SUBSID_MINOR;
542 547 major = ddi_driver_major(zcs->zc_devinfo);
543 548 lastminor = 0;
544 549 anchorindex = 1;
545 550 if (kstr_autopush(SET_AUTOPUSH, &major, &minor, &lastminor,
546 551 &anchorindex, zcons_mods) != 0) {
547 - DBG("zc_slave_open(): kstr_autopush() failed\n");
552 + DBG("zc_subsidiary_open(): kstr_autopush() failed\n");
548 553 return (EIO);
549 554 }
550 555
551 556 if ((mop = allocb(sizeof (struct stroptions), BPRI_MED)) == NULL) {
552 - DBG("zc_slave_open(): mop allocation failed\n");
557 + DBG("zc_subsidiary_open(): mop allocation failed\n");
553 558 return (ENOMEM);
554 559 }
555 560
556 561 zcs->zc_state |= ZC_STATE_SOPEN;
557 562
558 563 /*
559 564 * q_ptr stores driver private data; stash the soft state data on both
560 565 * read and write sides of the queue.
561 566 */
562 567 WR(rqp)->q_ptr = rqp->q_ptr = zcs;
563 568
564 569 qprocson(rqp);
565 570
566 571 /*
567 572 * Must follow qprocson(), since we aren't ready to process until then.
568 573 */
569 - zcs->zc_slave_rdq = rqp;
574 + zcs->zc_subsid_rdq = rqp;
570 575
571 576 /*
572 577 * set up hi/lo water marks on stream head read queue and add
573 578 * controlling tty as needed.
574 579 */
575 580 mop->b_datap->db_type = M_SETOPTS;
576 581 mop->b_wptr += sizeof (struct stroptions);
577 582 sop = (struct stroptions *)(void *)mop->b_rptr;
578 583 sop->so_flags = SO_HIWAT | SO_LOWAT | SO_ISTTY;
579 584 sop->so_hiwat = _TTY_BUFSIZ;
580 585 sop->so_lowat = 256;
581 586 putnext(rqp, mop);
582 587
583 588 return (0);
584 589 }
585 590
586 591 /*
587 592 * open(9e) entrypoint; checks sflag, and rejects anything unordinary.
588 593 */
589 594 static int
590 595 zc_open(queue_t *rqp, /* pointer to the read side queue */
591 596 dev_t *devp, /* pointer to stream tail's dev */
592 597 int oflag, /* the user open(2) supplied flags */
593 598 int sflag, /* open state flag */
594 599 cred_t *credp) /* credentials */
595 600 {
596 601 int instance = ZC_INSTANCE(*devp);
↓ open down ↓ |
17 lines elided |
↑ open up ↑ |
597 602 int ret;
598 603 zc_state_t *zcs;
599 604
600 605 if (sflag != 0)
601 606 return (EINVAL);
602 607
603 608 if ((zcs = ddi_get_soft_state(zc_soft_state, instance)) == NULL)
604 609 return (ENXIO);
605 610
606 611 switch (ZC_NODE(*devp)) {
607 - case ZC_MASTER_MINOR:
608 - ret = zc_master_open(zcs, rqp, devp, oflag, sflag, credp);
612 + case ZC_MANAGER_MINOR:
613 + ret = zc_manager_open(zcs, rqp, devp, oflag, sflag, credp);
609 614 break;
610 - case ZC_SLAVE_MINOR:
611 - ret = zc_slave_open(zcs, rqp, devp, oflag, sflag, credp);
615 + case ZC_SUBSID_MINOR:
616 + ret = zc_subsidiary_open(zcs, rqp, devp, oflag, sflag, credp);
612 617 break;
613 618 default:
614 619 ret = ENXIO;
615 620 break;
616 621 }
617 622
618 623 return (ret);
619 624 }
620 625
621 626 /*
622 627 * close(9e) entrypoint.
623 628 */
624 -/*ARGSUSED1*/
625 629 static int
626 630 zc_close(queue_t *rqp, int flag, cred_t *credp)
627 631 {
628 632 queue_t *wqp;
629 633 mblk_t *bp;
630 634 zc_state_t *zcs;
631 635 major_t major;
632 636 minor_t minor;
633 637
634 638 zcs = (zc_state_t *)rqp->q_ptr;
635 639
636 - if (rqp == zcs->zc_master_rdq) {
637 - DBG("Closing master side");
640 + if (rqp == zcs->zc_manager_rdq) {
641 + DBG("Closing manager side");
638 642
639 - zcs->zc_master_rdq = NULL;
643 + zcs->zc_manager_rdq = NULL;
640 644 zcs->zc_state &= ~ZC_STATE_MOPEN;
641 645
642 646 /*
643 - * qenable slave side write queue so that it can flush
644 - * its messages as master's read queue is going away
647 + * qenable subsidiary side write queue so that it can flush
648 + * its messages as manager's read queue is going away
645 649 */
646 - if (zcs->zc_slave_rdq != NULL) {
647 - qenable(WR(zcs->zc_slave_rdq));
650 + if (zcs->zc_subsid_rdq != NULL) {
651 + qenable(WR(zcs->zc_subsid_rdq));
648 652 }
649 653
650 654 qprocsoff(rqp);
651 655 WR(rqp)->q_ptr = rqp->q_ptr = NULL;
652 656
653 - } else if (rqp == zcs->zc_slave_rdq) {
657 + } else if (rqp == zcs->zc_subsid_rdq) {
654 658
655 - DBG("Closing slave side");
659 + DBG("Closing subsidiary side");
656 660 zcs->zc_state &= ~ZC_STATE_SOPEN;
657 - zcs->zc_slave_rdq = NULL;
661 + zcs->zc_subsid_rdq = NULL;
658 662
659 663 wqp = WR(rqp);
660 664 while ((bp = getq(wqp)) != NULL) {
661 - if (zcs->zc_master_rdq != NULL)
662 - putnext(zcs->zc_master_rdq, bp);
665 + if (zcs->zc_manager_rdq != NULL)
666 + putnext(zcs->zc_manager_rdq, bp);
663 667 else if (bp->b_datap->db_type == M_IOCTL)
664 668 miocnak(wqp, bp, 0, 0);
665 669 else
666 670 freemsg(bp);
667 671 }
668 672
669 673 /*
670 - * Qenable master side write queue so that it can flush its
671 - * messages as slaves's read queue is going away.
674 + * Qenable manager side write queue so that it can flush its
675 + * messages as subsidiarys's read queue is going away.
672 676 */
673 - if (zcs->zc_master_rdq != NULL)
674 - qenable(WR(zcs->zc_master_rdq));
677 + if (zcs->zc_manager_rdq != NULL)
678 + qenable(WR(zcs->zc_manager_rdq));
675 679
676 680 qprocsoff(rqp);
677 681 WR(rqp)->q_ptr = rqp->q_ptr = NULL;
678 682
679 683 /*
680 684 * Clear the sad configuration so that reopening doesn't fail
681 685 * to set up sad configuration.
682 686 */
683 687 major = ddi_driver_major(zcs->zc_devinfo);
684 - minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SLAVE_MINOR;
688 + minor = ddi_get_instance(zcs->zc_devinfo) << 1 |
689 + ZC_SUBSID_MINOR;
685 690 (void) kstr_autopush(CLR_AUTOPUSH, &major, &minor, NULL, NULL,
686 691 NULL);
687 692 }
688 693
689 694 return (0);
690 695 }
691 696
692 697 static void
693 698 handle_mflush(queue_t *qp, mblk_t *mp)
694 699 {
695 700 mblk_t *nmp;
696 701 DBG1("M_FLUSH on %s side", zc_side(qp));
697 702
698 703 if (*mp->b_rptr & FLUSHW) {
699 704 DBG1("M_FLUSH, FLUSHW, %s side", zc_side(qp));
700 705 flushq(qp, FLUSHDATA);
701 706 *mp->b_rptr &= ~FLUSHW;
702 707 if ((*mp->b_rptr & FLUSHR) == 0) {
703 708 /*
704 709 * FLUSHW only. Change to FLUSHR and putnext other side,
705 710 * then we are done.
706 711 */
707 712 *mp->b_rptr |= FLUSHR;
708 713 if (zc_switch(RD(qp)) != NULL) {
709 714 putnext(zc_switch(RD(qp)), mp);
710 715 return;
711 716 }
712 717 } else if ((zc_switch(RD(qp)) != NULL) &&
713 718 (nmp = copyb(mp)) != NULL) {
714 719 /*
715 720 * It is a FLUSHRW; we copy the mblk and send
716 721 * it to the other side, since we still need to use
717 722 * the mblk in FLUSHR processing, below.
718 723 */
719 724 putnext(zc_switch(RD(qp)), nmp);
720 725 }
721 726 }
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
722 727
723 728 if (*mp->b_rptr & FLUSHR) {
724 729 DBG("qreply(qp) turning FLUSHR around\n");
725 730 qreply(qp, mp);
726 731 return;
727 732 }
728 733 freemsg(mp);
729 734 }
730 735
731 736 /*
732 - * wput(9E) is symmetric for master and slave sides, so this handles both
737 + * wput(9E) is symmetric for manager and subsidiary sides, so this handles both
733 738 * without splitting the codepath. (The only exception to this is the
734 - * processing of zcons ioctls, which is restricted to the master side.)
739 + * processing of zcons ioctls, which is restricted to the manager side.)
735 740 *
736 741 * zc_wput() looks at the other side; if there is no process holding that
737 742 * side open, it frees the message. This prevents processes from hanging
738 743 * if no one is holding open the console. Otherwise, it putnext's high
739 744 * priority messages, putnext's normal messages if possible, and otherwise
740 745 * enqueues the messages; in the case that something is enqueued, wsrv(9E)
741 746 * will take care of eventually shuttling I/O to the other side.
742 747 */
743 748 static int
744 749 zc_wput(queue_t *qp, mblk_t *mp)
745 750 {
746 751 unsigned char type = mp->b_datap->db_type;
747 752 zc_state_t *zcs;
748 753 struct iocblk *iocbp;
749 - file_t *slave_filep;
750 - struct snode *slave_snodep;
751 - int slave_fd;
754 + file_t *subsidiary_filep;
755 + struct snode *subsidiary_snodep;
756 + int subsidiary_fd;
752 757
753 758 ASSERT(qp->q_ptr);
754 759
755 760 DBG1("entering zc_wput, %s side", zc_side(qp));
756 761
757 762 /*
758 - * Process zcons ioctl messages if qp is the master console's write
763 + * Process zcons ioctl messages if qp is the manager console's write
759 764 * queue.
760 765 */
761 766 zcs = (zc_state_t *)qp->q_ptr;
762 - if (zcs->zc_master_rdq != NULL && qp == WR(zcs->zc_master_rdq) &&
767 + if (zcs->zc_manager_rdq != NULL && qp == WR(zcs->zc_manager_rdq) &&
763 768 type == M_IOCTL) {
764 769 iocbp = (struct iocblk *)(void *)mp->b_rptr;
765 770 switch (iocbp->ioc_cmd) {
766 - case ZC_HOLDSLAVE:
771 + case ZC_HOLDSUBSID:
767 772 /*
768 - * Hold the slave's vnode and increment the refcount
769 - * of the snode. If the vnode is already held, then
770 - * indicate success.
773 + * Hold the subsidiary's vnode and increment the
774 + * refcount of the snode. If the vnode is already
775 + * held, then indicate success.
771 776 */
772 777 if (iocbp->ioc_count != TRANSPARENT) {
773 778 miocack(qp, mp, 0, EINVAL);
774 779 return (0);
775 780 }
776 - if (zcs->zc_slave_vnode != NULL) {
781 + if (zcs->zc_subsid_vnode != NULL) {
777 782 miocack(qp, mp, 0, 0);
778 783 return (0);
779 784 }
780 785
781 786 /*
782 787 * The process that passed the ioctl must be running in
783 788 * the global zone.
784 789 */
785 790 if (curzone != global_zone) {
786 791 miocack(qp, mp, 0, EINVAL);
787 792 return (0);
788 793 }
789 794
790 795 /*
791 796 * The calling process must pass a file descriptor for
792 - * the slave device.
797 + * the subsidiary device.
793 798 */
794 - slave_fd =
799 + subsidiary_fd =
795 800 (int)(intptr_t)*(caddr_t *)(void *)mp->b_cont->
796 801 b_rptr;
797 - slave_filep = getf(slave_fd);
798 - if (slave_filep == NULL) {
802 + subsidiary_filep = getf(subsidiary_fd);
803 + if (subsidiary_filep == NULL) {
799 804 miocack(qp, mp, 0, EINVAL);
800 805 return (0);
801 806 }
802 - if (ZC_STATE_TO_SLAVEDEV(zcs) !=
803 - slave_filep->f_vnode->v_rdev) {
804 - releasef(slave_fd);
807 + if (ZC_STATE_TO_SUBDEV(zcs) !=
808 + subsidiary_filep->f_vnode->v_rdev) {
809 + releasef(subsidiary_fd);
805 810 miocack(qp, mp, 0, EINVAL);
806 811 return (0);
807 812 }
808 813
809 814 /*
810 - * Get a reference to the slave's vnode. Also bump the
811 - * reference count on the associated snode.
815 + * Get a reference to the subsidiary's vnode. Also
816 + * bump the reference count on the associated snode.
812 817 */
813 - ASSERT(vn_matchops(slave_filep->f_vnode,
818 + ASSERT(vn_matchops(subsidiary_filep->f_vnode,
814 819 spec_getvnodeops()));
815 - zcs->zc_slave_vnode = slave_filep->f_vnode;
816 - VN_HOLD(zcs->zc_slave_vnode);
817 - slave_snodep = VTOCS(zcs->zc_slave_vnode);
818 - mutex_enter(&slave_snodep->s_lock);
819 - ++slave_snodep->s_count;
820 - mutex_exit(&slave_snodep->s_lock);
821 - releasef(slave_fd);
820 + zcs->zc_subsid_vnode = subsidiary_filep->f_vnode;
821 + VN_HOLD(zcs->zc_subsid_vnode);
822 + subsidiary_snodep = VTOCS(zcs->zc_subsid_vnode);
823 + mutex_enter(&subsidiary_snodep->s_lock);
824 + ++subsidiary_snodep->s_count;
825 + mutex_exit(&subsidiary_snodep->s_lock);
826 + releasef(subsidiary_fd);
822 827 miocack(qp, mp, 0, 0);
823 828 return (0);
824 - case ZC_RELEASESLAVE:
829 + case ZC_RELEASESUBSID:
825 830 /*
826 - * Release the master's handle on the slave's vnode.
827 - * If there isn't a handle for the vnode, then indicate
828 - * success.
831 + * Release the manager's handle on the subsidiary's
832 + * vnode. If there isn't a handle for the vnode, then
833 + * indicate success.
829 834 */
830 835 if (iocbp->ioc_count != TRANSPARENT) {
831 836 miocack(qp, mp, 0, EINVAL);
832 837 return (0);
833 838 }
834 - if (zcs->zc_slave_vnode == NULL) {
839 + if (zcs->zc_subsid_vnode == NULL) {
835 840 miocack(qp, mp, 0, 0);
836 841 return (0);
837 842 }
838 843
839 844 /*
840 845 * The process that passed the ioctl must be running in
841 846 * the global zone.
842 847 */
843 848 if (curzone != global_zone) {
844 849 miocack(qp, mp, 0, EINVAL);
845 850 return (0);
846 851 }
847 852
848 853 /*
849 854 * The process that passed the ioctl must have provided
850 - * a file descriptor for the slave device. Make sure
851 - * this is correct.
855 + * a file descriptor for the subsidiary device. Make
856 + * sure this is correct.
852 857 */
853 - slave_fd =
858 + subsidiary_fd =
854 859 (int)(intptr_t)*(caddr_t *)(void *)mp->b_cont->
855 860 b_rptr;
856 - slave_filep = getf(slave_fd);
857 - if (slave_filep == NULL) {
861 + subsidiary_filep = getf(subsidiary_fd);
862 + if (subsidiary_filep == NULL) {
858 863 miocack(qp, mp, 0, EINVAL);
859 864 return (0);
860 865 }
861 - if (zcs->zc_slave_vnode->v_rdev !=
862 - slave_filep->f_vnode->v_rdev) {
863 - releasef(slave_fd);
866 + if (zcs->zc_subsid_vnode->v_rdev !=
867 + subsidiary_filep->f_vnode->v_rdev) {
868 + releasef(subsidiary_fd);
864 869 miocack(qp, mp, 0, EINVAL);
865 870 return (0);
866 871 }
867 872
868 873 /*
869 874 * Decrement the snode's reference count and release the
870 875 * vnode.
871 876 */
872 - ASSERT(vn_matchops(slave_filep->f_vnode,
877 + ASSERT(vn_matchops(subsidiary_filep->f_vnode,
873 878 spec_getvnodeops()));
874 - slave_snodep = VTOCS(zcs->zc_slave_vnode);
875 - mutex_enter(&slave_snodep->s_lock);
876 - --slave_snodep->s_count;
877 - mutex_exit(&slave_snodep->s_lock);
878 - VN_RELE(zcs->zc_slave_vnode);
879 - zcs->zc_slave_vnode = NULL;
880 - releasef(slave_fd);
879 + subsidiary_snodep = VTOCS(zcs->zc_subsid_vnode);
880 + mutex_enter(&subsidiary_snodep->s_lock);
881 + --subsidiary_snodep->s_count;
882 + mutex_exit(&subsidiary_snodep->s_lock);
883 + VN_RELE(zcs->zc_subsid_vnode);
884 + zcs->zc_subsid_vnode = NULL;
885 + releasef(subsidiary_fd);
881 886 miocack(qp, mp, 0, 0);
882 887 return (0);
883 888 default:
884 889 break;
885 890 }
886 891 }
887 892
888 893 if (zc_switch(RD(qp)) == NULL) {
889 894 DBG1("wput to %s side (no one listening)", zc_side(qp));
890 895 switch (type) {
891 896 case M_FLUSH:
892 897 handle_mflush(qp, mp);
893 898 break;
894 899 case M_IOCTL:
895 900 miocnak(qp, mp, 0, 0);
896 901 break;
897 902 default:
898 903 freemsg(mp);
899 904 break;
900 905 }
901 906 return (0);
902 907 }
903 908
904 909 if (type >= QPCTL) {
905 910 DBG1("(hipri) wput, %s side", zc_side(qp));
906 911 switch (type) {
907 912 case M_READ: /* supposedly from ldterm? */
908 913 DBG("zc_wput: tossing M_READ\n");
909 914 freemsg(mp);
910 915 break;
911 916 case M_FLUSH:
912 917 handle_mflush(qp, mp);
913 918 break;
914 919 default:
915 920 /*
916 921 * Put this to the other side.
917 922 */
918 923 ASSERT(zc_switch(RD(qp)) != NULL);
919 924 putnext(zc_switch(RD(qp)), mp);
920 925 break;
921 926 }
922 927 DBG1("done (hipri) wput, %s side", zc_side(qp));
923 928 return (0);
924 929 }
925 930
926 931 /*
927 932 * Only putnext if there isn't already something in the queue.
928 933 * otherwise things would wind up out of order.
929 934 */
930 935 if (qp->q_first == NULL && bcanputnext(RD(zc_switch(qp)), mp->b_band)) {
931 936 DBG("wput: putting message to other side\n");
↓ open down ↓ |
41 lines elided |
↑ open up ↑ |
932 937 putnext(RD(zc_switch(qp)), mp);
933 938 } else {
934 939 DBG("wput: putting msg onto queue\n");
935 940 (void) putq(qp, mp);
936 941 }
937 942 DBG1("done wput, %s side", zc_side(qp));
938 943 return (0);
939 944 }
940 945
941 946 /*
942 - * rsrv(9E) is symmetric for master and slave, so zc_rsrv() handles both
947 + * rsrv(9E) is symmetric for manager and subsidiary, so zc_rsrv() handles both
943 948 * without splitting up the codepath.
944 949 *
945 950 * Enable the write side of the partner. This triggers the partner to send
946 951 * messages queued on its write side to this queue's read side.
947 952 */
948 953 static int
949 954 zc_rsrv(queue_t *qp)
950 955 {
951 956 zc_state_t *zcs;
952 957 zcs = (zc_state_t *)qp->q_ptr;
953 958
954 959 /*
955 - * Care must be taken here, as either of the master or slave side
960 + * Care must be taken here, as either of the manager or subsidiary side
956 961 * qptr could be NULL.
957 962 */
958 - ASSERT(qp == zcs->zc_master_rdq || qp == zcs->zc_slave_rdq);
963 + ASSERT(qp == zcs->zc_manager_rdq || qp == zcs->zc_subsid_rdq);
959 964 if (zc_switch(qp) == NULL) {
960 965 DBG("zc_rsrv: other side isn't listening\n");
961 966 return (0);
962 967 }
963 968 qenable(WR(zc_switch(qp)));
964 969 return (0);
965 970 }
966 971
967 972 /*
968 - * This routine is symmetric for master and slave, so it handles both without
969 - * splitting up the codepath.
973 + * This routine is symmetric for manager and subsidiary, so it handles both
974 + * without splitting up the codepath.
970 975 *
971 976 * If there are messages on this queue that can be sent to the other, send
972 977 * them via putnext(). Else, if queued messages cannot be sent, leave them
973 978 * on this queue.
974 979 */
975 980 static int
976 981 zc_wsrv(queue_t *qp)
977 982 {
978 983 mblk_t *mp;
979 984
980 - DBG1("zc_wsrv master (%s) side", zc_side(qp));
985 + DBG1("zc_wsrv manager (%s) side", zc_side(qp));
981 986
982 987 /*
983 988 * Partner has no read queue, so take the data, and throw it away.
984 989 */
985 990 if (zc_switch(RD(qp)) == NULL) {
986 991 DBG("zc_wsrv: other side isn't listening");
987 992 while ((mp = getq(qp)) != NULL) {
988 993 if (mp->b_datap->db_type == M_IOCTL)
989 994 miocnak(qp, mp, 0, 0);
990 995 else
991 996 freemsg(mp);
992 997 }
993 998 flushq(qp, FLUSHALL);
994 999 return (0);
995 1000 }
996 1001
997 1002 /*
998 1003 * while there are messages on this write queue...
999 1004 */
1000 1005 while ((mp = getq(qp)) != NULL) {
1001 1006 /*
1002 1007 * Due to the way zc_wput is implemented, we should never
1003 1008 * see a control message here.
1004 1009 */
1005 1010 ASSERT(mp->b_datap->db_type < QPCTL);
1006 1011
1007 1012 if (bcanputnext(RD(zc_switch(qp)), mp->b_band)) {
1008 1013 DBG("wsrv: send message to other side\n");
1009 1014 putnext(RD(zc_switch(qp)), mp);
1010 1015 } else {
1011 1016 DBG("wsrv: putting msg back on queue\n");
1012 1017 (void) putbq(qp, mp);
1013 1018 break;
1014 1019 }
1015 1020 }
1016 1021 return (0);
1017 1022 }
↓ open down ↓ |
27 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX