PSARC 2004/776 device checking for fs utilities
authorsjelinek
Thu, 27 Oct 2005 09:01:18 -0700
changeset 767 0aa24dfb5d87
parent 766 c521de78a32f
child 768 daea417d4c6b
PSARC 2004/776 device checking for fs utilities PSARC 2005/461 Device in use checking environment variables 5084421 libdiskmgt needs to detect in use ZFS data 5085739 remove workaround for bug 4725434 6194015 Device in use checking for Solaris utilities-PSARC/2004/776 6261853 libdiskmgt does not work correctly in all cases on amd64 6268374 libdiskmgt allocates incorrect size for readdir_r() dirent argument 6291309 PSARC/2005/461 - libdiskmgt should enable bypassing of inuse checking 6301815 PSARC/2005/461-Need Sun private libdiskmgt flag for use during install to disable sysevent starting
usr/src/cmd/dumpadm/Makefile
usr/src/cmd/dumpadm/dconf.c
usr/src/cmd/dumpadm/dconf.h
usr/src/cmd/dumpadm/main.c
usr/src/cmd/format/Makefile
usr/src/cmd/format/analyze.c
usr/src/cmd/format/checkdev.c
usr/src/cmd/format/checkdev.h
usr/src/cmd/format/checkmount.c
usr/src/cmd/format/checkmount.h
usr/src/cmd/format/disk_generic.c
usr/src/cmd/format/main.c
usr/src/cmd/format/menu_cache.c
usr/src/cmd/format/menu_command.c
usr/src/cmd/format/menu_developer.c
usr/src/cmd/format/menu_fdisk.c
usr/src/cmd/format/menu_scsi.c
usr/src/cmd/format/modify_partition.c
usr/src/cmd/fs.d/Makefile
usr/src/cmd/fs.d/switchout.c
usr/src/cmd/swap/Makefile.com
usr/src/cmd/swap/swap.c
usr/src/lib/Makefile
usr/src/lib/libdiskmgt/Makefile
usr/src/lib/libdiskmgt/Makefile.com
usr/src/lib/libdiskmgt/common/cache.c
usr/src/lib/libdiskmgt/common/disks_private.h
usr/src/lib/libdiskmgt/common/drive.c
usr/src/lib/libdiskmgt/common/entry.c
usr/src/lib/libdiskmgt/common/findevs.c
usr/src/lib/libdiskmgt/common/inuse_fs.c
usr/src/lib/libdiskmgt/common/inuse_svm.c
usr/src/lib/libdiskmgt/common/inuse_zpool.c
usr/src/lib/libdiskmgt/common/libdiskmgt.h
usr/src/lib/libdiskmgt/common/media.c
usr/src/lib/libdiskmgt/common/partition.c
usr/src/lib/libdiskmgt/common/slice.c
usr/src/lib/libdiskmgt/spec/diskmgt.spec
usr/src/pkgdefs/etc/exception_list_i386
usr/src/pkgdefs/etc/exception_list_sparc
usr/src/tools/findunref/exception_list
--- a/usr/src/cmd/dumpadm/Makefile	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/dumpadm/Makefile	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 #ident	"%Z%%M%	%I%	%E% SMI"
@@ -32,6 +32,7 @@
 OBJS = main.o dconf.o minfree.o utils.o swap.o
 SRCS = $(OBJS:.o=.c)
 
+
 lint := LINTFLAGS = -mx
 
 include ../Makefile.cmd
@@ -45,6 +46,8 @@
 ROOTMANIFESTDIR = $(ROOTSVCSYSTEM)
 $(ROOTMANIFEST) := FILEMODE = 0444
 
+LDLIBS +=	-ldiskmgt
+
 .KEEP_STATE:
 
 all: $(PROG)
--- a/usr/src/cmd/dumpadm/dconf.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/dumpadm/dconf.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -38,6 +38,7 @@
 #include <stdio.h>
 #include <fcntl.h>
 #include <errno.h>
+#include <libdiskmgt.h>
 
 #include "dconf.h"
 #include "minfree.h"
@@ -50,6 +51,7 @@
 	int (*tok_print)(const dumpconf_t *, FILE *);
 } dc_token_t;
 
+
 static int print_device(const dumpconf_t *, FILE *);
 static int print_savdir(const dumpconf_t *, FILE *);
 static int print_content(const dumpconf_t *, FILE *);
@@ -344,9 +346,25 @@
 }
 
 int
-dconf_update(dumpconf_t *dcp)
+dconf_update(dumpconf_t *dcp, int checkinuse)
 {
-	int oconf;
+	int 		oconf;
+	int		error;
+	char		*msg;
+
+	error = 0;
+
+	if (checkinuse && (dm_inuse(dcp->dc_device, &msg, DM_WHO_DUMP,
+		    &error) || error)) {
+		if (error != 0) {
+			warn(gettext("failed to determine if %s is"
+			    " in use"), dcp->dc_device);
+		} else {
+			warn(msg);
+			free(msg);
+			return (-1);
+		}
+	}
 
 	/*
 	 * Save the existing dump configuration in case something goes wrong.
--- a/usr/src/cmd/dumpadm/dconf.h	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/dumpadm/dconf.h	Thu Oct 27 09:01:18 2005 -0700
@@ -20,8 +20,8 @@
  * CDDL HEADER END
  */
 /*
- * Copyright (c) 1998 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #ifndef	_DCONF_H
@@ -64,7 +64,7 @@
 extern int dconf_getdev(dumpconf_t *);
 extern int dconf_close(dumpconf_t *);
 extern int dconf_write(dumpconf_t *);
-extern int dconf_update(dumpconf_t *);
+extern int dconf_update(dumpconf_t *, int);
 extern void dconf_print(dumpconf_t *, FILE *);
 
 extern int dconf_str2device(dumpconf_t *, char *);
--- a/usr/src/cmd/dumpadm/main.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/dumpadm/main.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,8 +20,8 @@
  * CDDL HEADER END
  */
 /*
- * Copyright (c) 1998-2000 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -53,7 +53,7 @@
 	u_longlong_t minf;
 	struct stat st;
 	int c;
-
+	int dflag = 0;			/* for checking in use during -d ops */
 	int dcmode = DC_CURRENT;	/* kernel settings override unless -u */
 	int modified = 0;		/* have we modified the dump config? */
 	char *minfstr = NULL;		/* string value of -m argument */
@@ -116,10 +116,10 @@
 					return (E_USAGE);
 				modified++;
 				break;
-
 			case 'd':
 				if (dconf_str2device(&dc, optarg) == -1)
 					return (E_USAGE);
+				dflag++;
 				modified++;
 				break;
 
@@ -166,7 +166,7 @@
 		 * fails, we re-load the kernel configuration and write that
 		 * out to the file in order to force the file in sync.
 		 */
-		if (dconf_update(&dc) == -1)
+		if (dconf_update(&dc, 0) == -1)
 			(void) dconf_getdev(&dc);
 		if (dconf_write(&dc) == -1)
 			return (E_ERROR);
@@ -176,7 +176,8 @@
 		 * If we're modifying the configuration, then try
 		 * to update it, and write out the file if successful.
 		 */
-		if (dconf_update(&dc) == -1 || dconf_write(&dc) == -1)
+		if (dconf_update(&dc, dflag) == -1 ||
+		    dconf_write(&dc) == -1)
 			return (E_ERROR);
 	}
 
--- a/usr/src/cmd/format/Makefile	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/Makefile	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 1991-1997,2002,2003 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -28,7 +28,7 @@
 
 PROG= format
 
-COBJS=	add_definition.o analyze.o checkmount.o ctlr_scsi.o \
+COBJS=	add_definition.o analyze.o checkdev.o ctlr_scsi.o \
 	defect.o init_menus.o io.o label.o main.o \
 	menu.o menu_analyze.o menu_cache.o menu_command.o menu_defect.o \
 	menu_partition.o misc.o modify_partition.o partition.o \
@@ -56,7 +56,7 @@
 $(ROOTETCDATA) := OWNER = root
 $(ROOTETCDATA) := GROUP = sys
 
-LDLIBS +=	-ladm -lefi
+LDLIBS +=	-ladm -lefi -ldiskmgt -lnvpair
 
 .KEEP_STATE:
 
--- a/usr/src/cmd/format/analyze.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/analyze.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 1998-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -37,7 +37,7 @@
 #include "defect.h"
 #include "label.h"
 #include "param.h"
