diff options
author | Alan Somers <asomers@FreeBSD.org> | 2023-04-05 20:30:43 +0000 |
---|---|---|
committer | Alan Somers <asomers@FreeBSD.org> | 2023-04-06 17:58:55 +0000 |
commit | f698c1e99b999df73b8f4eceec8662ccef67ebbb (patch) | |
tree | f114e98eaef75411ef92efc9d444a632fe5bf948 /cddl | |
parent | 7bc4ccf3aea935dde8ffc3e7c287884e22f87646 (diff) | |
download | src-f698c1e99b999df73b8f4eceec8662ccef67ebbb.tar.gz src-f698c1e99b999df73b8f4eceec8662ccef67ebbb.zip |
Diffstat (limited to 'cddl')
-rw-r--r-- | cddl/usr.sbin/zfsd/case_file.cc | 35 | ||||
-rw-r--r-- | cddl/usr.sbin/zfsd/case_file.h | 19 | ||||
-rw-r--r-- | cddl/usr.sbin/zfsd/vdev_iterator.cc | 9 | ||||
-rw-r--r-- | cddl/usr.sbin/zfsd/zfsd_event.cc | 14 |
4 files changed, 69 insertions, 8 deletions
diff --git a/cddl/usr.sbin/zfsd/case_file.cc b/cddl/usr.sbin/zfsd/case_file.cc index 34234a5736a5..5064d3c266dd 100644 --- a/cddl/usr.sbin/zfsd/case_file.cc +++ b/cddl/usr.sbin/zfsd/case_file.cc @@ -116,6 +116,26 @@ CaseFile::Find(Guid poolGUID, Guid vdevGUID) return (NULL); } +void +CaseFile::Find(Guid poolGUID, Guid vdevGUID, CaseFileList &cases) +{ + for (CaseFileList::iterator curCase = s_activeCases.begin(); + curCase != s_activeCases.end(); curCase++) { + if (((*curCase)->PoolGUID() != poolGUID && + Guid::InvalidGuid() != poolGUID) || + (*curCase)->VdevGUID() != vdevGUID) + continue; + + /* + * We can have multiple cases for spare vdevs + */ + cases.push_back(*curCase); + if (!(*curCase)->IsSpare()) { + return; + } + } +} + CaseFile * CaseFile::Find(const string &physPath) { @@ -217,6 +237,12 @@ CaseFile::PurgeAll() } +int +CaseFile::IsSpare() +{ + return (m_is_spare); +} + //- CaseFile Public Methods ---------------------------------------------------- bool CaseFile::RefreshVdevState() @@ -240,6 +266,7 @@ CaseFile::ReEvaluate(const string &devPath, const string &physPath, Vdev *vdev) { ZpoolList zpl(ZpoolList::ZpoolByGUID, &m_poolGUID); zpool_handle_t *pool(zpl.empty() ? NULL : zpl.front()); + int flags = ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE; if (pool == NULL || !RefreshVdevState()) { /* @@ -280,9 +307,10 @@ CaseFile::ReEvaluate(const string &devPath, const string &physPath, Vdev *vdev) || vdev->PoolGUID() == Guid::InvalidGuid()) && vdev->GUID() == m_vdevGUID) { + if (IsSpare()) + flags |= ZFS_ONLINE_SPARE; if (zpool_vdev_online(pool, vdev->GUIDString().c_str(), - ZFS_ONLINE_CHECKREMOVE | ZFS_ONLINE_UNSPARE, - &m_vdevState) != 0) { + flags, &m_vdevState) != 0) { syslog(LOG_ERR, "Failed to online vdev(%s/%s:%s): %s: %s\n", zpool_get_name(pool), vdev->GUIDString().c_str(), @@ -790,7 +818,8 @@ CaseFile::CaseFile(const Vdev &vdev) : m_poolGUID(vdev.PoolGUID()), m_vdevGUID(vdev.GUID()), m_vdevState(vdev.State()), - m_vdevPhysPath(vdev.PhysicalPath()) + m_vdevPhysPath(vdev.PhysicalPath()), + m_is_spare(vdev.IsSpare()) { stringstream guidString; diff --git a/cddl/usr.sbin/zfsd/case_file.h b/cddl/usr.sbin/zfsd/case_file.h index b4dc2dee5d96..d7475d331a76 100644 --- a/cddl/usr.sbin/zfsd/case_file.h +++ b/cddl/usr.sbin/zfsd/case_file.h @@ -99,6 +99,19 @@ public: static CaseFile *Find(DevdCtl::Guid poolGUID, DevdCtl::Guid vdevGUID); /** + * \brief Find multiple CaseFile objects by a vdev's pool/vdev + * GUID tuple (special case for spare vdevs) + * + * \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. + * \param caseList List of cases associated with the vdev. + */ + static void Find(DevdCtl::Guid poolGUID, DevdCtl::Guid vdevGUID, + CaseFileList &caseList); + + /** * \brief Find a CaseFile object by a vdev's current/last known * physical path. * @@ -219,6 +232,11 @@ public: */ bool ShouldFault() const; + /** + * \brief If this vdev is spare + */ + int IsSpare(); + protected: enum { /** @@ -384,6 +402,7 @@ protected: string m_poolGUIDString; string m_vdevGUIDString; string m_vdevPhysPath; + int m_is_spare; /** * \brief Callout activated when a grace period diff --git a/cddl/usr.sbin/zfsd/vdev_iterator.cc b/cddl/usr.sbin/zfsd/vdev_iterator.cc index b5a4f22c1c60..c23399ed68a8 100644 --- a/cddl/usr.sbin/zfsd/vdev_iterator.cc +++ b/cddl/usr.sbin/zfsd/vdev_iterator.cc @@ -78,8 +78,10 @@ VdevIterator::Reset() { nvlist_t *rootVdev; nvlist **cache_child; + nvlist **spare_child; int result; uint_t cache_children; + uint_t spare_children; result = nvlist_lookup_nvlist(m_poolConfig, ZPOOL_CONFIG_VDEV_TREE, @@ -95,6 +97,13 @@ VdevIterator::Reset() if (result == 0) for (uint_t c = 0; c < cache_children; c++) m_vdevQueue.push_back(cache_child[c]); + result = nvlist_lookup_nvlist_array(rootVdev, + ZPOOL_CONFIG_SPARES, + &spare_child, + &spare_children); + if (result == 0) + for (uint_t c = 0; c < spare_children; c++) + m_vdevQueue.push_back(spare_child[c]); } nvlist_t * diff --git a/cddl/usr.sbin/zfsd/zfsd_event.cc b/cddl/usr.sbin/zfsd/zfsd_event.cc index 688e7c0354a2..45fc7adbb31b 100644 --- a/cddl/usr.sbin/zfsd/zfsd_event.cc +++ b/cddl/usr.sbin/zfsd/zfsd_event.cc @@ -229,7 +229,9 @@ bool GeomEvent::OnlineByLabel(const string &devPath, const string& physPath, nvlist_t *devConfig) { + bool ret = false; try { + CaseFileList case_list; /* * A device with ZFS label information has been * inserted. If it matches a device for which we @@ -238,10 +240,12 @@ GeomEvent::OnlineByLabel(const string &devPath, const string& physPath, syslog(LOG_INFO, "Interrogating VDEV label for %s\n", devPath.c_str()); Vdev vdev(devConfig); - CaseFile *caseFile(CaseFile::Find(vdev.PoolGUID(), - vdev.GUID())); - if (caseFile != NULL) - return (caseFile->ReEvaluate(devPath, physPath, &vdev)); + CaseFile::Find(vdev.PoolGUID(),vdev.GUID(), case_list); + for (CaseFileList::iterator curr = case_list.begin(); + curr != case_list.end(); curr++) { + ret |= (*curr)->ReEvaluate(devPath, physPath, &vdev); + } + return (ret); } catch (ZfsdException &exp) { string context("GeomEvent::OnlineByLabel: " + devPath + ": "); @@ -249,7 +253,7 @@ GeomEvent::OnlineByLabel(const string &devPath, const string& physPath, exp.GetString().insert(0, context); exp.Log(); } - return (false); + return (ret); } |