aboutsummaryrefslogtreecommitdiff
path: root/cddl
diff options
context:
space:
mode:
authorAlan Somers <asomers@FreeBSD.org>2023-04-05 20:30:43 +0000
committerAlan Somers <asomers@FreeBSD.org>2023-04-06 17:58:55 +0000
commitf698c1e99b999df73b8f4eceec8662ccef67ebbb (patch)
treef114e98eaef75411ef92efc9d444a632fe5bf948 /cddl
parent7bc4ccf3aea935dde8ffc3e7c287884e22f87646 (diff)
downloadsrc-f698c1e99b999df73b8f4eceec8662ccef67ebbb.tar.gz
src-f698c1e99b999df73b8f4eceec8662ccef67ebbb.zip
Diffstat (limited to 'cddl')
-rw-r--r--cddl/usr.sbin/zfsd/case_file.cc35
-rw-r--r--cddl/usr.sbin/zfsd/case_file.h19
-rw-r--r--cddl/usr.sbin/zfsd/vdev_iterator.cc9
-rw-r--r--cddl/usr.sbin/zfsd/zfsd_event.cc14
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);
}