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)

*** 18,30 **** * * CDDL HEADER END */ /* - * Copyright 2012 Nexenta Systems, Inc. All rights reserved. * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ /* * Functions called by the IO deamon (IOD). * Here in the library to simplify testing. --- 18,31 ---- * * CDDL HEADER END */ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2018 Nexenta Systems, Inc. All rights reserved. */ /* * Functions called by the IO deamon (IOD). * Here in the library to simplify testing.
*** 57,184 **** #include "charsets.h" #include "private.h" /* ! * Be the reader thread for this VC. */ int smb_iod_work(smb_ctx_t *ctx) { smbioc_ssn_work_t *work = &ctx->ct_work; ! int vcst, err = 0; DPRINT("server: %s", ctx->ct_srvname); - /* Calle should have opened these */ - if (ctx->ct_tran_fd == -1 || ctx->ct_dev_fd == -1) { - err = EINVAL; - goto out; - } - /* * This is the reader / reconnect loop. * * We could start with state "idle", but * we know someone wants a connection to * this server, so start in "vcactive". * * XXX: Add some syslog calls in here? */ - vcst = SMBIOD_ST_VCACTIVE; for (;;) { ! switch (vcst) { case SMBIOD_ST_IDLE: /* * Wait for driver requests to arrive * for this VC, then return here. * Next state is normally RECONNECT. */ ! DPRINT("state: idle"); ! if (ioctl(ctx->ct_dev_fd, ! SMBIOC_IOD_IDLE, &vcst) == -1) { err = errno; DPRINT("ioc_idle: err %d", err); goto out; } continue; case SMBIOD_ST_RECONNECT: ! DPRINT("state: reconnect"); err = smb_iod_connect(ctx); ! if (err == 0) { ! vcst = SMBIOD_ST_VCACTIVE; continue; ! } ! DPRINT("_iod_connect: err %d", err); /* * If the error was EAUTH, retry is * not likely to succeed either, so * just exit this thread. The user * will need to run smbutil to get * a new thread with new auth info. */ ! if (err == EAUTH) goto out; ! vcst = SMBIOD_ST_RCFAILED; ! continue; ! ! case SMBIOD_ST_RCFAILED: ! DPRINT("state: rcfailed"); /* ! * Reconnect failed. Kill off any ! * requests waiting in the driver, ! * then get ready to try again. ! * Next state is normally IDLE. */ ! if (ioctl(ctx->ct_dev_fd, ! SMBIOC_IOD_RCFAIL, &vcst) == -1) { err = errno; ! DPRINT("ioc_rcfail: err %d", err); goto out; } continue; ! case SMBIOD_ST_VCACTIVE: ! DPRINT("state: active"); ! if (ioctl(ctx->ct_dev_fd, SMBIOC_IOD_WORK, work) == -1) { err = errno; ! DPRINT("ioc_work: err %d", err); goto out; } ! vcst = work->wk_out_state; ! /* ! * Go ahead and close the transport now, ! * rather than wait until reconnect to ! * this server. ! */ ! close(ctx->ct_tran_fd); ! ctx->ct_tran_fd = -1; continue; case SMBIOD_ST_DEAD: ! DPRINT("state: dead"); err = 0; goto out; default: ! DPRINT("state: BAD(%d)", vcst); err = EFAULT; goto out; } } out: - if (ctx->ct_tran_fd != -1) { - close(ctx->ct_tran_fd); - ctx->ct_tran_fd = -1; - } if (ctx->ct_dev_fd != -1) { ! close(ctx->ct_dev_fd); ctx->ct_dev_fd = -1; } return (err); } --- 58,178 ---- #include "charsets.h" #include "private.h" /* ! * The user agent (smbiod) calls smb_iod_connect for the first ! * connection to some server, and if that succeeds, will start a ! * thread running this function, passing the smb_ctx_t ! * ! * This thread now enters the driver and stays there, reading ! * network responses as long as the connection is alive. */ int smb_iod_work(smb_ctx_t *ctx) { smbioc_ssn_work_t *work = &ctx->ct_work; ! int err = 0; DPRINT("server: %s", ctx->ct_srvname); /* * This is the reader / reconnect loop. * * We could start with state "idle", but * we know someone wants a connection to * this server, so start in "vcactive". * * XXX: Add some syslog calls in here? */ for (;;) { ! DPRINT("state: %s", ! smb_iod_state_name(work->wk_out_state)); ! ! switch (work->wk_out_state) { case SMBIOD_ST_IDLE: /* * Wait for driver requests to arrive * for this VC, then return here. * Next state is normally RECONNECT. */ ! DPRINT("Call _ioc_idle..."); ! if (nsmb_ioctl(ctx->ct_dev_fd, ! SMBIOC_IOD_IDLE, work) == -1) { err = errno; DPRINT("ioc_idle: err %d", err); goto out; } + DPRINT("Ret. from _ioc_idle"); continue; case SMBIOD_ST_RECONNECT: ! DPRINT("Call _iod_connect..."); err = smb_iod_connect(ctx); ! if (err == 0) continue; ! DPRINT("iod_connect: err %d", err); /* * If the error was EAUTH, retry is * not likely to succeed either, so * just exit this thread. The user * will need to run smbutil to get * a new thread with new auth info. */ ! if (err == EAUTH) { ! DPRINT("iod_connect: EAUTH (give up)"); goto out; ! } /* ! * Reconnect failed. Notify any requests ! * that we're not connected, and delay. ! * Next state will be IDLE or RECONNECT. */ ! DPRINT("Call _iod_rcfail..."); ! if (nsmb_ioctl(ctx->ct_dev_fd, ! SMBIOC_IOD_RCFAIL, work) == -1) { err = errno; ! DPRINT("iod_rcfail: err %d", err); goto out; } continue; ! case SMBIOD_ST_AUTHOK: ! /* ! * This is where we enter the driver and ! * stay there. While the connection is up ! * the VC will have SMBIOD_ST_VCACTIVE ! */ ! DPRINT("Call _iod_work..."); ! if (nsmb_ioctl(ctx->ct_dev_fd, SMBIOC_IOD_WORK, work) == -1) { err = errno; ! DPRINT("iod_work: err %d", err); goto out; } ! DPRINT("Ret. from _ioc_work"); continue; case SMBIOD_ST_DEAD: ! DPRINT("got state=DEAD"); err = 0; goto out; default: ! DPRINT("Unexpected state: %d (%s)", ! work->wk_out_state, ! smb_iod_state_name(work->wk_out_state)); err = EFAULT; goto out; } } out: if (ctx->ct_dev_fd != -1) { ! nsmb_close(ctx->ct_dev_fd); ctx->ct_dev_fd = -1; } return (err); }