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
15359501f7d4b9abebd7b7bf6efd5982a8e7eb27Gordon Ross * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * Copyright 2012 Nexenta Systems, Inc. All rights reserved.
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * SMBFS I/O Daemon (Per-user IOD)
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Rossvoid iod_dispatch(void *cookie, char *argp, size_t argsz,
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross /* set locale and text domain for i18n */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Debugging support. */
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * If a user runs this command (i.e. by accident)
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * don't interfere with any already running IOD.
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * Want all signals blocked, as we're doing
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * synchronous delivery via sigwait below.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross /* Setup the door service. */
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross /* Initializations done. */
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * Post the initial alarm, and then just
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross * wait for signals.
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross /* No threads active for a while. */
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * Door call thread creation raced with
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * the alarm. Ignore this alaram.
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross /* Prevent a race with iod_thr_count */
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross break; /* normal termination */
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross /* Unexpected signal. */
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross fprintf(stderr, "iod_main: unexpected sig=%d\n", sig);
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * We need a reference in -lumem to satisfy check_rtime,
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * else we get build hoise. This is sufficient.
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
a547be5daca7e465ca82df6d179f6b1f8e0cda72Gordon Ross * the daemon 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));
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * Create the driver session first, so that any subsequent
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * requests for the same session will find this one and
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * wait, the same as when a reconnect is triggered.
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * There is still an inherent race here, where two callers
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * both find no VC in the driver, and both come here trying
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * to create the VC. In this case, we want the first one
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * to actually do the VC setup, and the second to proceed
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * as if the VC had been found in the driver. The second
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * caller gets an EEXIST error from the ioctl in this case,
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * which we therefore ignore here so that the caller will
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * go ahead and look again in the driver for the new VC.
613a2f6ba31e891e3d947a356daf5e563d43c1ceGordon Ross if (ioctl(ctx->ct_dev_fd, SMBIOC_SSN_CREATE, &ctx->ct_ssn) < 0) {
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * Do the initial connection setup here, so we can
fabf08ae7a95a47c3e249ee651d83d26f798bcfaGordon Ross * report the outcome to the door client.
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.