Print this page
    
re #13850 Refactor ZFS config discovery IOCs to libzfs_core patterns
re #9110 rb2713 - zdb dies with arithmetic exception
re #8346 rb2639 KT disk failures
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/lib/libzpool/common/util.c
          +++ new/usr/src/lib/libzpool/common/util.c
   1    1  /*
   2    2   * CDDL HEADER START
   3    3   *
   4    4   * The contents of this file are subject to the terms of the
   5    5   * Common Development and Distribution License (the "License").
   6    6   * You may not use this file except in compliance with the License.
   7    7   *
   8    8   * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9    9   * or http://www.opensolaris.org/os/licensing.
  10   10   * See the License for the specific language governing permissions
  11   11   * and limitations under the License.
  12   12   *
  
    | 
      ↓ open down ↓ | 
    12 lines elided | 
    
      ↑ open up ↑ | 
  
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2013 Nexenta Systems, Inc.  All rights reserved.
  23   24   * Copyright (c) 2016 by Delphix. All rights reserved.
  24   25   * Copyright 2017 RackTop Systems.
  25   26   */
  26   27  
  27   28  #include <assert.h>
  28   29  #include <sys/zfs_context.h>
  29   30  #include <sys/avl.h>
  30   31  #include <string.h>
  31   32  #include <stdio.h>
  32   33  #include <stdlib.h>
  33   34  #include <sys/spa.h>
  34   35  #include <sys/fs/zfs.h>
  35   36  #include <sys/refcount.h>
  36   37  #include <dlfcn.h>
  37   38  
  38   39  extern void nicenum(uint64_t num, char *buf, size_t);
  
    | 
      ↓ open down ↓ | 
    6 lines elided | 
    
      ↑ open up ↑ | 
  
  39   40  
  40   41  /*
  41   42   * Routines needed by more than one client of libzpool.
  42   43   */
  43   44  
  44   45  static void
  45   46  show_vdev_stats(const char *desc, const char *ctype, nvlist_t *nv, int indent)
  46   47  {
  47   48          vdev_stat_t *vs;
  48   49          vdev_stat_t v0 = { 0 };
  49      -        uint64_t sec;
       50 +        uint64_t sec, ops_rd, ops_wr;
  50   51          uint64_t is_log = 0;
  51   52          nvlist_t **child;
  52   53          uint_t c, children;
  53   54          char used[6], avail[6];
  54   55          char rops[6], wops[6], rbytes[6], wbytes[6], rerr[6], werr[6], cerr[6];
       56 +        char riotime[8], wiotime[8];
  55   57          char *prefix = "";
  56   58  
  57   59          if (indent == 0 && desc != NULL) {
  58   60                  (void) printf("                           "
  59      -                    " capacity   operations   bandwidth  ---- errors ----\n");
       61 +                    " capacity   operations   bandwidth   --- latency ---  "
       62 +                    "---- errors ----\n");
  60   63                  (void) printf("description                "
  61      -                    "used avail  read write  read write  read write cksum\n");
       64 +                    "used avail  read write  read write     read    write  "
       65 +                    "read write cksum\n");
  62   66          }
  63   67  
  64   68          if (desc != NULL) {
  65   69                  (void) nvlist_lookup_uint64(nv, ZPOOL_CONFIG_IS_LOG, &is_log);
  66   70  
  67   71                  if (is_log)
  68   72                          prefix = "log ";
  69   73  
  70   74                  if (nvlist_lookup_uint64_array(nv, ZPOOL_CONFIG_VDEV_STATS,
  71   75                      (uint64_t **)&vs, &c) != 0)
  72   76                          vs = &v0;
  73   77  
  74   78                  sec = MAX(1, vs->vs_timestamp / NANOSEC);
       79 +                ops_rd = MAX(1, vs->vs_ops[ZIO_TYPE_READ]);
       80 +                ops_wr = MAX(1, vs->vs_ops[ZIO_TYPE_WRITE]);
  75   81  
  76   82                  nicenum(vs->vs_alloc, used, sizeof (used));
  77   83                  nicenum(vs->vs_space - vs->vs_alloc, avail, sizeof (avail));
  78   84                  nicenum(vs->vs_ops[ZIO_TYPE_READ] / sec, rops, sizeof (rops));
  79   85                  nicenum(vs->vs_ops[ZIO_TYPE_WRITE] / sec, wops, sizeof (wops));
  80   86                  nicenum(vs->vs_bytes[ZIO_TYPE_READ] / sec, rbytes,
  81   87                      sizeof (rbytes));
  82   88                  nicenum(vs->vs_bytes[ZIO_TYPE_WRITE] / sec, wbytes,
  83   89                      sizeof (wbytes));
       90 +                nicenum(vs->vs_iotime[ZIO_TYPE_READ] / ops_rd, riotime,
       91 +                    sizeof (riotime));
       92 +                nicenum(vs->vs_iotime[ZIO_TYPE_WRITE] / ops_wr, wiotime,
       93 +                    sizeof (wiotime));
  84   94                  nicenum(vs->vs_read_errors, rerr, sizeof (rerr));
  85   95                  nicenum(vs->vs_write_errors, werr, sizeof (werr));
  86   96                  nicenum(vs->vs_checksum_errors, cerr, sizeof (cerr));
  87   97  
  88      -                (void) printf("%*s%s%*s%*s%*s %5s %5s %5s %5s %5s %5s %5s\n",
       98 +                (void) printf(
       99 +                    "%*s%s%*s%*s%*s %5s %5s %5s %5s %8s %8s %5s %5s %5s\n",
  89  100                      indent, "",
  90  101                      prefix,
  91  102                      indent + strlen(prefix) - 25 - (vs->vs_space ? 0 : 12),
  92  103                      desc,
  93  104                      vs->vs_space ? 6 : 0, vs->vs_space ? used : "",
  94  105                      vs->vs_space ? 6 : 0, vs->vs_space ? avail : "",
  95      -                    rops, wops, rbytes, wbytes, rerr, werr, cerr);
      106 +                    rops, wops, rbytes, wbytes, riotime, wiotime, rerr, werr,
      107 +                    cerr);
  96  108          }
  97  109  
  98  110          if (nvlist_lookup_nvlist_array(nv, ctype, &child, &children) != 0)
  99  111                  return;
 100  112  
 101  113          for (c = 0; c < children; c++) {
 102  114                  nvlist_t *cnv = child[c];
 103  115                  char *cname, *tname;
 104  116                  uint64_t np;
 105  117                  if (nvlist_lookup_string(cnv, ZPOOL_CONFIG_PATH, &cname) &&
 106  118                      nvlist_lookup_string(cnv, ZPOOL_CONFIG_TYPE, &cname))
 107  119                          cname = "<unknown>";
 108  120                  tname = calloc(1, strlen(cname) + 2);
 109  121                  (void) strcpy(tname, cname);
 110  122                  if (nvlist_lookup_uint64(cnv, ZPOOL_CONFIG_NPARITY, &np) == 0)
 111  123                          tname[strlen(tname)] = '0' + np;
 112  124                  show_vdev_stats(tname, ctype, cnv, indent + 2);
 113  125                  free(tname);
 114  126          }
 115  127  }
 116  128  
 117  129  void
 118  130  show_pool_stats(spa_t *spa)
 119  131  {
 120  132          nvlist_t *config, *nvroot;
 121  133          char *name;
 122  134  
 123  135          VERIFY(spa_get_stats(spa_name(spa), &config, NULL, 0) == 0);
 124  136  
 125  137          VERIFY(nvlist_lookup_nvlist(config, ZPOOL_CONFIG_VDEV_TREE,
 126  138              &nvroot) == 0);
 127  139          VERIFY(nvlist_lookup_string(config, ZPOOL_CONFIG_POOL_NAME,
 128  140              &name) == 0);
 129  141  
 130  142          show_vdev_stats(name, ZPOOL_CONFIG_CHILDREN, nvroot, 0);
 131  143          show_vdev_stats(NULL, ZPOOL_CONFIG_L2CACHE, nvroot, 0);
 132  144          show_vdev_stats(NULL, ZPOOL_CONFIG_SPARES, nvroot, 0);
 133  145  
 134  146          nvlist_free(config);
 135  147  }
 136  148  
 137  149  /*
 138  150   * Sets given global variable in libzpool to given unsigned 32-bit value.
 139  151   * arg: "<variable>=<value>"
 140  152   */
 141  153  int
 142  154  set_global_var(char *arg)
 143  155  {
 144  156          void *zpoolhdl;
 145  157          char *varname = arg, *varval;
 146  158          u_longlong_t val;
 147  159  
 148  160  #ifndef _LITTLE_ENDIAN
 149  161          /*
 150  162           * On big endian systems changing a 64-bit variable would set the high
 151  163           * 32 bits instead of the low 32 bits, which could cause unexpected
 152  164           * results.
 153  165           */
 154  166          fprintf(stderr, "Setting global variables is only supported on "
 155  167              "little-endian systems\n", varname);
 156  168          return (ENOTSUP);
 157  169  #endif
 158  170          if ((varval = strchr(arg, '=')) != NULL) {
 159  171                  *varval = '\0';
 160  172                  varval++;
 161  173                  val = strtoull(varval, NULL, 0);
 162  174                  if (val > UINT32_MAX) {
 163  175                          fprintf(stderr, "Value for global variable '%s' must "
 164  176                              "be a 32-bit unsigned integer\n", varname);
 165  177                          return (EOVERFLOW);
 166  178                  }
 167  179          } else {
 168  180                  return (EINVAL);
 169  181          }
 170  182  
 171  183          zpoolhdl = dlopen("libzpool.so", RTLD_LAZY);
 172  184          if (zpoolhdl != NULL) {
 173  185                  uint32_t *var;
 174  186                  var = dlsym(zpoolhdl, varname);
 175  187                  if (var == NULL) {
 176  188                          fprintf(stderr, "Global variable '%s' does not exist "
 177  189                              "in libzpool.so\n", varname);
 178  190                          return (EINVAL);
 179  191                  }
 180  192                  *var = (uint32_t)val;
 181  193  
 182  194                  dlclose(zpoolhdl);
 183  195          } else {
 184  196                  fprintf(stderr, "Failed to open libzpool.so to set global "
 185  197                      "variable\n");
 186  198                  return (EIO);
 187  199          }
 188  200  
 189  201          return (0);
 190  202  }
  
    | 
      ↓ open down ↓ | 
    85 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX