changeset 5109:0876b6c2ea48

6211435 disks with target names > 40 chars cannot be added to a diskset
author petede
date Fri, 21 Sep 2007 01:54:14 -0700
parents 43add252e506
children 6c913b66a74a
files usr/src/head/meta.h usr/src/lib/lvm/libmeta/common/meta_db.c usr/src/lib/lvm/libmeta/common/meta_error.c usr/src/lib/lvm/libmeta/common/metasplitname.c usr/src/uts/common/sys/lvm/mdiox.x
diffstat 5 files changed, 303 insertions(+), 116 deletions(-) [+]
line wrap: on
line diff
--- a/usr/src/head/meta.h	Thu Sep 20 14:23:25 2007 -0700
+++ b/usr/src/head/meta.h	Fri Sep 21 01:54:14 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -101,6 +101,7 @@
 #define	ADMSPECIAL		"/dev/md/admin"
 
 #define	MDB_STR			"metadevice state database"
+#define	META_LONGDISKNAME_STR	"<long disk name>"
 
 /* default database size (4MB) */
 #define	MD_DBSIZE	(8192)
@@ -176,6 +177,13 @@
 #define	METADEVADM_DISKMOVE	4
 
 /*
+ * return values for the splitname function
+ */
+#define	METASPLIT_SUCCESS		0
+#define	METASPLIT_LONGPREFIX		1
+#define	METASPLIT_LONGDISKNAME		2
+
+/*
  * meta_check* options
  */
 typedef	uint_t	mdchkopts_t;
--- a/usr/src/lib/lvm/libmeta/common/meta_db.c	Thu Sep 20 14:23:25 2007 -0700
+++ b/usr/src/lib/lvm/libmeta/common/meta_db.c	Fri Sep 21 01:54:14 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -67,6 +67,77 @@
 extern int procsigs(int block, sigset_t *oldsigs, md_error_t *ep);
 
 /*
+ * Are the locator blocks for the replicas using devids
+ */
+static int	devid_in_use = FALSE;
+
+static char *
+getlongname(
+	struct mddb_config	*c,
+	md_error_t		*ep
+)
+{
+	char		*diskname = NULL;
+	char		*devid_str;
+	devid_nmlist_t	*disklist = NULL;
+
+	c->c_locator.l_devid_flags = MDDB_DEVID_GETSZ;
+	if (metaioctl(MD_DB_ENDDEV, c, &c->c_mde, NULL) != 0) {
+		(void) mdstealerror(ep, &c->c_mde);
+		return (NULL);
+	}
+
+	if (c->c_locator.l_devid_flags & MDDB_DEVID_SZ) {
+		c->c_locator.l_devid = (uintptr_t)
+		    Malloc(c->c_locator.l_devid_sz);
+		c->c_locator.l_devid_flags =
+		    MDDB_DEVID_SPACE | MDDB_DEVID_SZ;
+	} else {
+		(void) mderror(ep, MDE_NODEVID, "");
+		goto out;
+	}
+
+	if (metaioctl(MD_DB_ENDDEV, c, &c->c_mde, NULL) != 0) {
+		(void) mdstealerror(ep, &c->c_mde);
+		goto out;
+	}
+
+	if (c->c_locator.l_devid_flags & MDDB_DEVID_NOSPACE) {
+		(void) mderror(ep, MDE_NODEVID, "");
+		goto out;
+	}
+
+	if (metaioctl(MD_DB_GETDEV, c, &c->c_mde, NULL) != 0) {
+		(void) mdstealerror(ep, &c->c_mde);
+		goto out;
+	}
+
+	if (c->c_locator.l_devid != NULL) {
+		if (meta_deviceid_to_nmlist("/dev/dsk",
+		    (ddi_devid_t)(uintptr_t)c->c_locator.l_devid,
+		    c->c_locator.l_minor_name, &disklist) != 0) {
+			devid_str = devid_str_encode(
+			    (ddi_devid_t)(uintptr_t)c->c_locator.l_devid, NULL);
+			(void) mderror(ep, MDE_MISSING_DEVID_DISK, "");
+			mderrorextra(ep, devid_str);
+			if (devid_str != NULL)
+				devid_str_free(devid_str);
+			goto out;
+		}
+		diskname = Strdup(disklist[0].devname);
+	}
+
+out:
+	if (disklist != NULL)
+		devid_free_nmlist(disklist);
+
+	if (c->c_locator.l_devid != NULL)
+		Free((void *)(uintptr_t)c->c_locator.l_devid);
+
+	return (diskname);
+}
+
+/*
  * meta_get_lb_inittime sends a request for the lb_inittime to the kernel
  */
 md_timeval32_t
@@ -255,10 +326,10 @@
 	}
 
 	if (crcchk((uchar_t *)mb, (uint_t *)&mb->mb_checksum,
-		(uint_t)DEV_BSIZE, (crc_skip_t *)NULL)) {
+	    (uint_t)DEV_BSIZE, (crc_skip_t *)NULL)) {
 		Free(mb);
 		return (mdmddberror(ep, MDE_NOTVERIFIED,
-			meta_getminor(np->dev), sp->setno, 0, np->rname));
+		    meta_getminor(np->dev), sp->setno, 0, np->rname));
 	}
 
 	Free(mb);
@@ -413,7 +484,7 @@
 	if (fprintf(cfp, "do not hand edit\n") < 0)
 		goto error;
 	if (fprintf(cfp,
-		"#driver\tminor_t\tdaddr_t\tdevice id\tchecksum\n") < 0)
+	    "#driver\tminor_t\tdaddr_t\tdevice id\tchecksum\n") < 0)
 		goto error;
 
 	/* dump replicas */
@@ -499,7 +570,7 @@
 	/* tempfile error */
 error:
 	rval = (in_miniroot) ? mdsyserror(ep, errno, tname):
-				mdsyserror(ep, errno, META_DBCONFTMP);
+	    mdsyserror(ep, errno, META_DBCONFTMP);
 
 
 	/* cleanup, return success */
@@ -508,7 +579,7 @@
 		metafreereplicalist(rlp);
 	if ((cfp != NULL) && (fclose(cfp) != 0) && (rval == 0)) {
 		rval = (in_miniroot) ? mdsyserror(ep, errno, tname):
-					mdsyserror(ep, errno, META_DBCONFTMP);
+		    mdsyserror(ep, errno, META_DBCONFTMP);
 	}
 	free(tname);
 	return (rval);
@@ -894,13 +965,19 @@
 			c.c_locator.l_blkno = blkno;
 			(void) strncpy(c.c_locator.l_driver, dname,
 			    sizeof (c.c_locator.l_driver));
-			(void) splitname(bname, &c.c_devname);
+			if (splitname(bname, &c.c_devname) ==
+			    METASPLIT_LONGDISKNAME && devid_in_use == FALSE) {
+				rval = mddeverror(ep, MDE_DISKNAMETOOLONG,
+				    NODEV64, np->rname);
+				break;
+			}
+
 			c.c_locator.l_mnum = mnum;
 
 			/* Fill in setno, setname, and sideno */
 			c.c_setno = sp->setno;
 			(void) strncpy(c.c_setname, sp->setname,
-				sizeof (c.c_setname));
+			    sizeof (c.c_setname));
 			c.c_sideno = sideno;
 
 			/*
@@ -1147,7 +1224,7 @@
 	}
 
 	if ((fflush(tsfp) != 0) || (fsync(fileno(tsfp)) != 0) ||
-					    (fclose(tsfp) != 0)) {
+	    (fclose(tsfp) != 0)) {
 		(void) mdsyserror(ep, errno, tsname);
 		goto out;
 	}
@@ -1464,10 +1541,10 @@
 			if (stale_bool == TRUE)
 				flags |= MD_MSGF_NO_LOG;
 			send_rval = mdmn_send_message(sp->setno,
-				MD_MN_MSG_META_DB_ATTACH,
-				flags, (char *)&attach,
-				sizeof (md_mn_msg_meta_db_attach_t),
-				&resultp, ep);
+			    MD_MN_MSG_META_DB_ATTACH,
+			    flags, (char *)&attach,
+			    sizeof (md_mn_msg_meta_db_attach_t),
+			    &resultp, ep);
 			if (send_rval != 0) {
 				rval = -1;
 				if (resultp == NULL)
@@ -1491,62 +1568,73 @@
 			if (resultp)
 				free_result(resultp);
 		} else {
-		    /* Adding mddb(s) to just this node */
-		    for (i = 0; i < dbcnt; i++) {
-			(void) memset(&c, 0, sizeof (c));
-			/* Fill in device/replica info */
-			c.c_locator.l_dev = meta_cmpldev(np->dev);
-			c.c_locator.l_blkno = i * dbsize + 16;
-			blkno = c.c_locator.l_blkno;
-			(void) strncpy(c.c_locator.l_driver, cinfo->dname,
-			    sizeof (c.c_locator.l_driver));
-			(void) splitname(np->bname, &c.c_devname);
-			c.c_locator.l_mnum = meta_getminor(np->dev);
+			/* Adding mddb(s) to just this node */
+			for (i = 0; i < dbcnt; i++) {
+				(void) memset(&c, 0, sizeof (c));
+				/* Fill in device/replica info */
+				c.c_locator.l_dev = meta_cmpldev(np->dev);
+				c.c_locator.l_blkno = i * dbsize + 16;
+				blkno = c.c_locator.l_blkno;
+				(void) strncpy(c.c_locator.l_driver,
+				    cinfo->dname,
+				    sizeof (c.c_locator.l_driver));
 
-			/* Fill in setno, setname, and sideno */
-			c.c_setno = sp->setno;
-			if (! metaislocalset(sp)) {
-				if (MD_MNSET_DESC(sd)) {
-					c.c_multi_node = 1;
+				if (splitname(np->bname, &c.c_devname) ==
+				    METASPLIT_LONGDISKNAME && devid_in_use ==
+				    FALSE) {
+					rval = mddeverror(ep,
+					    MDE_DISKNAMETOOLONG,
+					    NODEV64, np->rname);
+					goto out;
 				}
-			}
-			(void) strcpy(c.c_setname, sp->setname);
-			c.c_sideno = sideno;
+
+				c.c_locator.l_mnum = meta_getminor(np->dev);
+
+				/* Fill in setno, setname, and sideno */
+				c.c_setno = sp->setno;
+				if (! metaislocalset(sp)) {
+					if (MD_MNSET_DESC(sd)) {
+						c.c_multi_node = 1;
+					}
+				}
+				(void) strcpy(c.c_setname, sp->setname);
+				c.c_sideno = sideno;
 
-			/*
-			 * Don't need device id information from this ioctl
-			 * Kernel determines device id from dev_t, which
-			 * is just what this code would do.
-			 */
-			c.c_locator.l_devid = (uint64_t)0;
-			c.c_locator.l_devid_flags = 0;
+				/*
+				 * Don't need device id information from this
+				 * ioctl Kernel determines device id from
+				 * dev_t, which is just what this code would do.
+				 */
+				c.c_locator.l_devid = (uint64_t)0;
+				c.c_locator.l_devid_flags = 0;
 
-			if (timeval != NULL)
-				c.c_timestamp = *timeval;
+				if (timeval != NULL)
+					c.c_timestamp = *timeval;
 
-			if (setup_med_cfg(sp, &c, (options & MDCHK_SET_FORCE),
-			    ep)) {
-				rval = -1;
-				goto out;
-			}
+				if (setup_med_cfg(sp, &c,
+				    (options & MDCHK_SET_FORCE), ep)) {
+					rval = -1;
+					goto out;
+				}
 
-			if (metaioctl(MD_DB_NEWDEV, &c, &c.c_mde, NULL) != 0) {
-				rval = mdstealerror(ep, &c.c_mde);
-				goto out;
+				if (metaioctl(MD_DB_NEWDEV, &c, &c.c_mde,
+				    NULL) != 0) {
+					rval = mdstealerror(ep, &c.c_mde);
+					goto out;
+				}
+				/*
+				 * This is either a traditional diskset OR this
+				 * is the first replica added to a MN diskset.
+				 * In either case, set broadcast to NO_BCAST so
+				 * that message won't go through rpc.mdcommd.
+				 * If this is a traditional diskset, the bcast
+				 * flag is ignored since traditional disksets
+				 * don't use the rpc.mdcommd.
+				 */
+				if (meta_db_addsidenms(sp, np, blkno,
+				    DB_ADDSIDENMS_NO_BCAST, ep))
+					goto out;
 			}
-			/*
-			 * This is either a traditional diskset OR this
-			 * is the first replica added to a MN diskset.
-			 * In either case, set broadcast to NO_BCAST so
-			 * that message won't go through rpc.mdcommd.
-			 * If this is a traditional diskset, the bcast
-			 * flag is ignored since traditional disksets
-			 * don't use the rpc.mdcommd.
-			 */
-			if (meta_db_addsidenms(sp, np, blkno,
-			    DB_ADDSIDENMS_NO_BCAST, ep))
-				goto out;
-		    }
 		}
 		if (! metaislocalset(sp)) {
 			/* update the dbcnt and size in dd */
@@ -1769,6 +1857,14 @@
 
 		devname = splicename(&c.c_devname);
 
+		if (strstr(devname, META_LONGDISKNAME_STR) != NULL) {
+			Free(devname);
+			devname = getlongname(&c, ep);
+			if (devname == NULL) {
+				return (-1);
+			}
+		}
+
 		if ((index = in_deletelist(devname, db_nlp)) != -1) {
 			found = 1;
 			tag_array[index] = 1;
@@ -1776,9 +1872,8 @@
 		}
 
 		errored = c.c_locator.l_flags & (MDDB_F_EREAD |
-				MDDB_F_EWRITE | MDDB_F_TOOSMALL |
-				MDDB_F_EFMT | MDDB_F_EDATA |
-				MDDB_F_EMASTER);
+		    MDDB_F_EWRITE | MDDB_F_TOOSMALL | MDDB_F_EFMT |
+		    MDDB_F_EDATA | MDDB_F_EMASTER);
 
 		/*
 		 * There are four combinations of "errored" and "found"
@@ -1837,8 +1932,8 @@
 	 */
 
 	if ((invalid_replicas_todelete != replica_delete_count) &&
-		(invalid_replicas_nottodelete > valid_replicas_nottodelete) &&
-				(force_option != MDFORCE_LOCAL))
+	    (invalid_replicas_nottodelete > valid_replicas_nottodelete) &&
+	    (force_option != MDFORCE_LOCAL))
 		return (mderror(ep, MDE_DEL_VALIDDB_NOTALLOWED, sp->setname));
 
 	/*
@@ -1911,10 +2006,10 @@
 			if (stale_bool == TRUE)
 				flags |= MD_MSGF_NO_LOG;
 			send_rval = mdmn_send_message(sp->setno,
-				MD_MN_MSG_META_DB_DETACH,
-				flags, (char *)&detach,
-				sizeof (md_mn_msg_meta_db_detach_t),
-				&resultp, ep);
+			    MD_MN_MSG_META_DB_DETACH,
+			    flags, (char *)&detach,
+			    sizeof (md_mn_msg_meta_db_detach_t),
+			    &resultp, ep);
 			if (send_rval != 0) {
 				rval = -1;
 				if (resultp == NULL)
@@ -1955,6 +2050,16 @@
 				}
 
 				devname = splicename(&c.c_devname);
+
+				if (strstr(devname, META_LONGDISKNAME_STR)
+				    != NULL) {
+					Free(devname);
+					devname = getlongname(&c, ep);
+					if (devname == NULL) {
+						return (-1);
+					}
+				}
+
 				if (strcmp(devname, np->bname) != 0) {
 					Free(devname);
 					i++;
@@ -2008,9 +2113,9 @@
 
 			for (i = 0; i < DAEMON_COUNT; i++) {
 				(void) snprintf(buf, MAXPATHLEN,
-					"/usr/bin/pkill -%s -x %s",
-					svmd_kill_list[i].svmd_kill_val,
-					svmd_kill_list[i].svmd_name);
+				    "/usr/bin/pkill -%s -x %s",
+				    svmd_kill_list[i].svmd_kill_val,
+				    svmd_kill_list[i].svmd_name);
 				if (pclose(popen(buf, "w")) == -1)
 					md_perror(buf);
 			}
@@ -2068,12 +2173,46 @@
 	md_replica_t	*rp;
 	char		*devname;
 	size_t		sz;
+	devid_nmlist_t	*disklist = NULL;
+	char		*devid_str;
 
 	/* allocate replicaname */
 	rp = Zalloc(sizeof (*rp));
 
 	/* get device name */
 	devname = splicename(&c->c_devname);
