summaryrefslogtreecommitdiff
path: root/usr/src/lib/libdiskmgt/common
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib/libdiskmgt/common')
-rw-r--r--usr/src/lib/libdiskmgt/common/cache.c11
-rw-r--r--usr/src/lib/libdiskmgt/common/disks_private.h3
-rw-r--r--usr/src/lib/libdiskmgt/common/drive.c4
-rw-r--r--usr/src/lib/libdiskmgt/common/entry.c391
-rw-r--r--usr/src/lib/libdiskmgt/common/findevs.c4
-rw-r--r--usr/src/lib/libdiskmgt/common/inuse_fs.c3
-rw-r--r--usr/src/lib/libdiskmgt/common/inuse_svm.c65
-rw-r--r--usr/src/lib/libdiskmgt/common/inuse_zpool.c124
-rw-r--r--usr/src/lib/libdiskmgt/common/libdiskmgt.h23
-rw-r--r--usr/src/lib/libdiskmgt/common/media.c27
-rw-r--r--usr/src/lib/libdiskmgt/common/partition.c23
-rw-r--r--usr/src/lib/libdiskmgt/common/slice.c15
12 files changed, 579 insertions, 114 deletions
diff --git a/usr/src/lib/libdiskmgt/common/cache.c b/usr/src/lib/libdiskmgt/common/cache.c
index 411d6c41b7..1670aa3698 100644
--- a/usr/src/lib/libdiskmgt/common/cache.c
+++ b/usr/src/lib/libdiskmgt/common/cache.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -652,8 +652,13 @@ initialize()
cache_loaded = 1;
- if ((status = events_start_event_watcher()) != 0) {
- return (status);
+ /*
+ * Only start the event thread if we are not doing an install
+ */
+ if (getenv("_LIBDISKMGT_INSTALL") == NULL) {
+ if ((status = events_start_event_watcher()) != 0) {
+ return (status);
+ }
}
return (0);
diff --git a/usr/src/lib/libdiskmgt/common/disks_private.h b/usr/src/lib/libdiskmgt/common/disks_private.h
index 3239925853..99e8801640 100644
--- a/usr/src/lib/libdiskmgt/common/disks_private.h
+++ b/usr/src/lib/libdiskmgt/common/disks_private.h
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -262,6 +262,7 @@ int libdiskmgt_str_eq(char *nm1, char *nm2);
int inuse_mnt(char *slice, nvlist_t *attrs, int *errp);
int inuse_svm(char *slice, nvlist_t *attrs, int *errp);
int inuse_lu(char *slice, nvlist_t *attrs, int *errp);
+int inuse_zpool(char *slice, nvlist_t *attrs, int *errp);
int inuse_dump(char *slice, nvlist_t *attrs, int *errp);
int inuse_vxvm(char *slice, nvlist_t *attrs, int *errp);
int inuse_fs(char *slice, nvlist_t *attrs, int *errp);
diff --git a/usr/src/lib/libdiskmgt/common/drive.c b/usr/src/lib/libdiskmgt/common/drive.c
index 00fd979ae3..aed1db3b59 100644
--- a/usr/src/lib/libdiskmgt/common/drive.c
+++ b/usr/src/lib/libdiskmgt/common/drive.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -682,7 +682,7 @@ drive_open_disk(disk_t *diskp, char *opath, int len)
}
if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) +
- _PC_NAME_MAX + 1)) == NULL) {
+ PATH_MAX + 1)) == NULL) {
/* out of memory */
(void) close(fd);
return (-1);
diff --git a/usr/src/lib/libdiskmgt/common/entry.c b/usr/src/lib/libdiskmgt/common/entry.c
index cc760dbb83..ac08b47b7f 100644
--- a/usr/src/lib/libdiskmgt/common/entry.c
+++ b/usr/src/lib/libdiskmgt/common/entry.c
@@ -34,11 +34,16 @@
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
+#include <libintl.h>
+#include <locale.h>
+#include <sys/debug.h>
#include "libdiskmgt.h"
#include "disks_private.h"
#include "partition.h"
+extern char *getfullblkname();
+
extern dm_desc_type_t drive_assoc_types[];
extern dm_desc_type_t bus_assoc_types[];
@@ -49,8 +54,11 @@ extern dm_desc_type_t partition_assoc_types[];
extern dm_desc_type_t path_assoc_types[];
extern dm_desc_type_t alias_assoc_types[];
+
static dm_descriptor_t *ptr_array_to_desc_array(descriptor_t **ptrs, int *errp);
static descriptor_t **desc_array_to_ptr_array(dm_descriptor_t *da, int *errp);
+static int build_usage_string(char *dname, char *by, char *data, char **use,
+ int *found, int *errp);
void
dm_free_descriptor(dm_descriptor_t desc)
@@ -403,46 +411,57 @@ dm_get_stats(dm_descriptor_t desc, int stat_type, int *errp)
cache_rlock();
if (!cache_is_valid_desc(dp)) {
- cache_unlock();
- *errp = EBADF;
- return (NULL);
+ cache_unlock();
+ *errp = EBADF;
+ return (NULL);
}
/* verify that the descriptor is still valid */
if (dp->p.generic == NULL) {
- cache_unlock();
- *errp = ENODEV;
- return (NULL);
+ cache_unlock();
+ *errp = ENODEV;
+ return (NULL);
}
switch (dp->type) {
case DM_DRIVE:
- stats = drive_get_stats(dp, stat_type, errp);
- break;
+ stats = drive_get_stats(dp, stat_type, errp);
+ break;
case DM_BUS:
- stats = bus_get_stats(dp, stat_type, errp);
- break;
+ stats = bus_get_stats(dp, stat_type, errp);
+ break;
case DM_CONTROLLER:
- stats = controller_get_stats(dp, stat_type, errp);
- break;
+ stats = controller_get_stats(dp, stat_type, errp);
+ break;
case DM_MEDIA:
- stats = media_get_stats(dp, stat_type, errp);
- break;
+ stats = media_get_stats(dp, stat_type, errp);
+ break;
case DM_SLICE:
- stats = slice_get_stats(dp, stat_type, errp);
- break;
+ if (stat_type == DM_SLICE_STAT_USE) {
+ /*
+ * If NOINUSE_CHECK is set, we do not perform
+ * the in use checking if the user has set stat_type
+ * DM_SLICE_STAT_USE
+ */
+ if (getenv("NOINUSE_CHECK") != NULL) {
+ stats = NULL;
+ break;
+ }
+ }
+ stats = slice_get_stats(dp, stat_type, errp);
+ break;
case DM_PARTITION:
- stats = partition_get_stats(dp, stat_type, errp);
- break;
+ stats = partition_get_stats(dp, stat_type, errp);
+ break;
case DM_PATH:
- stats = path_get_stats(dp, stat_type, errp);
- break;
+ stats = path_get_stats(dp, stat_type, errp);
+ break;
case DM_ALIAS:
- stats = alias_get_stats(dp, stat_type, errp);
- break;
+ stats = alias_get_stats(dp, stat_type, errp);
+ break;
default:
- *errp = EINVAL;
- break;
+ *errp = EINVAL;
+ break;
}
cache_unlock();
@@ -468,7 +487,284 @@ dm_get_type(dm_descriptor_t desc)
return (dp->type);
}
+/*
+ * Returns, via slices paramater, a dm_descriptor_t list of
+ * slices for the named disk drive.
+ */
+void
+dm_get_slices(char *drive, dm_descriptor_t **slices, int *errp)
+{
+ dm_descriptor_t alias;
+ dm_descriptor_t *media;
+ dm_descriptor_t *disk;
+ *slices = NULL;
+ *errp = 0;
+
+ if (drive == NULL) {
+ return;
+ }
+
+ alias = dm_get_descriptor_by_name(DM_ALIAS, drive, errp);
+
+ /*
+ * Errors must be handled by the caller. The dm_descriptor_t *
+ * values will be NULL if an error occured in these calls.
+ */
+
+ if (alias != NULL) {
+ disk = dm_get_associated_descriptors(alias, DM_DRIVE, errp);
+ dm_free_descriptor(alias);
+ if (disk != NULL) {
+ media = dm_get_associated_descriptors(*disk,
+ DM_MEDIA, errp);
+ dm_free_descriptors(disk);
+ if (media != NULL) {
+ *slices = dm_get_associated_descriptors(*media,
+ DM_SLICE, errp);
+ dm_free_descriptors(media);
+ }
+ }
+ }
+}
+/*
+ * Convenience function to get slice stats
+ */
+void
+dm_get_slice_stats(char *slice, nvlist_t **dev_stats, int *errp)
+{
+ dm_descriptor_t devp;
+
+ *dev_stats = NULL;
+ *errp = 0;
+
+ if (slice == NULL) {
+ return;
+ }
+
+ /*
+ * Errors must be handled by the caller. The dm_descriptor_t *
+ * values will be NULL if an error occured in these calls.
+ */
+ devp = dm_get_descriptor_by_name(DM_SLICE, slice, errp);
+ if (devp != NULL) {
+ *dev_stats = dm_get_stats(devp, DM_SLICE_STAT_USE,
+ errp);
+ dm_free_descriptor(devp);
+ }
+}
+
+/*
+ * Returns 'in use' details, if found, about a specific dev_name,
+ * based on the caller(who). It is important to note that it is possible
+ * for there to be more than one 'in use' statistic regarding a dev_name.
+ * The **msg parameter returns a list of 'in use' details. This message
+ * is formatted via gettext().
+ */
+int
+dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
+{
+ nvlist_t *dev_stats = NULL;
+ char *by, *data;
+ nvpair_t *nvwhat = NULL;
+ nvpair_t *nvdesc = NULL;
+ int found = 0;
+ char *dname = NULL;
+
+ *errp = 0;
+ *msg = NULL;
+
+ dname = getfullblkname(dev_name);
+ /*
+ * If we cannot find the block name, we cannot check the device
+ * for in use statistics. So, return found, which is == 0.
+ */
+ if (dname == NULL || *dname == '\0') {
+ return (found);
+ }
+
+ dm_get_slice_stats(dname, &dev_stats, errp);
+ if (dev_stats == NULL) {
+ /*
+ * If there is an error, but it isn't a no device found error
+ * return the error as recorded. Otherwise, with a full
+ * block name, we might not be able to get the slice
+ * associated, and will get an ENODEV error. For example,
+ * an SVM metadevice will return a value from getfullblkname()
+ * but libdiskmgt won't be able to find this device for
+ * statistics gathering. This is expected and we should not
+ * report errnoneous errors.
+ */
+ if (*errp) {
+ if (*errp == ENODEV) {
+ *errp = 0;
+ }
+ }
+ free(dname);
+ return (found);
+ }
+
+ for (;;) {
+
+ nvwhat = nvlist_next_nvpair(dev_stats, nvdesc);
+ nvdesc = nvlist_next_nvpair(dev_stats, nvwhat);
+
+ /*
+ * End of the list found.
+ */
+ if (nvwhat == NULL || nvdesc == NULL) {
+ break;
+ }
+ /*
+ * Otherwise, we check to see if this client(who) cares
+ * about this in use scenario
+ */
+
+ ASSERT(strcmp(nvpair_name(nvwhat), DM_USED_BY) == 0);
+ ASSERT(strcmp(nvpair_name(nvdesc), DM_USED_NAME) == 0);
+ /*
+ * If we error getting the string value continue on
+ * to the next pair(if there is one)
+ */
+ if (nvpair_value_string(nvwhat, &by)) {
+ continue;
+ }
+ if (nvpair_value_string(nvdesc, &data)) {
+ continue;
+ }
+
+ switch (who) {
+ case DM_WHO_MKFS:
+ /*
+ * mkfs is not in use for these cases.
+ * All others are in use.
+ */
+ if (strcmp(by, DM_USE_LU) == 0 ||
+ strcmp(by, DM_USE_FS) == 0) {
+ break;
+ }
+ if (build_usage_string(dname,
+ by, data, msg, &found, errp) != 0) {
+ if (*errp) {
+ goto out;
+ }
+ }
+ break;
+ case DM_WHO_SWAP:
+ /*
+ * Not in use for this.
+ */
+ if (strcmp(by, DM_USE_DUMP) == 0 ||
+ strcmp(by, DM_USE_FS) == 0) {
+ break;
+ }
+
+ if (build_usage_string(dname,
+ by, data, msg, &found, errp) != 0) {
+ if (*errp) {
+ goto out;
+ }
+ }
+ break;
+ case DM_WHO_DUMP:
+ /*
+ * Not in use for this.
+ */
+ if ((strcmp(by, DM_USE_MOUNT) == 0 &&
+ strcmp(data, "swap") == 0) ||
+ strcmp(by, DM_USE_DUMP) == 0 ||
+ strcmp(by, DM_USE_FS) == 0) {
+ break;
+ }
+ if (build_usage_string(dname,
+ by, data, msg, &found, errp)) {
+ if (*errp) {
+ goto out;
+ }
+ }
+ break;
+
+ case DM_WHO_FORMAT:
+ if (strcmp(by, DM_USE_FS) == 0)
+ break;
+ if (build_usage_string(dname,
+ by, data, msg, &found, errp) != 0) {
+ if (*errp) {
+ goto out;
+ }
+ }
+ break;
+ default:
+ /*
+ * nothing found in use for this client
+ * of libdiskmgt. Default is 'not in use'.
+ */
+ break;
+ }
+ }
+out:
+ if (dname != NULL)
+ free(dname);
+ if (dev_stats != NULL)
+ nvlist_free(dev_stats);
+
+ return (found);
+}
+
+void
+dm_get_usage_string(char *what, char *how, char **usage_string)
+{
+
+
+ if (usage_string == NULL || what == NULL) {
+ return;
+ }
+ *usage_string = NULL;
+
+ if (strcmp(what, DM_USE_MOUNT) == 0) {
+ if (strcmp(how, "swap") == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is currently used by swap. Please see swap(1M)."
+ "\n");
+ } else {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is currently mounted on %s."
+ " Please see umount(1M).\n");
+ }
+ } else if (strcmp(what, DM_USE_VFSTAB) == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is normally mounted on %s according to /etc/vfstab. "
+ "Please remove this entry to use this device.\n");
+ } else if (strcmp(what, DM_USE_FS) == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "Warning: %s contains a %s filesystem.\n");
+ } else if (strcmp(what, DM_USE_SVM) == 0) {
+ if (strcmp(how, "mdb") == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s contains an SVM %s. Please see "
+ "metadb(1M).\n");
+ } else {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is part of SVM volume %s. "
+ "Please see metaclear(1M).\n");
+ }
+ } else if (strcmp(what, DM_USE_VXVM) == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is part of VxVM volume %s.\n");
+ } else if (strcmp(what, DM_USE_LU) == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is in use for live upgrade %s. Please see ludelete(1M)."
+ "\n");
+ } else if (strcmp(what, DM_USE_DUMP) == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is in use by %s. Please see dumpadm(1M)."
+ "\n");
+ } else if (strcmp(what, DM_USE_ZPOOL) == 0) {
+ *usage_string = dgettext(TEXT_DOMAIN,
+ "%s is in use by zpool %s. Please see zpool(1M)."
+ "\n");
+ }
+}
void
libdiskmgt_add_str(nvlist_t *attrs, char *name, char *val, int *errp)
{
@@ -597,3 +893,50 @@ ptr_array_to_desc_array(descriptor_t **ptrs, int *errp)
return (da);
#endif
}
+/*
+ * Build the usage string for the in use data. Return the build string in
+ * the msg parameter. This function takes care of reallocing all the memory
+ * for this usage string. Usage string is returned already formatted for
+ * localization.
+ */
+static int
+build_usage_string(char *dname, char *by, char *data, char **msg,
+ int *found, int *errp)
+{
+ int len0;
+ int len1;
+ char *use;
+ char *p;
+
+ *errp = 0;
+
+ dm_get_usage_string(by, data, &use);
+ if (!use) {
+ return (-1);
+ }
+
+ if (*msg)
+ len0 = strlen(*msg);
+ else
+ len0 = 0;
+ /* LINTED */
+ len1 = snprintf(NULL, 0, use, dname, data);
+
+ /*
+ * If multiple in use details they
+ * are listed 1 per line for ease of
+ * reading. dm_find_usage_string
+ * formats these appropriately.
+ */
+ if ((p = realloc(*msg, len0 + len1 + 1)) == NULL) {
+ *errp = errno;
+ free(*msg);
+ return (-1);
+ }
+ *msg = p;
+
+ /* LINTED */
+ (void) snprintf(*msg + len0, len1 + 1, use, dname, data);
+ (*found)++;
+ return (0);
+}
diff --git a/usr/src/lib/libdiskmgt/common/findevs.c b/usr/src/lib/libdiskmgt/common/findevs.c
index 39a9ddfd16..9c55ee7e2d 100644
--- a/usr/src/lib/libdiskmgt/common/findevs.c
+++ b/usr/src/lib/libdiskmgt/common/findevs.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -978,7 +978,7 @@ create_disk(char *deviceid, char *kernel_name, struct search_args *args)
diskp->removable = get_prop(REMOVABLE_PROP, args->node);
if (diskp->removable == -1) {
diskp->removable = 0;
-#ifdef i386
+#if defined(i386) || defined(__amd64)
/*
* x86 does not have removable property. Check for common
* removable drives, zip & jaz, and mark those correctly.
diff --git a/usr/src/lib/libdiskmgt/common/inuse_fs.c b/usr/src/lib/libdiskmgt/common/inuse_fs.c
index 7b37beb8c2..c2e751dcb2 100644
--- a/usr/src/lib/libdiskmgt/common/inuse_fs.c
+++ b/usr/src/lib/libdiskmgt/common/inuse_fs.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -142,7 +142,6 @@ inuse_fs(char *slice, nvlist_t *attrs, int *errp)
libdiskmgt_add_str(attrs, DM_USED_BY, DM_USE_VFSTAB, errp);
libdiskmgt_add_str(attrs, DM_USED_NAME, mountp, errp);
found = 1;
- break;
}
listp = listp->next;
}
diff --git a/usr/src/lib/libdiskmgt/common/inuse_svm.c b/usr/src/lib/libdiskmgt/common/inuse_svm.c
index 9298907af3..d50ba35515 100644
--- a/usr/src/lib/libdiskmgt/common/inuse_svm.c
+++ b/usr/src/lib/libdiskmgt/common/inuse_svm.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -124,35 +124,46 @@ inuse_svm(char *slice, nvlist_t *attrs, int *errp)
(void) mutex_lock(&init_lock);
if (!initialized) {
- /* dynamically load libmeta */
- if (init_svm()) {
- /* need to initialize the cluster library to avoid seg faults */
- (mdl_sdssc_bind_library)();
-
- /* load the SVM cache */
- *errp = load_svm();
-
- if (*errp == 0) {
- /* start a thread to monitor the svm config */
- sysevent_handle_t *shp;
- const char *subclass_list[1];
-
- shp = sysevent_bind_handle(event_handler);
- if (shp != NULL) {
- subclass_list[0] = EC_SUB_ALL;
- if (sysevent_subscribe_event(shp, EC_SVM_CONFIG,
- subclass_list, 1) != 0) {
- *errp = errno;
+ /* dynamically load libmeta */
+ if (init_svm()) {
+ /*
+ * need to initialize the cluster library to
+ * avoid seg faults
+ */
+ (mdl_sdssc_bind_library)();
+
+ /* load the SVM cache */
+ *errp = load_svm();
+
+ if (*errp == 0) {
+ /* start a thread to monitor the svm config */
+ sysevent_handle_t *shp;
+ const char *subclass_list[1];
+ /*
+ * Only start the svmevent thread if
+ * we are not doing an install
+ */
+
+ if (getenv("_LIBDISKMGT_INSTALL") == NULL) {
+ shp = sysevent_bind_handle(
+ event_handler);
+ if (shp != NULL) {
+ subclass_list[0] = EC_SUB_ALL;
+ if (sysevent_subscribe_event(
+ shp, EC_SVM_CONFIG,
+ subclass_list, 1) != 0) {
+ *errp = errno;
+ }
+ } else {
+ *errp = errno;
+ }
+ }
}
- } else {
- *errp = errno;
- }
}
- }
- if (*errp == 0) {
- initialized = 1;
- }
+ if (*errp == 0) {
+ initialized = 1;
+ }
}
(void) mutex_unlock(&init_lock);
diff --git a/usr/src/lib/libdiskmgt/common/inuse_zpool.c b/usr/src/lib/libdiskmgt/common/inuse_zpool.c
new file mode 100644
index 0000000000..9913b7ef22
--- /dev/null
+++ b/usr/src/lib/libdiskmgt/common/inuse_zpool.c
@@ -0,0 +1,124 @@
+/*
+ * 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 2005 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 <stdlib.h>
+#include <stdio.h>
+#include <strings.h>
+#include <sys/param.h>
+#include <sys/errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <thread.h>
+#include <synch.h>
+#include <dlfcn.h>
+#include <link.h>
+#include <ctype.h>
+
+#include "libdiskmgt.h"
+#include "disks_private.h"
+
+/*
+ * Pointers to libzfs.so functions that we dynamically resolve.
+ */
+static int (*zfsdl_zpool_in_use)(int fd, char **desc, char **name);
+
+static mutex_t init_lock = DEFAULTMUTEX;
+static rwlock_t zpool_lock = DEFAULTRWLOCK;
+static int initialized = 0;
+
+static void *init_zpool();
+
+int
+inuse_zpool(char *slice, nvlist_t *attrs, int *errp)
+{
+ int found = 0;
+ char *desc, *name;
+ int fd;
+
+ *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, &desc, &name)) {
+ libdiskmgt_add_str(attrs, DM_USED_BY,
+ DM_USE_ZPOOL, errp);
+ libdiskmgt_add_str(attrs, DM_USED_NAME,
+ name, errp);
+ found = 1;
+ }
+ }
+ (void) rw_unlock(&zpool_lock);
+
+ return (found);
+}
+
+/*
+ * 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, char **, char **))dlsym(lh,
+ "zpool_in_use")) == NULL) {
+ (void) dlclose(lh);
+ return (NULL);
+ }
+
+ return (lh);
+}
diff --git a/usr/src/lib/libdiskmgt/common/libdiskmgt.h b/usr/src/lib/libdiskmgt/common/libdiskmgt.h
index d9c2909539..ee8d1776b7 100644
--- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h
+++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -35,10 +35,21 @@ extern "C" {
#include <libnvpair.h>
-/* typedef void *dm_descriptor_t; */
+/*
+ * Holds all the data regarding the device.
+ * Private to libdiskmgt. Must use dm_xxx functions to set/get data.
+ */
typedef uint64_t dm_descriptor_t;
typedef enum {
+ DM_WHO_MKFS = 0,
+ DM_WHO_ZPOOL,
+ DM_WHO_FORMAT,
+ DM_WHO_SWAP,
+ DM_WHO_DUMP
+} dm_who_type_t;
+
+typedef enum {
DM_DRIVE = 0,
DM_CONTROLLER,
DM_MEDIA,
@@ -199,6 +210,7 @@ typedef enum {
#define DM_USE_VXVM "vxvm"
#define DM_USE_FS "fs"
#define DM_USE_VFSTAB "vfstab"
+#define DM_USE_ZPOOL "zpool"
/* event */
#define DM_EV_NAME "name"
@@ -232,6 +244,13 @@ nvlist_t *dm_get_stats(dm_descriptor_t desc, int stat_type,
void dm_init_event_queue(void(*callback)(nvlist_t *, int),
int *errp);
nvlist_t *dm_get_event(int *errp);
+void dm_get_slices(char *drive, dm_descriptor_t **slices,
+ int *errp);
+void dm_get_slice_stats(char *slice, nvlist_t **dev_stats,
+ int *errp);
+void dm_get_usage_string(char *who, char *data, char **msg);
+int dm_inuse(char *dev_name, char **msg, dm_who_type_t who,
+ int *errp);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libdiskmgt/common/media.c b/usr/src/lib/libdiskmgt/common/media.c
index 364ff92d2a..ac29898ede 100644
--- a/usr/src/lib/libdiskmgt/common/media.c
+++ b/usr/src/lib/libdiskmgt/common/media.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -440,27 +440,6 @@ apply_filter(descriptor_t **media, int filter[], int *errp)
cache_free_descriptor(media[i]);
}
}
-#ifdef i386
- /* XXX Work around bug 4725434 */
- else if (!media[i]->p.disk->removable) {
- int j;
- int match;
-
- match = 0;
- for (j = 0; filter[j] != DM_FILTER_END; j++) {
- if (DM_MT_FIXED == filter[j]) {
- found[pos++] = media[i];
- match = 1;
- break;
- }
- }
-
- if (!match) {
- cache_free_descriptor(media[i]);
- }
- }
-#endif
-
(void) close(fd);
}
found[pos] = NULL;
@@ -506,10 +485,6 @@ get_attrs(disk_t *dp, int fd, nvlist_t *attrs)
/* The first thing to do is read the media */
if (!media_read_info(fd, &minfo)) {
- /* XXX Work around bug 4725434 */
-#ifdef i386
- if (dp->removable)
-#endif
return (ENODEV);
}
diff --git a/usr/src/lib/libdiskmgt/common/partition.c b/usr/src/lib/libdiskmgt/common/partition.c
index 92e3e9579a..32141fc8ac 100644
--- a/usr/src/lib/libdiskmgt/common/partition.c
+++ b/usr/src/lib/libdiskmgt/common/partition.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -101,6 +101,9 @@ partition_get_assocs(descriptor_t *desc, int *errp)
struct ipart iparts[FD_NUMPART];
char pname[MAXPATHLEN];
int conv_flag = 0;
+#if defined(i386) || defined(__amd64)
+ int len;
+#endif
if (get_parts(desc->p.disk, iparts, pname, sizeof (pname)) != 0) {
return (libdiskmgt_empty_desc_array(errp));
@@ -114,17 +117,13 @@ partition_get_assocs(descriptor_t *desc, int *errp)
return (NULL);
}
-#ifdef i386
- {
+#if defined(i386) || defined(__amd64)
/* convert part. name (e.g. c0d0p0) */
- int len;
-
len = strlen(pname);
if (len > 1 && *(pname + (len - 2)) == 'p') {
conv_flag = 1;
*(pname + (len - 1)) = 0;
}
- }
#endif
/*
@@ -336,8 +335,7 @@ partition_make_descriptors()
int i;
char mname[MAXPATHLEN];
int conv_flag = 0;
-
-#ifdef i386
+#if defined(i386) || defined(__amd64)
/* convert part. name (e.g. c0d0p0) */
int len;
@@ -473,15 +471,8 @@ get_parts(disk_t *disk, struct ipart *iparts, char *opath, int opath_len)
/* First make sure media is inserted and spun up. */
if (!media_read_info(fd, &minfo)) {
-#ifdef i386
- /* XXX Work around bug 4725434 */
- if (disk->removable) {
-#endif
(void) close(fd);
return (ENODEV);
-#ifdef i386
- }
-#endif
}
if (!partition_has_fdisk(disk, fd)) {
@@ -659,7 +650,7 @@ open_disk(disk_t *diskp, char *opath, int len)
}
if ((dentp = (struct dirent *)malloc(sizeof (struct dirent) +
- _PC_NAME_MAX + 1)) == NULL) {
+ PATH_MAX + 1)) == NULL) {
/* out of memory */
(void) close(fd);
return (-1);
diff --git a/usr/src/lib/libdiskmgt/common/slice.c b/usr/src/lib/libdiskmgt/common/slice.c
index 607efeb120..c88c0a31c9 100644
--- a/usr/src/lib/libdiskmgt/common/slice.c
+++ b/usr/src/lib/libdiskmgt/common/slice.c
@@ -20,7 +20,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -60,6 +60,7 @@ static struct inuse_detectors {
} detectors[] = {
{inuse_mnt, DM_USE_MOUNT},
{inuse_svm, DM_USE_SVM},
+ {inuse_zpool, DM_USE_ZPOOL},
{inuse_lu, DM_USE_LU},
{inuse_dump, DM_USE_DUMP},
{inuse_vxvm, DM_USE_VXVM},
@@ -453,10 +454,6 @@ get_attrs(descriptor_t *dp, int fd, nvlist_t *attrs)
/* First make sure media is inserted and spun up. */
if (!media_read_info(fd, &minfo)) {
-#ifdef i386
- /* XXX Work around bug 4725434 */
- if (dp->p.disk->removable)
-#endif
return (ENODEV);
}
@@ -838,7 +835,7 @@ get_removable_assocs(descriptor_t *desc, char *volm_path, int *errp)
struct dirent *dentp;
dentp = (struct dirent *)malloc(sizeof (struct dirent) +
- _PC_NAME_MAX + 1);
+ PATH_MAX + 1);
if (dentp != NULL) {
#ifdef _LP64
while (readdir_r(dirp, dentp, &result) != NULL) {
@@ -1092,7 +1089,7 @@ make_volm_dir_descriptors(disk_t *dp, int dirfd, char *volm_path)
error = 0;
dentp = (struct dirent *)malloc(sizeof (struct dirent) +
- _PC_NAME_MAX + 1);
+ PATH_MAX + 1);
if (dentp != NULL) {
#ifdef _LP64
while (readdir_r(dirp, dentp, &result) != NULL) {
@@ -1284,7 +1281,7 @@ match_removable_name(disk_t *diskp, char *name, int *errp)
slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
dentp = (struct dirent *)malloc(sizeof (struct dirent) +
- _PC_NAME_MAX + 1);
+ PATH_MAX + 1);
if (dentp != NULL) {
#ifdef _LP64
while (readdir_r(dirp, dentp, &result) != NULL) {
@@ -1361,7 +1358,7 @@ num_removable_slices(int fd, struct stat *bufp, char *volm_path)
slice_rdsk2dsk(volm_path, devpath, sizeof (devpath));
dentp = (struct dirent *)malloc(sizeof (struct dirent) +
- _PC_NAME_MAX + 1);
+ PATH_MAX + 1);
if (dentp != NULL) {
#ifdef _LP64
while (readdir_r(dirp, dentp, &result) != NULL) {