-#include "checkmount.h"
+#include "checkdev.h"
 
 
 /*
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/format/checkdev.c	Thu Oct 27 09:01:18 2005 -0700
@@ -0,0 +1,759 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * This file contains miscellaneous device validation routines.
+ */
+
+#include "global.h"
+#include <sys/mnttab.h>
+#include <sys/mntent.h>
+#include <sys/autoconf.h>
+
+#include <signal.h>
+#include <malloc.h>
+#include <unistd.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+#include <sys/fcntl.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
+#include <sys/sysmacros.h>
+#include <ctype.h>
+#include <libdiskmgt.h>
+#include <libnvpair.h>
+#include "misc.h"
+#include "checkdev.h"
+
+/* Function prototypes */
+#ifdef	__STDC__
+
+static struct 	swaptable *getswapentries(void);
+static void 	freeswapentries(struct swaptable *);
+static int	getpartition(char *pathname);
+static int 	checkpartitions(int bm_mounted);
+
+#else	/* __STDC__ */
+
+static struct swaptable *getswapentries();
+static void freeswapentries();
+static int	getpartition();
+static int 	checkpartitions();
+
+#endif	/* __STDC__ */
+
+extern char	*getfullname();
+
+static struct swaptable *
+getswapentries(void)
+{
+	register struct swaptable *st;
+	register struct swapent *swapent;
+	int	i, num;
+	char	fullpathname[MAXPATHLEN];
+
+	/*
+	 * get the number of swap entries
+	 */
+	if ((num = swapctl(SC_GETNSWP, (void *)NULL)) == -1) {
+		err_print("swapctl error ");
+		fullabort();
+	}
+	if (num == 0)
+		return (NULL);
+	if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int)))
+			== NULL) {
+		err_print("getswapentries: malloc  failed.\n");
+		fullabort();
+	}
+	swapent = st->swt_ent;
+	for (i = 0; i < num; i++, swapent++) {
+		if ((swapent->ste_path = malloc(MAXPATHLEN)) == NULL) {
+			err_print("getswapentries: malloc  failed.\n");
+			fullabort();
+		}
+	}
+	st->swt_n = num;
+	if ((num = swapctl(SC_LIST, (void *)st)) == -1) {
+		err_print("swapctl error ");
+		fullabort();
+	}
+	swapent = st->swt_ent;
+	for (i = 0; i < num; i++, swapent++) {
+		if (*swapent->ste_path != '/') {
+			(void) snprintf(fullpathname, sizeof (fullpathname),
+			    "/dev/%s", swapent->ste_path);
+			(void) strcpy(swapent->ste_path, fullpathname);
+		}
+	}
+	return (st);
+}
+
+static void
+freeswapentries(st)
+struct swaptable *st;
+{
+	register struct swapent *swapent;
+	int i;
+
+	swapent = st->swt_ent;
+	for (i = 0; i < st->swt_n; i++, swapent++)
+		free(swapent->ste_path);
+	free(st);
+
+}
+
+/*
+ *  function getpartition:
+ */
+static int
+getpartition(pathname)
+char *pathname;
+{
+	int		mfd;
+	struct dk_cinfo dkinfo;
+	struct stat	stbuf;
+	char		raw_device[MAXPATHLEN];
+	int		found = -1;
+
+	/*
+	 * Map the block device name to the raw device name.
+	 * If it doesn't appear to be a device name, skip it.
+	 */
+	if (match_substr(pathname, "/dev/") == 0)
+		return (found);
+	(void) strcpy(raw_device, "/dev/r");
+	(void) strcat(raw_device, pathname + strlen("/dev/"));
+	/*
+	 * Determine if this appears to be a disk device.
+	 * First attempt to open the device.  If if fails, skip it.
+	 */
+	if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) {
+		return (found);
+	}
+	/*
+	 * Must be a character device
+	 */
+	if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) {
+		(void) close(mfd);
+		return (found);
+	}
+	/*
+	 * Attempt to read the configuration info on the disk.
+	 */
+	if (ioctl(mfd, DKIOCINFO, &dkinfo) < 0) {
+		(void) close(mfd);
+		return (found);
+	}
+	/*
+	 * Finished with the opened device
+	 */
+	(void) close(mfd);
+
+	/*
+	 * If it's not the disk we're interested in, it doesn't apply.
+	 */
+	if (cur_disk->disk_dkinfo.dki_ctype != dkinfo.dki_ctype ||
+		cur_disk->disk_dkinfo.dki_cnum != dkinfo.dki_cnum ||
+		cur_disk->disk_dkinfo.dki_unit != dkinfo.dki_unit ||
+		strcmp(cur_disk->disk_dkinfo.dki_dname,
+				dkinfo.dki_dname) != 0) {
+		return (found);
+	}
+
+	/*
+	 *  Extract the partition that is mounted.
+	 */
+	return (PARTITION(stbuf.st_rdev));
+}
+
+/*
+ * This Routine checks to see if there are partitions used for swapping overlaps
+ * a given portion of a disk. If the start parameter is < 0, it means
+ * that the entire disk should be checked
+ */
+int
+checkswap(start, end)
+	diskaddr_t start, end;
+{
+	struct swaptable *st;
+	struct swapent *swapent;
+	int		i;
+	int		found = 0;
+	struct dk_map32	*map;
+	int		part;
+
+	/*
+	 * If we are only checking part of the disk, the disk must
+	 * have a partition map to check against.  If it doesn't,
+	 * we hope for the best.
+	 */
+	if (cur_parts == NULL)
+		return (0);
+
+	/*
+	 * check for swap entries
+	 */
+	st = getswapentries();
+	/*
+	 * if there are no swap entries return.
+	 */
+	if (st == (struct swaptable *)NULL)
+		return (0);
+	swapent = st->swt_ent;
+	for (i = 0; i < st->swt_n; i++, swapent++) {
+		if ((part = getpartition(swapent->ste_path)) != -1) {
+			if (start == UINT_MAX64) {
+				found = -1;
+				break;
+			}
+			map = &cur_parts->pinfo_map[part];
+			if ((start >= (int)(map->dkl_cylno * spc() +
+				map->dkl_nblk)) || (end < (int)(map->dkl_cylno
+							* spc()))) {
+					continue;
+			}
+			found = -1;
+			break;
+		};
+	}
+	freeswapentries(st);
+	/*
+	 * If we found trouble and we're running from a command file,
+	 * quit before doing something we really regret.
+	 */
+
+	if (found && option_f) {
+		err_print(
+"Operation on disks being used for swapping must be interactive.\n");
+		cmdabort(SIGINT);
+	}
+
+	return (found);
+
+
+}
+/*
+ * Determines if there are partitions that are a part of an SVM, VxVM, zpool
+ * volume or a live upgrade device,  overlapping a given portion of a disk.
+ * Mounts and swap devices are checked in legacy format code.
+ */
+int
+checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, int print,
+	int check_label)
+{
+
+	int 		error;
+	int 		found = 0;
+	int		check = 0;
+	int 		i;
+	int		bm_inuse = 0;
+	int		part = 0;
+	uint64_t	slice_start, slice_size;
+	dm_descriptor_t	*slices = NULL;
+	nvlist_t	*attrs = NULL;
+	char		*usage;
+	char		*name;
+
+	/*
+	 * For format, we get basic 'in use' details from libdiskmgt. After
+	 * that we must do the appropriate checking to see if the 'in use'
+	 * details require a bit of additional work.
+	 */
+
+	dm_get_slices(cur_disk_path, &slices, &error);
+	if (error) {
+		err_print("Error occurred with device in use checking: %s\n",
+		    strerror(error));
+		return (found);
+	}
+	if (slices == NULL)
+		return (found);
+
+	for (i = 0; slices[i] != NULL; i++) {
+		/*
+		 * If we are checking the whole disk
+		 * then any and all in use data is
+		 * relevant.
+		 */
+		if (start == UINT_MAX64) {
+			name = dm_get_name(slices[i], &error);
+			if (error != 0 || !name) {
+				err_print("Error occurred with device "
+				    "in use checking: %s\n",
+				    strerror(error));
+				continue;
+			}
+			if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) ||
+			    error) {
+				if (error != 0) {
+					dm_free_name(name);
+					name = NULL;
+					err_print("Error occurred with device "
+					    "in use checking: %s\n",
+					    strerror(error));
+					continue;
+				}
+				dm_free_name(name);
+				name = NULL;
+				/*
+				 * If this is a dump device, then it is
+				 * a failure. You cannot format a slice
+				 * that is a dedicated dump device.
+				 */
+
+				if (strstr(usage, DM_USE_DUMP)) {
+					if (print) {
+						err_print(usage);
+						free(usage);
+					}
+					dm_free_descriptors(slices);
+					return (1);
+				}
+				/*
+				 * We really found a device that is in use.
+				 * Set 'found' for the return value, and set
+				 * 'check' to indicate below that we must
+				 * get the partition number to set bm_inuse
+				 * in the event we are trying to label this
+				 * device. check_label is set when we are
+				 * checking modifications for in use slices
+				 * on the device.
+				 */
+				found ++;
+				check = 1;
+				if (print) {
+					err_print(usage);
+					free(usage);
+				}
+			}
+		} else {
+			/*
+			 * Before getting the in use data, verify that the
+			 * current slice is within the range we are checking.
+			 */
+			attrs = dm_get_attributes(slices[i], &error);
+			if (error) {
+				err_print("Error occurred with device in use "
+				    "checking: %s\n", strerror(error));
+				continue;
+			}
+			if (attrs == NULL) {
+				continue;
+			}
+
+			(void) nvlist_lookup_uint64(attrs, DM_START,
+			    &slice_start);
+			(void) nvlist_lookup_uint64(attrs, DM_SIZE,
+			    &slice_size);
+			if (start >= (slice_start + slice_size) ||
+			    (end < slice_start)) {
+				nvlist_free(attrs);
+				attrs = NULL;
+				continue;
+			}
+			name = dm_get_name(slices[i], &error);
+			if (error != 0 || !name) {
+				err_print("Error occurred with device "
+				    "in use checking: %s\n",
+				    strerror(error));
+				nvlist_free(attrs);
+				attrs = NULL;
+				continue;
+			}
+			if (dm_inuse(name, &usage,
+			    DM_WHO_FORMAT, &error) || error) {
+				if (error != 0) {
+					dm_free_name(name);
+					name = NULL;
+					err_print("Error occurred with device "
+					    "in use checking: %s\n",
+					    strerror(error));
+					nvlist_free(attrs);
+					attrs = NULL;
+					continue;
+				}
+				dm_free_name(name);
+				name = NULL;
+				/*
+				 * If this is a dump device, then it is
+				 * a failure. You cannot format a slice
+				 * that is a dedicated dump device.
+				 */
+				if (strstr(usage, DM_USE_DUMP)) {
+					if (print) {
+						err_print(usage);
+						free(usage);
+					}
+					dm_free_descriptors(slices);
+					nvlist_free(attrs);
+					return (1);
+				}
+				/*
+				 * We really found a device that is in use.
+				 * Set 'found' for the return value, and set
+				 * 'check' to indicate below that we must
+				 * get the partition number to set bm_inuse
+				 * in the event we are trying to label this
+				 * device. check_label is set when we are
+				 * checking modifications for in use slices
+				 * on the device.
+				 */
+				found ++;
+				check = 1;
+				if (print) {
+					err_print(usage);
+					free(usage);
+				}
+			}
+		}
+		/*
+		 * If check is set it means we found a slice(the current slice)
+		 * on this device in use in some way.  We potentially want
+		 * to check this slice when labeling is
+		 * requested. We set bm_inuse with this partition value
+		 * for use later if check_label was set when called.
+		 */
+		if (check) {
+			name = dm_get_name(slices[i], &error);
+			if (error != 0 || !name) {
+				err_print("Error occurred with device "
+				    "in use checking: %s\n",
+				    strerror(error));
+				nvlist_free(attrs);
+				attrs = NULL;
+				continue;
+			}
+			part = getpartition(name);
+			dm_free_name(name);
+			name = NULL;
+			if (part != -1) {
+				bm_inuse |= 1 << part;
+			}
+			check = 0;
+		}
+		/*
+		 * If we have attributes then we have successfully
+		 * found the slice we were looking for and we also
+		 * know this means we are not searching the whole
+		 * disk so break out of the loop
+		 * now.
+		 */
+		if (attrs) {
+			nvlist_free(attrs);
+			break;
+		}
+	}
+
+	if (slices) {
+		dm_free_descriptors(slices);
+	}
+
+	/*
+	 * The user is trying to label the disk. We have to do special
+	 * checking here to ensure they are not trying to modify a slice
+	 * that is in use in an incompatible way.
+	 */
+	if (check_label && bm_inuse) {
+		/*
+		 * !0 indicates that we found a
+		 * problem. In this case, we have overloaded
+		 * the use of checkpartitions to work for
+		 * in use devices. bm_inuse is representative
+		 * of the slice that is in use, not that
+		 * is mounted as is in the case of the normal
+		 * use of checkpartitions.
+		 *
+		 * The call to checkpartitions will return !0 if
+		 * we are trying to shrink a device that we have found
+		 * to be in use above.
+		 */
+		return (checkpartitions(bm_inuse));
+	}
+
+	return (found);
+}
+/*
+ * This routine checks to see if there are mounted partitions overlapping
+ * a given portion of a disk.  If the start parameter is < 0, it means
+ * that the entire disk should be checked.
+ */
+int
+checkmount(start, end)
+	diskaddr_t	start, end;
+{
+	FILE		*fp;
+	int		found = 0;
+	struct dk_map32	*map;
+	int		part;
+	struct mnttab	mnt_record;
+	struct mnttab	*mp = &mnt_record;
+
+	/*
+	 * If we are only checking part of the disk, the disk must
+	 * have a partition map to check against.  If it doesn't,
+	 * we hope for the best.
+	 */
+	if (cur_parts == NULL)
+		return (0);
+
+	/*
+	 * Lock out interrupts because of the mntent protocol.
+	 */
+	enter_critical();
+	/*
+	 * Open the mount table.
+	 */
+	fp = fopen(MNTTAB, "r");
+	if (fp == NULL) {
+		err_print("Unable to open mount table.\n");
+		fullabort();
+	}
+	/*
+	 * Loop through the mount table until we run out of entries.
+	 */
+	while ((getmntent(fp, mp)) != -1) {
+
+		if ((part = getpartition(mp->mnt_special)) == -1)
+			continue;
+
+		/*
+		 * It's a mount on the disk we're checking.  If we are
+		 * checking whole disk, then we found trouble.  We can
+		 * quit searching.
+		 */
+		if (start == UINT_MAX64) {
+			found = -1;
+			break;
+		}
+
+		/*
+		 * If the partition overlaps the zone we're checking,
+		 * then we found trouble.  We can quit searching.
+		 */
+		map = &cur_parts->pinfo_map[part];
+		if ((start >= (int)(map->dkl_cylno * spc() + map->dkl_nblk)) ||
+			(end < (int)(map->dkl_cylno * spc()))) {
+			continue;
+		}
+		found = -1;
+		break;
+	}
+	/*
+	 * Close down the mount table.
+	 */
+	(void) fclose(fp);
+	exit_critical();
+
+	/*
+	 * If we found trouble and we're running from a command file,
+	 * quit before doing something we really regret.
+	 */
+
+	if (found && option_f) {
+		err_print("Operation on mounted disks must be interactive.\n");
+		cmdabort(SIGINT);
+	}
+	/*
+	 * Return the result.
+	 */
+	return (found);
+}
+
+int
+check_label_with_swap()
+{
+	int			i;
+	struct swaptable *st;
+	struct swapent *swapent;
+	int	part;
+	int	bm_swap = 0;
+
+	/*
+	 * If we are only checking part of the disk, the disk must
+	 * have a partition map to check against.  If it doesn't,
+	 * we hope for the best.
+	 */
+	if (cur_parts == NULL)
+		return (0);	/* Will be checked later */
+
+	/*
+	 * Check for swap entries
+	 */
+	st = getswapentries();
+	/*
+	 * if there are no swap entries return.
+	 */
+	if (st == (struct swaptable *)NULL)
+		return (0);
+	swapent = st->swt_ent;
+	for (i = 0; i < st->swt_n; i++, swapent++)
+		if ((part = getpartition(swapent->ste_path)) != -1)
+				bm_swap |= (1 << part);
+	freeswapentries(st);
+
+	return (checkpartitions(bm_swap));
+}
+
+/*
+ * Check the new label with the existing label on the disk,
+ * to make sure that any mounted partitions are not being
+ * affected by writing the new label.
+ */
+int
+check_label_with_mount()
+{
+	FILE			*fp;
+	int			part;
+	struct mnttab		mnt_record;
+	struct mnttab		*mp = &mnt_record;
+	int			bm_mounted = 0;
+
+
+	/*
+	 * If we are only checking part of the disk, the disk must
+	 * have a partition map to check against.  If it doesn't,
+	 * we hope for the best.
+	 */
+	if (cur_parts == NULL)
+		return (0);	/* Will be checked later */
+
+	/*
+	 * Lock out interrupts because of the mntent protocol.
+	 */
+	enter_critical();
+	/*
+	 * Open the mount table.
+	 */
+	fp = fopen(MNTTAB, "r");
+	if (fp == NULL) {
+		err_print("Unable to open mount table.\n");
+		fullabort();
+	}
+	/*
+	 * Loop through the mount table until we run out of entries.
+	 */
+	while ((getmntent(fp, mp)) != -1) {
+		if ((part = getpartition(mp->mnt_special)) != -1)
+			bm_mounted |= (1 << part);
+	}
+	/*
+	 * Close down the mount table.
+	 */
+	(void) fclose(fp);
+	exit_critical();
+
+	return (checkpartitions(bm_mounted));
+
+}
+
+/*
+ * This Routine checks if any partitions specified
+ * are affected by writing the new label
+ */
+static int
+checkpartitions(int bm_mounted)
+{
+	struct dk_map32		*n;
+	struct dk_map		*o;
+	struct dk_allmap	old_map;
+	int			i, found = 0;
+
+	/*
+	 * Now we need to check that the current partition list and the
+	 * previous partition list (which there must be if we actually
+	 * have partitions mounted) overlap  in any way on the mounted
+	 * partitions
+	 */
+
+	/*
+	 * Get the "real" (on-disk) version of the partition table
+	 */
+	if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
+		err_print("Unable to get current partition map.\n");
+		return (-1);
+	}
+	for (i = 0; i < NDKMAP; i++) {
+		if (bm_mounted & (1 << i)) {
+			/*
+			 * This partition is mounted
+			 */
+			o = &old_map.dka_map[i];
+			n = &cur_parts->pinfo_map[i];
+#ifdef DEBUG
+			fmt_print(
+"checkpartitions :checking partition '%c' \n", i + PARTITION_BASE);
+#endif
+			/*
+			 * If partition is identical, we're fine.
+			 * If the partition grows, we're also fine, because
+			 * the routines in partition.c check for overflow.
+			 * It will (ultimately) be up to the routines in
+			 * partition.c to warn about creation of overlapping
+			 * partitions
+			 */
+			if (o->dkl_cylno == n->dkl_cylno &&
+					o->dkl_nblk <= n->dkl_nblk) {
+#ifdef	DEBUG
+				if (o->dkl_nblk < n->dkl_nblk) {
+					fmt_print(
+"- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk);
+				}
+				fmt_print("\n");
+#endif
+				continue;
+			}
+#ifdef DEBUG
+			fmt_print("- changes; old (%d,%d)->new (%d,%d)\n",
+				o->dkl_cylno, o->dkl_nblk, n->dkl_cylno,
+				n->dkl_nblk);
+#endif
+			found = -1;
+		}
+		if (found)
+			break;
+	}
+
+	/*
+	 * If we found trouble and we're running from a command file,
+	 * quit before doing something we really regret.
+	 */
+
+	if (found && option_f) {
+		err_print("Operation on mounted disks or \
+disks currently being used for swapping must be interactive.\n");
+		cmdabort(SIGINT);
+	}
+	/*
+	 * Return the result.
+	 */
+	return (found);
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/cmd/format/checkdev.h	Thu Oct 27 09:01:18 2005 -0700
@@ -0,0 +1,51 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef	_CHECKDEV_H
+#define	_CHECKDEV_H
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+#ifdef	__cplusplus
+extern "C" {
+#endif
+
+/*
+ *	Prototypes for ANSI C
+ */
+int	checkmount(diskaddr_t start, diskaddr_t end);
+int	checkswap(diskaddr_t start, diskaddr_t end);
+int	check_label_with_mount(void);
+int	check_label_with_swap(void);
+int	checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end,
+	    int print, int check_label);
+
+
+#ifdef	__cplusplus
+}
+#endif
+
+#endif	/* _CHECKDEV_H */
--- a/usr/src/cmd/format/checkmount.c	Thu Oct 27 04:35:13 2005 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,517 +0,0 @@
-/*
- * 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.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 1991-2003 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-/*
- * This file contians miscellaneous routines.
- */
-#include "global.h"
-
-#include <sys/mnttab.h>
-#include <sys/mntent.h>
-#include <sys/autoconf.h>
-
-#include <signal.h>
-#include <malloc.h>
-#include <unistd.h>
-#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/fcntl.h>
-#include <sys/stat.h>
-#include <sys/swap.h>
-#include <sys/sysmacros.h>
-#include <ctype.h>
-#include "misc.h"
-#include "checkmount.h"
-
-/* Function prototypes */
-#ifdef	__STDC__
-
-static struct swaptable *getswapentries(void);
-static void freeswapentries(struct swaptable *);
-static int	getpartition(char *pathname);
-static int	checkpartitions(int mounted);
-
-#else	/* __STDC__ */
-
-static struct swaptable *getswapentries();
-static void freeswapentries();
-static int	getpartition();
-static int	checkpartitions();
-
-#endif	/* __STDC__ */
-
-static struct swaptable *
-getswapentries(void)
-{
-	register struct swaptable *st;
-	register struct swapent *swapent;
-	int	i, num;
-	char	fullpathname[MAXPATHLEN];
-
-	/*
-	 * get the number of swap entries
-	 */
-	if ((num = swapctl(SC_GETNSWP, (void *)NULL)) == -1) {
-		err_print("swapctl error ");
-		fullabort();
-	}
-	if (num == 0)
-		return (NULL);
-	if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int)))
-			== NULL) {
-		err_print("getswapentries: malloc  failed.\n");
-		fullabort();
-	}
-	swapent = st->swt_ent;
-	for (i = 0; i < num; i++, swapent++) {
-		if ((swapent->ste_path = malloc(MAXPATHLEN)) == NULL) {
-			err_print("getswapentries: malloc  failed.\n");
-			fullabort();
-		}
-	}
-	st->swt_n = num;
-	if ((num = swapctl(SC_LIST, (void *)st)) == -1) {
-		err_print("swapctl error ");
-		fullabort();
-	}
-	swapent = st->swt_ent;
-	for (i = 0; i < num; i++, swapent++) {
-		if (*swapent->ste_path != '/') {
-			(void) snprintf(fullpathname, sizeof (fullpathname),
-			    "/dev/%s", swapent->ste_path);
-			(void) strcpy(swapent->ste_path, fullpathname);
-		}
-	}
-	return (st);
-}
-
-static void
-freeswapentries(st)
-struct swaptable *st;
-{
-	register struct swapent *swapent;
-	int i;
-
-	swapent = st->swt_ent;
-	for (i = 0; i < st->swt_n; i++, swapent++)
-		free(swapent->ste_path);
-	free(st);
-
-}
-
-/*
- *  function getpartition:
- */
-static int
-getpartition(pathname)
-char *pathname;
-{
-	int		mfd;
-	struct dk_cinfo dkinfo;
-	struct stat	stbuf;
-	char		raw_device[MAXPATHLEN];
-	int		found = -1;
-
-	/*
-	 * Map the block device name to the raw device name.
-	 * If it doesn't appear to be a device name, skip it.
-	 */
-	if (match_substr(pathname, "/dev/") == 0)
-		return (found);
-	(void) strcpy(raw_device, "/dev/r");
-	(void) strcat(raw_device, pathname + strlen("/dev/"));
-	/*
-	 * Determine if this appears to be a disk device.
-	 * First attempt to open the device.  If if fails, skip it.
-	 */
-	if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) {
-		return (found);
-	}
-	/*
-	 * Must be a character device
-	 */
-	if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) {
-		(void) close(mfd);
-		return (found);
-	}
-	/*
-	 * Attempt to read the configuration info on the disk.
-	 */
-	if (ioctl(mfd, DKIOCINFO, &dkinfo) < 0) {
-		(void) close(mfd);
-		return (found);
-	}
-	/*
-	 * Finished with the opened device
-	 */
-	(void) close(mfd);
-
-	/*
-	 * If it's not the disk we're interested in, it doesn't apply.
-	 */
-	if (cur_disk->disk_dkinfo.dki_ctype != dkinfo.dki_ctype ||
-		cur_disk->disk_dkinfo.dki_cnum != dkinfo.dki_cnum ||
-		cur_disk->disk_dkinfo.dki_unit != dkinfo.dki_unit ||
-		strcmp(cur_disk->disk_dkinfo.dki_dname,
-				dkinfo.dki_dname) != 0) {
-		return (found);
-	}
-
-	/*
-	 *  Extract the partition that is mounted.
-	 */
-	return (PARTITION(stbuf.st_rdev));
-}
-
-/*
- * This Routine checks to see if there are partitions used for swapping overlaps
- * a given portion of a disk. If the start parameter is < 0, it means
- * that the entire disk should be checked
- */
-int
-checkswap(start, end)
-	diskaddr_t start, end;
-{
-	struct swaptable *st;
-	struct swapent *swapent;
-	int		i;
-	int		found = 0;
-	struct dk_map32	*map;
-	int		part;
-
-	/*
-	 * If we are only checking part of the disk, the disk must
-	 * have a partition map to check against.  If it doesn't,
-	 * we hope for the best.
-	 */
-	if (cur_parts == NULL)
-		return (0);
-
-	/*
-	 * check for swap entries
-	 */
-	st = getswapentries();
-	/*
-	 * if there are no swap entries return.
-	 */
-	if (st == (struct swaptable *)NULL)
-		return (0);
-	swapent = st->swt_ent;
-	for (i = 0; i < st->swt_n; i++, swapent++) {
-		if ((part = getpartition(swapent->ste_path)) != -1) {
-			if (start == UINT_MAX64) {
-				found = -1;
-				break;
-			}
-			map = &cur_parts->pinfo_map[part];
-			if ((start >= (int)(map->dkl_cylno * spc() +
-				map->dkl_nblk)) || (end < (int)(map->dkl_cylno
-							* spc()))) {
-					continue;
-			}
-			found = -1;
-			break;
-		};
-	}
-	freeswapentries(st);
-	/*
-	 * If we found trouble and we're running from a command file,
-	 * quit before doing something we really regret.
-	 */
-
-	if (found && option_f) {
-		err_print(
-"Operation on disks being used for swapping must be interactive.\n");
-		cmdabort(SIGINT);
-	}
-
-	return (found);
-
-
-}
-
-/*
- * This routine checks to see if there are mounted partitions overlapping
- * a given portion of a disk.  If the start parameter is < 0, it means
- * that the entire disk should be checked.
- */
-int
-checkmount(start, end)
-	diskaddr_t	start, end;
-{
-	FILE		*fp;
-	int		found = 0;
-	struct dk_map32	*map;
-	int		part;
-	struct mnttab	mnt_record;
-	struct mnttab	*mp = &mnt_record;
-
-	/*
-	 * If we are only checking part of the disk, the disk must
-	 * have a partition map to check against.  If it doesn't,
-	 * we hope for the best.
-	 */
-	if (cur_parts == NULL)
-		return (0);
-
-	/*
-	 * Lock out interrupts because of the mntent protocol.
-	 */
-	enter_critical();
-	/*
-	 * Open the mount table.
-	 */
-	fp = fopen(MNTTAB, "r");
-	if (fp == NULL) {
-		err_print("Unable to open mount table.\n");
-		fullabort();
-	}
-	/*
-	 * Loop through the mount table until we run out of entries.
-	 */
-	while ((getmntent(fp, mp)) != -1) {
-
-		if ((part = getpartition(mp->mnt_special)) == -1)
-			continue;
-
-		/*
-		 * It's a mount on the disk we're checking.  If we are
-		 * checking whole disk, then we found trouble.  We can
-		 * quit searching.
-		 */
-		if (start == UINT_MAX64) {
-			found = -1;
-			break;
-		}
-
-		/*
-		 * If the partition overlaps the zone we're checking,
-		 * then we found trouble.  We can quit searching.
-		 */
-		map = &cur_parts->pinfo_map[part];
-		if ((start >= (int)(map->dkl_cylno * spc() + map->dkl_nblk)) ||
-			(end < (int)(map->dkl_cylno * spc()))) {
-			continue;
-		}
-		found = -1;
-		break;
-	}
-	/*
-	 * Close down the mount table.
-	 */
-	(void) fclose(fp);
-	exit_critical();
-
-	/*
-	 * If we found trouble and we're running from a command file,
-	 * quit before doing something we really regret.
-	 */
-
-	if (found && option_f) {
-		err_print("Operation on mounted disks must be interactive.\n");
-		cmdabort(SIGINT);
-	}
-	/*
-	 * Return the result.
-	 */
-	return (found);
-}
-
-int
-check_label_with_swap()
-{
-	int			i;
-	struct swaptable *st;
-	struct swapent *swapent;
-	int	part;
-	int	bm_swap = 0;
-
-	/*
-	 * If we are only checking part of the disk, the disk must
-	 * have a partition map to check against.  If it doesn't,
-	 * we hope for the best.
-	 */
-	if (cur_parts == NULL)
-		return (0);	/* Will be checked later */
-
-	/*
-	 * Check for swap entries
-	 */
-	st = getswapentries();
-	/*
-	 * if there are no swap entries return.
-	 */
-	if (st == (struct swaptable *)NULL)
-		return (0);
-	swapent = st->swt_ent;
-	for (i = 0; i < st->swt_n; i++, swapent++)
-		if ((part = getpartition(swapent->ste_path)) != -1)
-				bm_swap |= (1 << part);
-	freeswapentries(st);
-
-	return (checkpartitions(bm_swap));
-}
-
-/*
- * Check the new label with the existing label on the disk,
- * to make sure that any mounted partitions are not being
- * affected by writing the new label.
- */
-int
-check_label_with_mount()
-{
-	FILE			*fp;
-	int			part;
-	struct mnttab		mnt_record;
-	struct mnttab		*mp = &mnt_record;
-	int			bm_mounted = 0;
-
-
-	/*
-	 * If we are only checking part of the disk, the disk must
-	 * have a partition map to check against.  If it doesn't,
-	 * we hope for the best.
-	 */
-	if (cur_parts == NULL)
-		return (0);	/* Will be checked later */
-
-	/*
-	 * Lock out interrupts because of the mntent protocol.
-	 */
-	enter_critical();
-	/*
-	 * Open the mount table.
-	 */
-	fp = fopen(MNTTAB, "r");
-	if (fp == NULL) {
-		err_print("Unable to open mount table.\n");
-		fullabort();
-	}
-	/*
-	 * Loop through the mount table until we run out of entries.
-	 */
-	while ((getmntent(fp, mp)) != -1) {
-		if ((part = getpartition(mp->mnt_special)) != -1)
-			bm_mounted |= (1 << part);
-	}
-	/*
-	 * Close down the mount table.
-	 */
-	(void) fclose(fp);
-	exit_critical();
-
-	return (checkpartitions(bm_mounted));
-
-}
-
-/*
- * This Routine checks if any partitions specified by the
- * bit-map of mounted/swap partitions are affected by
- * writing the new label
- */
-static int
-checkpartitions(bm_mounted)
-int bm_mounted;
-{
-	struct dk_map32		*n;
-	struct dk_map		*o;
-	struct dk_allmap	old_map;
-	int			i, found = 0;
-
-	/*
-	 * Now we need to check that the current partition list and the
-	 * previous partition list (which there must be if we actually
-	 * have partitions mounted) overlap  in any way on the mounted
-	 * partitions
-	 */
-
-	/*
-	 * Get the "real" (on-disk) version of the partition table
-	 */
-	if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
-		err_print("Unable to get current partition map.\n");
-		return (-1);
-	}
-	for (i = 0; i < NDKMAP; i++) {
-		if (bm_mounted & (1 << i)) {
-			/*
-			 * This partition is mounted
-			 */
-			o = &old_map.dka_map[i];
-			n = &cur_parts->pinfo_map[i];
-#ifdef DEBUG
-			fmt_print(
-"checkpartitions :checking partition '%c' \n", i + PARTITION_BASE);
-#endif
-			/*
-			 * If partition is identical, we're fine.
-			 * If the partition grows, we're also fine, because
-			 * the routines in partition.c check for overflow.
-			 * It will (ultimately) be up to the routines in
-			 * partition.c to warn about creation of overlapping
-			 * partitions
-			 */
-			if (o->dkl_cylno == n->dkl_cylno &&
-					o->dkl_nblk <= n->dkl_nblk) {
-#ifdef	DEBUG
-				if (o->dkl_nblk < n->dkl_nblk) {
-					fmt_print(
-"- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk);
-				}
-				fmt_print("\n");
-#endif
-				continue;
-			}
-#ifdef DEBUG
-			fmt_print("- changes; old (%d,%d)->new (%d,%d)\n",
-				o->dkl_cylno, o->dkl_nblk, n->dkl_cylno,
-				n->dkl_nblk);
-#endif
-			found = -1;
-		}
-		if (found)
-			break;
-	}
-
-	/*
-	 * If we found trouble and we're running from a command file,
-	 * quit before doing something we really regret.
-	 */
-
-	if (found && option_f) {
-		err_print("Operation on mounted disks or \
-disks currently being used for swapping must be interactive.\n");
-		cmdabort(SIGINT);
-	}
-	/*
-	 * Return the result.
-	 */
-	return (found);
-}
--- a/usr/src/cmd/format/checkmount.h	Thu Oct 27 04:35:13 2005 -0700
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,50 +0,0 @@
-/*
- * 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.
- *
- * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
- * or http://www.opensolaris.org/os/licensing.
- * See the License for the specific language governing permissions
- * and limitations under the License.
- *
- * When distributing Covered Code, include this CDDL HEADER in each
- * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
- * If applicable, add the following below this CDDL HEADER, with the
- * fields enclosed by brackets "[]" replaced with your own identifying
- * information: Portions Copyright [yyyy] [name of copyright owner]
- *
- * CDDL HEADER END
- */
-/*
- * Copyright 1991-2002 Sun Microsystems, Inc.  All rights reserved.
- * Use is subject to license terms.
- */
-
-#ifndef	_CHECKMOUNT_H
-#define	_CHECKMOUNT_H
-
-#pragma ident	"%Z%%M%	%I%	%E% SMI"
-
-#ifdef	__cplusplus
-extern "C" {
-#endif
-
-
-/*
- *	Prototypes for ANSI C
- */
-int	checkmount(diskaddr_t start, diskaddr_t end);
-int	checkswap(diskaddr_t start, diskaddr_t end);
-int	check_label_with_mount(void);
-int	check_label_with_swap(void);
-
-
-#ifdef	__cplusplus
-}
-#endif
-
-#endif	/* _CHECKMOUNT_H */
--- a/usr/src/cmd/format/disk_generic.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/disk_generic.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,8 +20,8 @@
  * CDDL HEADER END
  */
 /*
- * Copyright (c) 1998-2001 by Sun Microsystems, Inc.
- * All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -57,7 +57,7 @@
 #include "startup.h"
 #include "partition.h"
 #include "prompts.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "io.h"
 #include "ctlr_scsi.h"
 #include "auto_sense.h"
--- a/usr/src/cmd/format/main.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/main.c	Thu Oct 27 09:01:18 2005 -0700
@@ -25,7 +25,6 @@
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
-
 /*
  * This file contains the main entry point of the program and other
  * routines relating to the general flow.
@@ -54,7 +53,7 @@
 #include "menu_command.h"
 #include "menu_partition.h"
 #include "prompts.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "label.h"
 
 extern	struct menu_item menu_command[];
@@ -541,6 +540,13 @@
 		err_print("Warning: Current Disk has mounted partitions.\n");
 
 	/*
+	 * If any part of this device is also part of an SVM, VxVM or
+	 * Live Upgrade device, print a warning.
+	 */
+	(void) checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
+	    (diskaddr_t)-1, 1, 0);
+
+	/*
 	 * Get the Solaris Fdisk Partition information
 	 */
 	(void) copy_solaris_part(&cur_disk->fdisk_part);
--- a/usr/src/cmd/format/menu_cache.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/menu_cache.c	Thu Oct 27 09:01:18 2005 -0700
@@ -21,7 +21,8 @@
  */
 
 /*
- * Copyright (c) 1999-2001 by Sun Microsystems, Inc.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -50,7 +51,7 @@
 #include "startup.h"
 #include "partition.h"
 #include "prompts.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "io.h"
 #include "ctlr_scsi.h"
 #include "auto_sense.h"
--- a/usr/src/cmd/format/menu_command.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/menu_command.c	Thu Oct 27 09:01:18 2005 -0700
@@ -56,7 +56,7 @@
 #include "startup.h"
 #include "partition.h"
 #include "prompts.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "io.h"
 #include "ctlr_scsi.h"
 #include "auto_sense.h"
@@ -607,6 +607,18 @@
 currently being used for swapping.\n");
 		return (-1);
 	}
+
+	/*
+	 * Check for partitions being used in SVM, VxVM or LU devices
+	 */
+
+	if ((tptr != oldtype) &&
+		checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
+		    (diskaddr_t)-1, 0, 0)) {
+		err_print("Cannot set disk type while its "
+		    "partitions are currently in use.\n");
+				return (-1);
+	}
 	/*
 	 * If the type selected is different from the previous type,
 	 * mark the disk as not labelled and reload the current
@@ -748,7 +760,6 @@
 	fmt_print("\n");
 	return (0);
 }
-
 /*
  * This routine implements the 'format' command.  It allows the user
  * to format and verify any portion of the disk.
@@ -757,11 +768,11 @@
 c_format()
 {
 	diskaddr_t		start, end;
-	time_t		clock;
-	int		format_time, format_tracks, format_cyls;
-	int		format_interval;
-	int		deflt, status;
-	u_ioparam_t	ioparam;
+	time_t			clock;
+	int			format_time, format_tracks, format_cyls;
+	int			format_interval;
+	int			deflt, status;
+	u_ioparam_t		ioparam;
 
 	/*
 	 * There must be a current disk type and a current disk
@@ -857,6 +868,16 @@
 currently being used for swapping.\n");
 		return (-1);
 	}
+	/*
+	 * Check for partitions being used in SVM, VxVM or LU devices
+	 * in this format zone
+	 */
+	if (checkdevinuse(cur_disk->disk_name, start, end, 0, 0)) {
+		err_print("Cannot format disk while its partitions "
+			    "are currently in use.\n");
+			return (-1);
+	}
+
 	if (SCSI && (format_time = scsi_format_time()) > 0) {
 		fmt_print(
 		    "Ready to format.  Formatting cannot be interrupted\n"
@@ -1118,6 +1139,12 @@
 		return (-1);
 	}
 
+	if (checkdevinuse(cur_disk->disk_name, bn, bn, 0, 0)) {
+		if (check("Repair is in a partition which is currently "
+		    "in use.\ncontinue"))
+			return (-1);
+	}
+
 	/*
 	 * Try to read the sector before repairing it.  If we can
 	 * get good data out of it, we can write that data back
@@ -1288,8 +1315,8 @@
 int
 c_label()
 {
-	int	 status;
-	int	deflt, *defltptr = NULL;
+	int			status;
+	int			deflt, *defltptr = NULL;
 
 	/*
 	 * There must be a current disk type (and therefore a current disk).
@@ -1341,6 +1368,17 @@
 		}
 	}
 
+	/*
+	 * Check to see if any partitions used for svm, vxvm or live upgrade
+	 * are on the disk. If so, refuse to label the disk, but only
+	 * if we are trying to shrink a partition in use.
+	 */
+	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
+	    (diskaddr_t)-1, 0, 1)) {
+		err_print("Cannot label disk when "
+		    "partitions are in use as described.\n");
+		return (-1);
+	}
 
 	/*
 	 * If there is not a current partition map, warn the user we
--- a/usr/src/cmd/format/menu_developer.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/menu_developer.c	Thu Oct 27 09:01:18 2005 -0700
@@ -21,7 +21,8 @@
  */
 
 /*
- * Copyright (c) 1993-2001 by Sun Microsystems, Inc.
+ * Copyright 2005 Sun Microsystems, Inc.   All rights reserved.
+ * Use is subject to license terms.
  */
 
 #pragma ident	"%Z%%M%	%I%	%E% SMI"
