Date: Thu, 22 Feb 2018 02:16:44 +0000 (UTC) From: Alan Somers <asomers@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org Subject: svn commit: r329792 - stable/11/cddl/usr.sbin/zfsd Message-ID: <201802220216.w1M2GiVw063037@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: asomers Date: Thu Feb 22 02:16:44 2018 New Revision: 329792 URL: https://svnweb.freebsd.org/changeset/base/329792 Log: MFC r328605: zfsd: Don't spare a vdev that's being replaced If a zfs pool contains a replacing vdev (either created manually by "zpool replace" or by zfsd(8) via autoreplace by physical path) and then new spares get added to the pool, zfsd shouldn't use one to replace the drive that is already being replaced. That's a waste of resources that just slows down the rebuild. PR: 225547 Sponsored by: Spectra Logic Corp Modified: stable/11/cddl/usr.sbin/zfsd/case_file.cc Directory Properties: stable/11/ (props changed) Modified: stable/11/cddl/usr.sbin/zfsd/case_file.cc ============================================================================== --- stable/11/cddl/usr.sbin/zfsd/case_file.cc Thu Feb 22 02:15:45 2018 (r329791) +++ stable/11/cddl/usr.sbin/zfsd/case_file.cc Thu Feb 22 02:16:44 2018 (r329792) @@ -442,10 +442,38 @@ CaseFile::ReEvaluate(const ZfsEvent &event) return (consumed || closed); } +/* Find a Vdev containing the vdev with the given GUID */ +static nvlist_t* +find_parent(nvlist_t *pool_config, nvlist_t *config, DevdCtl::Guid child_guid) +{ + nvlist_t **vdevChildren; + int error; + unsigned ch, numChildren; + error = nvlist_lookup_nvlist_array(config, ZPOOL_CONFIG_CHILDREN, + &vdevChildren, &numChildren); + + if (error != 0 || numChildren == 0) + return (NULL); + + for (ch = 0; ch < numChildren; ch++) { + nvlist *result; + Vdev vdev(pool_config, vdevChildren[ch]); + + if (vdev.GUID() == child_guid) + return (config); + + result = find_parent(pool_config, vdevChildren[ch], child_guid); + if (result != NULL) + return (result); + } + + return (NULL); +} + bool CaseFile::ActivateSpare() { - nvlist_t *config, *nvroot; + nvlist_t *config, *nvroot, *parent_config; nvlist_t **spares; char *devPath, *vdev_type; const char *poolname; @@ -472,6 +500,22 @@ CaseFile::ActivateSpare() { "tree for pool %s", poolname); return (false); } + + parent_config = find_parent(config, nvroot, m_vdevGUID); + if (parent_config != NULL) { + char *parent_type; + + /* + * Don't activate spares for members of a "replacing" vdev. + * They're already dealt with. Sparing them will just drag out + * the resilver process. + */ + error = nvlist_lookup_string(parent_config, + ZPOOL_CONFIG_TYPE, &parent_type); + if (error == 0 && strcmp(parent_type, VDEV_TYPE_REPLACING) == 0) + return (false); + } + nspares = 0; nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_SPARES, &spares, &nspares);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201802220216.w1M2GiVw063037>