4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
28 * Attempt to dynamically link in the Veritas libvxvmsc.so so that we can
29 * see if there are any Veritas volumes on any of the slices.
35 #include <sys/param.h>
36 #include <sys/errno.h>
43 #include "libdiskmgt.h"
44 #include "disks_private.h"
46 #define VXVM_LIB_NAME "libvxvmsc.so"
48 #define VXVM_NAME_SIZE 1
49 #define VXVM_PATH_SIZE 2
51 typedef char *vm_name_t
;
52 typedef char *vm_path_t
;
55 * Pointers to libvxvmsc.so functions that we dynamically resolve.
57 static int (*vxdl_libvxvm_get_version
)(int version
);
58 static int (*vxdl_libvxvm_get_conf
)(int param
);
59 static int (*vxdl_libvxvm_get_dgs
)(int len
, vm_name_t namep
[]);
60 static int (*vxdl_libvxvm_get_disks
)(vm_name_t dgname
, int len
,
63 #define MAX_DISK_GROUPS 128
64 #define MAX_DISKS_DG 1024
67 struct vxvm_list
*next
;
71 static struct vxvm_list
*vxvm_listp
= NULL
;
72 static time_t timestamp
= 0;
73 static mutex_t vxvm_lock
= DEFAULTMUTEX
;
75 static int add_use_record(char *devname
);
76 static void free_vxvm();
77 static void *init_vxvm();
78 static int is_ctds(char *name
);
79 static int load_vxvm();
82 inuse_vxvm(char *slice
, nvlist_t
*attrs
, int *errp
)
94 * Since vxvm "encapsulates" the disk we need to match on any
95 * slice passed in. Strip the slice component from the devname.
98 if ((sp
= strrchr(slice
, '/')) == NULL
)
101 while (*sp
&& *sp
!= 's')
110 (void) mutex_lock(&vxvm_lock
);
112 curr_time
= time(NULL
);
113 if (timestamp
< curr_time
&& (curr_time
- timestamp
) > 60) {
114 free_vxvm(); /* free old entries */
115 *errp
= load_vxvm(); /* load the cache */
117 timestamp
= curr_time
;
121 struct vxvm_list
*listp
;
124 while (listp
!= NULL
) {
125 if (strcmp(slice
, listp
->slice
) == 0) {
126 libdiskmgt_add_str(attrs
, DM_USED_BY
,
128 libdiskmgt_add_str(attrs
, DM_USED_NAME
,
137 (void) mutex_unlock(&vxvm_lock
);
139 /* restore slice name to orignal value */
147 add_use_record(char *devname
)
149 struct vxvm_list
*sp
;
151 sp
= (struct vxvm_list
*)malloc(sizeof (struct vxvm_list
));
156 if ((sp
->slice
= strdup(devname
)) == NULL
) {
161 sp
->next
= vxvm_listp
;
165 * Since vxvm "encapsulates" the disk we need to match on any
166 * slice passed in. Strip the slice component from the devname.
168 if (is_ctds(sp
->slice
)) {
171 if ((dp
= strrchr(sp
->slice
, '/')) == NULL
)
174 while (*dp
&& *dp
!= 's')
183 * If the input name is in c[t]ds format then return 1, otherwise return 0.
190 if ((p
= strrchr(name
, '/')) == NULL
)
198 /* skip controller digits */
199 while (isdigit(*p
)) {
203 /* handle optional target */
206 /* skip over target */
207 while (isdigit(*p
) || isupper(*p
)) {
215 while (isdigit(*p
)) {
223 /* check the slice number */
224 while (isdigit(*p
)) {
236 * Free the list of vxvm entries.
241 struct vxvm_list
*listp
= vxvm_listp
;
242 struct vxvm_list
*nextp
;
244 while (listp
!= NULL
) {
246 free((void *)listp
->slice
);
255 * Try to dynamically link the vxvm functions we need.
262 if ((lh
= dlopen(VXVM_LIB_NAME
, RTLD_NOW
)) == NULL
) {
266 if ((vxdl_libvxvm_get_version
= (int (*)(int))dlsym(lh
,
267 "libvxvm_get_version")) == NULL
) {
272 if ((vxdl_libvxvm_get_conf
= (int (*)(int))dlsym(lh
,
273 "libvxvm_get_conf")) == NULL
) {
278 if ((vxdl_libvxvm_get_dgs
= (int (*)(int, vm_name_t
[]))dlsym(lh
,
279 "libvxvm_get_dgs")) == NULL
) {
284 if ((vxdl_libvxvm_get_disks
= (int (*)(vm_name_t
, int, vm_path_t
[]))
285 dlsym(lh
, "libvxvm_get_disks")) == NULL
) {
306 if ((lh
= init_vxvm()) == NULL
) {
311 vers
= (vxdl_libvxvm_get_version
)(1 << 8);
313 /* unsupported version */
318 nsize
= (vxdl_libvxvm_get_conf
)(VXVM_NAME_SIZE
);
319 psize
= (vxdl_libvxvm_get_conf
)(VXVM_PATH_SIZE
);
321 if (nsize
== -1 || psize
== -1) {
326 namep
= (vm_name_t
*)calloc(MAX_DISK_GROUPS
, nsize
);
332 pathp
= (vm_path_t
*)calloc(MAX_DISKS_DG
, psize
);
339 n_disk_groups
= (vxdl_libvxvm_get_dgs
)(MAX_DISK_GROUPS
, namep
);
340 if (n_disk_groups
< 0) {
348 for (i
= 0; i
< n_disk_groups
; i
++) {
351 n_disks
= (vxdl_libvxvm_get_disks
)(pnp
, MAX_DISKS_DG
, pathp
);
358 for (j
= 0; j
< n_disks
; j
++) {
360 if (strncmp(ppp
, "/dev/vx/", 8) == 0) {
364 pslash
= strrchr(ppp
, '/');
367 (void) snprintf(nm
, sizeof (nm
),
368 "/dev/dsk/%s", pslash
);
369 if (add_use_record(nm
)) {
376 if (add_use_record(ppp
)) {