Print this page
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9808 SMB3 persistent handles
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15578 SMB2 durable handle redesign
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-5665 SMB2 oplock leases
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-14658 mdb cannot show smbsrv sessions
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Note: requires:
8024 mdb_ctf_vread() needn't be so strict about unions
NEX-13653 Obsolete SMB server work-around for ZFS read-only
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-9497 SMB should bypass ACL traverse checking
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
NEX-9180 SMB: mdb "::smbreq -v" prints findstack errors
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
NEX-6041 Should pass the smbtorture lock tests
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-5906 mdb smbsrv SEGV with IPv6 clients
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
NEX-3553 SMB2/3 durable handles
Reviewed by: Gordon Ross <gwr@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-5560 smb2 should use 64-bit server-global uids
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5555 smb locks don't need l_uid or l_session_kid
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-5330 SMB server should combine TCP+NBT session lists
Reviewed by: Gordon Ross <gwr@nexenta.com>
NEX-3906 Prefer that SMB change notify not tie up a worker thread
NEX-5278 SMB notify should buffer per file handle
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-4085 Merge illumos 687 rpcgen should not generate absolute #includes
Reviewed by: Marcel Telka <marcel@telka.sk>
Approved by: Dan McDonald <danmcd@omniti.com>
NEX-3931 smbsrv mdb module should decode flags fields
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-3884 smbsrv mdb module compatibility with older builds
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
Reviewed by: Josef 'Jeff' Sipek <josef.sipek@nexenta.com>
NEX-3847 smbsrv mdb module should lookup enum values
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-3376 Want a way to extract SMB packets from a crash dump
Reviewed by: Dan Fields <dan.fields@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
NEX-3696 smbsrv mdb module could use some cleanup
NEX-3677 want mdb "shares" walker for smbsrv
NEX-3678 mdb -k smbsrv`smbvfs dcmd doesn't work
Reviewed by: Bayard Bell <bayard.bell@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
NEX-3004 Keep track of remote TCP port
Reviewed by: Dan Fields <Dan.Fields@nexenta.com>
Reviewed by: Josef Sipek <Josef.Sipek@nexenta.com>
Reviewed by: Matt Barden <Matt.Barden@nexenta.com>
Reviewed by: Kevin Crowe <Kevin.Crowe@nexenta.com>
Reviewed by: Alek Pinchuk <Alek.Pinchuk@nexenta.com>
Reviewed by: Rick McNeal <Rick.McNeal@nexenta.com>
SMB-146 SMBD disappeared on Codenomicon TC: 20867
SMB-147 mdb shows SMB2 commands incorrectly
This is a minimal fix for the release that touches only the mdb module.
SMB-11 SMB2 message parse & dispatch
SMB-12 SMB2 Negotiate Protocol
SMB-13 SMB2 Session Setup
SMB-14 SMB2 Logoff
SMB-15 SMB2 Tree Connect
SMB-16 SMB2 Tree Disconnect
SMB-17 SMB2 Create
SMB-18 SMB2 Close
SMB-19 SMB2 Flush
SMB-20 SMB2 Read
SMB-21 SMB2 Write
SMB-22 SMB2 Lock/Unlock
SMB-23 SMB2 Ioctl
SMB-24 SMB2 Cancel
SMB-25 SMB2 Echo
SMB-26 SMB2 Query Dir
SMB-27 SMB2 Change Notify
SMB-28 SMB2 Query Info
SMB-29 SMB2 Set Info
SMB-30 SMB2 Oplocks
SMB-53 SMB2 Create Context options
(SMB2 code review cleanup 1, 2, 3)
SMB-69 read-raw, write-raw are dead code
SMB-56 extended security NTLMSSP, inbound
SMB-50 User-mode SMB server
 Includes work by these authors:
 Thomas Keiser <thomas.keiser@nexenta.com>
 Albert Lee <trisk@nexenta.com>
SMB-65 SMB server in non-global zones (data structure changes)
Many things move to the smb_server_t object, and
many functions gain an sv arg (which server).
SMB-63 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0
re #11974 CIFS Share - Tree connect fails from Windows 7 Clients
re #12430 rb3946 Remove dependency on libtopo from zfs-monitor to fix build warning
re #12277 rb3881 new psrinfo does not print socket type
re #12412 rb3944 mdb smbsess dcmd in verbose mode calculates the wrong IP address

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c
          +++ new/usr/src/cmd/mdb/common/modules/smbsrv/smbsrv.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  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) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
  24      - * Copyright 2015 Nexenta Systems, Inc. All rights reserved.
       24 + * Copyright 2017 Nexenta Systems, Inc. All rights reserved.
  25   25   */
  26   26  
  27   27  #include <mdb/mdb_modapi.h>
  28   28  #include <mdb/mdb_ks.h>
       29 +#include <mdb/mdb_ctf.h>
       30 +#include <sys/note.h>
  29   31  #include <sys/thread.h>
  30   32  #include <sys/taskq.h>
  31   33  #include <smbsrv/smb_vops.h>
  32   34  #include <smbsrv/smb.h>
  33   35  #include <smbsrv/smb_ktypes.h>
       36 +#include <smbsrv/smb_token.h>
       37 +#include <smbsrv/smb_oplock.h>
  34   38  
       39 +#ifndef _KMDB
       40 +#include "smbsrv_pcap.h"
       41 +#endif
       42 +
  35   43  #ifdef _KERNEL
  36   44  #define SMBSRV_OBJNAME  "smbsrv"
  37   45  #else
  38   46  #define SMBSRV_OBJNAME  "libfksmbsrv.so.1"
  39   47  #endif
  40   48  
       49 +#define SMBSRV_SCOPE    SMBSRV_OBJNAME "`"
       50 +
  41   51  #define SMB_DCMD_INDENT         2
  42   52  #define ACE_TYPE_TABLEN         (ACE_ALL_TYPES + 1)
  43   53  #define ACE_TYPE_ENTRY(_v_)     {_v_, #_v_}
  44   54  #define SMB_COM_ENTRY(_v_, _x_) {#_v_, _x_}
  45   55  
  46      -#define SMB_MDB_MAX_OPTS        9
       56 +#define SMB_MDB_MAX_OPTS        10
  47   57  
  48   58  #define SMB_OPT_SERVER          0x00000001
  49   59  #define SMB_OPT_SESSION         0x00000002
  50   60  #define SMB_OPT_REQUEST         0x00000004
  51   61  #define SMB_OPT_USER            0x00000008
  52   62  #define SMB_OPT_TREE            0x00000010
  53   63  #define SMB_OPT_OFILE           0x00000020
  54   64  #define SMB_OPT_ODIR            0x00000040
  55   65  #define SMB_OPT_WALK            0x00000100
  56   66  #define SMB_OPT_VERBOSE         0x00000200
  57   67  #define SMB_OPT_ALL_OBJ         0x000000FF
  58   68  
  59   69  /*
       70 + * Use CTF to set var = OFFSETOF(typ, mem) if possible, otherwise
       71 + * fall back to just OFFSETOF.  The fall back is more convenient
       72 + * than trying to return an error where this is used, and also
       73 + * let's us find out at compile time if we're referring to any
       74 + * typedefs or member names that don't exist.  Without that
       75 + * OFFSETOF fall back, we'd only find out at run time.
       76 + */
       77 +#define GET_OFFSET(var, typ, mem) do {                          \
       78 +        var = mdb_ctf_offsetof_by_name(#typ, #mem);             \
       79 +        if (var < 0) {                                          \
       80 +                mdb_warn("cannot lookup: " #typ " ." #mem);     \
       81 +                var = (int)OFFSETOF(typ, mem);                  \
       82 +        }                                                       \
       83 +_NOTE(CONSTCOND) } while (0)
       84 +
       85 +/*
  60   86   * Structure associating an ACE type to a string.
  61   87   */
  62   88  typedef struct {
  63   89          uint8_t         ace_type_value;
  64   90          const char      *ace_type_sting;
  65   91  } ace_type_entry_t;
  66   92  
  67   93  /*
  68   94   * Structure containing strings describing an SMB command.
  69   95   */
  70   96  typedef struct {
  71   97          const char      *smb_com;
  72   98          const char      *smb_andx;
  73   99  } smb_com_entry_t;
  74  100  
  75  101  /*
  76  102   * Structure describing an object to be expanded (displayed).
  77  103   */
  78  104  typedef struct {
  79  105          uint_t          ex_mask;
  80      -        size_t          ex_offset;
      106 +        int             (*ex_offset)(void);
  81  107          const char      *ex_dcmd;
  82  108          const char      *ex_name;
  83  109  } smb_exp_t;
  84  110  
  85  111  /*
  86  112   * List of supported options. Ther order has the match the bits SMB_OPT_xxx.
  87  113   */
  88  114  typedef struct smb_mdb_opts {
  89  115          char            *o_name;
  90  116          uint32_t        o_value;
↓ open down ↓ 5 lines elided ↑ open up ↑
  96  122          { "-e", SMB_OPT_SESSION },
  97  123          { "-r", SMB_OPT_REQUEST },
  98  124          { "-u", SMB_OPT_USER    },
  99  125          { "-t", SMB_OPT_TREE    },
 100  126          { "-f", SMB_OPT_OFILE   },
 101  127          { "-d", SMB_OPT_ODIR    },
 102  128          { "-w", SMB_OPT_WALK    },
 103  129          { "-v", SMB_OPT_VERBOSE }
 104  130  };
 105  131  
      132 +/*
      133 + * These access mask bits are generic enough they could move into the
      134 + * genunix mdb module or somewhere so they could be shared.
      135 + */
      136 +static const mdb_bitmask_t
      137 +nt_access_bits[] = {
      138 +        { "READ_DATA",
      139 +            FILE_READ_DATA,
      140 +            FILE_READ_DATA },
      141 +        { "WRITE_DATA",
      142 +            FILE_WRITE_DATA,
      143 +            FILE_WRITE_DATA },
      144 +        { "APPEND_DATA",
      145 +            FILE_APPEND_DATA,
      146 +            FILE_APPEND_DATA },
      147 +        { "READ_EA",
      148 +            FILE_READ_EA,
      149 +            FILE_READ_EA },
      150 +        { "WRITE_EA",
      151 +            FILE_WRITE_EA,
      152 +            FILE_WRITE_EA },
      153 +        { "EXECUTE",
      154 +            FILE_EXECUTE,
      155 +            FILE_EXECUTE },
      156 +        { "DELETE_CHILD",
      157 +            FILE_DELETE_CHILD,
      158 +            FILE_DELETE_CHILD },
      159 +        { "READ_ATTR",
      160 +            FILE_READ_ATTRIBUTES,
      161 +            FILE_READ_ATTRIBUTES },
      162 +        { "WRITE_ATTR",
      163 +            FILE_WRITE_ATTRIBUTES,
      164 +            FILE_WRITE_ATTRIBUTES },
      165 +        { "DELETE",
      166 +            DELETE,
      167 +            DELETE },
      168 +        { "READ_CTRL",
      169 +            READ_CONTROL,
      170 +            READ_CONTROL },
      171 +        { "WRITE_DAC",
      172 +            WRITE_DAC,
      173 +            WRITE_DAC },
      174 +        { "WRITE_OWNER",
      175 +            WRITE_OWNER,
      176 +            WRITE_OWNER },
      177 +        { "SYNCH",
      178 +            SYNCHRONIZE,
      179 +            SYNCHRONIZE },
      180 +        { "ACC_SEC",
      181 +            ACCESS_SYSTEM_SECURITY,
      182 +            ACCESS_SYSTEM_SECURITY },
      183 +        { "MAX_ALLOWED",
      184 +            MAXIMUM_ALLOWED,
      185 +            MAXIMUM_ALLOWED },
      186 +        { "GEN_X",
      187 +            GENERIC_EXECUTE,
      188 +            GENERIC_EXECUTE },
      189 +        { "GEN_W",
      190 +            GENERIC_WRITE,
      191 +            GENERIC_WRITE },
      192 +        { "GEN_R",
      193 +            GENERIC_READ,
      194 +            GENERIC_READ },
      195 +        { NULL, 0, 0 }
      196 +};
      197 +
 106  198  static smb_com_entry_t  smb_com[256] =
 107  199  {
 108  200          SMB_COM_ENTRY(SMB_COM_CREATE_DIRECTORY, "No"),
 109  201          SMB_COM_ENTRY(SMB_COM_DELETE_DIRECTORY, "No"),
 110  202          SMB_COM_ENTRY(SMB_COM_OPEN, "No"),
 111  203          SMB_COM_ENTRY(SMB_COM_CREATE, "No"),
 112  204          SMB_COM_ENTRY(SMB_COM_CLOSE, "No"),
 113  205          SMB_COM_ENTRY(SMB_COM_FLUSH, "No"),
 114  206          SMB_COM_ENTRY(SMB_COM_DELETE, "No"),
 115  207          SMB_COM_ENTRY(SMB_COM_RENAME, "No"),
↓ open down ↓ 263 lines elided ↑ open up ↑
 379  471          "smb2_cancel",
 380  472          "smb2_echo",
 381  473          "smb2_query_dir",
 382  474          "smb2_change_notify",
 383  475          "smb2_query_info",
 384  476          "smb2_set_info",
 385  477          "smb2_oplock_break",
 386  478          "smb2_invalid_cmd"
 387  479  };
 388  480  
 389      -static int smb_dcmd_list(uintptr_t, uint_t, int, const mdb_arg_t *);
 390      -static void smb_dcmd_list_help(void);
 391      -static int smb_dcmd_server(uintptr_t, uint_t, int, const mdb_arg_t *);
 392      -static void smb_dcmd_session_help(void);
 393      -static int smb_dcmd_session(uintptr_t, uint_t, int, const mdb_arg_t *);
 394      -static int smb_dcmd_request(uintptr_t, uint_t, int, const mdb_arg_t *);
 395      -static void smb_dcmd_user_help(void);
 396      -static int smb_dcmd_user(uintptr_t, uint_t, int, const mdb_arg_t *);
 397      -static void smb_dcmd_tree_help(void);
 398      -static int smb_dcmd_tree(uintptr_t, uint_t, int, const mdb_arg_t *);
 399      -static int smb_dcmd_odir(uintptr_t, uint_t, int, const mdb_arg_t *);
 400      -static int smb_dcmd_ofile(uintptr_t, uint_t, int, const mdb_arg_t *);
 401      -static int smb_dcmd_kshare(uintptr_t, uint_t, int, const mdb_arg_t *);
 402      -static int smb_dcmd_vfs(uintptr_t, uint_t, int, const mdb_arg_t *);
 403      -static int smb_vfs_walk_init(mdb_walk_state_t *);
 404      -static int smb_vfs_walk_step(mdb_walk_state_t *);
 405      -static void smb_node_help(void);
 406      -static int smb_dcmd_node(uintptr_t, uint_t, int, const mdb_arg_t *);
 407      -static int smb_node_walk_init(mdb_walk_state_t *);
 408      -static int smb_node_walk_step(mdb_walk_state_t *);
 409      -static int smb_lock(uintptr_t, uint_t, int, const mdb_arg_t *);
 410      -static int smb_oplock(uintptr_t, uint_t, int, const mdb_arg_t *);
 411      -static int smb_oplock_grant(uintptr_t, uint_t, int, const mdb_arg_t *);
 412      -static int smb_ace(uintptr_t, uint_t, int, const mdb_arg_t *);
 413      -static int smb_ace_walk_init(mdb_walk_state_t *);
 414      -static int smb_ace_walk_step(mdb_walk_state_t *);
 415      -static int smb_acl(uintptr_t, uint_t, int, const mdb_arg_t *);
 416      -static int smb_sd(uintptr_t, uint_t, int, const mdb_arg_t *);
 417      -static int smb_sid(uintptr_t, uint_t, int, const mdb_arg_t *);
      481 +struct mdb_smb_oplock;
      482 +
 418  483  static int smb_sid_print(uintptr_t);
 419      -static int smb_fssd(uintptr_t, uint_t, int, const mdb_arg_t *);
 420  484  static int smb_dcmd_getopt(uint_t *, int, const mdb_arg_t *);
 421  485  static int smb_dcmd_setopt(uint_t, int, mdb_arg_t *);
 422  486  static int smb_obj_expand(uintptr_t, uint_t, const smb_exp_t *, ulong_t);
 423  487  static int smb_obj_list(const char *, uint_t, uint_t);
 424  488  static int smb_worker_findstack(uintptr_t);
 425      -static int smb_stats(uintptr_t, uint_t, int, const mdb_arg_t *);
      489 +static int smb_node_get_oplock(uintptr_t, struct mdb_smb_oplock **);
      490 +static int smb_node_oplock_cnt(struct mdb_smb_oplock *);
      491 +static void smb_inaddr_ntop(smb_inaddr_t *, char *, size_t);
      492 +static void get_enum(char *, size_t, const char *, int, const char *);
 426  493  
 427      -/*
 428      - * MDB module linkage information:
 429      - *
 430      - * We declare a list of structures describing our dcmds, a list of structures
 431      - * describing our walkers and a function named _mdb_init to return a pointer
 432      - * to our module information.
 433      - */
 434      -static const mdb_dcmd_t dcmds[] = {
 435      -        {   "smblist",
 436      -            "[-seutfdwv]",
 437      -            "print tree of SMB objects",
 438      -            smb_dcmd_list,
 439      -            smb_dcmd_list_help },
 440      -        {   "smbsrv",
 441      -            "[-seutfdwv]",
 442      -            "print smb_server information",
 443      -            smb_dcmd_server },
 444      -        {   "smbshares",
 445      -            "[-v]",
 446      -            "print smb_kshare_t information",
 447      -            smb_dcmd_kshare },
 448      -        {   "smbvfs",
 449      -            "[-v]",
 450      -            "print smb_vfs information",
 451      -            smb_dcmd_vfs },
 452      -        {   "smbnode",
 453      -            "?[-vps]",
 454      -            "print smb_node_t information",
 455      -            smb_dcmd_node,
 456      -            smb_node_help },
 457      -        {   "smbsess",
 458      -            "[-utfdwv]",
 459      -            "print smb_session_t information",
 460      -            smb_dcmd_session,
 461      -            smb_dcmd_session_help},
 462      -        {   "smbreq",
 463      -            ":[-v]",
 464      -            "print smb_request_t information",
 465      -            smb_dcmd_request },
 466      -        {   "smblock", ":[-v]",
 467      -            "print smb_lock_t information", smb_lock },
 468      -        {   "smbuser",
 469      -            ":[-vdftq]",
 470      -            "print smb_user_t information",
 471      -            smb_dcmd_user,
 472      -            smb_dcmd_user_help },
 473      -        {   "smbtree",
 474      -            ":[-vdf]",
 475      -            "print smb_tree_t information",
 476      -            smb_dcmd_tree,
 477      -            smb_dcmd_tree_help },
 478      -        {   "smbodir",
 479      -            ":[-v]",
 480      -            "print smb_odir_t information",
 481      -            smb_dcmd_odir },
 482      -        {   "smbofile",
 483      -            "[-v]",
 484      -            "print smb_file_t information",
 485      -            smb_dcmd_ofile },
 486      -        {   "smboplock", NULL,
 487      -            "print smb_oplock_t information", smb_oplock },
 488      -        {   "smboplockgrant", NULL,
 489      -            "print smb_oplock_grant_t information", smb_oplock_grant },
 490      -        {   "smbstat", NULL,
 491      -            "print all smb dispatched requests statistics",
 492      -            smb_stats },
 493      -        {   "smbace", "[-v]",
 494      -            "print smb_ace_t information", smb_ace },
 495      -        {   "smbacl", "[-v]",
 496      -            "print smb_acl_t information", smb_acl },
 497      -        {   "smbsid", "[-v]",
 498      -            "print smb_sid_t information", smb_sid },
 499      -        {   "smbsd", "[-v]",
 500      -            "print smb_sd_t information", smb_sd },
 501      -        {   "smbfssd", "[-v]",
 502      -            "print smb_fssd_t information", smb_fssd },
 503      -        { NULL }
 504      -};
      494 +typedef int (*dump_func_t)(struct mbuf_chain *, int32_t,
      495 +    smb_inaddr_t *, uint16_t, smb_inaddr_t *, uint16_t,
      496 +    hrtime_t, boolean_t);
      497 +static int smb_req_dump(struct mbuf_chain *, int32_t,
      498 +    smb_inaddr_t *, uint16_t, smb_inaddr_t *, uint16_t,
      499 +    hrtime_t, boolean_t);
      500 +static int smb_req_dump_m(uintptr_t, const void *, void *);
 505  501  
 506      -static const mdb_walker_t walkers[] = {
 507      -        {   "smbnode_walker",
 508      -            "walk list of smb_node_t structures",
 509      -            smb_node_walk_init,
 510      -            smb_node_walk_step,
 511      -            NULL,
 512      -            NULL },
 513      -        {   "smbvfs_walker",
 514      -            "walk list of smb_vfs_t structures",
 515      -            smb_vfs_walk_init,
 516      -            smb_vfs_walk_step,
 517      -            NULL,
 518      -            NULL },
 519      -        {   "smbace_walker",
 520      -            "walk list of smb_ace_t structures",
 521      -            smb_ace_walk_init,
 522      -            smb_ace_walk_step,
 523      -            NULL,
 524      -            NULL },
 525      -        { NULL }
 526      -};
 527      -
 528      -static const mdb_modinfo_t modinfo = {
 529      -        MDB_API_VERSION, dcmds, walkers
 530      -};
 531      -
 532      -const mdb_modinfo_t *
 533      -_mdb_init(void)
 534      -{
 535      -        return (&modinfo);
 536      -}
 537      -
 538  502  /*
 539  503   * *****************************************************************************
 540  504   * ****************************** Top level DCMD *******************************
 541  505   * *****************************************************************************
 542  506   */
 543  507  
 544  508  static void
 545      -smb_dcmd_list_help(void)
      509 +smblist_help(void)
 546  510  {
 547  511          mdb_printf(
 548  512              "Displays the list of objects using an indented tree format.\n"
 549  513              "If no option is specified the entire tree is displayed\n\n");
 550  514          (void) mdb_dec_indent(2);
 551  515          mdb_printf("%<b>OPTIONS%</b>\n");
 552  516          (void) mdb_inc_indent(2);
 553  517          mdb_printf(
 554  518              "-v\tDisplay verbose information\n"
 555  519              "-s\tDisplay the list of servers\n"
↓ open down ↓ 7 lines elided ↑ open up ↑
 563  527  
 564  528  /*
 565  529   * ::smblist
 566  530   *
 567  531   * This function lists the objects specified on the command line. If no object
 568  532   * is specified the entire tree (server through ofile and odir) is displayed.
 569  533   *
 570  534   */
 571  535  /*ARGSUSED*/
 572  536  static int
 573      -smb_dcmd_list(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
      537 +smblist_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 574  538  {
 575  539          GElf_Sym        sym;
 576  540          uint_t          opts = 0;
 577  541          int             new_argc;
 578  542          mdb_arg_t       new_argv[SMB_MDB_MAX_OPTS];
      543 +        int             ll_off;
 579  544  
 580  545          if (smb_dcmd_getopt(&opts, argc, argv))
 581  546                  return (DCMD_USAGE);
 582  547  
 583  548          if (!(opts & ~(SMB_OPT_WALK | SMB_OPT_VERBOSE)))
 584  549                  opts |= SMB_OPT_ALL_OBJ;
 585  550  
 586  551          opts |= SMB_OPT_WALK;
 587  552  
 588  553          new_argc = smb_dcmd_setopt(opts, SMB_MDB_MAX_OPTS, new_argv);
 589  554  
 590  555          if (mdb_lookup_by_obj(SMBSRV_OBJNAME, "smb_servers", &sym) == -1) {
 591  556                  mdb_warn("failed to find symbol smb_servers");
 592  557                  return (DCMD_ERR);
 593  558          }
 594  559  
 595      -        addr = (uintptr_t)sym.st_value + OFFSETOF(smb_llist_t, ll_list);
      560 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
      561 +        addr = (uintptr_t)sym.st_value + ll_off;
 596  562  
 597  563          if (mdb_pwalk_dcmd("list", "smbsrv", new_argc, new_argv, addr)) {
 598  564                  mdb_warn("cannot walk smb_server list");
 599  565                  return (DCMD_ERR);
 600  566          }
 601  567          return (DCMD_OK);
 602  568  }
 603  569  
 604  570  /*
 605  571   * *****************************************************************************
 606  572   * ***************************** smb_server_t **********************************
 607  573   * *****************************************************************************
 608  574   */
 609  575  
 610      -static const char *smb_server_state[SMB_SERVER_STATE_SENTINEL] =
      576 +typedef struct mdb_smb_server {
      577 +        smb_server_state_t      sv_state;
      578 +        zoneid_t                sv_zid;
      579 +        smb_hash_t              *sv_persistid_ht;
      580 +} mdb_smb_server_t;
      581 +
      582 +static int
      583 +smb_server_exp_off_sv_list(void)
 611  584  {
 612      -        "CREATED",
 613      -        "CONFIGURED",
 614      -        "RUNNING",
 615      -        "STOPPING",
 616      -        "DELETING"
 617      -};
      585 +        int svl_off, ll_off;
 618  586  
      587 +        /* OFFSETOF(smb_server_t, sv_session_list.ll_list); */
      588 +        GET_OFFSET(svl_off, smb_server_t, sv_session_list);
      589 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
      590 +        return (svl_off + ll_off);
      591 +}
      592 +
      593 +static int
      594 +smb_server_exp_off_nbt_list(void)
      595 +{
      596 +        int svd_off, lds_off, ll_off;
      597 +
      598 +        /* OFFSETOF(smb_server_t, sv_nbt_daemon.ld_session_list.ll_list); */
      599 +        GET_OFFSET(svd_off, smb_server_t, sv_nbt_daemon);
      600 +        /*
      601 +         * We can't do OFFSETOF() because the member doesn't exist,
      602 +         * but we want backwards compatibility to old cores
      603 +         */
      604 +        lds_off = mdb_ctf_offsetof_by_name("smb_listener_daemon_t",
      605 +            "ld_session_list");
      606 +        if (lds_off < 0) {
      607 +                mdb_warn("cannot lookup: "
      608 +                    "smb_listener_daemon_t .ld_session_list");
      609 +                return (-1);
      610 +        }
      611 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
      612 +        return (svd_off + lds_off + ll_off);
      613 +}
      614 +
      615 +static int
      616 +smb_server_exp_off_tcp_list(void)
      617 +{
      618 +        int svd_off, lds_off, ll_off;
      619 +
      620 +        /* OFFSETOF(smb_server_t, sv_tcp_daemon.ld_session_list.ll_list); */
      621 +        GET_OFFSET(svd_off, smb_server_t, sv_tcp_daemon);
      622 +        /*
      623 +         * We can't do OFFSETOF() because the member doesn't exist,
      624 +         * but we want backwards compatibility to old cores
      625 +         */
      626 +        lds_off = mdb_ctf_offsetof_by_name("smb_listener_daemon_t",
      627 +            "ld_session_list");
      628 +        if (lds_off < 0) {
      629 +                mdb_warn("cannot lookup: "
      630 +                    "smb_listener_daemon_t .ld_session_list");
      631 +                return (-1);
      632 +        }
      633 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
      634 +        return (svd_off + lds_off + ll_off);
      635 +}
      636 +
 619  637  /*
 620  638   * List of objects that can be expanded under a server structure.
 621  639   */
 622  640  static const smb_exp_t smb_server_exp[] =
 623  641  {
 624  642          { SMB_OPT_ALL_OBJ,
 625      -            OFFSETOF(smb_server_t, sv_nbt_daemon.ld_session_list.ll_list),
      643 +            smb_server_exp_off_sv_list,
 626  644              "smbsess", "smb_session"},
      645 +        { 0, 0, NULL, NULL }
      646 +};
      647 +
      648 +/* for backwards compatibility only */
      649 +static const smb_exp_t smb_server_exp_old[] =
      650 +{
 627  651          { SMB_OPT_ALL_OBJ,
 628      -            OFFSETOF(smb_server_t, sv_tcp_daemon.ld_session_list.ll_list),
      652 +            smb_server_exp_off_nbt_list,
 629  653              "smbsess", "smb_session"},
      654 +        { SMB_OPT_ALL_OBJ,
      655 +            smb_server_exp_off_tcp_list,
      656 +            "smbsess", "smb_session"},
 630  657          { 0, 0, NULL, NULL }
 631  658  };
 632  659  
 633  660  /*
 634  661   * ::smbsrv
 635  662   *
 636  663   * smbsrv dcmd - Print out smb_server structures.
 637  664   */
 638  665  /*ARGSUSED*/
 639  666  static int
 640      -smb_dcmd_server(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
      667 +smbsrv_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 641  668  {
 642  669          uint_t          opts;
 643  670          ulong_t         indent = 0;
      671 +        const smb_exp_t *sv_exp;
      672 +        mdb_ctf_id_t id;
      673 +        ulong_t off;
 644  674  
 645  675          if (smb_dcmd_getopt(&opts, argc, argv))
 646  676                  return (DCMD_USAGE);
 647  677  
 648  678          if (!(flags & DCMD_ADDRSPEC))
 649  679                  return (smb_obj_list("smb_server", opts | SMB_OPT_SERVER,
 650  680                      flags));
 651  681  
 652  682          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SERVER)) ||
 653  683              !(opts & SMB_OPT_WALK)) {
 654      -                smb_server_t    *sv;
 655      -                const char      *state;
      684 +                mdb_smb_server_t *sv;
      685 +                char state[40];
 656  686  
 657      -                sv = mdb_alloc(sizeof (smb_server_t), UM_SLEEP | UM_GC);
 658      -                if (mdb_vread(sv, sizeof (smb_server_t), addr) == -1) {
      687 +                sv = mdb_zalloc(sizeof (*sv), UM_SLEEP | UM_GC);
      688 +                if (mdb_ctf_vread(sv, SMBSRV_SCOPE "smb_server_t",
      689 +                    "mdb_smb_server_t", addr, 0) < 0) {
 659  690                          mdb_warn("failed to read smb_server at %p", addr);
 660  691                          return (DCMD_ERR);
 661  692                  }
 662  693  
 663  694                  indent = SMB_DCMD_INDENT;
 664  695  
 665  696                  if (opts & SMB_OPT_VERBOSE) {
 666  697                          mdb_arg_t       argv;
 667  698  
 668  699                          argv.a_type = MDB_TYPE_STRING;
↓ open down ↓ 2 lines elided ↑ open up ↑
 671  702                                  return (DCMD_ERR);
 672  703                  } else {
 673  704                          if (DCMD_HDRSPEC(flags))
 674  705                                  mdb_printf(
 675  706                                      "%<b>%<u>%-?s% "
 676  707                                      "%-4s% "
 677  708                                      "%-32s% "
 678  709                                      "%</u>%</b>\n",
 679  710                                      "SERVER", "ZONE", "STATE");
 680  711  
 681      -                        if (sv->sv_state >= SMB_SERVER_STATE_SENTINEL)
 682      -                                state = "UNKNOWN";
 683      -                        else
 684      -                                state = smb_server_state[sv->sv_state];
      712 +                        get_enum(state, sizeof (state),
      713 +                            "smb_server_state_t", sv->sv_state,
      714 +                            "SMB_SERVER_STATE_");
 685  715  
 686  716                          mdb_printf("%-?p %-4d %-32s \n",
 687  717                              addr, sv->sv_zid, state);
 688  718                  }
 689  719          }
 690      -        if (smb_obj_expand(addr, opts, smb_server_exp, indent))
      720 +
      721 +        /* if we can't look up the type name, just error out */
      722 +        if (mdb_ctf_lookup_by_name("smb_server_t", &id) == -1)
 691  723                  return (DCMD_ERR);
      724 +
      725 +        if (mdb_ctf_offsetof(id, "sv_session_list", &off) == -1)
      726 +                /* sv_session_list doesn't exist; old core */
      727 +                sv_exp = smb_server_exp_old;
      728 +        else
      729 +                sv_exp = smb_server_exp;
      730 +
      731 +        if (smb_obj_expand(addr, opts, sv_exp, indent))
      732 +                return (DCMD_ERR);
 692  733          return (DCMD_OK);
 693  734  }
 694  735  
 695  736  /*
 696  737   * *****************************************************************************
 697  738   * ***************************** smb_session_t *********************************
 698  739   * *****************************************************************************
 699  740   */
 700  741  
 701      -static const char *smb_session_state[SMB_SESSION_STATE_SENTINEL] =
      742 +/*
      743 + * After some changes merged from upstream, "::smblist" was failing with
      744 + * "inexact match for union au_addr (au_addr)" because the CTF data for
      745 + * the target vs mdb were apparently not exactly the same (unknown why).
      746 + *
      747 + * As described above mdb_ctf_vread(), the recommended way to read a
      748 + * union is to use an mdb struct with only the union "arm" appropriate
      749 + * to the given type instance.  That's difficult in this case, so we
      750 + * use a local union with only the in6_addr_t union arm (otherwise
      751 + * identical to smb_inaddr_t) and just cast it to an smb_inaddr_t
      752 + */
      753 +
      754 +typedef struct mdb_smb_inaddr {
      755 +        union {
      756 +#if 0   /* The real smb_inaddr_t has these too. */
      757 +                in_addr_t au_ipv4;
      758 +                in6_addr_t au_ipv6;
      759 +#endif
      760 +                in6_addr_t au_ip;
      761 +        } au_addr;
      762 +        int a_family;
      763 +} mdb_smb_inaddr_t;
      764 +
      765 +typedef struct mdb_smb_session {
      766 +        uint64_t                s_kid;
      767 +        smb_session_state_t     s_state;
      768 +        uint32_t                s_flags;
      769 +        uint16_t                s_local_port;
      770 +        uint16_t                s_remote_port;
      771 +        mdb_smb_inaddr_t        ipaddr;
      772 +        mdb_smb_inaddr_t        local_ipaddr;
      773 +        int                     dialect;
      774 +
      775 +        smb_slist_t             s_req_list;
      776 +        smb_llist_t             s_xa_list;
      777 +        smb_llist_t             s_user_list;
      778 +        smb_llist_t             s_tree_list;
      779 +
      780 +        volatile uint32_t       s_tree_cnt;
      781 +        volatile uint32_t       s_file_cnt;
      782 +        volatile uint32_t       s_dir_cnt;
      783 +
      784 +        char                    workstation[SMB_PI_MAX_HOST];
      785 +} mdb_smb_session_t;
      786 +
      787 +static int
      788 +smb_session_exp_off_req_list(void)
 702  789  {
 703      -        "INITIALIZED",
 704      -        "DISCONNECTED",
 705      -        "CONNECTED",
 706      -        "ESTABLISHED",
 707      -        "NEGOTIATED",
 708      -        "TERMINATED"
 709      -};
      790 +        int rl_off, sl_off;
 710  791  
      792 +        /* OFFSETOF(smb_session_t, s_req_list.sl_list); */
      793 +        GET_OFFSET(rl_off, smb_session_t, s_req_list);
      794 +        GET_OFFSET(sl_off, smb_slist_t, sl_list);
      795 +        return (rl_off + sl_off);
      796 +}
      797 +
      798 +static int
      799 +smb_session_exp_off_user_list(void)
      800 +{
      801 +        int ul_off, ll_off;
      802 +
      803 +        /* OFFSETOF(smb_session_t, s_user_list.ll_list); */
      804 +        GET_OFFSET(ul_off, smb_session_t, s_user_list);
      805 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
      806 +        return (ul_off + ll_off);
      807 +}
      808 +
      809 +static int
      810 +smb_session_exp_off_tree_list(void)
      811 +{
      812 +        int tl_off, ll_off;
      813 +
      814 +        /* OFFSETOF(smb_session_t, s_tree_list.ll_list); */
      815 +        GET_OFFSET(tl_off, smb_session_t, s_tree_list);
      816 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
      817 +        return (tl_off + ll_off);
      818 +}
      819 +
 711  820  /*
 712  821   * List of objects that can be expanded under a session structure.
 713  822   */
 714  823  static const smb_exp_t smb_session_exp[] =
 715  824  {
 716      -        { SMB_OPT_REQUEST,
 717      -            OFFSETOF(smb_session_t, s_req_list.sl_list),
 718      -            "smbreq", "smb_request"},
 719  825          { SMB_OPT_USER,
 720      -            OFFSETOF(smb_session_t, s_user_list.ll_list),
      826 +            smb_session_exp_off_user_list,
 721  827              "smbuser", "smb_user"},
 722  828          { SMB_OPT_TREE | SMB_OPT_OFILE | SMB_OPT_ODIR,
 723      -            OFFSETOF(smb_session_t, s_tree_list.ll_list),
      829 +            smb_session_exp_off_tree_list,
 724  830              "smbtree", "smb_tree"},
      831 +        { SMB_OPT_REQUEST,
      832 +            smb_session_exp_off_req_list,
      833 +            "smbreq", "smb_request"},
 725  834          { 0, 0, NULL, NULL}
 726  835  };
 727  836  
 728  837  static void
 729      -smb_dcmd_session_help(void)
      838 +smbsess_help(void)
 730  839  {
 731  840          mdb_printf(
 732  841              "Display the contents of smb_session_t, with optional"
 733  842              " filtering.\n\n");
 734  843          (void) mdb_dec_indent(2);
 735  844          mdb_printf("%<b>OPTIONS%</b>\n");
 736  845          (void) mdb_inc_indent(2);
 737  846          mdb_printf(
 738  847              "-v\tDisplay verbose smb_session information\n"
 739  848              "-r\tDisplay the list of smb requests attached\n"
 740  849              "-u\tDisplay the list of users attached\n");
 741  850  }
 742  851  
 743  852  /*
 744  853   * ::smbsess
 745  854   *
 746  855   * smbsess dcmd - Print out the smb_session structure.
 747  856   */
 748  857  static int
 749      -smb_dcmd_session(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
      858 +smbsess_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 750  859  {
 751  860          uint_t          opts;
 752  861          ulong_t         indent = 0;
 753  862  
 754  863          if (smb_dcmd_getopt(&opts, argc, argv))
 755  864                  return (DCMD_USAGE);
 756  865  
 757  866          if (!(flags & DCMD_ADDRSPEC)) {
 758  867                  opts |= SMB_OPT_SESSION;
 759  868                  opts &= ~SMB_OPT_SERVER;
 760  869                  return (smb_obj_list("smb_session", opts, flags));
 761  870          }
 762  871  
 763  872          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_SESSION)) ||
 764  873              !(opts & SMB_OPT_WALK)) {
 765  874                  char    cipaddr[INET6_ADDRSTRLEN];
 766  875                  char    lipaddr[INET6_ADDRSTRLEN];
 767      -                int     ipaddrstrlen;
 768      -                smb_session_t   *se;
 769      -                const char      *state;
      876 +                int     ipaddrstrlen = INET6_ADDRSTRLEN;
      877 +                mdb_smb_session_t *se;
      878 +                char    state[40];
 770  879  
 771  880                  indent = SMB_DCMD_INDENT;
 772  881  
 773      -                se = mdb_alloc(sizeof (*se), UM_SLEEP | UM_GC);
 774      -                if (mdb_vread(se, sizeof (*se), addr) == -1) {
      882 +                se = mdb_zalloc(sizeof (*se), UM_SLEEP | UM_GC);
      883 +                if (mdb_ctf_vread(se, SMBSRV_SCOPE "smb_session_t",
      884 +                    "mdb_smb_session_t", addr, 0) < 0) {
 775  885                          mdb_warn("failed to read smb_session at %p", addr);
 776  886                          return (DCMD_ERR);
 777  887                  }
 778      -                if (se->s_state >= SMB_SESSION_STATE_SENTINEL)
 779      -                        state = "INVALID";
 780      -                else
 781      -                        state = smb_session_state[se->s_state];
 782  888  
 783      -                switch (se->ipaddr.a_family) {
 784      -                case AF_INET:
 785      -                        ipaddrstrlen = INET_ADDRSTRLEN;
 786      -                        (void) mdb_snprintf(cipaddr, sizeof (cipaddr),
 787      -                            "%I", se->ipaddr.a_ipv4);
 788      -                        (void) mdb_snprintf(lipaddr, sizeof (lipaddr),
 789      -                            "%I", se->local_ipaddr.a_ipv4);
 790      -                        break;
 791      -                case AF_INET6:
 792      -                        ipaddrstrlen = INET6_ADDRSTRLEN;
 793      -                        (void) mdb_snprintf(cipaddr, sizeof (cipaddr),
 794      -                            "%N", &(se->ipaddr.a_ipv6));
 795      -                        (void) mdb_snprintf(lipaddr, sizeof (lipaddr),
 796      -                            "%N", &(se->local_ipaddr.a_ipv6));
 797      -                        break;
 798      -                default:
 799      -                        ipaddrstrlen = INET_ADDRSTRLEN;
 800      -                        (void) mdb_snprintf(cipaddr, sizeof (cipaddr),
 801      -                            "unknown");
 802      -                        (void) mdb_snprintf(lipaddr, sizeof (lipaddr),
 803      -                            "unknown");
 804      -                }
      889 +                get_enum(state, sizeof (state),
      890 +                    "smb_session_state_t", se->s_state,
      891 +                    "SMB_SESSION_STATE_");
 805  892  
      893 +                smb_inaddr_ntop((smb_inaddr_t *)&se->ipaddr,
      894 +                    cipaddr, ipaddrstrlen);
      895 +                smb_inaddr_ntop((smb_inaddr_t *)&se->local_ipaddr,
      896 +                    lipaddr, ipaddrstrlen);
      897 +
 806  898                  if (opts & SMB_OPT_VERBOSE) {
 807  899                          mdb_printf("%<b>%<u>SMB session information "
 808  900                              "(%p): %</u>%</b>\n", addr);
 809  901                          mdb_printf("Client IP address: %s %d\n",
 810  902                              cipaddr, se->s_remote_port);
 811  903                          mdb_printf("Local IP Address: %s %d\n",
 812  904                              lipaddr, se->s_local_port);
 813  905                          mdb_printf("Session KID: %u\n", se->s_kid);
 814  906                          mdb_printf("Workstation Name: %s\n",
 815  907                              se->workstation);
↓ open down ↓ 1 lines elided ↑ open up ↑
 817  909                              state);
 818  910                          mdb_printf("Session dialect: %#x\n", se->dialect);
 819  911                          mdb_printf("Number of Users: %u\n",
 820  912                              se->s_user_list.ll_count);
 821  913                          mdb_printf("Number of Trees: %u\n", se->s_tree_cnt);
 822  914                          mdb_printf("Number of Files: %u\n", se->s_file_cnt);
 823  915                          mdb_printf("Number of Shares: %u\n", se->s_dir_cnt);
 824  916                          mdb_printf("Number of active Transact.: %u\n\n",
 825  917                              se->s_xa_list.ll_count);
 826  918                  } else {
      919 +                        /*
      920 +                         * Use a reasonable mininum field width for the
      921 +                         * IP addr so the summary (usually) won't wrap.
      922 +                         */
      923 +                        int ipwidth = 22;
      924 +
 827  925                          if (DCMD_HDRSPEC(flags)) {
 828  926                                  mdb_printf(
 829  927                          "%<b>%<u>%-?s %-*s %-8s %-8s %-12s%</u>%</b>\n",
 830      -                                    "SESSION", ipaddrstrlen, "IP_ADDR",
      928 +                                    "SESSION", ipwidth, "IP_ADDR",
 831  929                                      "PORT", "DIALECT", "STATE");
 832  930                          }
 833  931                          mdb_printf("%-?p %-*s %-8d %-8#x %s\n",
 834      -                            addr, ipaddrstrlen, cipaddr,
      932 +                            addr, ipwidth, cipaddr,
 835  933                              se->s_remote_port, se->dialect, state);
 836  934                  }
 837  935          }
 838  936          if (smb_obj_expand(addr, opts, smb_session_exp, indent))
 839  937                  return (DCMD_ERR);
      938 +
 840  939          return (DCMD_OK);
 841  940  }
 842  941  
 843  942  /*
 844  943   * *****************************************************************************
 845  944   * **************************** smb_request_t **********************************
 846  945   * *****************************************************************************
 847  946   */
 848  947  
 849      -static const char *smb_request_state[SMB_REQ_STATE_SENTINEL] =
 850      -{
 851      -        "FREE",
 852      -        "INITIALIZING",
 853      -        "SUBMITTED",
 854      -        "ACTIVE",
 855      -        "WAITING_EVENT",
 856      -        "EVENT_OCCURRED",
 857      -        "WAITING_LOCK",
 858      -        "COMPLETED",
 859      -        "CANCELED",
 860      -        "CLEANED_UP"
 861      -};
      948 +typedef struct mdb_smb_request {
      949 +        smb_req_state_t         sr_state;
      950 +        smb_session_t           *session;
      951 +        struct mbuf_chain       command;
      952 +        struct mbuf_chain       reply;
 862  953  
      954 +        unsigned char           first_smb_com;
      955 +        unsigned char           smb_com;
      956 +
      957 +        uint16_t                smb_tid;
      958 +        uint32_t                smb_pid;
      959 +        uint16_t                smb_uid;
      960 +        uint16_t                smb_mid;
      961 +        uint16_t                smb_fid;
      962 +
      963 +        uint16_t                smb2_cmd_code;
      964 +        uint64_t                smb2_messageid;
      965 +        uint64_t                smb2_ssnid;
      966 +
      967 +        struct smb_tree         *tid_tree;
      968 +        struct smb_ofile        *fid_ofile;
      969 +        smb_user_t              *uid_user;
      970 +
      971 +        kthread_t               *sr_worker;
      972 +        hrtime_t                sr_time_submitted;
      973 +        hrtime_t                sr_time_active;
      974 +        hrtime_t                sr_time_start;
      975 +
      976 +} mdb_smb_request_t;
      977 +
 863  978  #define SMB_REQUEST_BANNER      \
 864      -        "%<b>%<u>%-?s %-?s %-14s %-14s %-16s %-32s%</u>%</b>\n"
      979 +        "%<b>%<u>%-?s %-14s %-?s %-16s %-16s%</u>%</b>\n"
 865  980  #define SMB_REQUEST_FORMAT      \
 866      -        "%-?p %-?p %-14lld %-14lld %-16s %s\n"
      981 +        "%-?p 0x%-12llx %-?p %-16s %s\n"
 867  982  
      983 +/*
      984 + * ::smbreq
      985 + *
      986 + * smbreq dcmd - Print out smb_request_t
      987 + */
 868  988  static int
 869      -smb_dcmd_request(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
      989 +smbreq_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 870  990  {
 871  991          uint_t          opts;
 872  992  
 873  993          if (smb_dcmd_getopt(&opts, argc, argv))
 874  994                  return (DCMD_USAGE);
 875  995  
 876  996          if (!(flags & DCMD_ADDRSPEC)) {
 877  997                  opts |= SMB_OPT_REQUEST;
 878  998                  opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_USER);
 879  999                  return (smb_obj_list("smb_request", opts, flags));
 880 1000          }
 881 1001  
 882 1002          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_REQUEST)) ||
 883 1003              !(opts & SMB_OPT_WALK)) {
 884      -                smb_request_t   *sr;
 885      -                const char      *state;
     1004 +                mdb_smb_request_t *sr;
     1005 +                char            state[40];
 886 1006                  const char      *cur_cmd_name;
 887 1007                  uint_t          cur_cmd_code;
 888      -                uint64_t        waiting;
 889      -                uint64_t        running;
     1008 +                uint64_t        msg_id;
 890 1009  
 891      -                sr = mdb_alloc(sizeof (*sr), UM_SLEEP | UM_GC);
 892      -                if (mdb_vread(sr, sizeof (*sr), addr) == -1) {
     1010 +                sr = mdb_zalloc(sizeof (*sr), UM_SLEEP | UM_GC);
     1011 +                if (mdb_ctf_vread(sr, SMBSRV_SCOPE "smb_request_t",
     1012 +                    "mdb_smb_request_t", addr, 0) < 0) {
 893 1013                          mdb_warn("failed to read smb_request at %p", addr);
 894 1014                          return (DCMD_ERR);
 895 1015                  }
 896      -                if (sr->sr_magic != SMB_REQ_MAGIC) {
 897      -                        mdb_warn("not an smb_request_t (%p)>", addr);
 898      -                        return (DCMD_ERR);
 899      -                }
 900      -                waiting = 0;
 901      -                running = 0;
 902      -                /*
 903      -                 * Note: mdb_gethrtime() is only available in kmdb
 904      -                 */
 905      -#ifdef  _KERNEL
 906      -                if (sr->sr_time_submitted != 0) {
 907      -                        if (sr->sr_time_active != 0) {
 908      -                                waiting = sr->sr_time_active -
 909      -                                    sr->sr_time_submitted;
 910      -                                running = mdb_gethrtime() -
 911      -                                    sr->sr_time_active;
 912      -                        } else {
 913      -                                waiting = mdb_gethrtime() -
 914      -                                    sr->sr_time_submitted;
 915      -                        }
 916      -                }
 917      -                waiting /= NANOSEC;
 918      -                running /= NANOSEC;
 919      -#endif  /* _KERNEL */
 920 1016  
 921      -                if (sr->sr_state >= SMB_REQ_STATE_SENTINEL)
 922      -                        state = "INVALID";
 923      -                else
 924      -                        state = smb_request_state[sr->sr_state];
     1017 +                get_enum(state, sizeof (state),
     1018 +                    "smb_req_state_t", sr->sr_state,
     1019 +                    "SMB_REQ_STATE_");
 925 1020  
 926 1021                  if (sr->smb2_cmd_code != 0) {
 927 1022                          /* SMB2 request */
 928 1023                          cur_cmd_code = sr->smb2_cmd_code;
 929 1024                          if (cur_cmd_code > SMB2_INVALID_CMD)
 930 1025                                  cur_cmd_code = SMB2_INVALID_CMD;
 931 1026                          cur_cmd_name = smb2_cmd_names[cur_cmd_code];
     1027 +                        msg_id = sr->smb2_messageid;
 932 1028                  } else {
 933 1029                          /* SMB1 request */
 934 1030                          cur_cmd_code = sr->smb_com & 0xFF;
 935 1031                          cur_cmd_name = smb_com[cur_cmd_code].smb_com;
     1032 +                        msg_id = sr->smb_mid;
 936 1033                  }
 937 1034  
 938 1035                  if (opts & SMB_OPT_VERBOSE) {
 939 1036                          mdb_printf(
 940 1037                              "%</b>%</u>SMB request information (%p):"
 941 1038                              "%</u>%</b>\n\n", addr);
 942 1039  
 943 1040                          if (sr->smb2_cmd_code == 0) {
 944 1041                                  /* SMB1 request */
 945 1042                                  mdb_printf(
↓ open down ↓ 3 lines elided ↑ open up ↑
 949 1046                          }
 950 1047  
 951 1048                          mdb_printf(
 952 1049                              "current SMB COM: %u (%s)\n",
 953 1050                              cur_cmd_code, cur_cmd_name);
 954 1051  
 955 1052                          mdb_printf(
 956 1053                              "state: %u (%s)\n",
 957 1054                              sr->sr_state, state);
 958 1055  
     1056 +                        if (sr->smb2_ssnid != 0) {
     1057 +                                mdb_printf(
     1058 +                                    "SSNID(user): 0x%llx (%p)\n",
     1059 +                                    sr->smb2_ssnid, sr->uid_user);
     1060 +                        } else {
     1061 +                                mdb_printf(
     1062 +                                    "UID(user): %u (%p)\n",
     1063 +                                    sr->smb_uid, sr->uid_user);
     1064 +                        }
     1065 +
 959 1066                          mdb_printf(
 960 1067                              "TID(tree): %u (%p)\n",
 961 1068                              sr->smb_tid, sr->tid_tree);
 962 1069  
 963 1070                          mdb_printf(
 964      -                            "UID(user): %u (%p)\n",
 965      -                            sr->smb_uid, sr->uid_user);
 966      -
 967      -                        mdb_printf(
 968 1071                              "FID(file): %u (%p)\n",
 969 1072                              sr->smb_fid, sr->fid_ofile);
 970 1073  
 971 1074                          mdb_printf(
 972 1075                              "PID: %u\n",
 973 1076                              sr->smb_pid);
 974 1077  
 975      -                        if (sr->smb2_messageid != 0) {
     1078 +                        mdb_printf(
     1079 +                            "MID: 0x%llx\n",
     1080 +                            msg_id);
     1081 +
     1082 +                        /*
     1083 +                         * Note: mdb_gethrtime() is only available in kmdb
     1084 +                         */
     1085 +#ifdef  _KERNEL
     1086 +                        if (sr->sr_time_submitted != 0) {
     1087 +                                uint64_t        waiting = 0;
     1088 +                                uint64_t        running = 0;
     1089 +
     1090 +                                if (sr->sr_time_active != 0) {
     1091 +                                        waiting = sr->sr_time_active -
     1092 +                                            sr->sr_time_submitted;
     1093 +                                        running = mdb_gethrtime() -
     1094 +                                            sr->sr_time_active;
     1095 +                                } else {
     1096 +                                        waiting = mdb_gethrtime() -
     1097 +                                            sr->sr_time_submitted;
     1098 +                                }
     1099 +                                waiting /= NANOSEC;
     1100 +                                running /= NANOSEC;
     1101 +
 976 1102                                  mdb_printf(
 977      -                                    "MID: 0x%llx\n\n",
 978      -                                    sr->smb2_messageid);
 979      -                        } else {
     1103 +                                    "waiting time: %lld\n",
     1104 +                                    waiting);
     1105 +
 980 1106                                  mdb_printf(
 981      -                                    "MID: %u\n\n",
 982      -                                    sr->smb_mid);
     1107 +                                    "running time: %lld\n",
     1108 +                                    running);
 983 1109                          }
     1110 +#endif  /* _KERNEL */
 984 1111  
 985 1112                          mdb_printf(
 986      -                            "waiting time: %lld\n",
 987      -                            waiting);
 988      -
 989      -                        mdb_printf(
 990      -                            "running time: %lld\n",
 991      -                            running);
 992      -
 993      -                        mdb_printf(
 994 1113                              "worker thread: %p\n",
 995 1114                              sr->sr_worker);
 996      -                        smb_worker_findstack((uintptr_t)sr->sr_worker);
     1115 +                        if (sr->sr_worker != NULL) {
     1116 +                                smb_worker_findstack((uintptr_t)sr->sr_worker);
     1117 +                        }
 997 1118                  } else {
 998 1119                          if (DCMD_HDRSPEC(flags))
 999 1120                                  mdb_printf(
1000 1121                                      SMB_REQUEST_BANNER,
1001      -                                    "ADDR",
     1122 +                                    "REQUEST",
     1123 +                                    "MSG_ID",
1002 1124                                      "WORKER",
1003      -                                    "WAITING(s)",
1004      -                                    "RUNNING(s)",
1005 1125                                      "STATE",
1006 1126                                      "COMMAND");
1007 1127  
1008 1128                          mdb_printf(
1009 1129                              SMB_REQUEST_FORMAT,
1010 1130                              addr,
     1131 +                            msg_id,
1011 1132                              sr->sr_worker,
1012      -                            waiting,
1013      -                            running,
1014 1133                              state,
1015 1134                              cur_cmd_name);
1016 1135                  }
1017 1136          }
1018 1137          return (DCMD_OK);
1019 1138  }
1020 1139  
     1140 +static void
     1141 +smbreq_dump_help(void)
     1142 +{
     1143 +        mdb_printf(
     1144 +            "Dump the network data for an smb_request_t, either"
     1145 +            " command, reply, or (by default) both.  Optionally"
     1146 +            " append data to a pcap file (mdb only, not kmdb).\n\n");
     1147 +        (void) mdb_dec_indent(2);
     1148 +        mdb_printf("%<b>OPTIONS%</b>\n");
     1149 +        (void) mdb_inc_indent(2);
     1150 +        mdb_printf(
     1151 +            "-c\tDump only the SMB command message\n"
     1152 +            "-r\tDump only the SMB reply message (if present)\n"
     1153 +            "-o FILE\tOutput to FILE (append) in pcap format\n");
     1154 +}
     1155 +
     1156 +#define SMB_RDOPT_COMMAND       1
     1157 +#define SMB_RDOPT_REPLY         2
     1158 +#define SMB_RDOPT_OUTFILE       4
     1159 +