+
+	/*
+	 * Check if the device has a long name (>40 characters) and
+	 * if so then we have to use devids to get the device name.
+	 * If this cannot be done then we have to fail the request.
+	 */
+	if (strstr(devname, META_LONGDISKNAME_STR) != NULL) {
+		if (c->c_locator.l_devid != NULL) {
+			if (meta_deviceid_to_nmlist("/dev/dsk",
+			    (ddi_devid_t)(uintptr_t)c->c_locator.l_devid,
+			    c->c_locator.l_minor_name, &disklist) != 0) {
+				devid_str = devid_str_encode(
+				    (ddi_devid_t)(uintptr_t)
+				    c->c_locator.l_devid, NULL);
+				(void) mderror(ep, MDE_MISSING_DEVID_DISK, "");
+				mderrorextra(ep, devid_str);
+				if (devid_str != NULL)
+					devid_str_free(devid_str);
+				Free(rp);
+				Free(devname);
+				return (NULL);
+			}
+		} else {
+			(void) mderror(ep, MDE_NODEVID, "");
+			Free(rp);
+			Free(devname);
+			return (NULL);
+		}
+		Free(devname);
+		devname = disklist[0].devname;
+	}
+
 	if (flags & PRINT_FAST) {
 		if ((rp->r_namep = metaname_fast(&sp, devname,
 		    LOGICAL_DEVICE, ep)) == NULL) {
@@ -2194,7 +2333,7 @@
 			 * space has been alloc'd.
 			 */
 			c.c_locator.l_devid_flags =
-				MDDB_DEVID_SPACE | MDDB_DEVID_SZ;
+			    MDDB_DEVID_SPACE | MDDB_DEVID_SZ;
 		}
 
 		if (metaioctl(MD_DB_ENDDEV, &c, &c.c_mde, NULL) != 0) {
@@ -2215,10 +2354,10 @@
 		if (c.c_locator.l_devid_flags & MDDB_DEVID_NOSPACE) {
 			(void) fprintf(stderr,
 			    dgettext(TEXT_DOMAIN,
-				"Error: Relocation Information "
-				"(drvnm=%s, mnum=0x%lx) \n"
-				"relocation information size changed - \n"
-				"rerun command\n"),
+			    "Error: Relocation Information "
+			    "(drvnm=%s, mnum=0x%lx) \n"
+			    "relocation information size changed - \n"
+			    "rerun command\n"),
 			    c.c_locator.l_driver, c.c_locator.l_mnum);
 			(void) mderror(ep, MDE_DEVID_TOOBIG, NULL);
 			goto out;
@@ -2380,7 +2519,7 @@
 		(void) strcpy(c.c_locator.l_minor_name, minor_name);
 		free(minor_name);
 		c.c_locator.l_devid_flags = MDDB_DEVID_VALID |
-			MDDB_DEVID_SPACE | MDDB_DEVID_SZ;
+		    MDDB_DEVID_SPACE | MDDB_DEVID_SZ;
 		c.c_locator.l_devid_sz = sz;
 
 		devid_size = strlen(devidp);
@@ -2423,9 +2562,16 @@
 	c.c_id = 0;
 	c.c_setno = MD_LOCAL_SET;
 
-	/* Don't need device id information from this ioctl */
+	/*
+	 * While we do not need the devid here we may need to
+	 * know if devid's are being used by the kernel for
+	 * the replicas. This is because under some circumstances
+	 * we can only manipulate the SVM configuration if the
+	 * kernel is using devid's.
+	 */
 	c.c_locator.l_devid = (uint64_t)0;
-	c.c_locator.l_devid_flags = 0;
+	c.c_locator.l_devid_flags = MDDB_DEVID_GETSZ;
+	c.c_locator.l_devid_sz = 0;
 
 	if (metaioctl(MD_DB_GETDEV, &c, &c.c_mde, NULL) != 0) {
 		if (! mdismddberror(&c.c_mde, MDE_DB_INVALID))
@@ -2437,6 +2583,14 @@
 		return (mdmddberror(ep, MDE_DB_STALE, NODEV32, MD_LOCAL_SET,
 		    0, NULL));
 
+	if (c.c_locator.l_devid_sz != 0) {
+		/*
+		 * Devid's are being used to track the replicas because
+		 * there is space for a devid.
+		 */
+		devid_in_use = TRUE;
+	}
+
 	/* success */
 	return (rval);
 }
@@ -2508,7 +2662,7 @@
 		 * of traversing the list each time
 		 */
 		tailpp = meta_namelist_append_wrapper(
-			tailpp, rl->rl_repp->r_namep);
+		    tailpp, rl->rl_repp->r_namep);
 		++cnt;
 	}
 
