1767Ssjelinek /* 2767Ssjelinek * CDDL HEADER START 3767Ssjelinek * 4767Ssjelinek * The contents of this file are subject to the terms of the 5767Ssjelinek * Common Development and Distribution License, Version 1.0 only 6767Ssjelinek * (the "License"). You may not use this file except in compliance 7767Ssjelinek * with the License. 8767Ssjelinek * 9767Ssjelinek * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10767Ssjelinek * or http://www.opensolaris.org/os/licensing. 11767Ssjelinek * See the License for the specific language governing permissions 12767Ssjelinek * and limitations under the License. 13767Ssjelinek * 14767Ssjelinek * When distributing Covered Code, include this CDDL HEADER in each 15767Ssjelinek * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16767Ssjelinek * If applicable, add the following below this CDDL HEADER, with the 17767Ssjelinek * fields enclosed by brackets "[]" replaced with your own identifying 18767Ssjelinek * information: Portions Copyright [yyyy] [name of copyright owner] 19767Ssjelinek * 20767Ssjelinek * CDDL HEADER END 21767Ssjelinek */ 22767Ssjelinek /* 23*1352Seschrock * Copyright 2006 Sun Microsystems, Inc. All rights reserved. 24767Ssjelinek * Use is subject to license terms. 25767Ssjelinek */ 26767Ssjelinek 27767Ssjelinek #pragma ident "%Z%%M% %I% %E% SMI" 28767Ssjelinek 29767Ssjelinek /* 30767Ssjelinek * Attempt to dynamically link in the ZFS libzfs.so.1 so that we can 31767Ssjelinek * see if there are any ZFS zpools on any of the slices. 32767Ssjelinek */ 33767Ssjelinek 34767Ssjelinek #include <stdlib.h> 35767Ssjelinek #include <stdio.h> 36767Ssjelinek #include <strings.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> 47*1352Seschrock #include <sys/fs/zfs.h> 48767Ssjelinek 49767Ssjelinek #include "libdiskmgt.h" 50767Ssjelinek #include "disks_private.h" 51767Ssjelinek 52767Ssjelinek /* 53767Ssjelinek * Pointers to libzfs.so functions that we dynamically resolve. 54767Ssjelinek */ 55*1352Seschrock static int (*zfsdl_zpool_in_use)(int fd, pool_state_t *state, char **name); 56767Ssjelinek 57767Ssjelinek static mutex_t init_lock = DEFAULTMUTEX; 58767Ssjelinek static rwlock_t zpool_lock = DEFAULTRWLOCK; 59767Ssjelinek static int initialized = 0; 60767Ssjelinek 61767Ssjelinek static void *init_zpool(); 62767Ssjelinek 63*1352Seschrock static int 64*1352Seschrock inuse_zpool_common(char *slice, nvlist_t *attrs, int *errp, char *type) 65767Ssjelinek { 66767Ssjelinek int found = 0; 67*1352Seschrock char *name; 68767Ssjelinek int fd; 69*1352Seschrock pool_state_t state; 70767Ssjelinek 71767Ssjelinek *errp = 0; 72767Ssjelinek if (slice == NULL) { 73767Ssjelinek return (found); 74767Ssjelinek } 75767Ssjelinek 76767Ssjelinek (void) mutex_lock(&init_lock); 77767Ssjelinek 78767Ssjelinek /* 79767Ssjelinek * Dynamically load libzfs 80767Ssjelinek */ 81767Ssjelinek if (!initialized) { 82767Ssjelinek if (!init_zpool()) { 83767Ssjelinek (void) mutex_unlock(&init_lock); 84767Ssjelinek return (found); 85767Ssjelinek } 86767Ssjelinek initialized = 1; 87767Ssjelinek } 88767Ssjelinek (void) mutex_unlock(&init_lock); 89767Ssjelinek (void) rw_rdlock(&zpool_lock); 90767Ssjelinek if ((fd = open(slice, O_RDONLY)) > 0) { 91*1352Seschrock if (zfsdl_zpool_in_use(fd, &state, &name)) { 92*1352Seschrock if (strcmp(type, DM_USE_ACTIVE_ZPOOL) == 0) { 93*1352Seschrock if (state == POOL_STATE_ACTIVE) 94*1352Seschrock found = 1; 95*1352Seschrock } else { 96*1352Seschrock found = 1; 97*1352Seschrock } 98*1352Seschrock 99*1352Seschrock if (found) { 100*1352Seschrock libdiskmgt_add_str(attrs, DM_USED_BY, 101*1352Seschrock type, errp); 102*1352Seschrock libdiskmgt_add_str(attrs, DM_USED_NAME, 103*1352Seschrock name, errp); 104*1352Seschrock } 105767Ssjelinek } 106767Ssjelinek } 107767Ssjelinek (void) rw_unlock(&zpool_lock); 108767Ssjelinek 109767Ssjelinek return (found); 110767Ssjelinek } 111767Ssjelinek 112*1352Seschrock int 113*1352Seschrock inuse_active_zpool(char *slice, nvlist_t *attrs, int *errp) 114*1352Seschrock { 115*1352Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_ACTIVE_ZPOOL)); 116*1352Seschrock } 117*1352Seschrock 118*1352Seschrock int 119*1352Seschrock inuse_exported_zpool(char *slice, nvlist_t *attrs, int *errp) 120*1352Seschrock { 121*1352Seschrock return (inuse_zpool_common(slice, attrs, errp, DM_USE_EXPORTED_ZPOOL)); 122*1352Seschrock } 123*1352Seschrock 124767Ssjelinek /* 125767Ssjelinek * Try to dynamically link the zfs functions we need. 126767Ssjelinek */ 127767Ssjelinek static void* 128767Ssjelinek init_zpool() 129767Ssjelinek { 130767Ssjelinek void *lh = NULL; 131767Ssjelinek 132767Ssjelinek if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) { 133767Ssjelinek return (lh); 134767Ssjelinek } 135767Ssjelinek /* 136767Ssjelinek * Instantiate the functions needed to get zpool configuration 137767Ssjelinek * data 138767Ssjelinek */ 139*1352Seschrock if ((zfsdl_zpool_in_use = (int (*)(int, pool_state_t *, char **)) 140*1352Seschrock dlsym(lh, "zpool_in_use")) == NULL) { 141767Ssjelinek (void) dlclose(lh); 142767Ssjelinek return (NULL); 143767Ssjelinek } 144767Ssjelinek 145767Ssjelinek return (lh); 146767Ssjelinek } 147