/*
* 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 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Creates and maintains a cache of slices used by SVM.
*/
#include <meta.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libintl.h>
#include <synch.h>
#include <thread.h>
#include <dlfcn.h>
#include <link.h>
#include <libsysevent.h>
#include <syslog.h>
#include "libdiskmgt.h"
#include "disks_private.h"
/*
* The list of SVM slices in use.
*/
struct svm_list {
char *slice;
char *name;
char *type;
};
static int initialized = 0;
static void event_handler();
static int init_svm();
static int load_svm();
mdsetname_t *sp);
/*
* Pointers to libmeta functions that we dynamically resolve.
*/
md_error_t *ep);
md_error_t *ep);
md_error_t *ep);
static void (*mdl_sdssc_bind_library)();
/*
* Search the list of devices under SVM for the specified device.
*/
int
{
int found = 0;
*errp = 0;
return (found);
}
(void) mutex_lock(&init_lock);
if (!initialized) {
/* dynamically load libmeta */
if (init_svm()) {
/*
* need to initialize the cluster library to
* avoid seg faults
*/
/* load the SVM cache */
if (*errp == 0) {
/* start a thread to monitor the svm config */
/*
* Only start the svmevent thread if
* we are not doing an install
*/
subclass_list[0] = EC_SUB_ALL;
subclass_list, 1) != 0) {
}
} else {
}
if (*errp) {
/*
* If the sysevent thread fails,
* log the error but continue
* on. This failing to start
* is not catastrophic in
* particular for short lived
* consumers of libdiskmgt.
*/
"libdiskmgt: sysevent "
"thread for SVM failed "
"to start\n"));
*errp = 0;
}
}
}
}
if (*errp == 0) {
initialized = 1;
}
}
(void) mutex_unlock(&init_lock);
} else {
}
found = 1;
break;
}
}
return (found);
}
static int
{
/* If prev. record is a dup, skip it. */
return (0);
}
return (ENOMEM);
}
return (ENOMEM);
}
return (ENOMEM);
}
return (ENOMEM);
}
return (0);
}
static int
{
>= 0) {
return (ENOMEM);
}
}
} else {
(mdl_mdclrerror)(&error);
/* there are no metadb's; that is ok, no need to check the rest */
return (0);
}
(mdl_mdclrerror)(&error);
sp)) {
return (ENOMEM);
}
}
}
(mdl_mdclrerror)(&error);
META_DEVICE, &error);
(mdl_mdclrerror)(&error);
continue;
}
(mdl_mdclrerror)(&error);
int i;
return (ENOMEM);
}
}
}
}
}
(mdl_mdclrerror)(&error);
META_DEVICE, &error);
(mdl_mdclrerror)(&error);
continue;
}
(mdl_mdclrerror)(&error);
int i;
int j;
return (ENOMEM);
}
}
}
}
}
}
(mdl_mdclrerror)(&error);
META_DEVICE, &error);
(mdl_mdclrerror)(&error);
continue;
}
(mdl_mdclrerror)(&error);
return (ENOMEM);
}
}
}
}
(mdl_mdclrerror)(&error);
return (ENOMEM);
}
}
}
(mdl_mdclrerror)(&error);
return (0);
}
/*
* SVM uses "drive names" (ctd name without trailing slice) for drives
* in disksets. Since it massages these names there is no direct correspondence
* with the slice device names in /dev. So, we need to massage these names
* back to something we can match on when a slice comes in. We create an
* entry for each possible slice since we don't know what slices actually
* exist. Slice 0 & 7 are probably enough, but the user could have
* repartitioned the drive after they added it to the diskset and removed the
* mdb.
*/
static int
{
int i;
/* change rdsk to dsk */
char *p;
/* start p pointing to r in rdsk */
for (p = path + 5; *p; p++) {
*p = *(p + 1);
}
/* change rdsk to dsk */
char *p;
/* start p pointing to r in rdsk */
for (p = path + 9; *p; p++) {
*p = *(p + 1);
}
}
for (i = 0; i < 8; i++) {
return (ENOMEM);
}
}
return (0);
}
static void
{
(mdl_metaflushnames)(0);
(void) load_svm();
}
static void
{
mdnamelist_t *p;
(mdl_meta_invalidate_name)(p->namep);
}
}
/*
* Free the list of SVM entries.
*/
static void
}
}
/*
* Try to dynamically link the libmeta functions we need.
*/
static int
init_svm()
{
void *lh;
return (0);
}
"metaflushsetname");
"metafreenamelist");
"metafreereplicalist");
"metasetnosetname");
"meta_invalidate_name");
return (1);
}
/*
* Create a list of SVM devices
*/
static int
load_svm()
{
int max_sets;
int i;
return (0);
}
(mdl_mdclrerror)(&error);
return (0);
}
/* for each possible set number, see if we really have a diskset */
for (i = 0; i < max_sets; i++) {
/* metad rpc program not registered - no metasets */
break;
}
(mdl_mdclrerror)(&error);
continue;
}
(mdl_mdclrerror)(&error);
/* pick up drives in disksets with no mdbs/metadevices */
&error);
(mdl_mdclrerror)(&error);
return (ENOMEM);
}
}
}
if (diskset_info(sp)) {
return (ENOMEM);
}
}
(mdl_mdclrerror)(&error);
return (0);
}
static int
{
(mdl_mdclrerror)(&error);
return (0);
}
}
return (0);
}