Skip to content

Commit

Permalink
6438937 if 'zfs destroy' fails, it can leave a zvol device link missing
Browse files Browse the repository at this point in the history
6573142 zpool destruction/export should better handle stale zvol links
6718816 ZFS volinit fails when ZFS root pool full
6761786 zpool import with 8500 snapshots took 11hours
6604403 replace volinit/volfini with /dev fs vnode ops
6847760 zfs volinit may happen a little too soon during boot
6488792 Warnings on console whenever a volume is created.
6738837 assertion failure in sdev_open
6878496 dmu_objset_own returns EINVAL instead of EROFS in some situations
  • Loading branch information
Eric Taylor authored and Eric Taylor committed Sep 21, 2009
1 parent 14d3298 commit 681d976
Show file tree
Hide file tree
Showing 37 changed files with 1,234 additions and 1,459 deletions.
61 changes: 5 additions & 56 deletions usr/src/cmd/devfsadm/zfs_link.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
* Copyright 2005 Sun Microsystems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

#pragma ident "%Z%%M% %I% %E% SMI"

#include <regex.h>
#include <devfsadm.h>
#include <stdio.h>
Expand All @@ -35,9 +32,7 @@
#include <sys/mkdev.h>
#include <sys/fs/zfs.h>

/* zfs and zvol name info */

#define ZVOL_LINK_RE_DEVICES "zvol/r?dsk/.*/.*$"
/* zfs name info */

static int zfs(di_minor_t minor, di_node_t node);

