Print this page
    
re #13388 rb4382 fmd_api.h uses bool which is a C99/C++ keyword
    
      
        | Split | 
	Close | 
      
      | Expand all | 
      | Collapse all | 
    
    
          --- old/usr/src/cmd/fm/fmd/common/fmd_mdb.c
          +++ new/usr/src/cmd/fm/fmd/common/fmd_mdb.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   *
  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  /*
  23   23   * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
  24   24   */
  25   25  
  26   26  #include <sys/mdb_modapi.h>
  27   27  #include <limits.h>
  28   28  
  29   29  #include <fmd_trace.h>
  30   30  #include <fmd_module.h>
  31   31  #include <fmd_thread.h>
  32   32  #include <fmd_ustat.h>
  33   33  #include <fmd_event.h>
  34   34  #include <fmd_case.h>
  35   35  #include <fmd_buf.h>
  36   36  #include <fmd_asru.h>
  37   37  #include <fmd_ckpt.h>
  38   38  #include <fmd_timerq.h>
  39   39  #include <fmd_xprt.h>
  40   40  
  41   41  #include <fmd.h>
  42   42  
  43   43  typedef struct trwalk_state {
  44   44          struct trwalk_state *trw_next;
  45   45          fmd_tracebuf_t trw_data;
  46   46          pthread_t trw_tid;
  47   47          uintptr_t trw_base;
  48   48          const fmd_tracerec_t *trw_stop;
  49   49          fmd_tracerec_t *trw_xrec;
  50   50  } trwalk_state_t;
  51   51  
  52   52  typedef struct hashwalk_data {
  53   53          uintptr_t *hw_hash;
  54   54          uint_t hw_hashlen;
  55   55          uint_t hw_hashidx;
  56   56          const char *hw_name;
  57   57          void *hw_data;
  58   58          size_t hw_size;
  59   59          size_t hw_next;
  60   60  } hashwalk_data_t;
  61   61  
  62   62  static int fmd_stat(uintptr_t, uint_t, int, const mdb_arg_t *);
  63   63  static int fmd_ustat(uintptr_t, uint_t, int, const mdb_arg_t *);
  64   64  
  65   65  static int
  66   66  trwalk_init(mdb_walk_state_t *wsp)
  67   67  {
  68   68          uintptr_t addr;
  69   69          fmd_thread_t thr;
  70   70          fmd_t F;
  71   71  
  72   72          if (wsp->walk_addr != NULL) {
  73   73                  mdb_warn("fmd_trace only supports global walks\n");
  74   74                  return (WALK_ERR);
  75   75          }
  76   76  
  77   77          if (mdb_readvar(&F, "fmd") != sizeof (F)) {
  78   78                  mdb_warn("failed to read fmd meta-data");
  79   79                  return (WALK_ERR);
  80   80          }
  81   81  
  82   82          for (addr = (uintptr_t)F.d_thr_list.l_next; addr != NULL;
  83   83              addr = (uintptr_t)thr.thr_list.l_next) {
  84   84  
  85   85                  size_t len, ptr_off, end_off;
  86   86                  fmd_tracerec_t *buf;
  87   87                  trwalk_state_t *t;
  88   88  
  89   89                  if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
  90   90                          mdb_warn("failed to read thread at %p "
  91   91                              "(some trace data will be unavailable)", addr);
  92   92                          break;
  93   93                  }
  94   94  
  95   95                  t = mdb_zalloc(sizeof (trwalk_state_t), UM_SLEEP);
  96   96                  t->trw_next = wsp->walk_data;
  97   97                  wsp->walk_data = t;
  98   98  
  99   99                  (void) mdb_vread(&t->trw_data,
 100  100                      sizeof (t->trw_data), (uintptr_t)thr.thr_trdata);
 101  101  
 102  102                  if (t->trw_data.tb_recs == 0)
 103  103                          continue; /* no trace buffer allocated for thread */
 104  104  
 105  105                  len = t->trw_data.tb_recs * t->trw_data.tb_size;
 106  106                  buf = mdb_alloc(len, UM_SLEEP);
 107  107  
 108  108                  t->trw_tid = thr.thr_tid;
 109  109                  t->trw_base = (uintptr_t)t->trw_data.tb_buf;
 110  110  
 111  111                  if (mdb_vread(buf, len, t->trw_base) == -1) {
 112  112                          mdb_warn("failed to read buffer for t%u", t->trw_tid);
 113  113                          bzero(buf, len);
 114  114                  }
 115  115  
 116  116                  end_off = (uintptr_t)t->trw_data.tb_end - t->trw_base;
 117  117                  ptr_off = (uintptr_t)t->trw_data.tb_ptr - t->trw_base;
 118  118  
 119  119                  t->trw_data.tb_buf = buf;
 120  120                  t->trw_data.tb_end = (void *)((uintptr_t)buf + end_off);
 121  121                  t->trw_data.tb_ptr = (void *)((uintptr_t)buf + ptr_off);
 122  122  
 123  123                  if (t->trw_data.tb_ptr < t->trw_data.tb_buf ||
 124  124                      t->trw_data.tb_ptr > t->trw_data.tb_end) {
 125  125                          mdb_warn("trace record ptr for t%u is corrupt "
 126  126                              "(some data may be unavailable)\n", t->trw_tid);
 127  127                          t->trw_data.tb_ptr = t->trw_data.tb_buf;
 128  128                  }
 129  129  
 130  130                  t->trw_stop = t->trw_data.tb_ptr;
 131  131                  t->trw_xrec = mdb_alloc(
 132  132                      t->trw_data.tb_size + sizeof (uintptr_t), UM_SLEEP);
 133  133          }
 134  134  
 135  135          return (WALK_NEXT);
 136  136  }
 137  137  
 138  138  static fmd_tracerec_t *
 139  139  trwalk_nextrec(trwalk_state_t *t)
 140  140  {
 141  141          if (t->trw_stop == NULL)
 142  142                  return (t->trw_data.tb_ptr);
 143  143  
 144  144          if (t->trw_data.tb_ptr == t->trw_data.tb_buf)
 145  145                  t->trw_data.tb_ptr = t->trw_data.tb_end;
 146  146          else
 147  147                  t->trw_data.tb_ptr = (fmd_tracerec_t *)
 148  148                      ((uintptr_t)t->trw_data.tb_ptr - t->trw_data.tb_size);
 149  149  
 150  150          if (t->trw_data.tb_ptr == t->trw_stop)
 151  151                  t->trw_stop = NULL; /* mark buffer as empty */
 152  152  
 153  153          return (t->trw_data.tb_ptr);
 154  154  }
 155  155  
 156  156  static int
 157  157  trwalk_step(mdb_walk_state_t *wsp)
 158  158  {
 159  159          trwalk_state_t *t, *oldest_t;
 160  160          hrtime_t oldest_time = 0;
 161  161          fmd_tracerec_t *trp;
 162  162          int status;
 163  163  
 164  164          for (t = wsp->walk_data; t != NULL; t = t->trw_next) {
 165  165                  for (trp = t->trw_data.tb_ptr; t->trw_stop != NULL &&
 166  166                      trp->tr_time == 0; trp = trwalk_nextrec(t))
 167  167                          continue;
 168  168  
 169  169                  if (t->trw_stop == NULL)
 170  170                          continue; /* buffer has been emptied */
 171  171  
 172  172                  if (trp->tr_time > oldest_time) {
 173  173                          oldest_time = trp->tr_time;
 174  174                          oldest_t = t;
 175  175                  }
 176  176          }
 177  177  
 178  178          if (oldest_time == 0)
 179  179                  return (WALK_DONE);
 180  180  
 181  181          t = oldest_t;
 182  182          trp = t->trw_data.tb_ptr;
 183  183  
 184  184          bcopy(trp, t->trw_xrec, t->trw_data.tb_size);
 185  185          t->trw_xrec->tr_depth = MIN(trp->tr_depth, t->trw_data.tb_frames);
 186  186          t->trw_xrec->tr_stack[t->trw_xrec->tr_depth] = t->trw_tid;
 187  187  
 188  188          status = wsp->walk_callback((uintptr_t)trp - (uintptr_t)
 189  189              t->trw_data.tb_buf + t->trw_base, t->trw_xrec, wsp->walk_cbdata);
 190  190  
 191  191          (void) trwalk_nextrec(t);
 192  192          return (status);
 193  193  }
 194  194  
 195  195  static void
 196  196  trwalk_fini(mdb_walk_state_t *wsp)
 197  197  {
 198  198          trwalk_state_t *t, *u;
 199  199  
 200  200          for (t = wsp->walk_data; t != NULL; t = u) {
 201  201                  u = t->trw_next;
 202  202                  mdb_free(t->trw_data.tb_buf,
 203  203                      t->trw_data.tb_recs * t->trw_data.tb_size);
 204  204                  mdb_free(t->trw_xrec, t->trw_data.tb_size + sizeof (uintptr_t));
 205  205                  mdb_free(t, sizeof (trwalk_state_t));
 206  206          }
 207  207  }
 208  208  
 209  209  /*ARGSUSED*/
 210  210  static int
 211  211  trprint_msg(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
 212  212  {
 213  213          if (tid == 0)
 214  214                  mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]);
 215  215          else if (trp->tr_stack[trp->tr_depth] != tid)
 216  216                  return (WALK_NEXT);
 217  217  
 218  218          mdb_printf("%016llx %04x %-5u %s\n",
 219  219              trp->tr_time, 1 << trp->tr_tag, trp->tr_errno, trp->tr_msg);
 220  220  
 221  221          return (WALK_NEXT);
 222  222  }
 223  223  
 224  224  /*ARGSUSED*/
 225  225  static int
 226  226  trprint_cpp(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
 227  227  {
 228  228          char file[64];
 229  229  
 230  230          if (tid == 0)
 231  231                  mdb_printf("%3lu ", trp->tr_stack[trp->tr_depth]);
 232  232          else if (trp->tr_stack[trp->tr_depth] != tid)
 233  233                  return (WALK_NEXT);
 234  234  
 235  235          if (mdb_readstr(file, sizeof (file), (uintptr_t)trp->tr_file) <= 0)
 236  236                  (void) strcpy(file, "???");
 237  237  
 238  238          mdb_printf("%016llx %04x %s: %u\n",
 239  239              trp->tr_time, 1 << trp->tr_tag, file, trp->tr_line);
 240  240  
 241  241          return (WALK_NEXT);
 242  242  }
 243  243  
 244  244  static void
 245  245  trprint_stack(const fmd_tracerec_t *trp)
 246  246  {
 247  247          uint8_t i;
 248  248  
 249  249          for (i = 0; i < trp->tr_depth; i++)
 250  250                  mdb_printf("\t%a\n", trp->tr_stack[i]);
 251  251  
 252  252          if (trp->tr_depth != 0)
 253  253                  mdb_printf("\n");
 254  254  }
 255  255  
 256  256  static int
 257  257  trprint_msg_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
 258  258  {
 259  259          int status = trprint_msg(addr, trp, tid);
 260  260          trprint_stack(trp);
 261  261          return (status);
 262  262  }
 263  263  
 264  264  static int
 265  265  trprint_cpp_stack(uintptr_t addr, const fmd_tracerec_t *trp, uintptr_t tid)
 266  266  {
 267  267          int status = trprint_cpp(addr, trp, tid);
 268  268          trprint_stack(trp);
 269  269          return (status);
 270  270  }
 271  271  
 272  272  static int
 273  273  fmd_trace(uintptr_t tid, uint_t flags, int argc, const mdb_arg_t *argv)
 274  274  {
 275  275          int (*func)(uintptr_t, const fmd_tracerec_t *, uintptr_t);
 276  276          uint_t opt_c = FALSE, opt_s = FALSE;
 277  277  
 278  278          if (mdb_getopts(argc, argv,
 279  279              'c', MDB_OPT_SETBITS, TRUE, &opt_c,
 280  280              's', MDB_OPT_SETBITS, TRUE, &opt_s, NULL) != argc)
 281  281                  return (DCMD_USAGE);
 282  282  
 283  283          if (!(flags & DCMD_ADDRSPEC)) {
 284  284                  mdb_printf("TID ");
 285  285                  tid = 0;
 286  286          }
 287  287  
 288  288          if (opt_c) {
 289  289                  mdb_printf("%-16s %-4s FILE:LINE\n", "TIME", "TAG");
 290  290                  func = opt_s ? trprint_cpp_stack : trprint_cpp;
 291  291          } else {
 292  292                  mdb_printf("%-16s %-4s %-5s MSG\n", "TIME", "TAG", "ERRNO");
 293  293                  func = opt_s ? trprint_msg_stack : trprint_msg;
 294  294          }
 295  295  
 296  296          if (mdb_walk("fmd_trace", (mdb_walk_cb_t)func, (void *)tid) == -1) {
 297  297                  mdb_warn("failed to walk fmd_trace");
 298  298                  return (DCMD_ERR);
 299  299          }
 300  300  
 301  301          return (DCMD_OK);
 302  302  }
 303  303  
 304  304  static int
 305  305  hash_walk_init(mdb_walk_state_t *wsp, uintptr_t addr, uint_t hashlen,
 306  306      const char *name, size_t size, size_t next)
 307  307  {
 308  308          hashwalk_data_t *hwp;
 309  309          size_t len = sizeof (uintptr_t) * hashlen;
 310  310  
 311  311          if (len == 0) {
 312  312                  mdb_warn("failed to walk hash: invalid hash length\n");
 313  313                  return (WALK_ERR);
 314  314          }
 315  315  
 316  316          hwp = mdb_alloc(sizeof (hashwalk_data_t), UM_SLEEP);
 317  317          hwp->hw_hash = mdb_zalloc(len, UM_SLEEP);
 318  318          (void) mdb_vread(hwp->hw_hash, len, addr);
 319  319          hwp->hw_hashlen = hashlen;
 320  320          hwp->hw_hashidx = 0;
 321  321          hwp->hw_name = name;
 322  322          hwp->hw_data = mdb_zalloc(size, UM_SLEEP);
 323  323          hwp->hw_size = size;
 324  324          hwp->hw_next = next;
 325  325  
 326  326          wsp->walk_addr = hwp->hw_hash[0];
 327  327          wsp->walk_data = hwp;
 328  328  
 329  329          return (WALK_NEXT);
 330  330  }
 331  331  
 332  332  static int
 333  333  hash_walk_step(mdb_walk_state_t *wsp)
 334  334  {
 335  335          hashwalk_data_t *hwp = wsp->walk_data;
 336  336          int rv;
 337  337  
 338  338          while (wsp->walk_addr == NULL) {
 339  339                  if (++hwp->hw_hashidx < hwp->hw_hashlen)
 340  340                          wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx];
 341  341                  else
 342  342                          return (WALK_DONE);
 343  343          }
 344  344  
 345  345          if (mdb_vread(hwp->hw_data, hwp->hw_size, wsp->walk_addr) == -1) {
 346  346                  mdb_warn("failed to read %s at %p",
 347  347                      hwp->hw_name, wsp->walk_addr);
 348  348                  return (WALK_ERR);
 349  349          }
 350  350  
 351  351          rv = wsp->walk_callback(wsp->walk_addr, hwp->hw_data, wsp->walk_cbdata);
 352  352          wsp->walk_addr = *(uintptr_t *)((uintptr_t)hwp->hw_data + hwp->hw_next);
 353  353          return (rv);
 354  354  }
 355  355  
 356  356  static void
 357  357  hash_walk_fini(mdb_walk_state_t *wsp)
 358  358  {
 359  359          hashwalk_data_t *hwp = wsp->walk_data;
 360  360  
 361  361          mdb_free(hwp->hw_hash, sizeof (uintptr_t) * hwp->hw_hashlen);
 362  362          mdb_free(hwp->hw_data, hwp->hw_size);
 363  363          mdb_free(hwp, sizeof (hashwalk_data_t));
 364  364  }
 365  365  
 366  366  static int
 367  367  ustat_walk_init(mdb_walk_state_t *wsp)
 368  368  {
 369  369          fmd_ustat_t us;
 370  370  
 371  371          if (mdb_vread(&us, sizeof (us), wsp->walk_addr) != sizeof (us)) {
 372  372                  mdb_warn("failed to read fmd_ustat_t at %p", wsp->walk_addr);
 373  373                  return (WALK_ERR);
 374  374          }
 375  375  
 376  376          return (hash_walk_init(wsp,
 377  377              (uintptr_t)us.us_hash, us.us_hashlen, NULL, 0, 0));
 378  378  }
 379  379  
 380  380  static int
 381  381  ustat_walk_step(mdb_walk_state_t *wsp)
 382  382  {
 383  383          hashwalk_data_t *hwp = wsp->walk_data;
 384  384          fmd_ustat_elem_t ue;
 385  385          fmd_stat_t s;
 386  386  
 387  387          while (wsp->walk_addr == NULL) {
 388  388                  if (++hwp->hw_hashidx < hwp->hw_hashlen)
 389  389                          wsp->walk_addr = hwp->hw_hash[hwp->hw_hashidx];
 390  390                  else
 391  391                          return (WALK_DONE);
 392  392          }
 393  393  
 394  394          if (mdb_vread(&ue, sizeof (ue), wsp->walk_addr) != sizeof (ue) ||
 395  395              mdb_vread(&s, sizeof (s), (uintptr_t)ue.use_stat) != sizeof (s)) {
 396  396                  mdb_warn("failed to read stat element at %p", wsp->walk_addr);
 397  397                  return (WALK_ERR);
 398  398          }
 399  399  
 400  400          wsp->walk_addr = (uintptr_t)ue.use_next;
 401  401  
 402  402          return (wsp->walk_callback(
 403  403              (uintptr_t)ue.use_stat, &s, wsp->walk_cbdata));
 404  404  }
 405  405  
 406  406  struct fmd_cmd_data {
 407  407          int argc;
 408  408          const mdb_arg_t *argv;
 409  409  };
 410  410  
 411  411  /* ARGSUSED */
 412  412  static int
 413  413  module_ustat(uintptr_t addr, const void *data, void *wsp)
 414  414  {
 415  415          fmd_module_t *modp = (fmd_module_t *)data;
 416  416          char name[PATH_MAX];
 417  417          const struct fmd_cmd_data *udp = wsp;
 418  418  
 419  419          if (mdb_readstr(name, sizeof (name), (uintptr_t)modp->mod_name) <= 0)
 420  420                  (void) mdb_snprintf(name, sizeof (name), "<%p>",
 421  421                      modp->mod_name);
 422  422          mdb_printf("%s\n", name);
 423  423          (void) fmd_ustat((uintptr_t)modp->mod_ustat,
 424  424              DCMD_ADDRSPEC | DCMD_LOOPFIRST, udp->argc, udp->argv);
 425  425          return (WALK_NEXT);
 426  426  }
 427  427  
 428  428  static int
 429  429  fmd_ustat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 430  430  {
 431  431          if (!(flags & DCMD_ADDRSPEC)) {
 432  432                  struct fmd_cmd_data ud;
 433  433  
 434  434                  ud.argc = argc;
 435  435                  ud.argv = argv;
 436  436                  if (mdb_walk("fmd_module", module_ustat, &ud) == -1) {
 437  437                          mdb_warn("failed to walk 'fmd_module'");
 438  438                          return (DCMD_ERR);
 439  439                  }
 440  440                  return (DCMD_OK);
 441  441          }
 442  442  
 443  443          if (mdb_pwalk_dcmd("fmd_ustat", "fmd_stat", argc, argv, addr) != 0) {
 444  444                  mdb_warn("failed to walk fmd_ustat at %p", addr);
 445  445                  return (DCMD_ERR);
 446  446          }
 447  447  
 448  448          return (DCMD_OK);
 449  449  }
 450  450  
 451  451  /* ARGSUSED */
 452  452  static int
 453  453  module_stat(uintptr_t addr, const void *data, void *wsp)
 454  454  {
 455  455          fmd_module_t *modp = (fmd_module_t *)data;
 456  456          char name[PATH_MAX];
 457  457          const struct fmd_cmd_data *udp = wsp;
 458  458          fmd_modstat_t *mod_stats;
 459  459  
 460  460          if (mdb_readstr(name, sizeof (name), (uintptr_t)modp->mod_name) <= 0) {
 461  461                  (void) mdb_snprintf(name, sizeof (name), "<%p>",
 462  462                      modp->mod_name);
 463  463          }
 464  464          mdb_printf("%s\n", name);
 465  465          mod_stats = modp->mod_stats;
 466  466          (void) fmd_stat((uintptr_t)&mod_stats->ms_loadtime,
 467  467              DCMD_ADDRSPEC | DCMD_LOOPFIRST, udp->argc, udp->argv);
 468  468          (void) fmd_stat((uintptr_t)&mod_stats->ms_snaptime,
 469  469              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 470  470          (void) fmd_stat((uintptr_t)&mod_stats->ms_accepted,
 471  471              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 472  472          (void) fmd_stat((uintptr_t)&mod_stats->ms_debugdrop,
 473  473              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 474  474          (void) fmd_stat((uintptr_t)&mod_stats->ms_memtotal,
 475  475              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 476  476          (void) fmd_stat((uintptr_t)&mod_stats->ms_memlimit,
 477  477              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 478  478          (void) fmd_stat((uintptr_t)&mod_stats->ms_buftotal,
 479  479              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 480  480          (void) fmd_stat((uintptr_t)&mod_stats->ms_buflimit,
 481  481              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 482  482          (void) fmd_stat((uintptr_t)&mod_stats->ms_thrtotal,
 483  483              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 484  484          (void) fmd_stat((uintptr_t)&mod_stats->ms_thrlimit,
 485  485              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 486  486          (void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrtotal,
 487  487              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 488  488          (void) fmd_stat((uintptr_t)&mod_stats->ms_doorthrlimit,
 489  489              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 490  490          (void) fmd_stat((uintptr_t)&mod_stats->ms_caseopen,
 491  491              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 492  492          (void) fmd_stat((uintptr_t)&mod_stats->ms_casesolved,
 493  493              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 494  494          (void) fmd_stat((uintptr_t)&mod_stats->ms_caseclosed,
 495  495              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 496  496          (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_save,
 497  497              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 498  498          (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_restore,
 499  499              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 500  500          (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_zeroed,
 501  501              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 502  502          (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_cnt,
 503  503              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 504  504          (void) fmd_stat((uintptr_t)&mod_stats->ms_ckpt_time,
 505  505              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 506  506          (void) fmd_stat((uintptr_t)&mod_stats->ms_xprtopen,
 507  507              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 508  508          (void) fmd_stat((uintptr_t)&mod_stats->ms_xprtlimit,
 509  509              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 510  510          (void) fmd_stat((uintptr_t)&mod_stats->ms_xprtqlimit,
 511  511              DCMD_ADDRSPEC | DCMD_LOOP, udp->argc, udp->argv);
 512  512          return (WALK_NEXT);
 513  513  }
 514  514  
 515  515  /*ARGSUSED*/
 516  516  static int
 517  517  fmd_stat(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 518  518  {
 519  519          char buf[512];
 520  520          fmd_stat_t s;
 521  521  
 522  522          if (argc != 0)
 523  523                  return (DCMD_USAGE);
 524  524  
 525  525          if (DCMD_HDRSPEC(flags))
 526  526                  mdb_printf("%<u>%-11s %-4s %-32s %s%</u>\n",
 527  527                      "ADDR", "TYPE", "NAME", "VALUE");
 528  528  
 529  529          if (!(flags & DCMD_ADDRSPEC)) {
 530  530                  struct fmd_cmd_data ud;
 531  531  
 532  532                  ud.argc = argc;
 533  533                  ud.argv = argv;
 534  534  
 535  535                  if (mdb_walk("fmd_module", module_stat, &ud) == -1) {
 536  536                          mdb_warn("failed to walk 'fmd_module'");
 537  537                          return (DCMD_ERR);
 538  538                  }
 539  539                  return (DCMD_OK);
  
    | 
      ↓ open down ↓ | 
    539 lines elided | 
    
      ↑ open up ↑ | 
  
 540  540          }
 541  541  
 542  542          if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) {
 543  543                  mdb_warn("failed to read statistic at %p", addr);
 544  544                  return (DCMD_ERR);
 545  545          }
 546  546  
 547  547          switch (s.fmds_type) {
 548  548          case FMD_TYPE_BOOL:
 549  549                  mdb_printf("%-11p %-4s %-32s %s\n", addr, "bool",
 550      -                    s.fmds_name, s.fmds_value.bool ? "true" : "false");
      550 +                    s.fmds_name, s.fmds_value.b ? "true" : "false");
 551  551                  break;
 552  552          case FMD_TYPE_INT32:
 553  553                  mdb_printf("%-11p %-4s %-32s %d\n", addr, "i32",
 554  554                      s.fmds_name, s.fmds_value.i32);
 555  555                  break;
 556  556          case FMD_TYPE_UINT32:
 557  557                  mdb_printf("%-11p %-4s %-32s %u\n", addr, "ui32",
 558  558                      s.fmds_name, s.fmds_value.i32);
 559  559                  break;
 560  560          case FMD_TYPE_INT64:
 561  561                  mdb_printf("%-11p %-4s %-32s %lld\n", addr, "i64",
 562  562                      s.fmds_name, s.fmds_value.i64);
 563  563                  break;
 564  564          case FMD_TYPE_UINT64:
 565  565                  mdb_printf("%-11p %-4s %-32s %llu\n", addr, "ui64",
 566  566                      s.fmds_name, s.fmds_value.ui64);
 567  567                  break;
 568  568          case FMD_TYPE_STRING:
 569  569                  if (mdb_readstr(buf, sizeof (buf),
 570  570                      (uintptr_t)s.fmds_value.str) < 0) {
 571  571                          (void) mdb_snprintf(buf, sizeof (buf), "<%p>",
 572  572                              s.fmds_value.str);
 573  573                  }
 574  574                  mdb_printf("%-11p %-4s %-32s %s\n", addr, "str",
 575  575                      s.fmds_name, buf);
 576  576                  break;
 577  577          case FMD_TYPE_TIME:
 578  578                  mdb_printf("%-11p %-4s %-32s %llu\n", addr, "time",
 579  579                      s.fmds_name, s.fmds_value.ui64);
 580  580                  break;
 581  581          case FMD_TYPE_SIZE:
 582  582                  mdb_printf("%-11p %-4s %-32s %llu\n", addr, "size",
 583  583                      s.fmds_name, s.fmds_value.ui64);
 584  584                  break;
 585  585          default:
 586  586                  mdb_printf("%-11p %-4u %-32s ???\n", addr,
 587  587                      s.fmds_type, s.fmds_name);
 588  588                  break;
 589  589          }
 590  590  
 591  591          return (DCMD_OK);
 592  592  }
 593  593  
 594  594  /*ARGSUSED*/
 595  595  static int
 596  596  fmd_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 597  597  {
 598  598          char type[16], name[16];
 599  599          fmd_event_impl_t ev;
 600  600  
 601  601          if (argc != 0)
 602  602                  return (DCMD_USAGE);
 603  603  
 604  604          if (mdb_vread(&ev, sizeof (ev), addr) != sizeof (ev)) {
 605  605                  mdb_warn("failed to read fmd_event at %p", addr);
 606  606                  return (DCMD_ERR);
 607  607          }
 608  608  
 609  609          if (DCMD_HDRSPEC(flags)) {
 610  610                  mdb_printf("%<u>%-11s %-4s %-5s %-3s %-?s%</u>\n",
 611  611                      "ADDR", "TYPE", "STATE", "REF", "NVPAIR");
 612  612          }
 613  613  
 614  614          switch (ev.ev_type) {
 615  615          case FMD_EVT_PROTOCOL:
 616  616                  (void) strcpy(type, "PROT");
 617  617                  break;
 618  618          case FMD_EVT_GC:
 619  619                  (void) strcpy(type, "GC");
 620  620                  break;
 621  621          case FMD_EVT_CLOSE:
 622  622                  (void) strcpy(type, "CLSE");
 623  623                  break;
 624  624          case FMD_EVT_TIMEOUT:
 625  625                  (void) strcpy(type, "TIME");
 626  626                  break;
 627  627          case FMD_EVT_STATS:
 628  628                  (void) strcpy(type, "STAT");
 629  629                  break;
 630  630          case FMD_EVT_PUBLISH:
 631  631                  (void) strcpy(type, "PUBL");
 632  632                  break;
 633  633          case FMD_EVT_TOPO:
 634  634                  (void) strcpy(type, "TOPO");
 635  635                  break;
 636  636          default:
 637  637                  (void) mdb_snprintf(type, sizeof (type), "%u", ev.ev_type);
 638  638          }
 639  639  
 640  640          switch (ev.ev_state) {
 641  641          case FMD_EVS_RECEIVED:
 642  642                  (void) strcpy(name, "RECVD");
 643  643                  break;
 644  644          case FMD_EVS_ACCEPTED:
 645  645                  (void) strcpy(name, "ACCPT");
 646  646                  break;
 647  647          case FMD_EVS_DISCARDED:
 648  648                  (void) strcpy(name, "DSCRD");
 649  649                  break;
 650  650          case FMD_EVS_DIAGNOSED:
 651  651                  (void) strcpy(name, "DIAGN");
 652  652                  break;
 653  653          default:
 654  654                  (void) mdb_snprintf(name, sizeof (name), "%u", ev.ev_state);
 655  655          }
 656  656  
 657  657          mdb_printf("%-11p %-4s %-5s %-3u %p\n",
 658  658              addr, type, name, ev.ev_refs, ev.ev_nvl);
 659  659  
 660  660          return (DCMD_OK);
 661  661  }
 662  662  
 663  663  static int
 664  664  thread_walk_init(mdb_walk_state_t *wsp)
 665  665  {
 666  666          fmd_t F;
 667  667  
 668  668          if (mdb_readvar(&F, "fmd") != sizeof (F)) {
 669  669                  mdb_warn("failed to read fmd meta-data");
 670  670                  return (WALK_ERR);
 671  671          }
 672  672  
 673  673          wsp->walk_addr = (uintptr_t)F.d_thr_list.l_next;
 674  674          return (WALK_NEXT);
 675  675  }
 676  676  
 677  677  static int
 678  678  thread_walk_step(mdb_walk_state_t *wsp)
 679  679  {
 680  680          uintptr_t addr = wsp->walk_addr;
 681  681          fmd_thread_t t;
 682  682  
 683  683          if (addr == NULL)
 684  684                  return (WALK_DONE);
 685  685  
 686  686          if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
 687  687                  mdb_warn("failed to read fmd_thread at %p", addr);
 688  688                  return (WALK_ERR);
 689  689          }
 690  690  
 691  691          wsp->walk_addr = (uintptr_t)t.thr_list.l_next;
 692  692          return (wsp->walk_callback(addr, &t, wsp->walk_cbdata));
 693  693  }
 694  694  
 695  695  static int
 696  696  fmd_thread(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 697  697  {
 698  698          fmd_thread_t thr;
 699  699  
 700  700          if (!(flags & DCMD_ADDRSPEC))
 701  701                  return (mdb_walk_dcmd("fmd_thread", "fmd_thread", argc, argv));
 702  702  
 703  703          if (argc != 0)
 704  704                  return (DCMD_USAGE);
 705  705  
 706  706          if (mdb_vread(&thr, sizeof (thr), addr) != sizeof (thr)) {
 707  707                  mdb_warn("failed to read fmd_thread at %p", addr);
 708  708                  return (DCMD_ERR);
 709  709          }
 710  710  
 711  711          if (DCMD_HDRSPEC(flags)) {
 712  712                  mdb_printf("%<u>%-11s %-11s %-8s %-16s%</u>\n",
 713  713                      "ADDR", "MOD", "TID", "FUNC");
 714  714          }
 715  715  
 716  716          mdb_printf("%-11p %-11p %-8u %a\n",
 717  717              addr, thr.thr_mod, thr.thr_tid, thr.thr_func);
 718  718  
 719  719          return (DCMD_OK);
 720  720  }
 721  721  
 722  722  static int
 723  723  mod_walk_init(mdb_walk_state_t *wsp)
 724  724  {
 725  725          fmd_t F;
 726  726  
 727  727          if (mdb_readvar(&F, "fmd") != sizeof (F)) {
 728  728                  mdb_warn("failed to read fmd meta-data");
 729  729                  return (WALK_ERR);
 730  730          }
 731  731  
 732  732          wsp->walk_addr = (uintptr_t)F.d_mod_list.l_next;
 733  733          return (WALK_NEXT);
 734  734  }
 735  735  
 736  736  static int
 737  737  mod_walk_step(mdb_walk_state_t *wsp)
 738  738  {
 739  739          uintptr_t addr = wsp->walk_addr;
 740  740          fmd_module_t m;
 741  741  
 742  742          if (addr == NULL)
 743  743                  return (WALK_DONE);
 744  744  
 745  745          if (mdb_vread(&m, sizeof (m), addr) != sizeof (m)) {
 746  746                  mdb_warn("failed to read fmd_module at %p", addr);
 747  747                  return (WALK_ERR);
 748  748          }
 749  749  
 750  750          wsp->walk_addr = (uintptr_t)m.mod_list.l_next;
 751  751          return (wsp->walk_callback(addr, &m, wsp->walk_cbdata));
 752  752  }
 753  753  
 754  754  static int
 755  755  fmd_module(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 756  756  {
 757  757          fmd_module_t mod;
 758  758          char name[PATH_MAX];
 759  759  
 760  760          if (!(flags & DCMD_ADDRSPEC))
 761  761                  return (mdb_walk_dcmd("fmd_module", "fmd_module", argc, argv));
 762  762  
 763  763          if (argc != 0)
 764  764                  return (DCMD_USAGE);
 765  765  
 766  766          if (mdb_vread(&mod, sizeof (mod), addr) != sizeof (mod)) {
 767  767                  mdb_warn("failed to read fmd_module at %p", addr);
 768  768                  return (DCMD_ERR);
 769  769          }
 770  770  
 771  771          if (DCMD_HDRSPEC(flags)) {
 772  772                  mdb_printf("%<u>%-11s %-16s %-11s %-4s %-?s %-16s%</u>\n",
 773  773                      "ADDR", "OPS", "DATA", "FLAG", "USTAT", "NAME");
 774  774          }
 775  775  
 776  776          if (mdb_readstr(name, sizeof (name), (uintptr_t)mod.mod_name) <= 0)
 777  777                  (void) mdb_snprintf(name, sizeof (name), "<%p>", mod.mod_name);
 778  778  
 779  779          mdb_printf("%-11p %-16a %-11p 0x%02x %-?p %s\n", addr,
 780  780              mod.mod_ops, mod.mod_data, mod.mod_flags, mod.mod_ustat, name);
 781  781  
 782  782          return (DCMD_OK);
 783  783  }
 784  784  
 785  785  static int
 786  786  case_walk_init(mdb_walk_state_t *wsp)
 787  787  {
 788  788          fmd_module_t mod;
 789  789          fmd_case_hash_t ch;
 790  790          fmd_t F;
 791  791  
 792  792          if (wsp->walk_addr != NULL) {
 793  793                  if (mdb_vread(&mod, sizeof (mod), wsp->walk_addr) == -1) {
 794  794                          mdb_warn("failed to read module at %p", wsp->walk_addr);
 795  795                          return (WALK_ERR);
 796  796                  }
 797  797  
 798  798                  wsp->walk_addr = (uintptr_t)mod.mod_cases.l_next;
 799  799                  return (WALK_NEXT);
 800  800          }
 801  801  
 802  802          if (mdb_readvar(&F, "fmd") != sizeof (F) ||
 803  803              mdb_vread(&ch, sizeof (ch), (uintptr_t)F.d_cases) != sizeof (ch)) {
 804  804                  mdb_warn("failed to read fmd meta-data");
 805  805                  return (WALK_ERR);
 806  806          }
 807  807  
 808  808          return (hash_walk_init(wsp, (uintptr_t)ch.ch_hash, ch.ch_hashlen,
 809  809              "fmd_case", sizeof (fmd_case_impl_t),
 810  810              OFFSETOF(fmd_case_impl_t, ci_next)));
 811  811  }
 812  812  
 813  813  static int
 814  814  case_walk_step(mdb_walk_state_t *wsp)
 815  815  {
 816  816          uintptr_t addr = wsp->walk_addr;
 817  817          fmd_case_impl_t ci;
 818  818  
 819  819          if (wsp->walk_data != NULL)
 820  820                  return (hash_walk_step(wsp));
 821  821  
 822  822          if (addr == NULL)
 823  823                  return (WALK_DONE);
 824  824  
 825  825          if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
 826  826                  mdb_warn("failed to read fmd_case at %p", addr);
 827  827                  return (WALK_ERR);
 828  828          }
 829  829  
 830  830          wsp->walk_addr = (uintptr_t)ci.ci_list.l_next;
 831  831          return (wsp->walk_callback(addr, &ci, wsp->walk_cbdata));
 832  832  }
 833  833  
 834  834  static void
 835  835  case_walk_fini(mdb_walk_state_t *wsp)
 836  836  {
 837  837          if (wsp->walk_data != NULL)
 838  838                  hash_walk_fini(wsp);
 839  839  }
 840  840  
 841  841  static int
 842  842  fmd_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 843  843  {
 844  844          char uuid[48], name[16];
 845  845          fmd_case_impl_t ci;
 846  846  
 847  847          if (!(flags & DCMD_ADDRSPEC)) {
 848  848                  if (mdb_walk_dcmd("fmd_case", "fmd_case", argc, argv) != 0) {
 849  849                          mdb_warn("failed to walk fmd_case hash");
 850  850                          return (DCMD_ERR);
 851  851                  }
 852  852                  return (DCMD_OK);
 853  853          }
 854  854  
 855  855          if (mdb_vread(&ci, sizeof (ci), addr) != sizeof (ci)) {
 856  856                  mdb_warn("failed to read fmd_case at %p", addr);
 857  857                  return (DCMD_ERR);
 858  858          }
 859  859  
 860  860          if (DCMD_HDRSPEC(flags)) {
 861  861                  mdb_printf("%<u>%-11s %-5s %-3s %-?s %-36s%</u>\n",
 862  862                      "ADDR", "STATE", "REF", "DATA", "UUID");
 863  863          }
 864  864  
 865  865          if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)ci.ci_uuid) <= 0)
 866  866                  (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", ci.ci_uuid);
 867  867  
 868  868          switch (ci.ci_state) {
 869  869          case FMD_CASE_UNSOLVED:
 870  870                  (void) strcpy(name, "UNSLV");
 871  871                  break;
 872  872          case FMD_CASE_SOLVED:
 873  873                  (void) strcpy(name, "SOLVE");
 874  874                  break;
 875  875          case FMD_CASE_CLOSE_WAIT:
 876  876                  (void) strcpy(name, "CWAIT");
 877  877                  break;
 878  878          case FMD_CASE_CLOSED:
 879  879                  (void) strcpy(name, "CLOSE");
 880  880                  break;
 881  881          case FMD_CASE_REPAIRED:
 882  882                  (void) strcpy(name, "RPAIR");
 883  883                  break;
 884  884          case FMD_CASE_RESOLVED:
 885  885                  (void) strcpy(name, "RSLVD");
 886  886                  break;
 887  887          default:
 888  888                  (void) mdb_snprintf(name, sizeof (name), "%u", ci.ci_state);
 889  889          }
 890  890  
 891  891          mdb_printf("%-11p %-5s %-3u %-?p %s\n",
 892  892              addr, name, ci.ci_refs, ci.ci_data, uuid);
 893  893  
 894  894          return (DCMD_OK);
 895  895  }
 896  896  
 897  897  static int
 898  898  buf_walk_init(mdb_walk_state_t *wsp)
 899  899  {
 900  900          fmd_buf_hash_t bh;
 901  901  
 902  902          if (mdb_vread(&bh, sizeof (bh), wsp->walk_addr) != sizeof (bh)) {
 903  903                  mdb_warn("failed to read fmd_buf_hash_t at %p", wsp->walk_addr);
 904  904                  return (WALK_ERR);
 905  905          }
 906  906  
 907  907          return (hash_walk_init(wsp, (uintptr_t)bh.bh_hash, bh.bh_hashlen,
 908  908              "fmd_buf", sizeof (fmd_buf_t), OFFSETOF(fmd_buf_t, buf_next)));
 909  909  }
 910  910  
 911  911  /*ARGSUSED*/
 912  912  static int
 913  913  fmd_buf(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 914  914  {
 915  915          char name[PATH_MAX];
 916  916          fmd_buf_t b;
 917  917  
 918  918          if (argc != 0 || !(flags & DCMD_ADDRSPEC))
 919  919                  return (DCMD_USAGE);
 920  920  
 921  921          if (mdb_vread(&b, sizeof (b), addr) != sizeof (b)) {
 922  922                  mdb_warn("failed to read fmd_buf at %p", addr);
 923  923                  return (DCMD_ERR);
 924  924          }
 925  925  
 926  926          if (DCMD_HDRSPEC(flags)) {
 927  927                  mdb_printf("%<u>%-11s %-32s %-5s %-?s %s%</u>\n",
 928  928                      "ADDR", "NAME", "FLAGS", "DATA", "SIZE");
 929  929          }
 930  930  
 931  931          if (mdb_readstr(name, sizeof (name), (uintptr_t)b.buf_name) <= 0)
 932  932                  (void) mdb_snprintf(name, sizeof (name), "<%p>", b.buf_name);
 933  933  
 934  934          mdb_printf("%-11p %-32s %-#5x %-?p %lu\n",
 935  935              addr, name, b.buf_flags, b.buf_data, b.buf_size);
 936  936  
 937  937          return (DCMD_OK);
 938  938  }
 939  939  
 940  940  static int
 941  941  serd_walk_init(mdb_walk_state_t *wsp)
 942  942  {
 943  943          fmd_serd_hash_t sh;
 944  944  
 945  945          if (mdb_vread(&sh, sizeof (sh), wsp->walk_addr) != sizeof (sh)) {
 946  946                  mdb_warn("failed to read fmd_serd_hash at %p", wsp->walk_addr);
 947  947                  return (WALK_ERR);
 948  948          }
 949  949  
 950  950          return (hash_walk_init(wsp, (uintptr_t)sh.sh_hash, sh.sh_hashlen,
 951  951              "fmd_serd_eng", sizeof (fmd_serd_eng_t),
 952  952              OFFSETOF(fmd_serd_eng_t, sg_next)));
 953  953  }
 954  954  
 955  955  /* ARGSUSED */
 956  956  static int
 957  957  module_serd(uintptr_t addr, const void *data, void *wsp)
 958  958  {
 959  959          fmd_module_t *modp = (fmd_module_t *)data;
 960  960  
 961  961          if (modp->mod_serds.sh_count != 0) {
 962  962                  modp = (fmd_module_t *)addr;
 963  963                  (void) mdb_pwalk_dcmd("fmd_serd", "fmd_serd", 0, 0,
 964  964                      (uintptr_t)&modp->mod_serds);
 965  965          }
 966  966          return (WALK_NEXT);
 967  967  }
 968  968  
 969  969  /*ARGSUSED*/
 970  970  static int
 971  971  fmd_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 972  972  {
 973  973          char name[PATH_MAX];
 974  974          fmd_serd_eng_t sg;
 975  975  
 976  976          if (argc != 0)
 977  977                  return (DCMD_USAGE);
 978  978          if (!(flags & DCMD_ADDRSPEC)) {
 979  979                  if (mdb_walk("fmd_module", module_serd, 0) == -1) {
 980  980                          mdb_warn("failed to walk 'fmd_module'");
 981  981                          return (DCMD_ERR);
 982  982                  }
 983  983                  return (DCMD_OK);
 984  984          }
 985  985  
 986  986          if (mdb_vread(&sg, sizeof (sg), addr) != sizeof (sg)) {
 987  987                  mdb_warn("failed to read fmd_serd_eng at %p", addr);
 988  988                  return (DCMD_ERR);
 989  989          }
 990  990  
 991  991          if (DCMD_HDRSPEC(flags)) {
 992  992                  mdb_printf("%<u>%-11s %-32s %-3s F >%-2s %-16s%</u>\n",
 993  993                      "ADDR", "NAME", "CNT", "N", "T");
 994  994          }
 995  995  
 996  996          if (mdb_readstr(name, sizeof (name), (uintptr_t)sg.sg_name) <= 0)
 997  997                  (void) mdb_snprintf(name, sizeof (name), "<%p>", sg.sg_name);
 998  998  
 999  999          mdb_printf("%-11p %-32s %-3u %c >%-2u %lluns\n",
1000 1000              addr, name, sg.sg_count, (sg.sg_flags & FMD_SERD_FIRED) ? 'F' : ' ',
1001 1001              sg.sg_n, (u_longlong_t)sg.sg_t);
1002 1002  
1003 1003          return (DCMD_OK);
1004 1004  }
1005 1005  
1006 1006  static int
1007 1007  asru_walk_init(mdb_walk_state_t *wsp)
1008 1008  {
1009 1009          fmd_asru_hash_t ah;
1010 1010          fmd_t F;
1011 1011  
1012 1012          if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) {
1013 1013                  mdb_warn("failed to read fmd meta-data");
1014 1014                  return (WALK_ERR);
1015 1015          }
1016 1016  
1017 1017          if (wsp->walk_addr == NULL)
1018 1018                  wsp->walk_addr = (uintptr_t)F.d_asrus;
1019 1019  
1020 1020          if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) {
1021 1021                  mdb_warn("failed to read asru_hash at %p", wsp->walk_addr);
1022 1022                  return (WALK_ERR);
1023 1023          }
1024 1024  
1025 1025          return (hash_walk_init(wsp, (uintptr_t)ah.ah_hash, ah.ah_hashlen,
1026 1026              "fmd_asru", sizeof (fmd_asru_t), OFFSETOF(fmd_asru_t, asru_next)));
1027 1027  }
1028 1028  
1029 1029  static int
1030 1030  fmd_asru(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1031 1031  {
1032 1032          char uuid[48], name[PATH_MAX];
1033 1033          fmd_asru_t a;
1034 1034  
1035 1035          if (!(flags & DCMD_ADDRSPEC)) {
1036 1036                  if (mdb_walk_dcmd("fmd_asru", "fmd_asru", argc, argv) != 0) {
1037 1037                          mdb_warn("failed to walk fmd_asru hash");
1038 1038                          return (DCMD_ERR);
1039 1039                  }
1040 1040                  return (DCMD_OK);
1041 1041          }
1042 1042  
1043 1043          if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
1044 1044                  mdb_warn("failed to read fmd_asru at %p", addr);
1045 1045                  return (DCMD_ERR);
1046 1046          }
1047 1047  
1048 1048          if (DCMD_HDRSPEC(flags))
1049 1049                  mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
1050 1050  
1051 1051          if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.asru_uuid) <= 0)
1052 1052                  (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.asru_uuid);
1053 1053          if (mdb_readstr(name, sizeof (name), (uintptr_t)a.asru_name) <= 0)
1054 1054                  (void) mdb_snprintf(name, sizeof (name), "<%p>", a.asru_name);
1055 1055  
1056 1056          mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
1057 1057          return (DCMD_OK);
1058 1058  }
1059 1059  
1060 1060  static int
1061 1061  al_walk_init(mdb_walk_state_t *wsp)
1062 1062  {
1063 1063          fmd_asru_hash_t ah;
1064 1064          fmd_t F;
1065 1065  
1066 1066          if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) {
1067 1067                  mdb_warn("failed to read fmd meta-data");
1068 1068                  return (WALK_ERR);
1069 1069          }
1070 1070  
1071 1071          if (wsp->walk_addr == NULL)
1072 1072                  wsp->walk_addr = (uintptr_t)F.d_asrus;
1073 1073  
1074 1074          if (mdb_vread(&ah, sizeof (ah), wsp->walk_addr) != sizeof (ah)) {
1075 1075                  mdb_warn("failed to read asru_hash at %p", wsp->walk_addr);
1076 1076                  return (WALK_ERR);
1077 1077          }
1078 1078  
1079 1079          return (hash_walk_init(wsp, (uintptr_t)ah.ah_rsrc_hash, ah.ah_hashlen,
1080 1080              "fmd_asru_link", sizeof (fmd_asru_link_t), OFFSETOF(fmd_asru_link_t,
1081 1081              al_rsrc_next)));
1082 1082  }
1083 1083  
1084 1084  static int
1085 1085  fmd_asru_link(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1086 1086  {
1087 1087          char uuid[48], name[PATH_MAX];
1088 1088          fmd_asru_link_t a;
1089 1089  
1090 1090          if (!(flags & DCMD_ADDRSPEC)) {
1091 1091                  if (mdb_walk_dcmd("fmd_asru_link", "fmd_asru_link", argc,
1092 1092                      argv) != 0) {
1093 1093                          mdb_warn("failed to walk fmd_asru_link hash");
1094 1094                          return (DCMD_ERR);
1095 1095                  }
1096 1096                  return (DCMD_OK);
1097 1097          }
1098 1098  
1099 1099          if (mdb_vread(&a, sizeof (a), addr) != sizeof (a)) {
1100 1100                  mdb_warn("failed to read fmd_asru_link at %p", addr);
1101 1101                  return (DCMD_ERR);
1102 1102          }
1103 1103  
1104 1104          if (DCMD_HDRSPEC(flags))
1105 1105                  mdb_printf("%<u>%-8s %-36s %s%</u>\n", "ADDR", "UUID", "NAME");
1106 1106  
1107 1107          if (mdb_readstr(uuid, sizeof (uuid), (uintptr_t)a.al_uuid) <= 0)
1108 1108                  (void) mdb_snprintf(uuid, sizeof (uuid), "<%p>", a.al_uuid);
1109 1109          if (mdb_readstr(name, sizeof (name), (uintptr_t)a.al_rsrc_name) <= 0)
1110 1110                  (void) mdb_snprintf(name, sizeof (name), "<%p>",
1111 1111                      a.al_rsrc_name);
1112 1112  
1113 1113          mdb_printf("%-8p %-36s %s\n", addr, uuid, name);
1114 1114          return (DCMD_OK);
1115 1115  }
1116 1116  
1117 1117  /*ARGSUSED*/
1118 1118  static int
1119 1119  fcf_hdr(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1120 1120  {
1121 1121          fcf_hdr_t h;
1122 1122  
1123 1123          if (argc != 0)
1124 1124                  return (DCMD_USAGE);
1125 1125  
1126 1126          if (!(flags & DCMD_ADDRSPEC))
1127 1127                  addr = 0; /* assume base of file in file target */
1128 1128  
1129 1129          if (mdb_vread(&h, sizeof (h), addr) != sizeof (h)) {
1130 1130                  mdb_warn("failed to read header at %p", addr);
1131 1131                  return (DCMD_ERR);
1132 1132          }
1133 1133  
1134 1134          mdb_printf("fcfh_ident.id_magic = 0x%x, %c, %c, %c\n",
1135 1135              h.fcfh_ident[FCF_ID_MAG0], h.fcfh_ident[FCF_ID_MAG1],
1136 1136              h.fcfh_ident[FCF_ID_MAG2], h.fcfh_ident[FCF_ID_MAG3]);
1137 1137  
1138 1138          switch (h.fcfh_ident[FCF_ID_MODEL]) {
1139 1139          case FCF_MODEL_ILP32:
1140 1140                  mdb_printf("fcfh_ident.id_model = ILP32\n");
1141 1141                  break;
1142 1142          case FCF_MODEL_LP64:
1143 1143                  mdb_printf("fcfh_ident.id_model = LP64\n");
1144 1144                  break;
1145 1145          default:
1146 1146                  mdb_printf("fcfh_ident.id_model = 0x%x\n",
1147 1147                      h.fcfh_ident[FCF_ID_MODEL]);
1148 1148          }
1149 1149  
1150 1150          switch (h.fcfh_ident[FCF_ID_ENCODING]) {
1151 1151          case FCF_ENCODE_LSB:
1152 1152                  mdb_printf("fcfh_ident.id_encoding = LSB\n");
1153 1153                  break;
1154 1154          case FCF_ENCODE_MSB:
1155 1155                  mdb_printf("fcfh_ident.id_encoding = MSB\n");
1156 1156                  break;
1157 1157          default:
1158 1158                  mdb_printf("fcfh_ident.id_encoding = 0x%x\n",
1159 1159                      h.fcfh_ident[FCF_ID_ENCODING]);
1160 1160          }
1161 1161  
1162 1162          mdb_printf("fcfh_ident.id_version = %u\n",
1163 1163              h.fcfh_ident[FCF_ID_VERSION]);
1164 1164  
1165 1165          mdb_printf("fcfh_flags = 0x%x\n", h.fcfh_flags);
1166 1166          mdb_printf("fcfh_hdrsize = %u\n", h.fcfh_hdrsize);
1167 1167          mdb_printf("fcfh_secsize = %u\n", h.fcfh_secsize);
1168 1168          mdb_printf("fcfh_secnum = %u\n", h.fcfh_secnum);
1169 1169          mdb_printf("fcfh_secoff = %llu\n", h.fcfh_secoff);
1170 1170          mdb_printf("fcfh_filesz = %llu\n", h.fcfh_filesz);
1171 1171          mdb_printf("fcfh_cgen = %llu\n", h.fcfh_cgen);
1172 1172  
1173 1173          return (DCMD_OK);
1174 1174  }
1175 1175  
1176 1176  static int fcf_sec(uintptr_t, uint_t, int, const mdb_arg_t *);
1177 1177  /*ARGSUSED*/
1178 1178  static int
1179 1179  fcf_sec_one(uintptr_t addr, void *ignored, uint_t *secp)
1180 1180  {
1181 1181  
1182 1182          mdb_printf("%3d ", (*secp)++);
1183 1183          (void) fcf_sec(addr, DCMD_ADDRSPEC | DCMD_LOOP, 0, NULL);
1184 1184          return (WALK_NEXT);
1185 1185  }
1186 1186  
1187 1187  /*ARGSUSED*/
1188 1188  static int
1189 1189  fcf_sec(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1190 1190  {
1191 1191          static const char *const types[] = {
1192 1192                  "none",         /* FCF_SECT_NONE */
1193 1193                  "strtab",       /* FCF_SECT_STRTAB */
1194 1194                  "module",       /* FCF_SECT_MODULE */
1195 1195                  "case",         /* FCF_SECT_CASE */
1196 1196                  "bufs",         /* FCF_SECT_BUFS */
1197 1197                  "buffer",       /* FCF_SECT_BUFFER */
1198 1198                  "serd",         /* FCF_SECT_SERD */
1199 1199                  "events",       /* FCF_SECT_EVENTS */
1200 1200                  "nvlists",      /* FCF_SECT_NVLISTS */
1201 1201          };
1202 1202  
1203 1203          uint_t sec = 0;
1204 1204          fcf_sec_t s;
1205 1205  
1206 1206          if (!(flags & DCMD_ADDRSPEC))
1207 1207                  mdb_printf("%<u>%-3s ", "NDX");
1208 1208  
1209 1209          if (!(flags & DCMD_ADDRSPEC) || DCMD_HDRSPEC(flags)) {
1210 1210                  mdb_printf("%<u>%?s %-10s %-5s %-5s %-5s %-6s %-5s%</u>\n",
1211 1211                      "ADDR", "TYPE", "ALIGN", "FLAGS", "ENTSZ", "OFF", "SIZE");
1212 1212          }
1213 1213  
1214 1214          if (!(flags & DCMD_ADDRSPEC)) {
1215 1215                  if (mdb_walk("fcf_sec", (mdb_walk_cb_t)fcf_sec_one, &sec) < 0) {
1216 1216                          mdb_warn("failed to walk fcf_sec");
1217 1217                          return (DCMD_ERR);
1218 1218                  }
1219 1219                  return (DCMD_OK);
1220 1220          }
1221 1221  
1222 1222          if (argc != 0)
1223 1223                  return (DCMD_USAGE);
1224 1224  
1225 1225          if (mdb_vread(&s, sizeof (s), addr) != sizeof (s)) {
1226 1226                  mdb_warn("failed to read section header at %p", addr);
1227 1227                  return (DCMD_ERR);
1228 1228          }
1229 1229  
1230 1230          mdb_printf("%?p ", addr);
1231 1231  
1232 1232          if (s.fcfs_type < sizeof (types) / sizeof (types[0]))
1233 1233                  mdb_printf("%-10s ", types[s.fcfs_type]);
1234 1234          else
1235 1235                  mdb_printf("%-10u ", s.fcfs_type);
1236 1236  
1237 1237          mdb_printf("%-5u %-#5x %-#5x %-6llx %-#5llx\n", s.fcfs_align,
1238 1238              s.fcfs_flags, s.fcfs_entsize, s.fcfs_offset, s.fcfs_size);
1239 1239  
1240 1240          return (DCMD_OK);
1241 1241  }
1242 1242  
1243 1243  static int
1244 1244  fcf_sec_walk_init(mdb_walk_state_t *wsp)
1245 1245  {
1246 1246          fcf_hdr_t h, *hp;
1247 1247          size_t size;
1248 1248  
1249 1249          if (mdb_vread(&h, sizeof (h), wsp->walk_addr) != sizeof (h)) {
1250 1250                  mdb_warn("failed to read FCF header at %p", wsp->walk_addr);
1251 1251                  return (WALK_ERR);
1252 1252          }
1253 1253  
1254 1254          size = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * h.fcfh_secnum;
1255 1255          hp = mdb_alloc(size, UM_SLEEP);
1256 1256  
1257 1257          if (mdb_vread(hp, size, wsp->walk_addr) != size) {
1258 1258                  mdb_warn("failed to read FCF sections at %p", wsp->walk_addr);
1259 1259                  mdb_free(hp, size);
1260 1260                  return (WALK_ERR);
1261 1261          }
1262 1262  
1263 1263          wsp->walk_data = hp;
1264 1264          wsp->walk_arg = 0;
1265 1265  
1266 1266          return (WALK_NEXT);
1267 1267  }
1268 1268  
1269 1269  static int
1270 1270  fcf_sec_walk_step(mdb_walk_state_t *wsp)
1271 1271  {
1272 1272          uint_t i = (uint_t)wsp->walk_arg;
1273 1273          size_t off = sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * i;
1274 1274          fcf_hdr_t *hp = wsp->walk_data;
1275 1275          fcf_sec_t *sp = (fcf_sec_t *)((uintptr_t)hp + off);
1276 1276  
1277 1277          if (i >= hp->fcfh_secnum)
1278 1278                  return (WALK_DONE);
1279 1279  
1280 1280          wsp->walk_arg = (void *)(i + 1);
1281 1281          return (wsp->walk_callback(wsp->walk_addr + off, sp, wsp->walk_cbdata));
1282 1282  }
1283 1283  
1284 1284  static void
1285 1285  fcf_sec_walk_fini(mdb_walk_state_t *wsp)
1286 1286  {
1287 1287          fcf_hdr_t *hp = wsp->walk_data;
1288 1288          mdb_free(hp, sizeof (fcf_hdr_t) + sizeof (fcf_sec_t) * hp->fcfh_secnum);
1289 1289  }
1290 1290  
1291 1291  /*ARGSUSED*/
1292 1292  static int
1293 1293  fcf_case(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1294 1294  {
1295 1295          fcf_case_t fcfc;
1296 1296  
1297 1297          if (argc != 0)
1298 1298                  return (DCMD_USAGE);
1299 1299  
1300 1300          if (mdb_vread(&fcfc, sizeof (fcfc), addr) != sizeof (fcfc)) {
1301 1301                  mdb_warn("failed to read case at %p", addr);
1302 1302                  return (DCMD_ERR);
1303 1303          }
1304 1304  
1305 1305          mdb_printf("fcfc_uuid = 0x%x\n", fcfc.fcfc_uuid);
1306 1306          mdb_printf("fcfc_state = %u\n", fcfc.fcfc_state);
1307 1307          mdb_printf("fcfc_bufs = %u\n", fcfc.fcfc_bufs);
1308 1308          mdb_printf("fcfc_events = %u\n", fcfc.fcfc_events);
1309 1309          mdb_printf("fcfc_suspects = %u\n", fcfc.fcfc_suspects);
1310 1310  
1311 1311          return (DCMD_OK);
1312 1312  }
1313 1313  
1314 1314  /*ARGSUSED*/
1315 1315  static int
1316 1316  fcf_event(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1317 1317  {
1318 1318          fcf_event_t fcfe;
1319 1319  
1320 1320          if (argc != 0)
1321 1321                  return (DCMD_USAGE);
1322 1322  
1323 1323          if (mdb_vread(&fcfe, sizeof (fcfe), addr) != sizeof (fcfe)) {
1324 1324                  mdb_warn("failed to read event at %p", addr);
1325 1325                  return (DCMD_ERR);
1326 1326          }
1327 1327  
1328 1328          mdb_printf("fcfe_todsec = %llu (%Y)\n",
1329 1329              fcfe.fcfe_todsec, (time_t)fcfe.fcfe_todsec);
1330 1330          mdb_printf("fcfe_todnsec = %llu\n", fcfe.fcfe_todnsec);
1331 1331          mdb_printf("fcfe_major = %u\n", fcfe.fcfe_major);
1332 1332          mdb_printf("fcfe_minor = %u\n", fcfe.fcfe_minor);
1333 1333          mdb_printf("fcfe_inode = %llu\n", fcfe.fcfe_inode);
1334 1334          mdb_printf("fcfe_offset = %llu\n", fcfe.fcfe_offset);
1335 1335  
1336 1336          return (DCMD_OK);
1337 1337  }
1338 1338  
1339 1339  /*ARGSUSED*/
1340 1340  static int
1341 1341  fcf_serd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1342 1342  {
1343 1343          fcf_serd_t fcfd;
1344 1344  
1345 1345          if (argc != 0)
1346 1346                  return (DCMD_USAGE);
1347 1347  
1348 1348          if (mdb_vread(&fcfd, sizeof (fcfd), addr) != sizeof (fcfd)) {
1349 1349                  mdb_warn("failed to read serd at %p", addr);
1350 1350                  return (DCMD_ERR);
1351 1351          }
1352 1352  
1353 1353          mdb_printf("fcfd_name = 0x%x\n", fcfd.fcfd_name);
1354 1354          mdb_printf("fcfd_events = %u\n", fcfd.fcfd_events);
1355 1355          mdb_printf("fcfd_n = >%u\n", fcfd.fcfd_n);
1356 1356          mdb_printf("fcfd_t = %lluns\n", fcfd.fcfd_t);
1357 1357  
1358 1358          return (DCMD_OK);
1359 1359  }
1360 1360  
1361 1361  static int
1362 1362  tmq_walk_init(mdb_walk_state_t *wsp)
1363 1363  {
1364 1364          fmd_timerq_t tmq;
1365 1365          fmd_t F;
1366 1366  
1367 1367          if (wsp->walk_addr == NULL && mdb_readvar(&F, "fmd") != sizeof (F)) {
1368 1368                  mdb_warn("failed to read fmd meta-data");
1369 1369                  return (WALK_ERR);
1370 1370          }
1371 1371  
1372 1372          if (wsp->walk_addr == NULL)
1373 1373                  wsp->walk_addr = (uintptr_t)F.d_timers;
1374 1374  
1375 1375          if (mdb_vread(&tmq, sizeof (tmq), wsp->walk_addr) != sizeof (tmq)) {
1376 1376                  mdb_warn("failed to read timerq at %p", wsp->walk_addr);
1377 1377                  return (WALK_ERR);
1378 1378          }
1379 1379  
1380 1380          wsp->walk_addr = (uintptr_t)tmq.tmq_list.l_next;
1381 1381          return (WALK_NEXT);
1382 1382  }
1383 1383  
1384 1384  static int
1385 1385  tmq_walk_step(mdb_walk_state_t *wsp)
1386 1386  {
1387 1387          uintptr_t addr = wsp->walk_addr;
1388 1388          fmd_timer_t tmr;
1389 1389  
1390 1390          if (addr == NULL)
1391 1391                  return (WALK_DONE);
1392 1392  
1393 1393          if (mdb_vread(&tmr, sizeof (tmr), addr) != sizeof (tmr)) {
1394 1394                  mdb_warn("failed to read fmd_timer at %p", addr);
1395 1395                  return (WALK_ERR);
1396 1396          }
1397 1397  
1398 1398          wsp->walk_addr = (uintptr_t)tmr.tmr_list.l_next;
1399 1399          return (wsp->walk_callback(addr, &tmr, wsp->walk_cbdata));
1400 1400  }
1401 1401  
1402 1402  static int
1403 1403  fmd_timer(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1404 1404  {
1405 1405          char name[32], func[MDB_SYM_NAMLEN];
1406 1406          fmd_timer_t t;
1407 1407  
1408 1408          if (!(flags & DCMD_ADDRSPEC)) {
1409 1409                  if (mdb_walk_dcmd("fmd_timerq", "fmd_timer", argc, argv) != 0) {
1410 1410                          mdb_warn("failed to walk fmd_timerq");
1411 1411                          return (DCMD_ERR);
1412 1412                  }
1413 1413                  return (DCMD_OK);
1414 1414          }
1415 1415  
1416 1416          if (mdb_vread(&t, sizeof (t), addr) != sizeof (t)) {
1417 1417                  mdb_warn("failed to read fmd_timer at %p", addr);
1418 1418                  return (DCMD_ERR);
1419 1419          }
1420 1420  
1421 1421          if (DCMD_HDRSPEC(flags)) {
1422 1422                  mdb_printf("%<u>%-8s %-20s %-4s %-18s %-8s %s%</u>\n",
1423 1423                      "ADDR", "MODULE", "ID", "HRTIME", "ARG", "FUNC");
1424 1424          }
1425 1425  
1426 1426          if (mdb_readstr(name, sizeof (name), (uintptr_t)
1427 1427              t.tmr_ids + OFFSETOF(fmd_idspace_t, ids_name)) <= 0)
1428 1428                  (void) mdb_snprintf(name, sizeof (name), "<%p>", t.tmr_ids);
1429 1429  
1430 1430          if (mdb_lookup_by_addr((uintptr_t)t.tmr_func, MDB_SYM_FUZZY,
1431 1431              func, sizeof (func), NULL) != 0)
1432 1432                  (void) mdb_snprintf(func, sizeof (func), "<%p>", t.tmr_func);
1433 1433  
1434 1434          mdb_printf("%-8p %-20s %4d 0x%-16llx %-8p %s\n",
1435 1435              addr, name, t.tmr_id, t.tmr_hrt, t.tmr_arg, func);
1436 1436          return (DCMD_OK);
1437 1437  }
1438 1438  
1439 1439  static int
1440 1440  xprt_walk_init(mdb_walk_state_t *wsp)
1441 1441  {
1442 1442          fmd_module_t m;
1443 1443  
1444 1444          if (wsp->walk_addr == NULL) {
1445 1445                  mdb_warn("transport walker requires fmd_module_t address\n");
1446 1446                  return (WALK_ERR);
1447 1447          }
1448 1448  
1449 1449          if (mdb_vread(&m, sizeof (m), wsp->walk_addr) != sizeof (m)) {
1450 1450                  mdb_warn("failed to read module at %p", wsp->walk_addr);
1451 1451                  return (WALK_ERR);
1452 1452          }
1453 1453  
1454 1454          wsp->walk_addr = (uintptr_t)m.mod_transports.l_next;
1455 1455          return (WALK_NEXT);
1456 1456  }
1457 1457  
1458 1458  static int
1459 1459  xprt_walk_step(mdb_walk_state_t *wsp)
1460 1460  {
1461 1461          uintptr_t addr = wsp->walk_addr;
1462 1462          fmd_xprt_impl_t xi;
1463 1463  
1464 1464          if (addr == NULL)
1465 1465                  return (WALK_DONE);
1466 1466  
1467 1467          if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) {
1468 1468                  mdb_warn("failed to read fmd_xprt at %p", addr);
1469 1469                  return (WALK_ERR);
1470 1470          }
1471 1471  
1472 1472          wsp->walk_addr = (uintptr_t)xi.xi_list.l_next;
1473 1473          return (wsp->walk_callback(addr, &xi, wsp->walk_cbdata));
1474 1474  }
1475 1475  
1476 1476  static int
1477 1477  xpc_walk_init(mdb_walk_state_t *wsp)
1478 1478  {
1479 1479          fmd_xprt_class_hash_t xch;
1480 1480  
1481 1481          if (mdb_vread(&xch, sizeof (xch), wsp->walk_addr) != sizeof (xch)) {
1482 1482                  mdb_warn("failed to read fmd_xprt_class_hash at %p",
1483 1483                      wsp->walk_addr);
1484 1484                  return (WALK_ERR);
1485 1485          }
1486 1486  
1487 1487          return (hash_walk_init(wsp, (uintptr_t)xch.xch_hash, xch.xch_hashlen,
1488 1488              "fmd_xprt_class", sizeof (fmd_xprt_class_t),
1489 1489              OFFSETOF(fmd_xprt_class_t, xc_next)));
1490 1490  }
1491 1491  
1492 1492  /*ARGSUSED*/
1493 1493  static int
1494 1494  fmd_xprt_class(uintptr_t addr, const void *data, void *arg)
1495 1495  {
1496 1496          const fmd_xprt_class_t *xcp = data;
1497 1497          char name[1024];
1498 1498  
1499 1499          if (mdb_readstr(name, sizeof (name), (uintptr_t)xcp->xc_class) <= 0)
1500 1500                  (void) mdb_snprintf(name, sizeof (name), "<%p>", xcp->xc_class);
1501 1501  
1502 1502          mdb_printf("%-8p %-4u %s\n", addr, xcp->xc_refs, name);
1503 1503          return (WALK_NEXT);
1504 1504  }
1505 1505  
1506 1506  static int
1507 1507  fmd_xprt(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1508 1508  {
1509 1509          uint_t opt_s = FALSE, opt_l = FALSE, opt_r = FALSE, opt_u = FALSE;
1510 1510          fmd_xprt_impl_t xi;
1511 1511  
1512 1512          if (mdb_getopts(argc, argv,
1513 1513              'l', MDB_OPT_SETBITS, TRUE, &opt_l,
1514 1514              'r', MDB_OPT_SETBITS, TRUE, &opt_r,
1515 1515              's', MDB_OPT_SETBITS, TRUE, &opt_s,
1516 1516              'u', MDB_OPT_SETBITS, TRUE, &opt_u, NULL) != argc)
1517 1517                  return (DCMD_USAGE);
1518 1518  
1519 1519          if (!(flags & DCMD_ADDRSPEC)) {
1520 1520                  if (mdb_walk_dcmd("fmd_xprt", "fmd_xprt", argc, argv) != 0) {
1521 1521                          mdb_warn("failed to walk fmd_xprt");
1522 1522                          return (DCMD_ERR);
1523 1523                  }
1524 1524                  return (DCMD_OK);
1525 1525          }
1526 1526  
1527 1527          if (mdb_vread(&xi, sizeof (xi), addr) != sizeof (xi)) {
1528 1528                  mdb_warn("failed to read fmd_xprt at %p", addr);
1529 1529                  return (DCMD_ERR);
1530 1530          }
1531 1531  
1532 1532          if (DCMD_HDRSPEC(flags)) {
1533 1533                  mdb_printf("%<u>%-8s %-4s %-4s %-5s %s%</u>\n",
1534 1534                      "ADDR", "ID", "VERS", "FLAGS", "STATE");
1535 1535          }
1536 1536  
1537 1537          mdb_printf("%-8p %-4d %-4u %-5x %a\n",
1538 1538              addr, xi.xi_id, xi.xi_version, xi.xi_flags, xi.xi_state);
1539 1539  
1540 1540          if (opt_l | opt_s) {
1541 1541                  (void) mdb_inc_indent(4);
1542 1542                  mdb_printf("Local subscriptions requested by peer:\n");
1543 1543                  mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1544 1544                  (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
1545 1545                      addr + OFFSETOF(fmd_xprt_impl_t, xi_lsub));
1546 1546                  (void) mdb_dec_indent(4);
1547 1547          }
1548 1548  
1549 1549          if (opt_r | opt_s) {
1550 1550                  (void) mdb_inc_indent(4);
1551 1551                  mdb_printf("Remote subscriptions requested of peer:\n");
1552 1552                  mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1553 1553                  (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
1554 1554                      addr + OFFSETOF(fmd_xprt_impl_t, xi_rsub));
1555 1555                  (void) mdb_dec_indent(4);
1556 1556          }
1557 1557  
1558 1558          if (opt_u | opt_s) {
1559 1559                  (void) mdb_inc_indent(4);
1560 1560                  mdb_printf("Pending unsubscription acknowledgements:\n");
1561 1561                  mdb_printf("%<u>%-8s %-4s %s%</u>\n", "ADDR", "REFS", "CLASS");
1562 1562                  (void) mdb_pwalk("fmd_xprt_class", fmd_xprt_class, &xi,
1563 1563                      addr + OFFSETOF(fmd_xprt_impl_t, xi_usub));
1564 1564                  (void) mdb_dec_indent(4);
1565 1565          }
1566 1566  
1567 1567          return (DCMD_OK);
1568 1568  }
1569 1569  
1570 1570  static int
1571 1571  tsnap_walk_init(mdb_walk_state_t *wsp)
1572 1572  {
1573 1573          fmd_t F;
1574 1574  
1575 1575          if (mdb_readvar(&F, "fmd") != sizeof (F)) {
1576 1576                  mdb_warn("failed to read fmd meta-data");
1577 1577                  return (WALK_ERR);
1578 1578          }
1579 1579  
1580 1580          wsp->walk_addr = (uintptr_t)F.d_topo_list.l_next;
1581 1581          return (WALK_NEXT);
1582 1582  }
1583 1583  
1584 1584  static int
1585 1585  tsnap_walk_step(mdb_walk_state_t *wsp)
1586 1586  {
1587 1587          uintptr_t addr = wsp->walk_addr;
1588 1588          fmd_topo_t ftp;
1589 1589  
1590 1590          if (addr == NULL)
1591 1591                  return (WALK_DONE);
1592 1592  
1593 1593          if (mdb_vread(&ftp, sizeof (ftp), addr) != sizeof (ftp)) {
1594 1594                  mdb_warn("failed to read fmd_topo_t at %p", addr);
1595 1595                  return (WALK_ERR);
1596 1596          }
1597 1597  
1598 1598          wsp->walk_addr = (uintptr_t)ftp.ft_list.l_next;
1599 1599          return (wsp->walk_callback(addr, &ftp, wsp->walk_cbdata));
1600 1600  }
1601 1601  
1602 1602  static int
1603 1603  mq_walk_init(mdb_walk_state_t *wsp)
1604 1604  {
1605 1605          fmd_module_t m;
1606 1606          struct fmd_eventq eq;
1607 1607  
1608 1608          if (wsp->walk_addr == NULL) {
1609 1609                  mdb_warn("NULL fmd_module_t passed in");
1610 1610                  return (WALK_ERR);
1611 1611          }
1612 1612  
1613 1613          if (mdb_vread(&m, sizeof (m), wsp->walk_addr) != sizeof (m)) {
1614 1614                  mdb_warn("failed to read fmd_module_t at %p", wsp->walk_addr);
1615 1615                  return (WALK_ERR);
1616 1616          }
1617 1617          if (mdb_vread(&eq, sizeof (eq), (uintptr_t)m.mod_queue)
1618 1618              != sizeof (eq)) {
1619 1619                  mdb_warn("failed to read fmd_eventq at %p", wsp->walk_addr);
1620 1620                  return (WALK_ERR);
1621 1621          }
1622 1622  
1623 1623          wsp->walk_addr = (uintptr_t)eq.eq_list.l_next;
1624 1624  
1625 1625          return (WALK_NEXT);
1626 1626  }
1627 1627  
1628 1628  static int
1629 1629  mq_walk_step(mdb_walk_state_t *wsp)
1630 1630  {
1631 1631          uintptr_t addr = wsp->walk_addr;
1632 1632          fmd_eventqelem_t eqe;
1633 1633  
1634 1634          if (addr == NULL)
1635 1635                  return (WALK_DONE);
1636 1636  
1637 1637          if (mdb_vread(&eqe, sizeof (eqe), addr) != sizeof (eqe)) {
1638 1638                  mdb_warn("failed to read fmd_eventqelem_t at %p", addr);
1639 1639                  return (WALK_ERR);
1640 1640          }
1641 1641  
1642 1642          wsp->walk_addr = (uintptr_t)eqe.eqe_list.l_next;
1643 1643          return (wsp->walk_callback(addr, &eqe, wsp->walk_cbdata));
1644 1644  }
1645 1645  
1646 1646  static const mdb_dcmd_t dcmds[] = {
1647 1647          { "fcf_case", "?", "print a FCF case", fcf_case },
1648 1648          { "fcf_event", "?", "print a FCF event", fcf_event },
1649 1649          { "fcf_hdr", "?", "print a FCF header", fcf_hdr },
1650 1650          { "fcf_sec", ":", "print a FCF section header", fcf_sec },
1651 1651          { "fcf_serd", "?", "print a FCF serd engine", fcf_serd },
1652 1652          { "fmd_trace", "?[-cs]", "display thread trace buffer(s)", fmd_trace },
1653 1653          { "fmd_ustat", "[:]", "display statistics collection", fmd_ustat },
1654 1654          { "fmd_stat", "[:]", "display statistic structure", fmd_stat },
1655 1655          { "fmd_event", NULL, "display event structure", fmd_event },
1656 1656          { "fmd_thread", "?", "display thread or list of threads", fmd_thread },
1657 1657          { "fmd_module", "?", "display module or list of modules", fmd_module },
1658 1658          { "fmd_case", ":", "display case file structure", fmd_case },
1659 1659          { "fmd_buf", ":", "display buffer structure", fmd_buf },
1660 1660          { "fmd_serd", "[:]", "display serd engine structure", fmd_serd },
1661 1661          { "fmd_asru", "?", "display asru resource structure", fmd_asru },
1662 1662          { "fmd_asru_link", "?", "display resource structure", fmd_asru_link },
1663 1663          { "fmd_timer", "?", "display pending timer(s)", fmd_timer },
1664 1664          { "fmd_xprt", "?[-lrsu]", "display event transport(s)", fmd_xprt },
1665 1665          { NULL }
1666 1666  };
1667 1667  
1668 1668  static const mdb_walker_t walkers[] = {
1669 1669          { "fcf_sec", "walk FCF section header table given header address",
1670 1670                  fcf_sec_walk_init, fcf_sec_walk_step, fcf_sec_walk_fini },
1671 1671          { "fmd_trace", "walk per-thread trace buffers",
1672 1672                  trwalk_init, trwalk_step, trwalk_fini },
1673 1673          { "fmd_ustat", "walk per-collection statistics",
1674 1674                  ustat_walk_init, ustat_walk_step, hash_walk_fini },
1675 1675          { "fmd_thread", "walk list of all fmd_thread_t's",
1676 1676                  thread_walk_init, thread_walk_step, NULL },
1677 1677          { "fmd_module", "walk list of all fmd_module_t's",
1678 1678                  mod_walk_init, mod_walk_step, NULL },
1679 1679          { "fmd_case", "walk per-module case objects",
1680 1680                  case_walk_init, case_walk_step, case_walk_fini },
1681 1681          { "fmd_buf", "walk per-buf_hash buffers",
1682 1682                  buf_walk_init, hash_walk_step, hash_walk_fini },
1683 1683          { "fmd_serd", "walk per-serd_hash engines",
1684 1684                  serd_walk_init, hash_walk_step, hash_walk_fini },
1685 1685          { "fmd_asru", "walk asru resource hash",
1686 1686                  asru_walk_init, hash_walk_step, hash_walk_fini },
1687 1687          { "fmd_asru_link", "walk resource hash",
1688 1688                  al_walk_init, hash_walk_step, hash_walk_fini },
1689 1689          { "fmd_timerq", "walk timer queue",
1690 1690                  tmq_walk_init, tmq_walk_step, NULL },
1691 1691          { "fmd_xprt", "walk per-module list of transports",
1692 1692                  xprt_walk_init, xprt_walk_step, NULL },
1693 1693          { "fmd_xprt_class", "walk hash table of subscription classes",
1694 1694                  xpc_walk_init, hash_walk_step, hash_walk_fini },
1695 1695          { "fmd_topo", "walk fmd's list of topo snapshots",
1696 1696                  tsnap_walk_init, tsnap_walk_step, NULL },
1697 1697          { "fmd_mod_queue", "walk per-module event queue",
1698 1698                  mq_walk_init, mq_walk_step, NULL },
1699 1699          { NULL, NULL, NULL, NULL, NULL }
1700 1700  };
1701 1701  
1702 1702  static const mdb_modinfo_t modinfo = { MDB_API_VERSION, dcmds, walkers };
1703 1703  
1704 1704  const mdb_modinfo_t *
1705 1705  _mdb_init(void)
1706 1706  {
1707 1707          return (&modinfo);
1708 1708  }
  
    | 
      ↓ open down ↓ | 
    1148 lines elided | 
    
      ↑ open up ↑ | 
  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX