xref: /onnv-gate/usr/src/lib/lvm/libmeta/common/meta_check.c (revision 9017:47960a78ed2a)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
51623Stw21770  * Common Development and Distribution License (the "License").
61623Stw21770  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
21*9017SJohn.Wren.Kennedy@Sun.COM 
220Sstevel@tonic-gate /*
23*9017SJohn.Wren.Kennedy@Sun.COM  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
240Sstevel@tonic-gate  * Use is subject to license terms.
250Sstevel@tonic-gate  */
260Sstevel@tonic-gate 
270Sstevel@tonic-gate /*
280Sstevel@tonic-gate  * Just in case we're not in a build environment, make sure that
290Sstevel@tonic-gate  * TEXT_DOMAIN gets set to something.
300Sstevel@tonic-gate  */
310Sstevel@tonic-gate #if !defined(TEXT_DOMAIN)
320Sstevel@tonic-gate #define	TEXT_DOMAIN "SYS_TEST"
330Sstevel@tonic-gate #endif
340Sstevel@tonic-gate 
350Sstevel@tonic-gate /*
360Sstevel@tonic-gate  * check componets
370Sstevel@tonic-gate  */
380Sstevel@tonic-gate 
390Sstevel@tonic-gate #include <meta.h>
400Sstevel@tonic-gate #include "meta_lib_prv.h"
410Sstevel@tonic-gate 
420Sstevel@tonic-gate #include <sys/mnttab.h>
430Sstevel@tonic-gate #include <sys/swap.h>
440Sstevel@tonic-gate #include <devid.h>
450Sstevel@tonic-gate #include <sys/dumpadm.h>
460Sstevel@tonic-gate 
47127Shshaw /* possible returns from meta_check_samedrive */
48127Shshaw #define	CANT_TELL		-1
49127Shshaw #define	NOT_SAMEDRIVE		0
50127Shshaw #define	IDENTICAL_NAME_DEVT	1
51127Shshaw #define	IDENTICAL_DEVIDS	2
52127Shshaw 
530Sstevel@tonic-gate /*
540Sstevel@tonic-gate  * static list(s)
550Sstevel@tonic-gate  */
560Sstevel@tonic-gate typedef struct dev_list {
570Sstevel@tonic-gate 	char			*dev_name;
580Sstevel@tonic-gate 	ddi_devid_t		devid;
590Sstevel@tonic-gate 	struct dev_list		*dev_nxt;
600Sstevel@tonic-gate } dev_list_t;
610Sstevel@tonic-gate 
620Sstevel@tonic-gate static dev_list_t	*devnamelist = NULL;
630Sstevel@tonic-gate 
64*9017SJohn.Wren.Kennedy@Sun.COM static char	*skip_these_mntents[] = {
65*9017SJohn.Wren.Kennedy@Sun.COM 	"nfs",
66*9017SJohn.Wren.Kennedy@Sun.COM 	"autofs",
67*9017SJohn.Wren.Kennedy@Sun.COM 	"proc",
68*9017SJohn.Wren.Kennedy@Sun.COM 	"tmpfs",
69*9017SJohn.Wren.Kennedy@Sun.COM 	"cachefs",
70*9017SJohn.Wren.Kennedy@Sun.COM 	"rfs",
71*9017SJohn.Wren.Kennedy@Sun.COM 	"fd",
72*9017SJohn.Wren.Kennedy@Sun.COM 	"mntfs",
73*9017SJohn.Wren.Kennedy@Sun.COM 	"lofs",
74*9017SJohn.Wren.Kennedy@Sun.COM 	"devfs",
75*9017SJohn.Wren.Kennedy@Sun.COM 	"dev",
76*9017SJohn.Wren.Kennedy@Sun.COM 	"ctfs",
77*9017SJohn.Wren.Kennedy@Sun.COM 	"objfs",
78*9017SJohn.Wren.Kennedy@Sun.COM 	"sharefs",
79*9017SJohn.Wren.Kennedy@Sun.COM 	NULL
80*9017SJohn.Wren.Kennedy@Sun.COM };
81*9017SJohn.Wren.Kennedy@Sun.COM 
820Sstevel@tonic-gate /*
830Sstevel@tonic-gate  * free swap info
840Sstevel@tonic-gate  */
850Sstevel@tonic-gate static void
free_swapinfo(struct swaptable * swtp)860Sstevel@tonic-gate free_swapinfo(
870Sstevel@tonic-gate 	struct swaptable	*swtp
880Sstevel@tonic-gate )
890Sstevel@tonic-gate {
900Sstevel@tonic-gate 	int			i;
910Sstevel@tonic-gate 
920Sstevel@tonic-gate 	if (swtp == NULL)
930Sstevel@tonic-gate 		return;
940Sstevel@tonic-gate 
950Sstevel@tonic-gate 	for (i = 0; (i < swtp->swt_n); ++i) {
960Sstevel@tonic-gate 		if (swtp->swt_ent[i].ste_path != NULL)
970Sstevel@tonic-gate 			Free(swtp->swt_ent[i].ste_path);
980Sstevel@tonic-gate 	}
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate 	Free(swtp);
1010Sstevel@tonic-gate }
1020Sstevel@tonic-gate 
1030Sstevel@tonic-gate /*
1040Sstevel@tonic-gate  * get swap info
1050Sstevel@tonic-gate  */
1060Sstevel@tonic-gate static int
get_swapinfo(struct swaptable ** swtpp,int * nswap,md_error_t * ep)1070Sstevel@tonic-gate get_swapinfo(
1080Sstevel@tonic-gate 	struct swaptable	**swtpp,
1090Sstevel@tonic-gate 	int			*nswap,
1100Sstevel@tonic-gate 	md_error_t		*ep
1110Sstevel@tonic-gate )
1120Sstevel@tonic-gate {
1130Sstevel@tonic-gate 	int			i;
1140Sstevel@tonic-gate 	size_t			swtsize;
1150Sstevel@tonic-gate 
1160Sstevel@tonic-gate 	*swtpp = NULL;
1170Sstevel@tonic-gate 
1180Sstevel@tonic-gate 	/* get number of entries */
1190Sstevel@tonic-gate 	if ((*nswap = swapctl(SC_GETNSWP, NULL)) < 0) {
1200Sstevel@tonic-gate 		return (mdsyserror(ep, errno, "swapctl(SC_GETNSWP)"));
1210Sstevel@tonic-gate 	}
1220Sstevel@tonic-gate 
1230Sstevel@tonic-gate 	/* allocate structure */
1240Sstevel@tonic-gate 	swtsize = sizeof ((*swtpp)->swt_n) +
1250Sstevel@tonic-gate 	    ((*nswap) * sizeof ((*swtpp)->swt_ent[0]));
1260Sstevel@tonic-gate 	*swtpp = (struct swaptable *)Zalloc(swtsize);
1270Sstevel@tonic-gate 	(*swtpp)->swt_n = *nswap;
1280Sstevel@tonic-gate 	for (i = 0; (i < (*nswap)); ++i)
1290Sstevel@tonic-gate 		(*swtpp)->swt_ent[i].ste_path = Zalloc(MAXPATHLEN);
1300Sstevel@tonic-gate 
1310Sstevel@tonic-gate 	/* get info */
1320Sstevel@tonic-gate 	if (((*nswap) = swapctl(SC_LIST, (*swtpp))) < 0) {
1330Sstevel@tonic-gate 		(void) mdsyserror(ep, errno, "swapctl(SC_LIST)");
1340Sstevel@tonic-gate 		free_swapinfo(*swtpp);
1350Sstevel@tonic-gate 		return (-1);
1360Sstevel@tonic-gate 	}
1370Sstevel@tonic-gate 
1380Sstevel@tonic-gate 	/* return success */
1390Sstevel@tonic-gate 	return (0);
1400Sstevel@tonic-gate }
1410Sstevel@tonic-gate 
1420Sstevel@tonic-gate /*
1430Sstevel@tonic-gate  * check whether device is swapped on
1440Sstevel@tonic-gate  */
1450Sstevel@tonic-gate static int
meta_check_swapped(mdsetname_t * sp,mdname_t * np,md_error_t * ep)1460Sstevel@tonic-gate meta_check_swapped(
1470Sstevel@tonic-gate 	mdsetname_t		*sp,
1480Sstevel@tonic-gate 	mdname_t		*np,
1490Sstevel@tonic-gate 	md_error_t		*ep
1500Sstevel@tonic-gate )
1510Sstevel@tonic-gate {
1520Sstevel@tonic-gate 	struct swaptable	*swtp;
1530Sstevel@tonic-gate 	int			nswap;
1540Sstevel@tonic-gate 	int			i;
1550Sstevel@tonic-gate 	int			rval = 0;
1560Sstevel@tonic-gate 
1570Sstevel@tonic-gate 	/* should have a set */
1580Sstevel@tonic-gate 	assert(sp != NULL);
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 	/* get swap info */
1610Sstevel@tonic-gate 	if (get_swapinfo(&swtp, &nswap, ep) != 0)
1620Sstevel@tonic-gate 		return (-1);
1630Sstevel@tonic-gate 
1640Sstevel@tonic-gate 	/* look for match */
1650Sstevel@tonic-gate 	for (i = 0; ((i < nswap) && (rval == 0)); ++i) {
1660Sstevel@tonic-gate 		mdname_t	*snp;
1670Sstevel@tonic-gate 
1680Sstevel@tonic-gate 		if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path,
1691623Stw21770 		    UNKNOWN, ep)) == NULL) {
1700Sstevel@tonic-gate 			mdclrerror(ep);
1710Sstevel@tonic-gate 			continue;
1720Sstevel@tonic-gate 		}
1730Sstevel@tonic-gate 		if (np->dev == snp->dev) {
1740Sstevel@tonic-gate 			rval = mddeverror(ep, MDE_IS_SWAPPED,
1750Sstevel@tonic-gate 			    np->dev, np->cname);
1760Sstevel@tonic-gate 		} else { /* not swap - does it overlap */
1770Sstevel@tonic-gate 			rval = meta_check_overlap(snp->cname, np, 0, -1,
1780Sstevel@tonic-gate 			    snp, 0, -1, ep);
1790Sstevel@tonic-gate 			if (rval != 0) {
1800Sstevel@tonic-gate 				(void) mdoverlaperror(ep, MDE_OVERLAP_SWAP,
181*9017SJohn.Wren.Kennedy@Sun.COM 				    np->cname, NULL, snp->cname);
1820Sstevel@tonic-gate 			}
1830Sstevel@tonic-gate 		}
1840Sstevel@tonic-gate 	}
1850Sstevel@tonic-gate 	free_swapinfo(swtp);
1860Sstevel@tonic-gate 
1870Sstevel@tonic-gate 	/* return success */
1880Sstevel@tonic-gate 	return (rval);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate /*
1920Sstevel@tonic-gate  * Is a driver currently swapped on?
1930Sstevel@tonic-gate  */
1940Sstevel@tonic-gate int
meta_check_driveswapped(mdsetname_t * sp,mddrivename_t * dnp,md_error_t * ep)1950Sstevel@tonic-gate meta_check_driveswapped(
1960Sstevel@tonic-gate 	mdsetname_t		*sp,
1970Sstevel@tonic-gate 	mddrivename_t		*dnp,
1980Sstevel@tonic-gate 	md_error_t		*ep
1990Sstevel@tonic-gate )
2000Sstevel@tonic-gate {
2010Sstevel@tonic-gate 	struct swaptable	*swtp;
2020Sstevel@tonic-gate 	int			nswap;
2030Sstevel@tonic-gate 	int			i;
2040Sstevel@tonic-gate 	int			rval = 0;
2050Sstevel@tonic-gate 
2060Sstevel@tonic-gate 	/* should have a set */
2070Sstevel@tonic-gate 	assert(sp != NULL);
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	/* get swap info */
2100Sstevel@tonic-gate 	if (get_swapinfo(&swtp, &nswap, ep) != 0)
2110Sstevel@tonic-gate 		return (-1);
2120Sstevel@tonic-gate 
2130Sstevel@tonic-gate 	/* look for match */
2140Sstevel@tonic-gate 	for (i = 0; (i < nswap); ++i) {
2150Sstevel@tonic-gate 		mdname_t	*snp;
2160Sstevel@tonic-gate 
2170Sstevel@tonic-gate 		if ((snp = metaname(&sp, swtp->swt_ent[i].ste_path,
2181623Stw21770 		    LOGICAL_DEVICE, ep)) == NULL) {
2190Sstevel@tonic-gate 			mdclrerror(ep);
2200Sstevel@tonic-gate 			continue;
2210Sstevel@tonic-gate 		}
2220Sstevel@tonic-gate 
2230Sstevel@tonic-gate 		if (strcmp(dnp->cname, snp->drivenamep->cname) == 0) {
2240Sstevel@tonic-gate 			rval = mddeverror(ep, MDE_IS_SWAPPED, NODEV64,
2250Sstevel@tonic-gate 			    dnp->cname);
2260Sstevel@tonic-gate 		}
2270Sstevel@tonic-gate 	}
2280Sstevel@tonic-gate 	free_swapinfo(swtp);
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	/* return success */
2310Sstevel@tonic-gate 	return (rval);
2320Sstevel@tonic-gate }
2330Sstevel@tonic-gate 
2340Sstevel@tonic-gate /*
2350Sstevel@tonic-gate  * check whether device is a dump device
2360Sstevel@tonic-gate  */
2370Sstevel@tonic-gate static int
meta_check_dump(mdsetname_t * sp,mdname_t * np,md_error_t * ep)2380Sstevel@tonic-gate meta_check_dump(
2390Sstevel@tonic-gate 	mdsetname_t	*sp,
2400Sstevel@tonic-gate 	mdname_t	*np,
2410Sstevel@tonic-gate 	md_error_t	*ep
2420Sstevel@tonic-gate )
2430Sstevel@tonic-gate {
2440Sstevel@tonic-gate 	int		rval = 0;
2450Sstevel@tonic-gate 	int		dump_fd;
2460Sstevel@tonic-gate 	char		device[MAXPATHLEN];
2470Sstevel@tonic-gate 
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	if ((dump_fd = open("/dev/dump", O_RDONLY)) < 0)
2500Sstevel@tonic-gate 		return (mdsyserror(ep, errno, "/dev/dump"));
2510Sstevel@tonic-gate 
2520Sstevel@tonic-gate 	if (ioctl(dump_fd, DIOCGETDEV, device) != -1) {
2530Sstevel@tonic-gate 		mdname_t	*dump_np;
2540Sstevel@tonic-gate 
2551623Stw21770 		if ((dump_np = metaname(&sp, device, UNKNOWN, ep)) == NULL) {
2560Sstevel@tonic-gate 			mdclrerror(ep);
2570Sstevel@tonic-gate 			(void) close(dump_fd);
2580Sstevel@tonic-gate 			return (0);
2590Sstevel@tonic-gate 		}
2600Sstevel@tonic-gate 
2610Sstevel@tonic-gate 		if (np->dev == dump_np->dev) {
2620Sstevel@tonic-gate 			rval = mddeverror(ep, MDE_IS_DUMP,
2630Sstevel@tonic-gate 			    np->dev, np->cname);
2640Sstevel@tonic-gate 		} else { /* not a dump device - but does it overlap? */
2650Sstevel@tonic-gate 			rval = meta_check_overlap(dump_np->cname, np, 0, -1,
2660Sstevel@tonic-gate 			    dump_np, 0, -1, ep);
2670Sstevel@tonic-gate 			if (rval != 0) {
2680Sstevel@tonic-gate 				(void) mdoverlaperror(ep, MDE_OVERLAP_DUMP,
269*9017SJohn.Wren.Kennedy@Sun.COM 				    np->cname, NULL, dump_np->cname);
2700Sstevel@tonic-gate 			}
2710Sstevel@tonic-gate 		}
2720Sstevel@tonic-gate 	}
2730Sstevel@tonic-gate 	(void) close(dump_fd);
2740Sstevel@tonic-gate 	return (rval);
2750Sstevel@tonic-gate }
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate /*
2780Sstevel@tonic-gate  * check whether device is mounted
2790Sstevel@tonic-gate  */
2800Sstevel@tonic-gate static int
meta_check_mounted(mdsetname_t * sp,mdname_t * np,md_error_t * ep)2810Sstevel@tonic-gate meta_check_mounted(
2820Sstevel@tonic-gate 	mdsetname_t	*sp,
2830Sstevel@tonic-gate 	mdname_t	*np,
2840Sstevel@tonic-gate 	md_error_t	*ep
2850Sstevel@tonic-gate )
2860Sstevel@tonic-gate {
2870Sstevel@tonic-gate 	FILE		*mfp;
2880Sstevel@tonic-gate 	struct mnttab	m;
2890Sstevel@tonic-gate 	int		rval = 0;
2900Sstevel@tonic-gate 	char		mountp[MNT_LINE_MAX];
2910Sstevel@tonic-gate 	char		mnt_special[MNT_LINE_MAX];
2920Sstevel@tonic-gate 
2930Sstevel@tonic-gate 	/* should have a set */
2940Sstevel@tonic-gate 	assert(sp != NULL);
2950Sstevel@tonic-gate 
2960Sstevel@tonic-gate 	/* look in mnttab */
2970Sstevel@tonic-gate 	if ((mfp = open_mnttab()) == NULL)
2980Sstevel@tonic-gate 		return (mdsyserror(ep, errno, MNTTAB));
2990Sstevel@tonic-gate 	while ((getmntent(mfp, &m) == 0) && (rval == 0)) {
300*9017SJohn.Wren.Kennedy@Sun.COM 		char		**fstype = skip_these_mntents;
301*9017SJohn.Wren.Kennedy@Sun.COM 		int		skipit = 0;
3020Sstevel@tonic-gate 		mdname_t	*mnp;
3030Sstevel@tonic-gate 
3040Sstevel@tonic-gate 		if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL))
3050Sstevel@tonic-gate 			continue;
3060Sstevel@tonic-gate 
3070Sstevel@tonic-gate 		if (m.mnt_mountp[0] != '/')
3080Sstevel@tonic-gate 			continue;
3090Sstevel@tonic-gate 
310*9017SJohn.Wren.Kennedy@Sun.COM 		while (*fstype != NULL)
311*9017SJohn.Wren.Kennedy@Sun.COM 			if (strcmp(m.mnt_fstype, *fstype++) == 0) {
312*9017SJohn.Wren.Kennedy@Sun.COM 				skipit++;
313*9017SJohn.Wren.Kennedy@Sun.COM 				break;
314*9017SJohn.Wren.Kennedy@Sun.COM 			}
315*9017SJohn.Wren.Kennedy@Sun.COM 
316*9017SJohn.Wren.Kennedy@Sun.COM 		if (skipit == 1)
3170Sstevel@tonic-gate 			continue;
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 		(void) strcpy(mountp, m.mnt_mountp);
3200Sstevel@tonic-gate 		(void) strcpy(mnt_special, m.mnt_special);
3210Sstevel@tonic-gate 
3221623Stw21770 		if ((mnp = metaname(&sp, mnt_special, UNKNOWN, ep)) == NULL) {
3230Sstevel@tonic-gate 			mdclrerror(ep);
3240Sstevel@tonic-gate 			continue;
3250Sstevel@tonic-gate 		}
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate 		if (np->dev == mnp->dev) {
3280Sstevel@tonic-gate 			rval = mduseerror(ep, MDE_IS_MOUNTED,
3290Sstevel@tonic-gate 			    np->dev, mountp, np->cname);
3300Sstevel@tonic-gate 		} else { /* device isn't in mnttab - does it overlap? */
3310Sstevel@tonic-gate 			rval = meta_check_overlap(mnp->cname, np, 0, -1,
3320Sstevel@tonic-gate 			    mnp, 0, -1, ep);
3330Sstevel@tonic-gate 			if (rval != 0) {
3340Sstevel@tonic-gate 				(void) mdoverlaperror(ep, MDE_OVERLAP_MOUNTED,
335*9017SJohn.Wren.Kennedy@Sun.COM 				    np->cname, mountp, mnp->cname);
3360Sstevel@tonic-gate 			}
3370Sstevel@tonic-gate 		}
3380Sstevel@tonic-gate 	}
3390Sstevel@tonic-gate 
3400Sstevel@tonic-gate 	/* return success */
3410Sstevel@tonic-gate 	return (rval);
3420Sstevel@tonic-gate }
3430Sstevel@tonic-gate 
3440Sstevel@tonic-gate 
3450Sstevel@tonic-gate /*
3460Sstevel@tonic-gate  * Is a file system currently mounted on this disk drive?
3470Sstevel@tonic-gate  */
3480Sstevel@tonic-gate int
meta_check_drivemounted(mdsetname_t * sp,mddrivename_t * dnp,md_error_t * ep)3490Sstevel@tonic-gate meta_check_drivemounted(
3500Sstevel@tonic-gate 	mdsetname_t	*sp,
3510Sstevel@tonic-gate 	mddrivename_t	*dnp,
3520Sstevel@tonic-gate 	md_error_t	*ep
3530Sstevel@tonic-gate )
3540Sstevel@tonic-gate {
3550Sstevel@tonic-gate 	FILE		*mfp;
3560Sstevel@tonic-gate 	struct mnttab	m;
3570Sstevel@tonic-gate 	int		rval = 0;
3580Sstevel@tonic-gate 	char		mountp[MNT_LINE_MAX];
3590Sstevel@tonic-gate 	char		mnt_special[MNT_LINE_MAX];
3600Sstevel@tonic-gate 
3610Sstevel@tonic-gate 	/* should have a set */
3620Sstevel@tonic-gate 	assert(sp != NULL);
3630Sstevel@tonic-gate 
3640Sstevel@tonic-gate 	/* look in mnttab */
3650Sstevel@tonic-gate 	if ((mfp = open_mnttab()) == NULL)
3660Sstevel@tonic-gate 		return (mdsyserror(ep, errno, MNTTAB));
3670Sstevel@tonic-gate 	while ((getmntent(mfp, &m) == 0) && (rval == 0)) {
368*9017SJohn.Wren.Kennedy@Sun.COM 		char		**fstype = skip_these_mntents;
369*9017SJohn.Wren.Kennedy@Sun.COM 		int		skipit = 0;
3700Sstevel@tonic-gate 		mdname_t	*mnp;
3710Sstevel@tonic-gate 
3720Sstevel@tonic-gate 		if ((m.mnt_special == NULL) || (m.mnt_mountp == NULL))
3730Sstevel@tonic-gate 			continue;
3740Sstevel@tonic-gate 
3750Sstevel@tonic-gate 		if (m.mnt_mountp[0] != '/')
3760Sstevel@tonic-gate 			continue;
3770Sstevel@tonic-gate 
378*9017SJohn.Wren.Kennedy@Sun.COM 		while (*fstype != NULL)
379*9017SJohn.Wren.Kennedy@Sun.COM 			if (strcmp(m.mnt_fstype, *fstype++) == 0) {
380*9017SJohn.Wren.Kennedy@Sun.COM 				skipit++;
381*9017SJohn.Wren.Kennedy@Sun.COM 				break;
382*9017SJohn.Wren.Kennedy@Sun.COM 			}
383*9017SJohn.Wren.Kennedy@Sun.COM 
384*9017SJohn.Wren.Kennedy@Sun.COM 		if (skipit == 1)
3850Sstevel@tonic-gate 			continue;
3860Sstevel@tonic-gate 
3870Sstevel@tonic-gate 		(void) strcpy(mountp, m.mnt_mountp);
3880Sstevel@tonic-gate 		(void) strcpy(mnt_special, m.mnt_special);
3891623Stw21770 		if ((mnp = metaname(&sp, mnt_special,
3901623Stw21770 		    LOGICAL_DEVICE, ep)) == NULL) {
3910Sstevel@tonic-gate 			mdclrerror(ep);
3920Sstevel@tonic-gate 			continue;
3930Sstevel@tonic-gate 		}
3940Sstevel@tonic-gate 		if (strcmp(dnp->cname, mnp->drivenamep->cname) == 0) {
3950Sstevel@tonic-gate 			rval = mduseerror(ep, MDE_IS_MOUNTED, NODEV64,
3960Sstevel@tonic-gate 			    mountp, dnp->cname);
3970Sstevel@tonic-gate 		}
3980Sstevel@tonic-gate 	}
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate 	/* return success */
4010Sstevel@tonic-gate 	return (rval);
4020Sstevel@tonic-gate }
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate /*
4050Sstevel@tonic-gate  * Check to see if the specified name is already in use or overlaps
4060Sstevel@tonic-gate  * with a device already in use. Checks are made to determine whether
4070Sstevel@tonic-gate  * the device is mounted, is a swap device, or a dump device.  In each
4080Sstevel@tonic-gate  * case if the device is not in use then an overlap check is done to ensure
4090Sstevel@tonic-gate  * that the specified slice does not overlap.
4100Sstevel@tonic-gate  */
4110Sstevel@tonic-gate int
meta_check_inuse(mdsetname_t * sp,mdname_t * np,mdinuseopts_t inuse_flags,md_error_t * ep)4120Sstevel@tonic-gate meta_check_inuse(
4130Sstevel@tonic-gate 	mdsetname_t	*sp,
4140Sstevel@tonic-gate 	mdname_t	*np,
4150Sstevel@tonic-gate 	mdinuseopts_t	inuse_flags,
4160Sstevel@tonic-gate 	md_error_t	*ep
4170Sstevel@tonic-gate )
4180Sstevel@tonic-gate {
4190Sstevel@tonic-gate 	int			rval = 0;
4200Sstevel@tonic-gate 
4210Sstevel@tonic-gate 	if ((inuse_flags & MDCHK_MOUNTED) &&
4220Sstevel@tonic-gate 	    (rval = meta_check_mounted(sp, np, ep)) != 0)
4230Sstevel@tonic-gate 		return (rval);
4240Sstevel@tonic-gate 
4250Sstevel@tonic-gate 	if ((inuse_flags & MDCHK_SWAP) &&
4260Sstevel@tonic-gate 	    (rval = meta_check_swapped(sp, np, ep)) != 0)
4270Sstevel@tonic-gate 		return (rval);
4280Sstevel@tonic-gate 
4290Sstevel@tonic-gate 	if ((inuse_flags & MDCHK_DUMP) &&
4300Sstevel@tonic-gate 	    (rval = meta_check_dump(sp, np, ep)) != 0)
4310Sstevel@tonic-gate 		return (rval);
4320Sstevel@tonic-gate 
4330Sstevel@tonic-gate 	return (rval);
4340Sstevel@tonic-gate }
4350Sstevel@tonic-gate 
4360Sstevel@tonic-gate int
meta_check_driveinset(mdsetname_t * sp,mddrivename_t * dn,md_error_t * ep)4370Sstevel@tonic-gate meta_check_driveinset(mdsetname_t *sp, mddrivename_t *dn, md_error_t *ep)
4380Sstevel@tonic-gate {
4390Sstevel@tonic-gate 	set_t		setno;
4400Sstevel@tonic-gate 	set_t		max_sets;
4410Sstevel@tonic-gate 
4420Sstevel@tonic-gate 	if ((max_sets = get_max_sets(ep)) == 0)
4430Sstevel@tonic-gate 		return (-1);
4440Sstevel@tonic-gate 
4450Sstevel@tonic-gate 	for (setno = 1; setno < max_sets; setno++) {
4460Sstevel@tonic-gate 		mdsetname_t	*sp1;
4470Sstevel@tonic-gate 		int		is_it;
4480Sstevel@tonic-gate 
4490Sstevel@tonic-gate 		if (setno == sp->setno)
4500Sstevel@tonic-gate 			continue;
4510Sstevel@tonic-gate 
4520Sstevel@tonic-gate 		if ((sp1 = metasetnosetname(setno, ep)) == NULL) {
4530Sstevel@tonic-gate 			if (mdismddberror(ep, MDE_DB_NODB)) {
4540Sstevel@tonic-gate 				mdclrerror(ep);
4550Sstevel@tonic-gate 				return (0);
4560Sstevel@tonic-gate 			}
4570Sstevel@tonic-gate 			if (mdiserror(ep, MDE_NO_SET)) {
4580Sstevel@tonic-gate 				mdclrerror(ep);
4590Sstevel@tonic-gate 				continue;
4600Sstevel@tonic-gate 			}
4610Sstevel@tonic-gate 			return (-1);
4620Sstevel@tonic-gate 		}
4630Sstevel@tonic-gate 
4640Sstevel@tonic-gate 		metaflushsetname(sp1);
4650Sstevel@tonic-gate 
4660Sstevel@tonic-gate 		if ((is_it = meta_is_drive_in_thisset(sp1, dn, FALSE, ep))
4670Sstevel@tonic-gate 		    == -1)
4680Sstevel@tonic-gate 			return (-1);
4690Sstevel@tonic-gate 
4700Sstevel@tonic-gate 		if (is_it)
4710Sstevel@tonic-gate 			return (mddserror(ep, MDE_DS_DRIVEINSET, sp->setno,
4720Sstevel@tonic-gate 			    sp1->setname, dn->cname, sp->setname));
4730Sstevel@tonic-gate 	}
4740Sstevel@tonic-gate 
4750Sstevel@tonic-gate 	return (0);
4760Sstevel@tonic-gate }
4770Sstevel@tonic-gate 
4780Sstevel@tonic-gate /*
4790Sstevel@tonic-gate  * Add a device/device id tuple to the devname cache
4800Sstevel@tonic-gate  */
4810Sstevel@tonic-gate static void
add_to_devname_list(char * device_name,ddi_devid_t devid)4820Sstevel@tonic-gate add_to_devname_list(
4830Sstevel@tonic-gate 	char 		*device_name,		/* fully qualified dev name */
4840Sstevel@tonic-gate 	ddi_devid_t	devid			/* device id */
4850Sstevel@tonic-gate )
4860Sstevel@tonic-gate {
4870Sstevel@tonic-gate 	dev_list_t	*dnlp;
4880Sstevel@tonic-gate 
4890Sstevel@tonic-gate 	dnlp = Zalloc(sizeof (*dnlp));
4900Sstevel@tonic-gate 	dnlp->dev_name = Strdup(device_name);
4910Sstevel@tonic-gate 	dnlp->devid = devid;
4920Sstevel@tonic-gate 
4930Sstevel@tonic-gate 	/* link the node into the devname list */
4940Sstevel@tonic-gate 	dnlp->dev_nxt = devnamelist;
4950Sstevel@tonic-gate 	devnamelist = dnlp;
4960Sstevel@tonic-gate }
4970Sstevel@tonic-gate 
4980Sstevel@tonic-gate /*
4990Sstevel@tonic-gate  * check for same drive
500127Shshaw  *
501127Shshaw  * Differentiate between matching on name/dev_t and devid.  In the latter
502127Shshaw  * case it is correct to fail but misleading to give the same error msg as
503127Shshaw  * for an overlapping slice.
504127Shshaw  *
5050Sstevel@tonic-gate  */
5060Sstevel@tonic-gate int
meta_check_samedrive(mdname_t * np1,mdname_t * np2,md_error_t * ep)5070Sstevel@tonic-gate meta_check_samedrive(
5080Sstevel@tonic-gate 	mdname_t	*np1,		/* first comp */
5090Sstevel@tonic-gate 	mdname_t	*np2,		/* second comp */
5100Sstevel@tonic-gate 	md_error_t	*ep
5110Sstevel@tonic-gate )
5120Sstevel@tonic-gate {
5130Sstevel@tonic-gate 
5140Sstevel@tonic-gate 	mdcinfo_t	*cinfop1, *cinfop2;
5150Sstevel@tonic-gate 	mdnmtype_t	type1 = np1->drivenamep->type;
5160Sstevel@tonic-gate 	mdnmtype_t	type2 = np2->drivenamep->type;
5170Sstevel@tonic-gate 	int		l = 0;
5180Sstevel@tonic-gate 
5190Sstevel@tonic-gate 	char		*name1 = NULL;
5200Sstevel@tonic-gate 	char		*name2 = NULL;
5210Sstevel@tonic-gate 
522127Shshaw 	int		retval = CANT_TELL;
5230Sstevel@tonic-gate 	int		fd1 = -1;
5240Sstevel@tonic-gate 	int		fd2 = -1;
5250Sstevel@tonic-gate 	int		rc1 = -2, rc2 = -2;
5260Sstevel@tonic-gate 	uint_t		strl1 = 0, strl2 = 0;
5270Sstevel@tonic-gate 	int		devid1_found = 0;
5280Sstevel@tonic-gate 	int		devid2_found = 0;
5290Sstevel@tonic-gate 
5300Sstevel@tonic-gate 	ddi_devid_t	devid1 = NULL;
5310Sstevel@tonic-gate 	ddi_devid_t	devid2 = NULL;
5320Sstevel@tonic-gate 	dev_list_t	*dnlp = NULL;
5330Sstevel@tonic-gate 
5340Sstevel@tonic-gate 	assert(type1 != MDT_FAST_META && type1 != MDT_FAST_COMP);
5350Sstevel@tonic-gate 	assert(type2 != MDT_FAST_META && type2 != MDT_FAST_COMP);
5360Sstevel@tonic-gate 
5370Sstevel@tonic-gate 	/*
5380Sstevel@tonic-gate 	 * The process of determining if 2 names are the same drive is
5390Sstevel@tonic-gate 	 * as follows:
5400Sstevel@tonic-gate 	 *
5410Sstevel@tonic-gate 	 * Case 1 - The filenames are identical
5420Sstevel@tonic-gate 	 *
5431623Stw21770 	 * Case 2 - Both devices have a devid
5440Sstevel@tonic-gate 	 * 	get and compare the devids for the devices. If both
5450Sstevel@tonic-gate 	 * 	devices have a devid then the compare will is all
5460Sstevel@tonic-gate 	 *	that is needed we are done.
5470Sstevel@tonic-gate 	 *
5481623Stw21770 	 * Case 3 - One or more devices does not have a devid
5490Sstevel@tonic-gate 	 *	start by doing a simple compare of the name, if they
5500Sstevel@tonic-gate 	 *	are the same just return.
5510Sstevel@tonic-gate 	 *
5520Sstevel@tonic-gate 	 *	If the names differ then keep going and see if the
5530Sstevel@tonic-gate 	 *	may be the same underlying devic.  First check to
5540Sstevel@tonic-gate 	 *	see if the sd name is the same (old code).
5550Sstevel@tonic-gate 	 *
5560Sstevel@tonic-gate 	 *	Then check the major and minor numbers to see if
5570Sstevel@tonic-gate 	 *	they are the same.  If they are then return (old code).
5580Sstevel@tonic-gate 	 *
5590Sstevel@tonic-gate 	 *	Next compare the raw name and the component name and
5600Sstevel@tonic-gate 	 *	if they are the same then return.
5610Sstevel@tonic-gate 	 *
5620Sstevel@tonic-gate 	 *	All else has failed so use the component name (cname)
5630Sstevel@tonic-gate 	 *	component number and unit number.  If they all are
5640Sstevel@tonic-gate 	 *	equal then call them the same drive.
5650Sstevel@tonic-gate 	 *
5660Sstevel@tonic-gate 	 */
5670Sstevel@tonic-gate 
5680Sstevel@tonic-gate 	if ((np1 == NULL) || (np2 == NULL))
569127Shshaw 		return (NOT_SAMEDRIVE);
5700Sstevel@tonic-gate 
5710Sstevel@tonic-gate 	/* if the name structs are the same then the drives must be */
5720Sstevel@tonic-gate 	if (np1 == np2)
573127Shshaw 		return (IDENTICAL_NAME_DEVT);
5740Sstevel@tonic-gate 
5750Sstevel@tonic-gate 	name1 = np1->bname;
5760Sstevel@tonic-gate 	name2 = np2->bname;
5770Sstevel@tonic-gate 
5780Sstevel@tonic-gate 	if ((name1 == NULL) || ((strl1 = strlen(name1)) == 0) ||
5790Sstevel@tonic-gate 	    (name2 == NULL) || ((strl2 = strlen(name2)) == 0))
580127Shshaw 		return (NOT_SAMEDRIVE);
5810Sstevel@tonic-gate 
5820Sstevel@tonic-gate 	if ((strl1 == strl2) && (strcmp(name1, name2) == 0)) {
5830Sstevel@tonic-gate 		/* names are identical */
584127Shshaw 		return (IDENTICAL_NAME_DEVT);
5850Sstevel@tonic-gate 	}
5860Sstevel@tonic-gate 
5870Sstevel@tonic-gate 	if (is_metaname(name1) || is_metaname(name2))
588127Shshaw 		return (NOT_SAMEDRIVE);
5890Sstevel@tonic-gate 
5900Sstevel@tonic-gate 	/*
5910Sstevel@tonic-gate 	 * Check to see if the devicename is in the static list.  If so,
5920Sstevel@tonic-gate 	 * use its devid.  Otherwise do the expensive operations
5930Sstevel@tonic-gate 	 * of opening the device, getting the devid, and closing the
5940Sstevel@tonic-gate 	 * device.  Add the result into the static list.
5950Sstevel@tonic-gate 	 *
5960Sstevel@tonic-gate 	 * The case where this list will be useful is when there are soft
5970Sstevel@tonic-gate 	 * partitions on multiple drives and a new soft partition is being
5980Sstevel@tonic-gate 	 * created.  In that situation the underlying physical device name
5990Sstevel@tonic-gate 	 * for the new soft partition would be compared against each of the
6000Sstevel@tonic-gate 	 * existing soft partititions.  Without this static list that would
6010Sstevel@tonic-gate 	 * involve 2 opens, closes, and devid gets for each existing soft
6020Sstevel@tonic-gate 	 * partition
6030Sstevel@tonic-gate 	 */
604*9017SJohn.Wren.Kennedy@Sun.COM 	for (dnlp = devnamelist; (dnlp != NULL) &&
605*9017SJohn.Wren.Kennedy@Sun.COM 	    !(devid1_found && devid2_found); dnlp = dnlp->dev_nxt) {
6060Sstevel@tonic-gate 		if (!devid1_found && (strcmp(dnlp->dev_name, name1) == 0)) {
6070Sstevel@tonic-gate 			devid1_found = 1;
6080Sstevel@tonic-gate 			devid1 = dnlp->devid;
6090Sstevel@tonic-gate 			if (devid1 == NULL)
6100Sstevel@tonic-gate 				rc1 = 1;
6110Sstevel@tonic-gate 			else
6120Sstevel@tonic-gate 				rc1 = 0;
6130Sstevel@tonic-gate 			continue;
6140Sstevel@tonic-gate 		}
6150Sstevel@tonic-gate 		if (!devid2_found && (strcmp(dnlp->dev_name, name2) == 0)) {
6160Sstevel@tonic-gate 			devid2_found = 1;
6170Sstevel@tonic-gate 			devid2 = dnlp->devid;
6180Sstevel@tonic-gate 			if (devid2 == NULL)
6190Sstevel@tonic-gate 				rc2 = 1;
6200Sstevel@tonic-gate 			else
6210Sstevel@tonic-gate 				rc2 = 0;
6220Sstevel@tonic-gate 			continue;
6230Sstevel@tonic-gate 		}
6240Sstevel@tonic-gate 	}
6250Sstevel@tonic-gate 
6260Sstevel@tonic-gate 	/*
6270Sstevel@tonic-gate 	 * Start by checking if the device has a device id, and if they
6280Sstevel@tonic-gate 	 * are equal.  If they are there is no question there is a match.
6290Sstevel@tonic-gate 	 *
6300Sstevel@tonic-gate 	 * The process here is open each disk, get the devid for each
6310Sstevel@tonic-gate 	 * disk.  If they both have a devid compare them and return
6320Sstevel@tonic-gate 	 * the results.
6330Sstevel@tonic-gate 	 */
6340Sstevel@tonic-gate 	if (!devid1_found) {
6350Sstevel@tonic-gate 		if ((fd1 = open(name1, O_RDONLY | O_NDELAY)) < 0) {
636127Shshaw 			return (NOT_SAMEDRIVE);
6370Sstevel@tonic-gate 		}
6380Sstevel@tonic-gate 		rc1 = devid_get(fd1, &devid1);
6390Sstevel@tonic-gate 		(void) close(fd1);
6400Sstevel@tonic-gate 
6410Sstevel@tonic-gate 		/* add the name and devid to the cache */
6420Sstevel@tonic-gate 		add_to_devname_list(name1, devid1);
6430Sstevel@tonic-gate 	}
6440Sstevel@tonic-gate 
6450Sstevel@tonic-gate 	if (!devid2_found) {
6460Sstevel@tonic-gate 		if ((fd2 = open(name2, O_RDONLY | O_NDELAY)) < 0) {
647127Shshaw 			return (NOT_SAMEDRIVE);
6480Sstevel@tonic-gate 		}
6490Sstevel@tonic-gate 		rc2 = devid_get(fd2, &devid2);
6500Sstevel@tonic-gate 		(void) close(fd2);
6510Sstevel@tonic-gate 
6520Sstevel@tonic-gate 		/* add the name and devid to the cache */
6530Sstevel@tonic-gate 		add_to_devname_list(name2, devid2);
6540Sstevel@tonic-gate 	}
6550Sstevel@tonic-gate 
6560Sstevel@tonic-gate 
6570Sstevel@tonic-gate 	if ((rc1 == 0) && (rc2 == 0)) {
6580Sstevel@tonic-gate 		if (devid_compare(devid1, devid2) == 0)
659127Shshaw 			retval = IDENTICAL_DEVIDS; /* same devid */
6600Sstevel@tonic-gate 		else
661127Shshaw 			retval = NOT_SAMEDRIVE; /* different drives */
6620Sstevel@tonic-gate 
6630Sstevel@tonic-gate 	}
6640Sstevel@tonic-gate 
6650Sstevel@tonic-gate 	if (retval >= 0) {
6660Sstevel@tonic-gate 		return (retval);
6670Sstevel@tonic-gate 	}
6680Sstevel@tonic-gate 
6690Sstevel@tonic-gate 	/*
6700Sstevel@tonic-gate 	 * At this point in time one of the two drives did not have a
6710Sstevel@tonic-gate 	 * device ID.  Do not make the assumption that is one drive
6720Sstevel@tonic-gate 	 * did have a device id and the other did not that they are not
6730Sstevel@tonic-gate 	 * the same.  One drive could be covered by a device and still
6740Sstevel@tonic-gate 	 * be the same drive.  This is a general flaw in the system at
6750Sstevel@tonic-gate 	 * this time.
6760Sstevel@tonic-gate 	 */
6770Sstevel@tonic-gate 
6780Sstevel@tonic-gate 	/*
6790Sstevel@tonic-gate 	 * The optimization can not happen if we are given an old style name
6800Sstevel@tonic-gate 	 * in the form /dev/XXNN[a-h], since the name caches differently and
6810Sstevel@tonic-gate 	 * allows overlaps to happen.
6820Sstevel@tonic-gate 	 */
6830Sstevel@tonic-gate 	if (! ((sscanf(np1->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 &&
6840Sstevel@tonic-gate 	    l == strlen(np1->bname)) ||
6850Sstevel@tonic-gate 	    (sscanf(np2->bname, "/dev/%*[^0-9/]%*u%*[a-h]%n", &l) == 0 &&
6860Sstevel@tonic-gate 	    l == strlen(np2->bname))) &&
6870Sstevel@tonic-gate 	    ((type1 == MDT_COMP) || (type1 == MDT_META)) &&
6880Sstevel@tonic-gate 	    ((type2 == MDT_COMP) || (type2 == MDT_META)))
689127Shshaw 		if (np1->drivenamep == np2->drivenamep)
690127Shshaw 			return (IDENTICAL_NAME_DEVT);
691127Shshaw 		else
692127Shshaw 			return (NOT_SAMEDRIVE);
6930Sstevel@tonic-gate 
6940Sstevel@tonic-gate 	/* check for same drive */
6950Sstevel@tonic-gate 	if (meta_getmajor(np1->dev) != meta_getmajor(np2->dev))
696127Shshaw 		return (NOT_SAMEDRIVE);		/* not same drive */
6970Sstevel@tonic-gate 
6980Sstevel@tonic-gate 	if (((cinfop1 = metagetcinfo(np1, ep)) == NULL) ||
6990Sstevel@tonic-gate 	    ((cinfop2 = metagetcinfo(np2, ep)) == NULL)) {
7000Sstevel@tonic-gate 		if ((strcmp(np1->drivenamep->cname,
7010Sstevel@tonic-gate 		    np2->drivenamep->cname) != 0) &&
7020Sstevel@tonic-gate 		    (strcmp(np1->drivenamep->rname,
7030Sstevel@tonic-gate 		    np2->drivenamep->rname) != 0)) {
7040Sstevel@tonic-gate 			mdclrerror(ep);
705127Shshaw 			return (NOT_SAMEDRIVE);	/* not same drive */
7060Sstevel@tonic-gate 		} else {
707127Shshaw 			return (CANT_TELL);	/* can't tell */
7080Sstevel@tonic-gate 		}
7090Sstevel@tonic-gate 	} else if ((strncmp(cinfop1->cname, cinfop2->cname,
7100Sstevel@tonic-gate 	    sizeof (cinfop1->cname)) != 0) ||
7110Sstevel@tonic-gate 	    (cinfop1->cnum != cinfop2->cnum) ||
7120Sstevel@tonic-gate 	    (cinfop1->unit != cinfop2->unit)) {
713127Shshaw 		return (NOT_SAMEDRIVE);		/* not same drive */
7140Sstevel@tonic-gate 	}
7150Sstevel@tonic-gate 
7160Sstevel@tonic-gate 	/* same drive */
717127Shshaw 	return (IDENTICAL_NAME_DEVT);
7180Sstevel@tonic-gate }
7190Sstevel@tonic-gate 
7200Sstevel@tonic-gate /*
7210Sstevel@tonic-gate  * check for overlap
7220Sstevel@tonic-gate  */
7230Sstevel@tonic-gate int
meta_check_overlap(char * uname,mdname_t * np1,diskaddr_t slblk1,diskaddr_t nblks1,mdname_t * np2,diskaddr_t slblk2,diskaddr_t nblks2,md_error_t * ep)7240Sstevel@tonic-gate meta_check_overlap(
7250Sstevel@tonic-gate 	char		*uname,		/* user supplied name for errors */
7260Sstevel@tonic-gate 	mdname_t	*np1,		/* first comp */
7270Sstevel@tonic-gate 	diskaddr_t	slblk1,		/* first comp - start logical block */
7280Sstevel@tonic-gate 	diskaddr_t	nblks1,		/* first comp - # of blocks */
7290Sstevel@tonic-gate 	mdname_t	*np2,		/* second comp */
7300Sstevel@tonic-gate 	diskaddr_t	slblk2,		/* second comp - start logical block */
7310Sstevel@tonic-gate 	diskaddr_t	nblks2,		/* second comp - # of blocks */
7320Sstevel@tonic-gate 	md_error_t	*ep
7330Sstevel@tonic-gate )
7340Sstevel@tonic-gate {
7350Sstevel@tonic-gate 	diskaddr_t	sblk1, sblk2;
7360Sstevel@tonic-gate 	mdvtoc_t	*vtocp1, *vtocp2;
7370Sstevel@tonic-gate 	uint_t		partno1, partno2;
7380Sstevel@tonic-gate 	mdpart_t	*partp1, *partp2;
739127Shshaw 	int		ret;
7400Sstevel@tonic-gate 
7410Sstevel@tonic-gate 	/* verify args */
7420Sstevel@tonic-gate 	if (slblk1 == MD_DISKADDR_ERROR) {
7430Sstevel@tonic-gate 		assert(0);
7440Sstevel@tonic-gate 		return (mdsyserror(ep, EINVAL, np1->cname));
7450Sstevel@tonic-gate 	}
7460Sstevel@tonic-gate 	if (slblk2 == MD_DISKADDR_ERROR) {
7470Sstevel@tonic-gate 		assert(0);
7480Sstevel@tonic-gate 		return (mdsyserror(ep, EINVAL, np2->cname));
7490Sstevel@tonic-gate 	}
7500Sstevel@tonic-gate 
7510Sstevel@tonic-gate 	/* check for same drive */
752127Shshaw 	if ((ret = meta_check_samedrive(np1, np2, ep)) == 0) {
7530Sstevel@tonic-gate 		return (0);			/* not same drive */
754127Shshaw 	} else if (ret < 0) {
7550Sstevel@tonic-gate 		return (-1);			/* can't tell */
7560Sstevel@tonic-gate 	}
7570Sstevel@tonic-gate 
7580Sstevel@tonic-gate 	/* check for overlap */
7590Sstevel@tonic-gate 	if (((vtocp1 = metagetvtoc(np1, FALSE, &partno1, ep)) == NULL) ||
7600Sstevel@tonic-gate 	    ((vtocp2 = metagetvtoc(np2, FALSE, &partno2, ep)) == NULL)) {
7610Sstevel@tonic-gate 		return (-1);			/* can't tell */
7620Sstevel@tonic-gate 	}
7630Sstevel@tonic-gate 	partp1 = &vtocp1->parts[partno1];
7640Sstevel@tonic-gate 	partp2 = &vtocp2->parts[partno2];
7650Sstevel@tonic-gate 	sblk1 = partp1->start + slblk1;
7660Sstevel@tonic-gate 	if (nblks1 == -1)
7670Sstevel@tonic-gate 		nblks1 = partp1->size - slblk1;
7680Sstevel@tonic-gate 	sblk2 = partp2->start + slblk2;
7690Sstevel@tonic-gate 	if (nblks2 == -1)
7700Sstevel@tonic-gate 		nblks2 = partp2->size - slblk2;
7710Sstevel@tonic-gate 	if (((sblk1 >= sblk2) && (sblk1 < (sblk2 + nblks2))) ||
7720Sstevel@tonic-gate 	    ((sblk2 >= sblk1) && (sblk2 < (sblk1 + nblks1)))) {
7730Sstevel@tonic-gate 		if (np1->dev == np2->dev) {	/* slice in use */
7740Sstevel@tonic-gate 			return (mduseerror(ep, MDE_ALREADY, np1->dev,
7750Sstevel@tonic-gate 			    uname, np1->cname));
7760Sstevel@tonic-gate 		}
777127Shshaw 		if (ret == IDENTICAL_NAME_DEVT)
778*9017SJohn.Wren.Kennedy@Sun.COM 			return (mduseerror(ep,		/* slice overlaps */
779*9017SJohn.Wren.Kennedy@Sun.COM 			    MDE_OVERLAP, np1->dev, uname, np1->cname));
780127Shshaw 		else
781*9017SJohn.Wren.Kennedy@Sun.COM 			return (mduseerror(ep,		/* same devid */
782*9017SJohn.Wren.Kennedy@Sun.COM 			    MDE_SAME_DEVID, np1->dev, uname, np2->cname));
7830Sstevel@tonic-gate 	}
7840Sstevel@tonic-gate 
7850Sstevel@tonic-gate 	/* return success */
7860Sstevel@tonic-gate 	return (0);				/* no overlap */
7870Sstevel@tonic-gate }
7880Sstevel@tonic-gate 
7890Sstevel@tonic-gate /*
7900Sstevel@tonic-gate  * check to see if a device is in a metadevice
7910Sstevel@tonic-gate  */
7920Sstevel@tonic-gate int
meta_check_inmeta(mdsetname_t * sp,mdname_t * np,mdchkopts_t options,diskaddr_t slblk,diskaddr_t nblks,md_error_t * ep)7930Sstevel@tonic-gate meta_check_inmeta(
7940Sstevel@tonic-gate 	mdsetname_t	*sp,
7950Sstevel@tonic-gate 	mdname_t	*np,
7960Sstevel@tonic-gate 	mdchkopts_t	options,
7970Sstevel@tonic-gate 	diskaddr_t	slblk,
7980Sstevel@tonic-gate 	diskaddr_t	nblks,
7990Sstevel@tonic-gate 	md_error_t	*ep
8000Sstevel@tonic-gate )
8010Sstevel@tonic-gate {
8020Sstevel@tonic-gate 	uint_t		partno;
8030Sstevel@tonic-gate 
8040Sstevel@tonic-gate 	/* see if replica slice is ok, only applies to disks in sets */
8050Sstevel@tonic-gate 	if (! (options & MDCHK_ALLOW_REPSLICE) &&
8060Sstevel@tonic-gate 	    ! metaislocalset(sp)) {
8070Sstevel@tonic-gate 		uint_t	rep_slice;
8080Sstevel@tonic-gate 
8090Sstevel@tonic-gate 		if (metagetvtoc(np, FALSE, &partno, ep) == NULL)
8100Sstevel@tonic-gate 			return (-1);
8110Sstevel@tonic-gate 		if (meta_replicaslice(np->drivenamep, &rep_slice, ep)
8120Sstevel@tonic-gate 		    != 0)
8130Sstevel@tonic-gate 			return (-1);
8140Sstevel@tonic-gate 		if (partno == rep_slice)
8150Sstevel@tonic-gate 			return (mddeverror(ep, MDE_REPCOMP_INVAL, np->dev,
8160Sstevel@tonic-gate 			    np->cname));
8170Sstevel@tonic-gate 	}
8180Sstevel@tonic-gate 
8190Sstevel@tonic-gate 	/* check for databases */
8200Sstevel@tonic-gate 	if (meta_check_inreplica(sp, np, slblk, nblks, ep) != 0) {
8210Sstevel@tonic-gate 		if (mdisuseerror(ep, MDE_ALREADY)) {
8220Sstevel@tonic-gate 			if (options & MDCHK_ALLOW_MDDB) {
8230Sstevel@tonic-gate 				mdclrerror(ep);
8240Sstevel@tonic-gate 			} else {
8250Sstevel@tonic-gate 				return (mddeverror(ep, MDE_HAS_MDDB,
8260Sstevel@tonic-gate 				    np->dev, np->cname));
8270Sstevel@tonic-gate 			}
8280Sstevel@tonic-gate 		} else {
8290Sstevel@tonic-gate 			return (-1);
8300Sstevel@tonic-gate 		}
8310Sstevel@tonic-gate 	}
8320Sstevel@tonic-gate 
8330Sstevel@tonic-gate 	/* check metadevices */
8340Sstevel@tonic-gate 	if (meta_check_instripe(sp, np, slblk, nblks, ep) != 0)
8350Sstevel@tonic-gate 		return (-1);
8360Sstevel@tonic-gate 	if (meta_check_inmirror(sp, np, slblk, nblks, ep) != 0)
8370Sstevel@tonic-gate 		return (-1);
8380Sstevel@tonic-gate 	if (meta_check_intrans(sp, np, options, slblk, nblks, ep) != 0)
8390Sstevel@tonic-gate 		return (-1);
8400Sstevel@tonic-gate 	if (meta_check_insp(sp, np, slblk, nblks, ep) != 0)
8410Sstevel@tonic-gate 		return (-1);
8420Sstevel@tonic-gate 	if (! (options & MDCHK_ALLOW_HS)) {
8430Sstevel@tonic-gate 		if (meta_check_inhsp(sp, np, slblk, nblks, ep) != 0)
8440Sstevel@tonic-gate 			return (-1);
8450Sstevel@tonic-gate 	}
8460Sstevel@tonic-gate 	if (meta_check_inraid(sp, np, slblk, nblks, ep) != 0)
8470Sstevel@tonic-gate 		return (-1);
8480Sstevel@tonic-gate 
8490Sstevel@tonic-gate 	/* return success */
8500Sstevel@tonic-gate 	return (0);
8510Sstevel@tonic-gate }
8520Sstevel@tonic-gate 
8530Sstevel@tonic-gate /*
8540Sstevel@tonic-gate  * check to see if a device is in its set
8550Sstevel@tonic-gate  */
8560Sstevel@tonic-gate int
meta_check_inset(mdsetname_t * sp,mdname_t * np,md_error_t * ep)8570Sstevel@tonic-gate meta_check_inset(
8580Sstevel@tonic-gate 	mdsetname_t	*sp,
8590Sstevel@tonic-gate 	mdname_t	*np,
8600Sstevel@tonic-gate 	md_error_t	*ep
8610Sstevel@tonic-gate )
8620Sstevel@tonic-gate {
8630Sstevel@tonic-gate 	mdsetname_t	*npsp;
8640Sstevel@tonic-gate 	int		bypass_daemon = FALSE;
8650Sstevel@tonic-gate 
8660Sstevel@tonic-gate 
8670Sstevel@tonic-gate 	/* check devices set */
8680Sstevel@tonic-gate 	if (metaislocalset(sp))
8690Sstevel@tonic-gate 		bypass_daemon = TRUE;
8700Sstevel@tonic-gate 	if ((npsp = metagetset(np, bypass_daemon, ep)) == NULL) {
8710Sstevel@tonic-gate 		if ((! metaismeta(np)) &&
8720Sstevel@tonic-gate 		    (metaislocalset(sp)) &&
8730Sstevel@tonic-gate 		    (mdismddberror(ep, MDE_DB_NODB))) {
8740Sstevel@tonic-gate 			mdclrerror(ep);
8750Sstevel@tonic-gate 			npsp = sp;
8760Sstevel@tonic-gate 		} else {
8770Sstevel@tonic-gate 			return (-1);
8780Sstevel@tonic-gate 		}
8790Sstevel@tonic-gate 	}
8800Sstevel@tonic-gate 
8810Sstevel@tonic-gate 	/* check set */
8820Sstevel@tonic-gate 	if (metaissameset(sp, npsp))
8830Sstevel@tonic-gate 		return (0);
8840Sstevel@tonic-gate 
8850Sstevel@tonic-gate 	/* return appropriate error */
8860Sstevel@tonic-gate 	if (metaislocalset(sp))
8870Sstevel@tonic-gate 		return (mddeverror(ep, MDE_IN_SHARED_SET, np->dev, np->cname));
8880Sstevel@tonic-gate 	else
8890Sstevel@tonic-gate 		return (mddeverror(ep, MDE_NOT_IN_SET, np->dev, np->cname));
8900Sstevel@tonic-gate }
8910Sstevel@tonic-gate 
8920Sstevel@tonic-gate /*
8930Sstevel@tonic-gate  * check to see if current user is root
8940Sstevel@tonic-gate  */
8950Sstevel@tonic-gate int
meta_check_root(md_error_t * ep)8960Sstevel@tonic-gate meta_check_root(md_error_t *ep)
8970Sstevel@tonic-gate {
8980Sstevel@tonic-gate 	if (geteuid() != 0) {
8990Sstevel@tonic-gate 		(void) mderror(ep, MDE_NOPERM, "");
9000Sstevel@tonic-gate 		return (-1);
9010Sstevel@tonic-gate 	}
9020Sstevel@tonic-gate 	return (0);
9030Sstevel@tonic-gate }
904