From owner-svn-src-projects@FreeBSD.ORG Mon Oct 14 23:41:56 2013 Return-Path: Delivered-To: svn-src-projects@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [8.8.178.115]) (using TLSv1 with cipher ADH-AES256-SHA (256/256 bits)) (No client certificate requested) by hub.freebsd.org (Postfix) with ESMTP id 0BD50472; Mon, 14 Oct 2013 23:41:56 +0000 (UTC) (envelope-from asomers@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:1900:2254:2068::e6a:0]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.freebsd.org (Postfix) with ESMTPS id EDACD2082; Mon, 14 Oct 2013 23:41:55 +0000 (UTC) Received: from svn.freebsd.org ([127.0.1.70]) by svn.freebsd.org (8.14.7/8.14.7) with ESMTP id r9ENftX1039330; Mon, 14 Oct 2013 23:41:55 GMT (envelope-from asomers@svn.freebsd.org) Received: (from asomers@localhost) by svn.freebsd.org (8.14.7/8.14.5/Submit) id r9ENftFg039327; Mon, 14 Oct 2013 23:41:55 GMT (envelope-from asomers@svn.freebsd.org) Message-Id: <201310142341.r9ENftFg039327@svn.freebsd.org> From: Alan Somers Date: Mon, 14 Oct 2013 23:41:55 +0000 (UTC) To: src-committers@freebsd.org, svn-src-projects@freebsd.org Subject: svn commit: r256479 - projects/zfsd/head/cddl/sbin/zfsd X-SVN-Group: projects MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-BeenThere: svn-src-projects@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: "SVN commit messages for the src " projects" tree" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 14 Oct 2013 23:41:56 -0000 Author: asomers Date: Mon Oct 14 23:41:55 2013 New Revision: 256479 URL: http://svnweb.freebsd.org/changeset/base/256479 Log: Fix a bug in zfsd: zfsd will fail to autoreplace by physical path a drive if it had previously replaced that same drive when it belonged to a different pool. The solution is to delete case files when their pools are destroyed. A better fix would be to refactor zfsd to eliminate casefiles altogether, and use a more stateless approach. cddl/sbin/zfsd/case_file.cc cddl/sbin/zfsd/zfsd_event.cc Close a case file when its pool is destroyed. Log a warning when two open case files correspond to the same physical path. Submitted by: alans Approved by: ken (mentor) Sponsored by: Spectra Logic Corporation Modified: projects/zfsd/head/cddl/sbin/zfsd/case_file.cc projects/zfsd/head/cddl/sbin/zfsd/case_file.h projects/zfsd/head/cddl/sbin/zfsd/zfsd_event.cc Modified: projects/zfsd/head/cddl/sbin/zfsd/case_file.cc ============================================================================== --- projects/zfsd/head/cddl/sbin/zfsd/case_file.cc Mon Oct 14 23:36:10 2013 (r256478) +++ projects/zfsd/head/cddl/sbin/zfsd/case_file.cc Mon Oct 14 23:41:55 2013 (r256479) @@ -150,15 +150,23 @@ CaseFile::Find(Guid poolGUID, Guid vdevG CaseFile * CaseFile::Find(const string &physPath) { + CaseFile *result = NULL; + for (CaseFileList::iterator curCase = s_activeCases.begin(); curCase != s_activeCases.end(); curCase++) { if ((*curCase)->PhysicalPath() != physPath) continue; - return (*curCase); + if (result != NULL) { + syslog(LOG_WARNING, "Multiple casefiles found for " + "physical path %s. " + "This is most likely a bug in zfsd", + physPath.c_str()); + } + result = *curCase; } - return (NULL); + return (result); } @@ -370,8 +378,12 @@ CaseFile::ReEvaluate(const ZfsEvent &eve Close(); return (/*consumed*/true); - } - else if (event.Value("type") == "misc.fs.zfs.config_sync") { + } else if (event.Value("type") == "misc.fs.zfs.pool_destroy") { + /* This Pool has been destroyed. Discard the case */ + Close(); + + return (/*consumed*/true); + } else if (event.Value("type") == "misc.fs.zfs.config_sync") { RefreshVdevState(); if (VdevState() < VDEV_STATE_HEALTHY) consumed = ActivateSpare(); Modified: projects/zfsd/head/cddl/sbin/zfsd/case_file.h ============================================================================== --- projects/zfsd/head/cddl/sbin/zfsd/case_file.h Mon Oct 14 23:36:10 2013 (r256478) +++ projects/zfsd/head/cddl/sbin/zfsd/case_file.h Mon Oct 14 23:41:55 2013 (r256479) @@ -296,7 +296,7 @@ protected: /** * \brief Unconditionally close a CaseFile. */ - void Close(); + virtual void Close(); /** * \brief Callout callback invoked when the remove timer grace Modified: projects/zfsd/head/cddl/sbin/zfsd/zfsd_event.cc ============================================================================== --- projects/zfsd/head/cddl/sbin/zfsd/zfsd_event.cc Mon Oct 14 23:36:10 2013 (r256478) +++ projects/zfsd/head/cddl/sbin/zfsd/zfsd_event.cc Mon Oct 14 23:41:55 2013 (r256479) @@ -195,6 +195,10 @@ DevfsEvent::Process() const "as a replace by physical path candidate.\n", devName.c_str()); } else if (havePhysPath && IsWholeDev()) { + /* + * TODO: attempt to resolve events using every casefile + * that matches this physpath + */ CaseFile *caseFile(CaseFile::Find(physPath)); if (caseFile != NULL) { syslog(LOG_INFO, @@ -371,6 +375,12 @@ ZfsEvent::ProcessPoolEvent() const { bool degradedDevice(false); + /* The pool is destroyed. Discard any open cases */ + if (Value("type") == "misc.fs.zfs.pool_destroy") { + CaseFile::ReEvaluateByGuid(PoolGUID(), *this); + return; + } + CaseFile *caseFile(CaseFile::Find(PoolGUID(), VdevGUID())); if (caseFile != NULL) { if (caseFile->VdevState() != VDEV_STATE_UNKNOWN