1021 1160  /*
     1161 + * Like "smbreq" but just dump the command/reply messages.
     1162 + * With the output file option, append to a pcap file.
     1163 + */
     1164 +static int
     1165 +smbreq_dump_dcmd(uintptr_t rqaddr, uint_t flags, int argc,
     1166 +    const mdb_arg_t *argv)
     1167 +{
     1168 +        mdb_smb_session_t *ssn;
     1169 +        mdb_smb_request_t *sr;
     1170 +        char            *outfile = NULL;
     1171 +        dump_func_t     dump_func;
     1172 +        uint64_t        msgid;
     1173 +        uintptr_t       ssnaddr;
     1174 +        uint_t          opts = 0;
     1175 +        int             rc = DCMD_OK;
     1176 +
     1177 +        if (!(flags & DCMD_ADDRSPEC))
     1178 +                return (DCMD_USAGE);
     1179 +
     1180 +        if (mdb_getopts(argc, argv,
     1181 +            'c', MDB_OPT_SETBITS, SMB_RDOPT_COMMAND, &opts,
     1182 +            'r', MDB_OPT_SETBITS, SMB_RDOPT_REPLY, &opts,
     1183 +            'o', MDB_OPT_STR, &outfile,
     1184 +            NULL) != argc)
     1185 +                return (DCMD_USAGE);
     1186 +#ifdef  _KMDB
     1187 +        if (outfile != NULL) {
     1188 +                mdb_warn("smbreq_dump -o option not supported in kmdb\n");
     1189 +                return (DCMD_ERR);
     1190 +        }
     1191 +#endif  /* _KMDB */
     1192 +
     1193 +        /*
     1194 +         * Default without -c or -r is to dump both.
     1195 +         */
     1196 +        if ((opts & (SMB_RDOPT_COMMAND | SMB_RDOPT_REPLY)) == 0)
     1197 +                opts |= SMB_RDOPT_COMMAND | SMB_RDOPT_REPLY;
     1198 +
     1199 +        /*
     1200 +         * Get the smb_request_t, for the cmd/reply messages.
     1201 +         */
     1202 +        sr = mdb_zalloc(sizeof (*sr), UM_SLEEP | UM_GC);
     1203 +        if (mdb_ctf_vread(sr, SMBSRV_SCOPE "smb_request_t",
     1204 +            "mdb_smb_request_t", rqaddr, 0) < 0) {
     1205 +                mdb_warn("failed to read smb_request at %p", rqaddr);
     1206 +                return (DCMD_ERR);
     1207 +        }
     1208 +
     1209 +        /*
     1210 +         * Get the session too, for the IP addresses & ports.
     1211 +         */
     1212 +        ssnaddr = (uintptr_t)sr->session;
     1213 +        ssn = mdb_zalloc(sizeof (*ssn), UM_SLEEP | UM_GC);
     1214 +        if (mdb_ctf_vread(ssn, SMBSRV_SCOPE "smb_session_t",
     1215 +            "mdb_smb_session_t", ssnaddr, 0) < 0) {
     1216 +                mdb_warn("failed to read smb_request at %p", ssnaddr);
     1217 +                return (DCMD_ERR);
     1218 +        }
     1219 +
     1220 +#ifndef _KMDB
     1221 +        if (outfile != NULL) {
     1222 +                rc = smbsrv_pcap_open(outfile);
     1223 +                if (rc != DCMD_OK)
     1224 +                        return (rc);
     1225 +                dump_func = smbsrv_pcap_dump;
     1226 +        } else
     1227 +#endif  /* _KMDB */
     1228 +        {
     1229 +                dump_func = smb_req_dump;
     1230 +        }
     1231 +
     1232 +        if (sr->smb2_messageid != 0)
     1233 +                msgid = sr->smb2_messageid;
     1234 +        else
     1235 +                msgid = sr->smb_mid;
     1236 +        mdb_printf("Dumping request %-?p, Msg_ID 0x%llx\n",
     1237 +            rqaddr, msgid);
     1238 +
     1239 +        if (opts & SMB_RDOPT_COMMAND) {
     1240 +                /*
     1241 +                 * Dump the command, length=max_bytes
     1242 +                 * src=remote, dst=local
     1243 +                 */
     1244 +                rc = dump_func(&sr->command, sr->command.max_bytes,
     1245 +                    (smb_inaddr_t *)&ssn->ipaddr, ssn->s_remote_port,
     1246 +                    (smb_inaddr_t *)&ssn->local_ipaddr, ssn->s_local_port,
     1247 +                    sr->sr_time_submitted, B_FALSE);
     1248 +        }
     1249 +
     1250 +        if ((opts & SMB_RDOPT_REPLY) != 0 &&
     1251 +            rc == DCMD_OK) {
     1252 +                /*
     1253 +                 * Dump the reply, length=chain_offset
     1254 +                 * src=local, dst=remote
     1255 +                 */
     1256 +                rc = dump_func(&sr->reply, sr->reply.chain_offset,
     1257 +                    (smb_inaddr_t *)&ssn->local_ipaddr, ssn->s_local_port,
     1258 +                    (smb_inaddr_t *)&ssn->ipaddr, ssn->s_remote_port,
     1259 +                    sr->sr_time_start, B_TRUE);
     1260 +        }
     1261 +
     1262 +#ifndef _KMDB
     1263 +        if (outfile != NULL) {
     1264 +                smbsrv_pcap_close();
     1265 +        }
     1266 +#endif
     1267 +
     1268 +        return (DCMD_OK);
     1269 +}
     1270 +
     1271 +struct req_dump_state {
     1272 +        int32_t rem_len;
     1273 +};
     1274 +
     1275 +static int
     1276 +smb_req_dump(struct mbuf_chain *mbc, int32_t smb_len,
     1277 +    smb_inaddr_t *src_ip, uint16_t src_port,
     1278 +    smb_inaddr_t *dst_ip, uint16_t dst_port,
     1279 +    hrtime_t rqtime, boolean_t is_reply)
     1280 +{
     1281 +        char    src_buf[INET6_ADDRSTRLEN];
     1282 +        char    dst_buf[INET6_ADDRSTRLEN];
     1283 +        struct req_dump_state dump_state;
     1284 +        _NOTE(ARGUNUSED(rqtime));
     1285 +
     1286 +        if (smb_len < 4)
     1287 +                return (DCMD_OK);
     1288 +        if (mbc->chain == NULL)
     1289 +                return (DCMD_ERR);
     1290 +
     1291 +        smb_inaddr_ntop(src_ip, src_buf, sizeof (src_buf));
     1292 +        smb_inaddr_ntop(dst_ip, dst_buf, sizeof (dst_buf));
     1293 +
     1294 +        mdb_printf("%-8s SRC: %s/%u  DST: %s/%u  LEN: %u\n",
     1295 +            (is_reply) ? "Reply:" : "Call:",
     1296 +            src_buf, src_port, dst_buf, dst_port, smb_len);
     1297 +
     1298 +        /*
     1299 +         * Calling "smb_mbuf_dump" with a wrapper function
     1300 +         * so we can set its length arg, and decrement
     1301 +         * req_dump_state.rem_len as it goes.
     1302 +         */
     1303 +        dump_state.rem_len = smb_len;
     1304 +        if (mdb_pwalk("smb_mbuf_walker", smb_req_dump_m,
     1305 +            &dump_state, (uintptr_t)mbc->chain) == -1) {
     1306 +                mdb_warn("cannot walk smb_req mbuf_chain");
     1307 +                return (DCMD_ERR);
     1308 +        }
     1309 +        return (DCMD_OK);
     1310 +}
     1311 +
     1312 +static int
     1313 +smb_req_dump_m(uintptr_t m_addr, const void *data, void *arg)
     1314 +{
     1315 +        struct req_dump_state *st = arg;
     1316 +        const struct mbuf *m = data;
     1317 +        mdb_arg_t       argv;
     1318 +        int cnt;
     1319 +
     1320 +        cnt = st->rem_len;
     1321 +        if (cnt > m->m_len)
     1322 +                cnt = m->m_len;
     1323 +        if (cnt <= 0)
     1324 +                return (WALK_DONE);
     1325 +
     1326 +        argv.a_type = MDB_TYPE_IMMEDIATE;
     1327 +        argv.a_un.a_val = cnt;
     1328 +        if (mdb_call_dcmd("smb_mbuf_dump", m_addr, 0, 1, &argv) < 0) {
     1329 +                mdb_warn("%p::smb_mbuf_dump failed\n", m_addr);
     1330 +                return (WALK_ERR);
     1331 +        }
     1332 +
     1333 +        st->rem_len -= cnt;
     1334 +        return (WALK_NEXT);
     1335 +}
     1336 +
     1337 +/*
1022 1338   * *****************************************************************************
1023 1339   * ****************************** smb_user_t ***********************************
1024 1340   * *****************************************************************************
1025 1341   */
     1342 +typedef struct mdb_smb_user {
     1343 +        smb_user_state_t        u_state;
1026 1344  
1027      -static const char *smb_user_state[SMB_USER_STATE_SENTINEL] =
1028      -{
1029      -        "LOGGING_ON",
1030      -        "LOGGED_ON",
1031      -        "LOGGING_OFF",
1032      -        "LOGGED_OFF"
     1345 +        struct smb_server       *u_server;
     1346 +        smb_session_t           *u_session;
     1347 +
     1348 +        uint16_t                u_name_len;
     1349 +        char                    *u_name;
     1350 +        uint16_t                u_domain_len;
     1351 +        char                    *u_domain;
     1352 +        time_t                  u_logon_time;
     1353 +        cred_t                  *u_cred;
     1354 +        cred_t                  *u_privcred;
     1355 +
     1356 +        uint64_t                u_ssnid;
     1357 +        uint32_t                u_refcnt;
     1358 +        uint32_t                u_flags;
     1359 +        uint32_t                u_privileges;
     1360 +        uint16_t                u_uid;
     1361 +} mdb_smb_user_t;
     1362 +
     1363 +static const mdb_bitmask_t
     1364 +user_flag_bits[] = {
     1365 +        { "ANON",
     1366 +            SMB_USER_FLAG_ANON,
     1367 +            SMB_USER_FLAG_ANON },
     1368 +        { "GUEST",
     1369 +            SMB_USER_FLAG_GUEST,
     1370 +            SMB_USER_FLAG_GUEST },
     1371 +        { "POWER_USER",
     1372 +            SMB_USER_FLAG_POWER_USER,
     1373 +            SMB_USER_FLAG_POWER_USER },
     1374 +        { "BACKUP_OP",
     1375 +            SMB_USER_FLAG_BACKUP_OPERATOR,
     1376 +            SMB_USER_FLAG_BACKUP_OPERATOR },
     1377 +        { "ADMIN",
     1378 +            SMB_USER_FLAG_ADMIN,
     1379 +            SMB_USER_FLAG_ADMIN },
     1380 +        { NULL, 0, 0 }
1033 1381  };
1034 1382  
     1383 +static const mdb_bitmask_t
     1384 +user_priv_bits[] = {
     1385 +        /*
     1386 +         * Old definitions of these bits, for when we're
     1387 +         * looking at an older core file.  These happen to
     1388 +         * have no overlap with the current definitions.
     1389 +         */
     1390 +        { "TAKE_OWNER", 1, 1 },
     1391 +        { "BACKUP",     2, 2 },
     1392 +        { "RESTORE",    4, 4 },
     1393 +        { "SECURITY",   8, 8 },
     1394 +        /*
     1395 +         * Current definitions
     1396 +         */
     1397 +        { "SECURITY",
     1398 +            SMB_USER_PRIV_SECURITY,
     1399 +            SMB_USER_PRIV_SECURITY },
     1400 +        { "TAKE_OWNER",
     1401 +            SMB_USER_PRIV_TAKE_OWNERSHIP,
     1402 +            SMB_USER_PRIV_TAKE_OWNERSHIP },
     1403 +        { "BACKUP",
     1404 +            SMB_USER_PRIV_BACKUP,
     1405 +            SMB_USER_PRIV_BACKUP },
     1406 +        { "RESTORE",
     1407 +            SMB_USER_PRIV_RESTORE,
     1408 +            SMB_USER_PRIV_RESTORE },
     1409 +        { "CHANGE_NOTIFY",
     1410 +            SMB_USER_PRIV_CHANGE_NOTIFY,
     1411 +            SMB_USER_PRIV_CHANGE_NOTIFY },
     1412 +        { NULL, 0, 0 }
     1413 +};
     1414 +
1035 1415  static void
1036      -smb_dcmd_user_help(void)
     1416 +smbuser_help(void)
1037 1417  {
1038 1418          mdb_printf(
1039 1419              "Display the contents of smb_user_t, with optional filtering.\n\n");
1040 1420          (void) mdb_dec_indent(2);
1041 1421          mdb_printf("%<b>OPTIONS%</b>\n");
1042 1422          (void) mdb_inc_indent(2);
1043 1423          mdb_printf(
1044 1424              "-v\tDisplay verbose smb_user information\n");
1045 1425  }
1046 1426  
1047 1427  static int
1048      -smb_dcmd_user(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     1428 +smbuser_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1049 1429  {
1050 1430          uint_t          opts;
1051 1431  
1052 1432          if (smb_dcmd_getopt(&opts, argc, argv))
1053 1433                  return (DCMD_USAGE);
1054 1434  
1055 1435          if (!(flags & DCMD_ADDRSPEC)) {
1056 1436                  opts |= SMB_OPT_USER;
1057 1437                  opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST);
1058 1438                  return (smb_obj_list("smb_user", opts, flags));
1059 1439          }
1060 1440  
1061 1441          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_USER)) ||
1062 1442              !(opts & SMB_OPT_WALK)) {
1063      -                smb_user_t      *user;
     1443 +                mdb_smb_user_t  *user;
1064 1444                  char            *account;
1065 1445  
1066      -                user = mdb_alloc(sizeof (*user), UM_SLEEP | UM_GC);
1067      -                if (mdb_vread(user, sizeof (*user), addr) == -1) {
     1446 +                user = mdb_zalloc(sizeof (*user), UM_SLEEP | UM_GC);
     1447 +                if (mdb_ctf_vread(user, SMBSRV_SCOPE "smb_user_t",
     1448 +                    "mdb_smb_user_t", addr, 0) < 0) {
1068 1449                          mdb_warn("failed to read smb_user at %p", addr);
1069 1450                          return (DCMD_ERR);
1070 1451                  }
1071 1452                  account = mdb_zalloc(user->u_domain_len + user->u_name_len + 2,
1072 1453                      UM_SLEEP | UM_GC);
1073 1454  
1074 1455                  if (user->u_domain_len)
1075 1456                          (void) mdb_vread(account, user->u_domain_len,
1076 1457                              (uintptr_t)user->u_domain);
1077 1458  
1078 1459                  strcat(account, "\\");
1079 1460  
1080 1461                  if (user->u_name_len)
1081 1462                          (void) mdb_vread(account + strlen(account),
1082 1463                              user->u_name_len, (uintptr_t)user->u_name);
1083 1464  
1084 1465                  if (opts & SMB_OPT_VERBOSE) {
1085      -                        const char      *state;
     1466 +                        char            state[40];
1086 1467  
1087      -                        if (user->u_state >= SMB_USER_STATE_SENTINEL)
1088      -                                state = "INVALID";
1089      -                        else
1090      -                                state = smb_user_state[user->u_state];
     1468 +                        get_enum(state, sizeof (state),
     1469 +                            "smb_user_state_t", user->u_state,
     1470 +                            "SMB_USER_STATE_");
1091 1471  
1092 1472                          mdb_printf("%<b>%<u>SMB user information (%p):"
1093 1473                              "%</u>%</b>\n", addr);
1094 1474                          mdb_printf("UID: %u\n", user->u_uid);
     1475 +                        mdb_printf("SSNID: %llx\n", user->u_ssnid);
1095 1476                          mdb_printf("State: %d (%s)\n", user->u_state, state);
1096      -                        mdb_printf("Flags: 0x%08x\n", user->u_flags);
1097      -                        mdb_printf("Privileges: 0x%08x\n", user->u_privileges);
     1477 +                        mdb_printf("Flags: 0x%08x <%b>\n", user->u_flags,
     1478 +                            user->u_flags, user_flag_bits);
     1479 +                        mdb_printf("Privileges: 0x%08x <%b>\n",
     1480 +                            user->u_privileges,
     1481 +                            user->u_privileges, user_priv_bits);
1098 1482                          mdb_printf("Credential: %p\n", user->u_cred);
1099 1483                          mdb_printf("Reference Count: %d\n", user->u_refcnt);
1100 1484                          mdb_printf("User Account: %s\n\n", account);
1101 1485                  } else {
1102 1486                          if (DCMD_HDRSPEC(flags))
1103 1487                                  mdb_printf(
1104 1488                                      "%<b>%<u>%?-s "
1105 1489                                      "%-5s "
     1490 +                                    "%-16s "
1106 1491                                      "%-32s%</u>%</b>\n",
1107      -                                    "USER", "UID", "ACCOUNT");
     1492 +                                    "USER", "UID", "SSNID", "ACCOUNT");
1108 1493  
1109      -                        mdb_printf("%-?p %-5u %-32s\n", addr, user->u_uid,
1110      -                            account);
     1494 +                        mdb_printf("%-?p %-5u %-16llx %-32s\n",
     1495 +                            addr, user->u_uid, user->u_ssnid, account);
1111 1496                  }
1112 1497          }
1113 1498          return (DCMD_OK);
1114 1499  }
1115 1500  
1116 1501  /*
1117 1502   * *****************************************************************************
1118 1503   * ****************************** smb_tree_t ***********************************
1119 1504   * *****************************************************************************
1120 1505   */
1121 1506  
1122      -static const char *smb_tree_state[SMB_TREE_STATE_SENTINEL] =
     1507 +typedef struct mdb_smb_tree {
     1508 +        smb_tree_state_t        t_state;
     1509 +
     1510 +        smb_node_t              *t_snode;
     1511 +        smb_llist_t             t_ofile_list;
     1512 +        smb_llist_t             t_odir_list;
     1513 +
     1514 +        uint32_t                t_refcnt;
     1515 +        uint32_t                t_flags;
     1516 +        int32_t                 t_res_type;
     1517 +        uint16_t                t_tid;
     1518 +        uint16_t                t_umask;
     1519 +        char                    t_sharename[MAXNAMELEN];
     1520 +        char                    t_resource[MAXPATHLEN];
     1521 +        char                    t_typename[SMB_TYPENAMELEN];
     1522 +        char                    t_volume[SMB_VOLNAMELEN];
     1523 +} mdb_smb_tree_t;
     1524 +
     1525 +static int
     1526 +smb_tree_exp_off_ofile_list(void)
