/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" /* * Attempt to dynamically link in the ZFS libzfs.so.1 so that we can * see if there are any ZFS zpools on any of the slices. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "libdiskmgt.h" #include "disks_private.h" /* * Pointers to libzfs.so functions that we dynamically resolve. */ static int (*zfsdl_zpool_in_use)(int fd, pool_state_t *state, char **name); static mutex_t init_lock = DEFAULTMUTEX; static rwlock_t zpool_lock = DEFAULTRWLOCK; static int initialized = 0; static void *init_zpool(); static int inuse_zpool_common(char *slice, nvlist_t *attrs, int *errp, char *type) { int found = 0; char *name; int fd; pool_state_t state; *errp = 0; if (slice == NULL) { return (found); } (void) mutex_lock(&init_lock); /* * Dynamically load libzfs */ if (!initialized) { if (!init_zpool()) { (void) mutex_unlock(&init_lock); return (found); } initialized = 1; } (void) mutex_unlock(&init_lock); (void) rw_rdlock(&zpool_lock); if ((fd = open(slice, O_RDONLY)) > 0) { if (zfsdl_zpool_in_use(fd, &state, &name)) { if (strcmp(type, DM_USE_ACTIVE_ZPOOL) == 0) { if (state == POOL_STATE_ACTIVE) found = 1; } else { found = 1; } if (found) { libdiskmgt_add_str(attrs, DM_USED_BY, type, errp); libdiskmgt_add_str(attrs, DM_USED_NAME, name, errp); } } } (void) rw_unlock(&zpool_lock); return (found); } int inuse_active_zpool(char *slice, nvlist_t *attrs, int *errp) { return (inuse_zpool_common(slice, attrs, errp, DM_USE_ACTIVE_ZPOOL)); } int inuse_exported_zpool(char *slice, nvlist_t *attrs, int *errp) { return (inuse_zpool_common(slice, attrs, errp, DM_USE_EXPORTED_ZPOOL)); } /* * Try to dynamically link the zfs functions we need. */ static void* init_zpool() { void *lh = NULL; if ((lh = dlopen("libzfs.so", RTLD_NOW)) == NULL) { return (lh); } /* * Instantiate the functions needed to get zpool configuration * data */ if ((zfsdl_zpool_in_use = (int (*)(int, pool_state_t *, char **)) dlsym(lh, "zpool_in_use")) == NULL) { (void) dlclose(lh); return (NULL); } return (lh); }