xref: /illumos-gate/usr/src/cmd/format/checkdev.c (revision b12aaafb)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5d25b227dSzl  * Common Development and Distribution License (the "License").
6d25b227dSzl  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
217c478bd9Sstevel@tonic-gate /*
228eb14f40SSharath M Srinivasan  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
237c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
247c478bd9Sstevel@tonic-gate  */
257c478bd9Sstevel@tonic-gate 
263e1bd7a2Ssjelinek 
277c478bd9Sstevel@tonic-gate 
287c478bd9Sstevel@tonic-gate /*
293e1bd7a2Ssjelinek  * This file contains miscellaneous device validation routines.
307c478bd9Sstevel@tonic-gate  */
317c478bd9Sstevel@tonic-gate 
323e1bd7a2Ssjelinek #include "global.h"
337c478bd9Sstevel@tonic-gate #include <sys/mnttab.h>
347c478bd9Sstevel@tonic-gate #include <sys/mntent.h>
357c478bd9Sstevel@tonic-gate #include <sys/autoconf.h>
367c478bd9Sstevel@tonic-gate 
377c478bd9Sstevel@tonic-gate #include <signal.h>
387c478bd9Sstevel@tonic-gate #include <malloc.h>
397c478bd9Sstevel@tonic-gate #include <unistd.h>
407c478bd9Sstevel@tonic-gate #include <string.h>
417c478bd9Sstevel@tonic-gate #include <errno.h>
427c478bd9Sstevel@tonic-gate #include <fcntl.h>
43d25b227dSzl #include <libgen.h>
447c478bd9Sstevel@tonic-gate #include <sys/ioctl.h>
457c478bd9Sstevel@tonic-gate #include <sys/fcntl.h>
467c478bd9Sstevel@tonic-gate #include <sys/stat.h>
477c478bd9Sstevel@tonic-gate #include <sys/swap.h>
487c478bd9Sstevel@tonic-gate #include <sys/sysmacros.h>
49d25b227dSzl #include <sys/mkdev.h>
50d25b227dSzl #include <sys/modctl.h>
517c478bd9Sstevel@tonic-gate #include <ctype.h>
523e1bd7a2Ssjelinek #include <libdiskmgt.h>
533e1bd7a2Ssjelinek #include <libnvpair.h>
547c478bd9Sstevel@tonic-gate #include "misc.h"
553e1bd7a2Ssjelinek #include "checkdev.h"
568eb14f40SSharath M Srinivasan #include <sys/efi_partition.h>
577c478bd9Sstevel@tonic-gate 
587c478bd9Sstevel@tonic-gate /* Function prototypes */
594d7452f8SToomas Soome static struct	swaptable *getswapentries(void);
604d7452f8SToomas Soome static void	freeswapentries(struct swaptable *);
617c478bd9Sstevel@tonic-gate static int	getpartition(char *pathname);
624d7452f8SToomas Soome static int	checkpartitions(int bm_mounted);
637c478bd9Sstevel@tonic-gate 
647c478bd9Sstevel@tonic-gate static struct swaptable *
getswapentries(void)657c478bd9Sstevel@tonic-gate getswapentries(void)
667c478bd9Sstevel@tonic-gate {
67*b12aaafbSToomas Soome 	struct swaptable *st;
68*b12aaafbSToomas Soome 	struct swapent *swapent;
697c478bd9Sstevel@tonic-gate 	int	i, num;
707c478bd9Sstevel@tonic-gate 	char	fullpathname[MAXPATHLEN];
717c478bd9Sstevel@tonic-gate 
727c478bd9Sstevel@tonic-gate 	/*
737c478bd9Sstevel@tonic-gate 	 * get the number of swap entries
747c478bd9Sstevel@tonic-gate 	 */
75*b12aaafbSToomas Soome 	if ((num = swapctl(SC_GETNSWP, NULL)) == -1) {
767c478bd9Sstevel@tonic-gate 		err_print("swapctl error ");
777c478bd9Sstevel@tonic-gate 		fullabort();
787c478bd9Sstevel@tonic-gate 	}
797c478bd9Sstevel@tonic-gate 	if (num == 0)
807c478bd9Sstevel@tonic-gate 		return (NULL);
817c478bd9Sstevel@tonic-gate 	if ((st = (swaptbl_t *)malloc(num * sizeof (swapent_t) + sizeof (int)))
828eb14f40SSharath M Srinivasan 	    == NULL) {
837c478bd9Sstevel@tonic-gate 		err_print("getswapentries: malloc  failed.\n");
847c478bd9Sstevel@tonic-gate 		fullabort();
857c478bd9Sstevel@tonic-gate 	}
867c478bd9Sstevel@tonic-gate 	swapent = st->swt_ent;
877c478bd9Sstevel@tonic-gate 	for (i = 0; i < num; i++, swapent++) {
887c478bd9Sstevel@tonic-gate 		if ((swapent->ste_path = malloc(MAXPATHLEN)) == NULL) {
897c478bd9Sstevel@tonic-gate 			err_print("getswapentries: malloc  failed.\n");
907c478bd9Sstevel@tonic-gate 			fullabort();
917c478bd9Sstevel@tonic-gate 		}
927c478bd9Sstevel@tonic-gate 	}
937c478bd9Sstevel@tonic-gate 	st->swt_n = num;
947c478bd9Sstevel@tonic-gate 	if ((num = swapctl(SC_LIST, (void *)st)) == -1) {
957c478bd9Sstevel@tonic-gate 		err_print("swapctl error ");
967c478bd9Sstevel@tonic-gate 		fullabort();
977c478bd9Sstevel@tonic-gate 	}
987c478bd9Sstevel@tonic-gate 	swapent = st->swt_ent;
997c478bd9Sstevel@tonic-gate 	for (i = 0; i < num; i++, swapent++) {
1007c478bd9Sstevel@tonic-gate 		if (*swapent->ste_path != '/') {
1017c478bd9Sstevel@tonic-gate 			(void) snprintf(fullpathname, sizeof (fullpathname),
1027c478bd9Sstevel@tonic-gate 			    "/dev/%s", swapent->ste_path);
1037c478bd9Sstevel@tonic-gate 			(void) strcpy(swapent->ste_path, fullpathname);
1047c478bd9Sstevel@tonic-gate 		}
1057c478bd9Sstevel@tonic-gate 	}
1067c478bd9Sstevel@tonic-gate 	return (st);
1077c478bd9Sstevel@tonic-gate }
1087c478bd9Sstevel@tonic-gate 
1097c478bd9Sstevel@tonic-gate static void
freeswapentries(struct swaptable * st)110*b12aaafbSToomas Soome freeswapentries(struct swaptable *st)
1117c478bd9Sstevel@tonic-gate {
112*b12aaafbSToomas Soome 	struct swapent *swapent;
1137c478bd9Sstevel@tonic-gate 	int i;
1147c478bd9Sstevel@tonic-gate 
1157c478bd9Sstevel@tonic-gate 	swapent = st->swt_ent;
1167c478bd9Sstevel@tonic-gate 	for (i = 0; i < st->swt_n; i++, swapent++)
1177c478bd9Sstevel@tonic-gate 		free(swapent->ste_path);
1187c478bd9Sstevel@tonic-gate 	free(st);
1197c478bd9Sstevel@tonic-gate 
1207c478bd9Sstevel@tonic-gate }
1217c478bd9Sstevel@tonic-gate 
1227c478bd9Sstevel@tonic-gate /*
1237c478bd9Sstevel@tonic-gate  *  function getpartition:
1247c478bd9Sstevel@tonic-gate  */
1257c478bd9Sstevel@tonic-gate static int
getpartition(char * pathname)126*b12aaafbSToomas Soome getpartition(char *pathname)
1277c478bd9Sstevel@tonic-gate {
1287c478bd9Sstevel@tonic-gate 	int		mfd;
1297c478bd9Sstevel@tonic-gate 	struct dk_cinfo dkinfo;
1307c478bd9Sstevel@tonic-gate 	struct stat	stbuf;
1317c478bd9Sstevel@tonic-gate 	char		raw_device[MAXPATHLEN];
1327c478bd9Sstevel@tonic-gate 	int		found = -1;
1337c478bd9Sstevel@tonic-gate 
1347c478bd9Sstevel@tonic-gate 	/*
1357c478bd9Sstevel@tonic-gate 	 * Map the block device name to the raw device name.
1367c478bd9Sstevel@tonic-gate 	 * If it doesn't appear to be a device name, skip it.
1377c478bd9Sstevel@tonic-gate 	 */
1387c478bd9Sstevel@tonic-gate 	if (match_substr(pathname, "/dev/") == 0)
1397c478bd9Sstevel@tonic-gate 		return (found);
1407c478bd9Sstevel@tonic-gate 	(void) strcpy(raw_device, "/dev/r");
1417c478bd9Sstevel@tonic-gate 	(void) strcat(raw_device, pathname + strlen("/dev/"));
1427c478bd9Sstevel@tonic-gate 	/*
1437c478bd9Sstevel@tonic-gate 	 * Determine if this appears to be a disk device.
1447c478bd9Sstevel@tonic-gate 	 * First attempt to open the device.  If if fails, skip it.
1457c478bd9Sstevel@tonic-gate 	 */
1467c478bd9Sstevel@tonic-gate 	if ((mfd = open(raw_device, O_RDWR | O_NDELAY)) < 0) {
1477c478bd9Sstevel@tonic-gate 		return (found);
1487c478bd9Sstevel@tonic-gate 	}
1497c478bd9Sstevel@tonic-gate 	/*
1507c478bd9Sstevel@tonic-gate 	 * Must be a character device
1517c478bd9Sstevel@tonic-gate 	 */
1527c478bd9Sstevel@tonic-gate 	if (fstat(mfd, &stbuf) == -1 || !S_ISCHR(stbuf.st_mode)) {
1537c478bd9Sstevel@tonic-gate 		(void) close(mfd);
1547c478bd9Sstevel@tonic-gate 		return (found);
1557c478bd9Sstevel@tonic-gate 	}
1567c478bd9Sstevel@tonic-gate 	/*
1577c478bd9Sstevel@tonic-gate 	 * Attempt to read the configuration info on the disk.
1587c478bd9Sstevel@tonic-gate 	 */
1597c478bd9Sstevel@tonic-gate 	if (ioctl(mfd, DKIOCINFO, &dkinfo) < 0) {
1607c478bd9Sstevel@tonic-gate 		(void) close(mfd);
1617c478bd9Sstevel@tonic-gate 		return (found);
1627c478bd9Sstevel@tonic-gate 	}
1637c478bd9Sstevel@tonic-gate 	/*
1647c478bd9Sstevel@tonic-gate 	 * Finished with the opened device
1657c478bd9Sstevel@tonic-gate 	 */
1667c478bd9Sstevel@tonic-gate 	(void) close(mfd);
1677c478bd9Sstevel@tonic-gate 
1687c478bd9Sstevel@tonic-gate 	/*
1697c478bd9Sstevel@tonic-gate 	 * If it's not the disk we're interested in, it doesn't apply.
1707c478bd9Sstevel@tonic-gate 	 */
1717c478bd9Sstevel@tonic-gate 	if (cur_disk->disk_dkinfo.dki_ctype != dkinfo.dki_ctype ||
172*b12aaafbSToomas Soome 	    cur_disk->disk_dkinfo.dki_cnum != dkinfo.dki_cnum ||
173*b12aaafbSToomas Soome 	    cur_disk->disk_dkinfo.dki_unit != dkinfo.dki_unit ||
174*b12aaafbSToomas Soome 	    strcmp(cur_disk->disk_dkinfo.dki_dname, dkinfo.dki_dname) != 0) {
1757c478bd9Sstevel@tonic-gate 		return (found);
1767c478bd9Sstevel@tonic-gate 	}
1777c478bd9Sstevel@tonic-gate 
1787c478bd9Sstevel@tonic-gate 	/*
1797c478bd9Sstevel@tonic-gate 	 *  Extract the partition that is mounted.
1807c478bd9Sstevel@tonic-gate 	 */
1817c478bd9Sstevel@tonic-gate 	return (PARTITION(stbuf.st_rdev));
1827c478bd9Sstevel@tonic-gate }
1837c478bd9Sstevel@tonic-gate 
1847c478bd9Sstevel@tonic-gate /*
1857c478bd9Sstevel@tonic-gate  * This Routine checks to see if there are partitions used for swapping overlaps
1867c478bd9Sstevel@tonic-gate  * a given portion of a disk. If the start parameter is < 0, it means
1877c478bd9Sstevel@tonic-gate  * that the entire disk should be checked
1887c478bd9Sstevel@tonic-gate  */
1897c478bd9Sstevel@tonic-gate int
checkswap(diskaddr_t start,diskaddr_t end)190*b12aaafbSToomas Soome checkswap(diskaddr_t start, diskaddr_t end)
1917c478bd9Sstevel@tonic-gate {
1927c478bd9Sstevel@tonic-gate 	struct swaptable *st;
1937c478bd9Sstevel@tonic-gate 	struct swapent *swapent;
1947c478bd9Sstevel@tonic-gate 	int		i;
1957c478bd9Sstevel@tonic-gate 	int		found = 0;
1967c478bd9Sstevel@tonic-gate 	struct dk_map32	*map;
1977c478bd9Sstevel@tonic-gate 	int		part;
1987c478bd9Sstevel@tonic-gate 
1997c478bd9Sstevel@tonic-gate 	/*
2007c478bd9Sstevel@tonic-gate 	 * If we are only checking part of the disk, the disk must
2017c478bd9Sstevel@tonic-gate 	 * have a partition map to check against.  If it doesn't,
2027c478bd9Sstevel@tonic-gate 	 * we hope for the best.
2037c478bd9Sstevel@tonic-gate 	 */
2047c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL)
2057c478bd9Sstevel@tonic-gate 		return (0);
2067c478bd9Sstevel@tonic-gate 
2077c478bd9Sstevel@tonic-gate 	/*
2087c478bd9Sstevel@tonic-gate 	 * check for swap entries
2097c478bd9Sstevel@tonic-gate 	 */
2107c478bd9Sstevel@tonic-gate 	st = getswapentries();
2117c478bd9Sstevel@tonic-gate 	/*
2127c478bd9Sstevel@tonic-gate 	 * if there are no swap entries return.
2137c478bd9Sstevel@tonic-gate 	 */
214*b12aaafbSToomas Soome 	if (st == NULL)
2157c478bd9Sstevel@tonic-gate 		return (0);
2167c478bd9Sstevel@tonic-gate 	swapent = st->swt_ent;
2177c478bd9Sstevel@tonic-gate 	for (i = 0; i < st->swt_n; i++, swapent++) {
2187c478bd9Sstevel@tonic-gate 		if ((part = getpartition(swapent->ste_path)) != -1) {
2197c478bd9Sstevel@tonic-gate 			if (start == UINT_MAX64) {
2207c478bd9Sstevel@tonic-gate 				found = -1;
2217c478bd9Sstevel@tonic-gate 				break;
2227c478bd9Sstevel@tonic-gate 			}
2237c478bd9Sstevel@tonic-gate 			map = &cur_parts->pinfo_map[part];
2247c478bd9Sstevel@tonic-gate 			if ((start >= (int)(map->dkl_cylno * spc() +
225*b12aaafbSToomas Soome 			    map->dkl_nblk)) ||
226*b12aaafbSToomas Soome 			    (end < (int)(map->dkl_cylno * spc()))) {
2277c478bd9Sstevel@tonic-gate 					continue;
2287c478bd9Sstevel@tonic-gate 			}
2297c478bd9Sstevel@tonic-gate 			found = -1;
2307c478bd9Sstevel@tonic-gate 			break;
2317c478bd9Sstevel@tonic-gate 		};
2327c478bd9Sstevel@tonic-gate 	}
2337c478bd9Sstevel@tonic-gate 	freeswapentries(st);
2347c478bd9Sstevel@tonic-gate 	/*
2357c478bd9Sstevel@tonic-gate 	 * If we found trouble and we're running from a command file,
2367c478bd9Sstevel@tonic-gate 	 * quit before doing something we really regret.
2377c478bd9Sstevel@tonic-gate 	 */
2387c478bd9Sstevel@tonic-gate 
2397c478bd9Sstevel@tonic-gate 	if (found && option_f) {
2407c478bd9Sstevel@tonic-gate 		err_print(
2417c478bd9Sstevel@tonic-gate "Operation on disks being used for swapping must be interactive.\n");
2427c478bd9Sstevel@tonic-gate 		cmdabort(SIGINT);
2437c478bd9Sstevel@tonic-gate 	}
2447c478bd9Sstevel@tonic-gate 
2457c478bd9Sstevel@tonic-gate 	return (found);
2467c478bd9Sstevel@tonic-gate 
2477c478bd9Sstevel@tonic-gate 
2487c478bd9Sstevel@tonic-gate }
2493e1bd7a2Ssjelinek /*
2503e1bd7a2Ssjelinek  * Determines if there are partitions that are a part of an SVM, VxVM, zpool
2513e1bd7a2Ssjelinek  * volume or a live upgrade device,  overlapping a given portion of a disk.
2523e1bd7a2Ssjelinek  * Mounts and swap devices are checked in legacy format code.
2533e1bd7a2Ssjelinek  */
2543e1bd7a2Ssjelinek int
checkdevinuse(char * cur_disk_path,diskaddr_t start,diskaddr_t end,int print,int check_label)2553e1bd7a2Ssjelinek checkdevinuse(char *cur_disk_path, diskaddr_t start, diskaddr_t end, int print,
256*b12aaafbSToomas Soome     int check_label)
2573e1bd7a2Ssjelinek {
2583e1bd7a2Ssjelinek 
2594d7452f8SToomas Soome 	int		error;
2604d7452f8SToomas Soome 	int		found = 0;
2613e1bd7a2Ssjelinek 	int		check = 0;
2624d7452f8SToomas Soome 	int		i;
2633e1bd7a2Ssjelinek 	int		bm_inuse = 0;
2643e1bd7a2Ssjelinek 	int		part = 0;
2653e1bd7a2Ssjelinek 	uint64_t	slice_start, slice_size;
2663e1bd7a2Ssjelinek 	dm_descriptor_t	*slices = NULL;
2673e1bd7a2Ssjelinek 	nvlist_t	*attrs = NULL;
2683e1bd7a2Ssjelinek 	char		*usage;
2693e1bd7a2Ssjelinek 	char		*name;
2703e1bd7a2Ssjelinek 
27182d71480Ssjelinek 	/*
27282d71480Ssjelinek 	 * If the user does not want to do in use checking, return immediately.
27382d71480Ssjelinek 	 * Normally, this is handled in libdiskmgt. For format, there is more
27482d71480Ssjelinek 	 * processing required, so we want to bypass the in use checking
27582d71480Ssjelinek 	 * here.
27682d71480Ssjelinek 	 */
27782d71480Ssjelinek 
27882d71480Ssjelinek 	if (NOINUSE_SET)
27982d71480Ssjelinek 		return (0);
28082d71480Ssjelinek 
281d25b227dSzl 	/*
282d25b227dSzl 	 * Skip if it is not a real disk
283d25b227dSzl 	 *
284d25b227dSzl 	 * There could be two kinds of strings in cur_disk_path
285d25b227dSzl 	 * One starts with c?t?d?, while the other is a absolute path of a
286d25b227dSzl 	 * block device file.
287d25b227dSzl 	 */
288d25b227dSzl 
289d25b227dSzl 	if (*cur_disk_path != 'c') {
290d25b227dSzl 		struct	stat	stbuf;
291d25b227dSzl 		char		majorname[16];
292d25b227dSzl 		major_t		majornum;
293d25b227dSzl 
294d25b227dSzl 		(void) stat(cur_disk_path, &stbuf);
295d25b227dSzl 		majornum = major(stbuf.st_rdev);
296d25b227dSzl 		(void) modctl(MODGETNAME, majorname, sizeof (majorname),
2978eb14f40SSharath M Srinivasan 		    &majornum);
298d25b227dSzl 
299d25b227dSzl 		if (strcmp(majorname, "sd"))
300d25b227dSzl 			if (strcmp(majorname, "ssd"))
301d25b227dSzl 				if (strcmp(majorname, "cmdk"))
302d25b227dSzl 					return (0);
303d25b227dSzl 	}
304d25b227dSzl 
305d25b227dSzl 	/*
306d25b227dSzl 	 * Truncate the characters following "d*", such as "s*" or "p*"
307d25b227dSzl 	 */
308d25b227dSzl 	cur_disk_path = basename(cur_disk_path);
309d25b227dSzl 	name = strrchr(cur_disk_path, 'd');
310d25b227dSzl 	if (name) {
311d25b227dSzl 		name++;
3128eb14f40SSharath M Srinivasan 		for (; (*name <= '9') && (*name >= '0'); name++) {
3138eb14f40SSharath M Srinivasan 		}
314d25b227dSzl 		*name = (char)0;
315d25b227dSzl 	}
316d25b227dSzl 
317d25b227dSzl 
3183e1bd7a2Ssjelinek 	/*
3193e1bd7a2Ssjelinek 	 * For format, we get basic 'in use' details from libdiskmgt. After
3203e1bd7a2Ssjelinek 	 * that we must do the appropriate checking to see if the 'in use'
3213e1bd7a2Ssjelinek 	 * details require a bit of additional work.
3223e1bd7a2Ssjelinek 	 */
3233e1bd7a2Ssjelinek 
3243e1bd7a2Ssjelinek 	dm_get_slices(cur_disk_path, &slices, &error);
3253e1bd7a2Ssjelinek 	if (error) {
3262b237d4bSny 		/*
3272b237d4bSny 		 * If ENODEV, it actually means the device is not in use.
3282b237d4bSny 		 * We will return 0 without displaying error.
3292b237d4bSny 		 */
3302b237d4bSny 		if (error != ENODEV) {
3312b237d4bSny 			err_print("Error occurred with device in use"
3322b237d4bSny 			    "checking: %s\n", strerror(error));
3332b237d4bSny 			return (found);
3342b237d4bSny 		}
3353e1bd7a2Ssjelinek 	}
3363e1bd7a2Ssjelinek 	if (slices == NULL)
3373e1bd7a2Ssjelinek 		return (found);
3383e1bd7a2Ssjelinek 
3394d7452f8SToomas Soome 	for (i = 0; slices[i] != 0; i++) {
3403e1bd7a2Ssjelinek 		/*
3413e1bd7a2Ssjelinek 		 * If we are checking the whole disk
3423e1bd7a2Ssjelinek 		 * then any and all in use data is
3433e1bd7a2Ssjelinek 		 * relevant.
3443e1bd7a2Ssjelinek 		 */
3453e1bd7a2Ssjelinek 		if (start == UINT_MAX64) {
3463e1bd7a2Ssjelinek 			name = dm_get_name(slices[i], &error);
3473e1bd7a2Ssjelinek 			if (error != 0 || !name) {
3483e1bd7a2Ssjelinek 				err_print("Error occurred with device "
3498eb14f40SSharath M Srinivasan 				    "in use checking: %s\n", strerror(error));
3503e1bd7a2Ssjelinek 				continue;
3513e1bd7a2Ssjelinek 			}
3523e1bd7a2Ssjelinek 			if (dm_inuse(name, &usage, DM_WHO_FORMAT, &error) ||
3533e1bd7a2Ssjelinek 			    error) {
3543e1bd7a2Ssjelinek 				if (error != 0) {
3553e1bd7a2Ssjelinek 					dm_free_name(name);
3563e1bd7a2Ssjelinek 					name = NULL;
3578eb14f40SSharath M Srinivasan 					err_print("Error occurred with "
3588eb14f40SSharath M Srinivasan 					    "device in use checking: "
3598eb14f40SSharath M Srinivasan 					    "%s\n", strerror(error));
3603e1bd7a2Ssjelinek 					continue;
3613e1bd7a2Ssjelinek 				}
3623e1bd7a2Ssjelinek 				dm_free_name(name);
3633e1bd7a2Ssjelinek 				name = NULL;
3643e1bd7a2Ssjelinek 				/*
3653e1bd7a2Ssjelinek 				 * If this is a dump device, then it is
3663e1bd7a2Ssjelinek 				 * a failure. You cannot format a slice
3673e1bd7a2Ssjelinek 				 * that is a dedicated dump device.
3683e1bd7a2Ssjelinek 				 */
3693e1bd7a2Ssjelinek 
3703e1bd7a2Ssjelinek 				if (strstr(usage, DM_USE_DUMP)) {
3713e1bd7a2Ssjelinek 					if (print) {
3723e1bd7a2Ssjelinek 						err_print(usage);
3733e1bd7a2Ssjelinek 						free(usage);
3743e1bd7a2Ssjelinek 					}
3753e1bd7a2Ssjelinek 					dm_free_descriptors(slices);
3763e1bd7a2Ssjelinek 					return (1);
3773e1bd7a2Ssjelinek 				}
3783e1bd7a2Ssjelinek 				/*
3793e1bd7a2Ssjelinek 				 * We really found a device that is in use.
3803e1bd7a2Ssjelinek 				 * Set 'found' for the return value, and set
3813e1bd7a2Ssjelinek 				 * 'check' to indicate below that we must
3823e1bd7a2Ssjelinek 				 * get the partition number to set bm_inuse
3833e1bd7a2Ssjelinek 				 * in the event we are trying to label this
3843e1bd7a2Ssjelinek 				 * device. check_label is set when we are
3853e1bd7a2Ssjelinek 				 * checking modifications for in use slices
3863e1bd7a2Ssjelinek 				 * on the device.
3873e1bd7a2Ssjelinek 				 */
3883e1bd7a2Ssjelinek 				found ++;
3893e1bd7a2Ssjelinek 				check = 1;
3903e1bd7a2Ssjelinek 				if (print) {
3913e1bd7a2Ssjelinek 					err_print(usage);
3923e1bd7a2Ssjelinek 					free(usage);
3933e1bd7a2Ssjelinek 				}
3943e1bd7a2Ssjelinek 			}
3953e1bd7a2Ssjelinek 		} else {
3963e1bd7a2Ssjelinek 			/*
3973e1bd7a2Ssjelinek 			 * Before getting the in use data, verify that the
3983e1bd7a2Ssjelinek 			 * current slice is within the range we are checking.
3993e1bd7a2Ssjelinek 			 */
4003e1bd7a2Ssjelinek 			attrs = dm_get_attributes(slices[i], &error);
4013e1bd7a2Ssjelinek 			if (error) {
4023e1bd7a2Ssjelinek 				err_print("Error occurred with device in use "
4033e1bd7a2Ssjelinek 				    "checking: %s\n", strerror(error));
4043e1bd7a2Ssjelinek 				continue;
4053e1bd7a2Ssjelinek 			}
4063e1bd7a2Ssjelinek 			if (attrs == NULL) {
4073e1bd7a2Ssjelinek 				continue;
4083e1bd7a2Ssjelinek 			}
4097c478bd9Sstevel@tonic-gate 
4103e1bd7a2Ssjelinek 			(void) nvlist_lookup_uint64(attrs, DM_START,
4113e1bd7a2Ssjelinek 			    &slice_start);
4123e1bd7a2Ssjelinek 			(void) nvlist_lookup_uint64(attrs, DM_SIZE,
4133e1bd7a2Ssjelinek 			    &slice_size);
4143e1bd7a2Ssjelinek 			if (start >= (slice_start + slice_size) ||
4153e1bd7a2Ssjelinek 			    (end < slice_start)) {
4163e1bd7a2Ssjelinek 				nvlist_free(attrs);
4173e1bd7a2Ssjelinek 				attrs = NULL;
4183e1bd7a2Ssjelinek 				continue;
4193e1bd7a2Ssjelinek 			}
4203e1bd7a2Ssjelinek 			name = dm_get_name(slices[i], &error);
4213e1bd7a2Ssjelinek 			if (error != 0 || !name) {
4223e1bd7a2Ssjelinek 				err_print("Error occurred with device "
4238eb14f40SSharath M Srinivasan 				    "in use checking: %s\n", strerror(error));
4243e1bd7a2Ssjelinek 				nvlist_free(attrs);
4253e1bd7a2Ssjelinek 				attrs = NULL;
4263e1bd7a2Ssjelinek 				continue;
4273e1bd7a2Ssjelinek 			}
4283e1bd7a2Ssjelinek 			if (dm_inuse(name, &usage,
4293e1bd7a2Ssjelinek 			    DM_WHO_FORMAT, &error) || error) {
4303e1bd7a2Ssjelinek 				if (error != 0) {
4313e1bd7a2Ssjelinek 					dm_free_name(name);
4323e1bd7a2Ssjelinek 					name = NULL;
4338eb14f40SSharath M Srinivasan 					err_print("Error occurred with "
4348eb14f40SSharath M Srinivasan 					    "device in use checking: "
4358eb14f40SSharath M Srinivasan 					    "%s\n", strerror(error));
4363e1bd7a2Ssjelinek 					nvlist_free(attrs);
4373e1bd7a2Ssjelinek 					attrs = NULL;
4383e1bd7a2Ssjelinek 					continue;
4393e1bd7a2Ssjelinek 				}
4403e1bd7a2Ssjelinek 				dm_free_name(name);
4413e1bd7a2Ssjelinek 				name = NULL;
4423e1bd7a2Ssjelinek 				/*
4433e1bd7a2Ssjelinek 				 * If this is a dump device, then it is
4443e1bd7a2Ssjelinek 				 * a failure. You cannot format a slice
4453e1bd7a2Ssjelinek 				 * that is a dedicated dump device.
4463e1bd7a2Ssjelinek 				 */
4473e1bd7a2Ssjelinek 				if (strstr(usage, DM_USE_DUMP)) {
4483e1bd7a2Ssjelinek 					if (print) {
4493e1bd7a2Ssjelinek 						err_print(usage);
4503e1bd7a2Ssjelinek 						free(usage);
4513e1bd7a2Ssjelinek 					}
4523e1bd7a2Ssjelinek 					dm_free_descriptors(slices);
4533e1bd7a2Ssjelinek 					nvlist_free(attrs);
4543e1bd7a2Ssjelinek 					return (1);
4553e1bd7a2Ssjelinek 				}
4563e1bd7a2Ssjelinek 				/*
4573e1bd7a2Ssjelinek 				 * We really found a device that is in use.
4583e1bd7a2Ssjelinek 				 * Set 'found' for the return value, and set
4593e1bd7a2Ssjelinek 				 * 'check' to indicate below that we must
4603e1bd7a2Ssjelinek 				 * get the partition number to set bm_inuse
4613e1bd7a2Ssjelinek 				 * in the event we are trying to label this
4623e1bd7a2Ssjelinek 				 * device. check_label is set when we are
4633e1bd7a2Ssjelinek 				 * checking modifications for in use slices
4643e1bd7a2Ssjelinek 				 * on the device.
4653e1bd7a2Ssjelinek 				 */
4663e1bd7a2Ssjelinek 				found ++;
4673e1bd7a2Ssjelinek 				check = 1;
4683e1bd7a2Ssjelinek 				if (print) {
4693e1bd7a2Ssjelinek 					err_print(usage);
4703e1bd7a2Ssjelinek 					free(usage);
4713e1bd7a2Ssjelinek 				}
4723e1bd7a2Ssjelinek 			}
4733e1bd7a2Ssjelinek 		}
4743e1bd7a2Ssjelinek 		/*
4753e1bd7a2Ssjelinek 		 * If check is set it means we found a slice(the current slice)
4763e1bd7a2Ssjelinek 		 * on this device in use in some way.  We potentially want
4773e1bd7a2Ssjelinek 		 * to check this slice when labeling is
4783e1bd7a2Ssjelinek 		 * requested. We set bm_inuse with this partition value
4793e1bd7a2Ssjelinek 		 * for use later if check_label was set when called.
4803e1bd7a2Ssjelinek 		 */
4813e1bd7a2Ssjelinek 		if (check) {
4823e1bd7a2Ssjelinek 			name = dm_get_name(slices[i], &error);
4833e1bd7a2Ssjelinek 			if (error != 0 || !name) {
4843e1bd7a2Ssjelinek 				err_print("Error occurred with device "
4858eb14f40SSharath M Srinivasan 				    "in use checking: %s\n", strerror(error));
4863e1bd7a2Ssjelinek 				nvlist_free(attrs);
4873e1bd7a2Ssjelinek 				attrs = NULL;
4883e1bd7a2Ssjelinek 				continue;
4893e1bd7a2Ssjelinek 			}
4903e1bd7a2Ssjelinek 			part = getpartition(name);
4913e1bd7a2Ssjelinek 			dm_free_name(name);
4923e1bd7a2Ssjelinek 			name = NULL;
4933e1bd7a2Ssjelinek 			if (part != -1) {
4943e1bd7a2Ssjelinek 				bm_inuse |= 1 << part;
4953e1bd7a2Ssjelinek 			}
4963e1bd7a2Ssjelinek 			check = 0;
4973e1bd7a2Ssjelinek 		}
4983e1bd7a2Ssjelinek 		/*
4993e1bd7a2Ssjelinek 		 * If we have attributes then we have successfully
5003e1bd7a2Ssjelinek 		 * found the slice we were looking for and we also
5013e1bd7a2Ssjelinek 		 * know this means we are not searching the whole
5023e1bd7a2Ssjelinek 		 * disk so break out of the loop
5033e1bd7a2Ssjelinek 		 * now.
5043e1bd7a2Ssjelinek 		 */
5053e1bd7a2Ssjelinek 		if (attrs) {
5063e1bd7a2Ssjelinek 			nvlist_free(attrs);
5073e1bd7a2Ssjelinek 			break;
5083e1bd7a2Ssjelinek 		}
5093e1bd7a2Ssjelinek 	}
5103e1bd7a2Ssjelinek 
5113e1bd7a2Ssjelinek 	if (slices) {
5123e1bd7a2Ssjelinek 		dm_free_descriptors(slices);
5133e1bd7a2Ssjelinek 	}
5143e1bd7a2Ssjelinek 
5153e1bd7a2Ssjelinek 	/*
5163e1bd7a2Ssjelinek 	 * The user is trying to label the disk. We have to do special
5173e1bd7a2Ssjelinek 	 * checking here to ensure they are not trying to modify a slice
5183e1bd7a2Ssjelinek 	 * that is in use in an incompatible way.
5193e1bd7a2Ssjelinek 	 */
5203e1bd7a2Ssjelinek 	if (check_label && bm_inuse) {
5213e1bd7a2Ssjelinek 		/*
5223e1bd7a2Ssjelinek 		 * !0 indicates that we found a
5233e1bd7a2Ssjelinek 		 * problem. In this case, we have overloaded
5243e1bd7a2Ssjelinek 		 * the use of checkpartitions to work for
5253e1bd7a2Ssjelinek 		 * in use devices. bm_inuse is representative
5263e1bd7a2Ssjelinek 		 * of the slice that is in use, not that
5273e1bd7a2Ssjelinek 		 * is mounted as is in the case of the normal
5283e1bd7a2Ssjelinek 		 * use of checkpartitions.
5293e1bd7a2Ssjelinek 		 *
5303e1bd7a2Ssjelinek 		 * The call to checkpartitions will return !0 if
5313e1bd7a2Ssjelinek 		 * we are trying to shrink a device that we have found
5323e1bd7a2Ssjelinek 		 * to be in use above.
5333e1bd7a2Ssjelinek 		 */
5343e1bd7a2Ssjelinek 		return (checkpartitions(bm_inuse));
5353e1bd7a2Ssjelinek 	}
5363e1bd7a2Ssjelinek 
5373e1bd7a2Ssjelinek 	return (found);
5383e1bd7a2Ssjelinek }
5397c478bd9Sstevel@tonic-gate /*
5407c478bd9Sstevel@tonic-gate  * This routine checks to see if there are mounted partitions overlapping
5417c478bd9Sstevel@tonic-gate  * a given portion of a disk.  If the start parameter is < 0, it means
5427c478bd9Sstevel@tonic-gate  * that the entire disk should be checked.
5437c478bd9Sstevel@tonic-gate  */
5447c478bd9Sstevel@tonic-gate int
checkmount(diskaddr_t start,diskaddr_t end)545*b12aaafbSToomas Soome checkmount(diskaddr_t start, diskaddr_t end)
5467c478bd9Sstevel@tonic-gate {
5477c478bd9Sstevel@tonic-gate 	FILE		*fp;
5487c478bd9Sstevel@tonic-gate 	int		found = 0;
5497c478bd9Sstevel@tonic-gate 	struct dk_map32	*map;
5507c478bd9Sstevel@tonic-gate 	int		part;
5517c478bd9Sstevel@tonic-gate 	struct mnttab	mnt_record;
5527c478bd9Sstevel@tonic-gate 	struct mnttab	*mp = &mnt_record;
5537c478bd9Sstevel@tonic-gate 
5547c478bd9Sstevel@tonic-gate 	/*
5557c478bd9Sstevel@tonic-gate 	 * If we are only checking part of the disk, the disk must
5567c478bd9Sstevel@tonic-gate 	 * have a partition map to check against.  If it doesn't,
5577c478bd9Sstevel@tonic-gate 	 * we hope for the best.
5587c478bd9Sstevel@tonic-gate 	 */
5597c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL)
5607c478bd9Sstevel@tonic-gate 		return (0);
5617c478bd9Sstevel@tonic-gate 
5627c478bd9Sstevel@tonic-gate 	/*
5637c478bd9Sstevel@tonic-gate 	 * Lock out interrupts because of the mntent protocol.
5647c478bd9Sstevel@tonic-gate 	 */
5657c478bd9Sstevel@tonic-gate 	enter_critical();
5667c478bd9Sstevel@tonic-gate 	/*
5677c478bd9Sstevel@tonic-gate 	 * Open the mount table.
5687c478bd9Sstevel@tonic-gate 	 */
5697c478bd9Sstevel@tonic-gate 	fp = fopen(MNTTAB, "r");
5707c478bd9Sstevel@tonic-gate 	if (fp == NULL) {
5717c478bd9Sstevel@tonic-gate 		err_print("Unable to open mount table.\n");
5727c478bd9Sstevel@tonic-gate 		fullabort();
5737c478bd9Sstevel@tonic-gate 	}
5747c478bd9Sstevel@tonic-gate 	/*
5757c478bd9Sstevel@tonic-gate 	 * Loop through the mount table until we run out of entries.
5767c478bd9Sstevel@tonic-gate 	 */
5777c478bd9Sstevel@tonic-gate 	while ((getmntent(fp, mp)) != -1) {
5787c478bd9Sstevel@tonic-gate 
5797c478bd9Sstevel@tonic-gate 		if ((part = getpartition(mp->mnt_special)) == -1)
5807c478bd9Sstevel@tonic-gate 			continue;
5817c478bd9Sstevel@tonic-gate 
5827c478bd9Sstevel@tonic-gate 		/*
5837c478bd9Sstevel@tonic-gate 		 * It's a mount on the disk we're checking.  If we are
5847c478bd9Sstevel@tonic-gate 		 * checking whole disk, then we found trouble.  We can
5857c478bd9Sstevel@tonic-gate 		 * quit searching.
5867c478bd9Sstevel@tonic-gate 		 */
5877c478bd9Sstevel@tonic-gate 		if (start == UINT_MAX64) {
5887c478bd9Sstevel@tonic-gate 			found = -1;
5897c478bd9Sstevel@tonic-gate 			break;
5907c478bd9Sstevel@tonic-gate 		}
5917c478bd9Sstevel@tonic-gate 
5927c478bd9Sstevel@tonic-gate 		/*
5937c478bd9Sstevel@tonic-gate 		 * If the partition overlaps the zone we're checking,
5947c478bd9Sstevel@tonic-gate 		 * then we found trouble.  We can quit searching.
5957c478bd9Sstevel@tonic-gate 		 */
5967c478bd9Sstevel@tonic-gate 		map = &cur_parts->pinfo_map[part];
5977c478bd9Sstevel@tonic-gate 		if ((start >= (int)(map->dkl_cylno * spc() + map->dkl_nblk)) ||
598*b12aaafbSToomas Soome 		    (end < (int)(map->dkl_cylno * spc()))) {
5997c478bd9Sstevel@tonic-gate 			continue;
6007c478bd9Sstevel@tonic-gate 		}
6017c478bd9Sstevel@tonic-gate 		found = -1;
6027c478bd9Sstevel@tonic-gate 		break;
6037c478bd9Sstevel@tonic-gate 	}
6047c478bd9Sstevel@tonic-gate 	/*
6057c478bd9Sstevel@tonic-gate 	 * Close down the mount table.
6067c478bd9Sstevel@tonic-gate 	 */
6077c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
6087c478bd9Sstevel@tonic-gate 	exit_critical();
6097c478bd9Sstevel@tonic-gate 
6107c478bd9Sstevel@tonic-gate 	/*
6117c478bd9Sstevel@tonic-gate 	 * If we found trouble and we're running from a command file,
6127c478bd9Sstevel@tonic-gate 	 * quit before doing something we really regret.
6137c478bd9Sstevel@tonic-gate 	 */
6147c478bd9Sstevel@tonic-gate 
6157c478bd9Sstevel@tonic-gate 	if (found && option_f) {
6167c478bd9Sstevel@tonic-gate 		err_print("Operation on mounted disks must be interactive.\n");
6177c478bd9Sstevel@tonic-gate 		cmdabort(SIGINT);
6187c478bd9Sstevel@tonic-gate 	}
6197c478bd9Sstevel@tonic-gate 	/*
6207c478bd9Sstevel@tonic-gate 	 * Return the result.
6217c478bd9Sstevel@tonic-gate 	 */
6227c478bd9Sstevel@tonic-gate 	return (found);
6237c478bd9Sstevel@tonic-gate }
6247c478bd9Sstevel@tonic-gate 
6257c478bd9Sstevel@tonic-gate int
check_label_with_swap(void)626*b12aaafbSToomas Soome check_label_with_swap(void)
6277c478bd9Sstevel@tonic-gate {
6287c478bd9Sstevel@tonic-gate 	int			i;
6297c478bd9Sstevel@tonic-gate 	struct swaptable *st;
6307c478bd9Sstevel@tonic-gate 	struct swapent *swapent;
6317c478bd9Sstevel@tonic-gate 	int	part;
6327c478bd9Sstevel@tonic-gate 	int	bm_swap = 0;
6337c478bd9Sstevel@tonic-gate 
6347c478bd9Sstevel@tonic-gate 	/*
6357c478bd9Sstevel@tonic-gate 	 * If we are only checking part of the disk, the disk must
6367c478bd9Sstevel@tonic-gate 	 * have a partition map to check against.  If it doesn't,
6377c478bd9Sstevel@tonic-gate 	 * we hope for the best.
6387c478bd9Sstevel@tonic-gate 	 */
6397c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL)
6407c478bd9Sstevel@tonic-gate 		return (0);	/* Will be checked later */
6417c478bd9Sstevel@tonic-gate 
6427c478bd9Sstevel@tonic-gate 	/*
6437c478bd9Sstevel@tonic-gate 	 * Check for swap entries
6447c478bd9Sstevel@tonic-gate 	 */
6457c478bd9Sstevel@tonic-gate 	st = getswapentries();
6467c478bd9Sstevel@tonic-gate 	/*
6477c478bd9Sstevel@tonic-gate 	 * if there are no swap entries return.
6487c478bd9Sstevel@tonic-gate 	 */
649*b12aaafbSToomas Soome 	if (st == NULL)
6507c478bd9Sstevel@tonic-gate 		return (0);
6517c478bd9Sstevel@tonic-gate 	swapent = st->swt_ent;
6527c478bd9Sstevel@tonic-gate 	for (i = 0; i < st->swt_n; i++, swapent++)
6537c478bd9Sstevel@tonic-gate 		if ((part = getpartition(swapent->ste_path)) != -1)
6547c478bd9Sstevel@tonic-gate 				bm_swap |= (1 << part);
6557c478bd9Sstevel@tonic-gate 	freeswapentries(st);
6567c478bd9Sstevel@tonic-gate 
6577c478bd9Sstevel@tonic-gate 	return (checkpartitions(bm_swap));
6587c478bd9Sstevel@tonic-gate }
6597c478bd9Sstevel@tonic-gate 
6607c478bd9Sstevel@tonic-gate /*
6617c478bd9Sstevel@tonic-gate  * Check the new label with the existing label on the disk,
6627c478bd9Sstevel@tonic-gate  * to make sure that any mounted partitions are not being
6637c478bd9Sstevel@tonic-gate  * affected by writing the new label.
6647c478bd9Sstevel@tonic-gate  */
6657c478bd9Sstevel@tonic-gate int
check_label_with_mount(void)666*b12aaafbSToomas Soome check_label_with_mount(void)
6677c478bd9Sstevel@tonic-gate {
6687c478bd9Sstevel@tonic-gate 	FILE			*fp;
6697c478bd9Sstevel@tonic-gate 	int			part;
6707c478bd9Sstevel@tonic-gate 	struct mnttab		mnt_record;
6717c478bd9Sstevel@tonic-gate 	struct mnttab		*mp = &mnt_record;
6727c478bd9Sstevel@tonic-gate 	int			bm_mounted = 0;
6737c478bd9Sstevel@tonic-gate 
6747c478bd9Sstevel@tonic-gate 
6757c478bd9Sstevel@tonic-gate 	/*
6767c478bd9Sstevel@tonic-gate 	 * If we are only checking part of the disk, the disk must
6777c478bd9Sstevel@tonic-gate 	 * have a partition map to check against.  If it doesn't,
6787c478bd9Sstevel@tonic-gate 	 * we hope for the best.
6797c478bd9Sstevel@tonic-gate 	 */
6807c478bd9Sstevel@tonic-gate 	if (cur_parts == NULL)
6817c478bd9Sstevel@tonic-gate 		return (0);	/* Will be checked later */
6827c478bd9Sstevel@tonic-gate 
6837c478bd9Sstevel@tonic-gate 	/*
6847c478bd9Sstevel@tonic-gate 	 * Lock out interrupts because of the mntent protocol.
6857c478bd9Sstevel@tonic-gate 	 */
6867c478bd9Sstevel@tonic-gate 	enter_critical();
6877c478bd9Sstevel@tonic-gate 	/*
6887c478bd9Sstevel@tonic-gate 	 * Open the mount table.
6897c478bd9Sstevel@tonic-gate 	 */
6907c478bd9Sstevel@tonic-gate 	fp = fopen(MNTTAB, "r");
6917c478bd9Sstevel@tonic-gate 	if (fp == NULL) {
6927c478bd9Sstevel@tonic-gate 		err_print("Unable to open mount table.\n");
6937c478bd9Sstevel@tonic-gate 		fullabort();
6947c478bd9Sstevel@tonic-gate 	}
6957c478bd9Sstevel@tonic-gate 	/*
6967c478bd9Sstevel@tonic-gate 	 * Loop through the mount table until we run out of entries.
6977c478bd9Sstevel@tonic-gate 	 */
6987c478bd9Sstevel@tonic-gate 	while ((getmntent(fp, mp)) != -1) {
6997c478bd9Sstevel@tonic-gate 		if ((part = getpartition(mp->mnt_special)) != -1)
7007c478bd9Sstevel@tonic-gate 			bm_mounted |= (1 << part);
7017c478bd9Sstevel@tonic-gate 	}
7027c478bd9Sstevel@tonic-gate 	/*
7037c478bd9Sstevel@tonic-gate 	 * Close down the mount table.
7047c478bd9Sstevel@tonic-gate 	 */
7057c478bd9Sstevel@tonic-gate 	(void) fclose(fp);
7067c478bd9Sstevel@tonic-gate 	exit_critical();
7077c478bd9Sstevel@tonic-gate 
7087c478bd9Sstevel@tonic-gate 	return (checkpartitions(bm_mounted));
7097c478bd9Sstevel@tonic-gate 
7107c478bd9Sstevel@tonic-gate }
7117c478bd9Sstevel@tonic-gate 
7127c478bd9Sstevel@tonic-gate /*
7133e1bd7a2Ssjelinek  * This Routine checks if any partitions specified
7143e1bd7a2Ssjelinek  * are affected by writing the new label
7157c478bd9Sstevel@tonic-gate  */
7167c478bd9Sstevel@tonic-gate static int
checkpartitions(int bm_mounted)7173e1bd7a2Ssjelinek checkpartitions(int bm_mounted)
7187c478bd9Sstevel@tonic-gate {
7197c478bd9Sstevel@tonic-gate 	struct dk_map32		*n;
7207c478bd9Sstevel@tonic-gate 	struct dk_map		*o;
7217c478bd9Sstevel@tonic-gate 	struct dk_allmap	old_map;
7227c478bd9Sstevel@tonic-gate 	int			i, found = 0;
7238eb14f40SSharath M Srinivasan 	struct partition64	o_efi;
7247c478bd9Sstevel@tonic-gate 
7257c478bd9Sstevel@tonic-gate 	/*
7267c478bd9Sstevel@tonic-gate 	 * Now we need to check that the current partition list and the
7277c478bd9Sstevel@tonic-gate 	 * previous partition list (which there must be if we actually
7287c478bd9Sstevel@tonic-gate 	 * have partitions mounted) overlap  in any way on the mounted
7297c478bd9Sstevel@tonic-gate 	 * partitions
7307c478bd9Sstevel@tonic-gate 	 */
7317c478bd9Sstevel@tonic-gate 
7327c478bd9Sstevel@tonic-gate 	/*
7338eb14f40SSharath M Srinivasan 	 * Check if the user wants to online-label an
7348eb14f40SSharath M Srinivasan 	 * existing EFI label.
7357c478bd9Sstevel@tonic-gate 	 */
7368eb14f40SSharath M Srinivasan 	if (cur_label == L_TYPE_EFI) {
7378eb14f40SSharath M Srinivasan 		for (i = 0; i < EFI_NUMPAR; i++) {
7388eb14f40SSharath M Srinivasan 			if (bm_mounted & (1 << i)) {
7398eb14f40SSharath M Srinivasan 				o_efi.p_partno = i;
7408eb14f40SSharath M Srinivasan 				if (ioctl(cur_file, DKIOCPARTITION, &o_efi)
7418eb14f40SSharath M Srinivasan 				    == -1) {
7428eb14f40SSharath M Srinivasan 					err_print("Unable to get information "
7438eb14f40SSharath M Srinivasan 					    "for EFI partition %d.\n", i);
7448eb14f40SSharath M Srinivasan 					return (-1);
7458eb14f40SSharath M Srinivasan 				}
7468eb14f40SSharath M Srinivasan 
7478eb14f40SSharath M Srinivasan 				/*
7488eb14f40SSharath M Srinivasan 				 * Partition can grow or remain same.
7498eb14f40SSharath M Srinivasan 				 */
7508eb14f40SSharath M Srinivasan 				if (o_efi.p_start == cur_parts->etoc->
7518eb14f40SSharath M Srinivasan 				    efi_parts[i].p_start && o_efi.p_size
7528eb14f40SSharath M Srinivasan 				    <= cur_parts->etoc->efi_parts[i].p_size) {
7538eb14f40SSharath M Srinivasan 					continue;
7548eb14f40SSharath M Srinivasan 				}
7558eb14f40SSharath M Srinivasan 
7568eb14f40SSharath M Srinivasan 				found = -1;
7578eb14f40SSharath M Srinivasan 			}
7588eb14f40SSharath M Srinivasan 			if (found)
7598eb14f40SSharath M Srinivasan 				break;
7608eb14f40SSharath M Srinivasan 		}
7618eb14f40SSharath M Srinivasan 
7628eb14f40SSharath M Srinivasan 	} else {
7638eb14f40SSharath M Srinivasan 
7648eb14f40SSharath M Srinivasan 		/*
7658eb14f40SSharath M Srinivasan 		 * Get the "real" (on-disk) version of the partition table
7668eb14f40SSharath M Srinivasan 		 */
7678eb14f40SSharath M Srinivasan 		if (ioctl(cur_file, DKIOCGAPART, &old_map) == -1) {
7688eb14f40SSharath M Srinivasan 			err_print("Unable to get current partition map.\n");
7698eb14f40SSharath M Srinivasan 			return (-1);
7708eb14f40SSharath M Srinivasan 		}
7718eb14f40SSharath M Srinivasan 		for (i = 0; i < NDKMAP; i++) {
7728eb14f40SSharath M Srinivasan 			if (bm_mounted & (1 << i)) {
7738eb14f40SSharath M Srinivasan 				/*
7748eb14f40SSharath M Srinivasan 				 * This partition is mounted
7758eb14f40SSharath M Srinivasan 				 */
7768eb14f40SSharath M Srinivasan 				o = &old_map.dka_map[i];
7778eb14f40SSharath M Srinivasan 				n = &cur_parts->pinfo_map[i];
7787c478bd9Sstevel@tonic-gate #ifdef DEBUG
7798eb14f40SSharath M Srinivasan 				fmt_print(
7807c478bd9Sstevel@tonic-gate "checkpartitions :checking partition '%c' \n", i + PARTITION_BASE);
7817c478bd9Sstevel@tonic-gate #endif
7828eb14f40SSharath M Srinivasan 				/*
7838eb14f40SSharath M Srinivasan 				 * If partition is identical, we're fine.
7848eb14f40SSharath M Srinivasan 				 * If the partition grows, we're also fine,
7858eb14f40SSharath M Srinivasan 				 * because the routines in partition.c check
7868eb14f40SSharath M Srinivasan 				 * for overflow. It will (ultimately) be up
7878eb14f40SSharath M Srinivasan 				 * to the routines in partition.c to warn
7888eb14f40SSharath M Srinivasan 				 * about creation of overlapping partitions.
7898eb14f40SSharath M Srinivasan 				 */
7908eb14f40SSharath M Srinivasan 				if (o->dkl_cylno == n->dkl_cylno &&
7918eb14f40SSharath M Srinivasan 				    o->dkl_nblk <= n->dkl_nblk) {
7927c478bd9Sstevel@tonic-gate #ifdef	DEBUG
7938eb14f40SSharath M Srinivasan 					if (o->dkl_nblk < n->dkl_nblk) {
7948eb14f40SSharath M Srinivasan 						fmt_print(
7957c478bd9Sstevel@tonic-gate "- new partition larger by %d blocks", n->dkl_nblk-o->dkl_nblk);
7968eb14f40SSharath M Srinivasan 					}
7978eb14f40SSharath M Srinivasan 					fmt_print("\n");
7987c478bd9Sstevel@tonic-gate #endif
7998eb14f40SSharath M Srinivasan 					continue;
8008eb14f40SSharath M Srinivasan 				}
8017c478bd9Sstevel@tonic-gate #ifdef DEBUG
8028eb14f40SSharath M Srinivasan 				fmt_print("- changes; old (%d,%d)->new "
8038eb14f40SSharath M Srinivasan "(%d,%d)\n", o->dkl_cylno, o->dkl_nblk, n->dkl_cylno, n->dkl_nblk);
8047c478bd9Sstevel@tonic-gate #endif
8058eb14f40SSharath M Srinivasan 				found = -1;
8068eb14f40SSharath M Srinivasan 			}
8078eb14f40SSharath M Srinivasan 			if (found)
8088eb14f40SSharath M Srinivasan 				break;
8097c478bd9Sstevel@tonic-gate 		}
8107c478bd9Sstevel@tonic-gate 	}
8117c478bd9Sstevel@tonic-gate 
8127c478bd9Sstevel@tonic-gate 	/*
8137c478bd9Sstevel@tonic-gate 	 * If we found trouble and we're running from a command file,
8147c478bd9Sstevel@tonic-gate 	 * quit before doing something we really regret.
8157c478bd9Sstevel@tonic-gate 	 */
8167c478bd9Sstevel@tonic-gate 
8177c478bd9Sstevel@tonic-gate 	if (found && option_f) {
8187c478bd9Sstevel@tonic-gate 		err_print("Operation on mounted disks or \
8197c478bd9Sstevel@tonic-gate disks currently being used for swapping must be interactive.\n");
8207c478bd9Sstevel@tonic-gate 		cmdabort(SIGINT);
8217c478bd9Sstevel@tonic-gate 	}
8227c478bd9Sstevel@tonic-gate 	/*
8237c478bd9Sstevel@tonic-gate 	 * Return the result.
8247c478bd9Sstevel@tonic-gate 	 */
8257c478bd9Sstevel@tonic-gate 	return (found);
8267c478bd9Sstevel@tonic-gate }
827