@@ -50,7 +51,7 @@
 #include "startup.h"
 #include "partition.h"
 #include "prompts.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "io.h"
 #include "ctlr_scsi.h"
 #include "auto_sense.h"
--- a/usr/src/cmd/format/menu_fdisk.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/menu_fdisk.c	Thu Oct 27 09:01:18 2005 -0700
@@ -55,7 +55,7 @@
 #include "startup.h"
 #include "partition.h"
 #include "prompts.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "io.h"
 #include "ctlr_scsi.h"
 #include "auto_sense.h"
--- a/usr/src/cmd/format/menu_scsi.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/menu_scsi.c	Thu Oct 27 09:01:18 2005 -0700
@@ -21,7 +21,7 @@
  */
 
 /*
- * Copyright 1991-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -45,7 +45,7 @@
 #include "menu_scsi.h"
 #include "ctlr_scsi.h"
 #include "startup.h"
-#include "checkmount.h"
+#include "checkdev.h"
 
 
 #ifdef	__STDC__
@@ -565,6 +565,15 @@
 currently being used for swapping.\n\n");
 		return (-1);
 	}
+	/*
+	 * Are any being used for SVM, VxVM or live upgrade.
+	 */
+	if (checkdevinuse(cur_disk->disk_name, (diskaddr_t)-1,
+	    (diskaddr_t)-1, 0, 0)) {
+		err_print("Cannot format disk while its partitions are "
+		    "currently being used as described.\n");
+		return (-1);
+	}
 
 	/*
 	 * Let the user choose between formatting with either
--- a/usr/src/cmd/format/modify_partition.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/format/modify_partition.c	Thu Oct 27 09:01:18 2005 -0700
@@ -34,7 +34,7 @@
 #include "menu_partition.h"
 #include "menu_command.h"
 #include "modify_partition.h"
-#include "checkmount.h"
+#include "checkdev.h"
 #include "misc.h"
 #include "label.h"
 #include "auto_sense.h"
--- a/usr/src/cmd/fs.d/Makefile	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/fs.d/Makefile	Thu Oct 27 09:01:18 2005 -0700
@@ -153,7 +153,7 @@
 	$(POST_PROCESS)
 
 $(SPPROG):	switchout.o deffs.o fssnapsup.o
-	$(LINK.c) -o $@ switchout.o deffs.o fssnapsup.o $(LDLIBS)
+	$(LINK.c) -o $@ switchout.o deffs.o fssnapsup.o $(LDLIBS) -ldiskmgt
 	$(POST_PROCESS)
 
 install: $(FSLIB) .WAIT $(SUBDIRS) .WAIT install_local
--- a/usr/src/cmd/fs.d/switchout.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/fs.d/switchout.c	Thu Oct 27 09:01:18 2005 -0700
@@ -24,7 +24,7 @@
 
 
 /*
- * Copyright 1996-2003 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -41,6 +41,11 @@
 #include	<sys/stat.h>
 #include	<fcntl.h>
 #include	<string.h>
+#include	<libdiskmgt.h>
+#include	"fslib.h"
+
+
+static int match(char **opts, char *s);
 
 #define	FSTYPE_MAX	8
 #define	ARGV_MAX	1024
@@ -117,13 +122,18 @@
 	char	*vfs_path = VFS_PATH;
 	char	*alt_path = ALT_PATH;
 	int	i;
+	int	j;
 	int	verbose = 0;		/* set if -V is specified */
 	int	F_flg = 0;
 	int	mflag = 0;
+	int	Nflag = 0;
 	char	*oopts = NULL;
+	char	*tmpopts = NULL;	/* used for in use checking */
 	int	iflag = 0;
 	int	usgflag = 0;
 	int	arg;			/* argument from getopt() */
+	char	*msg;
+	int	error;
 	extern	char *optarg;		/* getopt specific */
 	extern	int optind;
 	extern	int opterr;
@@ -167,6 +177,10 @@
 				newargv[newargc++] = "-o";
 				newargv[newargc++] = optarg;
 				oopts = optarg;
+				if (!Nflag) {
+					tmpopts = optarg;
+					Nflag = has_Nflag(tmpopts);
+				}
 				break;
 			case '?':	/* print usage message */
 				newargv[newargc++] = "-?";
@@ -192,14 +206,15 @@
 			optarg = NULL;
 	}
 	if (F_flg > 1) {
-		fprintf(stderr, gettext("%s: more than one FSType specified\n"),
-			cbasename);
+		(void) fprintf(stderr,
+		    gettext("%s: more than one FSType specified\n"),
+		    cbasename);
 		usage(cbasename, c_ptr->c_usgstr);
 		exit(2);
 	}
 	if (fstype != NULL) {
 		if (strlen(fstype) > FSTYPE_MAX) {
-			fprintf(stderr,
+			(void) fprintf(stderr,
 			    gettext("%s: FSType %s exceeds %d characters\n"),
 			    cbasename, fstype, FSTYPE_MAX);
 			exit(2);
@@ -224,18 +239,19 @@
 	}
 
 	if ((special == NULL) && (!usgflag)) {
-		fprintf(stderr, gettext("%s: special not specified\n"),
+		(void) fprintf(stderr, gettext("%s: special not specified\n"),
 		    cbasename);
 		usage(cbasename, c_ptr->c_usgstr);
 		exit(2);
 	}
+
 	if ((fstype == NULL) && (usgflag))
 		usage(cbasename, c_ptr->c_usgstr);
 	if (fstype == NULL)
 		lookup();
 	if (fstype == NULL) {
-		fprintf(stderr, gettext("%s: FSType cannot be identified\n"),
-			cbasename);
+		(void) fprintf(stderr,
+		    gettext("%s: FSType cannot be identified\n"), cbasename);
 		usage(cbasename, c_ptr->c_usgstr);
 		exit(2);
 	}
@@ -257,6 +273,29 @@
 	}
 
 	/*
+	 * Prior to executing the command for mkfs check for device in use.
+	 * If the mflag is set, user wants to see command that created
+	 * an already existing filesystem. Do not check for in use in this
+	 * case. If Nflag is set user wants to see what the parameters
+	 * would be to create the filesystem. Do not check for in use in
+	 * this case.
+	 */
+	if (strcmp(cbasename, "mkfs") == 0 && !mflag && !Nflag) {
+		if (dm_inuse(special, &msg, DM_WHO_MKFS, &error) ||
+		    error) {
+			if (error != 0) {
+				(void) fprintf(stderr, gettext("Error occurred"
+				    " with device in use checking: %s\n"),
+				    strerror(error));
+			} else {
+				(void) fprintf(stderr, "%s", msg);
+				free(msg);
+				exit(2);
+			}
+		}
+	}
+
+	/*
 	 *  Execute the FSType specific command.
 	 */
 	execv(full_path, &newargv[1]);
@@ -279,18 +318,18 @@
 	}
 	if (errno != ENOENT) {
 		perror(cbasename);
-		fprintf(stderr, gettext("%s: cannot execute %s\n"), cbasename,
-		    full_path);
+		(void) fprintf(stderr, gettext("%s: cannot execute %s\n"),
+		    cbasename, full_path);
 		exit(2);
 	}
 
 	if (sysfs(GETFSIND, fstype) == (-1)) {
-		fprintf(stderr,
+		(void) fprintf(stderr,
 		    gettext("%s: FSType %s not installed in the kernel\n"),
 		    cbasename, fstype);
 		exit(2);
 	}
-	fprintf(stderr,
+	(void) fprintf(stderr,
 	    gettext("%s: Operation not applicable for FSType %s \n"),
 	    cbasename, fstype);
 	exit(2);
@@ -301,9 +340,10 @@
 char **usg;
 {
 	int i;
-	fprintf(stderr, gettext("Usage:\n"));
+	(void) fprintf(stderr, gettext("Usage:\n"));
 	for (i = 0; usg[i] != NULL; i++)
-		fprintf(stderr, "%s %s\n", gettext(cmd), gettext(usg[i]));
+		(void) fprintf(stderr, "%s %s\n", gettext(cmd),
+		    gettext(usg[i]));
 	exit(2);
 }
 
@@ -323,7 +363,8 @@
 	struct vfstab	vget, vref;
 
 	if ((fd = fopen(vfstab, "r")) == NULL) {
-		fprintf(stderr, gettext("%s: cannot open vfstab\n"), cbasename);
+		(void) fprintf(stderr, gettext("%s: cannot open vfstab\n"),
+		    cbasename);
 		exit(1);
 	}
 	vfsnull(&vref);
@@ -345,13 +386,13 @@
 		fstype = vget.vfs_fstype;
 		break;
 	case VFS_TOOLONG:
-		fprintf(stderr,
+		(void) fprintf(stderr,
 		    gettext("%s: line in vfstab exceeds %d characters\n"),
 		    cbasename, VFS_LINE_MAX-2);
 		exit(1);
 		break;
 	case VFS_TOOFEW:
-		fprintf(stderr,
+		(void) fprintf(stderr,
 		    gettext("%s: line in vfstab has too few entries\n"),
 		    cbasename);
 		exit(1);
@@ -376,8 +417,9 @@
 			if (errstr == NULL)
 				errstr = gettext("Unknown error");
 
-			fprintf(stderr, gettext("%s: %s: error %d: %s\n"),
-				cmd, mountpoint, en, errstr);
+			(void) fprintf(stderr,
+			    gettext("%s: %s: error %d: %s\n"),
+			    cmd, mountpoint, en, errstr);
 
 			exit(2);
 		}
@@ -385,3 +427,55 @@
 	}
 	fssnap_show_status(mountpoint, opts, 1, (opts ? 0 : 1));
 }
+static int
+has_Nflag(char *opts)
+{
+	while (opts != NULL && *opts != '\0') {
+		if (match(&opts, "N")) {
+			return (1);
+		}
+		if (!opts)
+			break;
+		if (*opts == ',')
+			opts ++;
+		if (*opts == ' ')
+			opts ++;
+	}
+	return (0);
+}
+/*
+ * Parses the -o [fs specific options string] to search for the UFS -N flag.
+ * Return the opts string pointing to the next position in the string if
+ * match is not found. A delimiter of , or ' ' can be used depending on the
+ * caller, newfs or mkfs.
+ */
+static int
+match(char **opts, char *s)
+{
+	char *cs;
+	char *tmp_str;
+
+	cs = *opts;
+
+	while (*cs++ == *s) {
+		if (*s++ == '\0') {
+			goto true;
+		}
+	}
+	if (*s != '\0') {
+		/*
+		 * If we cannot find the delimiter it means we
+		 * have hit the end of the string.
+		 */
+		tmp_str = strchr(*opts, ',');
+		if (!tmp_str)
+			tmp_str = strchr(*opts, ' ');
+
+		*opts = tmp_str;
+		return (0);
+	}
+true:
+	cs--;
+	*opts = cs;
+	return (1);
+}
--- a/usr/src/cmd/swap/Makefile.com	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/swap/Makefile.com	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -46,6 +46,7 @@
 
 all: $(PROG)
 
+LDLIBS	+=	-ldiskmgt
 $(PROG): $(OBJS)
 	$(LINK.c) $(OBJS) -o $@ $(LDLIBS)
 	$(POST_PROCESS)
--- a/usr/src/cmd/swap/swap.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/cmd/swap/swap.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -63,6 +63,7 @@
 #include	<fcntl.h>
 #include	<locale.h>
 #include	<libintl.h>
+#include	<libdiskmgt.h>
 
 #define	LFLAG	0x01	/* swap -l (list swap devices) */
 #define	DFLAG	0x02	/* swap -d (delete swap device) */
@@ -85,9 +86,11 @@
 {
 	int c, flag = 0;
 	int ret;
+	int error = 0;
 	off_t s_offset = 0;
 	off_t length = 0;
 	char *pathname;
+	char *msg;
 
 	(void) setlocale(LC_ALL, "");
 
@@ -185,9 +188,6 @@
 					exit(1);
 				}
 			}
-			if ((ret = valid(pathname,
-			    s_offset * 512, length * 512)) == 0)
-				ret = add(pathname, s_offset, length, flag);
 			break;
 
 		case '1':
@@ -203,6 +203,32 @@
 			exit(1);
 		}
 	}
+	/*
+	 * do the add here. Check for in use prior to add.
+	 * The values for length and offset are set above.
+	 */
+	if (flag & AFLAG) {
+		/*
+		 * If device is in use for a swap device, print message
+		 * and exit.
+		 */
+		if (dm_inuse(pathname, &msg, DM_WHO_SWAP, &error) ||
+		    error) {
+			if (error != 0) {
+				(void) fprintf(stderr, gettext("Error occurred"
+				    " with device in use checking: %s\n"),
+				    strerror(error));
+			} else {
+				(void) fprintf(stderr, "%s", msg);
+				free(msg);
+				exit(1);
+			}
+		}
+		if ((ret = valid(pathname,
+		    s_offset * 512, length * 512)) == 0) {
+		    ret = add(pathname, s_offset, length, flag);
+		}
+	}
 	if (!flag) {
 		usage();
 		exit(1);
--- a/usr/src/lib/Makefile	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/Makefile	Thu Oct 27 09:01:18 2005 -0700
@@ -275,6 +275,7 @@
 	libdevice	\
 	libdevid	\
 	libdevinfo	\
+	libdiskmgt	\
 	libdladm	\
 	libdlpi		\
 	libdhcpagent	\
--- a/usr/src/lib/libdiskmgt/Makefile	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/Makefile	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2002-2003 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -29,20 +29,27 @@
 include ../Makefile.lib
 
 HDRS =		libdiskmgt.h
+ROOTHDRDIR=	$(ROOT)/usr/include
+ROOTHDRS=	$(HDRS:%=$(ROOTHDRDIR)/%)
+CHECKDIRS=	$(HDRS:%.h=%.check)
 HDRDIR =	common
 SUBDIRS =	spec .WAIT $(MACH) $(BUILD64) $(MACH64)
 
+$(ROOTHDRDIR)/%: %
+	$(INS.file)
+
 all :=		TARGET = all
 clean :=	TARGET = clean
 clobber	:=	TARGET = clobber
 install	:=	TARGET = install
 lint :=		TARGET = lint
+install_h:=	TARGET = install_h
 
 .KEEP_STATE:
 
 all clean clobber install lint: $(SUBDIRS)
 
-install_h:
+install_h: $(ROOTHDRS)
 
 check:		$(CHECKHDRS)
 
--- a/usr/src/lib/libdiskmgt/Makefile.com	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/Makefile.com	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 #
-# Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 # ident	"%Z%%M%	%I%	%E% SMI"
@@ -32,7 +32,7 @@
 		entry.o cache.o drive.o controller.o alias.o path.o \
                 media.o slice.o partition.o findevs.o events.o \
                 bus.o inuse_mnt.o inuse_svm.o inuse_lu.o inuse_fs.o \
-                inuse_vxvm.o inuse_dump.o
+                inuse_vxvm.o inuse_dump.o inuse_zpool.o
 
 include ../../Makefile.lib
 
--- a/usr/src/lib/libdiskmgt/common/cache.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/cache.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -652,8 +652,13 @@
 
 	cache_loaded = 1;
 
-	if ((status = events_start_event_watcher()) != 0) {
-	    return (status);
+	/*
+	 * Only start the event thread if we are not doing an install
+	 */
+	if (getenv("_LIBDISKMGT_INSTALL") == NULL) {
+		if ((status = events_start_event_watcher()) != 0) {
+			return (status);
+		}
 	}
 
 	return (0);
--- a/usr/src/lib/libdiskmgt/common/disks_private.h	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/disks_private.h	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -262,6 +262,7 @@
 int		inuse_mnt(char *slice, nvlist_t *attrs, int *errp);
 int		inuse_svm(char *slice, nvlist_t *attrs, int *errp);
 int		inuse_lu(char *slice, nvlist_t *attrs, int *errp);
+int		inuse_zpool(char *slice, nvlist_t *attrs, int *errp);
 int		inuse_dump(char *slice, nvlist_t *attrs, int *errp);
 int		inuse_vxvm(char *slice, nvlist_t *attrs, int *errp);
 int		inuse_fs(char *slice, nvlist_t *attrs, int *errp);
--- a/usr/src/lib/libdiskmgt/common/drive.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/drive.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -682,7 +682,7 @@
 		}
 
 		if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) +
-		    _PC_NAME_MAX + 1)) == NULL) {
+		    PATH_MAX + 1)) == NULL) {
 		    /* out of memory */
 		    (void) close(fd);
 		    return (-1);
--- a/usr/src/lib/libdiskmgt/common/entry.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/entry.c	Thu Oct 27 09:01:18 2005 -0700
@@ -34,11 +34,16 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <libintl.h>
+#include <locale.h>
+#include <sys/debug.h>
 
 #include "libdiskmgt.h"
 #include "disks_private.h"
 #include "partition.h"
 
+extern	char	*getfullblkname();
+
 
 extern dm_desc_type_t drive_assoc_types[];
 extern dm_desc_type_t bus_assoc_types[];
@@ -49,8 +54,11 @@
 extern dm_desc_type_t path_assoc_types[];
 extern dm_desc_type_t alias_assoc_types[];
 
+
 static dm_descriptor_t *ptr_array_to_desc_array(descriptor_t **ptrs, int *errp);
 static descriptor_t **desc_array_to_ptr_array(dm_descriptor_t *da, int *errp);
+static int build_usage_string(char *dname, char *by, char *data, char **use,
+	int *found, int *errp);
 
 void
 dm_free_descriptor(dm_descriptor_t desc)
@@ -403,46 +411,57 @@
 	cache_rlock();
 
 	if (!cache_is_valid_desc(dp)) {
-	    cache_unlock();
-	    *errp = EBADF;
-	    return (NULL);
+		cache_unlock();
+		*errp = EBADF;
+		return (NULL);
 	}
 
 	/* verify that the descriptor is still valid */
 	if (dp->p.generic == NULL) {
-	    cache_unlock();
-	    *errp = ENODEV;
-	    return (NULL);
+		cache_unlock();
+		*errp = ENODEV;
+		return (NULL);
 	}
 
 	switch (dp->type) {
 	case DM_DRIVE:
-	    stats = drive_get_stats(dp, stat_type, errp);
-	    break;
+		stats = drive_get_stats(dp, stat_type, errp);
+		break;
 	case DM_BUS:
-	    stats = bus_get_stats(dp, stat_type, errp);
-	    break;
+		stats = bus_get_stats(dp, stat_type, errp);
+		break;
 	case DM_CONTROLLER:
-	    stats = controller_get_stats(dp, stat_type, errp);
-	    break;
+		stats = controller_get_stats(dp, stat_type, errp);
+		break;
 	case DM_MEDIA:
-	    stats = media_get_stats(dp, stat_type, errp);
-	    break;
+		stats = media_get_stats(dp, stat_type, errp);
+		break;
 	case DM_SLICE:
-	    stats = slice_get_stats(dp, stat_type, errp);
-	    break;
+		if (stat_type == DM_SLICE_STAT_USE) {
+			/*
+			 * If NOINUSE_CHECK is set, we do not perform
+			 * the in use checking if the user has set stat_type
+			 * DM_SLICE_STAT_USE
+			 */
+			if (getenv("NOINUSE_CHECK") != NULL) {
+				stats = NULL;
+				break;
+			}
+		}
+		stats = slice_get_stats(dp, stat_type, errp);
+		break;
 	case DM_PARTITION:
-	    stats = partition_get_stats(dp, stat_type, errp);
-	    break;
+		stats = partition_get_stats(dp, stat_type, errp);
+		break;
 	case DM_PATH:
-	    stats = path_get_stats(dp, stat_type, errp);
-	    break;
+		stats = path_get_stats(dp, stat_type, errp);
+		break;
 	case DM_ALIAS:
-	    stats = alias_get_stats(dp, stat_type, errp);
-	    break;
+		stats = alias_get_stats(dp, stat_type, errp);
+		break;
 	default:
-	    *errp = EINVAL;
-	    break;
+		*errp = EINVAL;
+		break;
 	}
 
 	cache_unlock();
@@ -468,7 +487,284 @@
 
 	return (dp->type);
 }
