Print this page
NEX-14666 Need to provide SMB 2.1 Client
NEX-17187 panic in smbfs_acl_store
NEX-17231 smbfs create xattr files finds wrong file
NEX-17224 smbfs lookup EINVAL should be ENOENT
NEX-17260 SMB1 client fails to list directory after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Joyce McIntosh <joyce.mcintosh@nexenta.com>
and: (cleanup)
NEX-16818 Add fksmbcl development tool
NEX-17264 SMB client test tp_smbutil_013 fails after NEX-14666
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (fix ref leaks)

Split Close
Expand all
Collapse all
          --- old/usr/src/cmd/mdb/common/modules/nsmb/nsmb.c
          +++ new/usr/src/cmd/mdb/common/modules/nsmb/nsmb.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  
  22   22  /*
  23      - * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  24   23   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  25   24   * Use is subject to license terms.
       25 + *
       26 + * Copyright 2018 Nexenta Systems, Inc.  All rights reserved.
  26   27   */
  27   28  
  28   29  
  29   30  #include <sys/mdb_modapi.h>
  30   31  #include <mdb/mdb_ctf.h>
  31   32  #include <sys/types.h>
  32   33  #include <sys/socket.h>
  33   34  
  34   35  #include <netsmb/smb_conn.h>
  35   36  #include <netsmb/smb_rq.h>
  36   37  #include <netsmb/smb_pass.h>
  37   38  
       39 +#ifdef _KERNEL
       40 +#define NSMB_OBJNAME    "nsmb"
       41 +#else
       42 +#define NSMB_OBJNAME    "libfknsmb.so.1"
       43 +#endif
       44 +
  38   45  #define OPT_VERBOSE     0x0001  /* Be [-v]erbose in dcmd's */
  39   46  #define OPT_RECURSE     0x0002  /* recursive display */
  40   47  
  41   48  /*
  42   49   * We need to read in a private copy
  43   50   * of every string we want to print out.
  44   51   */
  45   52  void
  46   53  print_str(uintptr_t addr)
  47   54  {
↓ open down ↓ 11 lines elided ↑ open up ↑
  59   66  
  60   67  
  61   68  /*
  62   69   * Walker for smb_connobj_t structures, including
  63   70   * smb_vc_t and smb_share_t which "inherit" from it.
  64   71   * Tricky: Exploit the "inheritance" of smb_connobj_t
  65   72   * with common functions for walk_init, walk_next.
  66   73   */
  67   74  typedef struct smb_co_walk_data {
  68   75          uintptr_t       pp;
  69      -        int level;              /* SMBL_SM, SMBL_VC, SMBL_SHARE  */
       76 +        int level;              /* SMBL_SM, SMBL_VC, SMBL_SHARE, ...  */
  70   77          int size;               /* sizeof (union member) */
  71   78          union co_u {
  72   79                  smb_connobj_t   co;     /* copy of the list element */
  73   80                  smb_vc_t        vc;
  74   81                  smb_share_t     ss;
       82 +                smb_fh_t        fh;
  75   83          } u;
  76   84  } smb_co_walk_data_t;
  77   85  
  78   86  /*
  79   87   * Common walk_init for walking structs inherited
  80   88   * from smb_connobj_t (smb_vc_t, smb_share_t)
  81   89   */
  82   90  int
  83   91  smb_co_walk_init(mdb_walk_state_t *wsp, int level)
  84   92  {
↓ open down ↓ 16 lines elided ↑ open up ↑
 101  109          switch (level) {
 102  110          case SMBL_SM:
 103  111                  smbw->size = sizeof (smbw->u.co);
 104  112                  break;
 105  113          case SMBL_VC:
 106  114                  smbw->size = sizeof (smbw->u.vc);
 107  115                  break;
 108  116          case SMBL_SHARE:
 109  117                  smbw->size = sizeof (smbw->u.ss);
 110  118                  break;
      119 +        case SMBL_FH:
      120 +                smbw->size = sizeof (smbw->u.fh);
      121 +                break;
 111  122          default:
 112  123                  smbw->size = sizeof (smbw->u);
 113  124                  break;
 114  125          }
 115  126  
 116  127          /*
 117  128           * Read in the parent object.  Just need the
 118  129           * invariant part (smb_connobj_t) so we can
 119  130           * get the list of children below it.
 120  131           */
↓ open down ↓ 18 lines elided ↑ open up ↑
 139  150  smb_vc_walk_init(mdb_walk_state_t *wsp)
 140  151  {
 141  152          GElf_Sym sym;
 142  153  
 143  154          if (wsp->walk_addr != NULL) {
 144  155                  mdb_warn("::walk smb_vc only supports global walks\n");
 145  156                  return (WALK_ERR);
 146  157          }
 147  158  
 148  159          /* Locate the VC list head. */
 149      -        if (mdb_lookup_by_obj("nsmb", "smb_vclist", &sym)) {
      160 +        if (mdb_lookup_by_obj(NSMB_OBJNAME, "smb_vclist", &sym)) {
 150  161                  mdb_warn("failed to lookup `smb_vclist'\n");
 151  162                  return (WALK_ERR);
 152  163          }
 153  164          wsp->walk_addr = sym.st_value;
 154  165  
 155  166          return (smb_co_walk_init(wsp, SMBL_VC));
 156  167  }
 157  168  
 158  169  /*
 159  170   * Walk the share list below some VC.
↓ open down ↓ 7 lines elided ↑ open up ↑
 167  178           */
 168  179          if (wsp->walk_addr == 0) {
 169  180                  mdb_warn("::walk smb_ss does not support global walks\n");
 170  181                  return (WALK_ERR);
 171  182          }
 172  183  
 173  184          return (smb_co_walk_init(wsp, SMBL_SHARE));
 174  185  }
 175  186  
 176  187  /*
      188 + * Walk the file hande list below some share.
      189 + */
      190 +int
      191 +smb_fh_walk_init(mdb_walk_state_t *wsp)
      192 +{
      193 +
      194 +        /*
      195 +         * Initial walk_addr is address of parent (share)
      196 +         */
      197 +        if (wsp->walk_addr == 0) {
      198 +                mdb_warn("::walk smb_fh does not support global walks\n");
      199 +                return (WALK_ERR);
      200 +        }
      201 +
      202 +        return (smb_co_walk_init(wsp, SMBL_FH));
      203 +}
      204 +
      205 +/*
 177  206   * Common walk_step for walking structs inherited
 178  207   * from smb_connobj_t (smb_vc_t, smb_share_t)
 179  208   */
 180  209  int
 181  210  smb_co_walk_step(mdb_walk_state_t *wsp)
 182  211  {
 183  212          smb_co_walk_data_t *smbw = wsp->walk_data;
 184  213          int status;
 185  214  
 186  215          if (wsp->walk_addr == NULL)
↓ open down ↓ 21 lines elided ↑ open up ↑
 208  237   * all VCs, and optionally all shares under each VC.
 209  238   */
 210  239  
 211  240  typedef struct smb_co_cbdata {
 212  241          int flags;              /* OPT_...  */
 213  242          int printed_header;
 214  243          mdb_ctf_id_t ctf_id;
 215  244  } smb_co_cbdata_t;
 216  245  
 217  246  /*
      247 + * Call-back function for walking a file handle list.
      248 + */
      249 +/* ARGSUSED */
      250 +int
      251 +smb_fh_cb(uintptr_t addr, const void *data, void *arg)
      252 +{
      253 +        const smb_fh_t *fhp = data;
      254 +        // smb_co_cbdata_t *cbd = arg;
      255 +
      256 +        mdb_inc_indent(2);
      257 +        mdb_printf(" %-p", addr);
      258 +        if (fhp->fh_fid2.fid_volatile != 0) {
      259 +                mdb_printf("\t0x%llx\n",
      260 +                    (long long) fhp->fh_fid2.fid_volatile);
      261 +        } else {
      262 +                mdb_printf("\t0x%x\n", fhp->fh_fid1);
      263 +        }
      264 +
      265 +        mdb_dec_indent(2);
      266 +
      267 +        return (WALK_NEXT);
      268 +}
      269 +
      270 +/*
 218  271   * Call-back function for walking a share list.
 219  272   */
 220  273  int
 221  274  smb_ss_cb(uintptr_t addr, const void *data, void *arg)
 222  275  {
 223  276          const smb_share_t *ssp = data;
 224  277          smb_co_cbdata_t *cbd = arg;
      278 +        uint32_t tid;
 225  279  
 226      -        mdb_printf(" %-p\t%s\n", addr, ssp->ss_name);
      280 +        tid = ssp->ss2_tree_id;
      281 +        if (tid == 0)
      282 +                tid = ssp->ss_tid;
 227  283  
 228      -        if (cbd->flags & OPT_VERBOSE) {
      284 +        mdb_printf(" %-p\t0x%x\t%s\n", addr, tid, ssp->ss_name);
      285 +
      286 +        if (cbd->flags & OPT_RECURSE) {
 229  287                  mdb_inc_indent(2);
 230      -                /* Anything wanted here? */
      288 +                if (mdb_pwalk("nsmb_fh", smb_fh_cb, cbd, addr) < 0) {
      289 +                        mdb_warn("failed to walk 'nsmb_fh'");
      290 +                        /* Don't: return (WALK_ERR); */
      291 +                }
 231  292                  mdb_dec_indent(2);
 232  293          }
 233  294  
 234  295          return (WALK_NEXT);
 235  296  }
 236  297  
 237  298  static const char *
 238  299  vcstate_str(smb_co_cbdata_t *cbd, int stval)
 239  300  {
 240  301          static const char prefix[] = "SMBIOD_ST_";
↓ open down ↓ 160 lines elided ↑ open up ↑
 401  462          status = wsp->walk_callback(wsp->walk_addr, &rq,
 402  463              wsp->walk_cbdata);
 403  464  
 404  465          wsp->walk_addr = (uintptr_t)rq.sr_link.tqe_next;
 405  466  
 406  467          return (status);
 407  468  }
 408  469  
 409  470  typedef struct rqlist_cbdata {
 410  471          int printed_header;
      472 +        int vcflags;
 411  473          uintptr_t uid;          /* optional filtering by UID */
 412  474  } rqlist_cbdata_t;
 413  475  
 414  476  int
 415  477  rqlist_cb(uintptr_t addr, const void *data, void *arg)
 416  478  {
 417  479          const smb_rq_t *rq = data;
 418  480          rqlist_cbdata_t *cbd = arg;
 419  481  
 420  482          if (cbd->printed_header == 0) {
 421  483                  cbd->printed_header = 1;
 422  484                  mdb_printf("// smb_rq_t MID cmd sr_state sr_flags\n");
 423  485          }
 424  486  
 425  487          mdb_printf(" %-p", addr);       /* smb_rq_t */
 426      -        mdb_printf(" x%04x", rq->sr_mid);
 427      -        mdb_printf(" x%02x", rq->sr_cmd);
      488 +        if ((cbd->vcflags & SMBV_SMB2) != 0) {
      489 +                mdb_printf(" x%04llx", (long long)rq->sr2_messageid);
      490 +                mdb_printf(" x%02x", rq->sr2_command);
      491 +        } else {
      492 +                mdb_printf(" x%04x", rq->sr_mid);
      493 +                mdb_printf(" x%02x", rq->sr_cmd);
      494 +        }
 428  495          mdb_printf(" %d", rq->sr_state);
 429  496          mdb_printf(" x%x", rq->sr_flags);
 430  497          mdb_printf("\n");
 431  498  
 432  499          return (WALK_NEXT);
 433  500  }
 434  501  
 435  502  /*ARGSUSED*/
 436  503  int
 437  504  rqlist_dcmd(uintptr_t addr, uint_t flags, int argc, const mdb_arg_t *argv)
 438  505  {
 439  506          rqlist_cbdata_t cbd;
      507 +        smb_vc_t *vcp;
      508 +        size_t vcsz;
 440  509  
 441  510          memset(&cbd, 0, sizeof (cbd));
 442  511  
      512 +        /* Need the VC again to get  */
      513 +        vcsz = sizeof (*vcp);
      514 +        vcp = mdb_alloc(vcsz, UM_SLEEP | UM_GC);
      515 +        if (mdb_vread(vcp, vcsz, addr) != vcsz) {
      516 +                mdb_warn("cannot read VC from %p", addr);
      517 +                return (DCMD_ERR);
      518 +        }
      519 +        cbd.vcflags = vcp->vc_flags;
      520 +
 443  521          /*
 444  522           * Initial walk_addr is address of parent (VC)
 445  523           */
 446  524          if (!(flags & DCMD_ADDRSPEC)) {
 447  525                  mdb_warn("address required\n");
 448  526                  return (DCMD_ERR);
 449  527          }
 450  528  
 451  529          if (mdb_pwalk("nsmb_rqlist", rqlist_cb, &cbd, addr) == -1) {
 452  530                  mdb_warn("failed to walk 'nsmb_rqlist'");
↓ open down ↓ 11 lines elided ↑ open up ↑
 464  542  static int
 465  543  pwtree_walk_init(mdb_walk_state_t *wsp)
 466  544  {
 467  545          GElf_Sym sym;
 468  546  
 469  547          if (wsp->walk_addr != NULL) {
 470  548                  mdb_warn("pwtree walk only supports global walks\n");
 471  549                  return (WALK_ERR);
 472  550          }
 473  551  
 474      -        if (mdb_lookup_by_obj("nsmb", "smb_ptd", &sym) == -1) {
      552 +        if (mdb_lookup_by_obj(NSMB_OBJNAME, "smb_ptd", &sym) == -1) {
 475  553                  mdb_warn("failed to find symbol 'smb_ptd'");
 476  554                  return (WALK_ERR);
 477  555          }
 478  556  
 479  557          wsp->walk_addr = (uintptr_t)sym.st_value;
 480  558  
 481  559          if (mdb_layered_walk("avl", wsp) == -1) {
 482  560                  mdb_warn("failed to walk 'avl'\n");
 483  561                  return (WALK_ERR);
 484  562          }
↓ open down ↓ 108 lines elided ↑ open up ↑
 593  671                  "list smb_passid_t (password tree)",
 594  672                  pwtree_dcmd, pwtree_help },
 595  673          {NULL}
 596  674  };
 597  675  
 598  676  static const mdb_walker_t walkers[] = {
 599  677          { "nsmb_vc", "walk nsmb VC list",
 600  678                  smb_vc_walk_init, smb_co_walk_step, NULL },
 601  679          { "nsmb_ss", "walk nsmb share list for some VC",
 602  680                  smb_ss_walk_init, smb_co_walk_step, NULL },
      681 +        { "nsmb_fh", "walk nsmb share list for some VC",
      682 +                smb_fh_walk_init, smb_co_walk_step, NULL },
 603  683          { "nsmb_rqlist", "walk request list for some VC",
 604  684                  rqlist_walk_init, rqlist_walk_step, NULL },
 605  685          { "nsmb_pwtree", "walk passord AVL tree",
 606  686                  pwtree_walk_init, pwtree_walk_step, NULL },
 607  687          {NULL}
 608  688  };
 609  689  
 610  690  static const mdb_modinfo_t modinfo = {
 611  691          MDB_API_VERSION,
 612  692          dcmds,
 613  693          walkers
 614  694  };
 615  695  
 616  696  const mdb_modinfo_t *
 617  697  _mdb_init(void)
 618  698  {
 619  699          return (&modinfo);
 620  700  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX