1767Ssjelinek /*
2767Ssjelinek * CDDL HEADER START
3767Ssjelinek *
4767Ssjelinek * The contents of this file are subject to the terms of the
51594Slling * Common Development and Distribution License (the "License").
61594Slling * You may not use this file except in compliance with the License.
7767Ssjelinek *
8767Ssjelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9767Ssjelinek * or http://www.opensolaris.org/os/licensing.
10767Ssjelinek * See the License for the specific language governing permissions
11767Ssjelinek * and limitations under the License.
12767Ssjelinek *
13767Ssjelinek * When distributing Covered Code, include this CDDL HEADER in each
14767Ssjelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15767Ssjelinek * If applicable, add the following below this CDDL HEADER, with the
16767Ssjelinek * fields enclosed by brackets "[]" replaced with your own identifying
17767Ssjelinek * information: Portions Copyright [yyyy] [name of copyright owner]
18767Ssjelinek *
19767Ssjelinek * CDDL HEADER END
20767Ssjelinek */
21767Ssjelinek /*
22*5450Sbrendan * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
23767Ssjelinek * Use is subject to license terms.
24767Ssjelinek */
25767Ssjelinek
26767Ssjelinek #pragma ident "%Z%%M% %I% %E% SMI"
27767Ssjelinek
28767Ssjelinek /*
29767Ssjelinek * Attempt to dynamically link in the ZFS libzfs.so.1 so that we can
30767Ssjelinek * see if there are any ZFS zpools on any of the slices.
31767Ssjelinek */
32767Ssjelinek
33767Ssjelinek #include <stdlib.h>
34767Ssjelinek #include <stdio.h>
35767Ssjelinek #include <strings.h>
361594Slling #include <unistd.h>
37767Ssjelinek #include <sys/param.h>
38767Ssjelinek #include <sys/errno.h>
39767Ssjelinek #include <sys/types.h>
40767Ssjelinek #include <sys/stat.h>
41767Ssjelinek #include <fcntl.h>
42767Ssjelinek #include <thread.h>
43767Ssjelinek #include <synch.h>
44767Ssjelinek #include <dlfcn.h>
45767Ssjelinek #include <link.h>
46767Ssjelinek #include <ctype.h>
471352Seschrock #include <sys/fs/zfs.h>
48767Ssjelinek
492082Seschrock #include <libzfs.h>
50767Ssjelinek #include "libdiskmgt.h"
51767Ssjelinek #include "disks_private.h"
52767Ssjelinek
53767Ssjelinek /*
54767Ssjelinek * Pointers to libzfs.so functions that we dynamically resolve.
55767Ssjelinek */
562082Seschrock static int (*zfsdl_zpool_in_use)(libzfs_handle_t *hdl, int fd,
572082Seschrock pool_state_t *state, char **name, boolean_t *);
582082Seschrock static libzfs_handle_t *(*zfsdl_libzfs_init)(boolean_t);
59767Ssjelinek
60767Ssjelinek static mutex_t init_lock = DEFAULTMUTEX;
61767Ssjelinek static rwlock_t zpool_lock = DEFAULTRWLOCK;
622082Seschrock static boolean_t initialized;
632082Seschrock static libzfs_handle_t *zfs_hdl;
64767Ssjelinek
65767Ssjelinek static void *init_zpool();
66767Ssjelinek
671352Seschrock static int
inuse_zpool_common(char * slice,nvlist_t * attrs,int * errp,char * type)681352Seschrock inuse_zpool_common(char *slice, nvlist_t *attrs, int *errp, char *type)
69767Ssjelinek {
70767Ssjelinek int found = 0;
711352Seschrock char *name;
72767Ssjelinek int fd;
731352Seschrock pool_state_t state;
742082Seschrock boolean_t used;
75767Ssjelinek
76767Ssjelinek *errp = 0;
77767Ssjelinek if (slice == NULL) {
78767Ssjelinek return (found);
79767Ssjelinek }
80767Ssjelinek
81767Ssjelinek (void) mutex_lock(&init_lock);
82767Ssjelinek
83767Ssjelinek /*
84767Ssjelinek * Dynamically load libzfs
85767Ssjelinek */
86767Ssjelinek if (!initialized) {
87767Ssjelinek if (!init_zpool()) {
88767Ssjelinek (void) mutex_unlock(&init_lock);
89767Ssjelinek return (found);
90767Ssjelinek }
912082Seschrock initialized = B_TRUE;
92767Ssjelinek }
93767Ssjelinek (void) mutex_unlock(&init_lock);
94767Ssjelinek (void) rw_rdlock(&zpool_lock);
95767Ssjelinek if ((fd = open(slice, O_RDONLY)) > 0) {
962082Seschrock name = NULL;
972082Seschrock if (zfsdl_zpool_in_use(zfs_hdl, fd, &state,
982082Seschrock &name, &used) == 0 && used) {
991352Seschrock if (strcmp(type, DM_USE_ACTIVE_ZPOOL) == 0) {
1002082Seschrock if (state == POOL_STATE_ACTIVE) {
1011352Seschrock found = 1;
1022082Seschrock } else if (state == POOL_STATE_SPARE) {
1032082Seschrock found = 1;
1042082Seschrock type = DM_USE_SPARE_ZPOOL;
105*5450Sbrendan } else if (state == POOL_STATE_L2CACHE) {
106*5450Sbrendan found = 1;
107*5450Sbrendan type = DM_USE_L2CACHE_ZPOOL;
1082082Seschrock }
1091352Seschrock } else {
1101352Seschrock found = 1;
1111352Seschrock }
1121352Seschrock
1131352Seschrock if (found) {
1141352Seschrock libdiskmgt_add_str(attrs, DM_USED_BY,
1151352Seschrock type, errp);
1161352Seschrock libdiskmgt_add_str(attrs, DM_USED_NAME,
1172082Seschrock name, errp);
1181352Seschrock }
119767Ssjelinek }
1202082Seschrock if (name)
1212082Seschrock free(name);
1221594Slling (void) close(fd);
123767Ssjelinek }
124767Ssjelinek (void) rw_unlock(&zpool_lock);
125767Ssjelinek
126767Ssjelinek return (found);
127767Ssjelinek }
128767Ssjelinek
1291352Seschrock int
inuse_active_zpool(char * slice,nvlist_t * attrs,int * errp)1301352Seschrock inuse_active_zpool(char *slice, nvlist_t *attrs, int *errp)
1311352Seschrock {
1321352Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_ACTIVE_ZPOOL));
1331352Seschrock }
1341352Seschrock
1351352Seschrock int
inuse_exported_zpool(char * slice,nvlist_t * attrs,int * errp)1361352Seschrock inuse_exported_zpool(char *slice, nvlist_t *attrs, int *errp)
1371352Seschrock {
1381352Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_EXPORTED_ZPOOL));
1391352Seschrock }
1401352Seschrock
141767Ssjelinek /*
142767Ssjelinek * Try to dynamically link the zfs functions we need.
143767Ssjelinek */
144767Ssjelinek static void*
init_zpool()145767Ssjelinek init_zpool()
146767Ssjelinek {
147767Ssjelinek void *lh = NULL;
148767Ssjelinek
149767Ssjelinek if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) {
150767Ssjelinek return (lh);
151767Ssjelinek }
1522082Seschrock
153767Ssjelinek /*
154767Ssjelinek * Instantiate the functions needed to get zpool configuration
155767Ssjelinek * data
156767Ssjelinek */
1572082Seschrock if ((zfsdl_libzfs_init = (libzfs_handle_t *(*)(boolean_t))
1582082Seschrock dlsym(lh, "libzfs_init")) == NULL ||
1592082Seschrock (zfsdl_zpool_in_use = (int (*)(libzfs_handle_t *, int,
1602082Seschrock pool_state_t *, char **, boolean_t *))
1611352Seschrock dlsym(lh, "zpool_in_use")) == NULL) {
162767Ssjelinek (void) dlclose(lh);
163767Ssjelinek return (NULL);
164767Ssjelinek }
165767Ssjelinek
1662082Seschrock if ((zfs_hdl = (*zfsdl_libzfs_init)(B_FALSE)) == NULL) {
1672082Seschrock (void) dlclose(lh);
1682082Seschrock return (NULL);
1692082Seschrock }
1702082Seschrock
171767Ssjelinek return (lh);
172767Ssjelinek }
173