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 /* 226643Seschrock * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 231544Seschrock * Use is subject to license terms. 241544Seschrock */ 251544Seschrock 261544Seschrock #include <fm/fmd_fmri.h> 271544Seschrock #include <strings.h> 281544Seschrock #include <libzfs.h> 291544Seschrock 301544Seschrock typedef struct cbdata { 311544Seschrock uint64_t cb_guid; 321544Seschrock zpool_handle_t *cb_pool; 331544Seschrock } cbdata_t; 341544Seschrock 352082Seschrock libzfs_handle_t *g_zfs; 362082Seschrock 371544Seschrock static int 381544Seschrock find_pool(zpool_handle_t *zhp, void *data) 391544Seschrock { 401544Seschrock cbdata_t *cbp = data; 411544Seschrock 425094Slling if (zpool_get_prop_int(zhp, ZPOOL_PROP_GUID, NULL) == cbp->cb_guid) { 431544Seschrock cbp->cb_pool = zhp; 441544Seschrock return (1); 451544Seschrock } 461544Seschrock 471544Seschrock zpool_close(zhp); 481544Seschrock 491544Seschrock return (0); 501544Seschrock } 511544Seschrock 521544Seschrock ssize_t 531544Seschrock fmd_fmri_nvl2str(nvlist_t *nvl, char *buf, size_t buflen) 541544Seschrock { 551544Seschrock uint64_t pool_guid, vdev_guid; 561544Seschrock cbdata_t cb; 571544Seschrock ssize_t len; 581544Seschrock const char *name; 591544Seschrock char guidbuf[64]; 601544Seschrock 611544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 621544Seschrock 631544Seschrock /* 641544Seschrock * Attempt to convert the pool guid to a name. 651544Seschrock */ 661544Seschrock cb.cb_guid = pool_guid; 671544Seschrock cb.cb_pool = NULL; 681544Seschrock 692082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) == 1) { 701544Seschrock name = zpool_get_name(cb.cb_pool); 711544Seschrock } else { 721544Seschrock (void) snprintf(guidbuf, sizeof (guidbuf), "%llx", pool_guid); 731544Seschrock name = guidbuf; 741544Seschrock } 751544Seschrock 761544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) == 0) 771544Seschrock len = snprintf(buf, buflen, "%s://pool=%s/vdev=%llx", 781544Seschrock FM_FMRI_SCHEME_ZFS, name, vdev_guid); 791544Seschrock else 801544Seschrock len = snprintf(buf, buflen, "%s://pool=%s", 811544Seschrock FM_FMRI_SCHEME_ZFS, name); 821544Seschrock 831544Seschrock if (cb.cb_pool) 841544Seschrock zpool_close(cb.cb_pool); 851544Seschrock 861544Seschrock return (len); 871544Seschrock } 881544Seschrock 891544Seschrock static nvlist_t * 901544Seschrock find_vdev_iter(nvlist_t *nv, uint64_t search) 911544Seschrock { 921544Seschrock uint_t c, children; 931544Seschrock nvlist_t **child; 941544Seschrock uint64_t guid; 951544Seschrock nvlist_t *ret; 961544Seschrock 971544Seschrock (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_GUID, &guid); 981544Seschrock 991544Seschrock if (search == guid) 1001544Seschrock return (nv); 1011544Seschrock 1021544Seschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_CHILDREN, 1031544Seschrock &child, &children) != 0) 1046643Seschrock return (NULL); 1056643Seschrock 1066643Seschrock for (c = 0; c < children; c++) 1076643Seschrock if ((ret = find_vdev_iter(child[c], search)) != 0) 1086643Seschrock return (ret); 1096643Seschrock 1106643Seschrock if (nvlist_lookup_nvlist_array(nv, ZPOOL_CONFIG_L2CACHE, 1116643Seschrock &child, &children) != 0) 1126643Seschrock return (NULL); 1131544Seschrock 1141544Seschrock for (c = 0; c < children; c++) 1151544Seschrock if ((ret = find_vdev_iter(child[c], search)) != 0) 1161544Seschrock return (ret); 1171544Seschrock 1181544Seschrock return (NULL); 1191544Seschrock } 1201544Seschrock 1211544Seschrock static nvlist_t * 1221544Seschrock find_vdev(zpool_handle_t *zhp, uint64_t guid) 1231544Seschrock { 1246643Seschrock nvlist_t *config, *nvroot; 1251544Seschrock 1261544Seschrock config = zpool_get_config(zhp, NULL); 1271544Seschrock 1281544Seschrock (void) nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE, &nvroot); 1291544Seschrock 1301544Seschrock return (find_vdev_iter(nvroot, guid)); 1311544Seschrock } 1321544Seschrock 1331544Seschrock int 1341544Seschrock fmd_fmri_present(nvlist_t *nvl) 1351544Seschrock { 1361544Seschrock uint64_t pool_guid, vdev_guid; 1371544Seschrock cbdata_t cb; 1381544Seschrock int ret; 1391544Seschrock 1401544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 1411544Seschrock 1421544Seschrock cb.cb_guid = pool_guid; 1431544Seschrock cb.cb_pool = NULL; 1441544Seschrock 1452082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) != 1) 1461544Seschrock return (0); 1471544Seschrock 1481544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 1491544Seschrock zpool_close(cb.cb_pool); 1501544Seschrock return (1); 1511544Seschrock } 1521544Seschrock 1531544Seschrock ret = (find_vdev(cb.cb_pool, vdev_guid) != NULL); 1541544Seschrock 1551544Seschrock zpool_close(cb.cb_pool); 1561544Seschrock 1571544Seschrock return (ret); 1581544Seschrock } 1591544Seschrock 1601544Seschrock int 161*8021SStephen.Hanson@Sun.COM fmd_fmri_replaced(nvlist_t *nvl) 162*8021SStephen.Hanson@Sun.COM { 163*8021SStephen.Hanson@Sun.COM uint64_t pool_guid, vdev_guid; 164*8021SStephen.Hanson@Sun.COM cbdata_t cb; 165*8021SStephen.Hanson@Sun.COM int ret; 166*8021SStephen.Hanson@Sun.COM 167*8021SStephen.Hanson@Sun.COM (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 168*8021SStephen.Hanson@Sun.COM 169*8021SStephen.Hanson@Sun.COM cb.cb_guid = pool_guid; 170*8021SStephen.Hanson@Sun.COM cb.cb_pool = NULL; 171*8021SStephen.Hanson@Sun.COM 172*8021SStephen.Hanson@Sun.COM if (zpool_iter(g_zfs, find_pool, &cb) != 1) 173*8021SStephen.Hanson@Sun.COM return (FMD_OBJ_STATE_NOT_PRESENT); 174*8021SStephen.Hanson@Sun.COM 175*8021SStephen.Hanson@Sun.COM if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 176*8021SStephen.Hanson@Sun.COM zpool_close(cb.cb_pool); 177*8021SStephen.Hanson@Sun.COM return (FMD_OBJ_STATE_STILL_PRESENT); 178*8021SStephen.Hanson@Sun.COM } 179*8021SStephen.Hanson@Sun.COM 180*8021SStephen.Hanson@Sun.COM ret = (find_vdev(cb.cb_pool, vdev_guid) != NULL) ? 181*8021SStephen.Hanson@Sun.COM FMD_OBJ_STATE_STILL_PRESENT : FMD_OBJ_STATE_NOT_PRESENT; 182*8021SStephen.Hanson@Sun.COM 183*8021SStephen.Hanson@Sun.COM zpool_close(cb.cb_pool); 184*8021SStephen.Hanson@Sun.COM 185*8021SStephen.Hanson@Sun.COM return (ret); 186*8021SStephen.Hanson@Sun.COM } 187*8021SStephen.Hanson@Sun.COM 188*8021SStephen.Hanson@Sun.COM int 1891544Seschrock fmd_fmri_unusable(nvlist_t *nvl) 1901544Seschrock { 1911544Seschrock uint64_t pool_guid, vdev_guid; 1921544Seschrock cbdata_t cb; 1931544Seschrock nvlist_t *vd; 1941544Seschrock int ret; 1951544Seschrock 1961544Seschrock (void) nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_POOL, &pool_guid); 1971544Seschrock 1981544Seschrock cb.cb_guid = pool_guid; 1991544Seschrock cb.cb_pool = NULL; 2001544Seschrock 2012082Seschrock if (zpool_iter(g_zfs, find_pool, &cb) != 1) 2021544Seschrock return (1); 2031544Seschrock 2041544Seschrock if (nvlist_lookup_uint64(nvl, FM_FMRI_ZFS_VDEV, &vdev_guid) != 0) { 2051544Seschrock ret = (zpool_get_state(cb.cb_pool) == POOL_STATE_UNAVAIL); 2061544Seschrock zpool_close(cb.cb_pool); 2071544Seschrock return (ret); 2081544Seschrock } 2091544Seschrock 2101544Seschrock vd = find_vdev(cb.cb_pool, vdev_guid); 2111544Seschrock if (vd == NULL) { 2121544Seschrock ret = 1; 2131544Seschrock } else { 2141544Seschrock vdev_stat_t *vs; 2151544Seschrock uint_t c; 2161544Seschrock 2171544Seschrock (void) nvlist_lookup_uint64_array(vd, ZPOOL_CONFIG_STATS, 2181544Seschrock (uint64_t **)&vs, &c); 2191544Seschrock 2201544Seschrock ret = (vs->vs_state < VDEV_STATE_DEGRADED); 2211544Seschrock } 2221544Seschrock 2231544Seschrock zpool_close(cb.cb_pool); 2241544Seschrock 2251544Seschrock return (ret); 2261544Seschrock } 2272082Seschrock 2282082Seschrock int 2292082Seschrock fmd_fmri_init(void) 2302082Seschrock { 2312082Seschrock g_zfs = libzfs_init(); 2322082Seschrock 2332082Seschrock if (g_zfs == NULL) 2342082Seschrock return (-1); 2352082Seschrock else 2362082Seschrock return (0); 2372082Seschrock } 2382082Seschrock 2392082Seschrock void 2402082Seschrock fmd_fmri_fini(void) 2412082Seschrock { 2422082Seschrock if (g_zfs) 2432082Seschrock libzfs_fini(g_zfs); 2442082Seschrock } 245