From 12a88a3d637e7e7a3726e8dedbcf82cb96cea529 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Thu, 26 Oct 2017 15:28:18 +0000 Subject: [PATCH] zfsd should be able to online an L2ARC that disappears and returns Previously, this didn't work because L2ARC devices' labels don't contain pool GUIDs. Modify zfsd so that the pool GUID won't be required: lib/libdevdctl/guid.h Change INVALID_GUID from a uint64_t constant to a function that returns an invalid Guid object. Remove the void constructor. Nothing uses it, and it violates RAII. cddl/usr.sbin/zfsd/case_file.h cddl/usr.sbin/zfsd/case_file.cc Allow CaseFile::Find to match a CaseFile based on Vdev GUID alone. In CaseFile::ReEvaluate, attempt to online devices even if the newly arrived device has no pool GUID. cddl/usr.sbin/zfsd/vdev_iterator.cc Iterate through a pool's cache devices as well as its regular devices. Reported by: avg Reviewed by: avg MFC after: 3 weeks Sponsored by: Spectra Logic Corp Differential Revision: https://reviews.freebsd.org/D12791 --- cddl/usr.sbin/zfsd/case_file.cc | 6 ++++-- cddl/usr.sbin/zfsd/case_file.h | 2 ++ cddl/usr.sbin/zfsd/vdev_iterator.cc | 9 +++++++++ lib/libdevdctl/guid.h | 17 +++++++++-------- 4 files changed, 24 insertions(+), 10 deletions(-) diff --git a/cddl/usr.sbin/zfsd/case_file.cc b/cddl/usr.sbin/zfsd/case_file.cc index 0cd659622e94..c3105853b29c 100644 --- a/cddl/usr.sbin/zfsd/case_file.cc +++ b/cddl/usr.sbin/zfsd/case_file.cc @@ -102,7 +102,8 @@ CaseFile::Find(Guid poolGUID, Guid vdevGUID) for (CaseFileList::iterator curCase = s_activeCases.begin(); curCase != s_activeCases.end(); curCase++) { - if ((*curCase)->PoolGUID() != poolGUID + if (((*curCase)->PoolGUID() != poolGUID + && Guid::InvalidGuid() != poolGUID) || (*curCase)->VdevGUID() != vdevGUID) continue; @@ -268,7 +269,8 @@ CaseFile::ReEvaluate(const string &devPath, const string &physPath, Vdev *vdev) } if (vdev != NULL - && vdev->PoolGUID() == m_poolGUID + && ( vdev->PoolGUID() == m_poolGUID + || vdev->PoolGUID() == Guid::InvalidGuid()) && vdev->GUID() == m_vdevGUID) { zpool_vdev_online(pool, vdev->GUIDString().c_str(), diff --git a/cddl/usr.sbin/zfsd/case_file.h b/cddl/usr.sbin/zfsd/case_file.h index aa2a447e8a47..fcb1261f2a67 100644 --- a/cddl/usr.sbin/zfsd/case_file.h +++ b/cddl/usr.sbin/zfsd/case_file.h @@ -89,6 +89,8 @@ class CaseFile * \brief Find a CaseFile object by a vdev's pool/vdev GUID tuple. * * \param poolGUID Pool GUID for the vdev of the CaseFile to find. + * If InvalidGuid, then only match the vdev GUID + * instead of both pool and vdev GUIDs. * \param vdevGUID Vdev GUID for the vdev of the CaseFile to find. * * \return If found, a pointer to a valid CaseFile object. diff --git a/cddl/usr.sbin/zfsd/vdev_iterator.cc b/cddl/usr.sbin/zfsd/vdev_iterator.cc index 07f19d2b074c..31a4ce962970 100644 --- a/cddl/usr.sbin/zfsd/vdev_iterator.cc +++ b/cddl/usr.sbin/zfsd/vdev_iterator.cc @@ -76,7 +76,9 @@ void VdevIterator::Reset() { nvlist_t *rootVdev; + nvlist **cache_child; int result; + uint_t cache_children; result = nvlist_lookup_nvlist(m_poolConfig, ZPOOL_CONFIG_VDEV_TREE, @@ -85,6 +87,13 @@ VdevIterator::Reset() throw ZfsdException(m_poolConfig, "Unable to extract " "ZPOOL_CONFIG_VDEV_TREE from pool."); m_vdevQueue.assign(1, rootVdev); + result = nvlist_lookup_nvlist_array(rootVdev, + ZPOOL_CONFIG_L2CACHE, + &cache_child, + &cache_children); + if (result == 0) + for (uint_t c = 0; c < cache_children; c++) + m_vdevQueue.push_back(cache_child[c]); } nvlist_t * diff --git a/lib/libdevdctl/guid.h b/lib/libdevdctl/guid.h index ede414bec649..e40d3f983aab 100644 --- a/lib/libdevdctl/guid.h +++ b/lib/libdevdctl/guid.h @@ -62,9 +62,9 @@ class Guid { public: /* Constructors */ - Guid(); Guid(uint64_t guid); Guid(const std::string &guid); + static Guid InvalidGuid(); /* Assignment */ Guid& operator=(const Guid& rhs); @@ -80,25 +80,26 @@ class Guid operator uint64_t() const; operator bool() const; - static const uint64_t INVALID_GUID = 0; protected: + static const uint64_t INVALID_GUID = 0; + /* The integer value of the GUID. */ uint64_t m_GUID; }; //- Guid Inline Public Methods ------------------------------------------------ -inline -Guid::Guid() - : m_GUID(INVALID_GUID) -{ -} - inline Guid::Guid(uint64_t guid) : m_GUID(guid) { } +inline Guid +Guid::InvalidGuid() +{ + return (Guid(INVALID_GUID)); +} + inline Guid& Guid::operator=(const Guid &rhs) {