diff options
author | Ameer Hamza <[email protected]> | 2022-09-28 21:48:46 +0500 |
---|---|---|
committer | GitHub <[email protected]> | 2022-09-28 09:48:46 -0700 |
commit | 55c12724d377e6c7ace5b4bd42cd728d4a60af3e (patch) | |
tree | e5d28efce371d1097882dc064c16f362560e933e /cmd/zed/agents/zfs_agents.c | |
parent | eb9bec0a5d19abf9404f52081424fbb814e6188a (diff) |
zed: mark disks as REMOVED when they are removed
ZED does not take any action for disk removal events if there is no
spare VDEV available. Added zpool_vdev_remove_wanted() in libzfs
and vdev_remove_wanted() in vdev.c to remove the VDEV through ZED
on removal event. This means that if you are running zed and
remove a disk, it will be properly marked as REMOVED.
Reviewed-by: Alexander Motin <[email protected]>
Reviewed-by: Ryan Moeller <[email protected]>
Reviewed-by: Tony Hutter <[email protected]>
Signed-off-by: Ameer Hamza <[email protected]>
Closes #13797
Diffstat (limited to 'cmd/zed/agents/zfs_agents.c')
-rw-r--r-- | cmd/zed/agents/zfs_agents.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/cmd/zed/agents/zfs_agents.c b/cmd/zed/agents/zfs_agents.c index 2bc84a4f5..fb07266da 100644 --- a/cmd/zed/agents/zfs_agents.c +++ b/cmd/zed/agents/zfs_agents.c @@ -80,6 +80,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg) char *path = NULL; uint_t c, children; nvlist_t **child; + uint64_t vdev_guid; /* * First iterate over any children. @@ -100,7 +101,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg) &child, &children) == 0) { for (c = 0; c < children; c++) { if (zfs_agent_iter_vdev(zhp, child[c], gsp)) { - gsp->gs_vdev_type = DEVICE_TYPE_L2ARC; + gsp->gs_vdev_type = DEVICE_TYPE_SPARE; return (B_TRUE); } } @@ -109,7 +110,7 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg) &child, &children) == 0) { for (c = 0; c < children; c++) { if (zfs_agent_iter_vdev(zhp, child[c], gsp)) { - gsp->gs_vdev_type = DEVICE_TYPE_SPARE; + gsp->gs_vdev_type = DEVICE_TYPE_L2ARC; return (B_TRUE); } } @@ -126,6 +127,21 @@ zfs_agent_iter_vdev(zpool_handle_t *zhp, nvlist_t *nvl, void *arg) &gsp->gs_vdev_expandtime); return (B_TRUE); } + /* + * Otherwise, on a vdev guid match, grab the devid and expansion + * time. The devid might be missing on removal since its not part + * of blkid cache and L2ARC VDEV does not contain pool guid in its + * blkid, so this is a special case for L2ARC VDEV. + */ + else if (gsp->gs_vdev_guid != 0 && gsp->gs_devid == NULL && + nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_GUID, &vdev_guid) == 0 && + gsp->gs_vdev_guid == vdev_guid) { + (void) nvlist_lookup_string(nvl, ZPOOL_CONFIG_DEVID, + &gsp->gs_devid); + (void) nvlist_lookup_uint64(nvl, ZPOOL_CONFIG_EXPANSION_TIME, + &gsp->gs_vdev_expandtime); + return (B_TRUE); + } return (B_FALSE); } @@ -148,7 +164,7 @@ zfs_agent_iter_pool(zpool_handle_t *zhp, void *arg) /* * if a match was found then grab the pool guid */ - if (gsp->gs_vdev_guid) { + if (gsp->gs_vdev_guid && gsp->gs_devid) { (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_GUID, &gsp->gs_pool_guid); } @@ -195,11 +211,13 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl) uint64_t pool_guid = 0, vdev_guid = 0; guid_search_t search = { 0 }; device_type_t devtype = DEVICE_TYPE_PRIMARY; + char *devid = NULL; class = "resource.fs.zfs.removed"; subclass = ""; (void) nvlist_add_string(payload, FM_CLASS, class); + (void) nvlist_lookup_string(nvl, DEV_IDENTIFIER, &devid); (void) nvlist_lookup_uint64(nvl, ZFS_EV_POOL_GUID, &pool_guid); (void) nvlist_lookup_uint64(nvl, ZFS_EV_VDEV_GUID, &vdev_guid); @@ -209,20 +227,24 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl) (void) nvlist_add_int64_array(payload, FM_EREPORT_TIME, tod, 2); /* + * If devid is missing but vdev_guid is available, find devid + * and pool_guid from vdev_guid. * For multipath, spare and l2arc devices ZFS_EV_VDEV_GUID or * ZFS_EV_POOL_GUID may be missing so find them. */ - if (pool_guid == 0 || vdev_guid == 0) { - if ((nvlist_lookup_string(nvl, DEV_IDENTIFIER, - &search.gs_devid) == 0) && - (zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search) - == 1)) { - if (pool_guid == 0) - pool_guid = search.gs_pool_guid; - if (vdev_guid == 0) - vdev_guid = search.gs_vdev_guid; - devtype = search.gs_vdev_type; - } + if (devid == NULL || pool_guid == 0 || vdev_guid == 0) { + if (devid == NULL) + search.gs_vdev_guid = vdev_guid; + else + search.gs_devid = devid; + zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search); + if (devid == NULL) + devid = search.gs_devid; + if (pool_guid == 0) + pool_guid = search.gs_pool_guid; + if (vdev_guid == 0) + vdev_guid = search.gs_vdev_guid; + devtype = search.gs_vdev_type; } /* @@ -235,7 +257,9 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl) search.gs_vdev_expandtime + 10 > tv.tv_sec) { zed_log_msg(LOG_INFO, "agent post event: ignoring '%s' " "for recently expanded device '%s'", EC_DEV_REMOVE, - search.gs_devid); + devid); + fnvlist_free(payload); + free(event); goto out; } |