1123 1527  {
1124      -        "CONNECTED",
1125      -        "DISCONNECTING",
1126      -        "DISCONNECTED"
1127      -};
     1528 +        int tf_off, ll_off;
1128 1529  
     1530 +        /* OFFSETOF(smb_tree_t, t_ofile_list.ll_list); */
     1531 +        GET_OFFSET(tf_off, smb_tree_t, t_ofile_list);
     1532 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     1533 +        return (tf_off + ll_off);
     1534 +}
     1535 +
     1536 +static int
     1537 +smb_tree_exp_off_odir_list(void)
     1538 +{
     1539 +        int td_off, ll_off;
     1540 +
     1541 +        /* OFFSETOF(smb_tree_t, t_odir_list.ll_list); */
     1542 +        GET_OFFSET(td_off, smb_tree_t, t_odir_list);
     1543 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     1544 +        return (td_off + ll_off);
     1545 +}
     1546 +
1129 1547  /*
1130 1548   * List of objects that can be expanded under a tree structure.
1131 1549   */
1132 1550  static const smb_exp_t smb_tree_exp[] =
1133 1551  {
1134 1552          { SMB_OPT_OFILE,
1135      -            OFFSETOF(smb_tree_t, t_ofile_list.ll_list),
     1553 +            smb_tree_exp_off_ofile_list,
1136 1554              "smbofile", "smb_ofile"},
1137 1555          { SMB_OPT_ODIR,
1138      -            OFFSETOF(smb_tree_t, t_odir_list.ll_list),
     1556 +            smb_tree_exp_off_odir_list,
1139 1557              "smbodir", "smb_odir"},
1140 1558          { 0, 0, NULL, NULL}
1141 1559  };
1142 1560  
     1561 +static const mdb_bitmask_t
     1562 +tree_flag_bits[] = {
     1563 +        { "RO",
     1564 +            SMB_TREE_READONLY,
     1565 +            SMB_TREE_READONLY },
     1566 +        { "ACLS",
     1567 +            SMB_TREE_SUPPORTS_ACLS,
     1568 +            SMB_TREE_SUPPORTS_ACLS },
     1569 +        { "STREAMS",
     1570 +            SMB_TREE_STREAMS,
     1571 +            SMB_TREE_STREAMS },
     1572 +        { "CI",
     1573 +            SMB_TREE_CASEINSENSITIVE,
     1574 +            SMB_TREE_CASEINSENSITIVE },
     1575 +        { "NO_CS",
     1576 +            SMB_TREE_NO_CASESENSITIVE,
     1577 +            SMB_TREE_NO_CASESENSITIVE },
     1578 +        { "NO_EXPORT",
     1579 +            SMB_TREE_NO_EXPORT,
     1580 +            SMB_TREE_NO_EXPORT },
     1581 +        { "OPLOCKS",
     1582 +            SMB_TREE_OPLOCKS,
     1583 +            SMB_TREE_OPLOCKS },
     1584 +        { "SHORTNAMES",
     1585 +            SMB_TREE_SHORTNAMES,
     1586 +            SMB_TREE_SHORTNAMES },
     1587 +        { "XVATTR",
     1588 +            SMB_TREE_XVATTR,
     1589 +            SMB_TREE_XVATTR },
     1590 +        { "DIRENTFLAGS",
     1591 +            SMB_TREE_DIRENTFLAGS,
     1592 +            SMB_TREE_DIRENTFLAGS },
     1593 +        { "ACL_CR",
     1594 +            SMB_TREE_ACLONCREATE,
     1595 +            SMB_TREE_ACLONCREATE },
     1596 +        { "ACEMASK",
     1597 +            SMB_TREE_ACEMASKONACCESS,
     1598 +            SMB_TREE_ACEMASKONACCESS },
     1599 +        { "NFS_MNT",
     1600 +            SMB_TREE_NFS_MOUNTED,
     1601 +            SMB_TREE_NFS_MOUNTED },
     1602 +        { "UNICODE",
     1603 +            SMB_TREE_UNICODE_ON_DISK,
     1604 +            SMB_TREE_UNICODE_ON_DISK },
     1605 +        { "CATIA",
     1606 +            SMB_TREE_CATIA,
     1607 +            SMB_TREE_CATIA },
     1608 +        { "ABE",
     1609 +            SMB_TREE_ABE,
     1610 +            SMB_TREE_ABE },
     1611 +        { "QUOTA",
     1612 +            SMB_TREE_QUOTA,
     1613 +            SMB_TREE_QUOTA },
     1614 +        { "DFSROOT",
     1615 +            SMB_TREE_DFSROOT,
     1616 +            SMB_TREE_DFSROOT },
     1617 +        { "SPARSE",
     1618 +            SMB_TREE_SPARSE,
     1619 +            SMB_TREE_SPARSE },
     1620 +        { "XMOUNTS",
     1621 +            SMB_TREE_TRAVERSE_MOUNTS,
     1622 +            SMB_TREE_TRAVERSE_MOUNTS },
     1623 +        { "FORCE_L2_OPLOCK",
     1624 +            SMB_TREE_FORCE_L2_OPLOCK,
     1625 +            SMB_TREE_FORCE_L2_OPLOCK },
     1626 +        { "CA",
     1627 +            SMB_TREE_CA,
     1628 +            SMB_TREE_CA },
     1629 +        { NULL, 0, 0 }
     1630 +};
     1631 +
