xref: /onnv-gate/usr/src/lib/libdiskmgt/common/inuse_zpool.c (revision 5450:b25030891c44)
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