The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/contrib/openzfs/lib/libzfs/libzfs_status.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * CDDL HEADER START
    3  *
    4  * The contents of this file are subject to the terms of the
    5  * Common Development and Distribution License (the "License").
    6  * You may not use this file except in compliance with the License.
    7  *
    8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
    9  * or https://opensource.org/licenses/CDDL-1.0.
   10  * See the License for the specific language governing permissions
   11  * and limitations under the License.
   12  *
   13  * When distributing Covered Code, include this CDDL HEADER in each
   14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
   15  * If applicable, add the following below this CDDL HEADER, with the
   16  * fields enclosed by brackets "[]" replaced with your own identifying
   17  * information: Portions Copyright [yyyy] [name of copyright owner]
   18  *
   19  * CDDL HEADER END
   20  */
   21 
   22 /*
   23  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
   24  * Copyright (c) 2012 by Delphix. All rights reserved.
   25  * Copyright (c) 2013 Steven Hartland. All rights reserved.
   26  * Copyright (c) 2021, Colm Buckley <colm@tuatha.org>
   27  */
   28 
   29 /*
   30  * This file contains the functions which analyze the status of a pool.  This
   31  * include both the status of an active pool, as well as the status exported
   32  * pools.  Returns one of the ZPOOL_STATUS_* defines describing the status of
   33  * the pool.  This status is independent (to a certain degree) from the state of
   34  * the pool.  A pool's state describes only whether or not it is capable of
   35  * providing the necessary fault tolerance for data.  The status describes the
   36  * overall status of devices.  A pool that is online can still have a device
   37  * that is experiencing errors.
   38  *
   39  * Only a subset of the possible faults can be detected using 'zpool status',
   40  * and not all possible errors correspond to a FMA message ID.  The explanation
   41  * is left up to the caller, depending on whether it is a live pool or an
   42  * import.
   43  */
   44 
   45 #include <libzfs.h>
   46 #include <libzutil.h>
   47 #include <stdlib.h>
   48 #include <string.h>
   49 #include <unistd.h>
   50 #include <sys/systeminfo.h>
   51 #include "libzfs_impl.h"
   52 #include "zfeature_common.h"
   53 
   54 /*
   55  * Message ID table.  This must be kept in sync with the ZPOOL_STATUS_* defines
   56  * in include/libzfs.h.  Note that there are some status results which go past
   57  * the end of this table, and hence have no associated message ID.
   58  */
   59 static const char *const zfs_msgid_table[] = {
   60         "ZFS-8000-14", /* ZPOOL_STATUS_CORRUPT_CACHE */
   61         "ZFS-8000-2Q", /* ZPOOL_STATUS_MISSING_DEV_R */
   62         "ZFS-8000-3C", /* ZPOOL_STATUS_MISSING_DEV_NR */
   63         "ZFS-8000-4J", /* ZPOOL_STATUS_CORRUPT_LABEL_R */
   64         "ZFS-8000-5E", /* ZPOOL_STATUS_CORRUPT_LABEL_NR */
   65         "ZFS-8000-6X", /* ZPOOL_STATUS_BAD_GUID_SUM */
   66         "ZFS-8000-72", /* ZPOOL_STATUS_CORRUPT_POOL */
   67         "ZFS-8000-8A", /* ZPOOL_STATUS_CORRUPT_DATA */
   68         "ZFS-8000-9P", /* ZPOOL_STATUS_FAILING_DEV */
   69         "ZFS-8000-A5", /* ZPOOL_STATUS_VERSION_NEWER */
   70         "ZFS-8000-EY", /* ZPOOL_STATUS_HOSTID_MISMATCH */
   71         "ZFS-8000-EY", /* ZPOOL_STATUS_HOSTID_ACTIVE */
   72         "ZFS-8000-EY", /* ZPOOL_STATUS_HOSTID_REQUIRED */
   73         "ZFS-8000-HC", /* ZPOOL_STATUS_IO_FAILURE_WAIT */
   74         "ZFS-8000-JQ", /* ZPOOL_STATUS_IO_FAILURE_CONTINUE */
   75         "ZFS-8000-MM", /* ZPOOL_STATUS_IO_FAILURE_MMP */
   76         "ZFS-8000-K4", /* ZPOOL_STATUS_BAD_LOG */
   77         "ZFS-8000-ER", /* ZPOOL_STATUS_ERRATA */
   78         /*
   79          * The following results have no message ID.
   80          *      ZPOOL_STATUS_UNSUP_FEAT_READ
   81          *      ZPOOL_STATUS_UNSUP_FEAT_WRITE
   82          *      ZPOOL_STATUS_FAULTED_DEV_R
   83          *      ZPOOL_STATUS_FAULTED_DEV_NR
   84          *      ZPOOL_STATUS_VERSION_OLDER
   85          *      ZPOOL_STATUS_FEAT_DISABLED
   86          *      ZPOOL_STATUS_RESILVERING
   87          *      ZPOOL_STATUS_OFFLINE_DEV
   88          *      ZPOOL_STATUS_REMOVED_DEV
   89          *      ZPOOL_STATUS_REBUILDING
   90          *      ZPOOL_STATUS_REBUILD_SCRUB
   91          *      ZPOOL_STATUS_COMPATIBILITY_ERR
   92          *      ZPOOL_STATUS_INCOMPATIBLE_FEAT
   93          *      ZPOOL_STATUS_OK
   94          */
   95 };
   96 
   97 #define NMSGID  (sizeof (zfs_msgid_table) / sizeof (zfs_msgid_table[0]))
   98 
   99 static int
  100 vdev_missing(vdev_stat_t *vs, uint_t vsc)
  101 {
  102         (void) vsc;
  103         return (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  104             vs->vs_aux == VDEV_AUX_OPEN_FAILED);
  105 }
  106 
  107 static int
  108 vdev_faulted(vdev_stat_t *vs, uint_t vsc)
  109 {
  110         (void) vsc;
  111         return (vs->vs_state == VDEV_STATE_FAULTED);
  112 }
  113 
  114 static int
  115 vdev_errors(vdev_stat_t *vs, uint_t vsc)
  116 {
  117         (void) vsc;
  118         return (vs->vs_state == VDEV_STATE_DEGRADED ||
  119             vs->vs_read_errors != 0 || vs->vs_write_errors != 0 ||
  120             vs->vs_checksum_errors != 0);
  121 }
  122 
  123 static int
  124 vdev_broken(vdev_stat_t *vs, uint_t vsc)
  125 {
  126         (void) vsc;
  127         return (vs->vs_state == VDEV_STATE_CANT_OPEN);
  128 }
  129 
  130 static int
  131 vdev_offlined(vdev_stat_t *vs, uint_t vsc)
  132 {
  133         (void) vsc;
  134         return (vs->vs_state == VDEV_STATE_OFFLINE);
  135 }
  136 
  137 static int
  138 vdev_removed(vdev_stat_t *vs, uint_t vsc)
  139 {
  140         (void) vsc;
  141         return (vs->vs_state == VDEV_STATE_REMOVED);
  142 }
  143 
  144 static int
  145 vdev_non_native_ashift(vdev_stat_t *vs, uint_t vsc)
  146 {
  147         if (getenv("ZPOOL_STATUS_NON_NATIVE_ASHIFT_IGNORE") != NULL)
  148                 return (0);
  149 
  150         return (VDEV_STAT_VALID(vs_physical_ashift, vsc) &&
  151             vs->vs_configured_ashift < vs->vs_physical_ashift);
  152 }
  153 
  154 /*
  155  * Detect if any leaf devices that have seen errors or could not be opened.
  156  */
  157 static boolean_t
  158 find_vdev_problem(nvlist_t *vdev, int (*func)(vdev_stat_t *, uint_t),
  159     boolean_t ignore_replacing)
  160 {
  161         nvlist_t **child;
  162         uint_t c, children;
  163 
  164         /*
  165          * Ignore problems within a 'replacing' vdev, since we're presumably in
  166          * the process of repairing any such errors, and don't want to call them
  167          * out again.  We'll pick up the fact that a resilver is happening
  168          * later.
  169          */
  170         if (ignore_replacing == B_TRUE) {
  171                 char *type = fnvlist_lookup_string(vdev, ZPOOL_CONFIG_TYPE);
  172                 if (strcmp(type, VDEV_TYPE_REPLACING) == 0)
  173                         return (B_FALSE);
  174         }
  175 
  176         if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_CHILDREN, &child,
  177             &children) == 0) {
  178                 for (c = 0; c < children; c++)
  179                         if (find_vdev_problem(child[c], func, ignore_replacing))
  180                                 return (B_TRUE);
  181         } else {
  182                 uint_t vsc;
  183                 vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(
  184                     vdev, ZPOOL_CONFIG_VDEV_STATS, &vsc);
  185                 if (func(vs, vsc) != 0)
  186                         return (B_TRUE);
  187         }
  188 
  189         /*
  190          * Check any L2 cache devs
  191          */
  192         if (nvlist_lookup_nvlist_array(vdev, ZPOOL_CONFIG_L2CACHE, &child,
  193             &children) == 0) {
  194                 for (c = 0; c < children; c++)
  195                         if (find_vdev_problem(child[c], func, ignore_replacing))
  196                                 return (B_TRUE);
  197         }
  198 
  199         return (B_FALSE);
  200 }
  201 
  202 /*
  203  * Active pool health status.
  204  *
  205  * To determine the status for a pool, we make several passes over the config,
  206  * picking the most egregious error we find.  In order of importance, we do the
  207  * following:
  208  *
  209  *      - Check for a complete and valid configuration
  210  *      - Look for any faulted or missing devices in a non-replicated config
  211  *      - Check for any data errors
  212  *      - Check for any faulted or missing devices in a replicated config
  213  *      - Look for any devices showing errors
  214  *      - Check for any resilvering or rebuilding devices
  215  *
  216  * There can obviously be multiple errors within a single pool, so this routine
  217  * only picks the most damaging of all the current errors to report.
  218  */
  219 static zpool_status_t
  220 check_status(nvlist_t *config, boolean_t isimport,
  221     zpool_errata_t *erratap, const char *compat)
  222 {
  223         pool_scan_stat_t *ps = NULL;
  224         uint_t vsc, psc;
  225         uint64_t suspended;
  226         uint64_t hostid = 0;
  227         uint64_t errata = 0;
  228         unsigned long system_hostid = get_system_hostid();
  229 
  230         uint64_t version = fnvlist_lookup_uint64(config, ZPOOL_CONFIG_VERSION);
  231         nvlist_t *nvroot = fnvlist_lookup_nvlist(config,
  232             ZPOOL_CONFIG_VDEV_TREE);
  233         vdev_stat_t *vs = (vdev_stat_t *)fnvlist_lookup_uint64_array(nvroot,
  234             ZPOOL_CONFIG_VDEV_STATS, &vsc);
  235         uint64_t stateval = fnvlist_lookup_uint64(config,
  236             ZPOOL_CONFIG_POOL_STATE);
  237 
  238         /*
  239          * Currently resilvering a vdev
  240          */
  241         (void) nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_SCAN_STATS,
  242             (uint64_t **)&ps, &psc);
  243         if (ps != NULL && ps->pss_func == POOL_SCAN_RESILVER &&
  244             ps->pss_state == DSS_SCANNING)
  245                 return (ZPOOL_STATUS_RESILVERING);
  246 
  247         /*
  248          * Currently rebuilding a vdev, check top-level vdevs.
  249          */
  250         vdev_rebuild_stat_t *vrs = NULL;
  251         nvlist_t **child;
  252         uint_t c, i, children;
  253         uint64_t rebuild_end_time = 0;
  254         if (nvlist_lookup_nvlist_array(nvroot, ZPOOL_CONFIG_CHILDREN,
  255             &child, &children) == 0) {
  256                 for (c = 0; c < children; c++) {
  257                         if ((nvlist_lookup_uint64_array(child[c],
  258                             ZPOOL_CONFIG_REBUILD_STATS,
  259                             (uint64_t **)&vrs, &i) == 0) && (vrs != NULL)) {
  260                                 uint64_t state = vrs->vrs_state;
  261 
  262                                 if (state == VDEV_REBUILD_ACTIVE) {
  263                                         return (ZPOOL_STATUS_REBUILDING);
  264                                 } else if (state == VDEV_REBUILD_COMPLETE &&
  265                                     vrs->vrs_end_time > rebuild_end_time) {
  266                                         rebuild_end_time = vrs->vrs_end_time;
  267                                 }
  268                         }
  269                 }
  270 
  271                 /*
  272                  * If we can determine when the last scrub was run, and it
  273                  * was before the last rebuild completed, then recommend
  274                  * that the pool be scrubbed to verify all checksums.  When
  275                  * ps is NULL we can infer the pool has never been scrubbed.
  276                  */
  277                 if (rebuild_end_time > 0) {
  278                         if (ps != NULL) {
  279                                 if ((ps->pss_state == DSS_FINISHED &&
  280                                     ps->pss_func == POOL_SCAN_SCRUB &&
  281                                     rebuild_end_time > ps->pss_end_time) ||
  282                                     ps->pss_state == DSS_NONE)
  283                                         return (ZPOOL_STATUS_REBUILD_SCRUB);
  284                         } else {
  285                                 return (ZPOOL_STATUS_REBUILD_SCRUB);
  286                         }
  287                 }
  288         }
  289 
  290         /*
  291          * The multihost property is set and the pool may be active.
  292          */
  293         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  294             vs->vs_aux == VDEV_AUX_ACTIVE) {
  295                 mmp_state_t mmp_state;
  296                 nvlist_t *nvinfo;
  297 
  298                 nvinfo = fnvlist_lookup_nvlist(config, ZPOOL_CONFIG_LOAD_INFO);
  299                 mmp_state = fnvlist_lookup_uint64(nvinfo,
  300                     ZPOOL_CONFIG_MMP_STATE);
  301 
  302                 if (mmp_state == MMP_STATE_ACTIVE)
  303                         return (ZPOOL_STATUS_HOSTID_ACTIVE);
  304                 else if (mmp_state == MMP_STATE_NO_HOSTID)
  305                         return (ZPOOL_STATUS_HOSTID_REQUIRED);
  306                 else
  307                         return (ZPOOL_STATUS_HOSTID_MISMATCH);
  308         }
  309 
  310         /*
  311          * Pool last accessed by another system.
  312          */
  313         (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_HOSTID, &hostid);
  314         if (hostid != 0 && (unsigned long)hostid != system_hostid &&
  315             stateval == POOL_STATE_ACTIVE)
  316                 return (ZPOOL_STATUS_HOSTID_MISMATCH);
  317 
  318         /*
  319          * Newer on-disk version.
  320          */
  321         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  322             vs->vs_aux == VDEV_AUX_VERSION_NEWER)
  323                 return (ZPOOL_STATUS_VERSION_NEWER);
  324 
  325         /*
  326          * Unsupported feature(s).
  327          */
  328         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  329             vs->vs_aux == VDEV_AUX_UNSUP_FEAT) {
  330                 nvlist_t *nvinfo = fnvlist_lookup_nvlist(config,
  331                     ZPOOL_CONFIG_LOAD_INFO);
  332                 if (nvlist_exists(nvinfo, ZPOOL_CONFIG_CAN_RDONLY))
  333                         return (ZPOOL_STATUS_UNSUP_FEAT_WRITE);
  334                 return (ZPOOL_STATUS_UNSUP_FEAT_READ);
  335         }
  336 
  337         /*
  338          * Check that the config is complete.
  339          */
  340         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  341             vs->vs_aux == VDEV_AUX_BAD_GUID_SUM)
  342                 return (ZPOOL_STATUS_BAD_GUID_SUM);
  343 
  344         /*
  345          * Check whether the pool has suspended.
  346          */
  347         if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED,
  348             &suspended) == 0) {
  349                 uint64_t reason;
  350 
  351                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_SUSPENDED_REASON,
  352                     &reason) == 0 && reason == ZIO_SUSPEND_MMP)
  353                         return (ZPOOL_STATUS_IO_FAILURE_MMP);
  354 
  355                 if (suspended == ZIO_FAILURE_MODE_CONTINUE)
  356                         return (ZPOOL_STATUS_IO_FAILURE_CONTINUE);
  357                 return (ZPOOL_STATUS_IO_FAILURE_WAIT);
  358         }
  359 
  360         /*
  361          * Could not read a log.
  362          */
  363         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  364             vs->vs_aux == VDEV_AUX_BAD_LOG) {
  365                 return (ZPOOL_STATUS_BAD_LOG);
  366         }
  367 
  368         /*
  369          * Bad devices in non-replicated config.
  370          */
  371         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  372             find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
  373                 return (ZPOOL_STATUS_FAULTED_DEV_NR);
  374 
  375         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  376             find_vdev_problem(nvroot, vdev_missing, B_TRUE))
  377                 return (ZPOOL_STATUS_MISSING_DEV_NR);
  378 
  379         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  380             find_vdev_problem(nvroot, vdev_broken, B_TRUE))
  381                 return (ZPOOL_STATUS_CORRUPT_LABEL_NR);
  382 
  383         /*
  384          * Corrupted pool metadata
  385          */
  386         if (vs->vs_state == VDEV_STATE_CANT_OPEN &&
  387             vs->vs_aux == VDEV_AUX_CORRUPT_DATA)
  388                 return (ZPOOL_STATUS_CORRUPT_POOL);
  389 
  390         /*
  391          * Persistent data errors.
  392          */
  393         if (!isimport) {
  394                 uint64_t nerr;
  395                 if (nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRCOUNT,
  396                     &nerr) == 0 && nerr != 0)
  397                         return (ZPOOL_STATUS_CORRUPT_DATA);
  398         }
  399 
  400         /*
  401          * Missing devices in a replicated config.
  402          */
  403         if (find_vdev_problem(nvroot, vdev_faulted, B_TRUE))
  404                 return (ZPOOL_STATUS_FAULTED_DEV_R);
  405         if (find_vdev_problem(nvroot, vdev_missing, B_TRUE))
  406                 return (ZPOOL_STATUS_MISSING_DEV_R);
  407         if (find_vdev_problem(nvroot, vdev_broken, B_TRUE))
  408                 return (ZPOOL_STATUS_CORRUPT_LABEL_R);
  409 
  410         /*
  411          * Devices with errors
  412          */
  413         if (!isimport && find_vdev_problem(nvroot, vdev_errors, B_TRUE))
  414                 return (ZPOOL_STATUS_FAILING_DEV);
  415 
  416         /*
  417          * Offlined devices
  418          */
  419         if (find_vdev_problem(nvroot, vdev_offlined, B_TRUE))
  420                 return (ZPOOL_STATUS_OFFLINE_DEV);
  421 
  422         /*
  423          * Removed device
  424          */
  425         if (find_vdev_problem(nvroot, vdev_removed, B_TRUE))
  426                 return (ZPOOL_STATUS_REMOVED_DEV);
  427 
  428         /*
  429          * Suboptimal, but usable, ashift configuration.
  430          */
  431         if (find_vdev_problem(nvroot, vdev_non_native_ashift, B_FALSE))
  432                 return (ZPOOL_STATUS_NON_NATIVE_ASHIFT);
  433 
  434         /*
  435          * Informational errata available.
  436          */
  437         (void) nvlist_lookup_uint64(config, ZPOOL_CONFIG_ERRATA, &errata);
  438         if (errata) {
  439                 *erratap = errata;
  440                 return (ZPOOL_STATUS_ERRATA);
  441         }
  442 
  443         /*
  444          * Outdated, but usable, version
  445          */
  446         if (SPA_VERSION_IS_SUPPORTED(version) && version != SPA_VERSION) {
  447                 /* "legacy" compatibility disables old version reporting */
  448                 if (compat != NULL && strcmp(compat, ZPOOL_COMPAT_LEGACY) == 0)
  449                         return (ZPOOL_STATUS_OK);
  450                 else
  451                         return (ZPOOL_STATUS_VERSION_OLDER);
  452         }
  453 
  454         /*
  455          * Usable pool with disabled or superfluous features
  456          * (superfluous = beyond what's requested by 'compatibility')
  457          */
  458         if (version >= SPA_VERSION_FEATURES) {
  459                 int i;
  460                 nvlist_t *feat;
  461 
  462                 if (isimport) {
  463                         feat = fnvlist_lookup_nvlist(config,
  464                             ZPOOL_CONFIG_LOAD_INFO);
  465                         if (nvlist_exists(feat, ZPOOL_CONFIG_ENABLED_FEAT))
  466                                 feat = fnvlist_lookup_nvlist(feat,
  467                                     ZPOOL_CONFIG_ENABLED_FEAT);
  468                 } else {
  469                         feat = fnvlist_lookup_nvlist(config,
  470                             ZPOOL_CONFIG_FEATURE_STATS);
  471                 }
  472 
  473                 /* check against all features, or limited set? */
  474                 boolean_t c_features[SPA_FEATURES];
  475 
  476                 switch (zpool_load_compat(compat, c_features, NULL, 0)) {
  477                 case ZPOOL_COMPATIBILITY_OK:
  478                 case ZPOOL_COMPATIBILITY_WARNTOKEN:
  479                         break;
  480                 default:
  481                         return (ZPOOL_STATUS_COMPATIBILITY_ERR);
  482                 }
  483                 for (i = 0; i < SPA_FEATURES; i++) {
  484                         zfeature_info_t *fi = &spa_feature_table[i];
  485                         if (!fi->fi_zfs_mod_supported)
  486                                 continue;
  487                         if (c_features[i] && !nvlist_exists(feat, fi->fi_guid))
  488                                 return (ZPOOL_STATUS_FEAT_DISABLED);
  489                         if (!c_features[i] && nvlist_exists(feat, fi->fi_guid))
  490                                 return (ZPOOL_STATUS_INCOMPATIBLE_FEAT);
  491                 }
  492         }
  493 
  494         return (ZPOOL_STATUS_OK);
  495 }
  496 
  497 zpool_status_t
  498 zpool_get_status(zpool_handle_t *zhp, const char **msgid,
  499     zpool_errata_t *errata)
  500 {
  501         /*
  502          * pass in the desired feature set, as
  503          * it affects check for disabled features
  504          */
  505         char compatibility[ZFS_MAXPROPLEN];
  506         if (zpool_get_prop(zhp, ZPOOL_PROP_COMPATIBILITY, compatibility,
  507             ZFS_MAXPROPLEN, NULL, B_FALSE) != 0)
  508                 compatibility[0] = '\0';
  509 
  510         zpool_status_t ret = check_status(zhp->zpool_config, B_FALSE, errata,
  511             compatibility);
  512 
  513         if (msgid != NULL) {
  514                 if (ret >= NMSGID)
  515                         *msgid = NULL;
  516                 else
  517                         *msgid = zfs_msgid_table[ret];
  518         }
  519         return (ret);
  520 }
  521 
  522 zpool_status_t
  523 zpool_import_status(nvlist_t *config, const char **msgid,
  524     zpool_errata_t *errata)
  525 {
  526         zpool_status_t ret = check_status(config, B_TRUE, errata, NULL);
  527 
  528         if (ret >= NMSGID)
  529                 *msgid = NULL;
  530         else
  531                 *msgid = zfs_msgid_table[ret];
  532 
  533         return (ret);
  534 }

Cache object: 753e06b186bcdb1becfd34f7ce850ed4


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.