1143 1632  static void
1144      -smb_dcmd_tree_help(void)
     1633 +smbtree_help(void)
1145 1634  {
1146 1635          mdb_printf(
1147 1636              "Display the contents of smb_tree_t, with optional filtering.\n\n");
1148 1637          (void) mdb_dec_indent(2);
1149 1638          mdb_printf("%<b>OPTIONS%</b>\n");
1150 1639          (void) mdb_inc_indent(2);
1151 1640          mdb_printf(
1152 1641              "-v\tDisplay verbose smb_tree information\n"
1153 1642              "-d\tDisplay the list of smb_odirs attached\n"
1154 1643              "-f\tDisplay the list of smb_ofiles attached\n");
1155 1644  }
1156 1645  
1157 1646  static int
1158      -smb_dcmd_tree(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     1647 +smbtree_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1159 1648  {
1160 1649          uint_t          opts;
1161 1650          ulong_t         indent = 0;
1162 1651  
1163 1652          if (smb_dcmd_getopt(&opts, argc, argv))
1164 1653                  return (DCMD_USAGE);
1165 1654  
1166 1655          if (!(flags & DCMD_ADDRSPEC)) {
1167 1656                  opts |= SMB_OPT_TREE;
1168 1657                  opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
1169 1658                      SMB_OPT_USER);
1170 1659                  return (smb_obj_list("smb_tree", opts, flags));
1171 1660          }
1172 1661  
1173 1662          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_TREE)) ||
1174 1663              !(opts & SMB_OPT_WALK)) {
1175      -                smb_tree_t      *tree;
     1664 +                mdb_smb_tree_t *tree;
1176 1665  
1177 1666                  indent = SMB_DCMD_INDENT;
1178 1667  
1179      -                tree = mdb_alloc(sizeof (*tree), UM_SLEEP | UM_GC);
1180      -                if (mdb_vread(tree, sizeof (*tree), addr) == -1) {
     1668 +                tree = mdb_zalloc(sizeof (*tree), UM_SLEEP | UM_GC);
     1669 +                if (mdb_ctf_vread(tree, SMBSRV_SCOPE "smb_tree_t",
     1670 +                    "mdb_smb_tree_t", addr, 0) < 0) {
1181 1671                          mdb_warn("failed to read smb_tree at %p", addr);
1182 1672                          return (DCMD_ERR);
1183 1673                  }
1184 1674                  if (opts & SMB_OPT_VERBOSE) {
1185      -                        const char      *state;
     1675 +                        char            state[40];
1186 1676  
1187      -                        if (tree->t_state >= SMB_TREE_STATE_SENTINEL)
1188      -                                state = "INVALID";
1189      -                        else
1190      -                                state = smb_tree_state[tree->t_state];
     1677 +                        get_enum(state, sizeof (state),
     1678 +                            "smb_tree_state_t", tree->t_state,
     1679 +                            "SMB_TREE_STATE_");
1191 1680  
1192 1681                          mdb_printf("%<b>%<u>SMB tree information (%p):"
1193 1682                              "%</u>%</b>\n\n", addr);
1194 1683                          mdb_printf("TID: %04x\n", tree->t_tid);
1195 1684                          mdb_printf("State: %d (%s)\n", tree->t_state, state);
1196 1685                          mdb_printf("Share: %s\n", tree->t_sharename);
1197 1686                          mdb_printf("Resource: %s\n", tree->t_resource);
1198 1687                          mdb_printf("Type: %s\n", tree->t_typename);
1199 1688                          mdb_printf("Volume: %s\n", tree->t_volume);
1200 1689                          mdb_printf("Umask: %04x\n", tree->t_umask);
1201      -                        mdb_printf("Flags: %08x\n", tree->t_flags);
     1690 +                        mdb_printf("Flags: %08x <%b>\n", tree->t_flags,
     1691 +                            tree->t_flags, tree_flag_bits);
1202 1692                          mdb_printf("SMB Node: %llx\n", tree->t_snode);
1203 1693                          mdb_printf("Reference Count: %d\n\n", tree->t_refcnt);
1204 1694                  } else {
1205 1695                          if (DCMD_HDRSPEC(flags))
1206 1696                                  mdb_printf(
1207 1697                                      "%<b>%<u>%-?s %-5s %-16s %-32s%</u>%</b>\n",
1208 1698                                      "TREE", "TID", "SHARE NAME", "RESOURCE");
1209 1699  
1210 1700                          mdb_printf("%-?p %-5u %-16s %-32s\n", addr,
1211 1701                              tree->t_tid, tree->t_sharename, tree->t_resource);
↓ open down ↓ 3 lines elided ↑ open up ↑
1215 1705                  return (DCMD_ERR);
1216 1706          return (DCMD_OK);
1217 1707  }
1218 1708  
1219 1709  /*
1220 1710   * *****************************************************************************
1221 1711   * ****************************** smb_odir_t ***********************************
1222 1712   * *****************************************************************************
1223 1713   */
1224 1714  
1225      -static const char *smb_odir_state[SMB_ODIR_STATE_SENTINEL] =
1226      -{
1227      -        "OPEN",
1228      -        "IN_USE",
1229      -        "CLOSING",
1230      -        "CLOSED"
1231      -};
     1715 +typedef struct mdb_smb_odir {
     1716 +        smb_odir_state_t        d_state;
     1717 +        smb_session_t           *d_session;
     1718 +        smb_user_t              *d_user;
     1719 +        smb_tree_t              *d_tree;
     1720 +        smb_node_t              *d_dnode;
     1721 +        uint16_t                d_odid;
     1722 +        uint32_t                d_refcnt;
     1723 +        char                    d_pattern[MAXNAMELEN];
     1724 +} mdb_smb_odir_t;
1232 1725  
1233 1726  static int
1234      -smb_dcmd_odir(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     1727 +smbodir_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1235 1728  {
1236 1729          uint_t          opts;
1237 1730  
1238 1731          if (smb_dcmd_getopt(&opts, argc, argv))
1239 1732                  return (DCMD_USAGE);
1240 1733  
1241 1734          if (!(flags & DCMD_ADDRSPEC)) {
1242 1735                  opts |= SMB_OPT_ODIR;
1243 1736                  opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
1244 1737                      SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_OFILE);
1245 1738                  return (smb_obj_list("smb_odir", opts, flags));
1246 1739          }
1247 1740  
1248 1741          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_ODIR)) ||
1249 1742              !(opts & SMB_OPT_WALK)) {
1250      -                smb_odir_t      *od;
     1743 +                mdb_smb_odir_t *od;
1251 1744  
1252      -                od = mdb_alloc(sizeof (*od), UM_SLEEP | UM_GC);
1253      -                if (mdb_vread(od, sizeof (*od), addr) == -1) {
     1745 +                od = mdb_zalloc(sizeof (*od), UM_SLEEP | UM_GC);
     1746 +                if (mdb_ctf_vread(od, SMBSRV_SCOPE "smb_odir_t",
     1747 +                    "mdb_smb_odir_t", addr, 0) < 0) {
1254 1748                          mdb_warn("failed to read smb_odir at %p", addr);
1255 1749                          return (DCMD_ERR);
1256 1750                  }
1257 1751                  if (opts & SMB_OPT_VERBOSE) {
1258      -                        const char      *state;
     1752 +                        char            state[40];
1259 1753  
1260      -                        if (od->d_state >= SMB_ODIR_STATE_SENTINEL)
1261      -                                state = "INVALID";
1262      -                        else
1263      -                                state = smb_odir_state[od->d_state];
     1754 +                        get_enum(state, sizeof (state),
     1755 +                            "smb_odir_state_t", od->d_state,
     1756 +                            "SMB_ODIR_STATE_");
1264 1757  
1265 1758                          mdb_printf(
1266 1759                              "%<b>%<u>SMB odir information (%p):%</u>%</b>\n\n",
1267 1760                              addr);
1268 1761                          mdb_printf("State: %d (%s)\n", od->d_state, state);
1269 1762                          mdb_printf("SID: %u\n", od->d_odid);
1270 1763                          mdb_printf("User: %p\n", od->d_user);
1271 1764                          mdb_printf("Tree: %p\n", od->d_tree);
1272 1765                          mdb_printf("Reference Count: %d\n", od->d_refcnt);
1273 1766                          mdb_printf("Pattern: %s\n", od->d_pattern);
↓ open down ↓ 13 lines elided ↑ open up ↑
1287 1780          }
1288 1781          return (DCMD_OK);
1289 1782  }
1290 1783  
1291 1784  /*
1292 1785   * *****************************************************************************
1293 1786   * ****************************** smb_ofile_t **********************************
1294 1787   * *****************************************************************************
1295 1788   */
1296 1789  
1297      -static const char *smb_ofile_state[SMB_OFILE_STATE_SENTINEL] =
1298      -{
1299      -        "OPEN",
1300      -        "CLOSING",
1301      -        "CLOSED"
     1790 +typedef struct mdb_smb_ofile {
     1791 +        smb_ofile_state_t       f_state;
     1792 +
     1793 +        struct smb_server       *f_server;
     1794 +        smb_session_t           *f_session;
     1795 +        smb_user_t              *f_user;
     1796 +        smb_tree_t              *f_tree;
     1797 +        smb_node_t              *f_node;
     1798 +        smb_odir_t              *f_odir;
     1799 +        smb_opipe_t             *f_pipe;
     1800 +
     1801 +        uint32_t                f_uniqid;
     1802 +        uint32_t                f_refcnt;
     1803 +        uint32_t                f_flags;
     1804 +        uint32_t                f_granted_access;
     1805 +        uint32_t                f_share_access;
     1806 +
     1807 +        uint16_t                f_fid;
     1808 +        uint16_t                f_ftype;
     1809 +        uint64_t                f_llf_pos;
     1810 +        int                     f_mode;
     1811 +        cred_t                  *f_cr;
     1812 +        pid_t                   f_pid;
     1813 +        uintptr_t               f_lease;
     1814 +        smb_dh_vers_t           dh_vers;
     1815 +} mdb_smb_ofile_t;
     1816 +
     1817 +static const mdb_bitmask_t
     1818 +ofile_flag_bits[] = {
     1819 +        { "RO", 1, 1 }, /* old SMB_OFLAGS_READONLY */
     1820 +        { "EXEC",
     1821 +            SMB_OFLAGS_EXECONLY,
     1822 +            SMB_OFLAGS_EXECONLY },
     1823 +        { "DELETE",
     1824 +            SMB_OFLAGS_SET_DELETE_ON_CLOSE,
     1825 +            SMB_OFLAGS_SET_DELETE_ON_CLOSE },
     1826 +        { "POS_VALID",
     1827 +            SMB_OFLAGS_LLF_POS_VALID,
     1828 +            SMB_OFLAGS_LLF_POS_VALID },
     1829 +        { NULL, 0, 0}
1302 1830  };
1303 1831  
     1832 +static const mdb_bitmask_t
     1833 +smb_sharemode_bits[] = {
     1834 +        { "READ",
     1835 +            FILE_SHARE_READ,
     1836 +            FILE_SHARE_READ },
     1837 +        { "WRITE",
     1838 +            FILE_SHARE_WRITE,
     1839 +            FILE_SHARE_WRITE },
     1840 +        { "DELETE",
     1841 +            FILE_SHARE_DELETE,
     1842 +            FILE_SHARE_DELETE },
     1843 +        { NULL, 0, 0}
     1844 +};
     1845 +
1304 1846  static int
1305      -smb_dcmd_ofile(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     1847 +smbofile_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1306 1848  {
1307 1849          uint_t          opts;
1308 1850  
1309 1851          if (smb_dcmd_getopt(&opts, argc, argv))
1310 1852                  return (DCMD_USAGE);
1311 1853  
1312 1854          if (!(flags & DCMD_ADDRSPEC)) {
1313 1855                  opts |= SMB_OPT_OFILE;
1314 1856                  opts &= ~(SMB_OPT_SERVER | SMB_OPT_SESSION | SMB_OPT_REQUEST |
1315 1857                      SMB_OPT_USER | SMB_OPT_TREE | SMB_OPT_ODIR);
1316 1858                  return (smb_obj_list("smb_ofile", opts, flags));
1317 1859          }
1318 1860  
1319 1861          if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_OFILE)) ||
1320 1862              !(opts & SMB_OPT_WALK)) {
1321      -                smb_ofile_t     *of;
     1863 +                mdb_smb_ofile_t *of;
1322 1864  
1323      -                of = mdb_alloc(sizeof (*of), UM_SLEEP | UM_GC);
1324      -                if (mdb_vread(of, sizeof (*of), addr) == -1) {
     1865 +                of = mdb_zalloc(sizeof (*of), UM_SLEEP | UM_GC);
     1866 +                if (mdb_ctf_vread(of, SMBSRV_SCOPE "smb_ofile_t",
     1867 +                    "mdb_smb_ofile_t", addr, 0) < 0) {
1325 1868                          mdb_warn("failed to read smb_ofile at %p", addr);
1326 1869                          return (DCMD_ERR);
1327 1870                  }
1328 1871                  if (opts & SMB_OPT_VERBOSE) {
1329      -                        const char      *state;
     1872 +                        char            state[40];
     1873 +                        char            durable[40];
1330 1874  
1331      -                        if (of->f_state >= SMB_OFILE_STATE_SENTINEL)
1332      -                                state = "INVALID";
1333      -                        else
1334      -                                state = smb_ofile_state[of->f_state];
     1875 +                        get_enum(state, sizeof (state),
     1876 +                            "smb_ofile_state_t", of->f_state,
     1877 +                            "SMB_OFILE_STATE_");
1335 1878  
     1879 +                        get_enum(durable, sizeof (durable),
     1880 +                            "smb_dh_vers_t", of->dh_vers,
     1881 +                            "SMB2_");
     1882 +
1336 1883                          mdb_printf(
1337 1884                              "%<b>%<u>SMB ofile information (%p):%</u>%</b>\n\n",
1338 1885                              addr);
1339 1886                          mdb_printf("FID: %u\n", of->f_fid);
1340 1887                          mdb_printf("State: %d (%s)\n", of->f_state, state);
     1888 +                        mdb_printf("DH Type: %d (%s)\n", of->dh_vers,
     1889 +                            durable);
     1890 +                        mdb_printf("Lease: %p\n", of->f_lease);
1341 1891                          mdb_printf("SMB Node: %p\n", of->f_node);
1342 1892                          mdb_printf("LLF Offset: 0x%llx (%s)\n",
1343 1893                              of->f_llf_pos,
1344 1894                              ((of->f_flags & SMB_OFLAGS_LLF_POS_VALID) ?
1345 1895                              "Valid" : "Invalid"));
1346      -                        mdb_printf("Flags: 0x%08x\n", of->f_flags);
     1896 +                        mdb_printf("Flags: 0x%08x <%b>\n", of->f_flags,
     1897 +                            of->f_flags, ofile_flag_bits);
     1898 +                        mdb_printf("Granted Acc.: 0x%08x <%b>\n",
     1899 +                            of->f_granted_access,
     1900 +                            of->f_granted_access, nt_access_bits);
     1901 +                        mdb_printf("Share Mode: 0x%08x <%b>\n",
     1902 +                            of->f_share_access,
     1903 +                            of->f_share_access, smb_sharemode_bits);
1347 1904                          mdb_printf("User: %p\n", of->f_user);
1348 1905                          mdb_printf("Tree: %p\n", of->f_tree);
1349 1906                          mdb_printf("Credential: %p\n\n", of->f_cr);
1350 1907                  } else {
1351 1908                          if (DCMD_HDRSPEC(flags))
1352 1909                                  mdb_printf(
1353 1910                                      "%<b>%<u>%-?s "
1354 1911                                      "%-5s "
1355 1912                                      "%-?s "
     1913 +                                    "%-?s "
     1914 +                                    "%-?s "
     1915 +                                    "%</u>%</b>\n",
     1916 +                                    "OFILE",
     1917 +                                    "FID",
     1918 +                                    "NODE",
     1919 +                                    "CRED",
     1920 +                                    "LEASE");
     1921 +
     1922 +                        mdb_printf("%?p %-5u %-p %-p %-p\n", addr,
     1923 +                            of->f_fid, of->f_node, of->f_cr, of->f_lease);
     1924 +                }
     1925 +        }
     1926 +        return (DCMD_OK);
     1927 +}
     1928 +
     1929 +static int
     1930 +smbdurable_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     1931 +{
     1932 +        mdb_smb_server_t *sv;
     1933 +
     1934 +        if (!(flags & DCMD_ADDRSPEC)) {
     1935 +                mdb_printf("require address of an smb_server_t\n");
     1936 +                return (WALK_ERR);
     1937 +        }
     1938 +
     1939 +        sv = mdb_zalloc(sizeof (*sv), UM_SLEEP | UM_GC);
     1940 +        if (mdb_ctf_vread(sv, SMBSRV_SCOPE "smb_server_t",
     1941 +            "mdb_smb_server_t", addr, 0) < 0) {
     1942 +                mdb_warn("failed to read smb_server at %p", addr);
     1943 +                return (DCMD_ERR);
     1944 +        }
     1945 +
     1946 +        if (mdb_pwalk_dcmd("smb_hash_walker", "smbofile",
     1947 +            argc, argv, (uintptr_t)sv->sv_persistid_ht) == -1) {
     1948 +                mdb_warn("failed to walk 'smb_ofile'");
     1949 +                return (DCMD_ERR);
     1950 +        }
     1951 +        return (DCMD_OK);
     1952 +}
     1953 +
     1954 +static int
     1955 +smb_hash_walk_init(mdb_walk_state_t *wsp)
     1956 +{
     1957 +        smb_hash_t hash;
     1958 +        int ll_off, sll_off, i;
     1959 +        uintptr_t addr = wsp->walk_addr;
     1960 +
     1961 +        if (addr == NULL) {
     1962 +                mdb_printf("require address of an smb_hash_t\n");
     1963 +                return (WALK_ERR);
     1964 +        }
     1965 +
     1966 +        GET_OFFSET(sll_off, smb_bucket_t, b_list);
     1967 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     1968 +
     1969 +        if (mdb_vread(&hash, sizeof (hash), addr) == -1) {
     1970 +                mdb_warn("failed to read smb_hash_t at %p", addr);
     1971 +                return (WALK_ERR);
     1972 +        }
     1973 +
     1974 +        for (i = 0; i < hash.num_buckets; i++) {
     1975 +                wsp->walk_addr = (uintptr_t)hash.buckets +
     1976 +                    (i * sizeof (smb_bucket_t)) + sll_off + ll_off;
     1977 +                if (mdb_layered_walk("list", wsp) == -1) {
     1978 +                        mdb_warn("failed to walk 'list'");
     1979 +                        return (WALK_ERR);
     1980 +                }
     1981 +        }
     1982 +
     1983 +        return (WALK_NEXT);
     1984 +}
     1985 +
     1986 +static int
     1987 +smb_hash_walk_step(mdb_walk_state_t *wsp)
     1988 +{
     1989 +        return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
     1990 +            wsp->walk_cbdata));
     1991 +}
     1992 +
     1993 +static int
     1994 +smbhashstat_cb(uintptr_t addr, const void *data, void *varg)
     1995 +{
     1996 +        _NOTE(ARGUNUSED(varg))
     1997 +        const smb_bucket_t *bucket = data;
     1998 +
     1999 +        mdb_printf("%-?p ", addr);      /* smb_bucket_t */
     2000 +        mdb_printf("%-6u ", bucket->b_list.ll_count);
     2001 +        mdb_printf("%-16u", bucket->b_max_seen);
     2002 +        mdb_printf("%-u\n", (bucket->b_list.ll_wrop +
     2003 +            bucket->b_list.ll_count) / 2);
     2004 +        return (WALK_NEXT);
     2005 +}
     2006 +
     2007 +static int
     2008 +smbhashstat_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     2009 +{
     2010 +        _NOTE(ARGUNUSED(argc, argv))
     2011 +        if (!(flags & DCMD_ADDRSPEC)) {
     2012 +                mdb_printf("require address of an smb_hash_t\n");
     2013 +                return (DCMD_USAGE);
     2014 +        }
     2015 +
     2016 +        if (DCMD_HDRSPEC(flags)) {
     2017 +                mdb_printf(
     2018 +                    "%<b>%<u>"
     2019 +                    "%-?s "
     2020 +                    "%-6s "
     2021 +                    "%-16s"
     2022 +                    "%-s"
     2023 +                    "%</u>%</b>\n",
     2024 +                    "smb_bucket_t", "count", "largest seen", "inserts");
     2025 +        }
     2026 +
     2027 +        if (mdb_pwalk("smb_hashstat_walker", smbhashstat_cb,
     2028 +            NULL, addr) == -1) {
     2029 +                mdb_warn("failed to walk 'smb_ofile'");
     2030 +                return (DCMD_ERR);
     2031 +        }
     2032 +        return (DCMD_OK);
     2033 +}
     2034 +
     2035 +typedef struct smb_hash_wd {
     2036 +        smb_bucket_t    *bucket;
     2037 +        smb_bucket_t    *end;
     2038 +} smb_hash_wd_t;
     2039 +
     2040 +static int
     2041 +smb_hashstat_walk_init(mdb_walk_state_t *wsp)
     2042 +{
     2043 +        int sll_off, ll_off;
     2044 +        smb_hash_t hash;
     2045 +        smb_bucket_t *buckets;
     2046 +        uintptr_t addr = wsp->walk_addr;
     2047 +        uint32_t arr_sz;
     2048 +        smb_hash_wd_t *wd;
     2049 +
     2050 +        if (addr == NULL) {
     2051 +                mdb_printf("require address of an smb_hash_t\n");
     2052 +                return (WALK_ERR);
     2053 +        }
     2054 +
     2055 +        GET_OFFSET(sll_off, smb_bucket_t, b_list);
     2056 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     2057 +
     2058 +        if (mdb_vread(&hash, sizeof (hash), addr) == -1) {
     2059 +                mdb_warn("failed to read smb_hash_t at %p", addr);
     2060 +                return (WALK_ERR);
     2061 +        }
     2062 +
     2063 +        arr_sz = hash.num_buckets * sizeof (smb_bucket_t);
     2064 +        buckets = mdb_alloc(arr_sz, UM_SLEEP | UM_GC);
     2065 +        if (mdb_vread(buckets, arr_sz, (uintptr_t)hash.buckets) == -1) {
     2066 +                mdb_warn("failed to read smb_bucket_t array at %p",
     2067 +                    hash.buckets);
     2068 +                return (WALK_ERR);
     2069 +        }
     2070 +
     2071 +        wd = mdb_alloc(sizeof (*wd), UM_SLEEP | UM_GC);
     2072 +        wd->bucket = buckets;
     2073 +        wd->end = buckets + hash.num_buckets;
     2074 +
     2075 +        wsp->walk_addr = (uintptr_t)hash.buckets;
     2076 +        wsp->walk_data = wd;
     2077 +
     2078 +        return (WALK_NEXT);
     2079 +}
     2080 +
     2081 +static int
     2082 +smb_hashstat_walk_step(mdb_walk_state_t *wsp)
     2083 +{
     2084 +        int rc;
     2085 +        smb_hash_wd_t *wd = wsp->walk_data;
     2086 +
     2087 +        if (wd->bucket >= wd->end)
     2088 +                return (WALK_DONE);
     2089 +
     2090 +        rc = wsp->walk_callback(wsp->walk_addr, wd->bucket++,
     2091 +            wsp->walk_cbdata);
     2092 +
     2093 +        wsp->walk_addr += sizeof (smb_bucket_t);
     2094 +        return (rc);
     2095 +}
     2096 +
     2097 +/*
     2098 + * smbsrv_leases
     2099 + */
     2100 +static int
     2101 +smbsrv_leases_dcmd(uintptr_t addr, uint_t flags, int argc,
     2102 +    const mdb_arg_t *argv)
     2103 +{
     2104 +        uint_t          opts;
     2105 +        int             ht_off;
     2106 +        uintptr_t       ht_addr;
     2107 +
     2108 +        if (smb_dcmd_getopt(&opts, argc, argv))
     2109 +                return (DCMD_USAGE);
     2110 +
     2111 +        if (!(flags & DCMD_ADDRSPEC)) {
     2112 +                mdb_printf("require address of an smb_server_t\n");
     2113 +                return (DCMD_USAGE);
     2114 +        }
     2115 +
     2116 +        ht_off = mdb_ctf_offsetof_by_name("smb_server_t", "sv_lease_ht");
     2117 +        if (ht_off < 0) {
     2118 +                mdb_warn("No .sv_lease_ht in server (old kernel?)");
     2119 +                return (DCMD_ERR);
     2120 +        }
     2121 +        addr += ht_off;
     2122 +
     2123 +        if (mdb_vread(&ht_addr, sizeof (ht_addr), addr) <= 0) {
     2124 +                mdb_warn("failed to read server .sv_lease_ht");
     2125 +                return (DCMD_ERR);
     2126 +        }
     2127 +
     2128 +        if (mdb_pwalk_dcmd("smb_hash_walker", "smblease",
     2129 +            argc, argv, ht_addr) == -1) {
     2130 +                mdb_warn("failed to walk 'smb_lease'");
     2131 +                return (DCMD_ERR);
     2132 +        }
     2133 +        return (DCMD_OK);
     2134 +}
     2135 +
     2136 +typedef struct mdb_smb_lease {
     2137 +        struct smb_node         *ls_node;
     2138 +        uint32_t                ls_refcnt;
     2139 +        uint16_t                ls_epoch;
     2140 +        uint8_t                 ls_key[SMB_LEASE_KEY_SZ];
     2141 +} mdb_smb_lease_t;
     2142 +
     2143 +static int
     2144 +smblease_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     2145 +{
     2146 +        mdb_smb_lease_t *ls;
     2147 +        uint_t opts;
     2148 +        int i;
     2149 +
     2150 +        if (smb_dcmd_getopt(&opts, argc, argv))
     2151 +                return (DCMD_USAGE);
     2152 +
     2153 +        if (!(flags & DCMD_ADDRSPEC)) {
     2154 +                mdb_printf("require address of an smb_lease_t\n");
     2155 +                return (DCMD_USAGE);
     2156 +        }
     2157 +
     2158 +        if (((opts & SMB_OPT_WALK) && (opts & SMB_OPT_OFILE)) ||
     2159 +            !(opts & SMB_OPT_WALK)) {
     2160 +
     2161 +                ls = mdb_zalloc(sizeof (*ls), UM_SLEEP | UM_GC);
     2162 +                if (mdb_ctf_vread(ls, SMBSRV_SCOPE "smb_lease_t",
     2163 +                    "mdb_smb_lease_t", addr, 0) < 0) {
     2164 +                        mdb_warn("failed to read smb_lease_t at %p", addr);
     2165 +                        return (DCMD_ERR);
     2166 +                }
     2167 +                if (opts & SMB_OPT_VERBOSE) {
     2168 +
     2169 +                        mdb_printf(
     2170 +                            "%<b>%<u>SMB lease (%p):%</u>%</b>\n\n", addr);
     2171 +
     2172 +                        mdb_printf("SMB Node: %p\n", ls->ls_node);
     2173 +                        mdb_printf("Refcount: %u\n", ls->ls_refcnt);
     2174 +                        mdb_printf("Epoch: %u\n", ls->ls_epoch);
     2175 +
     2176 +                        mdb_printf("Key: [");
     2177 +                        for (i = 0; i < SMB_LEASE_KEY_SZ; i++) {
     2178 +                                mdb_printf(" %02x", ls->ls_key[i] & 0xFF);
     2179 +                                if ((i & 3) == 3)
     2180 +                                        mdb_printf(" ");
     2181 +                        }
     2182 +                        mdb_printf(" ]\n");
     2183 +                } else {
     2184 +                        if (DCMD_HDRSPEC(flags))
     2185 +                                mdb_printf(
     2186 +                                    "%<b>%<u>"
     2187 +                                    "%-?s "
     2188 +                                    "%-?s "
1356 2189                                      "%-?s%</u>%</b>\n",
1357      -                                    "OFILE", "FID", "SMB NODE", "CRED");
     2190 +                                    "LEASE", "SMB NODE", "KEY");
1358 2191  
1359      -                        mdb_printf("%?p %-5u %-p %p\n", addr,
1360      -                            of->f_fid, of->f_node, of->f_cr);
     2192 +                        mdb_printf("%?p %-p [", addr, ls->ls_node);
     2193 +                        for (i = 0; i < 8; i++) {
     2194 +                                mdb_printf(" %02x", ls->ls_key[i] & 0xFF);
     2195 +                        }
     2196 +                        mdb_printf(" ...]\n");
1361 2197                  }
1362 2198          }
     2199 +
