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.