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
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
|
↓ open down ↓ |
12 lines elided |
↑ open up ↑ |
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
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>
36 37 #include <string.h>
37 38 #include <stdlib.h>
38 39 #include <unistd.h>
39 40 #include <libintl.h>
40 41
41 42 #include <sys/byteorder.h>
42 43 #include <sys/types.h>
43 44 #include <sys/fcntl.h>
44 45 #include <sys/ioctl.h>
45 46 #include <sys/time.h>
46 47 #include <sys/socket.h>
47 48
48 49 #include <netinet/in.h>
49 50 #include <netinet/tcp.h>
50 51 #include <arpa/inet.h>
51 52
|
↓ 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