svn commit: r329792 - stable/11/cddl/usr.sbin/zfsd

Alan Somers asomers at FreeBSD.org
Thu Feb 22 02:16:45 UTC 2018


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);


More information about the svn-src-all mailing list