Print this page
NEX-16824 SMB client connection setup rework
NEX-17232 SMB client reconnect failures
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Matt Barden <matt.barden@nexenta.com>
and: (improve debug)
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/lib/libsmbfs/smb/iod_wk.c
          +++ new/usr/src/lib/libsmbfs/smb/iod_wk.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 2012 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   * Functions called by the IO deamon (IOD).
  30   31   * Here in the library to simplify testing.
  31   32   */
  32   33  
  33   34  #include <errno.h>
  34   35  #include <fcntl.h>
  35   36  #include <stdio.h>
↓ open down ↓ 16 lines elided ↑ open up ↑
  52   53  #include <netsmb/smb.h>
  53   54  #include <netsmb/smb_lib.h>
  54   55  #include <netsmb/netbios.h>
  55   56  #include <netsmb/nb_lib.h>
  56   57  #include <netsmb/smb_dev.h>
  57   58  
  58   59  #include "charsets.h"
  59   60  #include "private.h"
  60   61  
  61   62  /*
  62      - * Be the reader thread for this VC.
       63 + * The user agent (smbiod) calls smb_iod_connect for the first
       64 + * connection to some server, and if that succeeds, will start a
       65 + * thread running this function, passing the smb_ctx_t
       66 + *
       67 + * This thread now enters the driver and stays there, reading
       68 + * network responses as long as the connection is alive.
  63   69   */
  64   70  int
  65   71  smb_iod_work(smb_ctx_t *ctx)
  66   72  {
  67   73          smbioc_ssn_work_t *work = &ctx->ct_work;
  68      -        int     vcst, err = 0;
       74 +        int     err = 0;
  69   75  
  70   76          DPRINT("server: %s", ctx->ct_srvname);
  71   77  
  72      -        /* Calle should have opened these */
  73      -        if (ctx->ct_tran_fd == -1 || ctx->ct_dev_fd == -1) {
  74      -                err = EINVAL;
  75      -                goto out;
  76      -        }
  77      -
  78   78          /*
  79   79           * This is the reader / reconnect loop.
  80   80           *
  81   81           * We could start with state "idle", but
  82   82           * we know someone wants a connection to
  83   83           * this server, so start in "vcactive".
  84   84           *
  85   85           * XXX: Add some syslog calls in here?
  86   86           */
  87      -        vcst = SMBIOD_ST_VCACTIVE;
  88   87  
  89   88          for (;;) {
  90   89  
  91      -                switch (vcst) {
       90 +                DPRINT("state: %s",
       91 +                    smb_iod_state_name(work->wk_out_state));
       92 +
       93 +                switch (work->wk_out_state) {
  92   94                  case SMBIOD_ST_IDLE:
  93   95                          /*
  94   96                           * Wait for driver requests to arrive
  95   97                           * for this VC, then return here.
  96   98                           * Next state is normally RECONNECT.
  97   99                           */
  98      -                        DPRINT("state: idle");
  99      -                        if (ioctl(ctx->ct_dev_fd,
 100      -                            SMBIOC_IOD_IDLE, &vcst) == -1) {
      100 +                        DPRINT("Call _ioc_idle...");
      101 +                        if (nsmb_ioctl(ctx->ct_dev_fd,
      102 +                            SMBIOC_IOD_IDLE, work) == -1) {
 101  103                                  err = errno;
 102  104                                  DPRINT("ioc_idle: err %d", err);
 103  105                                  goto out;
 104  106                          }
      107 +                        DPRINT("Ret. from _ioc_idle");
 105  108                          continue;
 106  109  
 107  110                  case SMBIOD_ST_RECONNECT:
 108      -                        DPRINT("state: reconnect");
      111 +                        DPRINT("Call _iod_connect...");
 109  112                          err = smb_iod_connect(ctx);
 110      -                        if (err == 0) {
 111      -                                vcst = SMBIOD_ST_VCACTIVE;
      113 +                        if (err == 0)
 112  114                                  continue;
 113      -                        }
 114      -                        DPRINT("_iod_connect: err %d", err);
      115 +                        DPRINT("iod_connect: err %d", err);
 115  116                          /*
 116  117                           * If the error was EAUTH, retry is
 117  118                           * not likely to succeed either, so
 118  119                           * just exit this thread.  The user
 119  120                           * will need to run smbutil to get
 120  121                           * a new thread with new auth info.
 121  122                           */
 122      -                        if (err == EAUTH)
      123 +                        if (err == EAUTH) {
      124 +                                DPRINT("iod_connect: EAUTH (give up)");
 123  125                                  goto out;
 124      -                        vcst = SMBIOD_ST_RCFAILED;
 125      -                        continue;
 126      -
 127      -                case SMBIOD_ST_RCFAILED:
 128      -                        DPRINT("state: rcfailed");
      126 +                        }
 129  127                          /*
 130      -                         * Reconnect failed.  Kill off any
 131      -                         * requests waiting in the driver,
 132      -                         * then get ready to try again.
 133      -                         * Next state is normally IDLE.
      128 +                         * Reconnect failed.  Notify any requests
      129 +                         * that we're not connected, and delay.
      130 +                         * Next state will be IDLE or RECONNECT.
 134  131                           */
 135      -                        if (ioctl(ctx->ct_dev_fd,
 136      -                            SMBIOC_IOD_RCFAIL, &vcst) == -1) {
      132 +                        DPRINT("Call _iod_rcfail...");
      133 +                        if (nsmb_ioctl(ctx->ct_dev_fd,
      134 +                            SMBIOC_IOD_RCFAIL, work) == -1) {
 137  135                                  err = errno;
 138      -                                DPRINT("ioc_rcfail: err %d", err);
      136 +                                DPRINT("iod_rcfail: err %d", err);
 139  137                                  goto out;
 140  138                          }
 141  139                          continue;
 142  140  
 143      -                case SMBIOD_ST_VCACTIVE:
 144      -                        DPRINT("state: active");
 145      -                        if (ioctl(ctx->ct_dev_fd,
      141 +                case SMBIOD_ST_AUTHOK:
      142 +                        /*
      143 +                         * This is where we enter the driver and
      144 +                         * stay there.  While the connection is up
      145 +                         * the VC will have SMBIOD_ST_VCACTIVE
      146 +                         */
      147 +                        DPRINT("Call _iod_work...");
      148 +                        if (nsmb_ioctl(ctx->ct_dev_fd,
 146  149                              SMBIOC_IOD_WORK, work) == -1) {
 147  150                                  err = errno;
 148      -                                DPRINT("ioc_work: err %d", err);
      151 +                                DPRINT("iod_work: err %d", err);
 149  152                                  goto out;
 150  153                          }
 151      -                        vcst = work->wk_out_state;
 152      -                        /*
 153      -                         * Go ahead and close the transport now,
 154      -                         * rather than wait until reconnect to
 155      -                         * this server.
 156      -                         */
 157      -                        close(ctx->ct_tran_fd);
 158      -                        ctx->ct_tran_fd = -1;
      154 +                        DPRINT("Ret. from _ioc_work");
 159  155                          continue;
 160  156  
 161  157                  case SMBIOD_ST_DEAD:
 162      -                        DPRINT("state: dead");
      158 +                        DPRINT("got state=DEAD");
 163  159                          err = 0;
 164  160                          goto out;
 165  161  
 166  162                  default:
 167      -                        DPRINT("state: BAD(%d)", vcst);
      163 +                        DPRINT("Unexpected state: %d (%s)",
      164 +                            work->wk_out_state,
      165 +                            smb_iod_state_name(work->wk_out_state));
 168  166                          err = EFAULT;
 169  167                          goto out;
 170  168                  }
 171  169          }
 172  170  
 173  171  out:
 174      -        if (ctx->ct_tran_fd != -1) {
 175      -                close(ctx->ct_tran_fd);
 176      -                ctx->ct_tran_fd = -1;
 177      -        }
 178  172          if (ctx->ct_dev_fd != -1) {
 179      -                close(ctx->ct_dev_fd);
      173 +                nsmb_close(ctx->ct_dev_fd);
 180  174                  ctx->ct_dev_fd = -1;
 181  175          }
 182  176  
 183  177          return (err);
 184  178  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX