diff --git a/cmd/zed/agents/zfs_agents.c b/cmd/zed/agents/zfs_agents.c index 2bc84a4f57d1..3783b9024738 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); } @@ -208,11 +224,28 @@ zfs_agent_post_event(const char *class, const char *subclass, nvlist_t *nvl) tod[1] = tv.tv_usec; (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. + */ + if (nvlist_lookup_string(nvl, DEV_IDENTIFIER, + &search.gs_devid) != 0 && vdev_guid != 0 && + pool_guid == 0) { + search.gs_vdev_guid = vdev_guid; + zpool_iter(g_zfs_hdl, zfs_agent_iter_pool, &search); + if (search.gs_devid != NULL) { + nvlist_add_string(nvl, DEV_IDENTIFIER, + search.gs_devid); + } + if (search.gs_pool_guid != 0) + pool_guid = search.gs_pool_guid; + devtype = search.gs_vdev_type; + } /* * 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) { + else 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)