4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
27 * Client-side interface to the IO Daemon (IOD)
40 #include <sys/byteorder.h>
41 #include <sys/types.h>
42 #include <sys/fcntl.h>
43 #include <sys/ioctl.h>
45 #include <sys/socket.h>
47 #include <netinet/in.h>
48 #include <netinet/tcp.h>
49 #include <arpa/inet.h>
51 #include <netsmb/smb_lib.h>
52 #include <netsmb/netbios.h>
53 #include <netsmb/nb_lib.h>
54 #include <netsmb/smb_dev.h>
62 * This is constant for the life of a process,
63 * and initialized at startup, so no locks.
65 static char door_path
[64];
66 static int iod_start_timeout
= 10; /* seconds */
69 smb_iod_door_path(void)
74 if (door_path
[0] == '\0') {
76 x
= snprintf(door_path
, sizeof (door_path
),
77 SMBIOD_USR_DOOR
, uid
);
78 assert(x
<= sizeof (door_path
));
85 * Open the door (client side) and
86 * find out if the service is there.
89 smb_iod_open_door(int *fdp
)
96 path
= smb_iod_door_path();
97 fd
= open(path
, O_RDONLY
, 0);
102 * Make sure the IOD is running.
105 memset(&da
, 0, sizeof (da
));
106 da
.rbuf
= (void *) &err
;
107 da
.rsize
= sizeof (err
);
108 rc
= door_call(fd
, &da
);
119 /* This handle controls per-process resources. */
120 (void) fcntl(fd
, F_SETFD
, FD_CLOEXEC
);
127 * Request the creation of our per-user smbiod
128 * via door call to the "main" IOD service.
133 const char *svc_door
= SMBIOD_SVC_DOOR
;
138 fd
= open(svc_door
, O_RDONLY
, 0);
141 DPRINT("%s: open failed, err %d", svc_door
, err
);
145 memset(&da
, 0, sizeof (da
));
146 da
.data_ptr
= (void *) &cmd
;
147 da
.data_size
= sizeof (cmd
);
148 da
.rbuf
= (void *) &err
;
149 da
.rsize
= sizeof (err
);
150 rc
= door_call(fd
, &da
);
154 DPRINT("door_call, err %d", err
);
162 * Get a door handle to the IOD, starting it if necessary.
163 * On success, sets ctx->ct_door_fd
166 smb_iod_start(smb_ctx_t
*ctx
)
171 tmo
= iod_start_timeout
;
172 while ((err
= smb_iod_open_door(&fd
)) != 0) {
177 * We have no per-user IOD yet. Request one.
178 * Do this request every time through the loop
179 * because the master IOD will only start our
180 * per-user IOD if we don't have one, and our
181 * first requst could have happened while we
182 * had an IOD that was doing shutdown.
183 * (Prevents a shutdown/startup race).
189 * Wait for it to get ready.
194 /* Save the door fd. */
195 if (ctx
->ct_door_fd
!= -1)
196 close(ctx
->ct_door_fd
);
197 ctx
->ct_door_fd
= fd
;
202 smb_error(dgettext(TEXT_DOMAIN
,
203 "Could not contact service: %s"),
204 0, "svc:/network/smb/client");
209 * Ask the IOD to connect using the info in ctx.
213 smb_iod_cl_newvc(smb_ctx_t
*ctx
)
218 /* Should already have the IOD door. */
219 if (ctx
->ct_door_fd
< 0)
222 da
.data_ptr
= (void *) &ctx
->ct_iod_ssn
;
223 da
.data_size
= sizeof (ctx
->ct_iod_ssn
);
226 da
.rbuf
= (void *) &err
;
227 da
.rsize
= sizeof (err
);
228 if (door_call(ctx
->ct_door_fd
, &da
) < 0) {
230 DPRINT("door_call, err=%d", err
);