changeset 4049:1799c30fb70c

6532455 ip-type exclusive IP instances with bge interfaces can't autoboot 6540253 libdladm should not rely on stat() to force a device to be attached 6543436 System panic due to assertion failed: qprocsareon(rq), file: ../../common/os/strsubr.c, line: 1210
author dh155122
date Mon, 16 Apr 2007 19:43:30 -0700
parents 7212bc4f07cc
children 9349e27b46cc
files usr/src/lib/libdladm/common/linkprop.c usr/src/uts/common/io/dld/dld_drv.c usr/src/uts/common/io/dld/dld_str.c
diffstat 3 files changed, 37 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/lib/libdladm/common/linkprop.c	Mon Apr 16 15:36:28 2007 -0700
+++ b/usr/src/lib/libdladm/common/linkprop.c	Mon Apr 16 19:43:30 2007 -0700
@@ -871,8 +871,6 @@
 {
 	dladm_status_t	status;
 	zoneid_t	zid_old, zid_new;
-	char		buff[IF_NAMESIZE + 1];
-	struct stat	st;
 
 	if (val_cnt != 1)
 		return (DLADM_STATUS_BADVALCNT);
@@ -886,11 +884,6 @@
 	if (zid_new == zid_old)
 		return (DLADM_STATUS_OK);
 
-	/* Do a stat to get the vlan created by MAC, if it's not there */
-	(void) strcpy(buff, "/dev/");
-	(void) strlcat(buff, link, IF_NAMESIZE);
-	(void) stat(buff, &st);
-
 	if (zid_old != GLOBAL_ZONEID) {
 		if (dladm_rele_link(link, GLOBAL_ZONEID, B_TRUE) < 0)
 			return (dladm_errno2status(errno));
--- a/usr/src/uts/common/io/dld/dld_drv.c	Mon Apr 16 15:36:28 2007 -0700
+++ b/usr/src/uts/common/io/dld/dld_drv.c	Mon Apr 16 19:43:30 2007 -0700
@@ -496,29 +496,55 @@
 	queue_t		*q = ctls->cs_wq;
 	dld_hold_vlan_t	*dhv;
 	mblk_t		*nmp;
-	int		err;
+	int		err = EINVAL;
 	dls_vlan_t	*dvp;
+	char		mac[MAXNAMELEN];
+	dev_info_t	*dip = NULL;
+	major_t		major;
+	uint_t		index;
 
 	nmp = mp->b_cont;
-	if (nmp == NULL || MBLKL(nmp) < sizeof (dld_hold_vlan_t)) {
-		err = EINVAL;
-		miocnak(q, mp, 0, err);
-		return;
-	}
+	if (nmp == NULL || MBLKL(nmp) < sizeof (dld_hold_vlan_t))
+		goto failed;
+
 	dhv = (dld_hold_vlan_t *)nmp->b_rptr;
 
-	if ((err = dls_vlan_hold(dhv->dhv_name, &dvp, B_TRUE)) != 0) {
-		miocnak(q, mp, 0, err);
-		return;
+	/*
+	 * When a device instance without opens is detached, its
+	 * dls_vlan_t will be destroyed. A subsequent DLDIOCHOLDVLAN
+	 * invoked on this device instance will fail because
+	 * dls_vlan_hold() does not create non-tagged vlans on demand.
+	 * To handle this problem, we must force the creation of the
+	 * dls_vlan_t (if it doesn't already exist) by calling
+	 * ddi_hold_devi_by_instance() before calling dls_vlan_hold().
+	 */
+	if (ddi_parse(dhv->dhv_name, mac, &index) != DDI_SUCCESS)
+		goto failed;
+
+	if (DLS_PPA2VID(index) == VLAN_ID_NONE && strcmp(mac, "aggr") != 0) {
+		if ((major = ddi_name_to_major(mac)) == (major_t)-1 ||
+		    (dip = ddi_hold_devi_by_instance(major,
+		    DLS_PPA2INST(index), 0)) == NULL)
+			goto failed;
 	}
 
+	err = dls_vlan_hold(dhv->dhv_name, &dvp, B_TRUE);
+	if (dip != NULL)
+		ddi_release_devi(dip);
+
+	if (err != 0)
+		goto failed;
+
 	if ((err = dls_vlan_setzoneid(dhv->dhv_name, dhv->dhv_zid,
 	    dhv->dhv_docheck)) != 0) {
 		dls_vlan_rele(dvp);
-		miocnak(q, mp, 0, err);
+		goto failed;
 	} else {
 		miocack(q, mp, 0, 0);
+		return;
 	}
+failed:
+	miocnak(q, mp, 0, err);
 }
 
 /*
--- a/usr/src/uts/common/io/dld/dld_str.c	Mon Apr 16 15:36:28 2007 -0700
+++ b/usr/src/uts/common/io/dld/dld_str.c	Mon Apr 16 19:43:30 2007 -0700
@@ -288,7 +288,7 @@
 		 */
 		t_uscalar_t ppa;
 
-		if ((dls_ppa_from_minor(minor, &ppa)) != 0)
+		if ((err = dls_ppa_from_minor(minor, &ppa)) != 0)
 			goto failed;
 
 		if ((err = dld_str_attach(dsp, ppa)) != 0)