Speed up "zpool import" in the presence of many zvols
By default, FreeBSD does not allow zpools to be backed by zvols (that can be changed with the "vfs.zfs.vol.recursive" sysctl). When that sysctl is set to 0, the kernel does not attempt to read zvols when looking for vdevs. But the zpool command still does. This change brings the zpool command into line with the kernel's behavior. It speeds "zpool import" when an already imported pool has many zvols, or a zvol with many snapshots. https://svnweb.freebsd.org/base?view=revision&revision=357235 https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=241083 https://reviews.freebsd.org/D22077 Obtained from: FreeBSD Reported by: Martin Birgmeier <d8zNeCFG@aon.at> Sponsored by: Axcient Reviewed-by: Ryan Moeller <ryan@iXsystems.com> Reviewed-by: Alexander Motin <mav@FreeBSD.org> Signed-off-by: Alan Somers <asomers@gmail.com> Closes #11502
This commit is contained in:
parent
8887760aef
commit
fd95af8dd4
|
@ -42,6 +42,12 @@
|
||||||
* using our derived config, and record the results.
|
* using our derived config, and record the results.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/disk.h>
|
||||||
|
#include <sys/ioctl.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <sys/sysctl.h>
|
||||||
|
|
||||||
#include <aio.h>
|
#include <aio.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <dirent.h>
|
#include <dirent.h>
|
||||||
|
@ -51,9 +57,6 @@
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <sys/disk.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
|
||||||
|
@ -181,6 +184,7 @@ int
|
||||||
zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
||||||
avl_tree_t **slice_cache)
|
avl_tree_t **slice_cache)
|
||||||
{
|
{
|
||||||
|
const char *oid = "vfs.zfs.vol.recursive";
|
||||||
char *end, path[MAXPATHLEN];
|
char *end, path[MAXPATHLEN];
|
||||||
rdsk_node_t *slice;
|
rdsk_node_t *slice;
|
||||||
struct gmesh mesh;
|
struct gmesh mesh;
|
||||||
|
@ -188,8 +192,9 @@ zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
||||||
struct ggeom *gp;
|
struct ggeom *gp;
|
||||||
struct gprovider *pp;
|
struct gprovider *pp;
|
||||||
avl_index_t where;
|
avl_index_t where;
|
||||||
size_t pathleft;
|
int error, value;
|
||||||
int error;
|
size_t pathleft, size = sizeof (value);
|
||||||
|
boolean_t skip_zvols = B_FALSE;
|
||||||
|
|
||||||
end = stpcpy(path, "/dev/");
|
end = stpcpy(path, "/dev/");
|
||||||
pathleft = &path[sizeof (path)] - end;
|
pathleft = &path[sizeof (path)] - end;
|
||||||
|
@ -198,11 +203,16 @@ zpool_find_import_blkid(libpc_handle_t *hdl, pthread_mutex_t *lock,
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
|
if (sysctlbyname(oid, &value, &size, NULL, 0) == 0 && value == 0)
|
||||||
|
skip_zvols = B_TRUE;
|
||||||
|
|
||||||
*slice_cache = zutil_alloc(hdl, sizeof (avl_tree_t));
|
*slice_cache = zutil_alloc(hdl, sizeof (avl_tree_t));
|
||||||
avl_create(*slice_cache, slice_cache_compare, sizeof (rdsk_node_t),
|
avl_create(*slice_cache, slice_cache_compare, sizeof (rdsk_node_t),
|
||||||
offsetof(rdsk_node_t, rn_node));
|
offsetof(rdsk_node_t, rn_node));
|
||||||
|
|
||||||
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
|
LIST_FOREACH(mp, &mesh.lg_class, lg_class) {
|
||||||
|
if (skip_zvols && strcmp(mp->lg_name, "ZFS::ZVOL") == 0)
|
||||||
|
continue;
|
||||||
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
|
LIST_FOREACH(gp, &mp->lg_geom, lg_geom) {
|
||||||
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
LIST_FOREACH(pp, &gp->lg_provider, lg_provider) {
|
||||||
strlcpy(end, pp->lg_name, pathleft);
|
strlcpy(end, pp->lg_name, pathleft);
|
||||||
|
|
Loading…
Reference in New Issue