1c1cb2cd8Shaad /*
2c1cb2cd8Shaad * CDDL HEADER START
3c1cb2cd8Shaad *
4c1cb2cd8Shaad * The contents of this file are subject to the terms of the
5c1cb2cd8Shaad * Common Development and Distribution License (the "License").
6c1cb2cd8Shaad * You may not use this file except in compliance with the License.
7c1cb2cd8Shaad *
8c1cb2cd8Shaad * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9c1cb2cd8Shaad * or http://www.opensolaris.org/os/licensing.
10c1cb2cd8Shaad * See the License for the specific language governing permissions
11c1cb2cd8Shaad * and limitations under the License.
12c1cb2cd8Shaad *
13c1cb2cd8Shaad * When distributing Covered Code, include this CDDL HEADER in each
14c1cb2cd8Shaad * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15c1cb2cd8Shaad * If applicable, add the following below this CDDL HEADER, with the
16c1cb2cd8Shaad * fields enclosed by brackets "[]" replaced with your own identifying
17c1cb2cd8Shaad * information: Portions Copyright [yyyy] [name of copyright owner]
18c1cb2cd8Shaad *
19c1cb2cd8Shaad * CDDL HEADER END
20c1cb2cd8Shaad */
21*3227e6cfSchs
22c1cb2cd8Shaad /*
23*3227e6cfSchs * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
24*3227e6cfSchs * Copyright (c) 2012 by Delphix. All rights reserved.
25*3227e6cfSchs * Copyright (c) 2013 Steven Hartland. All rights reserved.
26c1cb2cd8Shaad */
27c1cb2cd8Shaad
28c1cb2cd8Shaad /*
29c1cb2cd8Shaad * This file contains the functions which analyze the status of a pool. This
30c1cb2cd8Shaad * include both the status of an active pool, as well as the status exported
31c1cb2cd8Shaad * pools. Returns one of the ZPOOL_STATUS_* defines describing the status of
32c1cb2cd8Shaad * the pool. This status is independent (to a certain degree) from the state of
33c1cb2cd8Shaad * the pool. A pool's state describes only whether or not it is capable of
34c1cb2cd8Shaad * providing the necessary fault tolerance for data. The status describes the
35c1cb2cd8Shaad * overall status of devices. A pool that is online can still have a device
36c1cb2cd8Shaad * that is experiencing errors.
37c1cb2cd8Shaad *
38c1cb2cd8Shaad * Only a subset of the possible faults can be detected using 'zpool status',
39c1cb2cd8Shaad * and not all possible errors correspond to a FMA message ID. The explanation
40c1cb2cd8Shaad * is left up to the caller, depending on whether it is a live pool or an
41c1cb2cd8Shaad * import.
42c1cb2cd8Shaad */
43c1cb2cd8Shaad
44c1cb2cd8Shaad #include <libzfs.h>
45c1cb2cd8Shaad #include <string.h>
46c1cb2cd8Shaad #include <unistd.h>
47c1cb2cd8Shaad #include "libzfs_impl.h"
48*3227e6cfSchs #include "zfeature_common.h"
49c1cb2cd8Shaad
50c1cb2cd8Shaad /*
51c1cb2cd8Shaad * Message ID table. This must be kept in sync with the ZPOOL_STATUS_* defines
52c1cb2cd8Shaad * in libzfs.h. Note that there are some status results which go past the end
53c1cb2cd8Shaad * of this table, and hence have no associated message ID.
54c1cb2cd8Shaad */
55c1cb2cd8Shaad static char *zfs_msgid_table[] = {
56c1cb2cd8Shaad "ZFS-8000-14",
57c1cb2cd8Shaad "ZFS-8000-2Q",
58c1cb2cd8Shaad "ZFS-8000-3C",
59c1cb2cd8Shaad "ZFS-8000-4J",
60c1cb2cd8Shaad "ZFS-8000-5E",
61c1cb2cd8Shaad "ZFS-8000-6X",
62c1cb2cd8Shaad "ZFS-8000-72",
63c1cb2cd8Shaad "ZFS-8000-8A",
64c1cb2cd8Shaad "ZFS-8000-9P",
65c1cb2cd8Shaad "ZFS-8000-A5",
66c1cb2cd8Shaad "ZFS-8000-EY",
67c1cb2cd8Shaad "ZFS-8000-HC",
68c1cb2cd8Shaad "ZFS-8000-JQ",
69c1cb2cd8Shaad "ZFS-8000-K4",
70c1cb2cd8Shaad };
71c1cb2cd8Shaad
72c1cb2cd8Shaad #define NMSGID (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
73c1cb2cd8Shaad
74c1cb2cd8Shaad /* ARGSUSED */
75c1cb2cd8Shaad static int
vdev_missing(vdev_stat_t * vs,uint_t vsc)76*3227e6cfSchs vdev_missing(vdev_stat_t *vs, uint_t vsc)
77c1cb2cd8Shaad {
78*3227e6cfSchs return (vs->vs_state == VDEV_STATE_CANT_OPEN &&
79*3227e6cfSchs vs->vs_aux == VDEV_AUX_OPEN_FAILED);
80c1cb2cd8Shaad }
81c1cb2cd8Shaad
82c1cb2cd8Shaad /* ARGSUSED */
83c1cb2cd8Shaad static int
vdev_faulted(vdev_stat_t * vs,uint_t vsc)84*3227e6cfSchs vdev_faulted(vdev_stat_t *vs, uint_t vsc)
85c1cb2cd8Shaad {
86*3227e6cfSchs return (vs->vs_state == VDEV_STATE_FAULTED);
87c1cb2cd8Shaad }
88c1cb2cd8Shaad
89c1cb2cd8Shaad /* ARGSUSED */
90c1cb2cd8Shaad static int
vdev_errors(vdev_stat_t * vs,uint_t vsc)91*3227e6cfSchs vdev_errors(vdev_stat_t *vs, uint_t vsc)
92c1cb2cd8Shaad {
93*3227e6cfSchs return (vs->vs_state == VDEV_STATE_DEGRADED ||
94*3227e6cfSchs vs->vs_read_errors != 0 || vs->vs_write_errors != 0 ||
95*3227e6cfSchs vs->vs_checksum_errors != 0);
96c1cb2cd8Shaad }
97c1cb2cd8Shaad
98c1cb2cd8Shaad /* ARGSUSED */
99c1cb2cd8Shaad static int
vdev_broken(vdev_stat_t * vs,uint_t vsc)100*3227e6cfSchs vdev_broken(vdev_stat_t *vs, uint_t vsc)
101c1cb2cd8Shaad {
102*3227e6cfSchs return (vs->vs_state == VDEV_STATE_CANT_OPEN);
103c1cb2cd8Shaad }
104c1cb2cd8Shaad
105c1cb2cd8Shaad /* ARGSUSED */
106c1cb2cd8Shaad static int
vdev_offlined(vdev_stat_t * vs,uint_t vsc)107*3227e6cfSchs vdev_offlined(vdev_stat_t *vs, uint_t vsc)
108c1cb2cd8Shaad {
109*3227e6cfSchs return (vs->vs_state == VDEV_STATE_OFFLINE);
110c1cb2cd8Shaad }
111c1cb2cd8Shaad
112f59c7639Shaad /* ARGSUSED */
113f59c7639Shaad static int
vdev_removed(vdev_stat_t * vs,uint_t vsc)114*3227e6cfSchs vdev_removed(vdev_stat_t *vs, uint_t vsc)
115f59c7639Shaad {
116*3227e6cfSchs return (vs->vs_state == VDEV_STATE_REMOVED);
117*3227e6cfSchs }
118*3227e6cfSchs
119*3227e6cfSchs static int
vdev_non_native_ashift(vdev_stat_t * vs,uint_t vsc)120*3227e6cfSchs vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)
121*3227e6cfSchs {
122*3227e6cfSchs return (VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
123*3227e6cfSchs vs->vs_configured_ashift < vs->vs_physical_ashift);
124f59c7639Shaad }
125f59c7639Shaad
126c1cb2cd8Shaad /*
127c1cb2cd8Shaad * Detect if any leaf devices that have seen errors or could not be opened.
128c1cb2cd8Shaad */
129c1cb2cd8Shaad static boolean_t
find_vdev_problem(nvlist_t * vdev,int (* func)(vdev_stat_t *,uint_t),boolean_t ignore_replacing)130*3227e6cfSchs find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
131*3227e6cfSchs boolean_t ignore_replacing)
132c1cb2cd8Shaad {
133c1cb2cd8Shaad nvlist_t **child;
134c1cb2cd8Shaad vdev_stat_t *vs;
135*3227e6cfSchs uint_t c, vsc, children;
136c1cb2cd8Shaad
137c1cb2cd8Shaad /*
138c1cb2cd8Shaad * Ignore problems within a 'replacing' vdev, since we're presumably in
139c1cb2cd8Shaad * the process of repairing any such errors, and don't want to call them
140c1cb2cd8Shaad * out again. We'll pick up the fact that a resilver is happening
141c1cb2cd8Shaad * later.
142c1cb2cd8Shaad */
143*3227e6cfSchs if (ignore_replacing == B_TRUE) {
144*3227e6cfSchs char *type;
145*3227e6cfSchs
146*3227e6cfSchs verify(nvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE,
147*3227e6cfSchs &type) == 0);
148c1cb2cd8Shaad if (strcmp(type, VDEV_TYPE_REPLACING) == 0)
149c1cb2cd8Shaad return (B_FALSE);
150*3227e6cfSchs }
151c1cb2cd8Shaad
152c1cb2cd8Shaad if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,
153c1cb2cd8Shaad &children) == 0) {
154c1cb2cd8Shaad for (c = 0; c < children; c++)
155*3227e6cfSchs if (find_vdev_problem(child[c], func, ignore_replacing))
156c1cb2cd8Shaad return (B_TRUE);
157c1cb2cd8Shaad } else {
158*3227e6cfSchs verify(nvlist_lookup_uint64_array(vdev, ZPOOL_CONFIG_VDEV_STATS,
159*3227e6cfSchs (uint64_t **)&vs, &vsc) == 0);
160c1cb2cd8Shaad
161*3227e6cfSchs if (func(vs, vsc) != 0)
162*3227e6cfSchs return (B_TRUE);
163*3227e6cfSchs }
164*3227e6cfSchs
165*3227e6cfSchs /*
166*3227e6cfSchs * Check any L2 cache devs
167*3227e6cfSchs */
168*3227e6cfSchs if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,
169*3227e6cfSchs &children) == 0) {
170*3227e6cfSchs for (c = 0; c < children; c++)
171*3227e6cfSchs if (find_vdev_problem(child[c], func, ignore_replacing))
172c1cb2cd8Shaad return (B_TRUE);
173c1cb2cd8Shaad }
174c1cb2cd8Shaad
175c1cb2cd8Shaad return (B_FALSE);
176c1cb2cd8Shaad }
177c1cb2cd8Shaad
178c1cb2cd8Shaad /*
179c1cb2cd8Shaad * Active pool health status.
180c1cb2cd8Shaad *
181c1cb2cd8Shaad * To determine the status for a pool, we make several passes over the config,
182c1cb2cd8Shaad * picking the most egregious error we find. In order of importance, we do the
183c1cb2cd8Shaad * following:
184c1cb2cd8Shaad *
185c1cb2cd8Shaad * - Check for a complete and valid configuration
186c1cb2cd8Shaad * - Look for any faulted or missing devices in a non-replicated config
187c1cb2cd8Shaad * - Check for any data errors
188c1cb2cd8Shaad * - Check for any faulted or missing devices in a replicated config
189c1cb2cd8Shaad * - Look for any devices showing errors
190c1cb2cd8Shaad * - Check for any resilvering devices
191c1cb2cd8Shaad *
192c1cb2cd8Shaad * There can obviously be multiple errors within a single pool, so this routine
193c1cb2cd8Shaad * only picks the most damaging of all the current errors to report.
194c1cb2cd8Shaad */
195c1cb2cd8Shaad static zpool_status_t
check_status(nvlist_t * config,boolean_t isimport)196c1cb2cd8Shaad check_status(nvlist_t *config, boolean_t isimport)
197c1cb2cd8Shaad {
198c1cb2cd8Shaad nvlist_t *nvroot;
199c1cb2cd8Shaad vdev_stat_t *vs;
200*3227e6cfSchs pool_scan_stat_t *ps = NULL;
201*3227e6cfSchs uint_t vsc, psc;
202c1cb2cd8Shaad uint64_t nerr;
203c1cb2cd8Shaad uint64_t version;
204c1cb2cd8Shaad uint64_t stateval;
205c1cb2cd8Shaad uint64_t suspended;
206c1cb2cd8Shaad uint64_t hostid = 0;
207c1cb2cd8Shaad
208c1cb2cd8Shaad verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION,
209c1cb2cd8Shaad &version) == 0);
210c1cb2cd8Shaad verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
211c1cb2cd8Shaad &nvroot) == 0);
212*3227e6cfSchs verify(nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS,
213c1cb2cd8Shaad (uint64_t **)&vs, &vsc) == 0);
214c1cb2cd8Shaad verify(nvlist_lookup_uint64(config, ZPOOL_CONFIG_POOL_STATE,
215c1cb2cd8Shaad &stateval) == 0);
216*3227e6cfSchs
217*3227e6cfSchs /*
218*3227e6cfSchs * Currently resilvering a vdev
219*3227e6cfSchs */
220*3227e6cfSchs (void) nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
221*3227e6cfSchs (uint64_t **)&ps, &psc);
222*3227e6cfSchs if (ps && ps->pss_func == POOL_SCAN_RESILVER &&
223*3227e6cfSchs ps->pss_state == DSS_SCANNING)
224*3227e6cfSchs return (ZPOOL_STATUS_RESILVERING);
225c1cb2cd8Shaad
226c1cb2cd8Shaad /*
227c1cb2cd8Shaad * Pool last accessed by another system.
228c1cb2cd8Shaad */
229*3227e6cfSchs (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
230c1cb2cd8Shaad if (hostid != 0 && (unsigned long)hostid != gethostid() &&
231c1cb2cd8Shaad stateval == POOL_STATE_ACTIVE)
232c1cb2cd8Shaad return (ZPOOL_STATUS_HOSTID_MISMATCH);
233c1cb2cd8Shaad
234c1cb2cd8Shaad /*
235c1cb2cd8Shaad * Newer on-disk version.
236c1cb2cd8Shaad */
237c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
238c1cb2cd8Shaad vs->vs_aux == VDEV_AUX_VERSION_NEWER)
239c1cb2cd8Shaad return (ZPOOL_STATUS_VERSION_NEWER);
240c1cb2cd8Shaad
241c1cb2cd8Shaad /*
242*3227e6cfSchs * Unsupported feature(s).
243*3227e6cfSchs */
244*3227e6cfSchs if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
245*3227e6cfSchs vs->vs_aux == VDEV_AUX_UNSUP_FEAT) {
246*3227e6cfSchs nvlist_t *nvinfo;
247*3227e6cfSchs
248*3227e6cfSchs verify(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO,
249*3227e6cfSchs &nvinfo) == 0);
250*3227e6cfSchs if (nvlist_exists(nvinfo, ZPOOL_CONFIG_CAN_RDONLY))
251*3227e6cfSchs return (ZPOOL_STATUS_UNSUP_FEAT_WRITE);
252*3227e6cfSchs return (ZPOOL_STATUS_UNSUP_FEAT_READ);
253*3227e6cfSchs }
254*3227e6cfSchs
255*3227e6cfSchs /*
256c1cb2cd8Shaad * Check that the config is complete.
257c1cb2cd8Shaad */
258c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
259c1cb2cd8Shaad vs->vs_aux == VDEV_AUX_BAD_GUID_SUM)
260c1cb2cd8Shaad return (ZPOOL_STATUS_BAD_GUID_SUM);
261c1cb2cd8Shaad
262c1cb2cd8Shaad /*
263c1cb2cd8Shaad * Check whether the pool has suspended due to failed I/O.
264c1cb2cd8Shaad */
265c1cb2cd8Shaad if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
266c1cb2cd8Shaad &suspended) == 0) {
267c1cb2cd8Shaad if (suspended == ZIO_FAILURE_MODE_CONTINUE)
268c1cb2cd8Shaad return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
269c1cb2cd8Shaad return (ZPOOL_STATUS_IO_FAILURE_WAIT);
270c1cb2cd8Shaad }
271c1cb2cd8Shaad
272c1cb2cd8Shaad /*
273c1cb2cd8Shaad * Could not read a log.
274c1cb2cd8Shaad */
275c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
276c1cb2cd8Shaad vs->vs_aux == VDEV_AUX_BAD_LOG) {
277c1cb2cd8Shaad return (ZPOOL_STATUS_BAD_LOG);
278c1cb2cd8Shaad }
279c1cb2cd8Shaad
280c1cb2cd8Shaad /*
281c1cb2cd8Shaad * Bad devices in non-replicated config.
282c1cb2cd8Shaad */
283c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
284*3227e6cfSchs find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
285c1cb2cd8Shaad return (ZPOOL_STATUS_FAULTED_DEV_NR);
286c1cb2cd8Shaad
287c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
288*3227e6cfSchs find_vdev_problem(nvroot, vdev_missing, B_TRUE))
289c1cb2cd8Shaad return (ZPOOL_STATUS_MISSING_DEV_NR);
290c1cb2cd8Shaad
291c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
292*3227e6cfSchs find_vdev_problem(nvroot, vdev_broken, B_TRUE))
293c1cb2cd8Shaad return (ZPOOL_STATUS_CORRUPT_LABEL_NR);
294c1cb2cd8Shaad
295c1cb2cd8Shaad /*
296c1cb2cd8Shaad * Corrupted pool metadata
297c1cb2cd8Shaad */
298c1cb2cd8Shaad if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
299c1cb2cd8Shaad vs->vs_aux == VDEV_AUX_CORRUPT_DATA)
300c1cb2cd8Shaad return (ZPOOL_STATUS_CORRUPT_POOL);
301c1cb2cd8Shaad
302c1cb2cd8Shaad /*
303c1cb2cd8Shaad * Persistent data errors.
304c1cb2cd8Shaad */
305c1cb2cd8Shaad if (!isimport) {
306c1cb2cd8Shaad if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
307c1cb2cd8Shaad &nerr) == 0 && nerr != 0)
308c1cb2cd8Shaad return (ZPOOL_STATUS_CORRUPT_DATA);
309c1cb2cd8Shaad }
310c1cb2cd8Shaad
311c1cb2cd8Shaad /*
312c1cb2cd8Shaad * Missing devices in a replicated config.
313c1cb2cd8Shaad */
314*3227e6cfSchs if (find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
315c1cb2cd8Shaad return (ZPOOL_STATUS_FAULTED_DEV_R);
316*3227e6cfSchs if (find_vdev_problem(nvroot, vdev_missing, B_TRUE))
317c1cb2cd8Shaad return (ZPOOL_STATUS_MISSING_DEV_R);
318*3227e6cfSchs if (find_vdev_problem(nvroot, vdev_broken, B_TRUE))
319c1cb2cd8Shaad return (ZPOOL_STATUS_CORRUPT_LABEL_R);
320c1cb2cd8Shaad
321c1cb2cd8Shaad /*
322c1cb2cd8Shaad * Devices with errors
323c1cb2cd8Shaad */
324*3227e6cfSchs if (!isimport && find_vdev_problem(nvroot, vdev_errors, B_TRUE))
325c1cb2cd8Shaad return (ZPOOL_STATUS_FAILING_DEV);
326c1cb2cd8Shaad
327c1cb2cd8Shaad /*
328c1cb2cd8Shaad * Offlined devices
329c1cb2cd8Shaad */
330*3227e6cfSchs if (find_vdev_problem(nvroot, vdev_offlined, B_TRUE))
331c1cb2cd8Shaad return (ZPOOL_STATUS_OFFLINE_DEV);
332c1cb2cd8Shaad
333c1cb2cd8Shaad /*
334f59c7639Shaad * Removed device
335f59c7639Shaad */
336*3227e6cfSchs if (find_vdev_problem(nvroot, vdev_removed, B_TRUE))
337f59c7639Shaad return (ZPOOL_STATUS_REMOVED_DEV);
338f59c7639Shaad
339f59c7639Shaad /*
340*3227e6cfSchs * Suboptimal, but usable, ashift configuration.
341c1cb2cd8Shaad */
342*3227e6cfSchs if (find_vdev_problem(nvroot, vdev_non_native_ashift, B_FALSE))
343*3227e6cfSchs return (ZPOOL_STATUS_NON_NATIVE_ASHIFT);
344c1cb2cd8Shaad
345c1cb2cd8Shaad /*
346c1cb2cd8Shaad * Outdated, but usable, version
347c1cb2cd8Shaad */
348*3227e6cfSchs if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION)
349c1cb2cd8Shaad return (ZPOOL_STATUS_VERSION_OLDER);
350c1cb2cd8Shaad
351*3227e6cfSchs /*
352*3227e6cfSchs * Usable pool with disabled features
353*3227e6cfSchs */
354*3227e6cfSchs if (version >= SPA_VERSION_FEATURES) {
355*3227e6cfSchs int i;
356*3227e6cfSchs nvlist_t *feat;
357*3227e6cfSchs
358*3227e6cfSchs if (isimport) {
359*3227e6cfSchs feat = fnvlist_lookup_nvlist(config,
360*3227e6cfSchs ZPOOL_CONFIG_LOAD_INFO);
361*3227e6cfSchs feat = fnvlist_lookup_nvlist(feat,
362*3227e6cfSchs ZPOOL_CONFIG_ENABLED_FEAT);
363*3227e6cfSchs } else {
364*3227e6cfSchs feat = fnvlist_lookup_nvlist(config,
365*3227e6cfSchs ZPOOL_CONFIG_FEATURE_STATS);
366*3227e6cfSchs }
367*3227e6cfSchs
368*3227e6cfSchs for (i = 0; i < SPA_FEATURES; i++) {
369*3227e6cfSchs zfeature_info_t *fi = &spa_feature_table[i];
370*3227e6cfSchs if (!nvlist_exists(feat, fi->fi_guid))
371*3227e6cfSchs return (ZPOOL_STATUS_FEAT_DISABLED);
372*3227e6cfSchs }
373*3227e6cfSchs }
374*3227e6cfSchs
375c1cb2cd8Shaad return (ZPOOL_STATUS_OK);
376c1cb2cd8Shaad }
377c1cb2cd8Shaad
378c1cb2cd8Shaad zpool_status_t
zpool_get_status(zpool_handle_t * zhp,char ** msgid)379c1cb2cd8Shaad zpool_get_status(zpool_handle_t *zhp, char **msgid)
380c1cb2cd8Shaad {
381c1cb2cd8Shaad zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE);
382c1cb2cd8Shaad
383c1cb2cd8Shaad if (ret >= NMSGID)
384c1cb2cd8Shaad *msgid = NULL;
385c1cb2cd8Shaad else
386c1cb2cd8Shaad *msgid = zfs_msgid_table[ret];
387c1cb2cd8Shaad
388c1cb2cd8Shaad return (ret);
389c1cb2cd8Shaad }
390c1cb2cd8Shaad
391c1cb2cd8Shaad zpool_status_t
zpool_import_status(nvlist_t * config,char ** msgid)392c1cb2cd8Shaad zpool_import_status(nvlist_t *config, char **msgid)
393c1cb2cd8Shaad {
394c1cb2cd8Shaad zpool_status_t ret = check_status(config, B_TRUE);
395c1cb2cd8Shaad
396c1cb2cd8Shaad if (ret >= NMSGID)
397c1cb2cd8Shaad *msgid = NULL;
398c1cb2cd8Shaad else
399c1cb2cd8Shaad *msgid = zfs_msgid_table[ret];
400c1cb2cd8Shaad
401c1cb2cd8Shaad return (ret);
402c1cb2cd8Shaad }
403f59c7639Shaad
404f59c7639Shaad static void
dump_ddt_stat(const ddt_stat_t * dds,int h)405f59c7639Shaad dump_ddt_stat(const ddt_stat_t *dds, int h)
406f59c7639Shaad {
407f59c7639Shaad char refcnt[6];
408f59c7639Shaad char blocks[6], lsize[6], psize[6], dsize[6];
409f59c7639Shaad char ref_blocks[6], ref_lsize[6], ref_psize[6], ref_dsize[6];
410f59c7639Shaad
411f59c7639Shaad if (dds == NULL || dds->dds_blocks == 0)
412f59c7639Shaad return;
413f59c7639Shaad
414f59c7639Shaad if (h == -1)
415f59c7639Shaad (void) strcpy(refcnt, "Total");
416f59c7639Shaad else
417f59c7639Shaad zfs_nicenum(1ULL << h, refcnt, sizeof (refcnt));
418f59c7639Shaad
419f59c7639Shaad zfs_nicenum(dds->dds_blocks, blocks, sizeof (blocks));
420f59c7639Shaad zfs_nicenum(dds->dds_lsize, lsize, sizeof (lsize));
421f59c7639Shaad zfs_nicenum(dds->dds_psize, psize, sizeof (psize));
422f59c7639Shaad zfs_nicenum(dds->dds_dsize, dsize, sizeof (dsize));
423f59c7639Shaad zfs_nicenum(dds->dds_ref_blocks, ref_blocks, sizeof (ref_blocks));
424f59c7639Shaad zfs_nicenum(dds->dds_ref_lsize, ref_lsize, sizeof (ref_lsize));
425f59c7639Shaad zfs_nicenum(dds->dds_ref_psize, ref_psize, sizeof (ref_psize));
426f59c7639Shaad zfs_nicenum(dds->dds_ref_dsize, ref_dsize, sizeof (ref_dsize));
427f59c7639Shaad
428f59c7639Shaad (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
429f59c7639Shaad refcnt,
430f59c7639Shaad blocks, lsize, psize, dsize,
431f59c7639Shaad ref_blocks, ref_lsize, ref_psize, ref_dsize);
432f59c7639Shaad }
433f59c7639Shaad
434f59c7639Shaad /*
435f59c7639Shaad * Print the DDT histogram and the column totals.
436f59c7639Shaad */
437f59c7639Shaad void
zpool_dump_ddt(const ddt_stat_t * dds_total,const ddt_histogram_t * ddh)438f59c7639Shaad zpool_dump_ddt(const ddt_stat_t *dds_total, const ddt_histogram_t *ddh)
439f59c7639Shaad {
440f59c7639Shaad int h;
441f59c7639Shaad
442f59c7639Shaad (void) printf("\n");
443f59c7639Shaad
444f59c7639Shaad (void) printf("bucket "
445f59c7639Shaad " allocated "
446f59c7639Shaad " referenced \n");
447f59c7639Shaad (void) printf("______ "
448f59c7639Shaad "______________________________ "
449f59c7639Shaad "______________________________\n");
450f59c7639Shaad
451f59c7639Shaad (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
452f59c7639Shaad "refcnt",
453f59c7639Shaad "blocks", "LSIZE", "PSIZE", "DSIZE",
454f59c7639Shaad "blocks", "LSIZE", "PSIZE", "DSIZE");
455f59c7639Shaad
456f59c7639Shaad (void) printf("%6s %6s %5s %5s %5s %6s %5s %5s %5s\n",
457f59c7639Shaad "------",
458f59c7639Shaad "------", "-----", "-----", "-----",
459f59c7639Shaad "------", "-----", "-----", "-----");
460f59c7639Shaad
461f59c7639Shaad for (h = 0; h < 64; h++)
462f59c7639Shaad dump_ddt_stat(&ddh->ddh_stat[h], h);
463f59c7639Shaad
464f59c7639Shaad dump_ddt_stat(dds_total, -1);
465f59c7639Shaad
466f59c7639Shaad (void) printf("\n");
467f59c7639Shaad }
468