13e1bd7a2Ssjelinek /* 23e1bd7a2Ssjelinek * CDDL HEADER START 33e1bd7a2Ssjelinek * 43e1bd7a2Ssjelinek * The contents of this file are subject to the terms of the 5752712d2Slling * Common Development and Distribution License (the "License"). 6752712d2Slling * You may not use this file except in compliance with the License. 73e1bd7a2Ssjelinek * 83e1bd7a2Ssjelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 93e1bd7a2Ssjelinek * or http://www.opensolaris.org/os/licensing. 103e1bd7a2Ssjelinek * See the License for the specific language governing permissions 113e1bd7a2Ssjelinek * and limitations under the License. 123e1bd7a2Ssjelinek * 133e1bd7a2Ssjelinek * When distributing Covered Code, include this CDDL HEADER in each 143e1bd7a2Ssjelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 153e1bd7a2Ssjelinek * If applicable, add the following below this CDDL HEADER, with the 163e1bd7a2Ssjelinek * fields enclosed by brackets "[]" replaced with your own identifying 173e1bd7a2Ssjelinek * information: Portions Copyright [yyyy] [name of copyright owner] 183e1bd7a2Ssjelinek * 193e1bd7a2Ssjelinek * CDDL HEADER END 203e1bd7a2Ssjelinek */ 213e1bd7a2Ssjelinek /* 22*fa94a07fSbrendan * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 233e1bd7a2Ssjelinek * Use is subject to license terms. 243e1bd7a2Ssjelinek */ 253e1bd7a2Ssjelinek 263e1bd7a2Ssjelinek #pragma ident "%Z%%M% %I% %E% SMI" 273e1bd7a2Ssjelinek 283e1bd7a2Ssjelinek /* 293e1bd7a2Ssjelinek * Attempt to dynamically link in the ZFS libzfs.so.1 so that we can 303e1bd7a2Ssjelinek * see if there are any ZFS zpools on any of the slices. 313e1bd7a2Ssjelinek */ 323e1bd7a2Ssjelinek 333e1bd7a2Ssjelinek #include <stdlib.h> 343e1bd7a2Ssjelinek #include <stdio.h> 353e1bd7a2Ssjelinek #include <strings.h> 36752712d2Slling #include <unistd.h> 373e1bd7a2Ssjelinek #include <sys/param.h> 383e1bd7a2Ssjelinek #include <sys/errno.h> 393e1bd7a2Ssjelinek #include <sys/types.h> 403e1bd7a2Ssjelinek #include <sys/stat.h> 413e1bd7a2Ssjelinek #include <fcntl.h> 423e1bd7a2Ssjelinek #include <thread.h> 433e1bd7a2Ssjelinek #include <synch.h> 443e1bd7a2Ssjelinek #include <dlfcn.h> 453e1bd7a2Ssjelinek #include <link.h> 463e1bd7a2Ssjelinek #include <ctype.h> 4746a2abf2Seschrock #include <sys/fs/zfs.h> 483e1bd7a2Ssjelinek 4999653d4eSeschrock #include <libzfs.h> 503e1bd7a2Ssjelinek #include "libdiskmgt.h" 513e1bd7a2Ssjelinek #include "disks_private.h" 523e1bd7a2Ssjelinek 533e1bd7a2Ssjelinek /* 543e1bd7a2Ssjelinek * Pointers to libzfs.so functions that we dynamically resolve. 553e1bd7a2Ssjelinek */ 5699653d4eSeschrock static int (*zfsdl_zpool_in_use)(libzfs_handle_t *hdl, int fd, 5799653d4eSeschrock pool_state_t *state, char **name, boolean_t *); 5899653d4eSeschrock static libzfs_handle_t *(*zfsdl_libzfs_init)(boolean_t); 593e1bd7a2Ssjelinek 603e1bd7a2Ssjelinek static mutex_t init_lock = DEFAULTMUTEX; 613e1bd7a2Ssjelinek static rwlock_t zpool_lock = DEFAULTRWLOCK; 6299653d4eSeschrock static boolean_t initialized; 6399653d4eSeschrock static libzfs_handle_t *zfs_hdl; 643e1bd7a2Ssjelinek 653e1bd7a2Ssjelinek static void *init_zpool(); 663e1bd7a2Ssjelinek 6746a2abf2Seschrock static int 6846a2abf2Seschrock inuse_zpool_common(char *slice, nvlist_t *attrs, int *errp, char *type) 693e1bd7a2Ssjelinek { 703e1bd7a2Ssjelinek int found = 0; 7146a2abf2Seschrock char *name; 723e1bd7a2Ssjelinek int fd; 7346a2abf2Seschrock pool_state_t state; 7499653d4eSeschrock boolean_t used; 753e1bd7a2Ssjelinek 763e1bd7a2Ssjelinek *errp = 0; 773e1bd7a2Ssjelinek if (slice == NULL) { 783e1bd7a2Ssjelinek return (found); 793e1bd7a2Ssjelinek } 803e1bd7a2Ssjelinek 813e1bd7a2Ssjelinek (void) mutex_lock(&init_lock); 823e1bd7a2Ssjelinek 833e1bd7a2Ssjelinek /* 843e1bd7a2Ssjelinek * Dynamically load libzfs 853e1bd7a2Ssjelinek */ 863e1bd7a2Ssjelinek if (!initialized) { 873e1bd7a2Ssjelinek if (!init_zpool()) { 883e1bd7a2Ssjelinek (void) mutex_unlock(&init_lock); 893e1bd7a2Ssjelinek return (found); 903e1bd7a2Ssjelinek } 9199653d4eSeschrock initialized = B_TRUE; 923e1bd7a2Ssjelinek } 933e1bd7a2Ssjelinek (void) mutex_unlock(&init_lock); 943e1bd7a2Ssjelinek (void) rw_rdlock(&zpool_lock); 953e1bd7a2Ssjelinek if ((fd = open(slice, O_RDONLY)) > 0) { 9699653d4eSeschrock name = NULL; 9799653d4eSeschrock if (zfsdl_zpool_in_use(zfs_hdl, fd, &state, 9899653d4eSeschrock &name, &used) == 0 && used) { 9946a2abf2Seschrock if (strcmp(type, DM_USE_ACTIVE_ZPOOL) == 0) { 10099653d4eSeschrock if (state == POOL_STATE_ACTIVE) { 10146a2abf2Seschrock found = 1; 10299653d4eSeschrock } else if (state == POOL_STATE_SPARE) { 10399653d4eSeschrock found = 1; 10499653d4eSeschrock type = DM_USE_SPARE_ZPOOL; 105*fa94a07fSbrendan } else if (state == POOL_STATE_L2CACHE) { 106*fa94a07fSbrendan found = 1; 107*fa94a07fSbrendan type = DM_USE_L2CACHE_ZPOOL; 10899653d4eSeschrock } 10946a2abf2Seschrock } else { 11046a2abf2Seschrock found = 1; 11146a2abf2Seschrock } 11246a2abf2Seschrock 11346a2abf2Seschrock if (found) { 1143e1bd7a2Ssjelinek libdiskmgt_add_str(attrs, DM_USED_BY, 11546a2abf2Seschrock type, errp); 1163e1bd7a2Ssjelinek libdiskmgt_add_str(attrs, DM_USED_NAME, 1173e1bd7a2Ssjelinek name, errp); 11846a2abf2Seschrock } 1193e1bd7a2Ssjelinek } 12099653d4eSeschrock if (name) 12199653d4eSeschrock free(name); 122752712d2Slling (void) close(fd); 1233e1bd7a2Ssjelinek } 1243e1bd7a2Ssjelinek (void) rw_unlock(&zpool_lock); 1253e1bd7a2Ssjelinek 1263e1bd7a2Ssjelinek return (found); 1273e1bd7a2Ssjelinek } 1283e1bd7a2Ssjelinek 12946a2abf2Seschrock int 13046a2abf2Seschrock inuse_active_zpool(char *slice, nvlist_t *attrs, int *errp) 13146a2abf2Seschrock { 13246a2abf2Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_ACTIVE_ZPOOL)); 13346a2abf2Seschrock } 13446a2abf2Seschrock 13546a2abf2Seschrock int 13646a2abf2Seschrock inuse_exported_zpool(char *slice, nvlist_t *attrs, int *errp) 13746a2abf2Seschrock { 13846a2abf2Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_EXPORTED_ZPOOL)); 13946a2abf2Seschrock } 14046a2abf2Seschrock 1413e1bd7a2Ssjelinek /* 1423e1bd7a2Ssjelinek * Try to dynamically link the zfs functions we need. 1433e1bd7a2Ssjelinek */ 1443e1bd7a2Ssjelinek static void* 1453e1bd7a2Ssjelinek init_zpool() 1463e1bd7a2Ssjelinek { 1473e1bd7a2Ssjelinek void *lh = NULL; 1483e1bd7a2Ssjelinek 1493e1bd7a2Ssjelinek if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) { 1503e1bd7a2Ssjelinek return (lh); 1513e1bd7a2Ssjelinek } 15299653d4eSeschrock 1533e1bd7a2Ssjelinek /* 1543e1bd7a2Ssjelinek * Instantiate the functions needed to get zpool configuration 1553e1bd7a2Ssjelinek * data 1563e1bd7a2Ssjelinek */ 15799653d4eSeschrock if ((zfsdl_libzfs_init = (libzfs_handle_t *(*)(boolean_t)) 15899653d4eSeschrock dlsym(lh, "libzfs_init")) == NULL || 15999653d4eSeschrock (zfsdl_zpool_in_use = (int (*)(libzfs_handle_t *, int, 16099653d4eSeschrock pool_state_t *, char **, boolean_t *)) 16146a2abf2Seschrock dlsym(lh, "zpool_in_use")) == NULL) { 1623e1bd7a2Ssjelinek (void) dlclose(lh); 1633e1bd7a2Ssjelinek return (NULL); 1643e1bd7a2Ssjelinek } 1653e1bd7a2Ssjelinek 16699653d4eSeschrock if ((zfs_hdl = (*zfsdl_libzfs_init)(B_FALSE)) == NULL) { 16799653d4eSeschrock (void) dlclose(lh); 16899653d4eSeschrock return (NULL); 16999653d4eSeschrock } 17099653d4eSeschrock 1713e1bd7a2Ssjelinek return (lh); 1723e1bd7a2Ssjelinek } 173