/*
* 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
*/
/*
*/
/*
* Metadevice diskset interfaces
*/
#include "meta_set_prv.h"
#include "meta_runtime.h"
#include <meta.h>
#include <devid.h>
#include <sdssc.h>
/*
* meta_devid_supported_in_did()
*
* Used to see if the Sun Cluster did driver supports
* device ids.
*
* Returns MD_DEVID_SUPPORTED if supported
* MD_DEVID_NOT_SUPPORTED if not supported
*/
int
{
/*
* We only want to make the expensive ioctl when needed
*/
if (idevid != MD_DEVID_NO_INIT)
return (idevid);
return (idevid);
}
/*
* Exported Entry Points
*/
int
char *node,
md_error_t *ep)
{
int release = 0;
int rval = 0;
int is_efi = 0;
int do_fallback = 0;
char *p;
return (-1);
release = 1;
return (-1);
return (-1);
}
}
rval = -1;
goto out;
}
/*
* First try and operate assuming the other side
* is running a SVM version that supports device id
* in disksets i.e. is running SVM RPC version 2.
*
* If this call fails due to the other side running
* a SVM version that does not support device id
* in disksets i.e. is running SVM RPC version 1, we
* fallback to the old behaviour.
*/
/*
* If the disk is connected to the remote node then the
* only thing we can be certain of is that the disk will
* have the same devid on that node, it may not have the
* same minor number nor the same ctd name. But if it
* does have the same ctd name then use it. In most cases
* there will only be a single entry returned but if the
* system has multi-path disks with MPXIO turned off there
* will be multiple entries. Attempting to choose the same
* name will give the user as consistent a view across the
* nodes as possible.
*/
do_fallback++;
goto fallback;
}
do_fallback++;
goto fallback;
}
/*
* we have a valid devid and minor name.
*/
"searching for %s on %s\n"),
}
} else {
/*
* Unable to get a minor name for the device so try
* searching without one which is painfully slow.
*/
"searching for %s on %s\n"),
}
}
/*
* If the return value was ENOTSUP, we know the
* other side is not running a SVM version that
* supports device id in disksets. We fallback
* to the previous behaviour in that case.
*/
do_fallback++;
goto fallback;
} else if (ret == -1) {
rval = -1;
goto out;
}
/*
* If the device does not exist on the remote node then
* the returned dev should indicate this (NODEV64) but
* we also check to make sure the returned name is not
* empty to make sure that the namespace does not get
* but being paranoid).
*/
goto out;
}
/*
* The rname returned from the remote node maybe different
* to the rname on this node, therefore we need to build up
* a dnp for this new rname.
*/
/* different rname */
LOGICAL_DEVICE, ep);
}
} else {
remote_dnp = dnp;
}
} else {
do_fallback++;
}
if (do_fallback) {
"failback search for %s on %s\n"),
}
/*
* Check if the disk in question is an EFI disk.
*/
is_efi++;
else if (ret == -1)
return (-1);
rval = -1;
goto out;
}
if (is_efi) {
/*
* For EFI disks, we compare the device
* id for the disks in question.
*/
== -1) {
rval = -1;
goto out;
}
goto out;
}
ep) == -1) {
rval = -1;
goto out;
}
if (encoded_otherdevid == NULL) {
rval = -1;
goto out;
}
NULL) == 0) {
/*
* If we are here, it means that dnp->devid
* is NULL.
*
* We want to explicitly get the device id
* for such a disk
*/
if (ret == 0) {
}
if (encoded_thisdevid)
}
if (ret != 0) {
goto out;
}
} else {
/*
* For VTOC disks, we compare the dev_t and
* timestamp for the disks in question.
*/
rval = -1;
goto out;
}
goto out;
}
}
remote_dnp = dnp;
}
rval = -1;
out:
if (release)
rval = -1;
}
return (rval);
}
{
int nid;
if (MD_MNSET_DESC(sd)) {
while (nd) {
}
}
return (MD_SIDEWILD);
}
/* If regular diskset */
continue;
return (sideno);
}
}
/*
* If the first loop fails we may be in a situation where this host
* is configured as part of a cluster yet not running in the cluster
* mode. If so, the names stored in sd->sd_nodes[] are going to be
* nodeid's instead of hostnames. See if we can find a match that way.
*/
continue;
return (sideno);
}
}
return (MD_SIDEWILD);
}
int
{
(void) memset(&c, 0, sizeof (c));
return (-1);
/* Don't need device id information from this ioctl */
c.c_locator.l_devid_flags = 0;
/* Kill any resyncs that are running on mirrors in this set */
}
return (0);
}
md_drive_desc **dd,
int dbcnt,
int dbsize,
)
{
md_drive_desc *p;
/* run to end of list */
/* void */;
/* allocate new list element */
return (p);
}
int
char *node,
)
{
int rval = 0;
return (-1);
/* Don't care if set record is MN or not */
return (-1);
return (-1);
return (0);
}
/* Looking for name only match */
rval = 1;
goto out;
}
goto out;
/* Looking for name and setno match */
rval = 1;
goto out;
}
goto out;
/* Looking for name, setno, and timestamp match */
rval = 1;
goto out;
}
/*
* Looking for name, setno, timestamp, and genid on
* other host is GT than other host.
*/
rval = 1;
goto out;
}
}
goto out;
}
/* Looking for name, setno, timestamp, and genid match */
rval = 1;
out:
/*
* Set record structure was allocated from RPC routine getset
* so this structure is only of size md_set_record even if
* the MN flag is set. So, clear the flag so that the free
* code doesn't attempt to free a structure the size of
* md_mnset_record.
*/
return (rval);
}
int
{
int i, j;
for (i = 0; i < cnt; i++)
for (j = i + 1; j < cnt; j++)
return (0);
}
int
{
int am_i_owner;
int i;
if (metaislocalset(sp)) {
if (owner_of_set != NULL)
return (MD_SETOWNER_YES);
}
return (-1);
return (-1);
if (MD_MNSET_DESC(sd)) {
if (am_i_owner == TRUE)
return (MD_SETOWNER_YES);
else
return (MD_SETOWNER_NO);
}
if (am_i_owner == TRUE) {
if (owner_of_set != NULL)
return (MD_SETOWNER_YES);
}
if (owner_of_set != NULL)
*owner_of_set = NULL;
return (MD_SETOWNER_NONE);
}
if (am_i_owner == TRUE) {
if (owner_of_set != NULL)
return (MD_SETOWNER_YES);
}
for (i = 0; i < MD_MAXSIDES; i++) {
/*
* Skip empty slots, and my own slot.
*/
continue;
return (-1);
if (am_i_owner == TRUE) {
if (owner_of_set != NULL)
return (MD_SETOWNER_NO);
}
}
/* We get here, we currently have no owner. */
if (owner_of_set != NULL)
*owner_of_set = NULL;
return (MD_SETOWNER_NONE);
}
void
int node_c,
char **node_v
)
{
int i, j;
/*
* Mark the set record MD_SR_OK.
*/
for (i = 0; i < node_c; i++)
mdclrerror(&xep);
max_genid++;
}
if (MD_MNSET_DESC(sd)) {
while (nd) {
continue;
}
/* Will only return a multi-node diskset record */
mdclrerror(&xep);
continue;
}
mdclrerror(&xep);
}
}
return;
}
/*
* Get current genid for each node.
*/
for (i = 0; i < MD_MAXSIDES; i++) {
cur_genid[i] = 0;
/* Skip empty slots */
continue;
/* Should be a non-multinode diskset */
mdclrerror(&xep);
continue;
}
if (MD_MNSET_REC(sr)) {
/*
* Set record structure was allocated from RPC routine
* getset so this structure is only of size
* md_set_record even if the MN flag is set. So,
* clear the flag so that the free code doesn't
* attempt to free a structure the size of
* md_mnset_record.
*/
continue;
}
}
/*
* Mark the set record MD_SR_OK
*/
for (i = 0; i < MD_MAXSIDES; i++) {
/* Skip empty slots */
continue;
&xep))
mdclrerror(&xep);
}
}
int
{
md_drive_desc *p;
struct mddb_config c;
int i, clboot = 0;
int need_to_free_devidp = 0;
return (-1);
return (-1);
}
(void) memset(&c, 0, sizeof (c));
return (-1);
return (-1);
if (p->dd_dbcnt == 0)
continue;
break;
}
/*
* The disk has no side name information
*/
== NULL)) {
mdclrerror(ep);
continue;
}
continue;
/*
* minor_name will be NULL if dnp->devid == NULL
* - see metagetvtoc()
*/
mdclrerror(ep);
continue;
}
} else {
if (MD_MNSET_DESC(sd)) {
} else {
}
}
}
/*
* If the device does not have a devid or
* did driver does not support devids.
*/
use_devid = 0;
if (use_devid) {
/*
* The devid associated with the dnp does not have
* a minor name and so we must add it in.
*/
need_to_free_devidp = 1;
/* If need to fix LB then setup old_devid info */
if (p->dd_flags & MD_DR_FIX_LB_NM_DID) {
need_to_free_devidp = 0;
devidp = new_devidp;
}
if (need_to_free_devidp) {
need_to_free_devidp = 0;
}
if (minor_name == NULL) {
/* ERROR fix up */
if (c.c_locator.l_old_devid_sz) {
Free((void *)
c.c_locator.l_old_devid_sz = 0;
c.c_locator.l_old_devid =
}
return (-1);
}
} else {
/*
* Don't need device id information from
* this ioctl
*/
c.c_locator.l_devid_flags = 0;
}
for (i = 0; i < p->dd_dbcnt; i++) {
if (use_devid) {
Free((void *)
if (c.c_locator.l_old_devid_sz) {
c.c_locator.l_old_devid);
c.c_locator.l_old_devid_sz = 0;
c.c_locator.l_old_devid =
}
}
}
}
if (use_devid) {
if (c.c_locator.l_old_devid_sz) {
Free((void *)
c.c_locator.l_old_devid_sz = 0;
}
}
}
/* return success */
return (0);
}
int
{
(void) memset(&c, '\0', sizeof (c));
return (-1);
/* Don't need device id information from this ioctl */
c.c_locator.l_devid_flags = 0;
if (stale_bool == TRUE) {
c.c_flags = MDDB_C_STALE;
}
if (c.c_flags & MDDB_C_STALE)
return (0);
}