1363 2200          return (DCMD_OK);
1364 2201  }
1365 2202  
1366 2203  /*
1367 2204   * *****************************************************************************
1368 2205   * ******************************** smb_kshare_t *******************************
1369 2206   * *****************************************************************************
1370 2207   */
1371 2208  
     2209 +struct smb_kshare_cb_args {
     2210 +        uint_t          opts;
     2211 +        char name[MAXNAMELEN];
     2212 +        char path[MAXPATHLEN];
     2213 +};
     2214 +
1372 2215  static int
1373      -smb_kshare_cb(uintptr_t addr, const void *data, void *arg)
     2216 +smb_kshare_cb(uintptr_t addr, const void *data, void *varg)
1374 2217  {
1375      -        uint_t *opts = arg;
1376      -        uintptr_t ta, sa;
1377      -        char name[32];
1378      -        char path[64];
1379      -        _NOTE(ARGUNUSED(data));
     2218 +        struct smb_kshare_cb_args *args = varg;
     2219 +        const smb_kshare_t *shr = data;
1380 2220  
1381      -        if (*opts & SMB_OPT_VERBOSE) {
     2221 +        if (args->opts & SMB_OPT_VERBOSE) {
1382 2222                  mdb_arg_t       argv;
1383 2223  
1384 2224                  argv.a_type = MDB_TYPE_STRING;
1385 2225                  argv.a_un.a_str = "smb_kshare_t";
1386 2226                  /* Don't fail the walk if this fails. */
     2227 +                mdb_printf("%-?p ", addr);
1387 2228                  mdb_call_dcmd("print", addr, 0, 1, &argv);
1388      -        } else {
1389      -                /*
1390      -                 * Summary line for a kshare
1391      -                 * Don't fail the walk if any of these fail.
1392      -                 */
1393      -                ta = addr + OFFSETOF(smb_kshare_t, shr_name);
1394      -                if (mdb_vread(&sa, sizeof (sa), ta) < 0 ||
1395      -                    mdb_readstr(name, sizeof (name), sa) <= 0)
1396      -                        strcpy(name, "?");
     2229 +                return (WALK_NEXT);
     2230 +        }
1397 2231  
1398      -                ta = addr + OFFSETOF(smb_kshare_t, shr_path);
1399      -                if (mdb_vread(&sa, sizeof (sa), ta) < 0 ||
1400      -                    mdb_readstr(path, sizeof (path), sa) <= 0)
1401      -                        strcpy(path, "?");
     2232 +        /*
     2233 +         * Summary line for an smb_kshare_t
     2234 +         * Don't fail the walk if any of these fail.
     2235 +         *
     2236 +         * Get the shr_name and shr_path strings.
     2237 +         */
     2238 +        if (mdb_readstr(args->name, sizeof (args->name),
     2239 +            (uintptr_t)shr->shr_name) <= 0)
     2240 +                strcpy(args->name, "?");
1402 2241  
1403      -                mdb_printf("%-?p ", addr);      /* smb_kshare_t */
1404      -                mdb_printf("%-16s ", name);
1405      -                mdb_printf("%-s", path);
1406      -                mdb_printf("\n");
1407      -        }
     2242 +        if (mdb_readstr(args->path, sizeof (args->path),
     2243 +            (uintptr_t)shr->shr_path) <= 0)
     2244 +                strcpy(args->path, "?");
1408 2245  
     2246 +        mdb_printf("%-?p ", addr);      /* smb_kshare_t */
     2247 +        mdb_printf("%-16s ", args->name);
     2248 +        mdb_printf("%-s\n", args->path);
     2249 +
1409 2250          return (WALK_NEXT);
1410 2251  }
1411 2252  
1412 2253  /*
1413      - * ::smbshares
     2254 + * ::smbshare
1414 2255   *
1415      - * dcmd - Print out smb_kshare structures.
     2256 + * smbshare dcmd - Print out smb_kshare structures.
1416 2257   *      requires addr of an smb_server_t
1417 2258   */
1418 2259  /*ARGSUSED*/
1419 2260  static int
1420      -smb_dcmd_kshare(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     2261 +smbshare_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1421 2262  {
1422      -        uint_t          opts = 0;
     2263 +        struct smb_kshare_cb_args *args;
1423 2264  
     2265 +        args = mdb_zalloc(sizeof (*args), UM_SLEEP | UM_GC);
1424 2266          if (mdb_getopts(argc, argv,
1425      -            'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, &opts,
     2267 +            'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, &args->opts,
1426 2268              NULL) != argc)
1427 2269                  return (DCMD_USAGE);
1428 2270  
1429 2271          if (!(flags & DCMD_ADDRSPEC))
1430 2272                  return (DCMD_USAGE);
1431      -        addr += OFFSETOF(smb_server_t, sv_export.e_share_avl.avl_tree);
1432 2273  
1433 2274          if (DCMD_HDRSPEC(flags)) {
1434      -                mdb_printf(
1435      -                    "%<b>%<u>"
1436      -                    "%-?s "
1437      -                    "%-16s "
1438      -                    "%-s"
1439      -                    "%</u>%</b>\n",
1440      -                    "smb_kshare_t", "name", "path");
     2275 +                if ((args->opts & SMB_OPT_VERBOSE) != 0) {
     2276 +                        mdb_printf("%<b>%<u>SMB kshares list:%</u>%</b>\n");
     2277 +                } else {
     2278 +                        mdb_printf(
     2279 +                            "%<b>%<u>"
     2280 +                            "%-?s "
     2281 +                            "%-16s "
     2282 +                            "%-s"
     2283 +                            "%</u>%</b>\n",
     2284 +                            "smb_kshare_t", "name", "path");
     2285 +                }
1441 2286          }
1442 2287  
1443      -        if (mdb_pwalk("avl", smb_kshare_cb, &opts, addr) == -1) {
     2288 +        if (mdb_pwalk("smbshare_walker", smb_kshare_cb, args, addr) == -1) {
1444 2289                  mdb_warn("cannot walk smb_kshare avl");
1445 2290                  return (DCMD_ERR);
1446 2291          }
1447 2292  
1448 2293          return (DCMD_OK);
1449 2294  }
1450 2295  
1451 2296  /*
     2297 + * Initialize the smb_kshare_t walker to point to the smb_export
     2298 + * in the specified smb_server_t instance.  (no global walks)
     2299 + */
     2300 +static int
     2301 +smb_kshare_walk_init(mdb_walk_state_t *wsp)
     2302 +{
     2303 +        int sv_exp_off, ex_sha_off, avl_tr_off;
     2304 +
     2305 +        if (wsp->walk_addr == NULL) {
     2306 +                mdb_printf("require address of an smb_server_t\n");
     2307 +                return (WALK_ERR);
     2308 +        }
     2309 +
     2310 +        /*
     2311 +         * Using CTF to get the equivalent of:
     2312 +         * OFFSETOF(smb_server_t, sv_export.e_share_avl.avl_tree);
     2313 +         */
     2314 +        GET_OFFSET(sv_exp_off, smb_server_t, sv_export);
     2315 +        GET_OFFSET(ex_sha_off, smb_export_t, e_share_avl);
     2316 +        GET_OFFSET(avl_tr_off, smb_avl_t, avl_tree);
     2317 +        wsp->walk_addr += (sv_exp_off + ex_sha_off + avl_tr_off);
     2318 +
     2319 +        if (mdb_layered_walk("avl", wsp) == -1) {
     2320 +                mdb_warn("failed to walk list of smb_kshare_t");
     2321 +                return (WALK_ERR);
     2322 +        }
     2323 +
     2324 +        return (WALK_NEXT);
     2325 +}
     2326 +
     2327 +static int
     2328 +smb_kshare_walk_step(mdb_walk_state_t *wsp)
     2329 +{
     2330 +        return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
     2331 +            wsp->walk_cbdata));
     2332 +}
     2333 +
     2334 +/*
1452 2335   * *****************************************************************************
1453 2336   * ******************************** smb_vfs_t **********************************
1454 2337   * *****************************************************************************
1455 2338   */
1456 2339  
     2340 +typedef struct mdb_smb_vfs {
     2341 +        list_node_t             sv_lnd;
     2342 +        uint32_t                sv_magic;
     2343 +        uint32_t                sv_refcnt;
     2344 +        vfs_t                   *sv_vfsp;
     2345 +        vnode_t                 *sv_rootvp;
     2346 +} mdb_smb_vfs_t;
     2347 +
     2348 +struct smb_vfs_cb_args {
     2349 +        uint_t          opts;
     2350 +        vnode_t         vn;
     2351 +        char            path[MAXPATHLEN];
     2352 +};
     2353 +
     2354 +/*ARGSUSED*/
     2355 +static int
     2356 +smb_vfs_cb(uintptr_t addr, const void *data, void *varg)
     2357 +{
     2358 +        struct smb_vfs_cb_args *args = varg;
     2359 +        mdb_smb_vfs_t sf;
     2360 +
     2361 +        if (args->opts & SMB_OPT_VERBOSE) {
     2362 +                mdb_arg_t       argv;
     2363 +
     2364 +                argv.a_type = MDB_TYPE_STRING;
     2365 +                argv.a_un.a_str = "smb_vfs_t";
     2366 +                /* Don't fail the walk if this fails. */
     2367 +                mdb_printf("%-?p ", addr);
     2368 +                mdb_call_dcmd("print", addr, 0, 1, &argv);
     2369 +                return (WALK_NEXT);
     2370 +        }
     2371 +
     2372 +        /*
     2373 +         * Summary line for an smb_vfs_t
     2374 +         * Don't fail the walk if any of these fail.
     2375 +         *
     2376 +         * Get the vnode v_path string if we can.
     2377 +         */
     2378 +        if (mdb_ctf_vread(&sf, SMBSRV_SCOPE "smb_vfs_t",
     2379 +            "mdb_smb_vfs_t", addr, 0) < 0) {
     2380 +                mdb_warn("failed to read struct smb_vfs at %p", addr);
     2381 +                return (DCMD_ERR);
     2382 +        }
     2383 +        strcpy(args->path, "?");
     2384 +        if (mdb_vread(&args->vn, sizeof (args->vn),
     2385 +            (uintptr_t)sf.sv_rootvp) == sizeof (args->vn))
     2386 +                (void) mdb_readstr(args->path, sizeof (args->path),
     2387 +                    (uintptr_t)args->vn.v_path);
     2388 +
     2389 +        mdb_printf("%-?p ", addr);
     2390 +        mdb_printf("%-10d ", sf.sv_refcnt);
     2391 +        mdb_printf("%-?p ", sf.sv_vfsp);
     2392 +        mdb_printf("%-?p ", sf.sv_rootvp);
     2393 +        mdb_printf("%-s\n", args->path);
     2394 +
     2395 +        return (WALK_NEXT);
     2396 +}
     2397 +
