Mercurial > illumos > illumos-gate
changeset 10670:04b72b54380d
6843300 node hangs after step 12 forced to return
author | jv227347 <Jordan.Vaughan@Sun.com> |
---|---|
date | Mon, 28 Sep 2009 12:55:17 -0700 |
parents | ccf9f7e81ff9 |
children | b0cfddcff787 |
files | usr/src/uts/common/io/zcons.c |
diffstat | 1 files changed, 57 insertions(+), 59 deletions(-) [+] |
line wrap: on
line diff
--- a/usr/src/uts/common/io/zcons.c Mon Sep 28 11:41:39 2009 -0700 +++ b/usr/src/uts/common/io/zcons.c Mon Sep 28 12:55:17 2009 -0700 @@ -172,6 +172,7 @@ #include <sys/zcons.h> #include <sys/vnode.h> #include <sys/fs/snode.h> +#include <sys/zone.h> static int zc_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **); static int zc_attach(dev_info_t *, ddi_attach_cmd_t); @@ -328,38 +329,11 @@ return (mod_info(&modlinkage, modinfop)); } -/* - * This is a convenience function that clears a device's autopush configuration. - * It is meant to be used on the slave side of the console. Unlike calling - * kstr_autopush() directly, this function outputs a warning via cmn_err() if - * kstr_autopush() fails. 'dip' must be non-NULL in debug builds. Both - * 'major' and 'minor' must be valid. - */ -static void -zc_clearautopush(dev_info_t *dip, major_t major, minor_t minor) -{ - char *devicepathp; - - if (kstr_autopush(CLR_AUTOPUSH, &major, &minor, NULL, NULL, NULL) != - 0 && zcons_debug != 0) { - devicepathp = (char *)kmem_alloc(MAXPATHLEN * sizeof (char), - KM_SLEEP); - (void) ddi_pathname(dip, devicepathp); - cmn_err(CE_NOTE, "zc_detach: could not clear sad configuration " - "for device %s\n", devicepathp); - kmem_free(devicepathp, MAXPATHLEN * sizeof (char)); - } -} - static int zc_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) { zc_state_t *zcs; int instance; - major_t major; - minor_t minor; - minor_t lastminor; - uint_t anchorindex; if (cmd != DDI_ATTACH) return (DDI_FAILURE); @@ -369,38 +343,20 @@ return (DDI_FAILURE); /* - * Set up sad(7D) so that the necessary STREAMS modules will be in place - * when the slave is opened. A wrinkle is that 'ptem' must be anchored - * in place (see streamio(7i)) because we always want the console to - * have terminal semantics. - */ - minor = instance << 1 | ZC_SLAVE_MINOR; - lastminor = 0; - major = ddi_driver_major(dip); - anchorindex = 1; - if (kstr_autopush(SET_AUTOPUSH, &major, &minor, &lastminor, - &anchorindex, zcons_mods) != 0) - goto commonfail; - - /* * Create the master and slave minor nodes. */ - if ((ddi_create_minor_node(dip, ZCONS_SLAVE_NAME, S_IFCHR, minor, - DDI_PSEUDO, 0) == DDI_FAILURE) || + if ((ddi_create_minor_node(dip, ZCONS_SLAVE_NAME, S_IFCHR, + instance << 1 | ZC_SLAVE_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE) || (ddi_create_minor_node(dip, ZCONS_MASTER_NAME, S_IFCHR, - instance << 1 | ZC_MASTER_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE)) - goto failwithautopush; + instance << 1 | ZC_MASTER_MINOR, DDI_PSEUDO, 0) == DDI_FAILURE)) { + ddi_remove_minor_node(dip, NULL); + ddi_soft_state_free(zc_soft_state, instance); + return (DDI_FAILURE); + } VERIFY((zcs = ddi_get_soft_state(zc_soft_state, instance)) != NULL); zcs->zc_devinfo = dip; return (DDI_SUCCESS); - -failwithautopush: - zc_clearautopush(dip, major, minor); - ddi_remove_minor_node(dip, NULL); -commonfail: - ddi_soft_state_free(zc_soft_state, instance); - return (DDI_FAILURE); } static int @@ -422,13 +378,6 @@ return (DDI_FAILURE); } - /* - * Clear the sad configuration so that reattaching doesn't fail to - * set up sad configuration. - */ - zc_clearautopush(dip, ddi_driver_major(dip), instance << 1 | - ZC_SLAVE_MINOR); - ddi_remove_minor_node(dip, NULL); ddi_soft_state_free(zc_soft_state, instance); @@ -570,6 +519,10 @@ { mblk_t *mop; struct stroptions *sop; + major_t major; + minor_t minor; + minor_t lastminor; + uint_t anchorindex; /* * The slave side can be opened as many times as needed. @@ -579,6 +532,22 @@ return (0); } + /* + * Set up sad(7D) so that the necessary STREAMS modules will be in + * place. A wrinkle is that 'ptem' must be anchored + * in place (see streamio(7i)) because we always want the console to + * have terminal semantics. + */ + minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SLAVE_MINOR; + major = ddi_driver_major(zcs->zc_devinfo); + lastminor = 0; + anchorindex = 1; + if (kstr_autopush(SET_AUTOPUSH, &major, &minor, &lastminor, + &anchorindex, zcons_mods) != 0) { + DBG("zc_slave_open(): kstr_autopush() failed\n"); + return (EIO); + } + if ((mop = allocb(sizeof (struct stroptions), BPRI_MED)) == NULL) { DBG("zc_slave_open(): mop allocation failed\n"); return (ENOMEM); @@ -659,6 +628,8 @@ queue_t *wqp; mblk_t *bp; zc_state_t *zcs; + major_t major; + minor_t minor; zcs = (zc_state_t *)rqp->q_ptr; @@ -704,6 +675,15 @@ qprocsoff(rqp); WR(rqp)->q_ptr = rqp->q_ptr = NULL; + + /* + * Clear the sad configuration so that reopening doesn't fail + * to set up sad configuration. + */ + major = ddi_driver_major(zcs->zc_devinfo); + minor = ddi_get_instance(zcs->zc_devinfo) << 1 | ZC_SLAVE_MINOR; + (void) kstr_autopush(CLR_AUTOPUSH, &major, &minor, NULL, NULL, + NULL); } return (0); @@ -799,6 +779,15 @@ } /* + * The process that passed the ioctl must be running in + * the global zone. + */ + if (curzone != global_zone) { + miocack(qp, mp, 0, EINVAL); + return; + } + + /* * The calling process must pass a file descriptor for * the slave device. */ @@ -848,6 +837,15 @@ } /* + * The process that passed the ioctl must be running in + * the global zone. + */ + if (curzone != global_zone) { + miocack(qp, mp, 0, EINVAL); + return; + } + + /* * The process that passed the ioctl must have provided * a file descriptor for the slave device. Make sure * this is correct.