Unleashed v1.4
[unleashed.git] / usr / src / lib / libdiskmgt / common / inuse_vxvm.c
blobd29b71143d9c78ebeb547796bb5bff028704dd72
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
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.
32 #include <stdlib.h>
33 #include <stdio.h>
34 #include <strings.h>
35 #include <sys/param.h>
36 #include <sys/errno.h>
37 #include <thread.h>
38 #include <synch.h>
39 #include <dlfcn.h>
40 #include <link.h>
41 #include <ctype.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,
61 vm_path_t pathp[]);
63 #define MAX_DISK_GROUPS 128
64 #define MAX_DISKS_DG 1024
66 struct vxvm_list {
67 struct vxvm_list *next;
68 char *slice;
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();
81 int
82 inuse_vxvm(char *slice, nvlist_t *attrs, int *errp)
84 int found = 0;
85 time_t curr_time;
86 char *sp = NULL;
88 *errp = 0;
89 if (slice == NULL) {
90 return (found);
94 * Since vxvm "encapsulates" the disk we need to match on any
95 * slice passed in. Strip the slice component from the devname.
97 if (is_ctds(slice)) {
98 if ((sp = strrchr(slice, '/')) == NULL)
99 sp = slice;
101 while (*sp && *sp != 's')
102 sp++;
104 if (*sp)
105 *sp = 0;
106 else
107 sp = NULL;
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;
120 if (*errp == 0) {
121 struct vxvm_list *listp;
123 listp = vxvm_listp;
124 while (listp != NULL) {
125 if (strcmp(slice, listp->slice) == 0) {
126 libdiskmgt_add_str(attrs, DM_USED_BY,
127 DM_USE_VXVM, errp);
128 libdiskmgt_add_str(attrs, DM_USED_NAME,
129 "", errp);
130 found = 1;
131 break;
133 listp = listp->next;
137 (void) mutex_unlock(&vxvm_lock);
139 /* restore slice name to orignal value */
140 if (sp != NULL)
141 *sp = 's';
143 return (found);
146 static int
147 add_use_record(char *devname)
149 struct vxvm_list *sp;
151 sp = (struct vxvm_list *)malloc(sizeof (struct vxvm_list));
152 if (sp == NULL) {
153 return (ENOMEM);
156 if ((sp->slice = strdup(devname)) == NULL) {
157 free(sp);
158 return (ENOMEM);
161 sp->next = vxvm_listp;
162 vxvm_listp = sp;
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)) {
169 char *dp;
171 if ((dp = strrchr(sp->slice, '/')) == NULL)
172 dp = sp->slice;
174 while (*dp && *dp != 's')
175 dp++;
176 *dp = 0;
179 return (0);
183 * If the input name is in c[t]ds format then return 1, otherwise return 0.
185 static int
186 is_ctds(char *name)
188 char *p;
190 if ((p = strrchr(name, '/')) == NULL)
191 p = name;
192 else
193 p++;
195 if (*p++ != 'c') {
196 return (0);
198 /* skip controller digits */
199 while (isdigit(*p)) {
200 p++;
203 /* handle optional target */
204 if (*p == 't') {
205 p++;
206 /* skip over target */
207 while (isdigit(*p) || isupper(*p)) {
208 p++;
212 if (*p++ != 'd') {
213 return (0);
215 while (isdigit(*p)) {
216 p++;
219 if (*p++ != 's') {
220 return (0);
223 /* check the slice number */
224 while (isdigit(*p)) {
225 p++;
228 if (*p != 0) {
229 return (0);
232 return (1);
236 * Free the list of vxvm entries.
238 static void
239 free_vxvm()
241 struct vxvm_list *listp = vxvm_listp;
242 struct vxvm_list *nextp;
244 while (listp != NULL) {
245 nextp = listp->next;
246 free((void *)listp->slice);
247 free((void *)listp);
248 listp = nextp;
251 vxvm_listp = NULL;
255 * Try to dynamically link the vxvm functions we need.
257 static void *
258 init_vxvm()
260 void *lh;
262 if ((lh = dlopen(VXVM_LIB_NAME, RTLD_NOW)) == NULL) {
263 return (NULL);
266 if ((vxdl_libvxvm_get_version = (int (*)(int))dlsym(lh,
267 "libvxvm_get_version")) == NULL) {
268 (void) dlclose(lh);
269 return (NULL);
272 if ((vxdl_libvxvm_get_conf = (int (*)(int))dlsym(lh,
273 "libvxvm_get_conf")) == NULL) {
274 (void) dlclose(lh);
275 return (NULL);
278 if ((vxdl_libvxvm_get_dgs = (int (*)(int, vm_name_t []))dlsym(lh,
279 "libvxvm_get_dgs")) == NULL) {
280 (void) dlclose(lh);
281 return (NULL);
284 if ((vxdl_libvxvm_get_disks = (int (*)(vm_name_t, int, vm_path_t []))
285 dlsym(lh, "libvxvm_get_disks")) == NULL) {
286 (void) dlclose(lh);
287 return (NULL);
290 return (lh);
293 static int
294 load_vxvm()
296 void *lh;
297 int vers;
298 int nsize;
299 int psize;
300 int n_disk_groups;
301 vm_name_t *namep;
302 char *pnp;
303 vm_path_t *pathp;
304 int i;
306 if ((lh = init_vxvm()) == NULL) {
307 /* No library. */
308 return (0);
311 vers = (vxdl_libvxvm_get_version)(1 << 8);
312 if (vers == -1) {
313 /* unsupported version */
314 (void) dlclose(lh);
315 return (0);
318 nsize = (vxdl_libvxvm_get_conf)(VXVM_NAME_SIZE);
319 psize = (vxdl_libvxvm_get_conf)(VXVM_PATH_SIZE);
321 if (nsize == -1 || psize == -1) {
322 (void) dlclose(lh);
323 return (0);
326 namep = (vm_name_t *)calloc(MAX_DISK_GROUPS, nsize);
327 if (namep == NULL) {
328 (void) dlclose(lh);
329 return (ENOMEM);
332 pathp = (vm_path_t *)calloc(MAX_DISKS_DG, psize);
333 if (pathp == NULL) {
334 (void) dlclose(lh);
335 free(namep);
336 return (ENOMEM);
339 n_disk_groups = (vxdl_libvxvm_get_dgs)(MAX_DISK_GROUPS, namep);
340 if (n_disk_groups < 0) {
341 (void) dlclose(lh);
342 free(namep);
343 free(pathp);
344 return (0);
347 pnp = (char *)namep;
348 for (i = 0; i < n_disk_groups; i++) {
349 int n_disks;
351 n_disks = (vxdl_libvxvm_get_disks)(pnp, MAX_DISKS_DG, pathp);
353 if (n_disks >= 0) {
354 int j;
355 char *ppp;
357 ppp = (char *)pathp;
358 for (j = 0; j < n_disks; j++) {
360 if (strncmp(ppp, "/dev/vx/", 8) == 0) {
361 char *pslash;
362 char nm[MAXPATHLEN];
364 pslash = strrchr(ppp, '/');
365 pslash++;
367 (void) snprintf(nm, sizeof (nm),
368 "/dev/dsk/%s", pslash);
369 if (add_use_record(nm)) {
370 (void) dlclose(lh);
371 free(pathp);
372 free(namep);
373 return (ENOMEM);
375 } else {
376 if (add_use_record(ppp)) {
377 (void) dlclose(lh);
378 free(pathp);
379 free(namep);
380 return (ENOMEM);
384 ppp += psize;
388 pnp += nsize;
391 (void) dlclose(lh);
392 free(pathp);
393 free(namep);
395 return (0);