summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authormmusante <none@none>2007-04-20 17:46:13 -0700
committermmusante <none@none>2007-04-20 17:46:13 -0700
commit181c2f42873ba1b0fdc4d0470593ad30176af1f0 (patch)
tree0b7574e6b5f5588bbec4f84d44143cb1577faf35 /usr/src
parenta8d26fb6e548eaca947efd01828081f72750fc0b (diff)
downloadillumos-joyent-181c2f42873ba1b0fdc4d0470593ad30176af1f0.tar.gz
6372011 libdiskmgt needs to build appropriate .po file
6533990 zpool create in-use check fails on svm swap device
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/cmd/zpool/zpool_vdev.c31
-rw-r--r--usr/src/lib/Makefile1
-rw-r--r--usr/src/lib/libdiskmgt/Makefile10
-rw-r--r--usr/src/lib/libdiskmgt/common/entry.c142
-rw-r--r--usr/src/lib/libdiskmgt/common/inuse_mnt.c98
-rw-r--r--usr/src/lib/libdiskmgt/common/libdiskmgt.h5
-rw-r--r--usr/src/lib/libdiskmgt/common/mapfile-vers5
7 files changed, 212 insertions, 80 deletions
diff --git a/usr/src/cmd/zpool/zpool_vdev.c b/usr/src/cmd/zpool/zpool_vdev.c
index 9a41649128..11c231561b 100644
--- a/usr/src/cmd/zpool/zpool_vdev.c
+++ b/usr/src/cmd/zpool/zpool_vdev.c
@@ -137,7 +137,6 @@ check_slice(const char *path, int force, boolean_t wholedisk, boolean_t isspare)
{
char *msg;
int error = 0;
- int ret = 0;
if (dm_inuse((char *)path, &msg, isspare ? DM_WHO_ZPOOL_SPARE :
(force ? DM_WHO_ZPOOL_FORCE : DM_WHO_ZPOOL), &error) || error) {
@@ -147,9 +146,8 @@ check_slice(const char *path, int force, boolean_t wholedisk, boolean_t isspare)
} else {
vdev_error("%s", msg);
free(msg);
- ret = -1;
+ return (-1);
}
-
}
/*
@@ -159,18 +157,19 @@ check_slice(const char *path, int force, boolean_t wholedisk, boolean_t isspare)
error = 0;
if (!wholedisk && !force &&
(dm_isoverlapping((char *)path, &msg, &error) || error)) {
- if (error != 0) {
+ if (error == 0) {
+ /* dm_isoverlapping returned -1 */
+ vdev_error(gettext("%s overlaps with %s\n"), path, msg);
+ free(msg);
+ return (-1);
+ } else if (error != ENODEV) {
+ /* libdiskmgt's devcache only handles physical drives */
libdiskmgt_error(error);
return (0);
- } else {
- vdev_error("%s overlaps with %s\n", path, msg);
- free(msg);
}
-
- ret = -1;
}
- return (ret);
+ return (0);
}
/*
@@ -273,7 +272,7 @@ check_device(const char *path, boolean_t force, boolean_t isspare)
/*
* Check that a file is valid. All we can do in this case is check that it's
- * not in use by another pool.
+ * not in use by another pool, and not in use by swap.
*/
int
check_file(const char *file, boolean_t force, boolean_t isspare)
@@ -281,9 +280,19 @@ check_file(const char *file, boolean_t force, boolean_t isspare)
char *name;
int fd;
int ret = 0;
+ int err;
pool_state_t state;
boolean_t inuse;
+ if (dm_inuse_swap(file, &err)) {
+ if (err)
+ libdiskmgt_error(err);
+ else
+ vdev_error(gettext("%s is currently used by swap. "
+ "Please see swap(1M).\n"), file);
+ return (-1);
+ }
+
if ((fd = open(file, O_RDONLY)) < 0)
return (0);
diff --git a/usr/src/lib/Makefile b/usr/src/lib/Makefile
index 89cebbc9d0..ef6a96f1b8 100644
--- a/usr/src/lib/Makefile
+++ b/usr/src/lib/Makefile
@@ -273,6 +273,7 @@ MSGSUBDIRS= \
libdhcpsvc \
libdhcputil \
libipsecutil \
+ libdiskmgt \
libdladm \
libgss \
libinetcfg \
diff --git a/usr/src/lib/libdiskmgt/Makefile b/usr/src/lib/libdiskmgt/Makefile
index 92b3f02d67..55ca6f483d 100644
--- a/usr/src/lib/libdiskmgt/Makefile
+++ b/usr/src/lib/libdiskmgt/Makefile
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -46,15 +46,20 @@ install := TARGET = install
lint := TARGET = lint
install_h:= TARGET = install_h
+POFILE = libdiskmgt.po
+MSGFILES = `$(GREP) -l gettext common/*.[ch]`
+
.KEEP_STATE:
all clean clobber install lint: $(SUBDIRS)
+$(POFILE): pofile_MSGFILES
+
install_h: $(ROOTHDRS)
check: $(CHECKHDRS)
-$(POFILE):
+_msg: $(MSGDOMAINPOFILE)
$(SUBDIRS): FRC
@cd $@; pwd; $(MAKE) $(TARGET)
@@ -62,3 +67,4 @@ $(SUBDIRS): FRC
FRC:
include ../Makefile.targ
+include ../../Makefile.msg.targ
diff --git a/usr/src/lib/libdiskmgt/common/entry.c b/usr/src/lib/libdiskmgt/common/entry.c
index a123a586f5..a7756b02d4 100644
--- a/usr/src/lib/libdiskmgt/common/entry.c
+++ b/usr/src/lib/libdiskmgt/common/entry.c
@@ -36,13 +36,20 @@
#include <libintl.h>
#include <locale.h>
#include <sys/debug.h>
+#include <strings.h>
+#include <sys/stat.h>
+#include <sys/swap.h>
#include "libdiskmgt.h"
#include "disks_private.h"
#include "partition.h"
-extern char *getfullblkname();
+#define ANY_ZPOOL_USE(who) \
+ (((who) == DM_WHO_ZPOOL_FORCE) || \
+ ((who) == DM_WHO_ZPOOL) || \
+ ((who) == DM_WHO_ZPOOL_SPARE))
+extern char *getfullblkname();
extern dm_desc_type_t drive_assoc_types[];
extern dm_desc_type_t bus_assoc_types[];
@@ -727,6 +734,113 @@ out:
}
/*
+ * Get the full list of swap entries. Returns -1 on error, or >= 0 to
+ * indicate the number of entries in the list. Callers are responsible
+ * for calling dm_free_swapentries() to deallocate memory. If this
+ * returns 0, the swaptbl_t still needs to be freed.
+ */
+int
+dm_get_swapentries(swaptbl_t **stp, int *errp)
+{
+ int count, i;
+ swaptbl_t *tbl;
+ char *ptr;
+
+ *stp = NULL;
+
+ /* get number of swap entries */
+ if ((count = swapctl(SC_GETNSWP, NULL)) < 0) {
+ *errp = errno;
+ return (-1);
+ }
+
+ if (count == 0) {
+ return (0);
+ }
+
+ /* allocate space */
+ tbl = calloc(1, sizeof (int) + count * sizeof (swapent_t));
+ if (tbl == NULL) {
+ *errp = ENOMEM;
+ return (-1);
+ }
+
+ ptr = calloc(1, count * MAXPATHLEN);
+ if (ptr == NULL) {
+ *errp = ENOMEM;
+ free(tbl);
+ return (-1);
+ }
+
+ /* set up pointers to the pathnames */
+ tbl->swt_n = count;
+ for (i = 0; i < count; i++) {
+ tbl->swt_ent[i].ste_path = ptr;
+ ptr += MAXPATHLEN;
+ }
+
+ /* get list of swap paths */
+ count = swapctl(SC_LIST, tbl);
+ if (count < 0) {
+ *errp = errno;
+ free(ptr);
+ free(tbl);
+ return (-1);
+ }
+
+ *stp = tbl;
+ return (count);
+}
+
+/* ARGSUSED */
+void
+dm_free_swapentries(swaptbl_t *stp)
+{
+ ASSERT(stp != NULL);
+
+ free(stp->swt_ent[0].ste_path);
+ free(stp);
+}
+
+/*
+ * Check a slice to see if it's being used by swap.
+ */
+int
+dm_inuse_swap(const char *dev_name, int *errp)
+{
+ int count;
+ int found;
+ swaptbl_t *tbl = NULL;
+
+ *errp = 0;
+
+ count = dm_get_swapentries(&tbl, errp);
+ if (count < 0 || *errp) {
+ if (tbl)
+ dm_free_swapentries(tbl);
+ return (-1);
+ }
+
+ /* if there are no swap entries, we're done */
+ if (!count) {
+ return (0);
+ }
+
+ ASSERT(tbl != NULL);
+
+ found = 0;
+ while (count--) {
+ if (strcmp(dev_name, tbl->swt_ent[count].ste_path) == 0) {
+ found = 1;
+ break;
+ }
+ }
+
+ dm_free_swapentries(tbl);
+ return (found);
+}
+
+/*
* 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.
@@ -741,6 +855,7 @@ dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
nvpair_t *nvwhat = NULL;
nvpair_t *nvdesc = NULL;
int found = 0;
+ int err;
char *dname = NULL;
*errp = 0;
@@ -762,6 +877,31 @@ dm_inuse(char *dev_name, char **msg, dm_who_type_t who, int *errp)
return (found);
}
+ /*
+ * Slice stats for swap devices are only returned if mounted
+ * (e.g. /tmp). Other devices or files being used for swap
+ * are ignored, so we add a special check here to use swapctl(2)
+ * to perform in-use checking.
+ */
+ if (ANY_ZPOOL_USE(who) && (err = dm_inuse_swap(dname, errp))) {
+
+ /* on error, dm_inuse_swap sets errp */
+ if (err < 0) {
+ free(dname);
+ return (err);
+ }
+
+ /* simulate a mounted swap device */
+ (void) build_usage_string(dname, DM_USE_MOUNT, "swap", msg,
+ &found, errp);
+
+ /* if this fails, dm_get_usage_string changed */
+ ASSERT(found == 1);
+
+ free(dname);
+ return (found);
+ }
+
dm_get_slice_stats(dname, &dev_stats, errp);
if (dev_stats == NULL) {
/*
diff --git a/usr/src/lib/libdiskmgt/common/inuse_mnt.c b/usr/src/lib/libdiskmgt/common/inuse_mnt.c
index 54001a46ce..7923dcfa99 100644
--- a/usr/src/lib/libdiskmgt/common/inuse_mnt.c
+++ b/usr/src/lib/libdiskmgt/common/inuse_mnt.c
@@ -2,9 +2,8 @@
* 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.
+ * Common Development and Distribution License (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.
@@ -20,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -207,6 +206,10 @@ load_mnttab(int send_event)
struct mntpnt_list *headp;
int num;
struct mntpnt_list *prevp;
+ struct swaptable *st;
+ struct swapent *swapent;
+ int err;
+ int i;
headp = NULL;
prevp = NULL;
@@ -276,94 +279,61 @@ load_mnttab(int send_event)
}
/* get the swap entries */
- if ((num = swapctl(SC_GETNSWP, NULL)) > -1) {
-
- struct swaptable *st;
- struct swapent *swapent;
- int i;
- char *path;
- char *pathstart;
- char fullpath[MAXPATHLEN+1];
-
- st = malloc((size_t)((num * sizeof (swapent_t)) + sizeof (int)));
- if (st == NULL) {
- /* out of memory, free what we have and return */
+ num = dm_get_swapentries(&st, &err);
+ if (num < 0) {
free_mnttab(headp);
return (ENOMEM);
- }
-
- path = malloc(num * MAXPATHLEN);
- if (path == NULL) {
- /* out of memory, free what we have and return */
- free(st);
- free_mnttab(headp);
- return (ENOMEM);
- }
- pathstart = path;
-
- swapent = st->swt_ent;
- for (i = 0; i < num; i++, swapent++) {
- swapent->ste_path = path;
- path += MAXPATHLEN;
- }
+ }
- st->swt_n = num;
- if ((num = swapctl(SC_LIST, st)) >= 0) {
- swapent = st->swt_ent;
- for (i = 0; i < num; i++, swapent++) {
+ for (i = 0, swapent = st->swt_ent; i < num; i++, swapent++) {
+ char fullpath[MAXPATHLEN+1];
- currp = (struct mntpnt_list *)
- calloc((size_t)1, (size_t)sizeof (struct mntpnt_list));
+ currp = (struct mntpnt_list *)
+ calloc((size_t)1, (size_t)sizeof (struct mntpnt_list));
- if (currp == NULL) {
+ if (currp == NULL) {
/* out of memory, free what we have and return */
- free((void *)st);
- free((void *)pathstart);
+ dm_free_swapentries(st);
free_mnttab(headp);
return (ENOMEM);
- }
+ }
- if (headp == NULL) {
+ if (headp == NULL) {
headp = currp;
- } else {
+ } else {
prevp->next = currp;
- }
+ }
- currp->next = NULL;
+ currp->next = NULL;
- if (*swapent->ste_path != '/') {
+ if (*swapent->ste_path != '/') {
(void) snprintf(fullpath, sizeof (fullpath), "/dev/%s",
swapent->ste_path);
- } else {
+ } else {
(void) strlcpy(fullpath, swapent->ste_path,
sizeof (fullpath));
- }
+ }
- currp->special = strdup(fullpath);
- if (currp->special == NULL) {
+ currp->special = strdup(fullpath);
+ if (currp->special == NULL) {
/* out of memory, free what we have and return */
- free(st);
- free(pathstart);
+ dm_free_swapentries(st);
free_mnttab(headp);
return (ENOMEM);
- }
+ }
- currp->mountp = strdup("swap");
- if (currp->mountp == NULL) {
+ currp->mountp = strdup("swap");
+ if (currp->mountp == NULL) {
/* out of memory, free what we have and return */
- free(st);
- free(pathstart);
+ dm_free_swapentries(st);
free_mnttab(headp);
return (ENOMEM);
- }
-
- prevp = currp;
}
- }
- free(st);
- free(pathstart);
+ prevp = currp;
}
+ if (num)
+ dm_free_swapentries(st);
/* note that we unlock the mutex in both paths of this if statement */
(void) rw_wrlock(&mntpoint_lock);
diff --git a/usr/src/lib/libdiskmgt/common/libdiskmgt.h b/usr/src/lib/libdiskmgt/common/libdiskmgt.h
index 67e1b55bef..3a580cbfb4 100644
--- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h
+++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h
@@ -33,7 +33,7 @@ extern "C" {
#endif
#include <libnvpair.h>
-
+#include <sys/swap.h>
/*
@@ -235,6 +235,7 @@ typedef enum {
void dm_free_descriptors(dm_descriptor_t *desc_list);
void dm_free_descriptor(dm_descriptor_t desc);
void dm_free_name(char *name);
+void dm_free_swapentries(swaptbl_t *);
dm_descriptor_t *dm_get_descriptors(dm_desc_type_t type, int filter[],
int *errp);
@@ -255,9 +256,11 @@ 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);
+int dm_get_swapentries(swaptbl_t **, int *);
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);
+int dm_inuse_swap(const char *dev_name, int *errp);
int dm_isoverlapping(char *dev_name, char **msg, int *errp);
#ifdef __cplusplus
diff --git a/usr/src/lib/libdiskmgt/common/mapfile-vers b/usr/src/lib/libdiskmgt/common/mapfile-vers
index 80a66faf35..10e4005b8e 100644
--- a/usr/src/lib/libdiskmgt/common/mapfile-vers
+++ b/usr/src/lib/libdiskmgt/common/mapfile-vers
@@ -19,7 +19,7 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2007 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# ident "%Z%%M% %I% %E% SMI"
@@ -30,6 +30,7 @@ SUNWprivate_1.1 {
dm_free_descriptor;
dm_free_descriptors;
dm_free_name;
+ dm_free_swapentries;
dm_get_associated_descriptors;
dm_get_associated_types;
dm_get_attributes;
@@ -40,9 +41,11 @@ SUNWprivate_1.1 {
dm_get_slices;
dm_get_slice_stats;
dm_get_stats;
+ dm_get_swapentries;
dm_get_type;
dm_init_event_queue;
dm_inuse;
+ dm_inuse_swap;
dm_isoverlapping;
local:
*;