smbiod.c revision 613a2f6ba31e891e3d947a356daf5e563d43c1ce
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * CDDL HEADER START
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * The contents of this file are subject to the terms of the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Common Development and Distribution License (the "License").
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * You may not use this file except in compliance with the License.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * See the License for the specific language governing permissions
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * and limitations under the License.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * When distributing Covered Code, include this CDDL HEADER in each
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * If applicable, add the following below this CDDL HEADER, with the
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * fields enclosed by brackets "[]" replaced with your own identifying
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * information: Portions Copyright [yyyy] [name of copyright owner]
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * CDDL HEADER END
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Use is subject to license terms.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * SMBFS I/O Deamon (smbiod)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#define DPRINT(...) do \
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross#define DPRINT(...) ((void)0)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid iod_dispatch(void *cookie, char *argp, size_t argsz,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross static const int door_attrs =
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Debugging support. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Find out if an IOD is already running.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * If so, we lost a harmless startup race.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * An IOD did start, so exit success.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Create a file for the door.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross tmp_fd = open(door_path, O_RDWR|O_CREAT|O_EXCL, 0600);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Close FDs 0,1,2 so we don't have a TTY, and
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * re-open them on /dev/null so they won't be
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * used for device handles (etc.) later, and
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * we don't have to worry about printf calls
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * or whatever going to these FDs.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross for (i = 0; i < 3; i++) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Exception: If smb_debug, keep stderr */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Become session leader.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Create door service threads with signals blocked.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Setup the door service. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross door_fd = door_create(iod_dispatch, NULL, door_attrs);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross fprintf(stderr, "%s: door_create failed\n", argv[0]);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross fprintf(stderr, "%s: fattach failed\n", argv[0]);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Post the initial alarm, and then just
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * wait for signals.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * If a door call races with the alarm, ignore the alarm.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * It will be rescheduled when the threads go away.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossiod_dispatch(void *cookie, char *argp, size_t argsz,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Verify that the calling process has the same UID.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Paranoia: The door we created has mode 0600, so
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * this check is probably redundant.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * The library uses a NULL arg call to check if
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * the deamon is running. Just return zero.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Otherwise, the arg must be the (fixed size)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * smb_iod_ssn_t
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Try making a connection with the server described by
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * the info in the smb_iod_ssn_t arg. If successful,
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * start an IOD thread to service it, then return to
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * the client side of the door.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * This needs to essentially "clone" the smb_ctx_t
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * from the client side of the door, or at least
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * as much of it as we need while creating a VC.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross bcopy(clnt_ssn, &ctx->ct_iod_ssn, sizeof (ctx->ct_iod_ssn));
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Do the initial connection setup here, so we can
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * report the outcome to the door client.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Create the driver session now, so we don't
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * race with the door client findvc call.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* The rest happens in the iod_work thread. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross err = thr_create(NULL, 0, iod_work, ctx, THR_DETACHED, &tid);
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Given to the new thread.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * free at end of iod_work
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Be the reader thread for some VC.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * This is started by a door call thread, which means
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * this is always at least the 2nd thread, therefore
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * it should never see thr_count==0 or terminating.