--- a/usr/src/lib/lvm/libmeta/common/meta_error.c	Thu Sep 20 14:23:25 2007 -0700
+++ b/usr/src/lib/lvm/libmeta/common/meta_error.c	Fri Sep 21 01:54:14 2007 -0700
@@ -19,7 +19,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -180,7 +180,7 @@
 		case MDEC_DEV:
 		{
 			md_dev_error_t	*ip =
-					&ep->info.md_error_info_t_u.dev_error;
+			    &ep->info.md_error_info_t_u.dev_error;
 
 			ep->name = dev_name(MD_SET_BAD, ip->dev);
 			break;
@@ -190,7 +190,7 @@
 		case MDEC_USE:
 		{
 			md_use_error_t	*ip =
-					&ep->info.md_error_info_t_u.use_error;
+			    &ep->info.md_error_info_t_u.use_error;
 
 			ep->name = dev_name(MD_SET_BAD, ip->dev);
 			if (ip->where == NULL) {
@@ -204,7 +204,7 @@
 		case MDEC_MD:
 		{
 			md_md_error_t	*ip =
-					&ep->info.md_error_info_t_u.md_error;
+			    &ep->info.md_error_info_t_u.md_error;
 
 			ep->name = md_name(ip->mnum);
 			break;
@@ -214,7 +214,7 @@
 		case MDEC_COMP:
 		{
 			md_comp_error_t	*ip =
-					&ep->info.md_error_info_t_u.comp_error;
+			    &ep->info.md_error_info_t_u.comp_error;
 			char		*mdname, *devname;
 			size_t 		len;
 
@@ -235,7 +235,7 @@
 		case MDEC_HSP:
 		{
 			md_hsp_error_t	*ip =
-					&ep->info.md_error_info_t_u.hsp_error;
+			    &ep->info.md_error_info_t_u.hsp_error;
 
 			ep->name = hsp_name(ip->hsp);
 			break;
@@ -245,7 +245,7 @@
 		case MDEC_HS:
 		{
 			md_hs_error_t	*ip =
-					&ep->info.md_error_info_t_u.hs_error;
+			    &ep->info.md_error_info_t_u.hs_error;
 			char		*hspname, *devname;
 			size_t 		len;
 
@@ -265,7 +265,7 @@
 		case MDEC_MDDB:
 		{
 			md_mddb_error_t	*ip =
-					&ep->info.md_error_info_t_u.mddb_error;
+			    &ep->info.md_error_info_t_u.mddb_error;
 			if (ip->mnum != NODEV32)
 				ep->name = md_name(ip->mnum);
 			ep->name = set_name(ip->setno);
@@ -432,7 +432,7 @@
 )
 {
 	md_overlap_error_t *ip =
-			&ep->info.md_error_info_t_u.overlap_error;
+	    &ep->info.md_error_info_t_u.overlap_error;
 
 	assert(overlap != NULL);
 	mdclrerror(ep);
@@ -441,7 +441,7 @@
 	ip->overlap = Strdup(overlap);
 	ip->where = NULL;
 	if (where != NULL)
-	    ip->where = Strdup(where);
+		ip->where = Strdup(where);
 
 	metacookerror(ep, name);
 	return (-1);
@@ -718,7 +718,7 @@
 		break;
 	case MDE_NOTENOUGH_DB:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
-			"must have at least 1 database (-f overrides)"));
+		    "must have at least 1 database (-f overrides)"));
 		break;
 	case MDE_DELDB_NOTALLOWED:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
@@ -893,6 +893,10 @@
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
 		"Volume administration unavailable within non-global zones."));
 		break;
+	case MDE_MISSING_DEVID_DISK:
+		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
+		    "device id does not exist."));
+		break;
 	default:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
 		    "unknown void error code %d"), ip->errnum);
@@ -1060,6 +1064,12 @@
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
 		    "cannot repartition a slice with an existing replica"));
 		break;
+	case MDE_DISKNAMETOOLONG:
+		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
+		    "disk name is too long with device ids disabled "
+		    "in Solaris Volume Manager. Check /kernel/drv/md.conf "
+		    "for md_devid_destroy, remove it and reboot"));
+		break;
 	default:
 		(void) snprintf(p, psize,
 		    dgettext(TEXT_DOMAIN, "unknown dev error code %d"),
@@ -1081,7 +1091,7 @@
 )
 {
 	md_overlap_error_t	*ip =
-			&ep->info.md_error_info_t_u.overlap_error;
+	    &ep->info.md_error_info_t_u.overlap_error;
 	char		*p = buf + strlen(buf);
 	size_t		psize = size - strlen(buf);
 
@@ -1089,7 +1099,7 @@
 	case MDE_OVERLAP_MOUNTED:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
 		    "overlaps with %s which is mounted as \'%s\'"),
-			ip->overlap, ip->where);
+		    ip->overlap, ip->where);
 		break;
 	case MDE_OVERLAP_SWAP:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
@@ -1137,12 +1147,12 @@
 		 */
 		if (strcmp(ip->where, MDB_STR) != 0) {
 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
-				"has appeared more than once in the "
-				"specification of %s"), ip->where);
+			    "has appeared more than once in the "
+			    "specification of %s"), ip->where);
 		} else {
 			(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
-				"has appeared more than once in the "
-				"specification of " MDB_STR));
+			    "has appeared more than once in the "
+			    "specification of " MDB_STR));
 		}
 		break;
 	case MDE_OVERLAP:
