11544Seschrock /* 21544Seschrock * CDDL HEADER START 31544Seschrock * 41544Seschrock * The contents of this file are subject to the terms of the 51544Seschrock * Common Development and Distribution License (the "License"). 61544Seschrock * You may not use this file except in compliance with the License. 71544Seschrock * 81544Seschrock * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 91544Seschrock * or http://www.opensolaris.org/os/licensing. 101544Seschrock * See the License for the specific language governing permissions 111544Seschrock * and limitations under the License. 121544Seschrock * 131544Seschrock * When distributing Covered Code, include this CDDL HEADER in each 141544Seschrock * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 151544Seschrock * If applicable, add the following below this CDDL HEADER, with the 161544Seschrock * fields enclosed by brackets "[]" replaced with your own identifying 171544Seschrock * information: Portions Copyright [yyyy] [name of copyright owner] 181544Seschrock * 191544Seschrock * CDDL HEADER END 201544Seschrock */ 211544Seschrock /* 22*6643Seschrock * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 231544Seschrock * Use is subject to license terms. 241544Seschrock */ 251544Seschrock 261544Seschrock #pragma ident "%Z%%M% %I% %E% SMI" 271544Seschrock 281544Seschrock #include <fm/fmd_fmri.h> 291544Seschrock #include <strings.h> 301544Seschrock #include <libzfs.h> 311544Seschrock 321544Seschrock typedef struct cbdata { 331544Seschrock uint64_t cb_guid; 341544Seschrock zpool_handle_t *cb_pool; 351544Seschrock } cbdata_t; 361544Seschrock 372082Seschrock libzfs_handle_t *g_zfs; 382082Seschrock 391544Seschrock static int 401544Seschrock find_pool(zpool_handle_t *zhp, void *data) 411544Seschrock { 421544Seschrock cbdata_t *cbp = data; 431544Seschrock 445094Slling if (zpool_get_prop_int(zhp, ZPOOL_PROP_GUID, NULL) == cbp->cb_guid) { 451544Seschrock cbp->cb_pool = zhp; 461544Seschrock return (1); 471544Seschrock } 481544Seschrock 491544Seschrock zpool_close(zhp); 501544Seschrock 511544Seschrock return (0); 521544Seschrock } 531544Seschrock 541544Seschrock ssize_t 551544Seschrock fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) 561544Seschrock { 571544Seschrock uint64_t pool_guid, vdev_guid; 581544Seschrock cbdata_t cb; 591544Seschrock ssize_t len; 601544Seschrock const char *name; 611544Seschrock char guidbuf[64]; 621544Seschrock 631544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 641544Seschrock 651544Seschrock /* 661544Seschrock * Attempt to convert the pool guid to a name. 671544Seschrock */ 681544Seschrock cb.cb_guid = pool_guid; 691544Seschrock cb.cb_pool = NULL; 701544Seschrock 712082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) == 1) { 721544Seschrock name = zpool_get_name(cb.cb_pool); 731544Seschrock } else { 741544Seschrock (void) snprintf(guidbuf, sizeof (guidbuf), "%llx", pool_guid); 751544Seschrock name = guidbuf; 761544Seschrock } 771544Seschrock 781544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) == 0) 791544Seschrock len = snprintf(buf, buflen, "%s://pool=%s/vdev=%llx", 801544Seschrock FM_FMRI_SCHEME_ZFS, name, vdev_guid); 811544Seschrock else 821544Seschrock len = snprintf(buf, buflen, "%s://pool=%s", 831544Seschrock FM_FMRI_SCHEME_ZFS, name); 841544Seschrock 851544Seschrock if (cb.cb_pool) 861544Seschrock zpool_close(cb.cb_pool); 871544Seschrock 881544Seschrock return (len); 891544Seschrock } 901544Seschrock 911544Seschrock static nvlist_t * 921544Seschrock find_vdev_iter(nvlist_t *nv, uint64_t search) 931544Seschrock { 941544Seschrock uint_t c, children; 951544Seschrock nvlist_t **child; 961544Seschrock uint64_t guid; 971544Seschrock nvlist_t *ret; 981544Seschrock 991544Seschrock (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid); 1001544Seschrock 1011544Seschrock if (search == guid) 1021544Seschrock return (nv); 1031544Seschrock 1041544Seschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1051544Seschrock &child, &children) != 0) 106*6643Seschrock return (NULL); 107*6643Seschrock 108*6643Seschrock for (c = 0; c < children; c++) 109*6643Seschrock if ((ret = find_vdev_iter(child[c], search)) != 0) 110*6643Seschrock return (ret); 111*6643Seschrock 112*6643Seschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 113*6643Seschrock &child, &children) != 0) 114*6643Seschrock return (NULL); 1151544Seschrock 1161544Seschrock for (c = 0; c < children; c++) 1171544Seschrock if ((ret = find_vdev_iter(child[c], search)) != 0) 1181544Seschrock return (ret); 1191544Seschrock 1201544Seschrock return (NULL); 1211544Seschrock } 1221544Seschrock 1231544Seschrock static nvlist_t * 1241544Seschrock find_vdev(zpool_handle_t *zhp, uint64_t guid) 1251544Seschrock { 126*6643Seschrock nvlist_t *config, *nvroot; 1271544Seschrock 1281544Seschrock config = zpool_get_config(zhp, NULL); 1291544Seschrock 1301544Seschrock (void) nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot); 1311544Seschrock 1321544Seschrock return (find_vdev_iter(nvroot, guid)); 1331544Seschrock } 1341544Seschrock 1351544Seschrock int 1361544Seschrock fmd_fmri_present(nvlist_t *nvl) 1371544Seschrock { 1381544Seschrock uint64_t pool_guid, vdev_guid; 1391544Seschrock cbdata_t cb; 1401544Seschrock int ret; 1411544Seschrock 1421544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 1431544Seschrock 1441544Seschrock cb.cb_guid = pool_guid; 1451544Seschrock cb.cb_pool = NULL; 1461544Seschrock 1472082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) != 1) 1481544Seschrock return (0); 1491544Seschrock 1501544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 1511544Seschrock zpool_close(cb.cb_pool); 1521544Seschrock return (1); 1531544Seschrock } 1541544Seschrock 1551544Seschrock ret = (find_vdev(cb.cb_pool, vdev_guid) != NULL); 1561544Seschrock 1571544Seschrock zpool_close(cb.cb_pool); 1581544Seschrock 1591544Seschrock return (ret); 1601544Seschrock } 1611544Seschrock 1621544Seschrock int 1631544Seschrock fmd_fmri_unusable(nvlist_t *nvl) 1641544Seschrock { 1651544Seschrock uint64_t pool_guid, vdev_guid; 1661544Seschrock cbdata_t cb; 1671544Seschrock nvlist_t *vd; 1681544Seschrock int ret; 1691544Seschrock 1701544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 1711544Seschrock 1721544Seschrock cb.cb_guid = pool_guid; 1731544Seschrock cb.cb_pool = NULL; 1741544Seschrock 1752082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) != 1) 1761544Seschrock return (1); 1771544Seschrock 1781544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 1791544Seschrock ret = (zpool_get_state(cb.cb_pool) == POOL_STATE_UNAVAIL); 1801544Seschrock zpool_close(cb.cb_pool); 1811544Seschrock return (ret); 1821544Seschrock } 1831544Seschrock 1841544Seschrock vd = find_vdev(cb.cb_pool, vdev_guid); 1851544Seschrock if (vd == NULL) { 1861544Seschrock ret = 1; 1871544Seschrock } else { 1881544Seschrock vdev_stat_t *vs; 1891544Seschrock uint_t c; 1901544Seschrock 1911544Seschrock (void) nvlist_lookup_uint64_array(vd, ZPOOL_CONFIG_STATS, 1921544Seschrock (uint64_t **)&vs, &c); 1931544Seschrock 1941544Seschrock ret = (vs->vs_state < VDEV_STATE_DEGRADED); 1951544Seschrock } 1961544Seschrock 1971544Seschrock zpool_close(cb.cb_pool); 1981544Seschrock 1991544Seschrock return (ret); 2001544Seschrock } 2012082Seschrock 2022082Seschrock int 2032082Seschrock fmd_fmri_init(void) 2042082Seschrock { 2052082Seschrock g_zfs = libzfs_init(); 2062082Seschrock 2072082Seschrock if (g_zfs == NULL) 2082082Seschrock return (-1); 2092082Seschrock else 2102082Seschrock return (0); 2112082Seschrock } 2122082Seschrock 2132082Seschrock void 2142082Seschrock fmd_fmri_fini(void) 2152082Seschrock { 2162082Seschrock if (g_zfs) 2172082Seschrock libzfs_fini(g_zfs); 2182082Seschrock } 219