4521 zfstest is trying to execute evil "zfs unmount -a"
illumos/illumos-gate@8808ac5dae
8808ac5dae
https://www.illumos.org/issues/4521
zfstest is trying to execute evil "zfs unmount -a", which fails (fortunately,
as it would otherwise leave me with my ~ missing):
03:44:11.86 cannot unmount '/export/home/yuri': Device busy cannot unmount '/
export/home': Device busy
03:44:11.86 ERROR: /usr/sbin/zfs unmount -a exited 1
This affects, at least, zfs_mount_009_neg and zfs_mount_all_001_pos, both
failing on that step. The pool containing the /export/home hierarchy is
included in KEEP variable, but it doesn't seem to affect anything here.
Reviewed by: Andriy Gapon <avg@FreeBSD.org>
Reviewed by: Dan McDonald <danmcd@omniti.com>
Reviewed by: Matthew Ahrens <mahrens@delphix.com>
Reviewed by: John Kennedy <john.kennedy@delphix.com>
Approved by: Robert Mustacchi <rm@joyent.com>
Author: Yuri Pankov <yuri.pankov@nexenta.com>
This commit is contained in:
parent
9b1e23defb
commit
aecdfa442a
@ -26,9 +26,9 @@
|
|||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
|
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2014 Integros [integros.com]
|
* Copyright (c) 2014 Integros [integros.com]
|
||||||
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
* Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
|
||||||
|
* Copyright 2016 Nexenta Systems, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
@ -6388,6 +6388,15 @@ unshare_unmount(int op, int argc, char **argv)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Ignore datasets that are excluded/restricted by
|
||||||
|
* parent pool name.
|
||||||
|
*/
|
||||||
|
if (zpool_skip_pool(zfs_get_pool_name(zhp))) {
|
||||||
|
zfs_close(zhp);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
switch (op) {
|
switch (op) {
|
||||||
case OP_SHARE:
|
case OP_SHARE:
|
||||||
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
|
verify(zfs_prop_get(zhp, ZFS_PROP_SHARENFS,
|
||||||
|
@ -25,8 +25,8 @@
|
|||||||
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
* Copyright (c) 2011, 2015 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
* Copyright (c) 2012, Joyent, Inc. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2014 Integros [integros.com]
|
* Copyright (c) 2014 Integros [integros.com]
|
||||||
|
* Copyright 2016 Nexenta Systems, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _LIBZFS_H
|
#ifndef _LIBZFS_H
|
||||||
@ -220,6 +220,7 @@ extern void zpool_free_handles(libzfs_handle_t *);
|
|||||||
*/
|
*/
|
||||||
typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
|
typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
|
||||||
extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
|
extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
|
||||||
|
extern boolean_t zpool_skip_pool(const char *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Functions to create and destroy pools
|
* Functions to create and destroy pools
|
||||||
@ -409,6 +410,7 @@ extern void zfs_close(zfs_handle_t *);
|
|||||||
extern zfs_type_t zfs_get_type(const zfs_handle_t *);
|
extern zfs_type_t zfs_get_type(const zfs_handle_t *);
|
||||||
extern const char *zfs_get_name(const zfs_handle_t *);
|
extern const char *zfs_get_name(const zfs_handle_t *);
|
||||||
extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
|
extern zpool_handle_t *zfs_get_pool_handle(const zfs_handle_t *);
|
||||||
|
extern const char *zfs_get_pool_name(const zfs_handle_t *);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Property management functions. Some functions are shared with the kernel,
|
* Property management functions. Some functions are shared with the kernel,
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 by Delphix. All rights reserved.
|
* Copyright (c) 2012 by Delphix. All rights reserved.
|
||||||
* Copyright (c) 2015 by Syneto S.R.L. All rights reserved.
|
* Copyright (c) 2015 by Syneto S.R.L. All rights reserved.
|
||||||
|
* Copyright 2016 Nexenta Systems, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -338,33 +339,47 @@ zpool_refresh_stats(zpool_handle_t *zhp, boolean_t *missing)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the __ZFS_POOL_RESTRICT environment variable is set we only iterate over
|
* The following environment variables are undocumented
|
||||||
* pools it lists.
|
* and should be used for testing purposes only:
|
||||||
*
|
*
|
||||||
* This is an undocumented feature for use during testing only.
|
* __ZFS_POOL_EXCLUDE - don't iterate over the pools it lists
|
||||||
|
* __ZFS_POOL_RESTRICT - iterate only over the pools it lists
|
||||||
*
|
*
|
||||||
* This function returns B_TRUE if the pool should be skipped
|
* This function returns B_TRUE if the pool should be skipped
|
||||||
* during iteration.
|
* during iteration.
|
||||||
*/
|
*/
|
||||||
static boolean_t
|
boolean_t
|
||||||
check_restricted(const char *poolname)
|
zpool_skip_pool(const char *poolname)
|
||||||
{
|
{
|
||||||
static boolean_t initialized = B_FALSE;
|
static boolean_t initialized = B_FALSE;
|
||||||
static char *restricted = NULL;
|
static const char *exclude = NULL;
|
||||||
|
static const char *restricted = NULL;
|
||||||
|
|
||||||
const char *cur, *end;
|
const char *cur, *end;
|
||||||
int len, namelen;
|
int len;
|
||||||
|
int namelen = strlen(poolname);
|
||||||
|
|
||||||
if (!initialized) {
|
if (!initialized) {
|
||||||
initialized = B_TRUE;
|
initialized = B_TRUE;
|
||||||
|
exclude = getenv("__ZFS_POOL_EXCLUDE");
|
||||||
restricted = getenv("__ZFS_POOL_RESTRICT");
|
restricted = getenv("__ZFS_POOL_RESTRICT");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (exclude != NULL) {
|
||||||
|
cur = exclude;
|
||||||
|
do {
|
||||||
|
end = strchr(cur, ' ');
|
||||||
|
len = (NULL == end) ? strlen(cur) : (end - cur);
|
||||||
|
if (len == namelen && 0 == strncmp(cur, poolname, len))
|
||||||
|
return (B_TRUE);
|
||||||
|
cur += (len + 1);
|
||||||
|
} while (NULL != end);
|
||||||
|
}
|
||||||
|
|
||||||
if (NULL == restricted)
|
if (NULL == restricted)
|
||||||
return (B_FALSE);
|
return (B_FALSE);
|
||||||
|
|
||||||
cur = restricted;
|
cur = restricted;
|
||||||
namelen = strlen(poolname);
|
|
||||||
do {
|
do {
|
||||||
end = strchr(cur, ' ');
|
end = strchr(cur, ' ');
|
||||||
len = (NULL == end) ? strlen(cur) : (end - cur);
|
len = (NULL == end) ? strlen(cur) : (end - cur);
|
||||||
@ -402,7 +417,7 @@ zpool_iter(libzfs_handle_t *hdl, zpool_iter_f func, void *data)
|
|||||||
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
||||||
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
||||||
|
|
||||||
if (check_restricted(cn->cn_name))
|
if (zpool_skip_pool(cn->cn_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) {
|
if (zpool_open_silent(hdl, cn->cn_name, &zhp) != 0) {
|
||||||
@ -440,7 +455,7 @@ zfs_iter_root(libzfs_handle_t *hdl, zfs_iter_f func, void *data)
|
|||||||
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
for (cn = uu_avl_first(hdl->libzfs_ns_avl); cn != NULL;
|
||||||
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
cn = uu_avl_next(hdl->libzfs_ns_avl, cn)) {
|
||||||
|
|
||||||
if (check_restricted(cn->cn_name))
|
if (zpool_skip_pool(cn->cn_name))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL)
|
if ((zhp = make_dataset_handle(hdl, cn->cn_name)) == NULL)
|
||||||
|
@ -27,8 +27,8 @@
|
|||||||
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
|
* Copyright (c) 2011-2012 Pawel Jakub Dawidek. All rights reserved.
|
||||||
* Copyright (c) 2013 Martin Matuska. All rights reserved.
|
* Copyright (c) 2013 Martin Matuska. All rights reserved.
|
||||||
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
* Copyright (c) 2013 Steven Hartland. All rights reserved.
|
||||||
* Copyright 2013 Nexenta Systems, Inc. All rights reserved.
|
|
||||||
* Copyright (c) 2014 Integros [integros.com]
|
* Copyright (c) 2014 Integros [integros.com]
|
||||||
|
* Copyright 2016 Nexenta Systems, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
@ -2906,6 +2906,15 @@ zfs_get_name(const zfs_handle_t *zhp)
|
|||||||
return (zhp->zfs_name);
|
return (zhp->zfs_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the name of the parent pool for the given zfs handle.
|
||||||
|
*/
|
||||||
|
const char *
|
||||||
|
zfs_get_pool_name(const zfs_handle_t *zhp)
|
||||||
|
{
|
||||||
|
return (zhp->zpool_hdl->zpool_name);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Returns the type of the given zfs handle.
|
* Returns the type of the given zfs handle.
|
||||||
*/
|
*/
|
||||||
|
Loading…
x
Reference in New Issue
Block a user