@@ -1270,7 +1280,7 @@
 		break;
 	case MDE_LAST_SM:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
-			"attempt to detach last running submirror"));
+		    "attempt to detach last running submirror"));
 		break;
 	case MDE_NO_READABLE_SM:
 		(void) snprintf(p, psize, dgettext(TEXT_DOMAIN,
--- a/usr/src/lib/lvm/libmeta/common/metasplitname.c	Thu Sep 20 14:23:25 2007 -0700
+++ b/usr/src/lib/lvm/libmeta/common/metasplitname.c	Fri Sep 21 01:54:14 2007 -0700
@@ -2,9 +2,8 @@
  * CDDL HEADER START
  *
  * The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License").  You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
  *
  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
  * or http://www.opensolaris.org/os/licensing.
@@ -21,8 +20,8 @@
  */
 
 /*
- * Copyright (c) 1992, 1993, 2000 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -39,6 +38,8 @@
 	size_t prefixlen;
 	size_t suffixlen;
 	char	*lastslash;
+	int	retval = METASPLIT_SUCCESS;
+
 	lastslash = strrchr(name, '/');
 	if (lastslash != NULL) {
 		prefixlen = lastslash - name;
@@ -47,14 +48,26 @@
 		prefixlen = 0;
 		suffixlen = strlen(name);
 	}
-	if (prefixlen > MD_MAXPREFIX ||
-	    suffixlen > MD_MAXSUFFIX)
-		return (1);
+	if (prefixlen > MD_MAXPREFIX)
+		return (METASPLIT_LONGPREFIX);
+
+	if (suffixlen > MD_MAXSUFFIX) {
+		lastslash = META_LONGDISKNAME_STR;
+		prefixlen = 0;
+		suffixlen = strlen(lastslash);
+		(void) memcpy(SPN_SUFFIX(spn).suf_data, lastslash, suffixlen);
+		SPN_SUFFIX(spn).suf_len = suffixlen;
+		retval = METASPLIT_LONGDISKNAME;
+	} else {
+		(void) memcpy(SPN_SUFFIX(spn).suf_data, lastslash + 1,
+		    suffixlen);
+		SPN_SUFFIX(spn).suf_len = suffixlen;
+	}
+
 	(void) memcpy(SPN_PREFIX(spn).pre_data, name, prefixlen);
 	SPN_PREFIX(spn).pre_len = prefixlen;
-	(void) memcpy(SPN_SUFFIX(spn).suf_data, lastslash + 1, suffixlen);
-	SPN_SUFFIX(spn).suf_len = suffixlen;
-	return (0);
+
+	return (retval);
 }
 
 char *
--- a/usr/src/uts/common/sys/lvm/mdiox.x	Thu Sep 20 14:23:25 2007 -0700
+++ b/usr/src/uts/common/sys/lvm/mdiox.x	Fri Sep 21 01:54:14 2007 -0700
@@ -20,7 +20,7 @@
 % */
 %
 %/*
-% * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+% * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
 % * Use is subject to license terms.
 % */
 %
@@ -1404,7 +1404,8 @@
 				/* instance name desired for hot spare pool */
 				/* is being used for a metadevice. */
 	MDE_ZONE_ADMIN,		/* in a zone & no admin device */
-	MDE_NAME_ILLEGAL	/* illegal syntax for metadevice or hsp name */
+	MDE_NAME_ILLEGAL,	/* illegal syntax for metadevice or hsp name */
+	MDE_MISSING_DEVID_DISK	/* unable to find disk using devid */
 };
 
 struct md_void_error_t {
@@ -1455,7 +1456,8 @@
 	MDE_MULTNM,		/* Multiple entries for device in namespace */
 	MDE_TOO_MANY_PARTS,	/* dev has more than MD_MAX_PARTS partitions */
 	MDE_REPART_REPLICA,	/* replica slice would move with repartitioning */
-	MDE_IS_DUMP		/* device already in use as dump device */
+	MDE_IS_DUMP,		/* device already in use as dump device */
+	MDE_DISKNAMETOOLONG	/* devid's not in use and diskname too long */
 };
 
 struct md_dev_error_t {