1457 2398  /*
1458 2399   * ::smbvfs
1459 2400   *
1460 2401   * smbvfs dcmd - Prints out smb_vfs structures.
     2402 + *      requires addr of an smb_server_t
1461 2403   */
1462 2404  /*ARGSUSED*/
1463 2405  static int
1464      -smb_dcmd_vfs(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     2406 +smbvfs_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1465 2407  {
1466      -        int             verbose = FALSE;
1467      -        smb_vfs_t       *sf;
1468      -        vnode_t         *vn;
1469      -        char            *path;
     2408 +        struct smb_vfs_cb_args *args;
1470 2409  
     2410 +        args = mdb_zalloc(sizeof (*args), UM_SLEEP | UM_GC);
1471 2411          if (mdb_getopts(argc, argv,
1472      -            'v', MDB_OPT_SETBITS, TRUE, &verbose,
     2412 +            'v', MDB_OPT_SETBITS, SMB_OPT_VERBOSE, &args->opts,
1473 2413              NULL) != argc)
1474 2414                  return (DCMD_USAGE);
1475 2415  
1476      -        /*
1477      -         * If no smb_vfs address was specified on the command line, we can
1478      -         * print out all smb_vfs by invoking the smb_vfs walker, using
1479      -         * this dcmd itself as the callback.
1480      -         */
1481      -        if (!(flags & DCMD_ADDRSPEC)) {
1482      -                if (mdb_walk_dcmd("smbvfs_walker", "smbvfs",
1483      -                    argc, argv) == -1) {
1484      -                        mdb_warn("failed to walk 'smb_vfs'");
1485      -                        return (DCMD_ERR);
1486      -                }
1487      -                return (DCMD_OK);
1488      -        }
     2416 +        if (!(flags & DCMD_ADDRSPEC))
     2417 +                return (DCMD_USAGE);
1489 2418  
1490 2419          if (DCMD_HDRSPEC(flags)) {
1491      -                mdb_printf(
1492      -                    "%<b>%<u>"
1493      -                    "%-?s "
1494      -                    "%-10s "
1495      -                    "%-16s "
1496      -                    "%-16s"
1497      -                    "%-s"
1498      -                    "%</u>%</b>\n",
1499      -                    "SMB_VFS", "REFCNT", "VFS", "VNODE", "ROOT");
     2420 +                if ((args->opts & SMB_OPT_VERBOSE) != 0) {
     2421 +                        mdb_printf("%<b>%<u>SMB VFS list:%</u>%</b>\n");
     2422 +                } else {
     2423 +                        mdb_printf(
     2424 +                            "%<b>%<u>"
     2425 +                            "%-?s "
     2426 +                            "%-10s "
     2427 +                            "%-16s "
     2428 +                            "%-16s"
     2429 +                            "%-s"
     2430 +                            "%</u>%</b>\n",
     2431 +                            "SMB_VFS", "REFCNT", "VFS", "VNODE", "ROOT");
     2432 +                }
1500 2433          }
1501 2434  
1502      -        sf = mdb_alloc(sizeof (*sf), UM_SLEEP | UM_GC);
1503      -        if (mdb_vread(sf, sizeof (*sf), addr) == -1) {
1504      -                mdb_warn("failed to read smb_vfs at %p", addr);
     2435 +        if (mdb_pwalk("smbvfs_walker", smb_vfs_cb, args, addr) == -1) {
     2436 +                mdb_warn("cannot walk smb_vfs list");
1505 2437                  return (DCMD_ERR);
1506 2438          }
1507 2439  
1508      -        vn = mdb_alloc(sizeof (*vn), UM_SLEEP | UM_GC);
1509      -        if (mdb_vread(vn, sizeof (*vn),
1510      -            (uintptr_t)sf->sv_rootvp) == -1) {
1511      -                mdb_warn("failed to read vnode at %p", sf->sv_rootvp);
1512      -                return (DCMD_ERR);
1513      -        }
1514      -
1515      -        path = mdb_zalloc(MAXPATHLEN, UM_SLEEP | UM_GC);
1516      -        (void) mdb_vread(path, MAXPATHLEN, (uintptr_t)vn->v_path);
1517      -
1518      -        mdb_printf(
1519      -            "%-?p %-10d %-?p %-?p %-s\n", addr, sf->sv_refcnt,
1520      -            sf->sv_vfsp, sf->sv_rootvp, path);
1521      -
1522 2440          return (DCMD_OK);
1523 2441  }
1524 2442  
1525 2443  /*
1526 2444   * Initialize the smb_vfs_t walker to point to the smb_export
1527 2445   * in the specified smb_server_t instance.  (no global walks)
1528 2446   */
1529 2447  static int
1530 2448  smb_vfs_walk_init(mdb_walk_state_t *wsp)
1531 2449  {
     2450 +        int sv_exp_off, ex_vfs_off, ll_off;
1532 2451  
1533 2452          if (wsp->walk_addr == NULL) {
1534 2453                  mdb_printf("require address of an smb_server_t\n");
1535 2454                  return (WALK_ERR);
1536 2455          }
1537 2456  
1538      -        wsp->walk_addr +=
1539      -            OFFSETOF(smb_server_t, sv_export.e_vfs_list.ll_list);
     2457 +        /*
     2458 +         * Using CTF to get the equivalent of:
     2459 +         * OFFSETOF(smb_server_t, sv_export.e_vfs_list.ll_list);
     2460 +         */
     2461 +        GET_OFFSET(sv_exp_off, smb_server_t, sv_export);
     2462 +        /* GET_OFFSET(ex_vfs_off, smb_export_t, e_vfs_list); */
     2463 +        ex_vfs_off = mdb_ctf_offsetof_by_name("smb_export_t", "e_vfs_list");
     2464 +        if (ex_vfs_off < 0) {
     2465 +                mdb_warn("cannot lookup: smb_export_t .e_vfs_list");
     2466 +                return (WALK_ERR);
     2467 +        }
     2468 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     2469 +        wsp->walk_addr += (sv_exp_off + ex_vfs_off + ll_off);
1540 2470  
1541 2471          if (mdb_layered_walk("list", wsp) == -1) {
1542      -                mdb_warn("failed to walk list of VFS");
     2472 +                mdb_warn("failed to walk list of smb_vfs_t");
1543 2473                  return (WALK_ERR);
1544 2474          }
1545 2475  
1546 2476          return (WALK_NEXT);
1547 2477  }
1548 2478  
1549 2479  static int
1550 2480  smb_vfs_walk_step(mdb_walk_state_t *wsp)
1551 2481  {
1552 2482          return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
1553 2483              wsp->walk_cbdata));
1554 2484  }
1555 2485  
1556 2486  /*
1557 2487   * *****************************************************************************
1558 2488   * ******************************* smb_node_t **********************************
1559 2489   * *****************************************************************************
1560 2490   */
1561 2491  
     2492 +typedef struct mdb_smb_node {
     2493 +        smb_node_state_t        n_state;
     2494 +        uint32_t                n_refcnt;
     2495 +        uint32_t                n_open_count;
     2496 +        uint32_t                n_opening_count;
     2497 +        smb_llist_t             n_ofile_list;
     2498 +        smb_llist_t             n_lock_list;
     2499 +        volatile int            flags;
     2500 +        struct smb_node         *n_dnode;
     2501 +        struct smb_node         *n_unode;
     2502 +        char                    od_name[MAXNAMELEN];
     2503 +        vnode_t                 *vp;
     2504 +        smb_audit_buf_node_t    *n_audit_buf;
     2505 +        /* Newer members (not in old kernels) - keep last! */
     2506 +        smb_llist_t             n_wlock_list;
     2507 +} mdb_smb_node_t;
     2508 +typedef struct mdb_smb_node_old {
     2509 +        /* Note: MUST be layout as above! */
     2510 +        smb_node_state_t        n_state;
     2511 +        uint32_t                n_refcnt;
     2512 +        uint32_t                n_open_count;
     2513 +        uint32_t                n_opening_count;
     2514 +        smb_llist_t             n_ofile_list;
     2515 +        smb_llist_t             n_lock_list;
     2516 +        volatile int            flags;
     2517 +        struct smb_node         *n_dnode;
     2518 +        struct smb_node         *n_unode;
     2519 +        char                    od_name[MAXNAMELEN];
     2520 +        vnode_t                 *vp;
     2521 +        smb_audit_buf_node_t    *n_audit_buf;
     2522 +        /* Newer members omitted from _old */
     2523 +} mdb_smb_node_old_t;
     2524 +
1562 2525  static void
1563      -smb_node_help(void)
     2526 +smbnode_help(void)