Expand All @@ -52,64 +47,18 @@ static devfsadm_create_t zfs_create_cbt[] = {
DEVFSADM_CREATE_INIT_V0(zfs_create_cbt);

/*
* devfs cleanup register
*/
static devfsadm_remove_t zfs_remove_cbt[] = {
{ "pseudo", ZVOL_LINK_RE_DEVICES, RM_HOT | RM_POST,
ILEVEL_0, devfsadm_rm_all },
};
DEVFSADM_REMOVE_INIT_V0(zfs_remove_cbt);

/*
* For the zfs control node:
* The zfs control node looks like this:
* /dev/zfs -> /devices/pseudo/zfs@0:zfs
* For zvols:
* /dev/zvol/dsk/<pool>/<dataset> -> /devices/pseudo/zfs@0:1
* /dev/zvol/rdsk/<pool>/<dataset> -> /devices/pseudo/zfs@0:1,raw
*/
static int
zfs(di_minor_t minor, di_node_t node)
{
dev_t dev;
int err;
char mn[MAXNAMELEN + 1];
char blkname[MAXNAMELEN + 1];
char rawname[MAXNAMELEN + 1];
char path[PATH_MAX + 1];
char *name;

(void) strcpy(mn, di_minor_name(minor));

if (strcmp(mn, ZFS_DRIVER) == 0) {
(void) devfsadm_mklink(ZFS_DRIVER, node, minor, 0);
} else {
dev = di_minor_devt(minor);
err = di_prop_lookup_strings(dev, node, ZVOL_PROP_NAME, &name);
if (err < 0) {
/* property not defined so can't do anything */
return (DEVFSADM_CONTINUE);
}
(void) snprintf(blkname, sizeof (blkname), "%dc",
(int)minor(dev));
(void) snprintf(rawname, sizeof (rawname), "%dc,raw",
(int)minor(dev));

/*
* This is where the actual public name gets constructed.
* Change the snprintf format to change the public
* path that gets constructed.
*/
if (strcmp(mn, blkname) == 0) {
(void) snprintf(path, sizeof (path), "%s/%s",
ZVOL_DEV_DIR, name);
} else if (strcmp(mn, rawname) == 0) {
(void) snprintf(path, sizeof (path), "%s/%s",
ZVOL_RDEV_DIR, name);
} else {
return (DEVFSADM_CONTINUE);
}

(void) devfsadm_mklink(path, node, minor, 0);
}
return (DEVFSADM_CONTINUE);
}
9 changes: 0 additions & 9 deletions usr/src/cmd/svc/milestone/devices-local
Original file line number Diff line number Diff line change
Expand Up @@ -75,13 +75,4 @@ if [ $? -eq 0 ]; then
fi
fi

# Create any zvol devices
if [ -x /usr/sbin/zfs ]; then
/usr/sbin/zfs volinit || exit $SMF_EXIT_ERR_FATAL
#
# Add swap again to allow for swapping to zvols.
#
/sbin/swapadd
fi

exit $SMF_EXIT_OK
14 changes: 1 addition & 13 deletions usr/src/cmd/svc/milestone/fs-usr
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,13 @@
# CDDL HEADER END
#
#
# Copyright 2008 Sun Microsystems, Inc. All rights reserved.
# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
# Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T.
# All rights reserved.
#
#
# ident "%Z%%M% %I% %E% SMI"

. /lib/svc/share/smf_include.sh
. /lib/svc/share/fs_include.sh

Expand All @@ -55,16 +53,6 @@ dump_setup()
# If we have a dedicated dump device, then go ahead and configure it.
#
if [ "x$special" != "x$DUMPADM_DEVICE" ]; then
if [ -x /usr/sbin/zfs ]; then
dataset=`echo $DUMPADM_DEVICE | cut -d'/' -f5-`
[ -n "$dataset" ] && \
/usr/sbin/zfs list -t volume $dataset > \
/dev/null 2>&1
if [ $? -eq 0 ]; then
/usr/sbin/zfs volinit
fi
fi

if [ -x /usr/sbin/dumpadm -a -b $DUMPADM_DEVICE ]; then
/usr/sbin/dumpadm -u || exit $SMF_EXIT_ERR_CONFIG
fi
Expand Down
4 changes: 0 additions & 4 deletions usr/src/cmd/truss/codes.c
Original file line number Diff line number Diff line change
Expand Up @@ -1186,10 +1186,6 @@ const struct ioc {
"zfs_cmd_t" },
{ (uint_t)ZFS_IOC_SET_PROP, "ZFS_IOC_SET_PROP",
"zfs_cmd_t" },
{ (uint_t)ZFS_IOC_CREATE_MINOR, "ZFS_IOC_CREATE_MINOR",
"zfs_cmd_t" },
{ (uint_t)ZFS_IOC_REMOVE_MINOR, "ZFS_IOC_REMOVE_MINOR",
"zfs_cmd_t" },
{ (uint_t)ZFS_IOC_CREATE, "ZFS_IOC_CREATE",
"zfs_cmd_t" },
{ (uint_t)ZFS_IOC_DESTROY, "ZFS_IOC_DESTROY",
Expand Down
32 changes: 1 addition & 31 deletions usr/src/cmd/zfs/zfs_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -875,7 +875,7 @@ destroy_callback(zfs_handle_t *zhp, void *data)

/*
* Ignore pools (which we've already flagged as an error before getting
* here.
* here).
*/
if (strchr(zfs_get_name(zhp), '/') == NULL &&
zfs_get_type(zhp) == ZFS_TYPE_FILESYSTEM) {
Expand Down Expand Up @@ -3996,27 +3996,6 @@ manual_unmount(int argc, char **argv)
return (unshare_unmount_path(OP_MOUNT, argv[0], flags, B_TRUE));
}

static int
volcheck(zpool_handle_t *zhp, void *data)
{
boolean_t isinit = *((boolean_t *)data);

if (isinit)
return (zpool_create_zvol_links(zhp));
else
return (zpool_remove_zvol_links(zhp));
}

/*
* Iterate over all pools in the system and either create or destroy /dev/zvol
* links, depending on the value of 'isinit'.
*/
static int
do_volcheck(boolean_t isinit)
{
return (zpool_iter(g_zfs, volcheck, &isinit) ? 1 : 0);
}

static int
find_command_idx(char *command, int *idx)
{
Expand Down Expand Up @@ -4102,15 +4081,6 @@ main(int argc, char **argv)
if (strcmp(cmdname, "-?") == 0)
usage(B_TRUE);

/*
* 'volinit' and 'volfini' do not appear in the usage message,
* so we have to special case them here.
*/
if (strcmp(cmdname, "volinit") == 0)
return (do_volcheck(B_TRUE));
else if (strcmp(cmdname, "volfini") == 0)
return (do_volcheck(B_FALSE));

/*
* Run the appropriate command.
*/
Expand Down
2 changes: 1 addition & 1 deletion usr/src/cmd/ztest/ztest.c
Original file line number Diff line number Diff line change
Expand Up @@ -1712,7 +1712,7 @@ ztest_dsl_dataset_promote_busy(ztest_args_t *za)
error = dsl_dataset_own(snap1name, B_FALSE, FTAG, &ds);
if (error)
fatal(0, "dsl_dataset_own(%s) = %d", snap1name, error);
error = dsl_dataset_promote(clone2name);
error = dsl_dataset_promote(clone2name, NULL);
if (error != EBUSY)
fatal(0, "dsl_dataset_promote(%s), %d, not EBUSY", clone2name,
error);
Expand Down
31 changes: 29 additions & 2 deletions usr/src/lib/libdiskmgt/common/findevs.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/

Expand All @@ -31,6 +31,7 @@
#include <sys/stat.h>
#include <sys/sunddi.h>
#include <sys/types.h>
#include <sys/mkdev.h>
#include <ctype.h>
#include <libgen.h>
#include <unistd.h>
Expand Down Expand Up @@ -579,6 +580,32 @@ add_devs(di_node_t node, di_minor_t minor, void *arg)
}
}
}
if (is_zvol(node, minor)) {
char zvdsk[MAXNAMELEN];
char *str;
alias_t *ap;

if (di_prop_lookup_strings(di_minor_devt(minor),
node, "name", &str) == -1)
return (DI_WALK_CONTINUE);
(void) snprintf(zvdsk, MAXNAMELEN, "/dev/zvol/rdsk/%s",
str);
if ((ap = find_alias(diskp, kernel_name)) == NULL) {
if (new_alias(diskp, kernel_name,
zvdsk, args) != 0) {
args->dev_walk_status = ENOMEM;
}
} else {
/*
* It is possible that we have already added this devpath.
* Do not add it again. new_devpath will return a 0 if
* found, and not add the path.
*/
if (new_devpath(ap, zvdsk) != 0) {
args->dev_walk_status = ENOMEM;
}
}
}

