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 /* 221352Seschrock * Copyright 2006 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 49*2082Seschrock #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 */ 56*2082Seschrock static int (*zfsdl_zpool_in_use)(libzfs_handle_t *hdl, int fd, 57*2082Seschrock pool_state_t *state, char **name, boolean_t *); 58*2082Seschrock static libzfs_handle_t *(*zfsdl_libzfs_init)(boolean_t); 59767Ssjelinek 60767Ssjelinek static mutex_t init_lock = DEFAULTMUTEX; 61767Ssjelinek static rwlock_t zpool_lock = DEFAULTRWLOCK; 62*2082Seschrock static boolean_t initialized; 63*2082Seschrock static libzfs_handle_t *zfs_hdl; 64767Ssjelinek 65767Ssjelinek static void *init_zpool(); 66767Ssjelinek 671352Seschrock static int 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; 74*2082Seschrock 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 } 91*2082Seschrock initialized = B_TRUE; 92767Ssjelinek } 93767Ssjelinek (void) mutex_unlock(&init_lock); 94767Ssjelinek (void) rw_rdlock(&zpool_lock); 95767Ssjelinek if ((fd = open(slice, O_RDONLY)) > 0) { 96*2082Seschrock name = NULL; 97*2082Seschrock if (zfsdl_zpool_in_use(zfs_hdl, fd, &state, 98*2082Seschrock &name, &used) == 0 && used) { 991352Seschrock if (strcmp(type, DM_USE_ACTIVE_ZPOOL) == 0) { 100*2082Seschrock if (state == POOL_STATE_ACTIVE) { 1011352Seschrock found = 1; 102*2082Seschrock } else if (state == POOL_STATE_SPARE) { 103*2082Seschrock found = 1; 104*2082Seschrock type = DM_USE_SPARE_ZPOOL; 105*2082Seschrock } 1061352Seschrock } else { 1071352Seschrock found = 1; 1081352Seschrock } 1091352Seschrock 1101352Seschrock if (found) { 1111352Seschrock libdiskmgt_add_str(attrs, DM_USED_BY, 1121352Seschrock type, errp); 1131352Seschrock libdiskmgt_add_str(attrs, DM_USED_NAME, 114*2082Seschrock name, errp); 1151352Seschrock } 116767Ssjelinek } 117*2082Seschrock if (name) 118*2082Seschrock free(name); 1191594Slling (void) close(fd); 120767Ssjelinek } 121767Ssjelinek (void) rw_unlock(&zpool_lock); 122767Ssjelinek 123767Ssjelinek return (found); 124767Ssjelinek } 125767Ssjelinek 1261352Seschrock int 1271352Seschrock inuse_active_zpool(char *slice, nvlist_t *attrs, int *errp) 1281352Seschrock { 1291352Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_ACTIVE_ZPOOL)); 1301352Seschrock } 1311352Seschrock 1321352Seschrock int 1331352Seschrock inuse_exported_zpool(char *slice, nvlist_t *attrs, int *errp) 1341352Seschrock { 1351352Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_EXPORTED_ZPOOL)); 1361352Seschrock } 1371352Seschrock 138767Ssjelinek /* 139767Ssjelinek * Try to dynamically link the zfs functions we need. 140767Ssjelinek */ 141767Ssjelinek static void* 142767Ssjelinek init_zpool() 143767Ssjelinek { 144767Ssjelinek void *lh = NULL; 145767Ssjelinek 146767Ssjelinek if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) { 147767Ssjelinek return (lh); 148767Ssjelinek } 149*2082Seschrock 150767Ssjelinek /* 151767Ssjelinek * Instantiate the functions needed to get zpool configuration 152767Ssjelinek * data 153767Ssjelinek */ 154*2082Seschrock if ((zfsdl_libzfs_init = (libzfs_handle_t *(*)(boolean_t)) 155*2082Seschrock dlsym(lh, "libzfs_init")) == NULL || 156*2082Seschrock (zfsdl_zpool_in_use = (int (*)(libzfs_handle_t *, int, 157*2082Seschrock pool_state_t *, char **, boolean_t *)) 1581352Seschrock dlsym(lh, "zpool_in_use")) == NULL) { 159767Ssjelinek (void) dlclose(lh); 160767Ssjelinek return (NULL); 161767Ssjelinek } 162767Ssjelinek 163*2082Seschrock if ((zfs_hdl = (*zfsdl_libzfs_init)(B_FALSE)) == NULL) { 164*2082Seschrock (void) dlclose(lh); 165*2082Seschrock return (NULL); 166*2082Seschrock } 167*2082Seschrock 168767Ssjelinek return (lh); 169767Ssjelinek } 170