xref: /titanic_53/usr/src/cmd/format/checkdev.c (revision 82d71480b3c112fa91f04032225eda15dfe22e17)
13e1bd7a2Ssjelinek /*
23e1bd7a2Ssjelinek  * CDDL HEADER START
33e1bd7a2Ssjelinek  *
43e1bd7a2Ssjelinek  * The contents of this file are subject to the terms of the
53e1bd7a2Ssjelinek  * Common Development and Distribution License, Version 1.0 only
63e1bd7a2Ssjelinek  * (the "License").  You may not use this file except in compliance
73e1bd7a2Ssjelinek  * with the License.
83e1bd7a2Ssjelinek  *
93e1bd7a2Ssjelinek  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
103e1bd7a2Ssjelinek  * or http://www.opensolaris.org/os/licensing.
113e1bd7a2Ssjelinek  * See the License for the specific language governing permissions
123e1bd7a2Ssjelinek  * and limitations under the License.
133e1bd7a2Ssjelinek  *
143e1bd7a2Ssjelinek  * When distributing Covered Code, include this CDDL HEADER in each
153e1bd7a2Ssjelinek  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
163e1bd7a2Ssjelinek  * If applicable, add the following below this CDDL HEADER, with the
173e1bd7a2Ssjelinek  * fields enclosed by brackets "[]" replaced with your own identifying
183e1bd7a2Ssjelinek  * information: Portions Copyright [yyyy] [name of copyright owner]
193e1bd7a2Ssjelinek  *
203e1bd7a2Ssjelinek  * CDDL HEADER END
213e1bd7a2Ssjelinek  */
223e1bd7a2Ssjelinek /*
233e1bd7a2Ssjelinek  * Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
243e1bd7a2Ssjelinek  * Use is subject to license terms.
253e1bd7a2Ssjelinek  */
263e1bd7a2Ssjelinek 
273e1bd7a2Ssjelinek 
283e1bd7a2Ssjelinek #pragma ident	"%Z%%M%	%I%	%E% SMI"
293e1bd7a2Ssjelinek 
303e1bd7a2Ssjelinek /*
313e1bd7a2Ssjelinek  * This file contains miscellaneous device validation routines.
323e1bd7a2Ssjelinek  */
333e1bd7a2Ssjelinek 
343e1bd7a2Ssjelinek #include "global.h"
353e1bd7a2Ssjelinek #include <sys/mnttab.h>
363e1bd7a2Ssjelinek #include <sys/mntent.h>
373e1bd7a2Ssjelinek #include <sys/autoconf.h>
383e1bd7a2Ssjelinek 
393e1bd7a2Ssjelinek #include <signal.h>
403e1bd7a2Ssjelinek #include <malloc.h>
413e1bd7a2Ssjelinek #include <unistd.h>
423e1bd7a2Ssjelinek #include <string.h>
433e1bd7a2Ssjelinek #include <errno.h>
443e1bd7a2Ssjelinek #include <fcntl.h>
453e1bd7a2Ssjelinek #include <sys/ioctl.h>
463e1bd7a2Ssjelinek #include <sys/fcntl.h>
473e1bd7a2Ssjelinek #include <sys/stat.h>
483e1bd7a2Ssjelinek #include <sys/swap.h>
493e1bd7a2Ssjelinek #include <sys/sysmacros.h>
503e1bd7a2Ssjelinek #include <ctype.h>
513e1bd7a2Ssjelinek #include <libdiskmgt.h>
523e1bd7a2Ssjelinek #include <libnvpair.h>
533e1bd7a2Ssjelinek #include "misc.h"
543e1bd7a2Ssjelinek #include "checkdev.h"
553e1bd7a2Ssjelinek 
563e1bd7a2Ssjelinek /* Function prototypes */
573e1bd7a2Ssjelinek #ifdef	__STDC__
583e1bd7a2Ssjelinek 
593e1bd7a2Ssjelinek static struct 	swaptable *getswapentries(void);
603e1bd7a2Ssjelinek static void 	freeswapentries(struct swaptable *);
613e1bd7a2Ssjelinek static int	getpartition(char *pathname);
623e1bd7a2Ssjelinek static int 	checkpartitions(int bm_mounted);
633e1bd7a2Ssjelinek 
643e1bd7a2Ssjelinek #else	/* __STDC__ */
653e1bd7a2Ssjelinek 
663e1bd7a2Ssjelinek static struct swaptable *getswapentries();
673e1bd7a2Ssjelinek static void freeswapentries();
683e1bd7a2Ssjelinek static int	getpartition();
693e1bd7a2Ssjelinek static int 	checkpartitions();
703e1bd7a2Ssjelinek 
713e1bd7a2Ssjelinek #endif	/* __STDC__ */
723e1bd7a2Ssjelinek 
733e1bd7a2Ssjelinek extern char	*getfullname();
743e1bd7a2Ssjelinek 
753e1bd7a2Ssjelinek static struct swaptable *
763e1bd7a2Ssjelinek getswapentries(void)
773e1bd7a2Ssjelinek {
783e1bd7a2Ssjelinek 	register struct swaptable *st;
793e1bd7a2Ssjelinek 	register struct swapent *swapent;
803e1bd7a2Ssjelinek 	int	i, num;
813e1bd7a2Ssjelinek 	char	fullpathname[MAXPATHLEN];
823e1bd7a2Ssjelinek 
833e1bd7a2Ssjelinek 	/*
843e1bd7a2Ssjelinek 	 * get the number of swap entries
853e1bd7a2Ssjelinek 	 */
863e1bd7a2Ssjelinek 	if ((num = swapctl(SC_GETNSWP, (void *)NULL)) == -1) {
873e1bd7a2Ssjelinek 		err_print("swapctl error ");
883e1bd7a2Ssjelinek 		fullabort();
893e1bd7a2Ssjelinek 	}
903e1bd7a2Ssjelinek 	if (num == 0)
913e1bd7a2Ssjelinek 		return (NULL);
923e1bd7a2Ssjelinek 	if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int)))
933e1bd7a2Ssjelinek 			== NULL) {
943e1bd7a2Ssjelinek 		err_print("getswapentries: malloc  failed.\n");
953e1bd7a2Ssjelinek 		fullabort();
963e1bd7a2Ssjelinek 	}
973e1bd7a2Ssjelinek 	swapent = st->swt_ent;
983e1bd7a2Ssjelinek 	for (i = 0; i < num; i++, swapent++) {
993e1bd7a2Ssjelinek 		if ((swapent->ste_path = malloc(MAXPATHLEN)) == NULL) {
1003e1bd7a2Ssjelinek 			err_print("getswapentries: malloc  failed.\n");
1013e1bd7a2Ssjelinek 			fullabort();
1023e1bd7a2Ssjelinek 		}
1033e1bd7a2Ssjelinek 	}
1043e1bd7a2Ssjelinek 	st->swt_n = num;
1053e1bd7a2Ssjelinek 	if ((num = swapctl(SC_LIST, (void *)st)) == -1) {
1063e1bd7a2Ssjelinek 		err_print("swapctl error ");
1073e1bd7a2Ssjelinek 		fullabort();
1083e1bd7a2Ssjelinek 	}
1093e1bd7a2Ssjelinek 	swapent = st->swt_ent;
1103e1bd7a2Ssjelinek 	for (i = 0; i < num; i++, swapent++) {
1113e1bd7a2Ssjelinek 		if (*swapent->ste_path != '/') {
1123e1bd7a2Ssjelinek 			(void) snprintf(fullpathname, sizeof (fullpathname),
1133e1bd7a2Ssjelinek 			    "/dev/%s", swapent->ste_path);
1143e1bd7a2Ssjelinek 			(void) strcpy(swapent->ste_path, fullpathname);
1153e1bd7a2Ssjelinek 		}
1163e1bd7a2Ssjelinek 	}
1173e1bd7a2Ssjelinek 	return (st);
1183e1bd7a2Ssjelinek }
1193e1bd7a2Ssjelinek 
1203e1bd7a2Ssjelinek static void
1213e1bd7a2Ssjelinek freeswapentries(st)
1223e1bd7a2Ssjelinek struct swaptable *st;
1233e1bd7a2Ssjelinek {
1243e1bd7a2Ssjelinek 	register struct swapent *swapent;
1253e1bd7a2Ssjelinek 	int i;
1263e1bd7a2Ssjelinek 
1273e1bd7a2Ssjelinek 	swapent = st->swt_ent;
1283e1bd7a2Ssjelinek 	for (i = 0; i < st->swt_n; i++, swapent++)
1293e1bd7a2Ssjelinek 		free(swapent->ste_path);
1303e1bd7a2Ssjelinek 	free(st);
1313e1bd7a2Ssjelinek 
1323e1bd7a2Ssjelinek }
1333e1bd7a2Ssjelinek 
1343e1bd7a2Ssjelinek /*
1353e1bd7a2Ssjelinek  *  function getpartition:
1363e1bd7a2Ssjelinek  */
1373e1bd7a2Ssjelinek static int
1383e1bd7a2Ssjelinek getpartition(pathname)
1393e1bd7a2Ssjelinek char *pathname;
1403e1bd7a2Ssjelinek {
1413e1bd7a2Ssjelinek 	int		mfd;
1423e1bd7a2Ssjelinek 	struct dk_cinfo dkinfo;
1433e1bd7a2Ssjelinek 	struct stat	stbuf;
1443e1bd7a2Ssjelinek 	char		raw_device[MAXPATHLEN];
1453e1bd7a2Ssjelinek 	int		found = -1;
1463e1bd7a2Ssjelinek 
1473e1bd7a2Ssjelinek 	/*
1483e1bd7a2Ssjelinek 	 * Map the block device name to the raw device name.
1493e1bd7a2Ssjelinek 	 * If it doesn't appear to be a device name, skip it.
1503e1bd7a2Ssjelinek 	 */
1513e1bd7a2Ssjelinek 	if (match_substr(pathname, "/dev/") == 0)
1523e1bd7a2Ssjelinek 		return (found);
1533e1bd7a2Ssjelinek 	(void) strcpy(raw_device, "/dev/r");
1543e1bd7a2Ssjelinek 	(void) strcat(raw_device, pathname + strlen("/dev/"));
1553e1bd7a2Ssjelinek 	/*
1563e1bd7a2Ssjelinek 	 * Determine if this appears to be a disk device.
1573e1bd7a2Ssjelinek 	 * First attempt to open the device.  If if fails, skip it.
1583e1bd7a2Ssjelinek 	 */
1593e1bd7a2Ssjelinek 	if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) {
1603e1bd7a2Ssjelinek 		return (found);
1613e1bd7a2Ssjelinek 	}
1623e1bd7a2Ssjelinek 	/*
1633e1bd7a2Ssjelinek 	 * Must be a character device
1643e1bd7a2Ssjelinek 	 */
1653e1bd7a2Ssjelinek 	if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) {
1663e1bd7a2Ssjelinek 		(void) close(mfd);
1673e1bd7a2Ssjelinek 		return (found);
1683e1bd7a2Ssjelinek 	}
1693e1bd7a2Ssjelinek 	/*
1703e1bd7a2Ssjelinek 	 * Attempt to read the configuration info on the disk.
1713e1bd7a2Ssjelinek 	 */
1723e1bd7a2Ssjelinek 	if (ioctl(mfd, DKIOCINFO, &dkinfo) < 0) {
1733e1bd7a2Ssjelinek 		(void) close(mfd);
1743e1bd7a2Ssjelinek 		return (found);
1753e1bd7a2Ssjelinek 	}
1763e1bd7a2Ssjelinek 	/*
1773e1bd7a2Ssjelinek 	 * Finished with the opened device
1783e1bd7a2Ssjelinek 	 */
1793e1bd7a2Ssjelinek 	(void) close(mfd);
1803e1bd7a2Ssjelinek 
1813e1bd7a2Ssjelinek 	/*
1823e1bd7a2Ssjelinek 	 * If it's not the disk we're interested in, it doesn't apply.
1833e1bd7a2Ssjelinek 	 */
1843e1bd7a2Ssjelinek 	if (cur_disk->disk_dkinfo.dki_ctype != dkinfo.dki_ctype ||
1853e1bd7a2Ssjelinek 		cur_disk->disk_dkinfo.dki_cnum != dkinfo.dki_cnum ||
1863e1bd7a2Ssjelinek 		cur_disk->disk_dkinfo.dki_unit != dkinfo.dki_unit ||
1873e1bd7a2Ssjelinek 		strcmp(cur_disk->disk_dkinfo.dki_dname,
1883e1bd7a2Ssjelinek 				dkinfo.dki_dname) != 0) {
1893e1bd7a2Ssjelinek 		return (found);
1903e1bd7a2Ssjelinek 	}
1913e1bd7a2Ssjelinek 
1923e1bd7a2Ssjelinek 	/*
1933e1bd7a2Ssjelinek 	 *  Extract the partition that is mounted.
1943e1bd7a2Ssjelinek 	 */
1953e1bd7a2Ssjelinek 	return (PARTITION(stbuf.st_rdev));
1963e1bd7a2Ssjelinek }
1973e1bd7a2Ssjelinek 
1983e1bd7a2Ssjelinek /*
1993e1bd7a2Ssjelinek  * This Routine checks to see if there are partitions used for swapping overlaps
2003e1bd7a2Ssjelinek  * a given portion of a disk. If the start parameter is < 0, it means
2013e1bd7a2Ssjelinek  * that the entire disk should be checked
2023e1bd7a2Ssjelinek  */
2033e1bd7a2Ssjelinek int
2043e1bd7a2Ssjelinek checkswap(start, end)
2053e1bd7a2Ssjelinek 	diskaddr_t start, end;
2063e1bd7a2Ssjelinek {
2073e1bd7a2Ssjelinek 	struct swaptable *st;
2083e1bd7a2Ssjelinek 	struct swapent *swapent;
2093e1bd7a2Ssjelinek 	int		i;
2103e1bd7a2Ssjelinek 	int		found = 0;
2113e1bd7a2Ssjelinek 	struct dk_map32	*map;
2123e1bd7a2Ssjelinek 	int		part;
2133e1bd7a2Ssjelinek 
2143e1bd7a2Ssjelinek 	/*
2153e1bd7a2Ssjelinek 	 * If we are only checking part of the disk, the disk must
2163e1bd7a2Ssjelinek 	 * have a partition map to check against.  If it doesn't,
2173e1bd7a2Ssjelinek 	 * we hope for the best.
2183e1bd7a2Ssjelinek 	 */
2193e1bd7a2Ssjelinek 	if (cur_parts == NULL)
2203e1bd7a2Ssjelinek 		return (0);
2213e1bd7a2Ssjelinek 
2223e1bd7a2Ssjelinek 	/*
2233e1bd7a2Ssjelinek 	 * check for swap entries
2243e1bd7a2Ssjelinek 	 */
2253e1bd7a2Ssjelinek 	st = getswapentries();
2263e1bd7a2Ssjelinek 	/*
2273e1bd7a2Ssjelinek 	 * if there are no swap entries return.
2283e1bd7a2Ssjelinek 	 */
2293e1bd7a2Ssjelinek 	if (st == (struct swaptable *)NULL)
2303e1bd7a2Ssjelinek 		return (0);
2313e1bd7a2Ssjelinek 	swapent = st->swt_ent;
2323e1bd7a2Ssjelinek 	for (i = 0; i < st->swt_n; i++, swapent++) {
2333e1bd7a2Ssjelinek 		if ((part = getpartition(swapent->ste_path)) != -1) {
2343e1bd7a2Ssjelinek 			if (start == UINT_MAX64) {
2353e1bd7a2Ssjelinek 				found = -1;
2363e1bd7a2Ssjelinek 				break;
2373e1bd7a2Ssjelinek 			}
2383e1bd7a2Ssjelinek 			map = &cur_parts->pinfo_map[part];
2393e1bd7a2Ssjelinek 			if ((start >= (int)(map->dkl_cylno * spc() +
2403e1bd7a2Ssjelinek 				map->dkl_nblk)) || (end < (int)(map->dkl_cylno
2413e1bd7a2Ssjelinek 							* spc()))) {
2423e1bd7a2Ssjelinek 					continue;
2433e1bd7a2Ssjelinek 			}
2443e1bd7a2Ssjelinek 			found = -1;
2453e1bd7a2Ssjelinek 			break;
2463e1bd7a2Ssjelinek 		};
2473e1bd7a2Ssjelinek 	}
2483e1bd7a2Ssjelinek 	freeswapentries(st);
2493e1bd7a2Ssjelinek 	/*
2503e1bd7a2Ssjelinek 	 * If we found trouble and we're running from a command file,
2513e1bd7a2Ssjelinek 	 * quit before doing something we really regret.
2523e1bd7a2Ssjelinek 	 */
2533e1bd7a2Ssjelinek 
2543e1bd7a2Ssjelinek 	if (found && option_f) {
2553e1bd7a2Ssjelinek 		err_print(
2563e1bd7a2Ssjelinek "Operation on disks being used for swapping must be interactive.\n");
2573e1bd7a2Ssjelinek 		cmdabort(SIGINT);
2583e1bd7a2Ssjelinek 	}
2593e1bd7a2Ssjelinek 
2603e1bd7a2Ssjelinek 	return (found);
2613e1bd7a2Ssjelinek 
2623e1bd7a2Ssjelinek 
2633e1bd7a2Ssjelinek }
2643e1bd7a2Ssjelinek /*
2653e1bd7a2Ssjelinek  * Determines if there are partitions that are a part of an SVM, VxVM, zpool
2663e1bd7a2Ssjelinek  * volume or a live upgrade device,  overlapping a given portion of a disk.
2673e1bd7a2Ssjelinek  * Mounts and swap devices are checked in legacy format code.
2683e1bd7a2Ssjelinek  */
2693e1bd7a2Ssjelinek int
2703e1bd7a2Ssjelinek checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, int print,
2713e1bd7a2Ssjelinek 	int check_label)
2723e1bd7a2Ssjelinek {
2733e1bd7a2Ssjelinek 
2743e1bd7a2Ssjelinek 	int 		error;
2753e1bd7a2Ssjelinek 	int 		found = 0;
2763e1bd7a2Ssjelinek 	int		check = 0;
2773e1bd7a2Ssjelinek 	int 		i;
2783e1bd7a2Ssjelinek 	int		bm_inuse = 0;
2793e1bd7a2Ssjelinek 	int		part = 0;
2803e1bd7a2Ssjelinek 	uint64_t	slice_start, slice_size;
2813e1bd7a2Ssjelinek 	dm_descriptor_t	*slices = NULL;
2823e1bd7a2Ssjelinek 	nvlist_t	*attrs = NULL;
2833e1bd7a2Ssjelinek 	char		*usage;
2843e1bd7a2Ssjelinek 	char		*name;
2853e1bd7a2Ssjelinek 
2863e1bd7a2Ssjelinek 	/*
287*82d71480Ssjelinek 	 * If the user does not want to do in use checking, return immediately.
288*82d71480Ssjelinek 	 * Normally, this is handled in libdiskmgt. For format, there is more
289*82d71480Ssjelinek 	 * processing required, so we want to bypass the in use checking
290*82d71480Ssjelinek 	 * here.
291*82d71480Ssjelinek 	 */
292*82d71480Ssjelinek 
293*82d71480Ssjelinek 	if (NOINUSE_SET)
294*82d71480Ssjelinek 		return (0);
295*82d71480Ssjelinek 
296*82d71480Ssjelinek 	/*
2973e1bd7a2Ssjelinek 	 * For format, we get basic 'in use' details from libdiskmgt. After
2983e1bd7a2Ssjelinek 	 * that we must do the appropriate checking to see if the 'in use'
2993e1bd7a2Ssjelinek 	 * details require a bit of additional work.
3003e1bd7a2Ssjelinek 	 */
3013e1bd7a2Ssjelinek 
3023e1bd7a2Ssjelinek 	dm_get_slices(cur_disk_path, &slices, &error);
3033e1bd7a2Ssjelinek 	if (error) {
3043e1bd7a2Ssjelinek 		err_print("Error occurred with device in use checking: %s\n",
3053e1bd7a2Ssjelinek 		    strerror(error));
3063e1bd7a2Ssjelinek 		return (found);
3073e1bd7a2Ssjelinek 	}
3083e1bd7a2Ssjelinek 	if (slices == NULL)
3093e1bd7a2Ssjelinek 		return (found);
3103e1bd7a2Ssjelinek 
3113e1bd7a2Ssjelinek 	for (i = 0; slices[i] != NULL; i++) {
3123e1bd7a2Ssjelinek 		/*
3133e1bd7a2Ssjelinek 		 * If we are checking the whole disk
3143e1bd7a2Ssjelinek 		 * then any and all in use data is
3153e1bd7a2Ssjelinek 		 * relevant.
3163e1bd7a2Ssjelinek 		 */
3173e1bd7a2Ssjelinek 		if (start == UINT_MAX64) {
3183e1bd7a2Ssjelinek 			name = dm_get_name(slices[i], &error);
3193e1bd7a2Ssjelinek 			if (error != 0 || !name) {
3203e1bd7a2Ssjelinek 				err_print("Error occurred with device "
3213e1bd7a2Ssjelinek 				    "in use checking: %s\n",
3223e1bd7a2Ssjelinek 				    strerror(error));
3233e1bd7a2Ssjelinek 				continue;
3243e1bd7a2Ssjelinek 			}
3253e1bd7a2Ssjelinek 			if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) ||
3263e1bd7a2Ssjelinek 			    error) {
3273e1bd7a2Ssjelinek 				if (error != 0) {
3283e1bd7a2Ssjelinek 					dm_free_name(name);
3293e1bd7a2Ssjelinek 					name = NULL;
3303e1bd7a2Ssjelinek 					err_print("Error occurred with device "
3313e1bd7a2Ssjelinek 					    "in use checking: %s\n",
3323e1bd7a2Ssjelinek 					    strerror(error));
3333e1bd7a2Ssjelinek 					continue;
3343e1bd7a2Ssjelinek 				}
3353e1bd7a2Ssjelinek 				dm_free_name(name);
3363e1bd7a2Ssjelinek 				name = NULL;
3373e1bd7a2Ssjelinek 				/*
3383e1bd7a2Ssjelinek 				 * If this is a dump device, then it is
3393e1bd7a2Ssjelinek 				 * a failure. You cannot format a slice
3403e1bd7a2Ssjelinek 				 * that is a dedicated dump device.
3413e1bd7a2Ssjelinek 				 */
3423e1bd7a2Ssjelinek 
3433e1bd7a2Ssjelinek 				if (strstr(usage, DM_USE_DUMP)) {
3443e1bd7a2Ssjelinek 					if (print) {
3453e1bd7a2Ssjelinek 						err_print(usage);
3463e1bd7a2Ssjelinek 						free(usage);
3473e1bd7a2Ssjelinek 					}
3483e1bd7a2Ssjelinek 					dm_free_descriptors(slices);
3493e1bd7a2Ssjelinek 					return (1);
3503e1bd7a2Ssjelinek 				}
3513e1bd7a2Ssjelinek 				/*
3523e1bd7a2Ssjelinek 				 * We really found a device that is in use.
3533e1bd7a2Ssjelinek 				 * Set 'found' for the return value, and set
3543e1bd7a2Ssjelinek 				 * 'check' to indicate below that we must
3553e1bd7a2Ssjelinek 				 * get the partition number to set bm_inuse
3563e1bd7a2Ssjelinek 				 * in the event we are trying to label this
3573e1bd7a2Ssjelinek 				 * device. check_label is set when we are
3583e1bd7a2Ssjelinek 				 * checking modifications for in use slices
3593e1bd7a2Ssjelinek 				 * on the device.
3603e1bd7a2Ssjelinek 				 */
3613e1bd7a2Ssjelinek 				found ++;
3623e1bd7a2Ssjelinek 				check = 1;
3633e1bd7a2Ssjelinek 				if (print) {
3643e1bd7a2Ssjelinek 					err_print(usage);
3653e1bd7a2Ssjelinek 					free(usage);
3663e1bd7a2Ssjelinek 				}
3673e1bd7a2Ssjelinek 			}
3683e1bd7a2Ssjelinek 		} else {
3693e1bd7a2Ssjelinek 			/*
3703e1bd7a2Ssjelinek 			 * Before getting the in use data, verify that the
3713e1bd7a2Ssjelinek 			 * current slice is within the range we are checking.
3723e1bd7a2Ssjelinek 			 */
3733e1bd7a2Ssjelinek 			attrs = dm_get_attributes(slices[i], &error);
3743e1bd7a2Ssjelinek 			if (error) {
3753e1bd7a2Ssjelinek 				err_print("Error occurred with device in use "
3763e1bd7a2Ssjelinek 				    "checking: %s\n", strerror(error));
3773e1bd7a2Ssjelinek 				continue;
3783e1bd7a2Ssjelinek 			}
3793e1bd7a2Ssjelinek 			if (attrs == NULL) {
3803e1bd7a2Ssjelinek 				continue;
3813e1bd7a2Ssjelinek 			}
3823e1bd7a2Ssjelinek 
3833e1bd7a2Ssjelinek 			(void) nvlist_lookup_uint64(attrs, DM_START,
3843e1bd7a2Ssjelinek 			    &slice_start);
3853e1bd7a2Ssjelinek 			(void) nvlist_lookup_uint64(attrs, DM_SIZE,
3863e1bd7a2Ssjelinek 			    &slice_size);
3873e1bd7a2Ssjelinek 			if (start >= (slice_start + slice_size) ||
3883e1bd7a2Ssjelinek 			    (end < slice_start)) {
3893e1bd7a2Ssjelinek 				nvlist_free(attrs);
3903e1bd7a2Ssjelinek 				attrs = NULL;
3913e1bd7a2Ssjelinek 				continue;
3923e1bd7a2Ssjelinek 			}
3933e1bd7a2Ssjelinek 			name = dm_get_name(slices[i], &error);
3943e1bd7a2Ssjelinek 			if (error != 0 || !name) {
3953e1bd7a2Ssjelinek 				err_print("Error occurred with device "
3963e1bd7a2Ssjelinek 				    "in use checking: %s\n",
3973e1bd7a2Ssjelinek 				    strerror(error));
3983e1bd7a2Ssjelinek 				nvlist_free(attrs);
3993e1bd7a2Ssjelinek 				attrs = NULL;
4003e1bd7a2Ssjelinek 				continue;
4013e1bd7a2Ssjelinek 			}
4023e1bd7a2Ssjelinek 			if (dm_inuse(name, &usage,
4033e1bd7a2Ssjelinek 			    DM_WHO_FORMAT, &error) || error) {
4043e1bd7a2Ssjelinek 				if (error != 0) {
4053e1bd7a2Ssjelinek 					dm_free_name(name);
4063e1bd7a2Ssjelinek 					name = NULL;
4073e1bd7a2Ssjelinek 					err_print("Error occurred with device "
4083e1bd7a2Ssjelinek 					    "in use checking: %s\n",
4093e1bd7a2Ssjelinek 					    strerror(error));
4103e1bd7a2Ssjelinek 					nvlist_free(attrs);
4113e1bd7a2Ssjelinek 					attrs = NULL;
4123e1bd7a2Ssjelinek 					continue;
4133e1bd7a2Ssjelinek 				}
4143e1bd7a2Ssjelinek 				dm_free_name(name);
4153e1bd7a2Ssjelinek 				name = NULL;
4163e1bd7a2Ssjelinek 				/*
4173e1bd7a2Ssjelinek 				 * If this is a dump device, then it is
4183e1bd7a2Ssjelinek 				 * a failure. You cannot format a slice
4193e1bd7a2Ssjelinek 				 * that is a dedicated dump device.
4203e1bd7a2Ssjelinek 				 */
4213e1bd7a2Ssjelinek 				if (strstr(usage, DM_USE_DUMP)) {
4223e1bd7a2Ssjelinek 					if (print) {
4233e1bd7a2Ssjelinek 						err_print(usage);
4243e1bd7a2Ssjelinek 						free(usage);
4253e1bd7a2Ssjelinek 					}
4263e1bd7a2Ssjelinek 					dm_free_descriptors(slices);
4273e1bd7a2Ssjelinek 					nvlist_free(attrs);
4283e1bd7a2Ssjelinek 					return (1);
4293e1bd7a2Ssjelinek 				}
4303e1bd7a2Ssjelinek 				/*
4313e1bd7a2Ssjelinek 				 * We really found a device that is in use.
4323e1bd7a2Ssjelinek 				 * Set 'found' for the return value, and set
4333e1bd7a2Ssjelinek 				 * 'check' to indicate below that we must
4343e1bd7a2Ssjelinek 				 * get the partition number to set bm_inuse
4353e1bd7a2Ssjelinek 				 * in the event we are trying to label this
4363e1bd7a2Ssjelinek 				 * device. check_label is set when we are
4373e1bd7a2Ssjelinek 				 * checking modifications for in use slices
4383e1bd7a2Ssjelinek 				 * on the device.
4393e1bd7a2Ssjelinek 				 */
4403e1bd7a2Ssjelinek 				found ++;
4413e1bd7a2Ssjelinek 				check = 1;
4423e1bd7a2Ssjelinek 				if (print) {
4433e1bd7a2Ssjelinek 					err_print(usage);
4443e1bd7a2Ssjelinek 					free(usage);
4453e1bd7a2Ssjelinek 				}
4463e1bd7a2Ssjelinek 			}
4473e1bd7a2Ssjelinek 		}
4483e1bd7a2Ssjelinek 		/*
4493e1bd7a2Ssjelinek 		 * If check is set it means we found a slice(the current slice)
4503e1bd7a2Ssjelinek 		 * on this device in use in some way.  We potentially want
4513e1bd7a2Ssjelinek 		 * to check this slice when labeling is
4523e1bd7a2Ssjelinek 		 * requested. We set bm_inuse with this partition value
4533e1bd7a2Ssjelinek 		 * for use later if check_label was set when called.
4543e1bd7a2Ssjelinek 		 */
4553e1bd7a2Ssjelinek 		if (check) {
4563e1bd7a2Ssjelinek 			name = dm_get_name(slices[i], &error);
4573e1bd7a2Ssjelinek 			if (error != 0 || !name) {
4583e1bd7a2Ssjelinek 				err_print("Error occurred with device "
4593e1bd7a2Ssjelinek 				    "in use checking: %s\n",
4603e1bd7a2Ssjelinek 				    strerror(error));
4613e1bd7a2Ssjelinek 				nvlist_free(attrs);
4623e1bd7a2Ssjelinek 				attrs = NULL;
4633e1bd7a2Ssjelinek 				continue;
4643e1bd7a2Ssjelinek 			}
4653e1bd7a2Ssjelinek 			part = getpartition(name);
4663e1bd7a2Ssjelinek 			dm_free_name(name);
4673e1bd7a2Ssjelinek 			name = NULL;
4683e1bd7a2Ssjelinek 			if (part != -1) {
4693e1bd7a2Ssjelinek 				bm_inuse |= 1 << part;
4703e1bd7a2Ssjelinek 			}
4713e1bd7a2Ssjelinek 			check = 0;
4723e1bd7a2Ssjelinek 		}
4733e1bd7a2Ssjelinek 		/*
4743e1bd7a2Ssjelinek 		 * If we have attributes then we have successfully
4753e1bd7a2Ssjelinek 		 * found the slice we were looking for and we also
4763e1bd7a2Ssjelinek 		 * know this means we are not searching the whole
4773e1bd7a2Ssjelinek 		 * disk so break out of the loop
4783e1bd7a2Ssjelinek 		 * now.
4793e1bd7a2Ssjelinek 		 */
4803e1bd7a2Ssjelinek 		if (attrs) {
4813e1bd7a2Ssjelinek 			nvlist_free(attrs);
4823e1bd7a2Ssjelinek 			break;
4833e1bd7a2Ssjelinek 		}
4843e1bd7a2Ssjelinek 	}
4853e1bd7a2Ssjelinek 
4863e1bd7a2Ssjelinek 	if (slices) {
4873e1bd7a2Ssjelinek 		dm_free_descriptors(slices);
4883e1bd7a2Ssjelinek 	}
4893e1bd7a2Ssjelinek 
4903e1bd7a2Ssjelinek 	/*
4913e1bd7a2Ssjelinek 	 * The user is trying to label the disk. We have to do special
4923e1bd7a2Ssjelinek 	 * checking here to ensure they are not trying to modify a slice
4933e1bd7a2Ssjelinek 	 * that is in use in an incompatible way.
4943e1bd7a2Ssjelinek 	 */
4953e1bd7a2Ssjelinek 	if (check_label && bm_inuse) {
4963e1bd7a2Ssjelinek 		/*
4973e1bd7a2Ssjelinek 		 * !0 indicates that we found a
4983e1bd7a2Ssjelinek 		 * problem. In this case, we have overloaded
4993e1bd7a2Ssjelinek 		 * the use of checkpartitions to work for
5003e1bd7a2Ssjelinek 		 * in use devices. bm_inuse is representative
5013e1bd7a2Ssjelinek 		 * of the slice that is in use, not that
5023e1bd7a2Ssjelinek 		 * is mounted as is in the case of the normal
5033e1bd7a2Ssjelinek 		 * use of checkpartitions.
5043e1bd7a2Ssjelinek 		 *
5053e1bd7a2Ssjelinek 		 * The call to checkpartitions will return !0 if
5063e1bd7a2Ssjelinek 		 * we are trying to shrink a device that we have found
5073e1bd7a2Ssjelinek 		 * to be in use above.
5083e1bd7a2Ssjelinek 		 */
5093e1bd7a2Ssjelinek 		return (checkpartitions(bm_inuse));
5103e1bd7a2Ssjelinek 	}
5113e1bd7a2Ssjelinek 
5123e1bd7a2Ssjelinek 	return (found);
5133e1bd7a2Ssjelinek }
5143e1bd7a2Ssjelinek /*
5153e1bd7a2Ssjelinek  * This routine checks to see if there are mounted partitions overlapping
5163e1bd7a2Ssjelinek  * a given portion of a disk.  If the start parameter is < 0, it means
5173e1bd7a2Ssjelinek  * that the entire disk should be checked.
5183e1bd7a2Ssjelinek  */
5193e1bd7a2Ssjelinek int
5203e1bd7a2Ssjelinek checkmount(start, end)
5213e1bd7a2Ssjelinek 	diskaddr_t	start, end;
5223e1bd7a2Ssjelinek {
5233e1bd7a2Ssjelinek 	FILE		*fp;
5243e1bd7a2Ssjelinek 	int		found = 0;
5253e1bd7a2Ssjelinek 	struct dk_map32	*map;
5263e1bd7a2Ssjelinek 	int		part;
5273e1bd7a2Ssjelinek 	struct mnttab	mnt_record;
5283e1bd7a2Ssjelinek 	struct mnttab	*mp = &mnt_record;
5293e1bd7a2Ssjelinek 
5303e1bd7a2Ssjelinek 	/*
5313e1bd7a2Ssjelinek 	 * If we are only checking part of the disk, the disk must
5323e1bd7a2Ssjelinek 	 * have a partition map to check against.  If it doesn't,
5333e1bd7a2Ssjelinek 	 * we hope for the best.
5343e1bd7a2Ssjelinek 	 */
5353e1bd7a2Ssjelinek 	if (cur_parts == NULL)
5363e1bd7a2Ssjelinek 		return (0);
5373e1bd7a2Ssjelinek 
5383e1bd7a2Ssjelinek 	/*
5393e1bd7a2Ssjelinek 	 * Lock out interrupts because of the mntent protocol.
5403e1bd7a2Ssjelinek 	 */
5413e1bd7a2Ssjelinek 	enter_critical();
5423e1bd7a2Ssjelinek 	/*
5433e1bd7a2Ssjelinek 	 * Open the mount table.
5443e1bd7a2Ssjelinek 	 */
5453e1bd7a2Ssjelinek 	fp = fopen(MNTTAB, "r");
5463e1bd7a2Ssjelinek 	if (fp == NULL) {
5473e1bd7a2Ssjelinek 		err_print("Unable to open mount table.\n");
5483e1bd7a2Ssjelinek 		fullabort();
5493e1bd7a2Ssjelinek 	}
5503e1bd7a2Ssjelinek 	/*
5513e1bd7a2Ssjelinek 	 * Loop through the mount table until we run out of entries.
5523e1bd7a2Ssjelinek 	 */
5533e1bd7a2Ssjelinek 	while ((getmntent(fp, mp)) != -1) {
5543e1bd7a2Ssjelinek 
5553e1bd7a2Ssjelinek 		if ((part = getpartition(mp->mnt_special)) == -1)
5563e1bd7a2Ssjelinek 			continue;
5573e1bd7a2Ssjelinek 
5583e1bd7a2Ssjelinek 		/*
5593e1bd7a2Ssjelinek 		 * It's a mount on the disk we're checking.  If we are
5603e1bd7a2Ssjelinek 		 * checking whole disk, then we found trouble.  We can
5613e1bd7a2Ssjelinek 		 * quit searching.
5623e1bd7a2Ssjelinek 		 */
5633e1bd7a2Ssjelinek 		if (start == UINT_MAX64) {
5643e1bd7a2Ssjelinek 			found = -1;
5653e1bd7a2Ssjelinek 			break;
5663e1bd7a2Ssjelinek 		}
5673e1bd7a2Ssjelinek 
5683e1bd7a2Ssjelinek 		/*
5693e1bd7a2Ssjelinek 		 * If the partition overlaps the zone we're checking,
5703e1bd7a2Ssjelinek 		 * then we found trouble.  We can quit searching.
5713e1bd7a2Ssjelinek 		 */
5723e1bd7a2Ssjelinek 		map = &cur_parts->pinfo_map[part];
5733e1bd7a2Ssjelinek 		if ((start >= (int)(map->dkl_cylno * spc() + map->dkl_nblk)) ||
5743e1bd7a2Ssjelinek 			(end < (int)(map->dkl_cylno * spc()))) {
5753e1bd7a2Ssjelinek 			continue;
5763e1bd7a2Ssjelinek 		}
5773e1bd7a2Ssjelinek 		found = -1;
5783e1bd7a2Ssjelinek 		break;
5793e1bd7a2Ssjelinek 	}
5803e1bd7a2Ssjelinek 	/*
5813e1bd7a2Ssjelinek 	 * Close down the mount table.
5823e1bd7a2Ssjelinek 	 */
5833e1bd7a2Ssjelinek 	(void) fclose(fp);
5843e1bd7a2Ssjelinek 	exit_critical();
5853e1bd7a2Ssjelinek 
5863e1bd7a2Ssjelinek 	/*
5873e1bd7a2Ssjelinek 	 * If we found trouble and we're running from a command file,
5883e1bd7a2Ssjelinek 	 * quit before doing something we really regret.
5893e1bd7a2Ssjelinek 	 */
5903e1bd7a2Ssjelinek 
5913e1bd7a2Ssjelinek 	if (found && option_f) {
5923e1bd7a2Ssjelinek 		err_print("Operation on mounted disks must be interactive.\n");
5933e1bd7a2Ssjelinek 		cmdabort(SIGINT);
5943e1bd7a2Ssjelinek 	}
5953e1bd7a2Ssjelinek 	/*
5963e1bd7a2Ssjelinek 	 * Return the result.
5973e1bd7a2Ssjelinek 	 */
5983e1bd7a2Ssjelinek 	return (found);
5993e1bd7a2Ssjelinek }
6003e1bd7a2Ssjelinek 
6013e1bd7a2Ssjelinek int
6023e1bd7a2Ssjelinek check_label_with_swap()
6033e1bd7a2Ssjelinek {
6043e1bd7a2Ssjelinek 	int			i;
6053e1bd7a2Ssjelinek 	struct swaptable *st;
6063e1bd7a2Ssjelinek 	struct swapent *swapent;
6073e1bd7a2Ssjelinek 	int	part;
6083e1bd7a2Ssjelinek 	int	bm_swap = 0;
6093e1bd7a2Ssjelinek 
6103e1bd7a2Ssjelinek 	/*
6113e1bd7a2Ssjelinek 	 * If we are only checking part of the disk, the disk must
6123e1bd7a2Ssjelinek 	 * have a partition map to check against.  If it doesn't,
6133e1bd7a2Ssjelinek 	 * we hope for the best.
6143e1bd7a2Ssjelinek 	 */
6153e1bd7a2Ssjelinek 	if (cur_parts == NULL)
6163e1bd7a2Ssjelinek 		return (0);	/* Will be checked later */
6173e1bd7a2Ssjelinek 
6183e1bd7a2Ssjelinek 	/*
6193e1bd7a2Ssjelinek 	 * Check for swap entries
6203e1bd7a2Ssjelinek 	 */
6213e1bd7a2Ssjelinek 	st = getswapentries();
6223e1bd7a2Ssjelinek 	/*
6233e1bd7a2Ssjelinek 	 * if there are no swap entries return.
6243e1bd7a2Ssjelinek 	 */
6253e1bd7a2Ssjelinek 	if (st == (struct swaptable *)NULL)
6263e1bd7a2Ssjelinek 		return (0);
6273e1bd7a2Ssjelinek 	swapent = st->swt_ent;
6283e1bd7a2Ssjelinek 	for (i = 0; i < st->swt_n; i++, swapent++)
6293e1bd7a2Ssjelinek 		if ((part = getpartition(swapent->ste_path)) != -1)
6303e1bd7a2Ssjelinek 				bm_swap |= (1 << part);
6313e1bd7a2Ssjelinek 	freeswapentries(st);
6323e1bd7a2Ssjelinek 
6333e1bd7a2Ssjelinek 	return (checkpartitions(bm_swap));
6343e1bd7a2Ssjelinek }
6353e1bd7a2Ssjelinek 
6363e1bd7a2Ssjelinek /*
6373e1bd7a2Ssjelinek  * Check the new label with the existing label on the disk,
6383e1bd7a2Ssjelinek  * to make sure that any mounted partitions are not being
6393e1bd7a2Ssjelinek  * affected by writing the new label.
6403e1bd7a2Ssjelinek  */
6413e1bd7a2Ssjelinek int
6423e1bd7a2Ssjelinek check_label_with_mount()
6433e1bd7a2Ssjelinek {
6443e1bd7a2Ssjelinek 	FILE			*fp;
6453e1bd7a2Ssjelinek 	int			part;
6463e1bd7a2Ssjelinek 	struct mnttab		mnt_record;
6473e1bd7a2Ssjelinek 	struct mnttab		*mp = &mnt_record;
6483e1bd7a2Ssjelinek 	int			bm_mounted = 0;
6493e1bd7a2Ssjelinek 
6503e1bd7a2Ssjelinek 
6513e1bd7a2Ssjelinek 	/*
6523e1bd7a2Ssjelinek 	 * If we are only checking part of the disk, the disk must
6533e1bd7a2Ssjelinek 	 * have a partition map to check against.  If it doesn't,
6543e1bd7a2Ssjelinek 	 * we hope for the best.
6553e1bd7a2Ssjelinek 	 */
6563e1bd7a2Ssjelinek 	if (cur_parts == NULL)
6573e1bd7a2Ssjelinek 		return (0);	/* Will be checked later */
6583e1bd7a2Ssjelinek 
6593e1bd7a2Ssjelinek 	/*
6603e1bd7a2Ssjelinek 	 * Lock out interrupts because of the mntent protocol.
6613e1bd7a2Ssjelinek 	 */
6623e1bd7a2Ssjelinek 	enter_critical();
6633e1bd7a2Ssjelinek 	/*
6643e1bd7a2Ssjelinek 	 * Open the mount table.
6653e1bd7a2Ssjelinek 	 */
6663e1bd7a2Ssjelinek 	fp = fopen(MNTTAB, "r");
6673e1bd7a2Ssjelinek 	if (fp == NULL) {
6683e1bd7a2Ssjelinek 		err_print("Unable to open mount table.\n");
6693e1bd7a2Ssjelinek 		fullabort();
6703e1bd7a2Ssjelinek 	}
6713e1bd7a2Ssjelinek 	/*
6723e1bd7a2Ssjelinek 	 * Loop through the mount table until we run out of entries.
6733e1bd7a2Ssjelinek 	 */
6743e1bd7a2Ssjelinek 	while ((getmntent(fp, mp)) != -1) {
6753e1bd7a2Ssjelinek 		if ((part = getpartition(mp->mnt_special)) != -1)
6763e1bd7a2Ssjelinek 			bm_mounted |= (1 << part);
6773e1bd7a2Ssjelinek 	}
6783e1bd7a2Ssjelinek 	/*
6793e1bd7a2Ssjelinek 	 * Close down the mount table.
6803e1bd7a2Ssjelinek 	 */
6813e1bd7a2Ssjelinek 	(void) fclose(fp);
6823e1bd7a2Ssjelinek 	exit_critical();
6833e1bd7a2Ssjelinek 
6843e1bd7a2Ssjelinek 	return (checkpartitions(bm_mounted));
6853e1bd7a2Ssjelinek 
6863e1bd7a2Ssjelinek }
6873e1bd7a2Ssjelinek 
6883e1bd7a2Ssjelinek /*
6893e1bd7a2Ssjelinek  * This Routine checks if any partitions specified
6903e1bd7a2Ssjelinek  * are affected by writing the new label
6913e1bd7a2Ssjelinek  */
6923e1bd7a2Ssjelinek static int
6933e1bd7a2Ssjelinek checkpartitions(int bm_mounted)
6943e1bd7a2Ssjelinek {
6953e1bd7a2Ssjelinek 	struct dk_map32		*n;
6963e1bd7a2Ssjelinek 	struct dk_map		*o;
6973e1bd7a2Ssjelinek 	struct dk_allmap	old_map;
6983e1bd7a2Ssjelinek 	int			i, found = 0;
6993e1bd7a2Ssjelinek 
7003e1bd7a2Ssjelinek 	/*
7013e1bd7a2Ssjelinek 	 * Now we need to check that the current partition list and the
7023e1bd7a2Ssjelinek 	 * previous partition list (which there must be if we actually
7033e1bd7a2Ssjelinek 	 * have partitions mounted) overlap  in any way on the mounted
7043e1bd7a2Ssjelinek 	 * partitions
7053e1bd7a2Ssjelinek 	 */
7063e1bd7a2Ssjelinek 
7073e1bd7a2Ssjelinek 	/*
7083e1bd7a2Ssjelinek 	 * Get the "real" (on-disk) version of the partition table
7093e1bd7a2Ssjelinek 	 */
7103e1bd7a2Ssjelinek 	if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
7113e1bd7a2Ssjelinek 		err_print("Unable to get current partition map.\n");
7123e1bd7a2Ssjelinek 		return (-1);
7133e1bd7a2Ssjelinek 	}
7143e1bd7a2Ssjelinek 	for (i = 0; i < NDKMAP; i++) {
7153e1bd7a2Ssjelinek 		if (bm_mounted & (1 << i)) {
7163e1bd7a2Ssjelinek 			/*
7173e1bd7a2Ssjelinek 			 * This partition is mounted
7183e1bd7a2Ssjelinek 			 */
7193e1bd7a2Ssjelinek 			o = &old_map.dka_map[i];
7203e1bd7a2Ssjelinek 			n = &cur_parts->pinfo_map[i];
7213e1bd7a2Ssjelinek #ifdef DEBUG
7223e1bd7a2Ssjelinek 			fmt_print(
7233e1bd7a2Ssjelinek "checkpartitions :checking partition '%c' \n", i + PARTITION_BASE);
7243e1bd7a2Ssjelinek #endif
7253e1bd7a2Ssjelinek 			/*
7263e1bd7a2Ssjelinek 			 * If partition is identical, we're fine.
7273e1bd7a2Ssjelinek 			 * If the partition grows, we're also fine, because
7283e1bd7a2Ssjelinek 			 * the routines in partition.c check for overflow.
7293e1bd7a2Ssjelinek 			 * It will (ultimately) be up to the routines in
7303e1bd7a2Ssjelinek 			 * partition.c to warn about creation of overlapping
7313e1bd7a2Ssjelinek 			 * partitions
7323e1bd7a2Ssjelinek 			 */
7333e1bd7a2Ssjelinek 			if (o->dkl_cylno == n->dkl_cylno &&
7343e1bd7a2Ssjelinek 					o->dkl_nblk <= n->dkl_nblk) {
7353e1bd7a2Ssjelinek #ifdef	DEBUG
7363e1bd7a2Ssjelinek 				if (o->dkl_nblk < n->dkl_nblk) {
7373e1bd7a2Ssjelinek 					fmt_print(
7383e1bd7a2Ssjelinek "- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk);
7393e1bd7a2Ssjelinek 				}
7403e1bd7a2Ssjelinek 				fmt_print("\n");
7413e1bd7a2Ssjelinek #endif
7423e1bd7a2Ssjelinek 				continue;
7433e1bd7a2Ssjelinek 			}
7443e1bd7a2Ssjelinek #ifdef DEBUG
7453e1bd7a2Ssjelinek 			fmt_print("- changes; old (%d,%d)->new (%d,%d)\n",
7463e1bd7a2Ssjelinek 				o->dkl_cylno, o->dkl_nblk, n->dkl_cylno,
7473e1bd7a2Ssjelinek 				n->dkl_nblk);
7483e1bd7a2Ssjelinek #endif
7493e1bd7a2Ssjelinek 			found = -1;
7503e1bd7a2Ssjelinek 		}
7513e1bd7a2Ssjelinek 		if (found)
7523e1bd7a2Ssjelinek 			break;
7533e1bd7a2Ssjelinek 	}
7543e1bd7a2Ssjelinek 
7553e1bd7a2Ssjelinek 	/*
7563e1bd7a2Ssjelinek 	 * If we found trouble and we're running from a command file,
7573e1bd7a2Ssjelinek 	 * quit before doing something we really regret.
7583e1bd7a2Ssjelinek 	 */
7593e1bd7a2Ssjelinek 
7603e1bd7a2Ssjelinek 	if (found && option_f) {
7613e1bd7a2Ssjelinek 		err_print("Operation on mounted disks or \
7623e1bd7a2Ssjelinek disks currently being used for swapping must be interactive.\n");
7633e1bd7a2Ssjelinek 		cmdabort(SIGINT);
7643e1bd7a2Ssjelinek 	}
7653e1bd7a2Ssjelinek 	/*
7663e1bd7a2Ssjelinek 	 * Return the result.
7673e1bd7a2Ssjelinek 	 */
7683e1bd7a2Ssjelinek 	return (found);
7693e1bd7a2Ssjelinek }
770