Skip to content

Commit 0c928f7

Browse files
ixhamzaamotin
authored andcommitted
ZED: Fix device type detection and pool iteration logic
During hotplug REMOVED events, devid matching fails for partition-based spares because devid information is not stored in pool config for partitioned devices. However, when devid is populated by the hotplug event, the original code skipped the search logic entirely, skipping vdev_guid matching and resulting in wrong device type detection that caused spares to be incorrectly identified as l2arc devices. Additionally, fix zfs_agent_iter_pool() to use the return value from zfs_agent_iter_vdev() instead of relying on search parameters, which was previously ignored. Also add pool_guid optimization to enable targeted pool searching when pool_guid is available. Reviewed-by: Brian Behlendorf <[email protected]> Reviewed-by: Alexander Motin <[email protected]> Signed-off-by: Ameer Hamza <[email protected]> Closes #17545
1 parent c79d5e4 commit 0c928f7

File tree

1 file changed

+36
-31
lines changed

1 file changed

+36
-31
lines changed

cmd/zed/agents/zfs_agents.c

Lines changed: 36 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -134,11 +134,13 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg)
134134
* of blkid cache and L2ARC VDEV does not contain pool guid in its
135135
* blkid, so this is a special case for L2ARC VDEV.
136136
*/
137-
else if (gsp->gs_vdev_guid != 0 && gsp->gs_devid == NULL &&
137+
else if (gsp->gs_vdev_guid != 0 &&
138138
nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &vdev_guid) == 0 &&
139139
gsp->gs_vdev_guid == vdev_guid) {
140-
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
141-
&gsp->gs_devid);
140+
if (gsp->gs_devid == NULL) {
141+
(void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID,
142+
&gsp->gs_devid);
143+
}
142144
(void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME,
143145
&gsp->gs_vdev_expandtime);
144146
return (B_TRUE);
@@ -156,22 +158,28 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg)
156158
/*
157159
* For each vdev in this pool, look for a match by devid
158160
*/
159-
if ((config = zpool_get_config(zhp, NULL)) != NULL) {
160-
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
161-
&nvl) == 0) {
162-
(void) zfs_agent_iter_vdev(zhp, nvl, gsp);
163-
}
164-
}
165-
/*
166-
* if a match was found then grab the pool guid
167-
*/
168-
if (gsp->gs_vdev_guid && gsp->gs_devid) {
169-
(void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
170-
&gsp->gs_pool_guid);
171-
}
161+
boolean_t found = B_FALSE;
162+
uint64_t pool_guid;
172163

164+
/* Get pool configuration and extract pool GUID */
165+
if ((config = zpool_get_config(zhp, NULL)) == NULL ||
166+
nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID,
167+
&pool_guid) != 0)
168+
goto out;
169+
170+
/* Skip this pool if we're looking for a specific pool */
171+
if (gsp->gs_pool_guid != 0 && pool_guid != gsp->gs_pool_guid)
172+
goto out;
173+
174+
if (nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvl) == 0)
175+
found = zfs_agent_iter_vdev(zhp, nvl, gsp);
176+
177+
if (found && gsp->gs_pool_guid == 0)
178+
gsp->gs_pool_guid = pool_guid;
179+
180+
out:
173181
zpool_close(zhp);
174-
return (gsp->gs_devid != NULL && gsp->gs_vdev_guid != 0);
182+
return (found);
175183
}
176184

177185
void
@@ -233,20 +241,17 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl)
233241
* For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or
234242
* ZFS_EV_POOL_GUID may be missing so find them.
235243
*/
236-
if (devid == NULL || pool_guid == 0 || vdev_guid == 0) {
237-
if (devid == NULL)
238-
search.gs_vdev_guid = vdev_guid;
239-
else
240-
search.gs_devid = devid;
241-
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
242-
if (devid == NULL)
243-
devid = search.gs_devid;
244-
if (pool_guid == 0)
245-
pool_guid = search.gs_pool_guid;
246-
if (vdev_guid == 0)
247-
vdev_guid = search.gs_vdev_guid;
248-
devtype = search.gs_vdev_type;
249-
}
244+
search.gs_devid = devid;
245+
search.gs_vdev_guid = vdev_guid;
246+
search.gs_pool_guid = pool_guid;
247+
zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search);
248+
if (devid == NULL)
249+
devid = search.gs_devid;
250+
if (pool_guid == 0)
251+
pool_guid = search.gs_pool_guid;
252+
if (vdev_guid == 0)
253+
vdev_guid = search.gs_vdev_guid;
254+
devtype = search.gs_vdev_type;
250255

251256
/*
252257
* We want to avoid reporting "remove" events coming from

0 commit comments

Comments
 (0)