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 /* 221544Seschrock * Copyright 2006 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 37*2082Seschrock libzfs_handle_t *g_zfs; 38*2082Seschrock 391544Seschrock static int 401544Seschrock find_pool(zpool_handle_t *zhp, void *data) 411544Seschrock { 421544Seschrock cbdata_t *cbp = data; 431544Seschrock 441544Seschrock if (zpool_get_guid(zhp) == 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 71*2082Seschrock 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) 1061544Seschrock return (0); 1071544Seschrock 1081544Seschrock for (c = 0; c < children; c++) 1091544Seschrock if ((ret = find_vdev_iter(child[c], search)) != 0) 1101544Seschrock return (ret); 1111544Seschrock 1121544Seschrock return (NULL); 1131544Seschrock } 1141544Seschrock 1151544Seschrock static nvlist_t * 1161544Seschrock find_vdev(zpool_handle_t *zhp, uint64_t guid) 1171544Seschrock { 1181544Seschrock nvlist_t *config; 1191544Seschrock nvlist_t *nvroot; 1201544Seschrock 1211544Seschrock config = zpool_get_config(zhp, NULL); 1221544Seschrock 1231544Seschrock (void) nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot); 1241544Seschrock 1251544Seschrock return (find_vdev_iter(nvroot, guid)); 1261544Seschrock } 1271544Seschrock 1281544Seschrock int 1291544Seschrock fmd_fmri_present(nvlist_t *nvl) 1301544Seschrock { 1311544Seschrock uint64_t pool_guid, vdev_guid; 1321544Seschrock cbdata_t cb; 1331544Seschrock int ret; 1341544Seschrock 1351544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 1361544Seschrock 1371544Seschrock cb.cb_guid = pool_guid; 1381544Seschrock cb.cb_pool = NULL; 1391544Seschrock 140*2082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) != 1) 1411544Seschrock return (0); 1421544Seschrock 1431544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 1441544Seschrock zpool_close(cb.cb_pool); 1451544Seschrock return (1); 1461544Seschrock } 1471544Seschrock 1481544Seschrock ret = (find_vdev(cb.cb_pool, vdev_guid) != NULL); 1491544Seschrock 1501544Seschrock zpool_close(cb.cb_pool); 1511544Seschrock 1521544Seschrock return (ret); 1531544Seschrock } 1541544Seschrock 1551544Seschrock int 1561544Seschrock fmd_fmri_unusable(nvlist_t *nvl) 1571544Seschrock { 1581544Seschrock uint64_t pool_guid, vdev_guid; 1591544Seschrock cbdata_t cb; 1601544Seschrock nvlist_t *vd; 1611544Seschrock int ret; 1621544Seschrock 1631544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 1641544Seschrock 1651544Seschrock cb.cb_guid = pool_guid; 1661544Seschrock cb.cb_pool = NULL; 1671544Seschrock 168*2082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) != 1) 1691544Seschrock return (1); 1701544Seschrock 1711544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 1721544Seschrock ret = (zpool_get_state(cb.cb_pool) == POOL_STATE_UNAVAIL); 1731544Seschrock zpool_close(cb.cb_pool); 1741544Seschrock return (ret); 1751544Seschrock } 1761544Seschrock 1771544Seschrock vd = find_vdev(cb.cb_pool, vdev_guid); 1781544Seschrock if (vd == NULL) { 1791544Seschrock ret = 1; 1801544Seschrock } else { 1811544Seschrock vdev_stat_t *vs; 1821544Seschrock uint_t c; 1831544Seschrock 1841544Seschrock (void) nvlist_lookup_uint64_array(vd, ZPOOL_CONFIG_STATS, 1851544Seschrock (uint64_t **)&vs, &c); 1861544Seschrock 1871544Seschrock ret = (vs->vs_state < VDEV_STATE_DEGRADED); 1881544Seschrock } 1891544Seschrock 1901544Seschrock zpool_close(cb.cb_pool); 1911544Seschrock 1921544Seschrock return (ret); 1931544Seschrock } 194*2082Seschrock 195*2082Seschrock int 196*2082Seschrock fmd_fmri_init(void) 197*2082Seschrock { 198*2082Seschrock g_zfs = libzfs_init(); 199*2082Seschrock 200*2082Seschrock if (g_zfs == NULL) 201*2082Seschrock return (-1); 202*2082Seschrock else 203*2082Seschrock return (0); 204*2082Seschrock } 205*2082Seschrock 206*2082Seschrock void 207*2082Seschrock fmd_fmri_fini(void) 208*2082Seschrock { 209*2082Seschrock if (g_zfs) 210*2082Seschrock libzfs_fini(g_zfs); 211*2082Seschrock } 212