/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
* Copyright 2015 Nexenta Systems, Inc. All rights reserved.
*/
/*
* Just in case we're not in a build environment, make sure that
* TEXT_DOMAIN gets set to something.
*/
#if !defined(TEXT_DOMAIN)
#endif
/*
* check componets
*/
#include <meta.h>
#include "meta_lib_prv.h"
#include <devid.h>
/* possible returns from meta_check_samedrive */
#define NOT_SAMEDRIVE 0
/*
* static list(s)
*/
typedef struct dev_list {
char *dev_name;
} dev_list_t;
static char *skip_these_mntents[] = {
"nfs",
"autofs",
"proc",
"tmpfs",
"rfs",
"fd",
"mntfs",
"lofs",
"devfs",
"dev",
"ctfs",
"objfs",
"sharefs",
};
/*
* free swap info
*/
static void
)
{
int i;
return;
}
}
/*
* get swap info
*/
static int
int *nswap,
)
{
int i;
/* get number of entries */
}
/* allocate structure */
for (i = 0; (i < (*nswap)); ++i)
/* get info */
return (-1);
}
/* return success */
return (0);
}
/*
* check whether device is swapped on
*/
static int
)
{
int nswap;
int i;
int rval = 0;
/* should have a set */
/* get swap info */
return (-1);
/* look for match */
mdclrerror(ep);
continue;
}
} else { /* not swap - does it overlap */
if (rval != 0) {
}
}
}
/* return success */
return (rval);
}
/*
* Is a driver currently swapped on?
*/
int
)
{
int nswap;
int i;
int rval = 0;
/* should have a set */
/* get swap info */
return (-1);
/* look for match */
for (i = 0; (i < nswap); ++i) {
mdclrerror(ep);
continue;
}
}
}
/* return success */
return (rval);
}
/*
* check whether device is a dump device
*/
static int
)
{
int rval = 0;
int dump_fd;
mdclrerror(ep);
return (0);
}
} else { /* not a dump device - but does it overlap? */
if (rval != 0) {
}
}
}
return (rval);
}
/*
* check whether device is mounted
*/
static int
)
{
struct mnttab m;
int rval = 0;
/* should have a set */
/* look in mnttab */
int skipit = 0;
continue;
if (m.mnt_mountp[0] != '/')
continue;
skipit++;
break;
}
if (skipit == 1)
continue;
mdclrerror(ep);
continue;
}
} else { /* device isn't in mnttab - does it overlap? */
if (rval != 0) {
}
}
}
/* return success */
return (rval);
}
/*
* Is a file system currently mounted on this disk drive?
*/
int
)
{
struct mnttab m;
int rval = 0;
/* should have a set */
/* look in mnttab */
int skipit = 0;
continue;
if (m.mnt_mountp[0] != '/')
continue;
skipit++;
break;
}
if (skipit == 1)
continue;
mdclrerror(ep);
continue;
}
}
}
/* return success */
return (rval);
}
/*
* Check to see if the specified name is already in use or overlaps
* with a device already in use. Checks are made to determine whether
* the device is mounted, is a swap device, or a dump device. In each
* case if the device is not in use then an overlap check is done to ensure
* that the specified slice does not overlap.
*/
int
)
{
int rval = 0;
if ((inuse_flags & MDCHK_MOUNTED) &&
return (rval);
if ((inuse_flags & MDCHK_SWAP) &&
return (rval);
if ((inuse_flags & MDCHK_DUMP) &&
return (rval);
return (rval);
}
int
{
return (-1);
int is_it;
continue;
mdclrerror(ep);
return (0);
}
mdclrerror(ep);
continue;
}
return (-1);
}
== -1)
return (-1);
if (is_it)
}
return (0);
}
/*
*/
static void
char *device_name, /* fully qualified dev name */
)
{
/* link the node into the devname list */
devnamelist = dnlp;
}
/*
* check for same drive
*
* case it is correct to fail but misleading to give the same error msg as
* for an overlapping slice.
*
*/
int
)
{
int l = 0;
int devid1_found = 0;
int devid2_found = 0;
/*
* The process of determining if 2 names are the same drive is
* as follows:
*
* Case 1 - The filenames are identical
*
* Case 2 - Both devices have a devid
* get and compare the devids for the devices. If both
* devices have a devid then the compare will is all
* that is needed we are done.
*
* Case 3 - One or more devices does not have a devid
* start by doing a simple compare of the name, if they
* are the same just return.
*
* If the names differ then keep going and see if the
* may be the same underlying devic. First check to
* see if the sd name is the same (old code).
*
* Then check the major and minor numbers to see if
* they are the same. If they are then return (old code).
*
* Next compare the raw name and the component name and
* if they are the same then return.
*
* All else has failed so use the component name (cname)
* component number and unit number. If they all are
* equal then call them the same drive.
*
*/
return (NOT_SAMEDRIVE);
/* if the name structs are the same then the drives must be */
return (IDENTICAL_NAME_DEVT);
return (NOT_SAMEDRIVE);
/* names are identical */
return (IDENTICAL_NAME_DEVT);
}
return (NOT_SAMEDRIVE);
/*
* Check to see if the devicename is in the static list. If so,
* use its devid. Otherwise do the expensive operations
* of opening the device, getting the devid, and closing the
* device. Add the result into the static list.
*
* The case where this list will be useful is when there are soft
* partitions on multiple drives and a new soft partition is being
* created. In that situation the underlying physical device name
* for the new soft partition would be compared against each of the
* existing soft partititions. Without this static list that would
* involve 2 opens, closes, and devid gets for each existing soft
* partition
*/
devid1_found = 1;
rc1 = 1;
else
rc1 = 0;
continue;
}
devid2_found = 1;
rc2 = 1;
else
rc2 = 0;
continue;
}
}
/*
* Start by checking if the device has a device id, and if they
* are equal. If they are there is no question there is a match.
*
* The process here is open each disk, get the devid for each
* disk. If they both have a devid compare them and return
* the results.
*/
if (!devid1_found) {
return (NOT_SAMEDRIVE);
}
/* add the name and devid to the cache */
}
if (!devid2_found) {
return (NOT_SAMEDRIVE);
}
/* add the name and devid to the cache */
}
else
}
if (retval >= 0) {
return (retval);
}
/*
* At this point in time one of the two drives did not have a
* device ID. Do not make the assumption that is one drive
* did have a device id and the other did not that they are not
* the same. One drive could be covered by a device and still
* be the same drive. This is a general flaw in the system at
* this time.
*/
/*
* The optimization can not happen if we are given an old style name
* allows overlaps to happen.
*/
return (IDENTICAL_NAME_DEVT);
else
return (NOT_SAMEDRIVE);
/* check for same drive */
return (NOT_SAMEDRIVE); /* not same drive */
mdclrerror(ep);
return (NOT_SAMEDRIVE); /* not same drive */
} else {
return (CANT_TELL); /* can't tell */
}
return (NOT_SAMEDRIVE); /* not same drive */
}
/* same drive */
return (IDENTICAL_NAME_DEVT);
}
/*
* check for overlap
*/
int
char *uname, /* user supplied name for errors */
)
{
int ret;
/* verify args */
if (slblk1 == MD_DISKADDR_ERROR) {
assert(0);
}
if (slblk2 == MD_DISKADDR_ERROR) {
assert(0);
}
/* check for same drive */
return (0); /* not same drive */
} else if (ret < 0) {
return (-1); /* can't tell */
}
/* check for overlap */
return (-1); /* can't tell */
}
if (nblks1 == -1)
if (nblks2 == -1)
}
if (ret == IDENTICAL_NAME_DEVT)
else
}
/* return success */
return (0); /* no overlap */
}
/*
* check to see if a device is in a metadevice
*/
int
)
{
/* see if replica slice is ok, only applies to disks in sets */
if (! (options & MDCHK_ALLOW_REPSLICE) &&
! metaislocalset(sp)) {
return (-1);
!= 0)
return (-1);
}
/* check for databases */
if (options & MDCHK_ALLOW_MDDB) {
mdclrerror(ep);
} else {
}
} else {
return (-1);
}
}
/* check metadevices */
return (-1);
return (-1);
return (-1);
return (-1);
if (! (options & MDCHK_ALLOW_HS)) {
return (-1);
}
return (-1);
/* return success */
return (0);
}
/*
* check to see if a device is in its set
*/
int
)
{
/* check devices set */
if (metaislocalset(sp))
if ((! metaismeta(np)) &&
(metaislocalset(sp)) &&
mdclrerror(ep);
} else {
return (-1);
}
}
/* check set */
return (0);
/* return appropriate error */
if (metaislocalset(sp))
else
}
/*
* check to see if current user is root
*/
int
{
if (geteuid() != 0) {
return (-1);
}
return (0);
}