+/*
+ * Returns, via slices paramater, a dm_descriptor_t list of
+ * slices for the named disk drive.
+ */
+void
+dm_get_slices(char *drive, dm_descriptor_t **slices, int *errp)
+{
+	dm_descriptor_t alias;
+	dm_descriptor_t	*media;
+	dm_descriptor_t *disk;
 
+	*slices = NULL;
+	*errp = 0;
+
+	if (drive == NULL) {
+		return;
+	}
+
+	alias = dm_get_descriptor_by_name(DM_ALIAS, drive, errp);
+
+	/*
+	 * Errors must be handled by the caller. The dm_descriptor_t *
+	 * values will be NULL if an error occured in these calls.
+	 */
+
+	if (alias != NULL) {
+		disk = dm_get_associated_descriptors(alias, DM_DRIVE, errp);
+		dm_free_descriptor(alias);
+		if (disk != NULL) {
+			media = dm_get_associated_descriptors(*disk,
+			    DM_MEDIA, errp);
+			dm_free_descriptors(disk);
+			if (media != NULL) {
+				*slices = dm_get_associated_descriptors(*media,
+				    DM_SLICE, errp);
+				dm_free_descriptors(media);
+			}
+		}
+	}
+}
+/*
+ * Convenience function to get slice stats
+ */
+void
+dm_get_slice_stats(char *slice, nvlist_t **dev_stats, int *errp)
+{
+	dm_descriptor_t	devp;
+
+	*dev_stats = NULL;
+	*errp = 0;
+
+	if (slice == NULL) {
+		return;
+	}
+
+	/*
+	 * Errors must be handled by the caller. The dm_descriptor_t *
+	 * values will be NULL if an error occured in these calls.
+	 */
+	devp = dm_get_descriptor_by_name(DM_SLICE, slice, errp);
+	if (devp != NULL) {
+		*dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE,
+		    errp);
+		dm_free_descriptor(devp);
+	}
+}
+
+/*
+ * Returns 'in use' details, if found, about a specific dev_name,
+ * based on the caller(who). It is important to note that it is possible
+ * for there to be more than one 'in use' statistic regarding a dev_name.
+ * The **msg parameter returns a list of 'in use' details. This message
+ * is formatted via gettext().
+ */
+int
+dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
+{
+	nvlist_t *dev_stats = NULL;
+	char *by, *data;
+	nvpair_t *nvwhat = NULL;
+	nvpair_t *nvdesc = NULL;
+	int	found = 0;
+	char	*dname = NULL;
+
+	*errp = 0;
+	*msg = NULL;
+
+	dname = getfullblkname(dev_name);
+	/*
+	 * If we cannot find the block name, we cannot check the device
+	 * for in use statistics. So, return found, which is == 0.
+	 */
+	if (dname == NULL || *dname == '\0') {
+		return (found);
+	}
+
+	dm_get_slice_stats(dname, &dev_stats, errp);
+	if (dev_stats == NULL) {
+		/*
+		 * If there is an error, but it isn't a no device found error
+		 * return the error as recorded. Otherwise, with a full
+		 * block name, we might not be able to get the slice
+		 * associated, and will get an ENODEV error. For example,
+		 * an SVM metadevice will return a value from getfullblkname()
+		 * but libdiskmgt won't be able to find this device for
+		 * statistics gathering. This is expected and we should not
+		 * report errnoneous errors.
+		 */
+		if (*errp) {
+			if (*errp == ENODEV) {
+				*errp = 0;
+			}
+		}
+		free(dname);
+		return (found);
+	}
+
+	for (;;) {
+
+		nvwhat = nvlist_next_nvpair(dev_stats, nvdesc);
+		nvdesc = nvlist_next_nvpair(dev_stats, nvwhat);
+
+		/*
+		 * End of the list found.
+		 */
+		if (nvwhat == NULL || nvdesc == NULL) {
+			break;
+		}
+		/*
+		 * Otherwise, we check to see if this client(who) cares
+		 * about this in use scenario
+		 */
+
+		ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0);
+		ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0);
+		/*
+		 * If we error getting the string value continue on
+		 * to the next pair(if there is one)
+		 */
+		if (nvpair_value_string(nvwhat, &by)) {
+			continue;
+		}
+		if (nvpair_value_string(nvdesc, &data)) {
+			continue;
+		}
+
+		switch (who) {
+			case DM_WHO_MKFS:
+				/*
+				 * mkfs is not in use for these cases.
+				 * All others are in use.
+				 */
+				if (strcmp(by, DM_USE_LU) == 0 ||
+				    strcmp(by, DM_USE_FS) == 0) {
+					break;
+				}
+				if (build_usage_string(dname,
+				    by, data, msg, &found, errp) != 0) {
+					if (*errp) {
+						goto out;
+					}
+				}
+				break;
+			case DM_WHO_SWAP:
+				/*
+				 * Not in use for this.
+				 */
+				if (strcmp(by, DM_USE_DUMP) == 0 ||
+				    strcmp(by, DM_USE_FS) == 0) {
+					break;
+				}
+
+				if (build_usage_string(dname,
+				    by, data, msg, &found, errp) != 0) {
+					if (*errp) {
+						goto out;
+					}
+				}
+				break;
+			case DM_WHO_DUMP:
+				/*
+				 * Not in use for this.
+				 */
+				if ((strcmp(by, DM_USE_MOUNT) == 0 &&
+				    strcmp(data, "swap") == 0) ||
+				    strcmp(by, DM_USE_DUMP) == 0 ||
+				    strcmp(by, DM_USE_FS) == 0) {
+					break;
+				}
+				if (build_usage_string(dname,
+				    by, data, msg, &found, errp)) {
+					if (*errp) {
+						goto out;
+					}
+				}
+				break;
+
+			case DM_WHO_FORMAT:
+				if (strcmp(by, DM_USE_FS) == 0)
+					break;
+				if (build_usage_string(dname,
+				    by, data, msg, &found, errp) != 0) {
+					if (*errp) {
+						goto out;
+					}
+				}
+				break;
+			default:
+				/*
+				 * nothing found in use for this client
+				 * of libdiskmgt. Default is 'not in use'.
+				 */
+				break;
+		}
+	}
+out:
+	if (dname != NULL)
+		free(dname);
+	if (dev_stats != NULL)
+		nvlist_free(dev_stats);
+
+	return (found);
+}
+
+void
+dm_get_usage_string(char *what, char *how, char **usage_string)
+{
+
+
+	if (usage_string == NULL || what == NULL) {
+		return;
+	}
+	*usage_string = NULL;
+
+	if (strcmp(what, DM_USE_MOUNT) == 0) {
+		if (strcmp(how, "swap") == 0) {
+			*usage_string = dgettext(TEXT_DOMAIN,
+			    "%s is currently used by swap. Please see swap(1M)."
+			    "\n");
+		} else {
+			*usage_string = dgettext(TEXT_DOMAIN,
+			    "%s is currently mounted on %s."
+			    " Please see umount(1M).\n");
+		}
+	} else if (strcmp(what, DM_USE_VFSTAB) == 0) {
+		*usage_string = dgettext(TEXT_DOMAIN,
+		    "%s is normally mounted on %s according to /etc/vfstab. "
+		    "Please remove this entry to use this device.\n");
+	} else if (strcmp(what, DM_USE_FS) == 0) {
+		*usage_string = dgettext(TEXT_DOMAIN,
+		    "Warning: %s contains a %s filesystem.\n");
+	} else if (strcmp(what, DM_USE_SVM) == 0) {
+		if (strcmp(how, "mdb") == 0) {
+			*usage_string = dgettext(TEXT_DOMAIN,
+			    "%s contains an SVM %s. Please see "
+			    "metadb(1M).\n");
+		} else {
+			*usage_string = dgettext(TEXT_DOMAIN,
+			    "%s is part of SVM volume %s. "
+			    "Please see metaclear(1M).\n");
+		}
+	} else if (strcmp(what, DM_USE_VXVM) == 0) {
+		*usage_string = dgettext(TEXT_DOMAIN,
+		    "%s is part of VxVM volume %s.\n");
+	} else if (strcmp(what, DM_USE_LU) == 0) {
+		*usage_string = dgettext(TEXT_DOMAIN,
+		    "%s is in use for live upgrade %s. Please see ludelete(1M)."
+		    "\n");
+	} else if (strcmp(what, DM_USE_DUMP) == 0) {
+		*usage_string = dgettext(TEXT_DOMAIN,
+		    "%s is in use by %s. Please see dumpadm(1M)."
+		    "\n");
+	} else if (strcmp(what, DM_USE_ZPOOL) == 0) {
+		*usage_string = dgettext(TEXT_DOMAIN,
+		    "%s is in use by zpool %s. Please see zpool(1M)."
+		    "\n");
+	}
+}
 void
 libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp)
 {
@@ -597,3 +893,50 @@
 	return (da);
 #endif
 }
+/*
+ * Build the usage string for the in use data. Return the build string in
+ * the msg parameter. This function takes care of reallocing all the memory
+ * for this usage string. Usage string is returned already formatted for
+ * localization.
+ */
+static int
+build_usage_string(char *dname, char *by, char *data, char **msg,
+    int *found, int *errp)
+{
+	int	len0;
+	int	len1;
+	char	*use;
+	char	*p;
+
+	*errp = 0;
+
+	dm_get_usage_string(by, data, &use);
+	if (!use) {
+		return (-1);
+	}
+
+	if (*msg)
+		len0 = strlen(*msg);
+	else
+		len0 = 0;
+	/* LINTED */
+	len1 = snprintf(NULL, 0, use, dname, data);
+
+	/*
+	 * If multiple in use details they
+	 * are listed 1 per line for ease of
+	 * reading. dm_find_usage_string
+	 * formats these appropriately.
+	 */
+	if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) {
+		*errp = errno;
+		free(*msg);
+		return (-1);
+	}
+	*msg = p;
+
+	/* LINTED */
+	(void) snprintf(*msg + len0, len1 + 1, use, dname, data);
+	(*found)++;
+	return (0);
+}
--- a/usr/src/lib/libdiskmgt/common/findevs.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/findevs.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -978,7 +978,7 @@
 	    diskp->removable = get_prop(REMOVABLE_PROP, args->node);
 	    if (diskp->removable == -1) {
 		diskp->removable = 0;
-#ifdef i386
+#if defined(i386) || defined(__amd64)
 		/*
 		 * x86 does not have removable property.  Check for common
 		 * removable drives, zip & jaz, and mark those correctly.
--- a/usr/src/lib/libdiskmgt/common/inuse_fs.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/inuse_fs.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -142,7 +142,6 @@
 		    libdiskmgt_add_str(attrs, DM_USED_BY, DM_USE_VFSTAB, errp);
 		    libdiskmgt_add_str(attrs, DM_USED_NAME, mountp, errp);
 		    found = 1;
-		    break;
 		}
 		listp = listp->next;
 	    }
--- a/usr/src/lib/libdiskmgt/common/inuse_svm.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/inuse_svm.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -124,35 +124,46 @@
 
 	(void) mutex_lock(&init_lock);
 	if (!initialized) {
-	    /* dynamically load libmeta */
-	    if (init_svm()) {
-		/* need to initialize the cluster library to avoid seg faults */
-		(mdl_sdssc_bind_library)();
+		/* dynamically load libmeta */
+		if (init_svm()) {
+			/*
+			 * need to initialize the cluster library to
+			 * avoid seg faults
+			 */
+			(mdl_sdssc_bind_library)();
+
+			/* load the SVM cache */
+			*errp = load_svm();
 
-		/* load the SVM cache */
-		*errp = load_svm();
+			if (*errp == 0) {
+				/* start a thread to monitor the svm config */
+				sysevent_handle_t *shp;
+				const char *subclass_list[1];
+				/*
+				 * Only start the svmevent thread if
+				 * we are not doing an install
+				 */
+
+				if (getenv("_LIBDISKMGT_INSTALL") == NULL) {
+					shp = sysevent_bind_handle(
+					    event_handler);
+					if (shp != NULL) {
+						subclass_list[0] = EC_SUB_ALL;
+						if (sysevent_subscribe_event(
+						    shp, EC_SVM_CONFIG,
+						    subclass_list, 1) != 0) {
+							*errp = errno;
+						}
+					} else {
+						*errp = errno;
+					}
+				}
+			}
+		}
 
 		if (*errp == 0) {
-		    /* start a thread to monitor the svm config */
-		    sysevent_handle_t *shp;
-		    const char *subclass_list[1];
-
-		    shp = sysevent_bind_handle(event_handler);
-		    if (shp != NULL) {
-			subclass_list[0] = EC_SUB_ALL;
-			if (sysevent_subscribe_event(shp, EC_SVM_CONFIG,
-			    subclass_list, 1) != 0) {
-			    *errp = errno;
-			}
-		    } else {
-			*errp = errno;
-		    }
+			initialized = 1;
 		}
-	    }
-
-	    if (*errp == 0) {
-		initialized = 1;
-	    }
 	}
 	(void) mutex_unlock(&init_lock);
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usr/src/lib/libdiskmgt/common/inuse_zpool.c	Thu Oct 27 09:01:18 2005 -0700
@@ -0,0 +1,124 @@
+/*
+ * 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.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ */
+/*
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#pragma ident	"%Z%%M%	%I%	%E% SMI"
+
+/*
+ * Attempt to dynamically link in the ZFS libzfs.so.1 so that we can
+ * see if there are any ZFS zpools on any of the slices.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <thread.h>
+#include <synch.h>
+#include <dlfcn.h>
+#include <link.h>
+#include <ctype.h>
+
+#include "libdiskmgt.h"
+#include "disks_private.h"
+
+/*
+ * Pointers to libzfs.so functions that we dynamically resolve.
+ */
+static	int	(*zfsdl_zpool_in_use)(int fd, char **desc, char **name);
+
+static mutex_t			init_lock = DEFAULTMUTEX;
+static rwlock_t			zpool_lock = DEFAULTRWLOCK;
+static	int			initialized = 0;
+
+static void	*init_zpool();
+
+int
+inuse_zpool(char *slice, nvlist_t *attrs, int *errp)
+{
+	int		found = 0;
+	char		*desc, *name;
+	int		fd;
+
+	*errp = 0;
+	if (slice == NULL) {
+	    return (found);
+	}
+
+	(void) mutex_lock(&init_lock);
+
+	/*
+	 * Dynamically load libzfs
+	 */
+	if (!initialized) {
+		if (!init_zpool()) {
+			(void) mutex_unlock(&init_lock);
+			return (found);
+		}
+		initialized = 1;
+	}
+	(void) mutex_unlock(&init_lock);
+	(void) rw_rdlock(&zpool_lock);
+	if ((fd = open(slice, O_RDONLY)) > 0) {
+		if (zfsdl_zpool_in_use(fd, &desc, &name)) {
+			libdiskmgt_add_str(attrs, DM_USED_BY,
+				DM_USE_ZPOOL, errp);
+			libdiskmgt_add_str(attrs, DM_USED_NAME,
+				name, errp);
+			found = 1;
+		}
+	}
+	(void) rw_unlock(&zpool_lock);
+
+	return (found);
+}
+
+/*
+ * Try to dynamically link the zfs functions we need.
+ */
+static void*
+init_zpool()
+{
+	void	*lh = NULL;
+
+	if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) {
+		return (lh);
+	}
+	/*
+	 * Instantiate the functions needed to get zpool configuration
+	 * data
+	 */
+	if ((zfsdl_zpool_in_use = (int (*)(int, char **, char **))dlsym(lh,
+	    "zpool_in_use")) == NULL) {
+		(void) dlclose(lh);
+		return (NULL);
+	}
+
+	return (lh);
+}
--- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -35,10 +35,21 @@
 
 #include <libnvpair.h>
 
