# HG changeset patch # User Gordon Ross # Date 1302219859 14400 # Node ID 2f33da224406b17c36ea0888e2e655ecc11b4152 # Parent b9e92167922a586f5c1b327a87c93ea31df9164d 849 domain controller "hot fail over" can take forever Reviewed by: Albert Lee Reviewed by: Garrett D'Amore Reviewed by: Richard Lowe Approved by: Richard Lowe diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c --- a/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libmlsvc/common/dssetup_clnt.c Thu Apr 07 19:44:19 2011 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ /* @@ -30,6 +31,7 @@ #include #include #include +#include #include #include @@ -78,19 +80,22 @@ return (0); } +/* + * Check whether our connection to the DC is working. + * Note: Do NOT want to block opening a connection, + * as that would interfere with smbd_dc_monitor + * getting to smbd_dc_update, smb_locate_dc. + */ int dssetup_check_service(void) { - ds_primary_domain_info_t ds_info; - int rc; + char cur_dc[MAXHOSTNAMELEN]; - bzero(&ds_info, sizeof (ds_primary_domain_info_t)); + bzero(cur_dc, sizeof (cur_dc)); + smb_domain_current_dc(cur_dc, sizeof (cur_dc)); - if ((rc = dssetup_get_domain_info(&ds_info)) == 0) { - free(ds_info.nt_domain); - free(ds_info.dns_domain); - free(ds_info.forest); - } + if (smbrdr_echo(cur_dc) < 0) + return (-1); - return (rc); + return (0); } diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h --- a/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libmlsvc/common/libmlsvc.h Thu Apr 07 19:44:19 2011 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBMLSVC_H @@ -59,6 +60,7 @@ */ extern boolean_t smb_locate_dc(char *, char *, smb_domainex_t *); +extern int smb_ddiscover_wait(void); extern int dssetup_check_service(void); extern void dssetup_clear_domain_info(void); diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_domain.c Thu Apr 07 19:44:19 2011 -0400 @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ #include @@ -154,6 +155,30 @@ } /* + * If domain discovery is running, wait for it to finish. + */ +int +smb_ddiscover_wait(void) +{ + timestruc_t to; + int rc = 0; + + (void) mutex_lock(&smb_dclocator.sdl_mtx); + + if (smb_dclocator.sdl_locate) { + to.tv_sec = SMB_DCLOCATOR_TIMEOUT; + to.tv_nsec = 0; + rc = cond_reltimedwait(&smb_dclocator.sdl_cv, + &smb_dclocator.sdl_mtx, &to); + } + + (void) mutex_unlock(&smb_dclocator.sdl_mtx); + + return (rc); +} + + +/* * ========================================================== * DC discovery functions * ========================================================== diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c --- a/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libmlsvc/common/mlsvc_init.c Thu Apr 07 19:44:19 2011 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ #include @@ -101,12 +102,17 @@ for (;;) { (void) sleep(MLSVC_TIMECHECK_INTERVAL); - if (smb_config_get_secmode() == SMB_SECMODE_DOMAIN) { - if (!smb_domain_getinfo(&di)) - continue; + if (smb_config_get_secmode() != SMB_SECMODE_DOMAIN) + continue; - ndr_srvsvc_timecheck(di.d_dc, di.d_primary.di_nbname); - } + /* Avoid interfering with DC discovery. */ + if (smb_ddiscover_wait() != 0) + continue; + + if (!smb_domain_getinfo(&di)) + continue; + + ndr_srvsvc_timecheck(di.d_dc, di.d_primary.di_nbname); } /*NOTREACHED*/ diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c --- a/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libmlsvc/common/netr_logon.c Thu Apr 07 19:44:19 2011 -0400 @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ /* @@ -155,7 +156,9 @@ (void) smb_getdomainname(resource_domain, SMB_PI_MAX_DOMAIN); - if (!smb_domain_getinfo(&di)) { + /* Avoid interfering with DC discovery. */ + if (smb_ddiscover_wait() != 0 || + !smb_domain_getinfo(&di)) { netr_invalidate_chain(); return (NT_STATUS_CANT_ACCESS_DOMAIN_INFO); } diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libsmb/common/libsmb.h --- a/usr/src/lib/smbsrv/libsmb/common/libsmb.h Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libsmb/common/libsmb.h Thu Apr 07 19:44:19 2011 -0400 @@ -21,6 +21,7 @@ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LIBSMB_H @@ -665,6 +666,7 @@ smb_domain_t *); void smb_domain_set_trust_info(char *, char *, char *, uint32_t, uint32_t, uint32_t, smb_domain_t *); +void smb_domain_current_dc(char *buf, size_t len); typedef struct smb_gsid { smb_sid_t *gs_sid; diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libsmb/common/mapfile-vers --- a/usr/src/lib/smbsrv/libsmb/common/mapfile-vers Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libsmb/common/mapfile-vers Thu Apr 07 19:44:19 2011 -0400 @@ -19,6 +19,7 @@ # # # Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2011 Nexenta Systems, Inc. All rights reserved. # # @@ -124,6 +125,7 @@ smb_ctxbuf_printf; smb_dlclose; smb_dlopen; + smb_domain_current_dc; smb_domain_end_update; smb_domain_fini; smb_domain_getinfo; diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libsmb/common/smb_domain.c --- a/usr/src/lib/smbsrv/libsmb/common/smb_domain.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libsmb/common/smb_domain.c Thu Apr 07 19:44:19 2011 -0400 @@ -21,6 +21,8 @@ /* * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ /* @@ -301,6 +303,16 @@ } /* + * Get the name of the current DC (if any) + * Does NOT block. + */ +void +smb_domain_current_dc(char *buf, size_t len) +{ + smb_dcache_getdc(buf, len); +} + +/* * Transfer the cache to updating state. * In this state any request for reading the cache would * be blocked until the update is finished. diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr.h Thu Apr 07 19:44:19 2011 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ #ifndef _SMBRDR_H_ @@ -258,6 +259,8 @@ #endif } smb_read_andx_rsp_t; +extern int smbrdr_default_timeout; /* seconds */ + /* * smbrdr_netbios.c */ diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_netbios.c Thu Apr 07 19:44:19 2011 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ /* @@ -63,6 +64,8 @@ #define NB_READ_MSG_ERR_UNDERFLOW -3 #define NB_RCV_MSG_ERR_INVTYPE -4 +int smbrdr_default_timeout = 45; /* sec. */ + /* * Semaphore object used to serialize access through NetBIOS exchange. */ @@ -329,7 +332,9 @@ FD_ZERO(&readfds); FD_SET(fd, &readfds); - tval.tv_sec = (timeout == 0) ? 45 : timeout; + if (timeout == 0) + timeout = smbrdr_default_timeout; + tval.tv_sec = timeout; tval.tv_usec = 0; if ((rc = select(fd + 1, &readfds, 0, 0, &tval)) <= 0) { diff -r b9e92167922a -r 2f33da224406 usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c --- a/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c Wed Apr 06 20:07:39 2011 -0500 +++ b/usr/src/lib/smbsrv/libsmbrdr/common/smbrdr_session.c Thu Apr 07 19:44:19 2011 -0400 @@ -20,6 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2011 Nexenta Systems, Inc. All rights reserved. */ /* @@ -211,7 +212,7 @@ char hostname[MAXHOSTNAMELEN]; struct sockaddr_in sin; struct sockaddr_in6 sin6; - int sock, rc; + int sock, rc, tmo; smb_wchar_t unicode_server_name[SMB_PI_MAX_DOMAIN]; char server_name[SMB_PI_MAX_DOMAIN]; char ipstr[INET6_ADDRSTRLEN]; @@ -222,6 +223,15 @@ strerror(errno)); return (-1); } + + /* + * The default connect timeout is very long. + * We want to give up after 45 sec. + */ + tmo = 1000 * smbrdr_default_timeout; + setsockopt(sock, IPPROTO_TCP, TCP_CONN_ABORT_THRESHOLD, + &tmo, sizeof (tmo)); + if (sess->srv_ipaddr.a_family == AF_INET) { bzero(&sin, sizeof (struct sockaddr_in)); sin.sin_family = AF_INET;