xref: /onnv-gate/usr/src/cmd/fm/schemes/zfs/scheme.c (revision 8021:b8fe9660eb2d)
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