-/* typedef void  *dm_descriptor_t; */
+/*
+ * Holds all the data regarding the device.
+ * Private to libdiskmgt. Must use dm_xxx functions to set/get data.
+ */
 typedef uint64_t  dm_descriptor_t;
 
 typedef enum {
+	DM_WHO_MKFS = 0,
+	DM_WHO_ZPOOL,
+	DM_WHO_FORMAT,
+	DM_WHO_SWAP,
+	DM_WHO_DUMP
+} dm_who_type_t;
+
+typedef enum {
     DM_DRIVE = 0,
     DM_CONTROLLER,
     DM_MEDIA,
@@ -199,6 +210,7 @@
 #define	DM_USE_VXVM		"vxvm"
 #define	DM_USE_FS		"fs"
 #define	DM_USE_VFSTAB		"vfstab"
+#define	DM_USE_ZPOOL		"zpool"
 
 /* event */
 #define	DM_EV_NAME		"name"
@@ -232,6 +244,13 @@
 void			dm_init_event_queue(void(*callback)(nvlist_t *, int),
 			    int *errp);
 nvlist_t		*dm_get_event(int *errp);
+void			dm_get_slices(char *drive, dm_descriptor_t **slices,
+			    int *errp);
+void			dm_get_slice_stats(char *slice, nvlist_t **dev_stats,
+			    int *errp);
+void			dm_get_usage_string(char *who, char *data, char **msg);
+int			dm_inuse(char *dev_name, char **msg, dm_who_type_t who,
+			    int *errp);
 
 #ifdef __cplusplus
 }
--- a/usr/src/lib/libdiskmgt/common/media.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/media.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -440,27 +440,6 @@
 		    cache_free_descriptor(media[i]);
 		}
 	    }
-#ifdef i386
-	    /* XXX Work around bug 4725434 */
-	    else if (!media[i]->p.disk->removable) {
-		int	j;
-		int	match;
-
-		match = 0;
-		for (j = 0; filter[j] != DM_FILTER_END; j++) {
-		    if (DM_MT_FIXED == filter[j]) {
-			found[pos++] = media[i];
-			match = 1;
-			break;
-		    }
-		}
-
-		if (!match) {
-		    cache_free_descriptor(media[i]);
-		}
-	    }
-#endif
-
 	    (void) close(fd);
 	}
 	found[pos] = NULL;
@@ -506,10 +485,6 @@
 
 	/* The first thing to do is read the media */
 	if (!media_read_info(fd, &minfo)) {
-	    /* XXX Work around bug 4725434 */
-#ifdef i386
-	    if (dp->removable)
-#endif
 	    return (ENODEV);
 	}
 
--- a/usr/src/lib/libdiskmgt/common/partition.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/partition.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -101,6 +101,9 @@
 	struct ipart	iparts[FD_NUMPART];
 	char		pname[MAXPATHLEN];
 	int		conv_flag = 0;
+#if defined(i386) || defined(__amd64)
+	int		len;
+#endif
 
 	if (get_parts(desc->p.disk, iparts, pname, sizeof (pname)) != 0) {
 	    return (libdiskmgt_empty_desc_array(errp));
@@ -114,17 +117,13 @@
 	    return (NULL);
 	}
 
-#ifdef i386
-	{
+#if defined(i386) || defined(__amd64)
 	    /* convert part. name (e.g. c0d0p0) */
-	    int	len;
-
 	    len = strlen(pname);
 	    if (len > 1 && *(pname + (len - 2)) == 'p') {
 		conv_flag = 1;
 		*(pname + (len - 1)) = 0;
 	    }
-	}
 #endif
 
 	/*
@@ -336,8 +335,7 @@
 		int	i;
 		char	mname[MAXPATHLEN];
 		int	conv_flag = 0;
-
-#ifdef i386
+#if defined(i386) || defined(__amd64)
 		/* convert part. name (e.g. c0d0p0) */
 		int	len;
 
@@ -473,15 +471,8 @@
 
 	/* First make sure media is inserted and spun up. */
 	if (!media_read_info(fd, &minfo)) {
-#ifdef i386
-	    /* XXX Work around bug 4725434 */
-	    if (disk->removable) {
-#endif
 	    (void) close(fd);
 	    return (ENODEV);
-#ifdef i386
-	    }
-#endif
 	}
 
 	if (!partition_has_fdisk(disk, fd)) {
@@ -659,7 +650,7 @@
 		}
 
 		if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) +
-		    _PC_NAME_MAX + 1)) == NULL) {
+		    PATH_MAX + 1)) == NULL) {
 		    /* out of memory */
 		    (void) close(fd);
 		    return (-1);
--- a/usr/src/lib/libdiskmgt/common/slice.c	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/common/slice.c	Thu Oct 27 09:01:18 2005 -0700
@@ -20,7 +20,7 @@
  * CDDL HEADER END
  */
 /*
- * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
  */
 
@@ -60,6 +60,7 @@
 } detectors[] = {
 	{inuse_mnt, DM_USE_MOUNT},
 	{inuse_svm, DM_USE_SVM},
+	{inuse_zpool, DM_USE_ZPOOL},
 	{inuse_lu, DM_USE_LU},
 	{inuse_dump, DM_USE_DUMP},
 	{inuse_vxvm, DM_USE_VXVM},
@@ -453,10 +454,6 @@
 
 	/* First make sure media is inserted and spun up. */
 	if (!media_read_info(fd, &minfo)) {
-#ifdef i386
-	    /* XXX Work around bug 4725434 */
-	    if (dp->p.disk->removable)
-#endif
 	    return (ENODEV);
 	}
 
@@ -838,7 +835,7 @@
 		struct dirent	*dentp;
 
 		dentp = (struct dirent *)malloc(sizeof (struct dirent) +
-		    _PC_NAME_MAX + 1);
+		    PATH_MAX + 1);
 		if (dentp != NULL) {
 #ifdef _LP64
 		    while (readdir_r(dirp, dentp, &result) != NULL) {
@@ -1092,7 +1089,7 @@
 
 	error = 0;
 	dentp = (struct dirent *)malloc(sizeof (struct dirent) +
-	    _PC_NAME_MAX + 1);
+	    PATH_MAX + 1);
 	if (dentp != NULL) {
 #ifdef _LP64
 	    while (readdir_r(dirp, dentp, &result) != NULL) {
@@ -1284,7 +1281,7 @@
 		    slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
 
 		    dentp = (struct dirent *)malloc(sizeof (struct dirent) +
-			_PC_NAME_MAX + 1);
+			PATH_MAX + 1);
 		    if (dentp != NULL) {
 #ifdef _LP64
 			while (readdir_r(dirp, dentp, &result) != NULL) {
@@ -1361,7 +1358,7 @@
 		slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
 
 		dentp = (struct dirent *)malloc(sizeof (struct dirent) +
-		    _PC_NAME_MAX + 1);
+		    PATH_MAX + 1);
 		if (dentp != NULL) {
 #ifdef _LP64
 		    while (readdir_r(dirp, dentp, &result) != NULL) {
--- a/usr/src/lib/libdiskmgt/spec/diskmgt.spec	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/lib/libdiskmgt/spec/diskmgt.spec	Thu Oct 27 09:01:18 2005 -0700
@@ -22,7 +22,7 @@
 #
 # CDDL HEADER END
 #
-# ident	"%Z%%M%	%I%	%E% SMI"
+# pragma ident	"%Z%%M%	%I%	%E% SMI"
 #
 # lib/libdiskmgt/spec/diskmgt.spec
 
@@ -109,3 +109,25 @@
 declaration     nvlist_t *dm_get_event(int *errp)
 version         SUNWprivate_1.1
 end
+
+function	dm_get_slices
+include		<libdiskmgt.h>
+declaration	void dm_get_slices(char * drive, dm_descriptor_t **slices, \
+		int *errp)
+version		SUNWprivate_1.1
+end
+
+function	dm_get_slice_stats
+include		<libdiskmgt.h>
+declaration	void dm_get_slice_stats(char *slice, nvlist_t **dev_stats, \
+		int *errp)
+version		SUNWprivate_1.1
+end
+
+function	dm_inuse
+include		<libdiskmgt.h>
+declaration	void dm_inuse(char * dev_name, char **msg, dm_who_type_t who, 
+		int *errp)
+version		SUNWprivate_1.1
+end
+
--- a/usr/src/pkgdefs/etc/exception_list_i386	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/pkgdefs/etc/exception_list_i386	Thu Oct 27 09:01:18 2005 -0700
@@ -104,6 +104,11 @@
 lib/llib-lmacadm.ln		i386
 lib/llib-lmacadm		i386
 #
+# Installed in the proto area for building utilties dependent on
+# it, but is not shipped.
+#
+usr/include/libdiskmgt.h	i386
+#
 # The following files are used by the dhcpmgr.
 #
 usr/share/lib/locale/com/sun/dhcpmgr/bridge/ResourceBundle.properties	i386
--- a/usr/src/pkgdefs/etc/exception_list_sparc	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/pkgdefs/etc/exception_list_sparc	Thu Oct 27 09:01:18 2005 -0700
@@ -93,6 +93,10 @@
 lib/llib-lmacadm.ln		sparc
 lib/llib-lmacadm		sparc
 #
+# Installed in the proto area for building those things
+# that are dependent on it. No delivered as part of a pkg.
+usr/include/libdiskmgt.h	sparc
+#
 # IKE and IPsec support library exceptions.  The IKE support
 # library contains exclusively private interfaces, as does
 # libipsecutil.  My apologies for the glut of header files here.
--- a/usr/src/tools/findunref/exception_list	Thu Oct 27 04:35:13 2005 -0700
+++ b/usr/src/tools/findunref/exception_list	Thu Oct 27 09:01:18 2005 -0700
@@ -192,9 +192,9 @@
 ./lib/libbsm/common/adt_ucred.h
 
 #
-# Ignore files provided by Adaptec as part of their software drop.
+# Ignore libdiskmgt.h. Used for building but not delivered.
 #
-./uts/intel/io/adpu320/chim/hwm/seqse320.h
+./lib/libdiskmgt/common/libdiskmgt.h
 
 #
 # Ignore files originally supplied by ISC (Internet Software Consortium)