xref: /titanic_50/usr/src/lib/libsmbfs/smb/iod_wk.c (revision 3d804dabd641ca3bac12a320ebf63c36c6f3eba0)
1613a2f6bSGordon Ross /*
2613a2f6bSGordon Ross  * CDDL HEADER START
3613a2f6bSGordon Ross  *
4613a2f6bSGordon Ross  * The contents of this file are subject to the terms of the
5613a2f6bSGordon Ross  * Common Development and Distribution License (the "License").
6613a2f6bSGordon Ross  * You may not use this file except in compliance with the License.
7613a2f6bSGordon Ross  *
8613a2f6bSGordon Ross  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9613a2f6bSGordon Ross  * or http://www.opensolaris.org/os/licensing.
10613a2f6bSGordon Ross  * See the License for the specific language governing permissions
11613a2f6bSGordon Ross  * and limitations under the License.
12613a2f6bSGordon Ross  *
13613a2f6bSGordon Ross  * When distributing Covered Code, include this CDDL HEADER in each
14613a2f6bSGordon Ross  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15613a2f6bSGordon Ross  * If applicable, add the following below this CDDL HEADER, with the
16613a2f6bSGordon Ross  * fields enclosed by brackets "[]" replaced with your own identifying
17613a2f6bSGordon Ross  * information: Portions Copyright [yyyy] [name of copyright owner]
18613a2f6bSGordon Ross  *
19613a2f6bSGordon Ross  * CDDL HEADER END
20613a2f6bSGordon Ross  */
21613a2f6bSGordon Ross 
22613a2f6bSGordon Ross /*
23*3d804dabSGordon Ross  * Copyright 2012 Nexenta Systems, Inc.  All rights reserved.
24613a2f6bSGordon Ross  * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
25613a2f6bSGordon Ross  * Use is subject to license terms.
26613a2f6bSGordon Ross  */
27613a2f6bSGordon Ross 
28613a2f6bSGordon Ross /*
29613a2f6bSGordon Ross  * Functions called by the IO deamon (IOD).
30613a2f6bSGordon Ross  * Here in the library to simplify testing.
31613a2f6bSGordon Ross  */
32613a2f6bSGordon Ross 
33613a2f6bSGordon Ross #include <errno.h>
34613a2f6bSGordon Ross #include <fcntl.h>
35613a2f6bSGordon Ross #include <stdio.h>
36613a2f6bSGordon Ross #include <string.h>
37613a2f6bSGordon Ross #include <stdlib.h>
38613a2f6bSGordon Ross #include <unistd.h>
39613a2f6bSGordon Ross #include <libintl.h>
40613a2f6bSGordon Ross 
41613a2f6bSGordon Ross #include <sys/byteorder.h>
42613a2f6bSGordon Ross #include <sys/types.h>
43613a2f6bSGordon Ross #include <sys/fcntl.h>
44613a2f6bSGordon Ross #include <sys/ioctl.h>
45613a2f6bSGordon Ross #include <sys/time.h>
46613a2f6bSGordon Ross #include <sys/socket.h>
47613a2f6bSGordon Ross 
48613a2f6bSGordon Ross #include <netinet/in.h>
49613a2f6bSGordon Ross #include <netinet/tcp.h>
50613a2f6bSGordon Ross #include <arpa/inet.h>
51613a2f6bSGordon Ross 
52613a2f6bSGordon Ross #include <netsmb/smb.h>
53613a2f6bSGordon Ross #include <netsmb/smb_lib.h>
54613a2f6bSGordon Ross #include <netsmb/netbios.h>
55613a2f6bSGordon Ross #include <netsmb/nb_lib.h>
56613a2f6bSGordon Ross #include <netsmb/smb_dev.h>
57613a2f6bSGordon Ross 
58613a2f6bSGordon Ross #include "charsets.h"
59613a2f6bSGordon Ross #include "private.h"
60613a2f6bSGordon Ross 
61613a2f6bSGordon Ross /*
62613a2f6bSGordon Ross  * Be the reader thread for this VC.
63613a2f6bSGordon Ross  */
64613a2f6bSGordon Ross int
smb_iod_work(smb_ctx_t * ctx)65613a2f6bSGordon Ross smb_iod_work(smb_ctx_t *ctx)
66613a2f6bSGordon Ross {
67613a2f6bSGordon Ross 	smbioc_ssn_work_t *work = &ctx->ct_work;
68613a2f6bSGordon Ross 	int	vcst, err = 0;
69613a2f6bSGordon Ross 
70613a2f6bSGordon Ross 	DPRINT("server: %s", ctx->ct_srvname);
71613a2f6bSGordon Ross 
72613a2f6bSGordon Ross 	/* Calle should have opened these */
73613a2f6bSGordon Ross 	if (ctx->ct_tran_fd == -1 || ctx->ct_dev_fd == -1) {
74613a2f6bSGordon Ross 		err = EINVAL;
75613a2f6bSGordon Ross 		goto out;
76613a2f6bSGordon Ross 	}
77613a2f6bSGordon Ross 
78613a2f6bSGordon Ross 	/*
79613a2f6bSGordon Ross 	 * This is the reader / reconnect loop.
80613a2f6bSGordon Ross 	 *
81613a2f6bSGordon Ross 	 * We could start with state "idle", but
82613a2f6bSGordon Ross 	 * we know someone wants a connection to
83613a2f6bSGordon Ross 	 * this server, so start in "vcactive".
84613a2f6bSGordon Ross 	 *
85613a2f6bSGordon Ross 	 * XXX: Add some syslog calls in here?
86613a2f6bSGordon Ross 	 */
87613a2f6bSGordon Ross 	vcst = SMBIOD_ST_VCACTIVE;
88613a2f6bSGordon Ross 
89613a2f6bSGordon Ross 	for (;;) {
90613a2f6bSGordon Ross 
91613a2f6bSGordon Ross 		switch (vcst) {
92613a2f6bSGordon Ross 		case SMBIOD_ST_IDLE:
93613a2f6bSGordon Ross 			/*
94613a2f6bSGordon Ross 			 * Wait for driver requests to arrive
95613a2f6bSGordon Ross 			 * for this VC, then return here.
96613a2f6bSGordon Ross 			 * Next state is normally RECONNECT.
97613a2f6bSGordon Ross 			 */
98613a2f6bSGordon Ross 			DPRINT("state: idle");
99613a2f6bSGordon Ross 			if (ioctl(ctx->ct_dev_fd,
100613a2f6bSGordon Ross 			    SMBIOC_IOD_IDLE, &vcst) == -1) {
101613a2f6bSGordon Ross 				err = errno;
102613a2f6bSGordon Ross 				DPRINT("ioc_idle: err %d", err);
103613a2f6bSGordon Ross 				goto out;
104613a2f6bSGordon Ross 			}
105613a2f6bSGordon Ross 			continue;
106613a2f6bSGordon Ross 
107613a2f6bSGordon Ross 		case SMBIOD_ST_RECONNECT:
108613a2f6bSGordon Ross 			DPRINT("state: reconnect");
109613a2f6bSGordon Ross 			err = smb_iod_connect(ctx);
110613a2f6bSGordon Ross 			if (err == 0) {
111613a2f6bSGordon Ross 				vcst = SMBIOD_ST_VCACTIVE;
112613a2f6bSGordon Ross 				continue;
113613a2f6bSGordon Ross 			}
114613a2f6bSGordon Ross 			DPRINT("_iod_connect: err %d", err);
115613a2f6bSGordon Ross 			/*
116613a2f6bSGordon Ross 			 * If the error was EAUTH, retry is
117613a2f6bSGordon Ross 			 * not likely to succeed either, so
118613a2f6bSGordon Ross 			 * just exit this thread.  The user
119613a2f6bSGordon Ross 			 * will need to run smbutil to get
120613a2f6bSGordon Ross 			 * a new thread with new auth info.
121613a2f6bSGordon Ross 			 */
122613a2f6bSGordon Ross 			if (err == EAUTH)
123613a2f6bSGordon Ross 				goto out;
124613a2f6bSGordon Ross 			vcst = SMBIOD_ST_RCFAILED;
125613a2f6bSGordon Ross 			continue;
126613a2f6bSGordon Ross 
127613a2f6bSGordon Ross 		case SMBIOD_ST_RCFAILED:
128613a2f6bSGordon Ross 			DPRINT("state: rcfailed");
129613a2f6bSGordon Ross 			/*
130613a2f6bSGordon Ross 			 * Reconnect failed.  Kill off any
131613a2f6bSGordon Ross 			 * requests waiting in the driver,
132613a2f6bSGordon Ross 			 * then get ready to try again.
133613a2f6bSGordon Ross 			 * Next state is normally IDLE.
134613a2f6bSGordon Ross 			 */
135613a2f6bSGordon Ross 			if (ioctl(ctx->ct_dev_fd,
136613a2f6bSGordon Ross 			    SMBIOC_IOD_RCFAIL, &vcst) == -1) {
137613a2f6bSGordon Ross 				err = errno;
138613a2f6bSGordon Ross 				DPRINT("ioc_rcfail: err %d", err);
139613a2f6bSGordon Ross 				goto out;
140613a2f6bSGordon Ross 			}
141613a2f6bSGordon Ross 			continue;
142613a2f6bSGordon Ross 
143613a2f6bSGordon Ross 		case SMBIOD_ST_VCACTIVE:
144613a2f6bSGordon Ross 			DPRINT("state: active");
145613a2f6bSGordon Ross 			if (ioctl(ctx->ct_dev_fd,
146613a2f6bSGordon Ross 			    SMBIOC_IOD_WORK, work) == -1) {
147613a2f6bSGordon Ross 				err = errno;
148613a2f6bSGordon Ross 				DPRINT("ioc_work: err %d", err);
149613a2f6bSGordon Ross 				goto out;
150613a2f6bSGordon Ross 			}
151613a2f6bSGordon Ross 			vcst = work->wk_out_state;
152*3d804dabSGordon Ross 			/*
153*3d804dabSGordon Ross 			 * Go ahead and close the transport now,
154*3d804dabSGordon Ross 			 * rather than wait until reconnect to
155*3d804dabSGordon Ross 			 * this server.
156*3d804dabSGordon Ross 			 */
157*3d804dabSGordon Ross 			close(ctx->ct_tran_fd);
158*3d804dabSGordon Ross 			ctx->ct_tran_fd = -1;
159613a2f6bSGordon Ross 			continue;
160613a2f6bSGordon Ross 
161613a2f6bSGordon Ross 		case SMBIOD_ST_DEAD:
162613a2f6bSGordon Ross 			DPRINT("state: dead");
163613a2f6bSGordon Ross 			err = 0;
164613a2f6bSGordon Ross 			goto out;
165613a2f6bSGordon Ross 
166613a2f6bSGordon Ross 		default:
167613a2f6bSGordon Ross 			DPRINT("state: BAD(%d)", vcst);
168613a2f6bSGordon Ross 			err = EFAULT;
169613a2f6bSGordon Ross 			goto out;
170613a2f6bSGordon Ross 		}
171613a2f6bSGordon Ross 	}
172613a2f6bSGordon Ross 
173613a2f6bSGordon Ross out:
174613a2f6bSGordon Ross 	if (ctx->ct_tran_fd != -1) {
175613a2f6bSGordon Ross 		close(ctx->ct_tran_fd);
176613a2f6bSGordon Ross 		ctx->ct_tran_fd = -1;
177613a2f6bSGordon Ross 	}
178613a2f6bSGordon Ross 	if (ctx->ct_dev_fd != -1) {
179613a2f6bSGordon Ross 		close(ctx->ct_dev_fd);
180613a2f6bSGordon Ross 		ctx->ct_dev_fd = -1;
181613a2f6bSGordon Ross 	}
182613a2f6bSGordon Ross 
183613a2f6bSGordon Ross 	return (err);
184613a2f6bSGordon Ross }
185