# HG changeset patch # User mmusante # Date 1177116373 25200 # Node ID 2e3825fd8bb5e6d436a8b732f43772fd80168f68 # Parent d68a788b1ca0f1e21bbdab728bffa0c5ca8f9d90 6372011 libdiskmgt needs to build appropriate .po file 6533990 zpool create in-use check fails on svm swap device diff -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/cmd/zpool/zpool_vdev.c --- a/usr/src/cmd/zpool/zpool_vdev.c Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/cmd/zpool/zpool_vdev.c Fri Apr 20 17:46:13 2007 -0700 @@ -137,7 +137,6 @@ { 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 @@ } else { vdev_error("%s", msg); free(msg); - ret = -1; + return (-1); } - } /* @@ -159,18 +157,19 @@ 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 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 @@ 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 -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/lib/Makefile --- a/usr/src/lib/Makefile Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/lib/Makefile Fri Apr 20 17:46:13 2007 -0700 @@ -273,6 +273,7 @@ libdhcpsvc \ libdhcputil \ libipsecutil \ + libdiskmgt \ libdladm \ libgss \ libinetcfg \ diff -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/lib/libdiskmgt/Makefile --- a/usr/src/lib/libdiskmgt/Makefile Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/lib/libdiskmgt/Makefile Fri Apr 20 17:46:13 2007 -0700 @@ -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 @@ 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 @@ FRC: include ../Makefile.targ +include ../../Makefile.msg.targ diff -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/lib/libdiskmgt/common/entry.c --- a/usr/src/lib/libdiskmgt/common/entry.c Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/lib/libdiskmgt/common/entry.c Fri Apr 20 17:46:13 2007 -0700 @@ -36,14 +36,21 @@ #include #include #include +#include +#include +#include #include "libdiskmgt.h" #include "disks_private.h" #include "partition.h" +#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[]; extern dm_desc_type_t controller_assoc_types[]; @@ -727,6 +734,113 @@ } /* + * 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 @@ nvpair_t *nvwhat = NULL; nvpair_t *nvdesc = NULL; int found = 0; + int err; char *dname = NULL; *errp = 0; @@ -762,6 +877,31 @@ 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 -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/lib/libdiskmgt/common/inuse_mnt.c --- a/usr/src/lib/libdiskmgt/common/inuse_mnt.c Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/lib/libdiskmgt/common/inuse_mnt.c Fri Apr 20 17:46:13 2007 -0700 @@ -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 @@ 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 @@ } /* 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 */ - free_mnttab(headp); - return (ENOMEM); - } - - path = malloc(num * MAXPATHLEN); - if (path == NULL) { - /* out of memory, free what we have and return */ - free(st); + num = dm_get_swapentries(&st, &err); + if (num < 0) { free_mnttab(headp); return (ENOMEM); - } - pathstart = path; + } - swapent = st->swt_ent; - for (i = 0; i < num; i++, swapent++) { - swapent->ste_path = path; - path += MAXPATHLEN; - } + for (i = 0, swapent = st->swt_ent; i < num; i++, swapent++) { + char fullpath[MAXPATHLEN+1]; - st->swt_n = num; - if ((num = swapctl(SC_LIST, st)) >= 0) { - swapent = st->swt_ent; - for (i = 0; i < num; i++, swapent++) { + 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 -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/lib/libdiskmgt/common/libdiskmgt.h --- a/usr/src/lib/libdiskmgt/common/libdiskmgt.h Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/lib/libdiskmgt/common/libdiskmgt.h Fri Apr 20 17:46:13 2007 -0700 @@ -33,7 +33,7 @@ #endif #include - +#include /* @@ -235,6 +235,7 @@ 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 @@ 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 -r d68a788b1ca0 -r 2e3825fd8bb5 usr/src/lib/libdiskmgt/common/mapfile-vers --- a/usr/src/lib/libdiskmgt/common/mapfile-vers Fri Apr 20 14:52:21 2007 -0700 +++ b/usr/src/lib/libdiskmgt/common/mapfile-vers Fri Apr 20 17:46:13 2007 -0700 @@ -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 @@ 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 @@ 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: *;