/* Add the devpaths for the drive. */
if (args->dev_walk_status == 0) {
Expand Down Expand Up @@ -1537,7 +1564,7 @@ static int
is_zvol(di_node_t node, di_minor_t minor)
{
if ((strncmp(di_node_name(node), ZFS_DRIVER, 3) == 0) &&
di_minor_devt(minor))
minor(di_minor_devt(minor)))
return (1);
return (0);
}
Expand Down
2 changes: 1 addition & 1 deletion usr/src/lib/libzfs/Makefile.com
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ INCS += -I../../../common/zfs

C99MODE= -xc99=%all
C99LMODE= -Xc99=%all
LDLIBS += -lc -lm -ldevinfo -ldevid -lgen -lnvpair -luutil -lavl -lefi \
LDLIBS += -lc -lm -ldevid -lgen -lnvpair -luutil -lavl -lefi \
-lidmap
CPPFLAGS += $(INCS) -D_REENTRANT

Expand Down
8 changes: 0 additions & 8 deletions usr/src/lib/libzfs/common/libzfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ enum {
EZFS_BADSTREAM, /* bad backup stream */
EZFS_DSREADONLY, /* dataset is readonly */
EZFS_VOLTOOBIG, /* volume is too large for 32-bit system */
EZFS_VOLHASDATA, /* volume already contains data */
EZFS_INVALIDNAME, /* invalid dataset name */
EZFS_BADRESTORE, /* unable to restore to destination */
EZFS_BADBACKUP, /* backup failed */
Expand All @@ -85,7 +84,6 @@ enum {
EZFS_UMOUNTFAILED, /* failed to unmount dataset */
EZFS_UNSHARENFSFAILED, /* unshare(1M) failed */
EZFS_SHARENFSFAILED, /* share(1M) failed */
EZFS_DEVLINKS, /* failed to create zvol links */
EZFS_PERM, /* permission denied */
EZFS_NOSPC, /* out of space */
EZFS_IO, /* I/O error */
Expand Down Expand Up @@ -582,12 +580,6 @@ extern int zpool_in_use(libzfs_handle_t *, int, pool_state_t *, char **,
*/
extern int zpool_read_label(int, nvlist_t **);

/*
* Create and remove zvol /dev links.
*/
extern int zpool_create_zvol_links(zpool_handle_t *);
extern int zpool_remove_zvol_links(zpool_handle_t *);

/* is this zvol valid for use as a dump device? */
extern int zvol_check_dump_config(char *);

Expand Down
22 changes: 2 additions & 20 deletions usr/src/lib/libzfs/common/libzfs_changelist.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,18 +119,8 @@ changelist_prefix(prop_changelist_t *clp)
if (ZFS_IS_VOLUME(cn->cn_handle)) {
switch (clp->cl_realprop) {
case ZFS_PROP_NAME:
/*
* If this was a rename, unshare the zvol, and
* remove the /dev/zvol links.
*/
/* If this was a rename, unshare the zvol */
(void) zfs_unshare_iscsi(cn->cn_handle);

if (zvol_remove_link(cn->cn_handle->zfs_hdl,
cn->cn_handle->zfs_name) != 0) {
ret = -1;
cn->cn_needpost = B_FALSE;
(void) zfs_share_iscsi(cn->cn_handle);
}
break;

case ZFS_PROP_VOLSIZE:
Expand Down Expand Up @@ -235,15 +225,7 @@ changelist_postfix(prop_changelist_t *clp)
zfs_refresh_properties(cn->cn_handle);

if (ZFS_IS_VOLUME(cn->cn_handle)) {
/*
* If we're doing a rename, recreate the /dev/zvol
* links.
*/
if (clp->cl_realprop == ZFS_PROP_NAME &&
zvol_create_link(cn->cn_handle->zfs_hdl,
cn->cn_handle->zfs_name) != 0) {
errors++;
} else if (cn->cn_shared ||
if (cn->cn_shared ||
clp->cl_prop == ZFS_PROP_SHAREISCSI) {
if (zfs_prop_get(cn->cn_handle,
ZFS_PROP_SHAREISCSI, shareopts,
Expand Down
Loading

0 comments on commit 681d976

Please sign in to comment.