1564 2527  {
1565 2528          mdb_printf(
1566 2529              "Display the contents of smb_node_t, with optional filtering.\n\n");
1567 2530          (void) mdb_dec_indent(2);
1568 2531          mdb_printf("%<b>OPTIONS%</b>\n");
1569 2532          (void) mdb_inc_indent(2);
1570 2533          mdb_printf(
1571 2534              "-v\tDisplay verbose smb_node information\n"
1572 2535              "-p\tDisplay the full path of the vnode associated\n"
1573 2536              "-s\tDisplay the stack of the last 16 calls that modified the "
1574 2537              "reference\n\tcount\n");
1575 2538  }
1576 2539  
1577 2540  /*
1578 2541   * ::smbnode
1579 2542   *
1580 2543   * smb_node dcmd - Print out smb_node structure.
1581 2544   */
1582 2545  static int
1583      -smb_dcmd_node(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     2546 +smbnode_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1584 2547  {
1585      -        smb_node_t      node;
     2548 +        static smb_llist_t zero_llist = {0};
     2549 +        mdb_smb_node_t  node;
1586 2550          int             rc;
1587 2551          int             verbose = FALSE;
1588 2552          int             print_full_path = FALSE;
1589 2553          int             stack_trace = FALSE;
     2554 +        int             ol_cnt = 0;
1590 2555          vnode_t         vnode;
1591 2556          char            od_name[MAXNAMELEN];
1592 2557          char            path_name[1024];
1593      -        uintptr_t       list_addr, oplock_addr;
     2558 +        uintptr_t       list_addr;
     2559 +        struct mdb_smb_oplock *node_oplock;
1594 2560  
1595 2561          if (mdb_getopts(argc, argv,
1596 2562              'v', MDB_OPT_SETBITS, TRUE, &verbose,
1597 2563              'p', MDB_OPT_SETBITS, TRUE, &print_full_path,
1598 2564              's', MDB_OPT_SETBITS, TRUE, &stack_trace,
1599 2565              NULL) != argc)
1600 2566                  return (DCMD_USAGE);
1601 2567  
1602 2568          /*
1603 2569           * If no smb_node address was specified on the command line, we can
↓ open down ↓ 3 lines elided ↑ open up ↑
1607 2573          if (!(flags & DCMD_ADDRSPEC)) {
1608 2574                  if (mdb_walk_dcmd("smbnode_walker", "smbnode",
1609 2575                      argc, argv) == -1) {
1610 2576                          mdb_warn("failed to walk 'smb_node'");
1611 2577                          return (DCMD_ERR);
1612 2578                  }
1613 2579                  return (DCMD_OK);
1614 2580          }
1615 2581  
1616 2582          /*
1617      -         * If this is the first invocation of the command, print a nice
1618      -         * header line for the output that will follow.
     2583 +         * For each smb_node, we just need to read the smb_node_t struct, read
     2584 +         * and then print out the following fields.
1619 2585           */
1620      -        if (DCMD_HDRSPEC(flags)) {
1621      -                if (verbose) {
1622      -                        mdb_printf("%<b>%<u>SMB node information:%</u>%</b>\n");
     2586 +        if (mdb_ctf_vread(&node, SMBSRV_SCOPE "smb_node_t",
     2587 +            "mdb_smb_node_t", addr, 0) < 0) {
     2588 +                /*
     2589 +                 * Fall-back handling for mdb_smb_node_old_t
     2590 +                 * Should remove after a while.
     2591 +                 */
     2592 +                if (mdb_ctf_vread(&node, SMBSRV_SCOPE "smb_node_t",
     2593 +                    "mdb_smb_node_old_t", addr, 0) < 0) {
     2594 +                        mdb_warn("failed to read struct smb_node at %p", addr);
     2595 +                        return (DCMD_ERR);
     2596 +                }
     2597 +                node.n_wlock_list = zero_llist;
     2598 +        }
     2599 +
     2600 +        (void) mdb_snprintf(od_name, sizeof (od_name), "%s",
     2601 +            node.od_name);
     2602 +        if (print_full_path) {
     2603 +                if (mdb_vread(&vnode, sizeof (vnode_t),
     2604 +                    (uintptr_t)node.vp) == sizeof (vnode_t)) {
     2605 +                        if (mdb_readstr(path_name, sizeof (path_name),
     2606 +                            (uintptr_t)vnode.v_path) <= 0) {
     2607 +                                (void) mdb_snprintf(path_name,
     2608 +                                    sizeof (path_name), "N/A");
     2609 +                        }
     2610 +                }
     2611 +        }
     2612 +
     2613 +        rc = smb_node_get_oplock(addr, &node_oplock);
     2614 +        if (rc != DCMD_OK)
     2615 +                return (rc);
     2616 +        ol_cnt = smb_node_oplock_cnt(node_oplock);
     2617 +
     2618 +        if (verbose) {
     2619 +                int nol_off, nll_off, wll_off, ll_off;
     2620 +
     2621 +                GET_OFFSET(nol_off, smb_node_t, n_ofile_list);
     2622 +                GET_OFFSET(nll_off, smb_node_t, n_lock_list);
     2623 +                GET_OFFSET(ll_off, smb_llist_t, ll_list);
     2624 +                /* This one is optional (for now). */
     2625 +                /* GET_OFFSET(wll_off, smb_node_t, n_wlock_list); */
     2626 +                wll_off = mdb_ctf_offsetof_by_name(
     2627 +                    "smb_node_t", "n_wlock_list");
     2628 +
     2629 +                mdb_printf("%<b>%<u>SMB node information "
     2630 +                    "(%p):%</u>%</b>\n", addr);
     2631 +                mdb_printf("VP: %p\n", node.vp);
     2632 +                mdb_printf("Name: %s\n", od_name);
     2633 +                if (print_full_path)
     2634 +                        mdb_printf("V-node Path: %s\n", path_name);
     2635 +                mdb_printf("Reference Count: %u\n", node.n_refcnt);
     2636 +                mdb_printf("Ofiles: %u\n", node.n_ofile_list.ll_count);
     2637 +                if (node.n_ofile_list.ll_count != 0 && nol_off != -1) {
     2638 +                        (void) mdb_inc_indent(SMB_DCMD_INDENT);
     2639 +                        list_addr = addr + nol_off + ll_off;
     2640 +                        if (mdb_pwalk_dcmd("list", "smbofile", 0,
     2641 +                            NULL, list_addr)) {
     2642 +                                mdb_warn("failed to walk node's ofiles");
     2643 +                        }
     2644 +                        (void) mdb_dec_indent(SMB_DCMD_INDENT);
     2645 +                }
     2646 +
     2647 +                mdb_printf("Granted Locks: %u\n",
     2648 +                    node.n_lock_list.ll_count);
     2649 +                if (node.n_lock_list.ll_count != 0) {
     2650 +                        (void) mdb_inc_indent(SMB_DCMD_INDENT);
     2651 +                        list_addr = addr + nll_off + ll_off;
     2652 +                        if (mdb_pwalk_dcmd("list", "smblock", 0,
     2653 +                            NULL, list_addr)) {
     2654 +                                mdb_warn("failed to walk node's granted"
     2655 +                                    " locks");
     2656 +                        }
     2657 +                        (void) mdb_dec_indent(SMB_DCMD_INDENT);
     2658 +                }
     2659 +                mdb_printf("Waiting Locks: %u\n",
     2660 +                    node.n_wlock_list.ll_count);
     2661 +                if (node.n_wlock_list.ll_count != 0 && wll_off != -1) {
     2662 +                        (void) mdb_inc_indent(SMB_DCMD_INDENT);
     2663 +                        list_addr = addr + wll_off + ll_off;
     2664 +                        if (mdb_pwalk_dcmd("list", "smblock", 0,
     2665 +                            NULL, list_addr)) {
     2666 +                                mdb_warn("failed to walk node's waiting"
     2667 +                                    " locks");
     2668 +                        }
     2669 +                        (void) mdb_dec_indent(SMB_DCMD_INDENT);
     2670 +                }
     2671 +                if (ol_cnt == 0) {
     2672 +                        mdb_printf("Opportunistic Locks: (none)\n");
1623 2673                  } else {
     2674 +                        mdb_printf("Opportunistic Locks:\n");
     2675 +                        (void) mdb_inc_indent(SMB_DCMD_INDENT);
     2676 +                        /* Takes node address */
     2677 +                        rc = mdb_call_dcmd("smbnode_oplock", addr,
     2678 +                            flags, argc, argv);
     2679 +                        (void) mdb_dec_indent(SMB_DCMD_INDENT);
     2680 +                        if (rc != DCMD_OK)
     2681 +                                return (rc);
     2682 +                }
     2683 +        } else {
     2684 +                if (DCMD_HDRSPEC(flags)) {
1624 2685                          mdb_printf(
1625 2686                              "%<b>%<u>%-?s "
1626 2687                              "%-?s "
1627 2688                              "%-18s "
1628 2689                              "%-6s "
1629 2690                              "%-6s "
1630 2691                              "%-8s "
     2692 +                            "%-8s "
1631 2693                              "%-6s%</u>%</b>\n",
1632 2694                              "ADDR", "VP", "NODE-NAME", "OFILES", "LOCKS",
1633      -                            "OPLOCK", "REF");
     2695 +                            "WLOCKS", "OPLOCK", "REF");
1634 2696                  }
     2697 +
     2698 +                mdb_printf("%-?p %-?p %-18s %-6d %-6d %-8d %-8d %-6d ",
     2699 +                    addr, node.vp, od_name, node.n_ofile_list.ll_count,
     2700 +                    node.n_lock_list.ll_count, node.n_wlock_list.ll_count,
     2701 +                    ol_cnt, node.n_refcnt);
     2702 +
     2703 +                if (print_full_path)
     2704 +                        mdb_printf("\t%s\n", path_name);
1635 2705          }
     2706 +        if (stack_trace && node.n_audit_buf) {
     2707 +                int ctr;
     2708 +                smb_audit_buf_node_t *anb;
1636 2709  
1637      -        /*
1638      -         * For each smb_node, we just need to read the smb_node_t struct, read
1639      -         * and then print out the following fields.
1640      -         */
1641      -        if (mdb_vread(&node, sizeof (node), addr) == sizeof (node)) {
1642      -                (void) mdb_snprintf(od_name, sizeof (od_name), "%s",
1643      -                    node.od_name);
1644      -                if (print_full_path) {
1645      -                        if (mdb_vread(&vnode, sizeof (vnode_t),
1646      -                            (uintptr_t)node.vp) == sizeof (vnode_t)) {
1647      -                                if (mdb_readstr(path_name, sizeof (path_name),
1648      -                                    (uintptr_t)vnode.v_path) != 0) {
1649      -                                        (void) mdb_snprintf(od_name,
1650      -                                            sizeof (od_name), "N/A");
1651      -                                }
1652      -                        }
1653      -                }
1654      -                if (verbose) {
1655      -                        mdb_printf("VP: %p\n", node.vp);
1656      -                        mdb_printf("Name: %s\n", od_name);
1657      -                        if (print_full_path)
1658      -                                mdb_printf("V-node Path: %s\n", path_name);
1659      -                        mdb_printf("Ofiles: %u\n", node.n_ofile_list.ll_count);
1660      -                        mdb_printf("Range Locks: %u\n",
1661      -                            node.n_lock_list.ll_count);
1662      -                        if (node.n_lock_list.ll_count != 0) {
1663      -                                (void) mdb_inc_indent(SMB_DCMD_INDENT);
1664      -                                list_addr = addr +
1665      -                                    OFFSETOF(smb_node_t, n_lock_list) +
1666      -                                    OFFSETOF(smb_llist_t, ll_list);
1667      -                                if (mdb_pwalk_dcmd("list", "smblock", 0,
1668      -                                    NULL, list_addr)) {
1669      -                                        mdb_warn("failed to walk node's active"
1670      -                                            " locks");
1671      -                                }
1672      -                                (void) mdb_dec_indent(SMB_DCMD_INDENT);
1673      -                        }
1674      -                        if (node.n_oplock.ol_count == 0) {
1675      -                                mdb_printf("Opportunistic Locks: 0\n");
1676      -                        } else {
1677      -                                oplock_addr =
1678      -                                    addr + OFFSETOF(smb_node_t, n_oplock);
1679      -                                mdb_printf("Opportunistic Lock: %p\n",
1680      -                                    oplock_addr);
1681      -                                rc = mdb_call_dcmd("smboplock", oplock_addr,
1682      -                                    flags, argc, argv);
1683      -                                if (rc != DCMD_OK)
1684      -                                        return (rc);
1685      -                        }
1686      -                        mdb_printf("Reference Count: %u\n\n", node.n_refcnt);
1687      -                } else {
1688      -                        mdb_printf("%-?p %-?p %-18s %-6d %-6d %-8d %-6d ",
1689      -                            addr, node.vp, od_name, node.n_ofile_list.ll_count,
1690      -                            node.n_lock_list.ll_count,
1691      -                            node.n_oplock.ol_count, node.n_refcnt);
     2710 +                anb = mdb_alloc(sizeof (smb_audit_buf_node_t),
     2711 +                    UM_SLEEP | UM_GC);
1692 2712  
1693      -                        if (print_full_path)
1694      -                                mdb_printf("\t%s\n", path_name);
     2713 +                if (mdb_vread(anb, sizeof (*anb),
     2714 +                    (uintptr_t)node.n_audit_buf) != sizeof (*anb)) {
     2715 +                        mdb_warn("failed to read audit buffer");
     2716 +                        return (DCMD_ERR);
1695 2717                  }
1696      -                if (stack_trace && node.n_audit_buf) {
1697      -                        int ctr;
1698      -                        smb_audit_buf_node_t *anb;
     2718 +                ctr = anb->anb_max_index + 1;
     2719 +                anb->anb_index--;
     2720 +                anb->anb_index &= anb->anb_max_index;
1699 2721  
1700      -                        anb = mdb_alloc(sizeof (smb_audit_buf_node_t),
1701      -                            UM_SLEEP | UM_GC);
     2722 +                while (ctr) {
     2723 +                        smb_audit_record_node_t *anr;
1702 2724  
1703      -                        if (mdb_vread(anb, sizeof (*anb),
1704      -                            (uintptr_t)node.n_audit_buf) != sizeof (*anb)) {
1705      -                                mdb_warn("failed to read audit buffer");
1706      -                                return (DCMD_ERR);
1707      -                        }
1708      -                        ctr = anb->anb_max_index + 1;
1709      -                        anb->anb_index--;
1710      -                        anb->anb_index &= anb->anb_max_index;
     2725 +                        anr = anb->anb_records + anb->anb_index;
1711 2726  
1712      -                        while (ctr) {
1713      -                                smb_audit_record_node_t *anr;
     2727 +                        if (anr->anr_depth) {
     2728 +                                char c[MDB_SYM_NAMLEN];
     2729 +                                GElf_Sym sym;
     2730 +                                int i;
1714 2731  
1715      -                                anr = anb->anb_records + anb->anb_index;
     2732 +                                mdb_printf("\nRefCnt: %u\t",
     2733 +                                    anr->anr_refcnt);
1716 2734  
1717      -                                if (anr->anr_depth) {
1718      -                                        char c[MDB_SYM_NAMLEN];
1719      -                                        GElf_Sym sym;
1720      -                                        int i;
1721      -
1722      -                                        mdb_printf("\nRefCnt: %u\t",
1723      -                                            anr->anr_refcnt);
1724      -
1725      -                                        for (i = 0;
1726      -                                            i < anr->anr_depth;
1727      -                                            i++) {
1728      -                                                if (mdb_lookup_by_addr(
1729      -                                                    anr->anr_stack[i],
1730      -                                                    MDB_SYM_FUZZY,
1731      -                                                    c, sizeof (c),
1732      -                                                    &sym) == -1) {
1733      -                                                        continue;
1734      -                                                }
1735      -                                                mdb_printf("%s+0x%1x",
1736      -                                                    c,
1737      -                                                    anr->anr_stack[i] -
1738      -                                                    (uintptr_t)sym.st_value);
1739      -                                                ++i;
1740      -                                                break;
     2735 +                                for (i = 0;
     2736 +                                    i < anr->anr_depth;
     2737 +                                    i++) {
     2738 +                                        if (mdb_lookup_by_addr(
     2739 +                                            anr->anr_stack[i],
     2740 +                                            MDB_SYM_FUZZY,
     2741 +                                            c, sizeof (c),
     2742 +                                            &sym) == -1) {
     2743 +                                                continue;
1741 2744                                          }
     2745 +                                        mdb_printf("%s+0x%1x",
     2746 +                                            c,
     2747 +                                            anr->anr_stack[i] -
     2748 +                                            (uintptr_t)sym.st_value);
     2749 +                                        ++i;
     2750 +                                        break;
     2751 +                                }
1742 2752  
1743      -                                        while (i < anr->anr_depth) {
1744      -                                                if (mdb_lookup_by_addr(
1745      -                                                    anr->anr_stack[i],
1746      -                                                    MDB_SYM_FUZZY,
1747      -                                                    c, sizeof (c),
1748      -                                                    &sym) == -1) {
1749      -                                                        ++i;
1750      -                                                        continue;
1751      -                                                }
1752      -                                                mdb_printf("\n\t\t%s+0x%1x",
1753      -                                                    c,
1754      -                                                    anr->anr_stack[i] -
1755      -                                                    (uintptr_t)sym.st_value);
     2753 +                                while (i < anr->anr_depth) {
     2754 +                                        if (mdb_lookup_by_addr(
     2755 +                                            anr->anr_stack[i],
     2756 +                                            MDB_SYM_FUZZY,
     2757 +                                            c, sizeof (c),
     2758 +                                            &sym) == -1) {
1756 2759                                                  ++i;
     2760 +                                                continue;
1757 2761                                          }
1758      -                                        mdb_printf("\n");
     2762 +                                        mdb_printf("\n\t\t%s+0x%1x",
     2763 +                                            c,
     2764 +                                            anr->anr_stack[i] -
     2765 +                                            (uintptr_t)sym.st_value);
     2766 +                                        ++i;
1759 2767                                  }
1760      -                                anb->anb_index--;
1761      -                                anb->anb_index &= anb->anb_max_index;
1762      -                                ctr--;
     2768 +                                mdb_printf("\n");
1763 2769                          }
     2770 +                        anb->anb_index--;
     2771 +                        anb->anb_index &= anb->anb_max_index;
     2772 +                        ctr--;
1764 2773                  }
1765      -        } else {
1766      -                mdb_warn("failed to read struct smb_node at %p", addr);
1767      -                return (DCMD_ERR);
1768 2774          }
1769 2775  
1770 2776          return (DCMD_OK);
1771 2777  }
1772 2778  
1773 2779  /*
1774 2780   * Initialize the smb_node_t walker by reading the value of smb_node_hash_table
1775 2781   * in the kernel's symbol table. Only global walk supported.
1776 2782   */
1777 2783  static int
1778 2784  smb_node_walk_init(mdb_walk_state_t *wsp)
1779 2785  {
1780 2786          GElf_Sym        sym;
1781      -        int             i;
1782 2787          uintptr_t       node_hash_table_addr;
     2788 +        int             ll_off;
     2789 +        int             i;
1783 2790  
1784 2791          if (wsp->walk_addr == NULL) {
1785 2792                  if (mdb_lookup_by_obj(SMBSRV_OBJNAME, "smb_node_hash_table",
1786 2793                      &sym) == -1) {
1787 2794                          mdb_warn("failed to find 'smb_node_hash_table'");
1788 2795                          return (WALK_ERR);
1789 2796                  }
1790 2797                  node_hash_table_addr = (uintptr_t)sym.st_value;
1791 2798          } else {
1792 2799                  mdb_printf("smb_node walk only supports global walks\n");
1793 2800                  return (WALK_ERR);
1794 2801          }
1795 2802  
     2803 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     2804 +
1796 2805          for (i = 0; i < SMBND_HASH_MASK + 1; i++) {
1797 2806                  wsp->walk_addr = node_hash_table_addr +
1798      -                    (i * sizeof (smb_llist_t)) + OFFSETOF(smb_llist_t, ll_list);
     2807 +                    (i * sizeof (smb_llist_t)) + ll_off;
1799 2808                  if (mdb_layered_walk("list", wsp) == -1) {
1800 2809                          mdb_warn("failed to walk 'list'");
1801 2810                          return (WALK_ERR);
1802 2811                  }
1803 2812          }
1804 2813  
1805 2814          return (WALK_NEXT);
1806 2815  }
1807 2816  
1808 2817  static int
↓ open down ↓ 2 lines elided ↑ open up ↑
1811 2820          return (wsp->walk_callback(wsp->walk_addr, wsp->walk_layer,
1812 2821              wsp->walk_cbdata));
1813 2822  }
1814 2823  
1815 2824  /*
1816 2825   * *****************************************************************************
1817 2826   * ****************************** smb_lock_t ***********************************
1818 2827   * *****************************************************************************
1819 2828   */
1820 2829  
     2830 +typedef struct mdb_smb_lock {
     2831 +        smb_ofile_t             *l_file;
     2832 +        struct smb_lock         *l_blocked_by;
     2833 +        uint64_t                l_start;
     2834 +        uint64_t                l_length;
     2835 +        uint32_t                l_pid;
     2836 +        uint32_t                l_type;
     2837 +        uint32_t                l_flags;
     2838 +        /* Newer members (not in old kernels) - keep last! */
     2839 +        uint32_t                l_conflicts;
     2840 +} mdb_smb_lock_t;
     2841 +typedef struct mdb_smb_lock_old {
     2842 +        /* Note: MUST be same layout as above! */
     2843 +        smb_ofile_t             *l_file;
     2844 +        struct smb_lock         *l_blocked_by;
     2845 +        uint64_t                l_start;
     2846 +        uint64_t                l_length;
     2847 +        uint32_t                l_pid;
     2848 +        uint32_t                l_type;
     2849 +        uint32_t                l_flags;
     2850 +        /* Newer members omitted from _old */
     2851 +} mdb_smb_lock_old_t;
     2852 +
1821 2853  static int
1822      -smb_lock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     2854 +smblock_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
1823 2855  {
1824      -        smb_lock_t      lock;
     2856 +        mdb_smb_lock_t  lock;
1825 2857          int             verbose = FALSE;
1826      -        uintptr_t       list_addr;
1827 2858          char            *lock_type;
1828 2859  
1829 2860          if (mdb_getopts(argc, argv,
1830 2861              'v', MDB_OPT_SETBITS, TRUE, &verbose,
1831 2862              NULL) != argc)
1832 2863                  return (DCMD_USAGE);
1833 2864  
1834 2865          /*
1835 2866           * An smb_lock_t address must be specified.
1836 2867           */
1837 2868          if (!(flags & DCMD_ADDRSPEC))
1838 2869                  return (DCMD_USAGE);
1839 2870  
1840      -        /*
1841      -         * If this is the first invocation of the command, print a nice
1842      -         * header line for the output that will follow.
1843      -         */
1844      -        if (DCMD_HDRSPEC(flags)) {
1845      -                if (verbose)
1846      -                        mdb_printf("SMB lock information:\n\n");
1847      -                else
1848      -                        mdb_printf("%<u>%-?s %4s %16s %8s %9s%</u>\n",
1849      -                            "Locks: ", "TYPE", "START", "LENGTH",
1850      -                            "CONFLICTS");
     2871 +        if (mdb_ctf_vread(&lock, SMBSRV_SCOPE "smb_lock_t",
     2872 +            "mdb_smb_lock_t", addr, 0) < 0) {
     2873 +                /*
     2874 +                 * Fall-back handling for mdb_smb_lock_old_t
     2875 +                 * Should remove after a while.
     2876 +                 */
     2877 +                if (mdb_ctf_vread(&lock, SMBSRV_SCOPE "smb_lock_t",
     2878 +                    "mdb_smb_lock_old_t", addr, 0) < 0) {
     2879 +                        mdb_warn("failed to read struct smb_lock at %p", addr);
     2880 +                        return (DCMD_ERR);
     2881 +                }
     2882 +                lock.l_conflicts = 0;
1851 2883          }
1852 2884  
1853      -        if (mdb_vread(&lock, sizeof (lock), addr) == sizeof (lock)) {
1854      -                switch (lock.l_type) {
1855      -                case SMB_LOCK_TYPE_READWRITE:
1856      -                        lock_type = "RW";
1857      -                        break;
1858      -                case SMB_LOCK_TYPE_READONLY:
1859      -                        lock_type = "RO";
1860      -                        break;
1861      -                default:
1862      -                        lock_type = "N/A";
1863      -                        break;
1864      -                }
1865      -                if (verbose) {
1866      -                        mdb_printf("Type             :\t%s (%u)\n",
1867      -                            lock_type, lock.l_type);
1868      -                        mdb_printf("Start            :\t%llx\n",
1869      -                            lock.l_start);
1870      -                        mdb_printf("Length           :\t%lx\n",
1871      -                            lock.l_length);
1872      -                        mdb_printf("Session          :\t%p\n",
1873      -                            lock.l_session);
1874      -                        mdb_printf("File             :\t%p\n",
1875      -                            lock.l_file);
1876      -                        mdb_printf("User ID          :\t%u\n",
1877      -                            lock.l_uid);
1878      -                        mdb_printf("Process ID       :\t%u\n",
1879      -                            lock.l_pid);
1880      -                        mdb_printf("Conflicts        :\t%u\n",
1881      -                            lock.l_conflict_list.sl_count);
1882      -                        if (lock.l_conflict_list.sl_count != 0) {
1883      -                                (void) mdb_inc_indent(SMB_DCMD_INDENT);
1884      -                                list_addr = addr +
1885      -                                    OFFSETOF(smb_lock_t, l_conflict_list) +
1886      -                                    OFFSETOF(smb_slist_t, sl_list);
1887      -                                if (mdb_pwalk_dcmd("list", "smb_lock",
1888      -                                    0, NULL, list_addr)) {
1889      -                                        mdb_warn("failed to walk conflict "
1890      -                                            "locks ");
1891      -                                }
1892      -                                (void) mdb_dec_indent(SMB_DCMD_INDENT);
1893      -                        }
1894      -                        mdb_printf("Blocked by       :\t%p\n",
1895      -                            lock.l_blocked_by);
1896      -                        mdb_printf("Flags            :\t0x%x\n",
1897      -                            lock.l_flags);
1898      -                        mdb_printf("\n");
1899      -                } else {
1900      -                        mdb_printf("%?p %4s %16llx %08lx %9x", addr,
1901      -                            lock_type, lock.l_start, lock.l_length,
1902      -                            lock.l_conflict_list.sl_count);
1903      -                }
     2885 +        switch (lock.l_type) {
     2886 +        case SMB_LOCK_TYPE_READWRITE:
     2887 +                lock_type = "RW";
     2888 +                break;
     2889 +        case SMB_LOCK_TYPE_READONLY:
     2890 +                lock_type = "RO";
     2891 +                break;
     2892 +        default:
     2893 +                lock_type = "?";
     2894 +                break;
     2895 +        }
     2896 +        if (verbose) {
     2897 +                mdb_printf("%<b>%<u>SMB lock information "
     2898 +                    "(%p):%</u>%</b>\n", addr);
     2899 +
     2900 +                mdb_printf("Type             :\t%s (%u)\n",
     2901 +                    lock_type, lock.l_type);
     2902 +                mdb_printf("Start            :\t%llu\n",
     2903 +                    lock.l_start);
     2904 +                mdb_printf("Length           :\t%llu\n",
     2905 +                    lock.l_length);
     2906 +                mdb_printf("OFile            :\t%p\n",
     2907 +                    lock.l_file);
     2908 +                mdb_printf("Process ID       :\t%u\n",
     2909 +                    lock.l_pid);
     2910 +                mdb_printf("Conflicts        :\t%u\n",
     2911 +                    lock.l_conflicts);
     2912 +                mdb_printf("Blocked by       :\t%p\n",
     2913 +                    lock.l_blocked_by);
     2914 +                mdb_printf("Flags            :\t0x%x\n",
     2915 +                    lock.l_flags);
     2916 +                mdb_printf("\n");
1904 2917          } else {
1905      -                mdb_warn("failed to read struct smb_request at %p", addr);
1906      -                return (DCMD_ERR);
     2918 +                if (DCMD_HDRSPEC(flags)) {
     2919 +                        mdb_printf("%<u>%-?s %4s %16s %8s %9s %-?s%</u>\n",
     2920 +                            "Locks: ", "TYPE", "START", "LENGTH",
     2921 +                            "CONFLICTS", "BLOCKED-BY");
     2922 +                }
     2923 +                mdb_printf("%?p %4s %16llx %08llx %9u %?p",
     2924 +                    addr, lock_type, lock.l_start, lock.l_length,
     2925 +                    lock.l_conflicts, lock.l_blocked_by);
1907 2926          }
1908 2927  
1909 2928          return (DCMD_OK);
1910 2929  }
1911 2930  
1912 2931  /*
1913 2932   * *****************************************************************************
1914 2933   * ************************** smb_oplock_grant_t *******************************
1915 2934   * *****************************************************************************
1916 2935   */
     2936 +
     2937 +typedef struct mdb_smb_oplock_grant {
     2938 +        uint32_t                og_state;       /* latest sent to client */
     2939 +        uint8_t                 onlist_II;
     2940 +        uint8_t                 onlist_R;
     2941 +        uint8_t                 onlist_RH;
     2942 +        uint8_t                 onlist_RHBQ;
     2943 +        uint8_t                 BreakingToRead;
     2944 +} mdb_smb_oplock_grant_t;
     2945 +
     2946 +static const mdb_bitmask_t
     2947 +oplock_bits[] = {
     2948 +        {  "READ_CACHING",
     2949 +            READ_CACHING,
     2950 +            READ_CACHING },
     2951 +        {  "HANDLE_CACHING",
     2952 +            HANDLE_CACHING,
     2953 +            HANDLE_CACHING },
     2954 +        {  "WRITE_CACHING",
     2955 +            WRITE_CACHING,
     2956 +            WRITE_CACHING },
     2957 +        {  "EXCLUSIVE",
     2958 +            EXCLUSIVE,
     2959 +            EXCLUSIVE },
     2960 +        {  "MIXED_R_AND_RH",
     2961 +            MIXED_R_AND_RH,
     2962 +            MIXED_R_AND_RH },
     2963 +        {  "LEVEL_TWO_OPLOCK",
     2964 +            LEVEL_TWO_OPLOCK,
     2965 +            LEVEL_TWO_OPLOCK },
     2966 +        {  "LEVEL_ONE_OPLOCK",
     2967 +            LEVEL_ONE_OPLOCK,
     2968 +            LEVEL_ONE_OPLOCK },
     2969 +        {  "BATCH_OPLOCK",
     2970 +            BATCH_OPLOCK,
     2971 +            BATCH_OPLOCK },
     2972 +        {  "BREAK_TO_TWO",
     2973 +            BREAK_TO_TWO,
     2974 +            BREAK_TO_TWO },
     2975 +        {  "BREAK_TO_NONE",
     2976 +            BREAK_TO_NONE,
     2977 +            BREAK_TO_NONE },
     2978 +        {  "BREAK_TO_TWO_TO_NONE",
     2979 +            BREAK_TO_TWO_TO_NONE,
     2980 +            BREAK_TO_TWO_TO_NONE },
     2981 +        {  "BREAK_TO_READ_CACHING",
     2982 +            BREAK_TO_READ_CACHING,
     2983 +            BREAK_TO_READ_CACHING },
     2984 +        {  "BREAK_TO_HANDLE_CACHING",
     2985 +            BREAK_TO_HANDLE_CACHING,
     2986 +            BREAK_TO_HANDLE_CACHING },
     2987 +        {  "BREAK_TO_WRITE_CACHING",
     2988 +            BREAK_TO_WRITE_CACHING,
     2989 +            BREAK_TO_WRITE_CACHING },
     2990 +        {  "BREAK_TO_NO_CACHING",
     2991 +            BREAK_TO_NO_CACHING,
     2992 +            BREAK_TO_NO_CACHING },
     2993 +        {  "NO_OPLOCK",
     2994 +            NO_OPLOCK,
     2995 +            NO_OPLOCK },
     2996 +        {  NULL, 0, 0 }
     2997 +};
     2998 +
     2999 +/*
     3000 + * Show smb_ofile_t oplock info
     3001 + * address is the ofile
     3002 + */
     3003 +
1917 3004  /*ARGSUSED*/
1918 3005  static int
1919      -smb_oplock_grant(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3006 +smbofile_oplock_dcmd(uintptr_t addr, uint_t flags, int argc,
     3007 +    const mdb_arg_t *argv)
1920 3008  {
1921      -        smb_oplock_grant_t      grant;
1922      -        char                     *level;
     3009 +        mdb_smb_oplock_grant_t  og;
     3010 +        int verbose = FALSE;
     3011 +        static int og_off;
1923 3012  
     3013 +        if (mdb_getopts(argc, argv,
     3014 +            'v', MDB_OPT_SETBITS, TRUE, &verbose,
     3015 +            NULL) != argc)
     3016 +                return (DCMD_USAGE);
     3017 +
1924 3018          if (!(flags & DCMD_ADDRSPEC))
1925 3019                  return (DCMD_USAGE);
1926 3020  
1927      -        /*
1928      -         * If this is the first invocation of the command, print a nice
1929      -         * header line for the output that will follow.
1930      -         */
1931      -        if (DCMD_HDRSPEC(flags)) {
1932      -                mdb_printf("%<u>%-16s %-10s %-16s%</u>\n",
1933      -                    "Grants:", "LEVEL", "OFILE");
     3021 +        if (og_off <= 0) {
     3022 +                og_off = mdb_ctf_offsetof_by_name(
     3023 +                    "smb_ofile_t", "f_oplock");
     3024 +                if (og_off < 0) {
     3025 +                        mdb_warn("cannot lookup: smb_ofile_t .f_oplock");
     3026 +                        return (DCMD_ERR);
     3027 +                }
1934 3028          }
1935 3029  
1936      -        if (mdb_vread(&grant, sizeof (grant), addr) == sizeof (grant)) {
1937      -                switch (grant.og_level) {
1938      -                case SMB_OPLOCK_EXCLUSIVE:
1939      -                        level = "EXCLUSIVE";
1940      -                        break;
1941      -                case SMB_OPLOCK_BATCH:
1942      -                        level = "BATCH";
1943      -                        break;
1944      -                case SMB_OPLOCK_LEVEL_II:
1945      -                        level = "LEVEL_II";
1946      -                        break;
1947      -                default:
1948      -                        level = "UNKNOWN";
1949      -                        break;
     3030 +        if (mdb_ctf_vread(&og, SMBSRV_SCOPE "smb_oplock_grant_t",
     3031 +            "mdb_smb_oplock_grant_t", addr + og_off, 0) < 0) {
     3032 +                mdb_warn("failed to read oplock grant in ofile at %p", addr);
     3033 +                return (DCMD_ERR);
     3034 +        }
     3035 +
     3036 +        if (verbose) {
     3037 +                mdb_printf("%<b>%<u>SMB ofile (oplock_grant) "
     3038 +                    "(%p):%</u>%</b>\n", addr);
     3039 +                mdb_printf("State: 0x%x <%b>\n",
     3040 +                    og.og_state,
     3041 +                    og.og_state,
     3042 +                    oplock_bits);
     3043 +                mdb_printf("OnList_II: %d\n", og.onlist_II);
     3044 +                mdb_printf("OnList_R: %d\n", og.onlist_R);
     3045 +                mdb_printf("OnList_RH: %d\n", og.onlist_RH);
     3046 +                mdb_printf("OnList_RHBQ: %d\n", og.onlist_RHBQ);
     3047 +                mdb_printf("BrkToRead: %d\n", og.BreakingToRead);
     3048 +
     3049 +        } else {
     3050 +
     3051 +                if (DCMD_HDRSPEC(flags)) {
     3052 +                        mdb_printf("%<u>%-16s %-10s %-16s%</u>\n",
     3053 +                            "OFILE", "STATE", "OnList...");
1950 3054                  }
1951 3055  
1952      -                mdb_printf("%-16p %-10s %-16p", addr, level, grant.og_ofile);
     3056 +                mdb_printf("%-16p", addr);
     3057 +                mdb_printf(" 0x%x", og.og_state);
     3058 +                if (og.onlist_II)
     3059 +                        mdb_printf(" II");
     3060 +                if (og.onlist_R)
     3061 +                        mdb_printf(" R");
     3062 +                if (og.onlist_RH)
     3063 +                        mdb_printf(" RH");
     3064 +                if (og.onlist_RHBQ)
     3065 +                        mdb_printf(" RHBQ");
     3066 +                if (og.BreakingToRead)
     3067 +                        mdb_printf(" BrkToRd");
     3068 +                mdb_printf("\n");
1953 3069          }
     3070 +
1954 3071          return (DCMD_OK);
1955 3072  }
1956 3073  
1957 3074  /*
1958 3075   * *****************************************************************************
1959 3076   * ***************************** smb_oplock_t **********************************
1960 3077   * *****************************************************************************
1961 3078   */
     3079 +
     3080 +typedef struct mdb_smb_oplock {
     3081 +        struct smb_ofile        *excl_open;
     3082 +        uint32_t                ol_state;
     3083 +        int32_t                 cnt_II;
     3084 +        int32_t                 cnt_R;
     3085 +        int32_t                 cnt_RH;
     3086 +        int32_t                 cnt_RHBQ;
     3087 +        int32_t                 waiters;
     3088 +} mdb_smb_oplock_t;
     3089 +
     3090 +/*
     3091 + * Helpers for smbnode_dcmd and smbnode_oplock_dcmd
     3092 + */
     3093 +
     3094 +/*
     3095 + * Read the smb_oplock_t part of the node
     3096 + * addr is the smb_node
     3097 + */
     3098 +static int
     3099 +smb_node_get_oplock(uintptr_t addr, struct mdb_smb_oplock **ol_ret)
     3100 +{
     3101 +        mdb_smb_oplock_t *ol;
     3102 +        static int ol_off;
     3103 +
     3104 +        if (ol_off <= 0) {
     3105 +                ol_off = mdb_ctf_offsetof_by_name(
     3106 +                    "smb_node_t", "n_oplock");
     3107 +                if (ol_off < 0) {
     3108 +                        mdb_warn("cannot lookup: smb_node_t .n_oplock");
     3109 +                        return (DCMD_ERR);
     3110 +                }
     3111 +        }
     3112 +
     3113 +        ol = mdb_alloc(sizeof (*ol), UM_SLEEP | UM_GC);
     3114 +
     3115 +        if (mdb_ctf_vread(ol, SMBSRV_SCOPE "smb_oplock_t",
     3116 +            "mdb_smb_oplock_t", addr + ol_off, 0) < 0) {
     3117 +                mdb_warn("failed to read smb_oplock in node at %p", addr);
     3118 +                return (DCMD_ERR);
     3119 +        }
     3120 +
     3121 +        *ol_ret = ol;
     3122 +        return (DCMD_OK);
     3123 +}
     3124 +
     3125 +/*
     3126 + * Return the oplock count
     3127 + */
     3128 +static int
     3129 +smb_node_oplock_cnt(struct mdb_smb_oplock *ol)
     3130 +{
     3131 +        int ol_cnt = 0;
     3132 +
     3133 +        /* Compute total oplock count. */
     3134 +        if (ol->excl_open != NULL)
     3135 +                ol_cnt++;
     3136 +        ol_cnt += ol->cnt_II;
     3137 +        ol_cnt += ol->cnt_R;
     3138 +        ol_cnt += ol->cnt_RH;
     3139 +
     3140 +        return (ol_cnt);
     3141 +}
     3142 +
     3143 +/*
     3144 + * Show smb_node_t oplock info, and optionally the
     3145 + * list of ofiles with oplocks on this node.
     3146 + * Address is the smb_node_t.
     3147 + */
     3148 +
1962 3149  /*ARGSUSED*/
1963 3150  static int
1964      -smb_oplock(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3151 +smbnode_oplock_dcmd(uintptr_t addr, uint_t flags, int argc,
     3152 +    const mdb_arg_t *argv)
1965 3153  {
1966      -        smb_oplock_t    oplock;
1967      -        uintptr_t       list_addr;
     3154 +        mdb_smb_oplock_t *ol;
     3155 +        int verbose = FALSE;
     3156 +        int ol_cnt, rc;
     3157 +        int fl_off, ll_off;
1968 3158  
     3159 +        if (mdb_getopts(argc, argv,
     3160 +            'v', MDB_OPT_SETBITS, TRUE, &verbose,
     3161 +            NULL) != argc)
     3162 +                return (DCMD_USAGE);
     3163 +
1969 3164          if (!(flags & DCMD_ADDRSPEC))
1970 3165                  return (DCMD_USAGE);
1971 3166  
1972      -        if (mdb_vread(&oplock, sizeof (oplock), addr) != sizeof (oplock)) {
1973      -                mdb_warn("failed to read struct smb_oplock at %p", addr);
1974      -                return (DCMD_ERR);
     3167 +        rc = smb_node_get_oplock(addr, &ol);
     3168 +        if (rc != DCMD_OK)
     3169 +                return (rc);
     3170 +        ol_cnt = smb_node_oplock_cnt(ol);
     3171 +
     3172 +        if (verbose) {
     3173 +                mdb_printf("%<b>%<u>SMB node (oplock) "
     3174 +                    "(%p):%</u>%</b>\n", addr);
     3175 +                mdb_printf("State: 0x%x <%b>\n",
     3176 +                    ol->ol_state,
     3177 +                    ol->ol_state,
     3178 +                    oplock_bits);
     3179 +                mdb_printf("Exclusive Open: %p\n", ol->excl_open);
     3180 +                mdb_printf("cnt_II: %d\n", ol->cnt_II);
     3181 +                mdb_printf("cnt_R: %d\n", ol->cnt_R);
     3182 +                mdb_printf("cnt_RH: %d\n", ol->cnt_RH);
     3183 +                mdb_printf("cnt_RHBQ: %d\n", ol->cnt_RHBQ);
     3184 +                mdb_printf("waiters: %d\n", ol->waiters);
     3185 +        } else {
     3186 +                if (DCMD_HDRSPEC(flags)) {
     3187 +                        mdb_printf("%<u>%-16s %-10s %-16s%</u>\n",
     3188 +                            "NODE", "STATE", "OPLOCKS");
     3189 +                }
     3190 +                mdb_printf("%-16p 0x%x %d\n",
     3191 +                    addr, ol->ol_state, ol_cnt);
1975 3192          }
1976 3193  
1977      -        if (oplock.ol_count == 0)
     3194 +        if (ol_cnt == 0)
1978 3195                  return (DCMD_OK);
1979 3196  
     3197 +        GET_OFFSET(fl_off, smb_node_t, n_ofile_list);
     3198 +        GET_OFFSET(ll_off, smb_llist_t, ll_list);
     3199 +
1980 3200          (void) mdb_inc_indent(SMB_DCMD_INDENT);
1981      -        switch (oplock.ol_break) {
1982      -        case SMB_OPLOCK_BREAK_TO_NONE:
1983      -                mdb_printf("Break Pending: BREAK_TO_NONE\n");
1984      -                break;
1985      -        case SMB_OPLOCK_BREAK_TO_LEVEL_II:
1986      -                mdb_printf(
1987      -                    "Break Pending: BREAK_TO_LEVEL_II\n");
1988      -                break;
1989      -        default:
1990      -                break;
1991      -        }
1992 3201  
1993      -        list_addr = addr + OFFSETOF(smb_oplock_t, ol_grants);
1994      -
1995      -        if (mdb_pwalk_dcmd("list", "smboplockgrant",
1996      -            argc, argv, list_addr)) {
1997      -                mdb_warn("failed to walk oplock grants");
     3202 +        if (mdb_pwalk_dcmd("list", "smbofile_oplock",
     3203 +            argc, argv, addr + fl_off + ll_off)) {
     3204 +                mdb_warn("failed to walk ofile oplocks");
1998 3205          }
1999 3206  
2000 3207          (void) mdb_dec_indent(SMB_DCMD_INDENT);
2001 3208  
2002 3209          return (DCMD_OK);
2003 3210  }
2004 3211  
2005 3212  /*
2006      - * ::smbstat
     3213 + * *******************************************************************
     3214 + * (smb) mbuf_t
2007 3215   *
2008      - * Prints SMB requests statistics.
     3216 + * ::smb_mbuf_dump [max_len]
     3217 + * dcmd to dump the data portion of an mbuf_t
     3218 + * stop at max_len
2009 3219   */
2010      -/*ARGSUSED*/
2011 3220  static int
2012      -smb_stats(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3221 +smb_mbuf_dump_dcmd(uintptr_t addr, uint_t flags, int argc,
     3222 +    const mdb_arg_t *argv)
2013 3223  {
2014      -        smb_server_t    *sv;
     3224 +        struct m_hdr mh;
     3225 +        uintptr_t mdata;
     3226 +        int len, max_len;
     3227 +        int dumpptr_flags;
2015 3228  
2016      -        if (!(flags & DCMD_ADDRSPEC))
2017      -                return (DCMD_USAGE);
2018      -
2019      -        sv = mdb_alloc(sizeof (*sv), UM_SLEEP | UM_GC);
2020      -        if (mdb_vread(sv, sizeof (*sv), addr) == -1) {
2021      -                mdb_warn("failed to read server object at %p", addr);
     3229 +        if (mdb_vread(&mh, sizeof (mh), addr) < 0) {
     3230 +                mdb_warn("failed to read mbuf at %p", addr);
2022 3231                  return (DCMD_ERR);
2023 3232          }
2024      -        if (sv->sv_magic != SMB_SERVER_MAGIC) {
2025      -                mdb_warn("not an smb_server_t (%p)>", addr);
2026      -                return (DCMD_ERR);
     3233 +        len = mh.mh_len;
     3234 +        mdata = (uintptr_t)mh.mh_data;
     3235 +
     3236 +        if (argc > 0) {
     3237 +                if (argv[0].a_type == MDB_TYPE_IMMEDIATE)
     3238 +                        max_len = argv[0].a_un.a_val;
     3239 +                else
     3240 +                        max_len = mdb_strtoull(argv[0].a_un.a_str);
     3241 +                if (len > max_len)
     3242 +                        len = max_len;
2027 3243          }
2028      -        mdb_printf(
2029      -            "\n%<b>  nbt   tcp users trees files pipes%</b>\n"
2030      -            "%5d %5d %5d %5d %5d %5d\n",
2031      -            sv->sv_nbt_sess,
2032      -            sv->sv_tcp_sess,
2033      -            sv->sv_users,
2034      -            sv->sv_trees,
2035      -            sv->sv_files,
2036      -            sv->sv_pipes);
     3244 +        if (len <= 0)
     3245 +                return (DCMD_OK);
2037 3246  
     3247 +        if (DCMD_HDRSPEC(flags)) {
     3248 +                mdb_printf("%<u>%-16s %-16s %-12s%</u>\n",
     3249 +                    "mbuf_t", "m_data", "m_len");
     3250 +        }
     3251 +        mdb_printf("%-16p %-16p %-12u\n",
     3252 +            addr, mdata, mh.mh_len);
     3253 +
     3254 +        dumpptr_flags = MDB_DUMP_RELATIVE | MDB_DUMP_ASCII | MDB_DUMP_HEADER;
     3255 +        if (mdb_dumpptr(mdata, len, dumpptr_flags,
     3256 +            (mdb_dumpptr_cb_t)mdb_vread, NULL) < 0)
     3257 +                return (DCMD_ERR);
     3258 +
2038 3259          return (DCMD_OK);
2039 3260  }
2040 3261  
     3262 +static int
     3263 +smb_mbuf_walk_init(mdb_walk_state_t *wsp)
     3264 +{
     3265 +        mbuf_t *m;
     3266 +
     3267 +        if (wsp->walk_addr == NULL) {
     3268 +                mdb_printf("require address of an mbuf_t\n");
     3269 +                return (WALK_ERR);
     3270 +        }
     3271 +        m = mdb_alloc(sizeof (*m), UM_SLEEP | UM_GC);
     3272 +        wsp->walk_data = m;
     3273 +        return (WALK_NEXT);
     3274 +}
     3275 +
     3276 +static int
     3277 +smb_mbuf_walk_step(mdb_walk_state_t *wsp)
     3278 +{
     3279 +        uintptr_t addr = wsp->walk_addr;
     3280 +        mbuf_t *m = wsp->walk_data;
     3281 +        int rc;
     3282 +
     3283 +        if (wsp->walk_addr == 0)
     3284 +                return (WALK_DONE);
     3285 +
     3286 +        if (mdb_vread(m, sizeof (*m), addr) == -1) {
     3287 +                mdb_warn("failed to read mbuf_t at %p", addr);
     3288 +                return (WALK_ERR);
     3289 +        }
     3290 +
     3291 +        rc = wsp->walk_callback(addr, m, wsp->walk_cbdata);
     3292 +        wsp->walk_addr = (uintptr_t)m->m_next;
     3293 +
     3294 +        return (rc);
     3295 +}
     3296 +
2041 3297  /*
2042 3298   * *****************************************************************************
2043 3299   * ******************************** smb_ace_t **********************************
2044 3300   * *****************************************************************************
2045 3301   */
2046 3302  static const ace_type_entry_t   ace_types[ACE_TYPE_TABLEN] =
2047 3303  {
2048 3304          ACE_TYPE_ENTRY(ACE_ACCESS_ALLOWED_ACE_TYPE),
2049 3305          ACE_TYPE_ENTRY(ACE_ACCESS_DENIED_ACE_TYPE),
2050 3306          ACE_TYPE_ENTRY(ACE_SYSTEM_AUDIT_ACE_TYPE),
↓ open down ↓ 40 lines elided ↑ open up ↑
2091 3347              SUCCESSFUL_ACCESS_ACE_FLAG },
2092 3348          { "FAILED_ACCESS_ACE_FLAG", FAILED_ACCESS_ACE_FLAG,
2093 3349              FAILED_ACCESS_ACE_FLAG },
2094 3350          { NULL, 0, 0 }
2095 3351  };
2096 3352  
2097 3353  /*
2098 3354   * ::smbace
2099 3355   */
2100 3356  static int
2101      -smb_ace(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3357 +smbace_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2102 3358  {
2103 3359          smb_ace_t       ace;
2104 3360          int             verbose = FALSE;
2105 3361          const char      *ptr;
2106 3362          int             rc;
2107 3363  
2108 3364          if (mdb_getopts(argc, argv, 'v', MDB_OPT_SETBITS, TRUE, &verbose,
2109 3365              NULL) != argc)
2110 3366                  return (DCMD_USAGE);
2111 3367  
↓ open down ↓ 29 lines elided ↑ open up ↑
2141 3397                      ace.se_hdr.se_type, ace.se_hdr.se_flags, ace.se_mask);
2142 3398          }
2143 3399          rc = smb_sid_print((uintptr_t)ace.se_sid);
2144 3400          mdb_printf("\n");
2145 3401          return (rc);
2146 3402  }
2147 3403  
2148 3404  static int
2149 3405  smb_ace_walk_init(mdb_walk_state_t *wsp)
2150 3406  {
     3407 +        int sal_off;
     3408 +
2151 3409          if (wsp->walk_addr == 0) {
2152 3410                  mdb_printf("smb_ace walk only supports local walks\n");
2153 3411                  return (WALK_ERR);
2154 3412          }
2155 3413  
2156      -        wsp->walk_addr += OFFSETOF(smb_acl_t, sl_sorted);
     3414 +        GET_OFFSET(sal_off, smb_acl_t, sl_sorted);
     3415 +        wsp->walk_addr += sal_off;
2157 3416  
2158 3417          if (mdb_layered_walk("list", wsp) == -1) {
2159 3418                  mdb_warn("failed to walk list of ACEs");
2160 3419                  return (WALK_ERR);
2161 3420          }
2162 3421  
2163 3422          return (WALK_NEXT);
2164 3423  }
2165 3424  
2166 3425  static int
↓ open down ↓ 6 lines elided ↑ open up ↑
2173 3432  /*
2174 3433   * *****************************************************************************
2175 3434   * ******************************** smb_acl_t **********************************
2176 3435   * *****************************************************************************
2177 3436   */
2178 3437  
2179 3438  /*
2180 3439   * ::smbacl
2181 3440   */
2182 3441  static int
2183      -smb_acl(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3442 +smbacl_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2184 3443  {
2185 3444          smb_acl_t       acl;
2186 3445  
2187 3446          /* An smb_acl address is required. */
2188 3447          if (!(flags & DCMD_ADDRSPEC))
2189 3448                  return (DCMD_USAGE);
2190 3449  
2191 3450          if (mdb_vread(&acl, sizeof (acl), addr) != sizeof (acl)) {
2192 3451                  mdb_warn("failed to read struct smb_acl at %p", addr);
2193 3452                  return (DCMD_ERR);
↓ open down ↓ 16 lines elided ↑ open up ↑
2210 3469  /*
2211 3470   * *****************************************************************************
2212 3471   * ********************************* smb_sd_t **********************************
2213 3472   * *****************************************************************************
2214 3473   */
2215 3474  
2216 3475  /*
2217 3476   * ::smbsd
2218 3477   */
2219 3478  static int
2220      -smb_sd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3479 +smbsd_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2221 3480  {
2222 3481          smb_sd_t        sd;
2223 3482          int             rc;
2224 3483  
2225 3484          /*
2226 3485           * An smb_sid address is required.
2227 3486           */
2228 3487          if (!(flags & DCMD_ADDRSPEC))
2229 3488                  return (DCMD_USAGE);
2230 3489  
↓ open down ↓ 67 lines elided ↑ open up ↑
2298 3557   * *****************************************************************************
2299 3558   * ********************************* smb_sid_t *********************************
2300 3559   * *****************************************************************************
2301 3560   */
2302 3561  
2303 3562  /*
2304 3563   * ::smbsid
2305 3564   */
2306 3565  /*ARGSUSED*/
2307 3566  static int
2308      -smb_sid(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3567 +smbsid_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2309 3568  {
2310 3569          /*
2311 3570           * An smb_sid address is required.
2312 3571           */
2313 3572          if (!(flags & DCMD_ADDRSPEC))
2314 3573                  return (DCMD_USAGE);
2315 3574  
2316 3575          return (smb_sid_print(addr));
2317 3576  }
2318 3577  
2319 3578  /*
2320 3579   * smb_sid_print
2321 3580   */
2322 3581  static int
2323 3582  smb_sid_print(uintptr_t addr)
2324 3583  {
2325 3584          smb_sid_t       sid;
2326 3585          smb_sid_t       *psid;
2327 3586          size_t          sid_size;
2328      -        int             i;
2329 3587          uint64_t        authority;
     3588 +        int             ssa_off;
     3589 +        int             i;
2330 3590  
2331      -        sid_size = OFFSETOF(smb_sid_t, sid_subauth);
     3591 +        GET_OFFSET(ssa_off, smb_sid_t, sid_subauth);
     3592 +        sid_size = ssa_off;
2332 3593  
2333 3594          if (mdb_vread(&sid, sid_size, addr) != sid_size) {
2334 3595                  mdb_warn("failed to read struct smb_sid at %p", addr);
2335 3596                  return (DCMD_ERR);
2336 3597          }
2337 3598  
2338 3599          sid_size += sid.sid_subauthcnt * sizeof (sid.sid_subauth[0]);
2339 3600  
2340 3601          psid = mdb_zalloc(sid_size, UM_SLEEP | UM_GC);
2341 3602          if (mdb_vread(psid, sid_size, addr) != sid_size) {
↓ open down ↓ 18 lines elided ↑ open up ↑
2360 3621  /*
2361 3622   * *****************************************************************************
2362 3623   * ********************************* smb_fssd_t ********************************
2363 3624   * *****************************************************************************
2364 3625   */
2365 3626  
2366 3627  /*
2367 3628   * ::smbfssd
2368 3629   */
2369 3630  static int
2370      -smb_fssd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
     3631 +smbfssd_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
2371 3632  {
2372 3633          smb_fssd_t      fssd;
2373 3634          int             rc;
2374 3635  
2375 3636          /*
2376 3637           * An smb_fssd address is required.
2377 3638           */
2378 3639          if (!(flags & DCMD_ADDRSPEC))
2379 3640                  return (DCMD_USAGE);
2380 3641  
↓ open down ↓ 93 lines elided ↑ open up ↑
2474 3735          return (argc);
2475 3736  }
2476 3737  
2477 3738  /*
2478 3739   * smb_obj_expand
2479 3740   */
2480 3741  static int
2481 3742  smb_obj_expand(uintptr_t addr, uint_t opts, const smb_exp_t *x, ulong_t indent)
2482 3743  {
2483 3744          int             rc = 0;
     3745 +        int             ex_off;
2484 3746          int             argc;
2485 3747          mdb_arg_t       argv[SMB_MDB_MAX_OPTS];
2486 3748  
2487 3749          argc = smb_dcmd_setopt(opts | SMB_OPT_WALK, SMB_MDB_MAX_OPTS, argv);
2488 3750  
2489 3751          (void) mdb_inc_indent(indent);
2490 3752          while (x->ex_dcmd) {
2491 3753                  if (x->ex_mask & opts) {
     3754 +                        ex_off = (x->ex_offset)();
     3755 +                        if (ex_off < 0) {
     3756 +                                mdb_warn("failed to get the list offset for %s",
     3757 +                                    x->ex_name);
     3758 +                                rc = ex_off;
     3759 +                                break;
     3760 +                        }
     3761 +
2492 3762                          rc = mdb_pwalk_dcmd("list", x->ex_dcmd, argc, argv,
2493      -                            addr + x->ex_offset);
     3763 +                            addr + ex_off);
2494 3764  
2495 3765                          if (rc) {
2496 3766                                  mdb_warn("failed to walk the list of %s in %p",
2497      -                                    x->ex_name, addr + x->ex_offset);
     3767 +                                    x->ex_name, addr + ex_off);
2498 3768                                  break;
2499 3769                          }
2500 3770                  }
2501 3771                  x++;
2502 3772          }
2503 3773          (void) mdb_dec_indent(indent);
2504 3774          return (rc);
2505 3775  }
2506 3776  
2507 3777  /*
↓ open down ↓ 30 lines elided ↑ open up ↑
2538 3808          mdb_arg_t       cmdarg;
2539 3809  
2540 3810          mdb_inc_indent(2);
2541 3811          mdb_snprintf(cmd, sizeof (cmd), "<.$c%d", 16);
2542 3812          cmdarg.a_type = MDB_TYPE_STRING;
2543 3813          cmdarg.a_un.a_str = cmd;
2544 3814          (void) mdb_call_dcmd("findstack", addr, DCMD_ADDRSPEC, 1, &cmdarg);
2545 3815          mdb_dec_indent(2);
2546 3816          mdb_printf("\n");
2547 3817          return (DCMD_OK);
     3818 +}
     3819 +
     3820 +static void
     3821 +smb_inaddr_ntop(smb_inaddr_t *ina, char *buf, size_t sz)
     3822 +{
     3823 +
     3824 +        switch (ina->a_family) {
     3825 +        case AF_INET:
     3826 +                (void) mdb_snprintf(buf, sz, "%I", ina->a_ipv4);
     3827 +                break;
     3828 +        case AF_INET6:
     3829 +                (void) mdb_snprintf(buf, sz, "%N", &ina->a_ipv6);
     3830 +                break;
     3831 +        default:
     3832 +                (void) mdb_snprintf(buf, sz, "(?)");
     3833 +                break;
     3834 +        }
     3835 +}
     3836 +
     3837 +/*
     3838 + * Get the name for an enum value
     3839 + */
     3840 +static void
     3841 +get_enum(char *out, size_t size, const char *type_str, int val,
     3842 +    const char *prefix)
     3843 +{
     3844 +        mdb_ctf_id_t type_id;
     3845 +        const char *cp;
     3846 +
     3847 +        if (mdb_ctf_lookup_by_name(type_str, &type_id) != 0)
     3848 +                goto errout;
     3849 +        if (mdb_ctf_type_resolve(type_id, &type_id) != 0)
     3850 +                goto errout;
     3851 +        if ((cp = mdb_ctf_enum_name(type_id, val)) == NULL)
     3852 +                goto errout;
     3853 +        if (prefix != NULL) {
     3854 +                size_t len = strlen(prefix);
     3855 +                if (strncmp(cp, prefix, len) == 0)
     3856 +                        cp += len;
     3857 +        }
     3858 +        (void) strncpy(out, cp, size);
     3859 +        return;
     3860 +
     3861 +errout:
     3862 +        mdb_snprintf(out, size, "? (%d)", val);
     3863 +}
     3864 +
     3865 +/*
     3866 + * MDB module linkage information:
     3867 + *
     3868 + * We declare a list of structures describing our dcmds, a list of structures
     3869 + * describing our walkers and a function named _mdb_init to return a pointer
     3870 + * to our module information.
     3871 + */
     3872 +static const mdb_dcmd_t dcmds[] = {
     3873 +        {   "smblist",
     3874 +            "[-seutfdwv]",
     3875 +            "print tree of SMB objects",
     3876 +            smblist_dcmd,
     3877 +            smblist_help },
     3878 +        {   "smbsrv",
     3879 +            "[-seutfdwv]",
     3880 +            "print smb_server information",
     3881 +            smbsrv_dcmd },
     3882 +        {   "smbshare",
     3883 +            ":[-v]",
     3884 +            "print smb_kshare_t information",
     3885 +            smbshare_dcmd },
     3886 +        {   "smbvfs",
     3887 +            ":[-v]",
     3888 +            "print smb_vfs information",
     3889 +            smbvfs_dcmd },
     3890 +        {   "smbnode",
     3891 +            "?[-vps]",
     3892 +            "print smb_node_t information",
     3893 +            smbnode_dcmd,
     3894 +            smbnode_help },
     3895 +        {   "smbsess",
     3896 +            "[-utfdwv]",
     3897 +            "print smb_session_t information",
     3898 +            smbsess_dcmd,
     3899 +            smbsess_help},
     3900 +        {   "smbreq",
     3901 +            ":[-v]",
     3902 +            "print smb_request_t information",
     3903 +            smbreq_dcmd },
     3904 +        {   "smbreq_dump",
     3905 +            ":[-cr] [-o outfile]",
     3906 +            "dump smb_request_t packets (cmd/reply)",
     3907 +            smbreq_dump_dcmd,
     3908 +            smbreq_dump_help,
     3909 +        },
     3910 +        {   "smblock", ":[-v]",
     3911 +            "print smb_lock_t information",
     3912 +            smblock_dcmd },
     3913 +        {   "smbuser",
     3914 +            ":[-vdftq]",
     3915 +            "print smb_user_t information",
     3916 +            smbuser_dcmd,
     3917 +            smbuser_help },
     3918 +        {   "smbtree",
     3919 +            ":[-vdf]",
     3920 +            "print smb_tree_t information",
     3921 +            smbtree_dcmd,
     3922 +            smbtree_help },
     3923 +        {   "smbodir",
     3924 +            ":[-v]",
     3925 +            "print smb_odir_t information",
     3926 +            smbodir_dcmd },
     3927 +        {   "smbofile",
     3928 +            "[-v]",
     3929 +            "print smb_file_t information",
     3930 +            smbofile_dcmd },
     3931 +        {   "smbsrv_leases",
     3932 +            "[-v]",
     3933 +            "print lease table for a server",
     3934 +            smbsrv_leases_dcmd },
     3935 +        {   "smblease",
     3936 +            "[-v]",
     3937 +            "print smb_lease_t information",
     3938 +            smblease_dcmd },
     3939 +        {   "smbnode_oplock", NULL,
     3940 +            "print smb_node_t oplock information",
     3941 +            smbnode_oplock_dcmd },
     3942 +        {   "smbofile_oplock", NULL,
     3943 +            "print smb_ofile_t oplock information",
     3944 +            smbofile_oplock_dcmd },
     3945 +        {   "smbace", "[-v]",
     3946 +            "print smb_ace_t information",
     3947 +            smbace_dcmd },
     3948 +        {   "smbacl", "[-v]",
     3949 +            "print smb_acl_t information",
     3950 +            smbacl_dcmd },
     3951 +        {   "smbsid", "[-v]",
     3952 +            "print smb_sid_t information",
     3953 +            smbsid_dcmd },
     3954 +        {   "smbsd", "[-v]",
     3955 +            "print smb_sd_t information",
     3956 +            smbsd_dcmd },
     3957 +        {   "smbfssd", "[-v]",
     3958 +            "print smb_fssd_t information",
     3959 +            smbfssd_dcmd },
     3960 +        {   "smb_mbuf_dump", ":[max_len]",
     3961 +            "print mbuf_t data",
     3962 +            smb_mbuf_dump_dcmd },
     3963 +        {   "smbdurable",
     3964 +            "[-v]",
     3965 +            "list ofiles on sv->sv_persistid_ht",
     3966 +            smbdurable_dcmd },
     3967 +        {   "smbhashstat",
     3968 +            "[-v]",
     3969 +            "list stats from an smb_hash_t structure",
     3970 +            smbhashstat_dcmd },
     3971 +
     3972 +        { NULL }
     3973 +};
     3974 +
     3975 +static const mdb_walker_t walkers[] = {
     3976 +        {   "smbnode_walker",
     3977 +            "walk list of smb_node_t structures",
     3978 +            smb_node_walk_init,
     3979 +            smb_node_walk_step,
     3980 +            NULL,
     3981 +            NULL },
     3982 +        {   "smbshare_walker",
     3983 +            "walk list of smb_kshare_t structures",
     3984 +            smb_kshare_walk_init,
     3985 +            smb_kshare_walk_step,
     3986 +            NULL,
     3987 +            NULL },
     3988 +        {   "smbvfs_walker",
     3989 +            "walk list of smb_vfs_t structures",
     3990 +            smb_vfs_walk_init,
     3991 +            smb_vfs_walk_step,
     3992 +            NULL,
     3993 +            NULL },
     3994 +        {   "smbace_walker",
     3995 +            "walk list of smb_ace_t structures",
     3996 +            smb_ace_walk_init,
     3997 +            smb_ace_walk_step,
     3998 +            NULL,
     3999 +            NULL },
     4000 +        {   "smb_mbuf_walker",
     4001 +            "walk list of mbuf_t structures",
     4002 +            smb_mbuf_walk_init,
     4003 +            smb_mbuf_walk_step,
     4004 +            NULL,
     4005 +            NULL },
     4006 +        {   "smb_hash_walker",
     4007 +            "walk an smb_hash_t structure",
     4008 +            smb_hash_walk_init,
     4009 +            smb_hash_walk_step,
     4010 +            NULL,
     4011 +            NULL },
     4012 +        {   "smb_hashstat_walker",
     4013 +            "walk the buckets from an smb_hash_t structure",
     4014 +            smb_hashstat_walk_init,
     4015 +            smb_hashstat_walk_step,
     4016 +            NULL,
     4017 +            NULL },
     4018 +
     4019 +        { NULL }
     4020 +};
     4021 +
     4022 +static const mdb_modinfo_t modinfo = {
     4023 +        MDB_API_VERSION, dcmds, walkers
     4024 +};
     4025 +
     4026 +const mdb_modinfo_t *
     4027 +_mdb_init(void)
     4028 +{
     4029 +        return (&modinfo);
2548 4030  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX