16139Sjb150015 /*
26139Sjb150015 * CDDL HEADER START
36139Sjb150015 *
46139Sjb150015 * The contents of this file are subject to the terms of the
56139Sjb150015 * Common Development and Distribution License (the "License").
66139Sjb150015 * You may not use this file except in compliance with the License.
76139Sjb150015 *
86139Sjb150015 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
96139Sjb150015 * or http://www.opensolaris.org/os/licensing.
106139Sjb150015 * See the License for the specific language governing permissions
116139Sjb150015 * and limitations under the License.
126139Sjb150015 *
136139Sjb150015 * When distributing Covered Code, include this CDDL HEADER in each
146139Sjb150015 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
156139Sjb150015 * If applicable, add the following below this CDDL HEADER, with the
166139Sjb150015 * fields enclosed by brackets "[]" replaced with your own identifying
176139Sjb150015 * information: Portions Copyright [yyyy] [name of copyright owner]
186139Sjb150015 *
196139Sjb150015 * CDDL HEADER END
206139Sjb150015 */
216139Sjb150015 /*
2212065SKeyur.Desai@Sun.COM * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
236139Sjb150015 */
246139Sjb150015
256139Sjb150015 /*
266139Sjb150015 * General Structures Layout
276139Sjb150015 * -------------------------
286139Sjb150015 *
296139Sjb150015 * This is a simplified diagram showing the relationship between most of the
306139Sjb150015 * main structures.
316139Sjb150015 *
326139Sjb150015 * +-------------------+
336139Sjb150015 * | SMB_SERVER |
346139Sjb150015 * +-------------------+
356139Sjb150015 * |
366139Sjb150015 * |
376139Sjb150015 * v
386139Sjb150015 * +-------------------+ +-------------------+ +-------------------+
396139Sjb150015 * | SESSION |<----->| SESSION |......| SESSION |
406139Sjb150015 * +-------------------+ +-------------------+ +-------------------+
416139Sjb150015 * |
426139Sjb150015 * |
436139Sjb150015 * v
446139Sjb150015 * +-------------------+ +-------------------+ +-------------------+
456139Sjb150015 * | USER |<----->| USER |......| USER |
466139Sjb150015 * +-------------------+ +-------------------+ +-------------------+
476139Sjb150015 * |
486139Sjb150015 * |
496139Sjb150015 * v
506139Sjb150015 * +-------------------+ +-------------------+ +-------------------+
516139Sjb150015 * | TREE |<----->| TREE |......| TREE |
526139Sjb150015 * +-------------------+ +-------------------+ +-------------------+
536139Sjb150015 * | |
546139Sjb150015 * | |
556139Sjb150015 * | v
566139Sjb150015 * | +-------+ +-------+ +-------+
576139Sjb150015 * | | OFILE |<----->| OFILE |......| OFILE |
586139Sjb150015 * | +-------+ +-------+ +-------+
596139Sjb150015 * |
606139Sjb150015 * |
616139Sjb150015 * v
626139Sjb150015 * +-------+ +------+ +------+
636139Sjb150015 * | ODIR |<----->| ODIR |......| ODIR |
646139Sjb150015 * +-------+ +------+ +------+
656139Sjb150015 *
666139Sjb150015 *
676139Sjb150015 * Module Interface Overview
686139Sjb150015 * -------------------------
696139Sjb150015 *
706139Sjb150015 *
716139Sjb150015 * +===================================+
726139Sjb150015 * | smbd daemon |
736139Sjb150015 * +===================================+
746139Sjb150015 * | | ^
756139Sjb150015 * | | |
766139Sjb150015 * User | | |
776139Sjb150015 * -----------|--------------|----------------|--------------------------------
786139Sjb150015 * Kernel | | |
796139Sjb150015 * | | |
806139Sjb150015 * | | |
816139Sjb150015 * +=========|==============|================|=================+
826139Sjb150015 * | v v | |
836139Sjb150015 * | +-----------+ +--------------------+ +------------------+ |
846139Sjb150015 * | | IO | | Kernel Door Server | | User Door Servers| |
856139Sjb150015 * | | Interface | | Interface | | Interface | |
866139Sjb150015 * | +-----------+ +--------------------+ +------------------+ |
876139Sjb150015 * | | | ^ ^ |
886139Sjb150015 * | v v | | | +=========+
896139Sjb150015 * | +-----------------------------------+ | | | |
906139Sjb150015 * | + SMB Server Management (this file) |<------------------| ZFS |
916139Sjb150015 * | +-----------------------------------+ | | | |
926139Sjb150015 * | | | | Module |
936139Sjb150015 * | +-----------------------------------+ | | | |
946139Sjb150015 * | + SMB Server Internal Layers |------+ | +=========+
956139Sjb150015 * | +-----------------------------------+ |
966139Sjb150015 * | |
976139Sjb150015 * | |
986139Sjb150015 * +===========================================================+
996139Sjb150015 *
1006139Sjb150015 *
1016139Sjb150015 * Server State Machine
1026139Sjb150015 * --------------------
1036139Sjb150015 * |
1046139Sjb150015 * | T0
1056139Sjb150015 * |
1066139Sjb150015 * v
1076139Sjb150015 * +-----------------------------+
1086139Sjb150015 * | SMB_SERVER_STATE_CREATED |
1096139Sjb150015 * +-----------------------------+
1106139Sjb150015 * |
1116139Sjb150015 * | T1
1126139Sjb150015 * |
1136139Sjb150015 * v
1146139Sjb150015 * +-----------------------------+
1156139Sjb150015 * | SMB_SERVER_STATE_CONFIGURED |
1166139Sjb150015 * +-----------------------------+
1176139Sjb150015 * |
1186139Sjb150015 * | T2
1196139Sjb150015 * |
1206139Sjb150015 * v
1216139Sjb150015 * +-----------------------------+
12211963SAfshin.Ardakani@Sun.COM * | SMB_SERVER_STATE_RUNNING / |
12311963SAfshin.Ardakani@Sun.COM * | SMB_SERVER_STATE_STOPPING |
1246139Sjb150015 * +-----------------------------+
1256139Sjb150015 * |
1266139Sjb150015 * | T3
1276139Sjb150015 * |
1286139Sjb150015 * v
1296139Sjb150015 * +-----------------------------+
1306139Sjb150015 * | SMB_SERVER_STATE_DELETING |
1316139Sjb150015 * +-----------------------------+
1326139Sjb150015 * |
1336139Sjb150015 * |
1346139Sjb150015 * |
1356139Sjb150015 * v
1366139Sjb150015 *
1376139Sjb150015 * States
1386139Sjb150015 * ------
1396139Sjb150015 *
1406139Sjb150015 * SMB_SERVER_STATE_CREATED
1416139Sjb150015 *
1426139Sjb150015 * This is the state of the server just after creation.
1436139Sjb150015 *
1446139Sjb150015 * SMB_SERVER_STATE_CONFIGURED
1456139Sjb150015 *
1466139Sjb150015 * The server has been configured.
1476139Sjb150015 *
1486139Sjb150015 * SMB_SERVER_STATE_RUNNING
1496139Sjb150015 *
1506139Sjb150015 * The server has been started. While in this state the threads listening on
151*13138SJose.Borrego@Sun.COM * the sockets are started.
1526139Sjb150015 *
153*13138SJose.Borrego@Sun.COM * When a client establishes a connection the thread listening dispatches
154*13138SJose.Borrego@Sun.COM * a task with the new session as an argument. If the dispatch fails the new
155*13138SJose.Borrego@Sun.COM * session context is destroyed.
1566139Sjb150015 *
1576139Sjb150015 * SMB_SERVER_STATE_STOPPING
1586139Sjb150015 *
1596139Sjb150015 * The threads listening on the NBT and TCP sockets are being terminated.
1606139Sjb150015 *
1616139Sjb150015 *
1626139Sjb150015 * Transitions
1636139Sjb150015 * -----------
1646139Sjb150015 *
1656139Sjb150015 * Transition T0
1666139Sjb150015 *
1676139Sjb150015 * The daemon smbd triggers its creation by opening the smbsrv device. If
1686139Sjb150015 * the zone where the daemon lives doesn't have an smb server yet it is
1696139Sjb150015 * created.
1706139Sjb150015 *
1716139Sjb150015 * smb_drv_open() --> smb_server_create()
1726139Sjb150015 *
1736139Sjb150015 * Transition T1
1746139Sjb150015 *
1756139Sjb150015 * This transition occurs in smb_server_configure(). It is triggered by the
1766139Sjb150015 * daemon through an Ioctl.
1776139Sjb150015 *
1786139Sjb150015 * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure()
1796139Sjb150015 *
1806139Sjb150015 * Transition T2
1816139Sjb150015 *
1826139Sjb150015 * This transition occurs in smb_server_start(). It is triggered by the
1836139Sjb150015 * daemon through an Ioctl.
1846139Sjb150015 *
1856139Sjb150015 * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start()
1866139Sjb150015 *
1876139Sjb150015 * Transition T3
1886139Sjb150015 *
1896139Sjb150015 * This transition occurs in smb_server_delete(). It is triggered by the
1906139Sjb150015 * daemon when closing the smbsrv device
1916139Sjb150015 *
1926139Sjb150015 * smb_drv_close() --> smb_server_delete()
1936139Sjb150015 *
1946139Sjb150015 * Comments
1956139Sjb150015 * --------
1966139Sjb150015 *
1976139Sjb150015 * This files assumes that there will one SMB server per zone. For now the
1986139Sjb150015 * smb server works only in global zone. There's nothing in this file preventing
1996139Sjb150015 * an smb server from being created in a non global zone. That limitation is
2006139Sjb150015 * enforced in user space.
2016139Sjb150015 */
2026139Sjb150015
2036139Sjb150015 #include <sys/strsubr.h>
2046139Sjb150015 #include <sys/cmn_err.h>
2056139Sjb150015 #include <sys/priv.h>
2066139Sjb150015 #include <sys/socketvar.h>
2076139Sjb150015 #include <sys/zone.h>
20810966SJordan.Brown@Sun.COM #include <netinet/in.h>
20910966SJordan.Brown@Sun.COM #include <netinet/in_systm.h>
21010966SJordan.Brown@Sun.COM #include <netinet/ip.h>
21110966SJordan.Brown@Sun.COM #include <netinet/ip_icmp.h>
21210966SJordan.Brown@Sun.COM #include <netinet/ip_var.h>
21310966SJordan.Brown@Sun.COM #include <netinet/tcp.h>
2146139Sjb150015 #include <smbsrv/smb_kproto.h>
21510966SJordan.Brown@Sun.COM #include <smbsrv/string.h>
2166139Sjb150015 #include <smbsrv/netbios.h>
2176139Sjb150015 #include <smbsrv/smb_fsops.h>
2187052Samw #include <smbsrv/smb_share.h>
21911963SAfshin.Ardakani@Sun.COM #include <smbsrv/smb_door.h>
2206432Sas200622 #include <smbsrv/smb_kstat.h>
2216139Sjb150015
2226139Sjb150015 extern void smb_reply_notify_change_request(smb_request_t *);
2236139Sjb150015
224*13138SJose.Borrego@Sun.COM typedef struct {
225*13138SJose.Borrego@Sun.COM smb_listener_daemon_t *ra_listener;
226*13138SJose.Borrego@Sun.COM smb_session_t *ra_session;
227*13138SJose.Borrego@Sun.COM } smb_receiver_arg_t;
228*13138SJose.Borrego@Sun.COM
22912508Samw@Sun.COM static void smb_server_kstat_init(smb_server_t *);
2306139Sjb150015 static void smb_server_kstat_fini(smb_server_t *);
2316139Sjb150015 static void smb_server_timers(smb_thread_t *, void *);
2326139Sjb150015 static int smb_server_lookup(smb_server_t **);
2336139Sjb150015 static void smb_server_release(smb_server_t *);
2349832Samw@Sun.COM static void smb_server_store_cfg(smb_server_t *, smb_ioc_cfg_t *);
23511963SAfshin.Ardakani@Sun.COM static void smb_server_shutdown(smb_server_t *);
2366139Sjb150015 static int smb_server_fsop_start(smb_server_t *);
2376139Sjb150015 static void smb_server_fsop_stop(smb_server_t *);
23811963SAfshin.Ardakani@Sun.COM static void smb_event_cancel(smb_server_t *, uint32_t);
23911963SAfshin.Ardakani@Sun.COM static uint32_t smb_event_alloc_txid(void);
2406139Sjb150015
241*13138SJose.Borrego@Sun.COM static void smb_server_disconnect_share(smb_llist_t *, const char *);
242*13138SJose.Borrego@Sun.COM static void smb_server_enum_private(smb_llist_t *, smb_svcenum_t *);
243*13138SJose.Borrego@Sun.COM static int smb_server_session_disconnect(smb_llist_t *, const char *,
24410122SJordan.Brown@Sun.COM const char *);
245*13138SJose.Borrego@Sun.COM static int smb_server_fclose(smb_llist_t *, uint32_t);
24612508Samw@Sun.COM static int smb_server_kstat_update(kstat_t *, int);
24712890SJoyce.McIntosh@Sun.COM static int smb_server_legacy_kstat_update(kstat_t *, int);
248*13138SJose.Borrego@Sun.COM static void smb_server_listener_init(smb_server_t *, smb_listener_daemon_t *,
249*13138SJose.Borrego@Sun.COM char *, in_port_t, int);
250*13138SJose.Borrego@Sun.COM static void smb_server_listener_destroy(smb_listener_daemon_t *);
251*13138SJose.Borrego@Sun.COM static int smb_server_listener_start(smb_listener_daemon_t *);
252*13138SJose.Borrego@Sun.COM static void smb_server_listener_stop(smb_listener_daemon_t *);
253*13138SJose.Borrego@Sun.COM static void smb_server_listener(smb_thread_t *, void *);
254*13138SJose.Borrego@Sun.COM static void smb_server_receiver(void *);
255*13138SJose.Borrego@Sun.COM static void smb_server_create_session(smb_listener_daemon_t *, ksocket_t);
256*13138SJose.Borrego@Sun.COM static void smb_server_destroy_session(smb_listener_daemon_t *,
257*13138SJose.Borrego@Sun.COM smb_session_t *);
25810122SJordan.Brown@Sun.COM
25911963SAfshin.Ardakani@Sun.COM int smb_event_debug = 0;
26011963SAfshin.Ardakani@Sun.COM
2616139Sjb150015 static smb_llist_t smb_servers;
2626139Sjb150015
2636139Sjb150015 /*
2646139Sjb150015 * *****************************************************************************
2656139Sjb150015 * **************** Functions called from the device interface *****************
2666139Sjb150015 * *****************************************************************************
2676139Sjb150015 *
26810122SJordan.Brown@Sun.COM * These functions typically have to determine the relevant smb server
26910122SJordan.Brown@Sun.COM * to which the call applies.
2706139Sjb150015 */
2716139Sjb150015
2726139Sjb150015 /*
2736139Sjb150015 * smb_server_svc_init
2746139Sjb150015 *
2757348SJose.Borrego@Sun.COM * This function must be called from smb_drv_attach().
2766139Sjb150015 */
2776139Sjb150015 int
smb_server_svc_init(void)2786139Sjb150015 smb_server_svc_init(void)
2796139Sjb150015 {
2806139Sjb150015 int rc = 0;
2816139Sjb150015
2826139Sjb150015 while (rc == 0) {
2838934SJose.Borrego@Sun.COM if (rc = smb_mbc_init())
2848934SJose.Borrego@Sun.COM continue;
2856139Sjb150015 if (rc = smb_vop_init())
2866139Sjb150015 continue;
2876139Sjb150015 if (rc = smb_node_init())
2886496Sjb150015 continue;
28912890SJoyce.McIntosh@Sun.COM if (rc = smb_oplock_init())
29012890SJoyce.McIntosh@Sun.COM continue;
2916139Sjb150015 if (rc = smb_fem_init())
2926496Sjb150015 continue;
2936139Sjb150015 if (rc = smb_notify_init())
2946496Sjb150015 continue;
2956496Sjb150015 if (rc = smb_net_init())
2966496Sjb150015 continue;
29711963SAfshin.Ardakani@Sun.COM smb_llist_init();
2986139Sjb150015 smb_llist_constructor(&smb_servers, sizeof (smb_server_t),
2996139Sjb150015 offsetof(smb_server_t, sv_lnd));
3006139Sjb150015 return (0);
3016139Sjb150015 }
30211963SAfshin.Ardakani@Sun.COM
30311963SAfshin.Ardakani@Sun.COM smb_llist_fini();
3046496Sjb150015 smb_net_fini();
3056139Sjb150015 smb_notify_fini();
3066139Sjb150015 smb_fem_fini();
3076139Sjb150015 smb_node_fini();
3086139Sjb150015 smb_vop_fini();
3098934SJose.Borrego@Sun.COM smb_mbc_fini();
3106139Sjb150015 return (rc);
3116139Sjb150015 }
3126139Sjb150015
3136139Sjb150015 /*
3146139Sjb150015 * smb_server_svc_fini
3156139Sjb150015 *
3166139Sjb150015 * This function must called from smb_drv_detach(). It will fail if servers
3176139Sjb150015 * still exist.
3186139Sjb150015 */
3196139Sjb150015 int
smb_server_svc_fini(void)3206139Sjb150015 smb_server_svc_fini(void)
3216139Sjb150015 {
3226139Sjb150015 int rc = EBUSY;
3236139Sjb150015
3246139Sjb150015 if (smb_llist_get_count(&smb_servers) == 0) {
32511963SAfshin.Ardakani@Sun.COM smb_llist_fini();
3266496Sjb150015 smb_net_fini();
3276139Sjb150015 smb_notify_fini();
3286139Sjb150015 smb_fem_fini();
3296139Sjb150015 smb_node_fini();
33012890SJoyce.McIntosh@Sun.COM smb_oplock_fini();
3316139Sjb150015 smb_vop_fini();
3328934SJose.Borrego@Sun.COM smb_mbc_fini();
3336139Sjb150015 smb_llist_destructor(&smb_servers);
3346139Sjb150015 rc = 0;
3356139Sjb150015 }
3366139Sjb150015 return (rc);
3376139Sjb150015 }
3386139Sjb150015
3396139Sjb150015 /*
3406139Sjb150015 * smb_server_create
3416139Sjb150015 *
3426139Sjb150015 * This function will fail if there's already a server associated with the
3436139Sjb150015 * caller's zone.
3446139Sjb150015 */
3456139Sjb150015 int
smb_server_create(void)3466139Sjb150015 smb_server_create(void)
3476139Sjb150015 {
3486139Sjb150015 zoneid_t zid;
3496139Sjb150015 smb_server_t *sv;
3506139Sjb150015
3516139Sjb150015 zid = getzoneid();
3526139Sjb150015
3536139Sjb150015 smb_llist_enter(&smb_servers, RW_WRITER);
3546139Sjb150015 sv = smb_llist_head(&smb_servers);
3556139Sjb150015 while (sv) {
35611963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
3576139Sjb150015 if (sv->sv_zid == zid) {
3586139Sjb150015 smb_llist_exit(&smb_servers);
3598167Samw@Sun.COM return (EPERM);
3606139Sjb150015 }
3616139Sjb150015 sv = smb_llist_next(&smb_servers, sv);
3626139Sjb150015 }
3636139Sjb150015
3646139Sjb150015 sv = kmem_zalloc(sizeof (smb_server_t), KM_NOSLEEP);
3656139Sjb150015 if (sv == NULL) {
3666139Sjb150015 smb_llist_exit(&smb_servers);
3676139Sjb150015 return (ENOMEM);
3686139Sjb150015 }
3696139Sjb150015
37011963SAfshin.Ardakani@Sun.COM smb_llist_constructor(&sv->sv_opipe_list, sizeof (smb_opipe_t),
37111963SAfshin.Ardakani@Sun.COM offsetof(smb_opipe_t, p_lnd));
37211963SAfshin.Ardakani@Sun.COM
37311963SAfshin.Ardakani@Sun.COM smb_llist_constructor(&sv->sv_event_list, sizeof (smb_event_t),
37411963SAfshin.Ardakani@Sun.COM offsetof(smb_event_t, se_lnd));
37511963SAfshin.Ardakani@Sun.COM
37612890SJoyce.McIntosh@Sun.COM smb_llist_constructor(&sv->sp_info.sp_list, sizeof (smb_kspooldoc_t),
37712890SJoyce.McIntosh@Sun.COM offsetof(smb_kspooldoc_t, sd_lnd));
37812890SJoyce.McIntosh@Sun.COM
37912890SJoyce.McIntosh@Sun.COM smb_llist_constructor(&sv->sp_info.sp_fidlist,
38012890SJoyce.McIntosh@Sun.COM sizeof (smb_spoolfid_t), offsetof(smb_spoolfid_t, sf_lnd));
38112890SJoyce.McIntosh@Sun.COM
3826139Sjb150015 sv->si_cache_request = kmem_cache_create("smb_request_cache",
3836139Sjb150015 sizeof (smb_request_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3846139Sjb150015 sv->si_cache_session = kmem_cache_create("smb_session_cache",
3856139Sjb150015 sizeof (smb_session_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3866139Sjb150015 sv->si_cache_user = kmem_cache_create("smb_user_cache",
3876139Sjb150015 sizeof (smb_user_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3886139Sjb150015 sv->si_cache_tree = kmem_cache_create("smb_tree_cache",
3896139Sjb150015 sizeof (smb_tree_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3906139Sjb150015 sv->si_cache_ofile = kmem_cache_create("smb_ofile_cache",
3916139Sjb150015 sizeof (smb_ofile_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3926139Sjb150015 sv->si_cache_odir = kmem_cache_create("smb_odir_cache",
3936139Sjb150015 sizeof (smb_odir_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
39411963SAfshin.Ardakani@Sun.COM sv->si_cache_opipe = kmem_cache_create("smb_opipe_cache",
39511963SAfshin.Ardakani@Sun.COM sizeof (smb_opipe_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
39611963SAfshin.Ardakani@Sun.COM sv->si_cache_event = kmem_cache_create("smb_event_cache",
39711963SAfshin.Ardakani@Sun.COM sizeof (smb_event_t), 8, NULL, NULL, NULL, NULL, NULL, 0);
3986139Sjb150015
3996139Sjb150015 smb_thread_init(&sv->si_thread_timers,
400*13138SJose.Borrego@Sun.COM "smb_timers", smb_server_timers, sv);
4016139Sjb150015
4026432Sas200622 sv->sv_pid = curproc->p_pid;
40312508Samw@Sun.COM smb_srqueue_init(&sv->sv_srqueue);
4046139Sjb150015
40511963SAfshin.Ardakani@Sun.COM smb_kdoor_init();
4067052Samw smb_opipe_door_init();
40712508Samw@Sun.COM smb_server_kstat_init(sv);
4086139Sjb150015
4096139Sjb150015 mutex_init(&sv->sv_mutex, NULL, MUTEX_DEFAULT, NULL);
41012890SJoyce.McIntosh@Sun.COM mutex_init(&sv->sp_info.sp_mutex, NULL, MUTEX_DEFAULT, NULL);
4116139Sjb150015 cv_init(&sv->sv_cv, NULL, CV_DEFAULT, NULL);
41212890SJoyce.McIntosh@Sun.COM cv_init(&sv->sp_info.sp_cv, NULL, CV_DEFAULT, NULL);
41312890SJoyce.McIntosh@Sun.COM
4146139Sjb150015 sv->sv_state = SMB_SERVER_STATE_CREATED;
4156139Sjb150015 sv->sv_magic = SMB_SERVER_MAGIC;
4166139Sjb150015 sv->sv_zid = zid;
4176139Sjb150015
4186139Sjb150015 smb_llist_insert_tail(&smb_servers, sv);
4196139Sjb150015 smb_llist_exit(&smb_servers);
42012890SJoyce.McIntosh@Sun.COM
42112890SJoyce.McIntosh@Sun.COM smb_threshold_init(&sv->sv_ssetup_ct, SMB_SSETUP_CMD,
42212890SJoyce.McIntosh@Sun.COM smb_ssetup_threshold, smb_ssetup_timeout);
42312890SJoyce.McIntosh@Sun.COM smb_threshold_init(&sv->sv_tcon_ct, SMB_TCON_CMD, smb_tcon_threshold,
42412890SJoyce.McIntosh@Sun.COM smb_tcon_timeout);
42512890SJoyce.McIntosh@Sun.COM smb_threshold_init(&sv->sv_opipe_ct, SMB_OPIPE_CMD, smb_opipe_threshold,
42612890SJoyce.McIntosh@Sun.COM smb_opipe_timeout);
42712890SJoyce.McIntosh@Sun.COM
4286139Sjb150015 return (0);
4296139Sjb150015 }
4306139Sjb150015
4316139Sjb150015 /*
4326139Sjb150015 * smb_server_delete
4336139Sjb150015 *
4346139Sjb150015 * This function will delete the server passed in. It will make sure that all
4356139Sjb150015 * activity associated that server has ceased before destroying it.
4366139Sjb150015 */
4376139Sjb150015 int
smb_server_delete(void)4386139Sjb150015 smb_server_delete(void)
4396139Sjb150015 {
4406139Sjb150015 smb_server_t *sv;
4416139Sjb150015 int rc;
4426139Sjb150015
4436139Sjb150015 rc = smb_server_lookup(&sv);
4446139Sjb150015 if (rc != 0)
4456139Sjb150015 return (rc);
4466139Sjb150015
44712890SJoyce.McIntosh@Sun.COM smb_threshold_fini(&sv->sv_ssetup_ct);
44812890SJoyce.McIntosh@Sun.COM smb_threshold_fini(&sv->sv_tcon_ct);
44912890SJoyce.McIntosh@Sun.COM smb_threshold_fini(&sv->sv_opipe_ct);
45012890SJoyce.McIntosh@Sun.COM
4516139Sjb150015 mutex_enter(&sv->sv_mutex);
4526139Sjb150015 switch (sv->sv_state) {
4536139Sjb150015 case SMB_SERVER_STATE_RUNNING:
45411963SAfshin.Ardakani@Sun.COM sv->sv_state = SMB_SERVER_STATE_STOPPING;
4556139Sjb150015 mutex_exit(&sv->sv_mutex);
456*13138SJose.Borrego@Sun.COM smb_server_shutdown(sv);
4576139Sjb150015 mutex_enter(&sv->sv_mutex);
458*13138SJose.Borrego@Sun.COM cv_broadcast(&sv->sp_info.sp_cv);
459*13138SJose.Borrego@Sun.COM sv->sv_state = SMB_SERVER_STATE_DELETING;
460*13138SJose.Borrego@Sun.COM break;
461*13138SJose.Borrego@Sun.COM case SMB_SERVER_STATE_STOPPING:
462*13138SJose.Borrego@Sun.COM sv->sv_state = SMB_SERVER_STATE_DELETING;
4636139Sjb150015 break;
4646139Sjb150015 case SMB_SERVER_STATE_CONFIGURED:
4656139Sjb150015 case SMB_SERVER_STATE_CREATED:
4666139Sjb150015 sv->sv_state = SMB_SERVER_STATE_DELETING;
4676139Sjb150015 break;
4686139Sjb150015 default:
46911963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state);
4706139Sjb150015 mutex_exit(&sv->sv_mutex);
4716139Sjb150015 smb_server_release(sv);
4726139Sjb150015 return (ENOTTY);
4736139Sjb150015 }
4746139Sjb150015
4756139Sjb150015 ASSERT(sv->sv_state == SMB_SERVER_STATE_DELETING);
4766139Sjb150015
4776139Sjb150015 sv->sv_refcnt--;
4786139Sjb150015 while (sv->sv_refcnt)
4796139Sjb150015 cv_wait(&sv->sv_cv, &sv->sv_mutex);
4806139Sjb150015
4816139Sjb150015 mutex_exit(&sv->sv_mutex);
4826139Sjb150015
4836139Sjb150015 smb_llist_enter(&smb_servers, RW_WRITER);
4846139Sjb150015 smb_llist_remove(&smb_servers, sv);
4856139Sjb150015 smb_llist_exit(&smb_servers);
4866139Sjb150015
487*13138SJose.Borrego@Sun.COM smb_server_listener_destroy(&sv->sv_nbt_daemon);
488*13138SJose.Borrego@Sun.COM smb_server_listener_destroy(&sv->sv_tcp_daemon);
4896139Sjb150015 rw_destroy(&sv->sv_cfg_lock);
4907052Samw smb_opipe_door_fini();
49111963SAfshin.Ardakani@Sun.COM smb_kdoor_fini();
4926139Sjb150015 smb_server_kstat_fini(sv);
49311963SAfshin.Ardakani@Sun.COM smb_llist_destructor(&sv->sv_opipe_list);
49411963SAfshin.Ardakani@Sun.COM smb_llist_destructor(&sv->sv_event_list);
4957619SJose.Borrego@Sun.COM
4966139Sjb150015 kmem_cache_destroy(sv->si_cache_request);
4976139Sjb150015 kmem_cache_destroy(sv->si_cache_session);
4986139Sjb150015 kmem_cache_destroy(sv->si_cache_user);
4996139Sjb150015 kmem_cache_destroy(sv->si_cache_tree);
5006139Sjb150015 kmem_cache_destroy(sv->si_cache_ofile);
5016139Sjb150015 kmem_cache_destroy(sv->si_cache_odir);
50211963SAfshin.Ardakani@Sun.COM kmem_cache_destroy(sv->si_cache_opipe);
50311963SAfshin.Ardakani@Sun.COM kmem_cache_destroy(sv->si_cache_event);
5046139Sjb150015
50512508Samw@Sun.COM smb_srqueue_destroy(&sv->sv_srqueue);
50612508Samw@Sun.COM
5076139Sjb150015 smb_thread_destroy(&sv->si_thread_timers);
5086139Sjb150015 mutex_destroy(&sv->sv_mutex);
5096139Sjb150015 cv_destroy(&sv->sv_cv);
5106139Sjb150015 sv->sv_magic = 0;
5116139Sjb150015 kmem_free(sv, sizeof (smb_server_t));
5126139Sjb150015
5136139Sjb150015 return (0);
5146139Sjb150015 }
5156139Sjb150015
5166139Sjb150015 /*
5176139Sjb150015 * smb_server_configure
5186139Sjb150015 */
5196139Sjb150015 int
smb_server_configure(smb_ioc_cfg_t * ioc)5209832Samw@Sun.COM smb_server_configure(smb_ioc_cfg_t *ioc)
5216139Sjb150015 {
5226139Sjb150015 int rc = 0;
5236139Sjb150015 smb_server_t *sv;
5246139Sjb150015
5256139Sjb150015 rc = smb_server_lookup(&sv);
5266139Sjb150015 if (rc)
5276139Sjb150015 return (rc);
5286139Sjb150015
5296139Sjb150015 mutex_enter(&sv->sv_mutex);
5306139Sjb150015 switch (sv->sv_state) {
5316139Sjb150015 case SMB_SERVER_STATE_CREATED:
5329832Samw@Sun.COM smb_server_store_cfg(sv, ioc);
5336139Sjb150015 sv->sv_state = SMB_SERVER_STATE_CONFIGURED;
5346139Sjb150015 break;
5356139Sjb150015
5366139Sjb150015 case SMB_SERVER_STATE_CONFIGURED:
5379832Samw@Sun.COM smb_server_store_cfg(sv, ioc);
5386139Sjb150015 break;
5396139Sjb150015
5406139Sjb150015 case SMB_SERVER_STATE_RUNNING:
54111963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING:
5426139Sjb150015 rw_enter(&sv->sv_cfg_lock, RW_WRITER);
5439832Samw@Sun.COM smb_server_store_cfg(sv, ioc);
5446139Sjb150015 rw_exit(&sv->sv_cfg_lock);
5456139Sjb150015 break;
5466139Sjb150015
5476139Sjb150015 default:
54811963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state);
5496139Sjb150015 rc = EFAULT;
5506139Sjb150015 break;
5516139Sjb150015 }
5526139Sjb150015 mutex_exit(&sv->sv_mutex);
5536139Sjb150015
5546139Sjb150015 smb_server_release(sv);
5556139Sjb150015
5566139Sjb150015 return (rc);
5576139Sjb150015 }
5586139Sjb150015
5596139Sjb150015 /*
5606139Sjb150015 * smb_server_start
5616139Sjb150015 */
5626139Sjb150015 int
smb_server_start(smb_ioc_start_t * ioc)5639832Samw@Sun.COM smb_server_start(smb_ioc_start_t *ioc)
5646139Sjb150015 {
5656139Sjb150015 int rc = 0;
566*13138SJose.Borrego@Sun.COM int family;
5676139Sjb150015 smb_server_t *sv;
5686139Sjb150015
5696139Sjb150015 rc = smb_server_lookup(&sv);
5706139Sjb150015 if (rc)
5716139Sjb150015 return (rc);
5726139Sjb150015
5736139Sjb150015 mutex_enter(&sv->sv_mutex);
5746139Sjb150015 switch (sv->sv_state) {
5756139Sjb150015 case SMB_SERVER_STATE_CONFIGURED:
57610966SJordan.Brown@Sun.COM smb_codepage_init();
5776139Sjb150015
578*13138SJose.Borrego@Sun.COM sv->sv_worker_pool = taskq_create("smb_workers",
5796139Sjb150015 sv->sv_cfg.skc_maxworkers, SMB_WORKER_PRIORITY,
5806139Sjb150015 sv->sv_cfg.skc_maxworkers, INT_MAX,
5816139Sjb150015 TASKQ_DYNAMIC|TASKQ_PREPOPULATE);
5826139Sjb150015
583*13138SJose.Borrego@Sun.COM sv->sv_receiver_pool = taskq_create("smb_receivers",
584*13138SJose.Borrego@Sun.COM sv->sv_cfg.skc_maxconnections, SMB_WORKER_PRIORITY,
585*13138SJose.Borrego@Sun.COM sv->sv_cfg.skc_maxconnections, INT_MAX,
586*13138SJose.Borrego@Sun.COM TASKQ_DYNAMIC);
587*13138SJose.Borrego@Sun.COM
5888670SJose.Borrego@Sun.COM sv->sv_session = smb_session_create(NULL, 0, sv, 0);
5897588Samw@Sun.COM
590*13138SJose.Borrego@Sun.COM if (sv->sv_worker_pool == NULL || sv->sv_session == NULL) {
5916139Sjb150015 rc = ENOMEM;
5926139Sjb150015 break;
5936139Sjb150015 }
5946139Sjb150015
5956139Sjb150015 if (rc = smb_server_fsop_start(sv))
5966139Sjb150015 break;
5976139Sjb150015 ASSERT(sv->sv_lmshrd == NULL);
59812508Samw@Sun.COM sv->sv_lmshrd = smb_kshare_door_init(ioc->lmshrd);
5996139Sjb150015 if (sv->sv_lmshrd == NULL)
6006139Sjb150015 break;
60111963SAfshin.Ardakani@Sun.COM if (rc = smb_kdoor_open(ioc->udoor)) {
60211963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "Cannot open smbd door");
6036139Sjb150015 break;
60411963SAfshin.Ardakani@Sun.COM }
60511963SAfshin.Ardakani@Sun.COM if (rc = smb_opipe_door_open(ioc->opipe)) {
60611963SAfshin.Ardakani@Sun.COM cmn_err(CE_WARN, "Cannot open opipe door");
60711963SAfshin.Ardakani@Sun.COM break;
60811963SAfshin.Ardakani@Sun.COM }
6096139Sjb150015 if (rc = smb_thread_start(&sv->si_thread_timers))
6106139Sjb150015 break;
611*13138SJose.Borrego@Sun.COM
612*13138SJose.Borrego@Sun.COM family = AF_INET;
613*13138SJose.Borrego@Sun.COM smb_server_listener_init(sv, &sv->sv_nbt_daemon,
614*13138SJose.Borrego@Sun.COM "smb_nbt_listener", IPPORT_NETBIOS_SSN, family);
615*13138SJose.Borrego@Sun.COM if (sv->sv_cfg.skc_ipv6_enable)
616*13138SJose.Borrego@Sun.COM family = AF_INET6;
617*13138SJose.Borrego@Sun.COM smb_server_listener_init(sv, &sv->sv_tcp_daemon,
618*13138SJose.Borrego@Sun.COM "smb_tcp_listener", IPPORT_SMB, family);
619*13138SJose.Borrego@Sun.COM rc = smb_server_listener_start(&sv->sv_nbt_daemon);
620*13138SJose.Borrego@Sun.COM if (rc != 0)
621*13138SJose.Borrego@Sun.COM break;
622*13138SJose.Borrego@Sun.COM rc = smb_server_listener_start(&sv->sv_tcp_daemon);
623*13138SJose.Borrego@Sun.COM if (rc != 0)
624*13138SJose.Borrego@Sun.COM break;
625*13138SJose.Borrego@Sun.COM
6266139Sjb150015 sv->sv_state = SMB_SERVER_STATE_RUNNING;
62712508Samw@Sun.COM sv->sv_start_time = gethrtime();
6286139Sjb150015 mutex_exit(&sv->sv_mutex);
6296139Sjb150015 smb_server_release(sv);
63012508Samw@Sun.COM smb_export_start();
6316139Sjb150015 return (0);
6326139Sjb150015 default:
63311963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state);
6346139Sjb150015 mutex_exit(&sv->sv_mutex);
6356139Sjb150015 smb_server_release(sv);
6366139Sjb150015 return (ENOTTY);
6376139Sjb150015 }
6386139Sjb150015
639*13138SJose.Borrego@Sun.COM mutex_exit(&sv->sv_mutex);
64011963SAfshin.Ardakani@Sun.COM smb_server_shutdown(sv);
6416139Sjb150015 smb_server_release(sv);
6426139Sjb150015 return (rc);
6436139Sjb150015 }
6446139Sjb150015
6456139Sjb150015 /*
64611963SAfshin.Ardakani@Sun.COM * An smbd is shutting down.
64711963SAfshin.Ardakani@Sun.COM */
64811963SAfshin.Ardakani@Sun.COM int
smb_server_stop(void)64911963SAfshin.Ardakani@Sun.COM smb_server_stop(void)
65011963SAfshin.Ardakani@Sun.COM {
65111963SAfshin.Ardakani@Sun.COM smb_server_t *sv;
65211963SAfshin.Ardakani@Sun.COM int rc;
65311963SAfshin.Ardakani@Sun.COM
65411963SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0)
65511963SAfshin.Ardakani@Sun.COM return (rc);
65611963SAfshin.Ardakani@Sun.COM
65711963SAfshin.Ardakani@Sun.COM mutex_enter(&sv->sv_mutex);
65811963SAfshin.Ardakani@Sun.COM switch (sv->sv_state) {
65911963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_RUNNING:
66011963SAfshin.Ardakani@Sun.COM sv->sv_state = SMB_SERVER_STATE_STOPPING;
661*13138SJose.Borrego@Sun.COM mutex_exit(&sv->sv_mutex);
662*13138SJose.Borrego@Sun.COM smb_server_shutdown(sv);
663*13138SJose.Borrego@Sun.COM mutex_enter(&sv->sv_mutex);
66412890SJoyce.McIntosh@Sun.COM cv_broadcast(&sv->sp_info.sp_cv);
66511963SAfshin.Ardakani@Sun.COM break;
66611963SAfshin.Ardakani@Sun.COM default:
66711963SAfshin.Ardakani@Sun.COM SMB_SERVER_STATE_VALID(sv->sv_state);
66811963SAfshin.Ardakani@Sun.COM break;
66911963SAfshin.Ardakani@Sun.COM }
67011963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex);
67111963SAfshin.Ardakani@Sun.COM
67211963SAfshin.Ardakani@Sun.COM smb_server_release(sv);
67311963SAfshin.Ardakani@Sun.COM return (0);
67411963SAfshin.Ardakani@Sun.COM }
67511963SAfshin.Ardakani@Sun.COM
67611963SAfshin.Ardakani@Sun.COM boolean_t
smb_server_is_stopping(void)67711963SAfshin.Ardakani@Sun.COM smb_server_is_stopping(void)
67811963SAfshin.Ardakani@Sun.COM {
67912508Samw@Sun.COM smb_server_t *sv;
68011963SAfshin.Ardakani@Sun.COM boolean_t status;
68111963SAfshin.Ardakani@Sun.COM
68211963SAfshin.Ardakani@Sun.COM if (smb_server_lookup(&sv) != 0)
68311963SAfshin.Ardakani@Sun.COM return (B_TRUE);
68411963SAfshin.Ardakani@Sun.COM
68511963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
68611963SAfshin.Ardakani@Sun.COM
68711963SAfshin.Ardakani@Sun.COM mutex_enter(&sv->sv_mutex);
68811963SAfshin.Ardakani@Sun.COM
68911963SAfshin.Ardakani@Sun.COM switch (sv->sv_state) {
69011963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_STOPPING:
69111963SAfshin.Ardakani@Sun.COM case SMB_SERVER_STATE_DELETING:
69211963SAfshin.Ardakani@Sun.COM status = B_TRUE;
69311963SAfshin.Ardakani@Sun.COM break;
69411963SAfshin.Ardakani@Sun.COM default:
69511963SAfshin.Ardakani@Sun.COM status = B_FALSE;
69611963SAfshin.Ardakani@Sun.COM break;
69711963SAfshin.Ardakani@Sun.COM }
69811963SAfshin.Ardakani@Sun.COM
69911963SAfshin.Ardakani@Sun.COM mutex_exit(&sv->sv_mutex);
70011963SAfshin.Ardakani@Sun.COM smb_server_release(sv);
70111963SAfshin.Ardakani@Sun.COM return (status);
70211963SAfshin.Ardakani@Sun.COM }
70311963SAfshin.Ardakani@Sun.COM
70411963SAfshin.Ardakani@Sun.COM int
smb_server_cancel_event(uint32_t txid)70511963SAfshin.Ardakani@Sun.COM smb_server_cancel_event(uint32_t txid)
70611963SAfshin.Ardakani@Sun.COM {
70711963SAfshin.Ardakani@Sun.COM smb_server_t *sv;
70811963SAfshin.Ardakani@Sun.COM int rc;
70911963SAfshin.Ardakani@Sun.COM
71011963SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) {
71111963SAfshin.Ardakani@Sun.COM smb_event_cancel(sv, txid);
71211963SAfshin.Ardakani@Sun.COM smb_server_release(sv);
71311963SAfshin.Ardakani@Sun.COM }
71411963SAfshin.Ardakani@Sun.COM
71511963SAfshin.Ardakani@Sun.COM return (rc);
71611963SAfshin.Ardakani@Sun.COM }
71711963SAfshin.Ardakani@Sun.COM
71811963SAfshin.Ardakani@Sun.COM int
smb_server_notify_event(smb_ioc_event_t * ioc)71911963SAfshin.Ardakani@Sun.COM smb_server_notify_event(smb_ioc_event_t *ioc)
72011963SAfshin.Ardakani@Sun.COM {
72111963SAfshin.Ardakani@Sun.COM smb_server_t *sv;
72211963SAfshin.Ardakani@Sun.COM int rc;
72311963SAfshin.Ardakani@Sun.COM
72411963SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) {
72511963SAfshin.Ardakani@Sun.COM smb_event_notify(sv, ioc->txid);
72611963SAfshin.Ardakani@Sun.COM smb_server_release(sv);
72711963SAfshin.Ardakani@Sun.COM }
72811963SAfshin.Ardakani@Sun.COM
72911963SAfshin.Ardakani@Sun.COM return (rc);
73011963SAfshin.Ardakani@Sun.COM }
73111963SAfshin.Ardakani@Sun.COM
73211963SAfshin.Ardakani@Sun.COM /*
73312890SJoyce.McIntosh@Sun.COM * smb_server_spooldoc
73412890SJoyce.McIntosh@Sun.COM *
73512890SJoyce.McIntosh@Sun.COM * Waits for print file close broadcast.
73612890SJoyce.McIntosh@Sun.COM * Gets the head of the fid list,
73712890SJoyce.McIntosh@Sun.COM * then searches the spooldoc list and returns
73812890SJoyce.McIntosh@Sun.COM * this info via the ioctl to user land.
73912890SJoyce.McIntosh@Sun.COM *
74012890SJoyce.McIntosh@Sun.COM * rc - 0 success
74112890SJoyce.McIntosh@Sun.COM */
74212890SJoyce.McIntosh@Sun.COM
74312890SJoyce.McIntosh@Sun.COM int
smb_server_spooldoc(smb_ioc_spooldoc_t * ioc)74412890SJoyce.McIntosh@Sun.COM smb_server_spooldoc(smb_ioc_spooldoc_t *ioc)
74512890SJoyce.McIntosh@Sun.COM {
74612890SJoyce.McIntosh@Sun.COM smb_server_t *sv;
74712890SJoyce.McIntosh@Sun.COM int rc;
74812890SJoyce.McIntosh@Sun.COM smb_kspooldoc_t *spdoc;
74912890SJoyce.McIntosh@Sun.COM uint16_t fid;
75012890SJoyce.McIntosh@Sun.COM
75112890SJoyce.McIntosh@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) {
75212890SJoyce.McIntosh@Sun.COM if (sv->sv_state != SMB_SERVER_STATE_RUNNING) {
75312890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
75412890SJoyce.McIntosh@Sun.COM return (ECANCELED);
75512890SJoyce.McIntosh@Sun.COM }
75612890SJoyce.McIntosh@Sun.COM mutex_enter(&sv->sp_info.sp_mutex);
75712890SJoyce.McIntosh@Sun.COM spdoc = kmem_zalloc(sizeof (smb_kspooldoc_t), KM_SLEEP);
75812890SJoyce.McIntosh@Sun.COM cv_wait(&sv->sp_info.sp_cv, &sv->sp_info.sp_mutex);
75912890SJoyce.McIntosh@Sun.COM if (sv->sv_state != SMB_SERVER_STATE_RUNNING)
76012890SJoyce.McIntosh@Sun.COM rc = ECANCELED;
76112890SJoyce.McIntosh@Sun.COM else {
76212890SJoyce.McIntosh@Sun.COM fid = smb_spool_get_fid();
76312890SJoyce.McIntosh@Sun.COM atomic_inc_32(&sv->sp_info.sp_cnt);
76412890SJoyce.McIntosh@Sun.COM if (smb_spool_lookup_doc_byfid(fid, spdoc)) {
76512890SJoyce.McIntosh@Sun.COM ioc->spool_num = spdoc->sd_spool_num;
76612890SJoyce.McIntosh@Sun.COM ioc->ipaddr = spdoc->sd_ipaddr;
76712890SJoyce.McIntosh@Sun.COM (void) strlcpy(ioc->path, spdoc->sd_path,
76812890SJoyce.McIntosh@Sun.COM MAXPATHLEN);
76912890SJoyce.McIntosh@Sun.COM (void) strlcpy(ioc->username,
77012890SJoyce.McIntosh@Sun.COM spdoc->sd_username, MAXNAMELEN);
77112890SJoyce.McIntosh@Sun.COM }
77212890SJoyce.McIntosh@Sun.COM }
77312890SJoyce.McIntosh@Sun.COM kmem_free(spdoc, sizeof (smb_kspooldoc_t));
77412890SJoyce.McIntosh@Sun.COM mutex_exit(&sv->sp_info.sp_mutex);
77512890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
77612890SJoyce.McIntosh@Sun.COM }
77712890SJoyce.McIntosh@Sun.COM return (rc);
77812890SJoyce.McIntosh@Sun.COM }
77912890SJoyce.McIntosh@Sun.COM
7806139Sjb150015 int
smb_server_set_gmtoff(smb_ioc_gmt_t * ioc)7819832Samw@Sun.COM smb_server_set_gmtoff(smb_ioc_gmt_t *ioc)
7826139Sjb150015 {
7836139Sjb150015 int rc;
7846139Sjb150015 smb_server_t *sv;
7856139Sjb150015
7869422SAfshin.Ardakani@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) {
7879832Samw@Sun.COM sv->si_gmtoff = ioc->offset;
7889422SAfshin.Ardakani@Sun.COM smb_server_release(sv);
7899422SAfshin.Ardakani@Sun.COM }
7906139Sjb150015
7916139Sjb150015 return (rc);
7926139Sjb150015 }
7936139Sjb150015
7949832Samw@Sun.COM int
smb_server_numopen(smb_ioc_opennum_t * ioc)79510122SJordan.Brown@Sun.COM smb_server_numopen(smb_ioc_opennum_t *ioc)
7969832Samw@Sun.COM {
7979832Samw@Sun.COM smb_server_t *sv;
7989832Samw@Sun.COM int rc;
7999832Samw@Sun.COM
8009832Samw@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) {
80112508Samw@Sun.COM ioc->open_users = sv->sv_users;
80212508Samw@Sun.COM ioc->open_trees = sv->sv_trees;
80312508Samw@Sun.COM ioc->open_files = sv->sv_files + sv->sv_pipes;
8049832Samw@Sun.COM smb_server_release(sv);
8059832Samw@Sun.COM }
8069832Samw@Sun.COM return (rc);
8079832Samw@Sun.COM }
8089832Samw@Sun.COM
8096139Sjb150015 /*
81010122SJordan.Brown@Sun.COM * Enumerate objects within the server. The svcenum provides the
81110122SJordan.Brown@Sun.COM * enumeration context, i.e. what the caller want to get back.
81210122SJordan.Brown@Sun.COM */
81310122SJordan.Brown@Sun.COM int
smb_server_enum(smb_ioc_svcenum_t * ioc)81410122SJordan.Brown@Sun.COM smb_server_enum(smb_ioc_svcenum_t *ioc)
81510122SJordan.Brown@Sun.COM {
816*13138SJose.Borrego@Sun.COM smb_svcenum_t *svcenum = &ioc->svcenum;
817*13138SJose.Borrego@Sun.COM smb_server_t *sv;
818*13138SJose.Borrego@Sun.COM int rc;
81910122SJordan.Brown@Sun.COM
82010122SJordan.Brown@Sun.COM switch (svcenum->se_type) {
82110122SJordan.Brown@Sun.COM case SMB_SVCENUM_TYPE_USER:
82210122SJordan.Brown@Sun.COM case SMB_SVCENUM_TYPE_TREE:
82310122SJordan.Brown@Sun.COM case SMB_SVCENUM_TYPE_FILE:
82410122SJordan.Brown@Sun.COM break;
82510122SJordan.Brown@Sun.COM default:
82610122SJordan.Brown@Sun.COM return (EINVAL);
82710122SJordan.Brown@Sun.COM }
82810122SJordan.Brown@Sun.COM
82910122SJordan.Brown@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0)
83010122SJordan.Brown@Sun.COM return (rc);
83110122SJordan.Brown@Sun.COM
83210122SJordan.Brown@Sun.COM svcenum->se_bavail = svcenum->se_buflen;
83310122SJordan.Brown@Sun.COM svcenum->se_bused = 0;
83410122SJordan.Brown@Sun.COM svcenum->se_nitems = 0;
83510122SJordan.Brown@Sun.COM
836*13138SJose.Borrego@Sun.COM smb_server_enum_private(&sv->sv_nbt_daemon.ld_session_list, svcenum);
837*13138SJose.Borrego@Sun.COM smb_server_enum_private(&sv->sv_tcp_daemon.ld_session_list, svcenum);
83810122SJordan.Brown@Sun.COM
83910122SJordan.Brown@Sun.COM smb_server_release(sv);
84010122SJordan.Brown@Sun.COM return (0);
84110122SJordan.Brown@Sun.COM }
84210122SJordan.Brown@Sun.COM
84310122SJordan.Brown@Sun.COM /*
84410122SJordan.Brown@Sun.COM * Look for sessions to disconnect by client and user name.
84510122SJordan.Brown@Sun.COM */
84610122SJordan.Brown@Sun.COM int
smb_server_session_close(smb_ioc_session_t * ioc)84710122SJordan.Brown@Sun.COM smb_server_session_close(smb_ioc_session_t *ioc)
84810122SJordan.Brown@Sun.COM {
849*13138SJose.Borrego@Sun.COM smb_llist_t *ll;
850*13138SJose.Borrego@Sun.COM smb_server_t *sv;
851*13138SJose.Borrego@Sun.COM int nbt_cnt;
852*13138SJose.Borrego@Sun.COM int tcp_cnt;
853*13138SJose.Borrego@Sun.COM int rc;
85410122SJordan.Brown@Sun.COM
85510122SJordan.Brown@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0)
85610122SJordan.Brown@Sun.COM return (rc);
85710122SJordan.Brown@Sun.COM
858*13138SJose.Borrego@Sun.COM ll = &sv->sv_nbt_daemon.ld_session_list;
859*13138SJose.Borrego@Sun.COM nbt_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
86010122SJordan.Brown@Sun.COM
861*13138SJose.Borrego@Sun.COM ll = &sv->sv_tcp_daemon.ld_session_list;
862*13138SJose.Borrego@Sun.COM tcp_cnt = smb_server_session_disconnect(ll, ioc->client, ioc->username);
86310122SJordan.Brown@Sun.COM
86410122SJordan.Brown@Sun.COM smb_server_release(sv);
86510122SJordan.Brown@Sun.COM
86610122SJordan.Brown@Sun.COM if ((nbt_cnt == 0) && (tcp_cnt == 0))
86710122SJordan.Brown@Sun.COM return (ENOENT);
86810122SJordan.Brown@Sun.COM return (0);
86910122SJordan.Brown@Sun.COM }
87010122SJordan.Brown@Sun.COM
87110122SJordan.Brown@Sun.COM /*
87210122SJordan.Brown@Sun.COM * Close a file by uniqid.
87310122SJordan.Brown@Sun.COM */
87410122SJordan.Brown@Sun.COM int
smb_server_file_close(smb_ioc_fileid_t * ioc)87510122SJordan.Brown@Sun.COM smb_server_file_close(smb_ioc_fileid_t *ioc)
87610122SJordan.Brown@Sun.COM {
877*13138SJose.Borrego@Sun.COM uint32_t uniqid = ioc->uniqid;
878*13138SJose.Borrego@Sun.COM smb_llist_t *ll;
879*13138SJose.Borrego@Sun.COM smb_server_t *sv;
880*13138SJose.Borrego@Sun.COM int rc;
88110122SJordan.Brown@Sun.COM
88210122SJordan.Brown@Sun.COM if ((rc = smb_server_lookup(&sv)) != 0)
88310122SJordan.Brown@Sun.COM return (rc);
88410122SJordan.Brown@Sun.COM
885*13138SJose.Borrego@Sun.COM ll = &sv->sv_nbt_daemon.ld_session_list;
886*13138SJose.Borrego@Sun.COM rc = smb_server_fclose(ll, uniqid);
88710122SJordan.Brown@Sun.COM
88810122SJordan.Brown@Sun.COM if (rc == ENOENT) {
889*13138SJose.Borrego@Sun.COM ll = &sv->sv_tcp_daemon.ld_session_list;
890*13138SJose.Borrego@Sun.COM rc = smb_server_fclose(ll, uniqid);
89110122SJordan.Brown@Sun.COM }
89210122SJordan.Brown@Sun.COM
89310122SJordan.Brown@Sun.COM smb_server_release(sv);
89410122SJordan.Brown@Sun.COM return (rc);
89510122SJordan.Brown@Sun.COM }
89610122SJordan.Brown@Sun.COM
89710122SJordan.Brown@Sun.COM /*
8986139Sjb150015 * These functions determine the relevant smb server to which the call apply.
8996139Sjb150015 */
9006139Sjb150015
9016139Sjb150015 uint32_t
smb_server_get_session_count(void)9026139Sjb150015 smb_server_get_session_count(void)
9036139Sjb150015 {
9046139Sjb150015 smb_server_t *sv;
9056139Sjb150015 uint32_t counter = 0;
9066139Sjb150015
9076139Sjb150015 if (smb_server_lookup(&sv))
9086139Sjb150015 return (0);
9096139Sjb150015
910*13138SJose.Borrego@Sun.COM counter = smb_llist_get_count(&sv->sv_nbt_daemon.ld_session_list);
911*13138SJose.Borrego@Sun.COM counter += smb_llist_get_count(&sv->sv_tcp_daemon.ld_session_list);
9126139Sjb150015
9136139Sjb150015 smb_server_release(sv);
9146139Sjb150015
9156139Sjb150015 return (counter);
9166139Sjb150015 }
9176139Sjb150015
9186139Sjb150015 /*
91912508Samw@Sun.COM * Gets the vnode of the specified share path.
92012508Samw@Sun.COM *
92112508Samw@Sun.COM * A hold on the returned vnode pointer is taken so the caller
92212508Samw@Sun.COM * must call VN_RELE.
92312508Samw@Sun.COM */
92412508Samw@Sun.COM int
smb_server_sharevp(const char * shr_path,vnode_t ** vp)92512508Samw@Sun.COM smb_server_sharevp(const char *shr_path, vnode_t **vp)
92612508Samw@Sun.COM {
92712508Samw@Sun.COM smb_server_t *sv;
92812508Samw@Sun.COM smb_request_t *sr;
92912508Samw@Sun.COM smb_node_t *fnode = NULL;
93012508Samw@Sun.COM smb_node_t *dnode;
93112508Samw@Sun.COM char last_comp[MAXNAMELEN];
93212508Samw@Sun.COM int rc = 0;
93312508Samw@Sun.COM
93412508Samw@Sun.COM ASSERT(shr_path);
93512508Samw@Sun.COM
93612508Samw@Sun.COM if ((rc = smb_server_lookup(&sv)))
93712508Samw@Sun.COM return (rc);
93812508Samw@Sun.COM
93912508Samw@Sun.COM mutex_enter(&sv->sv_mutex);
94012508Samw@Sun.COM switch (sv->sv_state) {
94112508Samw@Sun.COM case SMB_SERVER_STATE_RUNNING:
94212508Samw@Sun.COM break;
94312508Samw@Sun.COM default:
94412508Samw@Sun.COM mutex_exit(&sv->sv_mutex);
94512508Samw@Sun.COM smb_server_release(sv);
94612508Samw@Sun.COM return (ENOTACTIVE);
94712508Samw@Sun.COM }
94812508Samw@Sun.COM mutex_exit(&sv->sv_mutex);
94912508Samw@Sun.COM
95012508Samw@Sun.COM if ((sr = smb_request_alloc(sv->sv_session, 0)) == NULL) {
95112508Samw@Sun.COM smb_server_release(sv);
95212508Samw@Sun.COM return (ENOMEM);
95312508Samw@Sun.COM }
95412508Samw@Sun.COM sr->user_cr = kcred;
95512508Samw@Sun.COM
95612508Samw@Sun.COM rc = smb_pathname_reduce(sr, sr->user_cr, shr_path,
95712508Samw@Sun.COM NULL, NULL, &dnode, last_comp);
95812508Samw@Sun.COM
95912508Samw@Sun.COM if (rc == 0) {
96012508Samw@Sun.COM rc = smb_fsop_lookup(sr, sr->user_cr, SMB_FOLLOW_LINKS,
96112508Samw@Sun.COM sv->si_root_smb_node, dnode, last_comp, &fnode);
96212508Samw@Sun.COM smb_node_release(dnode);
96312508Samw@Sun.COM }
96412508Samw@Sun.COM
96512508Samw@Sun.COM smb_request_free(sr);
96612508Samw@Sun.COM smb_server_release(sv);
96712508Samw@Sun.COM
96812508Samw@Sun.COM if (rc != 0)
96912508Samw@Sun.COM return (rc);
97012508Samw@Sun.COM
97112508Samw@Sun.COM ASSERT(fnode->vp && fnode->vp->v_vfsp);
97212508Samw@Sun.COM
97312508Samw@Sun.COM VN_HOLD(fnode->vp);
97412508Samw@Sun.COM *vp = fnode->vp;
97512508Samw@Sun.COM
97612508Samw@Sun.COM smb_node_release(fnode);
97712508Samw@Sun.COM
97812508Samw@Sun.COM return (0);
97912508Samw@Sun.COM }
98012508Samw@Sun.COM
98112508Samw@Sun.COM
98212508Samw@Sun.COM /*
98312508Samw@Sun.COM * This is a special interface that will be utilized by ZFS to cause a share to
98412508Samw@Sun.COM * be added/removed.
98512508Samw@Sun.COM *
98612508Samw@Sun.COM * arg is either a lmshare_info_t or share_name from userspace.
98712508Samw@Sun.COM * It will need to be copied into the kernel. It is lmshare_info_t
98812508Samw@Sun.COM * for add operations and share_name for delete operations.
98912508Samw@Sun.COM */
99012508Samw@Sun.COM int
smb_server_share(void * arg,boolean_t add_share)99112508Samw@Sun.COM smb_server_share(void *arg, boolean_t add_share)
99212508Samw@Sun.COM {
99312508Samw@Sun.COM smb_server_t *sv;
99412508Samw@Sun.COM int rc;
99512508Samw@Sun.COM
99612508Samw@Sun.COM if ((rc = smb_server_lookup(&sv)) == 0) {
99712508Samw@Sun.COM mutex_enter(&sv->sv_mutex);
99812508Samw@Sun.COM switch (sv->sv_state) {
99912508Samw@Sun.COM case SMB_SERVER_STATE_RUNNING:
100012508Samw@Sun.COM mutex_exit(&sv->sv_mutex);
100112508Samw@Sun.COM (void) smb_kshare_upcall(sv->sv_lmshrd, arg, add_share);
100212508Samw@Sun.COM break;
100312508Samw@Sun.COM default:
100412508Samw@Sun.COM mutex_exit(&sv->sv_mutex);
100512508Samw@Sun.COM break;
100612508Samw@Sun.COM }
100712508Samw@Sun.COM smb_server_release(sv);
100812508Samw@Sun.COM }
100912508Samw@Sun.COM
101012508Samw@Sun.COM return (rc);
101112508Samw@Sun.COM }
101212508Samw@Sun.COM
101312508Samw@Sun.COM int
smb_server_unshare(const char * sharename)101412508Samw@Sun.COM smb_server_unshare(const char *sharename)
101512508Samw@Sun.COM {
1016*13138SJose.Borrego@Sun.COM smb_server_t *sv;
1017*13138SJose.Borrego@Sun.COM smb_llist_t *ll;
1018*13138SJose.Borrego@Sun.COM int rc;
101912508Samw@Sun.COM
102012508Samw@Sun.COM if ((rc = smb_server_lookup(&sv)))
102112508Samw@Sun.COM return (rc);
102212508Samw@Sun.COM
102312508Samw@Sun.COM mutex_enter(&sv->sv_mutex);
102412508Samw@Sun.COM switch (sv->sv_state) {
102512508Samw@Sun.COM case SMB_SERVER_STATE_RUNNING:
102612508Samw@Sun.COM case SMB_SERVER_STATE_STOPPING:
102712508Samw@Sun.COM break;
102812508Samw@Sun.COM default:
102912508Samw@Sun.COM mutex_exit(&sv->sv_mutex);
103012508Samw@Sun.COM smb_server_release(sv);
103112508Samw@Sun.COM return (ENOTACTIVE);
103212508Samw@Sun.COM }
103312508Samw@Sun.COM mutex_exit(&sv->sv_mutex);
103412508Samw@Sun.COM
1035*13138SJose.Borrego@Sun.COM ll = &sv->sv_nbt_daemon.ld_session_list;
1036*13138SJose.Borrego@Sun.COM smb_server_disconnect_share(ll, sharename);
103712508Samw@Sun.COM
1038*13138SJose.Borrego@Sun.COM ll = &sv->sv_tcp_daemon.ld_session_list;
1039*13138SJose.Borrego@Sun.COM smb_server_disconnect_share(ll, sharename);
104012508Samw@Sun.COM
104112508Samw@Sun.COM smb_server_release(sv);
104212508Samw@Sun.COM return (0);
104312508Samw@Sun.COM }
104412508Samw@Sun.COM
104512508Samw@Sun.COM /*
104611963SAfshin.Ardakani@Sun.COM * Disconnect the specified share.
104711963SAfshin.Ardakani@Sun.COM * Typically called when a share has been removed.
10486139Sjb150015 */
10497619SJose.Borrego@Sun.COM static void
smb_server_disconnect_share(smb_llist_t * ll,const char * sharename)1050*13138SJose.Borrego@Sun.COM smb_server_disconnect_share(smb_llist_t *ll, const char *sharename)
10516139Sjb150015 {
1052*13138SJose.Borrego@Sun.COM smb_session_t *session;
105311963SAfshin.Ardakani@Sun.COM
1054*13138SJose.Borrego@Sun.COM smb_llist_enter(ll, RW_READER);
105511963SAfshin.Ardakani@Sun.COM
1056*13138SJose.Borrego@Sun.COM session = smb_llist_head(ll);
105711963SAfshin.Ardakani@Sun.COM while (session) {
1058*13138SJose.Borrego@Sun.COM SMB_SESSION_VALID(session);
105911963SAfshin.Ardakani@Sun.COM smb_rwx_rwenter(&session->s_lock, RW_READER);
106011963SAfshin.Ardakani@Sun.COM switch (session->s_state) {
106111963SAfshin.Ardakani@Sun.COM case SMB_SESSION_STATE_NEGOTIATED:
106211963SAfshin.Ardakani@Sun.COM case SMB_SESSION_STATE_OPLOCK_BREAKING:
106311963SAfshin.Ardakani@Sun.COM case SMB_SESSION_STATE_WRITE_RAW_ACTIVE:
106411963SAfshin.Ardakani@Sun.COM smb_session_disconnect_share(session, sharename);
106511963SAfshin.Ardakani@Sun.COM break;
106611963SAfshin.Ardakani@Sun.COM default:
106711963SAfshin.Ardakani@Sun.COM break;
106811963SAfshin.Ardakani@Sun.COM }
106911963SAfshin.Ardakani@Sun.COM smb_rwx_rwexit(&session->s_lock);
1070*13138SJose.Borrego@Sun.COM session = smb_llist_next(ll, session);
107111963SAfshin.Ardakani@Sun.COM }
107211963SAfshin.Ardakani@Sun.COM
1073*13138SJose.Borrego@Sun.COM smb_llist_exit(ll);
10746139Sjb150015 }
10756139Sjb150015
10766139Sjb150015 /*
10776139Sjb150015 * *****************************************************************************
10786139Sjb150015 * **************** Functions called from the internal layers ******************
10796139Sjb150015 * *****************************************************************************
10806139Sjb150015 *
10816139Sjb150015 * These functions are provided the relevant smb server by the caller.
10826139Sjb150015 */
10836139Sjb150015
10846139Sjb150015 void
smb_server_reconnection_check(smb_server_t * sv,smb_session_t * session)10856139Sjb150015 smb_server_reconnection_check(smb_server_t *sv, smb_session_t *session)
10866139Sjb150015 {
10876139Sjb150015 ASSERT(sv == session->s_server);
10886139Sjb150015
10896139Sjb150015 smb_session_reconnection_check(&sv->sv_nbt_daemon.ld_session_list,
10906139Sjb150015 session);
10916139Sjb150015 smb_session_reconnection_check(&sv->sv_tcp_daemon.ld_session_list,
10926139Sjb150015 session);
10936139Sjb150015 }
10946139Sjb150015
10956139Sjb150015 void
smb_server_get_cfg(smb_server_t * sv,smb_kmod_cfg_t * cfg)10966139Sjb150015 smb_server_get_cfg(smb_server_t *sv, smb_kmod_cfg_t *cfg)
10976139Sjb150015 {
10986139Sjb150015 rw_enter(&sv->sv_cfg_lock, RW_READER);
10996139Sjb150015 bcopy(&sv->sv_cfg, cfg, sizeof (*cfg));
11006139Sjb150015 rw_exit(&sv->sv_cfg_lock);
11016139Sjb150015 }
11026139Sjb150015
11036139Sjb150015 /*
110412508Samw@Sun.COM *
110512508Samw@Sun.COM */
110612508Samw@Sun.COM void
smb_server_inc_nbt_sess(smb_server_t * sv)110712508Samw@Sun.COM smb_server_inc_nbt_sess(smb_server_t *sv)
110812508Samw@Sun.COM {
110912508Samw@Sun.COM SMB_SERVER_VALID(sv);
111012508Samw@Sun.COM atomic_inc_32(&sv->sv_nbt_sess);
111112508Samw@Sun.COM }
111212508Samw@Sun.COM
111312508Samw@Sun.COM void
smb_server_dec_nbt_sess(smb_server_t * sv)111412508Samw@Sun.COM smb_server_dec_nbt_sess(smb_server_t *sv)
111512508Samw@Sun.COM {
111612508Samw@Sun.COM SMB_SERVER_VALID(sv);
111712508Samw@Sun.COM atomic_dec_32(&sv->sv_nbt_sess);
111812508Samw@Sun.COM }
111912508Samw@Sun.COM
112012508Samw@Sun.COM void
smb_server_inc_tcp_sess(smb_server_t * sv)112112508Samw@Sun.COM smb_server_inc_tcp_sess(smb_server_t *sv)
112212508Samw@Sun.COM {
112312508Samw@Sun.COM SMB_SERVER_VALID(sv);
112412508Samw@Sun.COM atomic_inc_32(&sv->sv_tcp_sess);
112512508Samw@Sun.COM }
112612508Samw@Sun.COM
112712508Samw@Sun.COM void
smb_server_dec_tcp_sess(smb_server_t * sv)112812508Samw@Sun.COM smb_server_dec_tcp_sess(smb_server_t *sv)
112912508Samw@Sun.COM {
113012508Samw@Sun.COM SMB_SERVER_VALID(sv);
113112508Samw@Sun.COM atomic_dec_32(&sv->sv_tcp_sess);
113212508Samw@Sun.COM }
113312508Samw@Sun.COM
113412508Samw@Sun.COM void
smb_server_inc_users(smb_server_t * sv)113512508Samw@Sun.COM smb_server_inc_users(smb_server_t *sv)
113612508Samw@Sun.COM {
113712508Samw@Sun.COM SMB_SERVER_VALID(sv);
113812508Samw@Sun.COM atomic_inc_32(&sv->sv_users);
113912508Samw@Sun.COM }
114012508Samw@Sun.COM
114112508Samw@Sun.COM void
smb_server_dec_users(smb_server_t * sv)114212508Samw@Sun.COM smb_server_dec_users(smb_server_t *sv)
114312508Samw@Sun.COM {
114412508Samw@Sun.COM SMB_SERVER_VALID(sv);
114512508Samw@Sun.COM atomic_dec_32(&sv->sv_users);
114612508Samw@Sun.COM }
114712508Samw@Sun.COM
114812508Samw@Sun.COM void
smb_server_inc_trees(smb_server_t * sv)114912508Samw@Sun.COM smb_server_inc_trees(smb_server_t *sv)
115012508Samw@Sun.COM {
115112508Samw@Sun.COM SMB_SERVER_VALID(sv);
115212508Samw@Sun.COM atomic_inc_32(&sv->sv_trees);
115312508Samw@Sun.COM }
115412508Samw@Sun.COM
115512508Samw@Sun.COM void
smb_server_dec_trees(smb_server_t * sv)115612508Samw@Sun.COM smb_server_dec_trees(smb_server_t *sv)
115712508Samw@Sun.COM {
115812508Samw@Sun.COM SMB_SERVER_VALID(sv);
115912508Samw@Sun.COM atomic_dec_32(&sv->sv_trees);
116012508Samw@Sun.COM }
116112508Samw@Sun.COM
116212508Samw@Sun.COM void
smb_server_inc_files(smb_server_t * sv)116312508Samw@Sun.COM smb_server_inc_files(smb_server_t *sv)
116412508Samw@Sun.COM {
116512508Samw@Sun.COM SMB_SERVER_VALID(sv);
116612508Samw@Sun.COM atomic_inc_32(&sv->sv_files);
116712508Samw@Sun.COM }
116812508Samw@Sun.COM
116912508Samw@Sun.COM void
smb_server_dec_files(smb_server_t * sv)117012508Samw@Sun.COM smb_server_dec_files(smb_server_t *sv)
117112508Samw@Sun.COM {
117212508Samw@Sun.COM SMB_SERVER_VALID(sv);
117312508Samw@Sun.COM atomic_dec_32(&sv->sv_files);
117412508Samw@Sun.COM }
117512508Samw@Sun.COM
117612508Samw@Sun.COM void
smb_server_inc_pipes(smb_server_t * sv)117712508Samw@Sun.COM smb_server_inc_pipes(smb_server_t *sv)
117812508Samw@Sun.COM {
117912508Samw@Sun.COM SMB_SERVER_VALID(sv);
118012508Samw@Sun.COM atomic_inc_32(&sv->sv_pipes);
118112508Samw@Sun.COM }
118212508Samw@Sun.COM
118312508Samw@Sun.COM void
smb_server_dec_pipes(smb_server_t * sv)118412508Samw@Sun.COM smb_server_dec_pipes(smb_server_t *sv)
118512508Samw@Sun.COM {
118612508Samw@Sun.COM SMB_SERVER_VALID(sv);
118712508Samw@Sun.COM atomic_dec_32(&sv->sv_pipes);
118812508Samw@Sun.COM }
118912508Samw@Sun.COM
119012508Samw@Sun.COM void
smb_server_add_rxb(smb_server_t * sv,int64_t value)119112508Samw@Sun.COM smb_server_add_rxb(smb_server_t *sv, int64_t value)
119212508Samw@Sun.COM {
119312508Samw@Sun.COM SMB_SERVER_VALID(sv);
119412508Samw@Sun.COM atomic_add_64(&sv->sv_rxb, value);
119512508Samw@Sun.COM }
119612508Samw@Sun.COM
119712508Samw@Sun.COM void
smb_server_add_txb(smb_server_t * sv,int64_t value)119812508Samw@Sun.COM smb_server_add_txb(smb_server_t *sv, int64_t value)
119912508Samw@Sun.COM {
120012508Samw@Sun.COM SMB_SERVER_VALID(sv);
120112508Samw@Sun.COM atomic_add_64(&sv->sv_txb, value);
120212508Samw@Sun.COM }
120312508Samw@Sun.COM
120412508Samw@Sun.COM void
smb_server_inc_req(smb_server_t * sv)120512508Samw@Sun.COM smb_server_inc_req(smb_server_t *sv)
120612508Samw@Sun.COM {
120712508Samw@Sun.COM SMB_SERVER_VALID(sv);
120812508Samw@Sun.COM atomic_inc_64(&sv->sv_nreq);
120912508Samw@Sun.COM }
121012508Samw@Sun.COM
121112508Samw@Sun.COM /*
12126139Sjb150015 * *****************************************************************************
12136139Sjb150015 * *************************** Static Functions ********************************
12146139Sjb150015 * *****************************************************************************
12156139Sjb150015 */
12166139Sjb150015
12176139Sjb150015 static void
smb_server_timers(smb_thread_t * thread,void * arg)12186139Sjb150015 smb_server_timers(smb_thread_t *thread, void *arg)
12196139Sjb150015 {
12206139Sjb150015 smb_server_t *sv = (smb_server_t *)arg;
12216139Sjb150015
12226139Sjb150015 ASSERT(sv != NULL);
12236139Sjb150015
12246139Sjb150015 while (smb_thread_continue_timedwait(thread, 1 /* Seconds */)) {
12256139Sjb150015 smb_session_timers(&sv->sv_nbt_daemon.ld_session_list);
12266139Sjb150015 smb_session_timers(&sv->sv_tcp_daemon.ld_session_list);
12276139Sjb150015 }
12286139Sjb150015 }
12296139Sjb150015
12306139Sjb150015 /*
12316139Sjb150015 * smb_server_kstat_init
12326139Sjb150015 */
123312508Samw@Sun.COM static void
smb_server_kstat_init(smb_server_t * sv)12346139Sjb150015 smb_server_kstat_init(smb_server_t *sv)
12356139Sjb150015 {
123612890SJoyce.McIntosh@Sun.COM char name[KSTAT_STRLEN];
123712890SJoyce.McIntosh@Sun.COM
123812508Samw@Sun.COM sv->sv_ksp = kstat_create_zone(SMBSRV_KSTAT_MODULE, sv->sv_zid,
123912508Samw@Sun.COM SMBSRV_KSTAT_STATISTICS, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_RAW,
124012508Samw@Sun.COM sizeof (smbsrv_kstats_t), 0, sv->sv_zid);
12416139Sjb150015
124212508Samw@Sun.COM if (sv->sv_ksp != NULL) {
124312508Samw@Sun.COM sv->sv_ksp->ks_update = smb_server_kstat_update;
124412508Samw@Sun.COM sv->sv_ksp->ks_private = sv;
124512508Samw@Sun.COM ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_start_time =
124612508Samw@Sun.COM sv->sv_start_time;
124712508Samw@Sun.COM smb_dispatch_stats_init(
124812508Samw@Sun.COM ((smbsrv_kstats_t *)sv->sv_ksp->ks_data)->ks_reqs);
12496139Sjb150015 kstat_install(sv->sv_ksp);
125012508Samw@Sun.COM } else {
125112508Samw@Sun.COM cmn_err(CE_WARN, "SMB Server: Statistics unavailable");
12526139Sjb150015 }
125312890SJoyce.McIntosh@Sun.COM
125412890SJoyce.McIntosh@Sun.COM (void) snprintf(name, sizeof (name), "%s%d",
125512890SJoyce.McIntosh@Sun.COM SMBSRV_KSTAT_NAME, sv->sv_zid);
125612890SJoyce.McIntosh@Sun.COM
125712890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp = kstat_create(SMBSRV_KSTAT_MODULE, sv->sv_zid,
125812890SJoyce.McIntosh@Sun.COM name, SMBSRV_KSTAT_CLASS, KSTAT_TYPE_NAMED,
125912890SJoyce.McIntosh@Sun.COM sizeof (smb_server_legacy_kstat_t) / sizeof (kstat_named_t), 0);
126012890SJoyce.McIntosh@Sun.COM
126112890SJoyce.McIntosh@Sun.COM if (sv->sv_legacy_ksp != NULL) {
126212890SJoyce.McIntosh@Sun.COM smb_server_legacy_kstat_t *ksd;
126312890SJoyce.McIntosh@Sun.COM
126412890SJoyce.McIntosh@Sun.COM ksd = sv->sv_legacy_ksp->ks_data;
126512890SJoyce.McIntosh@Sun.COM
126612890SJoyce.McIntosh@Sun.COM (void) strlcpy(ksd->ls_files.name, "open_files",
126712890SJoyce.McIntosh@Sun.COM sizeof (ksd->ls_files.name));
126812890SJoyce.McIntosh@Sun.COM ksd->ls_files.data_type = KSTAT_DATA_UINT32;
126912890SJoyce.McIntosh@Sun.COM
127012890SJoyce.McIntosh@Sun.COM (void) strlcpy(ksd->ls_trees.name, "connections",
127112890SJoyce.McIntosh@Sun.COM sizeof (ksd->ls_trees.name));
127212890SJoyce.McIntosh@Sun.COM ksd->ls_trees.data_type = KSTAT_DATA_UINT32;
127312890SJoyce.McIntosh@Sun.COM
127412890SJoyce.McIntosh@Sun.COM (void) strlcpy(ksd->ls_users.name, "connections",
127512890SJoyce.McIntosh@Sun.COM sizeof (ksd->ls_users.name));
127612890SJoyce.McIntosh@Sun.COM ksd->ls_users.data_type = KSTAT_DATA_UINT32;
127712890SJoyce.McIntosh@Sun.COM
127812890SJoyce.McIntosh@Sun.COM mutex_init(&sv->sv_legacy_ksmtx, NULL, MUTEX_DEFAULT, NULL);
127912890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp->ks_lock = &sv->sv_legacy_ksmtx;
128012890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp->ks_update = smb_server_legacy_kstat_update;
128112890SJoyce.McIntosh@Sun.COM kstat_install(sv->sv_legacy_ksp);
128212890SJoyce.McIntosh@Sun.COM }
12836139Sjb150015 }
12846139Sjb150015
12856139Sjb150015 /*
12866139Sjb150015 * smb_server_kstat_fini
12876139Sjb150015 */
12886139Sjb150015 static void
smb_server_kstat_fini(smb_server_t * sv)12896139Sjb150015 smb_server_kstat_fini(smb_server_t *sv)
12906139Sjb150015 {
129112890SJoyce.McIntosh@Sun.COM if (sv->sv_legacy_ksp != NULL) {
129212890SJoyce.McIntosh@Sun.COM kstat_delete(sv->sv_legacy_ksp);
129312890SJoyce.McIntosh@Sun.COM mutex_destroy(&sv->sv_legacy_ksmtx);
129412890SJoyce.McIntosh@Sun.COM sv->sv_legacy_ksp = NULL;
129512890SJoyce.McIntosh@Sun.COM }
129612890SJoyce.McIntosh@Sun.COM
129712508Samw@Sun.COM if (sv->sv_ksp != NULL) {
12986139Sjb150015 kstat_delete(sv->sv_ksp);
12996139Sjb150015 sv->sv_ksp = NULL;
130012508Samw@Sun.COM smb_dispatch_stats_fini();
13016139Sjb150015 }
13026139Sjb150015 }
13036139Sjb150015
130412508Samw@Sun.COM /*
130512508Samw@Sun.COM * smb_server_kstat_update
130612508Samw@Sun.COM */
13076139Sjb150015 static int
smb_server_kstat_update(kstat_t * ksp,int rw)130812508Samw@Sun.COM smb_server_kstat_update(kstat_t *ksp, int rw)
13096139Sjb150015 {
13106139Sjb150015 smb_server_t *sv;
131112508Samw@Sun.COM smbsrv_kstats_t *ksd;
13126139Sjb150015
131312508Samw@Sun.COM if (rw == KSTAT_READ) {
131412508Samw@Sun.COM sv = ksp->ks_private;
131511963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
131612508Samw@Sun.COM ksd = (smbsrv_kstats_t *)ksp->ks_data;
131712508Samw@Sun.COM /*
131812508Samw@Sun.COM * Counters
131912508Samw@Sun.COM */
132012508Samw@Sun.COM ksd->ks_nbt_sess = sv->sv_nbt_sess;
132112508Samw@Sun.COM ksd->ks_tcp_sess = sv->sv_tcp_sess;
132212508Samw@Sun.COM ksd->ks_users = sv->sv_users;
132312508Samw@Sun.COM ksd->ks_trees = sv->sv_trees;
132412508Samw@Sun.COM ksd->ks_files = sv->sv_files;
132512508Samw@Sun.COM ksd->ks_pipes = sv->sv_pipes;
132612508Samw@Sun.COM /*
132712508Samw@Sun.COM * Throughput
132812508Samw@Sun.COM */
132912508Samw@Sun.COM ksd->ks_txb = sv->sv_txb;
133012508Samw@Sun.COM ksd->ks_rxb = sv->sv_rxb;
133112508Samw@Sun.COM ksd->ks_nreq = sv->sv_nreq;
133212508Samw@Sun.COM /*
133312508Samw@Sun.COM * Busyness
133412508Samw@Sun.COM */
133512508Samw@Sun.COM ksd->ks_maxreqs = sv->sv_cfg.skc_maxworkers;
133612508Samw@Sun.COM smb_srqueue_update(&sv->sv_srqueue,
133712508Samw@Sun.COM &ksd->ks_utilization);
133812508Samw@Sun.COM /*
133912508Samw@Sun.COM * Latency & Throughput of the requests
134012508Samw@Sun.COM */
134112508Samw@Sun.COM smb_dispatch_stats_update(ksd->ks_reqs, 0, SMB_COM_NUM);
134212508Samw@Sun.COM return (0);
134312508Samw@Sun.COM }
134412508Samw@Sun.COM if (rw == KSTAT_WRITE)
134512508Samw@Sun.COM return (EACCES);
13466139Sjb150015
134712508Samw@Sun.COM return (EIO);
13486139Sjb150015 }
13496139Sjb150015
135012890SJoyce.McIntosh@Sun.COM static int
smb_server_legacy_kstat_update(kstat_t * ksp,int rw)135112890SJoyce.McIntosh@Sun.COM smb_server_legacy_kstat_update(kstat_t *ksp, int rw)
135212890SJoyce.McIntosh@Sun.COM {
135312890SJoyce.McIntosh@Sun.COM smb_server_t *sv;
135412890SJoyce.McIntosh@Sun.COM smb_server_legacy_kstat_t *ksd;
135512890SJoyce.McIntosh@Sun.COM int rc;
135612890SJoyce.McIntosh@Sun.COM
135712890SJoyce.McIntosh@Sun.COM switch (rw) {
135812890SJoyce.McIntosh@Sun.COM case KSTAT_WRITE:
135912890SJoyce.McIntosh@Sun.COM rc = EACCES;
136012890SJoyce.McIntosh@Sun.COM break;
136112890SJoyce.McIntosh@Sun.COM case KSTAT_READ:
136212890SJoyce.McIntosh@Sun.COM if (!smb_server_lookup(&sv)) {
136312890SJoyce.McIntosh@Sun.COM ASSERT(MUTEX_HELD(ksp->ks_lock));
136412890SJoyce.McIntosh@Sun.COM ASSERT(sv->sv_legacy_ksp == ksp);
136512890SJoyce.McIntosh@Sun.COM ksd = (smb_server_legacy_kstat_t *)ksp->ks_data;
136612890SJoyce.McIntosh@Sun.COM ksd->ls_files.value.ui32 = sv->sv_files + sv->sv_pipes;
136712890SJoyce.McIntosh@Sun.COM ksd->ls_trees.value.ui32 = sv->sv_trees;
136812890SJoyce.McIntosh@Sun.COM ksd->ls_users.value.ui32 = sv->sv_users;
136912890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
137012890SJoyce.McIntosh@Sun.COM rc = 0;
137112890SJoyce.McIntosh@Sun.COM break;
137212890SJoyce.McIntosh@Sun.COM }
137312890SJoyce.McIntosh@Sun.COM _NOTE(FALLTHRU)
137412890SJoyce.McIntosh@Sun.COM default:
137512890SJoyce.McIntosh@Sun.COM rc = EIO;
137612890SJoyce.McIntosh@Sun.COM break;
137712890SJoyce.McIntosh@Sun.COM }
137812890SJoyce.McIntosh@Sun.COM return (rc);
137912890SJoyce.McIntosh@Sun.COM
138012890SJoyce.McIntosh@Sun.COM }
138112890SJoyce.McIntosh@Sun.COM
13826139Sjb150015 /*
1383*13138SJose.Borrego@Sun.COM * smb_server_shutdown
13846139Sjb150015 */
13856139Sjb150015 static void
smb_server_shutdown(smb_server_t * sv)138611963SAfshin.Ardakani@Sun.COM smb_server_shutdown(smb_server_t *sv)
13876139Sjb150015 {
138811963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
13896139Sjb150015
13907052Samw smb_opipe_door_close();
13916139Sjb150015 smb_thread_stop(&sv->si_thread_timers);
139211963SAfshin.Ardakani@Sun.COM smb_kdoor_close();
139312508Samw@Sun.COM smb_kshare_door_fini(sv->sv_lmshrd);
13946849Sjb150015 sv->sv_lmshrd = NULL;
139512508Samw@Sun.COM smb_export_stop();
13966139Sjb150015 smb_server_fsop_stop(sv);
13977588Samw@Sun.COM
1398*13138SJose.Borrego@Sun.COM smb_server_listener_stop(&sv->sv_nbt_daemon);
1399*13138SJose.Borrego@Sun.COM smb_server_listener_stop(&sv->sv_tcp_daemon);
1400*13138SJose.Borrego@Sun.COM
1401*13138SJose.Borrego@Sun.COM if (sv->sv_session != NULL) {
14026139Sjb150015 smb_session_delete(sv->sv_session);
14036139Sjb150015 sv->sv_session = NULL;
14046139Sjb150015 }
14057588Samw@Sun.COM
1406*13138SJose.Borrego@Sun.COM if (sv->sv_receiver_pool != NULL) {
1407*13138SJose.Borrego@Sun.COM taskq_destroy(sv->sv_receiver_pool);
1408*13138SJose.Borrego@Sun.COM sv->sv_receiver_pool = NULL;
1409*13138SJose.Borrego@Sun.COM }
1410*13138SJose.Borrego@Sun.COM
1411*13138SJose.Borrego@Sun.COM if (sv->sv_worker_pool != NULL) {
1412*13138SJose.Borrego@Sun.COM taskq_destroy(sv->sv_worker_pool);
1413*13138SJose.Borrego@Sun.COM sv->sv_worker_pool = NULL;
14147588Samw@Sun.COM }
14156139Sjb150015 }
14166139Sjb150015
1417*13138SJose.Borrego@Sun.COM /*
1418*13138SJose.Borrego@Sun.COM * smb_server_listener_init
1419*13138SJose.Borrego@Sun.COM *
1420*13138SJose.Borrego@Sun.COM * Initializes listener contexts.
1421*13138SJose.Borrego@Sun.COM */
1422*13138SJose.Borrego@Sun.COM static void
smb_server_listener_init(smb_server_t * sv,smb_listener_daemon_t * ld,char * name,in_port_t port,int family)1423*13138SJose.Borrego@Sun.COM smb_server_listener_init(
14246139Sjb150015 smb_server_t *sv,
14256139Sjb150015 smb_listener_daemon_t *ld,
1426*13138SJose.Borrego@Sun.COM char *name,
14276139Sjb150015 in_port_t port,
1428*13138SJose.Borrego@Sun.COM int family)
14296139Sjb150015 {
1430*13138SJose.Borrego@Sun.COM ASSERT(ld->ld_magic != SMB_LISTENER_MAGIC);
1431*13138SJose.Borrego@Sun.COM
1432*13138SJose.Borrego@Sun.COM bzero(ld, sizeof (*ld));
1433*13138SJose.Borrego@Sun.COM
1434*13138SJose.Borrego@Sun.COM ld->ld_sv = sv;
1435*13138SJose.Borrego@Sun.COM ld->ld_family = family;
1436*13138SJose.Borrego@Sun.COM ld->ld_port = port;
14376139Sjb150015
1438*13138SJose.Borrego@Sun.COM if (family == AF_INET) {
1439*13138SJose.Borrego@Sun.COM ld->ld_sin.sin_family = (uint32_t)family;
1440*13138SJose.Borrego@Sun.COM ld->ld_sin.sin_port = htons(port);
1441*13138SJose.Borrego@Sun.COM ld->ld_sin.sin_addr.s_addr = htonl(INADDR_ANY);
1442*13138SJose.Borrego@Sun.COM } else {
1443*13138SJose.Borrego@Sun.COM ld->ld_sin6.sin6_family = (uint32_t)family;
1444*13138SJose.Borrego@Sun.COM ld->ld_sin6.sin6_port = htons(port);
1445*13138SJose.Borrego@Sun.COM (void) memset(&ld->ld_sin6.sin6_addr.s6_addr, 0,
1446*13138SJose.Borrego@Sun.COM sizeof (ld->ld_sin6.sin6_addr.s6_addr));
14476139Sjb150015 }
14486139Sjb150015
1449*13138SJose.Borrego@Sun.COM smb_llist_constructor(&ld->ld_session_list, sizeof (smb_session_t),
1450*13138SJose.Borrego@Sun.COM offsetof(smb_session_t, s_lnd));
1451*13138SJose.Borrego@Sun.COM smb_thread_init(&ld->ld_thread, name, smb_server_listener, ld);
1452*13138SJose.Borrego@Sun.COM ld->ld_magic = SMB_LISTENER_MAGIC;
1453*13138SJose.Borrego@Sun.COM }
1454*13138SJose.Borrego@Sun.COM
1455*13138SJose.Borrego@Sun.COM /*
1456*13138SJose.Borrego@Sun.COM * smb_server_listener_destroy
1457*13138SJose.Borrego@Sun.COM *
1458*13138SJose.Borrego@Sun.COM * Destroyes listener contexts.
1459*13138SJose.Borrego@Sun.COM */
1460*13138SJose.Borrego@Sun.COM static void
smb_server_listener_destroy(smb_listener_daemon_t * ld)1461*13138SJose.Borrego@Sun.COM smb_server_listener_destroy(smb_listener_daemon_t *ld)
1462*13138SJose.Borrego@Sun.COM {
1463*13138SJose.Borrego@Sun.COM SMB_LISTENER_VALID(ld);
1464*13138SJose.Borrego@Sun.COM ASSERT(ld->ld_so == NULL);
1465*13138SJose.Borrego@Sun.COM smb_thread_destroy(&ld->ld_thread);
1466*13138SJose.Borrego@Sun.COM smb_llist_destructor(&ld->ld_session_list);
1467*13138SJose.Borrego@Sun.COM ld->ld_magic = 0;
1468*13138SJose.Borrego@Sun.COM }
1469*13138SJose.Borrego@Sun.COM
1470*13138SJose.Borrego@Sun.COM /*
1471*13138SJose.Borrego@Sun.COM * smb_server_listener_start
1472*13138SJose.Borrego@Sun.COM *
1473*13138SJose.Borrego@Sun.COM * Starts the listener associated with the context passed in.
1474*13138SJose.Borrego@Sun.COM *
1475*13138SJose.Borrego@Sun.COM * Return: 0 Success
1476*13138SJose.Borrego@Sun.COM * not 0 Failure
1477*13138SJose.Borrego@Sun.COM */
1478*13138SJose.Borrego@Sun.COM static int
smb_server_listener_start(smb_listener_daemon_t * ld)1479*13138SJose.Borrego@Sun.COM smb_server_listener_start(smb_listener_daemon_t *ld)
1480*13138SJose.Borrego@Sun.COM {
1481*13138SJose.Borrego@Sun.COM int rc;
1482*13138SJose.Borrego@Sun.COM uint32_t on;
1483*13138SJose.Borrego@Sun.COM uint32_t off;
1484*13138SJose.Borrego@Sun.COM
1485*13138SJose.Borrego@Sun.COM SMB_LISTENER_VALID(ld);
1486*13138SJose.Borrego@Sun.COM
1487*13138SJose.Borrego@Sun.COM if (ld->ld_so != NULL)
1488*13138SJose.Borrego@Sun.COM return (EINVAL);
1489*13138SJose.Borrego@Sun.COM
1490*13138SJose.Borrego@Sun.COM ld->ld_so = smb_socreate(ld->ld_family, SOCK_STREAM, 0);
14916139Sjb150015 if (ld->ld_so == NULL) {
1492*13138SJose.Borrego@Sun.COM cmn_err(CE_WARN, "port %d: socket create failed", ld->ld_port);
1493*13138SJose.Borrego@Sun.COM return (ENOMEM);
1494*13138SJose.Borrego@Sun.COM }
149511963SAfshin.Ardakani@Sun.COM
1496*13138SJose.Borrego@Sun.COM off = 0;
1497*13138SJose.Borrego@Sun.COM (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1498*13138SJose.Borrego@Sun.COM SO_MAC_EXEMPT, &off, sizeof (off), CRED());
14996139Sjb150015
1500*13138SJose.Borrego@Sun.COM on = 1;
1501*13138SJose.Borrego@Sun.COM (void) ksocket_setsockopt(ld->ld_so, SOL_SOCKET,
1502*13138SJose.Borrego@Sun.COM SO_REUSEADDR, &on, sizeof (on), CRED());
150311963SAfshin.Ardakani@Sun.COM
1504*13138SJose.Borrego@Sun.COM if (ld->ld_family == AF_INET) {
1505*13138SJose.Borrego@Sun.COM rc = ksocket_bind(ld->ld_so,
1506*13138SJose.Borrego@Sun.COM (struct sockaddr *)&ld->ld_sin,
1507*13138SJose.Borrego@Sun.COM sizeof (ld->ld_sin), CRED());
1508*13138SJose.Borrego@Sun.COM } else {
1509*13138SJose.Borrego@Sun.COM rc = ksocket_bind(ld->ld_so,
1510*13138SJose.Borrego@Sun.COM (struct sockaddr *)&ld->ld_sin6,
1511*13138SJose.Borrego@Sun.COM sizeof (ld->ld_sin6), CRED());
1512*13138SJose.Borrego@Sun.COM }
1513*13138SJose.Borrego@Sun.COM
1514*13138SJose.Borrego@Sun.COM if (rc != 0) {
1515*13138SJose.Borrego@Sun.COM cmn_err(CE_WARN, "port %d: bind failed", ld->ld_port);
1516*13138SJose.Borrego@Sun.COM return (rc);
1517*13138SJose.Borrego@Sun.COM }
15189021Samw@Sun.COM
1519*13138SJose.Borrego@Sun.COM rc = ksocket_listen(ld->ld_so, 20, CRED());
1520*13138SJose.Borrego@Sun.COM if (rc < 0) {
1521*13138SJose.Borrego@Sun.COM cmn_err(CE_WARN, "port %d: listen failed", ld->ld_port);
1522*13138SJose.Borrego@Sun.COM return (rc);
1523*13138SJose.Borrego@Sun.COM }
1524*13138SJose.Borrego@Sun.COM
1525*13138SJose.Borrego@Sun.COM ksocket_hold(ld->ld_so);
1526*13138SJose.Borrego@Sun.COM rc = smb_thread_start(&ld->ld_thread);
1527*13138SJose.Borrego@Sun.COM if (rc != 0) {
1528*13138SJose.Borrego@Sun.COM ksocket_rele(ld->ld_so);
1529*13138SJose.Borrego@Sun.COM cmn_err(CE_WARN, "port %d: listener failed to start",
1530*13138SJose.Borrego@Sun.COM ld->ld_port);
1531*13138SJose.Borrego@Sun.COM return (rc);
1532*13138SJose.Borrego@Sun.COM }
1533*13138SJose.Borrego@Sun.COM return (0);
1534*13138SJose.Borrego@Sun.COM }
153511963SAfshin.Ardakani@Sun.COM
1536*13138SJose.Borrego@Sun.COM /*
1537*13138SJose.Borrego@Sun.COM * smb_server_listener_stop
1538*13138SJose.Borrego@Sun.COM *
1539*13138SJose.Borrego@Sun.COM * Stops the listener associated with the context passed in.
1540*13138SJose.Borrego@Sun.COM */
1541*13138SJose.Borrego@Sun.COM static void
smb_server_listener_stop(smb_listener_daemon_t * ld)1542*13138SJose.Borrego@Sun.COM smb_server_listener_stop(smb_listener_daemon_t *ld)
1543*13138SJose.Borrego@Sun.COM {
1544*13138SJose.Borrego@Sun.COM SMB_LISTENER_VALID(ld);
1545*13138SJose.Borrego@Sun.COM
1546*13138SJose.Borrego@Sun.COM if (ld->ld_so != NULL) {
1547*13138SJose.Borrego@Sun.COM smb_soshutdown(ld->ld_so);
1548*13138SJose.Borrego@Sun.COM smb_sodestroy(ld->ld_so);
1549*13138SJose.Borrego@Sun.COM smb_thread_stop(&ld->ld_thread);
1550*13138SJose.Borrego@Sun.COM ld->ld_so = NULL;
1551*13138SJose.Borrego@Sun.COM }
1552*13138SJose.Borrego@Sun.COM }
155311963SAfshin.Ardakani@Sun.COM
1554*13138SJose.Borrego@Sun.COM /*
1555*13138SJose.Borrego@Sun.COM * smb_server_listener
1556*13138SJose.Borrego@Sun.COM *
1557*13138SJose.Borrego@Sun.COM * Entry point of the listeners.
1558*13138SJose.Borrego@Sun.COM */
1559*13138SJose.Borrego@Sun.COM static void
smb_server_listener(smb_thread_t * thread,void * arg)1560*13138SJose.Borrego@Sun.COM smb_server_listener(smb_thread_t *thread, void *arg)
1561*13138SJose.Borrego@Sun.COM {
1562*13138SJose.Borrego@Sun.COM _NOTE(ARGUNUSED(thread))
1563*13138SJose.Borrego@Sun.COM smb_listener_daemon_t *ld;
1564*13138SJose.Borrego@Sun.COM smb_session_t *session;
1565*13138SJose.Borrego@Sun.COM ksocket_t s_so;
1566*13138SJose.Borrego@Sun.COM int on;
1567*13138SJose.Borrego@Sun.COM int txbuf_size;
1568*13138SJose.Borrego@Sun.COM
1569*13138SJose.Borrego@Sun.COM ld = (smb_listener_daemon_t *)arg;
1570*13138SJose.Borrego@Sun.COM
1571*13138SJose.Borrego@Sun.COM SMB_LISTENER_VALID(ld);
15726139Sjb150015
15736139Sjb150015 DTRACE_PROBE1(so__wait__accept, struct sonode *, ld->ld_so);
15746139Sjb150015
1575*13138SJose.Borrego@Sun.COM while (ksocket_accept(ld->ld_so, NULL, NULL, &s_so, CRED())
1576*13138SJose.Borrego@Sun.COM == 0) {
157711963SAfshin.Ardakani@Sun.COM DTRACE_PROBE1(so__accept, struct sonode *, s_so);
157811963SAfshin.Ardakani@Sun.COM
157911963SAfshin.Ardakani@Sun.COM on = 1;
158011963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(s_so, IPPROTO_TCP, TCP_NODELAY,
158111963SAfshin.Ardakani@Sun.COM &on, sizeof (on), CRED());
158211963SAfshin.Ardakani@Sun.COM
158311963SAfshin.Ardakani@Sun.COM on = 1;
158411963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_KEEPALIVE,
158511963SAfshin.Ardakani@Sun.COM &on, sizeof (on), CRED());
15866139Sjb150015
158711963SAfshin.Ardakani@Sun.COM txbuf_size = 128*1024;
158811963SAfshin.Ardakani@Sun.COM (void) ksocket_setsockopt(s_so, SOL_SOCKET, SO_SNDBUF,
158911963SAfshin.Ardakani@Sun.COM (const void *)&txbuf_size, sizeof (txbuf_size), CRED());
159011963SAfshin.Ardakani@Sun.COM
159111963SAfshin.Ardakani@Sun.COM /*
159211963SAfshin.Ardakani@Sun.COM * Create a session for this connection.
159311963SAfshin.Ardakani@Sun.COM */
1594*13138SJose.Borrego@Sun.COM smb_server_create_session(ld, s_so);
159511963SAfshin.Ardakani@Sun.COM }
1596*13138SJose.Borrego@Sun.COM /* Disconnect all the sessions this listener created. */
1597*13138SJose.Borrego@Sun.COM smb_llist_enter(&ld->ld_session_list, RW_READER);
1598*13138SJose.Borrego@Sun.COM session = smb_llist_head(&ld->ld_session_list);
1599*13138SJose.Borrego@Sun.COM while (session != NULL) {
1600*13138SJose.Borrego@Sun.COM smb_session_disconnect(session);
1601*13138SJose.Borrego@Sun.COM session = smb_llist_next(&ld->ld_session_list, session);
1602*13138SJose.Borrego@Sun.COM }
1603*13138SJose.Borrego@Sun.COM smb_llist_exit(&ld->ld_session_list);
1604*13138SJose.Borrego@Sun.COM ksocket_rele(ld->ld_so);
160511963SAfshin.Ardakani@Sun.COM }
160611963SAfshin.Ardakani@Sun.COM
1607*13138SJose.Borrego@Sun.COM /*
1608*13138SJose.Borrego@Sun.COM * smb_server_receiver
1609*13138SJose.Borrego@Sun.COM *
1610*13138SJose.Borrego@Sun.COM * Entry point of the receiver threads.
1611*13138SJose.Borrego@Sun.COM */
161211963SAfshin.Ardakani@Sun.COM static void
smb_server_receiver(void * arg)1613*13138SJose.Borrego@Sun.COM smb_server_receiver(void *arg)
161411963SAfshin.Ardakani@Sun.COM {
1615*13138SJose.Borrego@Sun.COM smb_listener_daemon_t *ld;
1616*13138SJose.Borrego@Sun.COM smb_session_t *session;
161711963SAfshin.Ardakani@Sun.COM
1618*13138SJose.Borrego@Sun.COM ld = ((smb_receiver_arg_t *)arg)->ra_listener;
1619*13138SJose.Borrego@Sun.COM session = ((smb_receiver_arg_t *)arg)->ra_session;
1620*13138SJose.Borrego@Sun.COM smb_mem_free(arg);
1621*13138SJose.Borrego@Sun.COM smb_session_receiver(session);
1622*13138SJose.Borrego@Sun.COM smb_server_destroy_session(ld, session);
16236139Sjb150015 }
16246139Sjb150015
16256139Sjb150015 /*
16266139Sjb150015 * smb_server_lookup
16276139Sjb150015 *
16286139Sjb150015 * This function tries to find the server associated with the zone of the
16296139Sjb150015 * caller.
16306139Sjb150015 */
16316139Sjb150015 static int
smb_server_lookup(smb_server_t ** psv)16326139Sjb150015 smb_server_lookup(smb_server_t **psv)
16336139Sjb150015 {
16346139Sjb150015 zoneid_t zid;
16356139Sjb150015 smb_server_t *sv;
16366139Sjb150015
16376139Sjb150015 zid = getzoneid();
16386139Sjb150015
16396139Sjb150015 smb_llist_enter(&smb_servers, RW_READER);
16406139Sjb150015 sv = smb_llist_head(&smb_servers);
16416139Sjb150015 while (sv) {
164211963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
16436139Sjb150015 if (sv->sv_zid == zid) {
16446139Sjb150015 mutex_enter(&sv->sv_mutex);
16456139Sjb150015 if (sv->sv_state != SMB_SERVER_STATE_DELETING) {
16466139Sjb150015 sv->sv_refcnt++;
16476139Sjb150015 mutex_exit(&sv->sv_mutex);
16486139Sjb150015 smb_llist_exit(&smb_servers);
16496139Sjb150015 *psv = sv;
16506139Sjb150015 return (0);
16516139Sjb150015 }
16526139Sjb150015 mutex_exit(&sv->sv_mutex);
16536139Sjb150015 break;
16546139Sjb150015 }
16556139Sjb150015 sv = smb_llist_next(&smb_servers, sv);
16566139Sjb150015 }
16576139Sjb150015 smb_llist_exit(&smb_servers);
16586139Sjb150015 return (EPERM);
16596139Sjb150015 }
16606139Sjb150015
16616139Sjb150015 /*
16626139Sjb150015 * smb_server_release
16636139Sjb150015 *
16646139Sjb150015 * This function decrements the reference count of the server and signals its
16656139Sjb150015 * condition variable if the state of the server is SMB_SERVER_STATE_DELETING.
16666139Sjb150015 */
16676139Sjb150015 static void
smb_server_release(smb_server_t * sv)16686139Sjb150015 smb_server_release(smb_server_t *sv)
16696139Sjb150015 {
167011963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
16716139Sjb150015
16726139Sjb150015 mutex_enter(&sv->sv_mutex);
16736139Sjb150015 ASSERT(sv->sv_refcnt);
16746139Sjb150015 sv->sv_refcnt--;
16756139Sjb150015 if ((sv->sv_refcnt == 0) && (sv->sv_state == SMB_SERVER_STATE_DELETING))
16766139Sjb150015 cv_signal(&sv->sv_cv);
16776139Sjb150015 mutex_exit(&sv->sv_mutex);
16786139Sjb150015 }
16796139Sjb150015
168010122SJordan.Brown@Sun.COM /*
168110122SJordan.Brown@Sun.COM * Enumerate the users associated with a session list.
168210122SJordan.Brown@Sun.COM */
168310122SJordan.Brown@Sun.COM static void
smb_server_enum_private(smb_llist_t * ll,smb_svcenum_t * svcenum)1684*13138SJose.Borrego@Sun.COM smb_server_enum_private(smb_llist_t *ll, smb_svcenum_t *svcenum)
16856139Sjb150015 {
168610122SJordan.Brown@Sun.COM smb_session_t *sn;
168710122SJordan.Brown@Sun.COM smb_llist_t *ulist;
168810122SJordan.Brown@Sun.COM smb_user_t *user;
168910122SJordan.Brown@Sun.COM int rc = 0;
16906139Sjb150015
1691*13138SJose.Borrego@Sun.COM smb_llist_enter(ll, RW_READER);
1692*13138SJose.Borrego@Sun.COM sn = smb_llist_head(ll);
169310122SJordan.Brown@Sun.COM
169410122SJordan.Brown@Sun.COM while (sn != NULL) {
1695*13138SJose.Borrego@Sun.COM SMB_SESSION_VALID(sn);
16966139Sjb150015 ulist = &sn->s_user_list;
16976139Sjb150015 smb_llist_enter(ulist, RW_READER);
16986139Sjb150015 user = smb_llist_head(ulist);
169910122SJordan.Brown@Sun.COM
170010122SJordan.Brown@Sun.COM while (user != NULL) {
170110122SJordan.Brown@Sun.COM if (smb_user_hold(user)) {
170210122SJordan.Brown@Sun.COM rc = smb_user_enum(user, svcenum);
170310122SJordan.Brown@Sun.COM smb_user_release(user);
170410122SJordan.Brown@Sun.COM }
170510122SJordan.Brown@Sun.COM
170610122SJordan.Brown@Sun.COM user = smb_llist_next(ulist, user);
170710122SJordan.Brown@Sun.COM }
170810122SJordan.Brown@Sun.COM
170910122SJordan.Brown@Sun.COM smb_llist_exit(ulist);
171010122SJordan.Brown@Sun.COM
171110122SJordan.Brown@Sun.COM if (rc != 0)
171210122SJordan.Brown@Sun.COM break;
171310122SJordan.Brown@Sun.COM
1714*13138SJose.Borrego@Sun.COM sn = smb_llist_next(ll, sn);
171510122SJordan.Brown@Sun.COM }
171610122SJordan.Brown@Sun.COM
1717*13138SJose.Borrego@Sun.COM smb_llist_exit(ll);
171810122SJordan.Brown@Sun.COM }
171910122SJordan.Brown@Sun.COM
172010122SJordan.Brown@Sun.COM /*
172110122SJordan.Brown@Sun.COM * Disconnect sessions associated with the specified client and username.
172210122SJordan.Brown@Sun.COM * Empty strings are treated as wildcards.
172310122SJordan.Brown@Sun.COM */
172410122SJordan.Brown@Sun.COM static int
smb_server_session_disconnect(smb_llist_t * ll,const char * client,const char * name)1725*13138SJose.Borrego@Sun.COM smb_server_session_disconnect(smb_llist_t *ll,
172610122SJordan.Brown@Sun.COM const char *client, const char *name)
172710122SJordan.Brown@Sun.COM {
172810122SJordan.Brown@Sun.COM smb_session_t *sn;
172910122SJordan.Brown@Sun.COM smb_llist_t *ulist;
173010122SJordan.Brown@Sun.COM smb_user_t *user;
173110122SJordan.Brown@Sun.COM boolean_t match;
173210122SJordan.Brown@Sun.COM int count = 0;
173310122SJordan.Brown@Sun.COM
1734*13138SJose.Borrego@Sun.COM smb_llist_enter(ll, RW_READER);
1735*13138SJose.Borrego@Sun.COM sn = smb_llist_head(ll);
173610122SJordan.Brown@Sun.COM
173710122SJordan.Brown@Sun.COM while (sn != NULL) {
1738*13138SJose.Borrego@Sun.COM SMB_SESSION_VALID(sn);
173910122SJordan.Brown@Sun.COM
174010122SJordan.Brown@Sun.COM if ((*client != '\0') && (!smb_session_isclient(sn, client))) {
1741*13138SJose.Borrego@Sun.COM sn = smb_llist_next(ll, sn);
174210122SJordan.Brown@Sun.COM continue;
174310122SJordan.Brown@Sun.COM }
174410122SJordan.Brown@Sun.COM
174510122SJordan.Brown@Sun.COM ulist = &sn->s_user_list;
174610122SJordan.Brown@Sun.COM smb_llist_enter(ulist, RW_READER);
174710122SJordan.Brown@Sun.COM user = smb_llist_head(ulist);
174810122SJordan.Brown@Sun.COM
174910122SJordan.Brown@Sun.COM while (user != NULL) {
175010122SJordan.Brown@Sun.COM if (smb_user_hold(user)) {
175110122SJordan.Brown@Sun.COM match = (*name == '\0');
175210122SJordan.Brown@Sun.COM if (!match)
175310122SJordan.Brown@Sun.COM match = smb_user_namecmp(user, name);
175410122SJordan.Brown@Sun.COM
175510122SJordan.Brown@Sun.COM if (match) {
175610122SJordan.Brown@Sun.COM smb_llist_exit(ulist);
175710122SJordan.Brown@Sun.COM smb_user_logoff(user);
175810122SJordan.Brown@Sun.COM ++count;
175910122SJordan.Brown@Sun.COM smb_user_release(user);
176010122SJordan.Brown@Sun.COM smb_llist_enter(ulist, RW_READER);
176110122SJordan.Brown@Sun.COM user = smb_llist_head(ulist);
176210122SJordan.Brown@Sun.COM continue;
17636139Sjb150015 }
176410122SJordan.Brown@Sun.COM
176510122SJordan.Brown@Sun.COM smb_user_release(user);
17666139Sjb150015 }
176710122SJordan.Brown@Sun.COM
17686139Sjb150015 user = smb_llist_next(ulist, user);
17696139Sjb150015 }
177010122SJordan.Brown@Sun.COM
17716139Sjb150015 smb_llist_exit(ulist);
1772*13138SJose.Borrego@Sun.COM sn = smb_llist_next(ll, sn);
17736139Sjb150015 }
177410122SJordan.Brown@Sun.COM
1775*13138SJose.Borrego@Sun.COM smb_llist_exit(ll);
177610122SJordan.Brown@Sun.COM return (count);
177710122SJordan.Brown@Sun.COM }
177810122SJordan.Brown@Sun.COM
177910122SJordan.Brown@Sun.COM /*
178010122SJordan.Brown@Sun.COM * Close a file by its unique id.
178110122SJordan.Brown@Sun.COM */
178210122SJordan.Brown@Sun.COM static int
smb_server_fclose(smb_llist_t * ll,uint32_t uniqid)1783*13138SJose.Borrego@Sun.COM smb_server_fclose(smb_llist_t *ll, uint32_t uniqid)
178410122SJordan.Brown@Sun.COM {
178510122SJordan.Brown@Sun.COM smb_session_t *sn;
178610122SJordan.Brown@Sun.COM smb_llist_t *ulist;
178710122SJordan.Brown@Sun.COM smb_user_t *user;
178810122SJordan.Brown@Sun.COM int rc = ENOENT;
178910122SJordan.Brown@Sun.COM
1790*13138SJose.Borrego@Sun.COM smb_llist_enter(ll, RW_READER);
1791*13138SJose.Borrego@Sun.COM sn = smb_llist_head(ll);
179210122SJordan.Brown@Sun.COM
179310122SJordan.Brown@Sun.COM while ((sn != NULL) && (rc == ENOENT)) {
1794*13138SJose.Borrego@Sun.COM SMB_SESSION_VALID(sn);
179510122SJordan.Brown@Sun.COM ulist = &sn->s_user_list;
179610122SJordan.Brown@Sun.COM smb_llist_enter(ulist, RW_READER);
179710122SJordan.Brown@Sun.COM user = smb_llist_head(ulist);
179810122SJordan.Brown@Sun.COM
179910122SJordan.Brown@Sun.COM while ((user != NULL) && (rc == ENOENT)) {
180010122SJordan.Brown@Sun.COM if (smb_user_hold(user)) {
180110122SJordan.Brown@Sun.COM rc = smb_user_fclose(user, uniqid);
180210122SJordan.Brown@Sun.COM smb_user_release(user);
180310122SJordan.Brown@Sun.COM }
180410122SJordan.Brown@Sun.COM
180510122SJordan.Brown@Sun.COM user = smb_llist_next(ulist, user);
180610122SJordan.Brown@Sun.COM }
180710122SJordan.Brown@Sun.COM
180810122SJordan.Brown@Sun.COM smb_llist_exit(ulist);
1809*13138SJose.Borrego@Sun.COM sn = smb_llist_next(ll, sn);
181010122SJordan.Brown@Sun.COM }
181110122SJordan.Brown@Sun.COM
1812*13138SJose.Borrego@Sun.COM smb_llist_exit(ll);
181310122SJordan.Brown@Sun.COM return (rc);
18146139Sjb150015 }
18156139Sjb150015
18166139Sjb150015 static void
smb_server_store_cfg(smb_server_t * sv,smb_ioc_cfg_t * ioc)18179832Samw@Sun.COM smb_server_store_cfg(smb_server_t *sv, smb_ioc_cfg_t *ioc)
18186139Sjb150015 {
18199832Samw@Sun.COM if (ioc->maxconnections == 0)
18209832Samw@Sun.COM ioc->maxconnections = 0xFFFFFFFF;
18216139Sjb150015
18226139Sjb150015 smb_session_correct_keep_alive_values(
18239832Samw@Sun.COM &sv->sv_nbt_daemon.ld_session_list, ioc->keepalive);
18246139Sjb150015 smb_session_correct_keep_alive_values(
18259832Samw@Sun.COM &sv->sv_tcp_daemon.ld_session_list, ioc->keepalive);
18266139Sjb150015
18279832Samw@Sun.COM sv->sv_cfg.skc_maxworkers = ioc->maxworkers;
18289832Samw@Sun.COM sv->sv_cfg.skc_maxconnections = ioc->maxconnections;
18299832Samw@Sun.COM sv->sv_cfg.skc_keepalive = ioc->keepalive;
18309832Samw@Sun.COM sv->sv_cfg.skc_restrict_anon = ioc->restrict_anon;
18319832Samw@Sun.COM sv->sv_cfg.skc_signing_enable = ioc->signing_enable;
18329832Samw@Sun.COM sv->sv_cfg.skc_signing_required = ioc->signing_required;
18339832Samw@Sun.COM sv->sv_cfg.skc_oplock_enable = ioc->oplock_enable;
18349832Samw@Sun.COM sv->sv_cfg.skc_sync_enable = ioc->sync_enable;
18359832Samw@Sun.COM sv->sv_cfg.skc_secmode = ioc->secmode;
18369832Samw@Sun.COM sv->sv_cfg.skc_ipv6_enable = ioc->ipv6_enable;
183712890SJoyce.McIntosh@Sun.COM sv->sv_cfg.skc_print_enable = ioc->print_enable;
183812508Samw@Sun.COM sv->sv_cfg.skc_execflags = ioc->exec_flags;
183912508Samw@Sun.COM sv->sv_cfg.skc_version = ioc->version;
18409832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_nbdomain, ioc->nbdomain,
18419832Samw@Sun.COM sizeof (sv->sv_cfg.skc_nbdomain));
18429832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_fqdn, ioc->fqdn,
18439832Samw@Sun.COM sizeof (sv->sv_cfg.skc_fqdn));
18449832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_hostname, ioc->hostname,
18459832Samw@Sun.COM sizeof (sv->sv_cfg.skc_hostname));
18469832Samw@Sun.COM (void) strlcpy(sv->sv_cfg.skc_system_comment, ioc->system_comment,
18479832Samw@Sun.COM sizeof (sv->sv_cfg.skc_system_comment));
18486139Sjb150015 }
18496139Sjb150015
18506139Sjb150015 static int
smb_server_fsop_start(smb_server_t * sv)18516139Sjb150015 smb_server_fsop_start(smb_server_t *sv)
18526139Sjb150015 {
18536139Sjb150015 int error;
18546139Sjb150015
18556139Sjb150015 error = smb_node_root_init(rootdir, sv, &sv->si_root_smb_node);
18566139Sjb150015 if (error != 0)
18576139Sjb150015 sv->si_root_smb_node = NULL;
18586139Sjb150015
18596139Sjb150015 return (error);
18606139Sjb150015 }
18616139Sjb150015
18626139Sjb150015 static void
smb_server_fsop_stop(smb_server_t * sv)18636139Sjb150015 smb_server_fsop_stop(smb_server_t *sv)
18646139Sjb150015 {
18656139Sjb150015 if (sv->si_root_smb_node != NULL) {
18666139Sjb150015 smb_node_release(sv->si_root_smb_node);
18676139Sjb150015 sv->si_root_smb_node = NULL;
18686139Sjb150015 }
18696139Sjb150015 }
187011963SAfshin.Ardakani@Sun.COM
187111963SAfshin.Ardakani@Sun.COM smb_event_t *
smb_event_create(int timeout)187212890SJoyce.McIntosh@Sun.COM smb_event_create(int timeout)
187311963SAfshin.Ardakani@Sun.COM {
187411963SAfshin.Ardakani@Sun.COM smb_server_t *sv;
187511963SAfshin.Ardakani@Sun.COM smb_event_t *event;
187611963SAfshin.Ardakani@Sun.COM
187711963SAfshin.Ardakani@Sun.COM if (smb_server_is_stopping())
187811963SAfshin.Ardakani@Sun.COM return (NULL);
187911963SAfshin.Ardakani@Sun.COM
188011963SAfshin.Ardakani@Sun.COM if (smb_server_lookup(&sv) != 0) {
188111963SAfshin.Ardakani@Sun.COM cmn_err(CE_NOTE, "smb_event_create failed");
188211963SAfshin.Ardakani@Sun.COM return (NULL);
188311963SAfshin.Ardakani@Sun.COM }
188411963SAfshin.Ardakani@Sun.COM
188511963SAfshin.Ardakani@Sun.COM event = kmem_cache_alloc(sv->si_cache_event, KM_SLEEP);
188611963SAfshin.Ardakani@Sun.COM
188711963SAfshin.Ardakani@Sun.COM bzero(event, sizeof (smb_event_t));
188811963SAfshin.Ardakani@Sun.COM mutex_init(&event->se_mutex, NULL, MUTEX_DEFAULT, NULL);
188911963SAfshin.Ardakani@Sun.COM cv_init(&event->se_cv, NULL, CV_DEFAULT, NULL);
189011963SAfshin.Ardakani@Sun.COM event->se_magic = SMB_EVENT_MAGIC;
189111963SAfshin.Ardakani@Sun.COM event->se_txid = smb_event_alloc_txid();
189211963SAfshin.Ardakani@Sun.COM event->se_server = sv;
189312890SJoyce.McIntosh@Sun.COM event->se_timeout = timeout;
189411963SAfshin.Ardakani@Sun.COM
189511963SAfshin.Ardakani@Sun.COM smb_llist_enter(&sv->sv_event_list, RW_WRITER);
189611963SAfshin.Ardakani@Sun.COM smb_llist_insert_tail(&sv->sv_event_list, event);
189711963SAfshin.Ardakani@Sun.COM smb_llist_exit(&sv->sv_event_list);
189811963SAfshin.Ardakani@Sun.COM
189911963SAfshin.Ardakani@Sun.COM smb_server_release(sv);
190011963SAfshin.Ardakani@Sun.COM return (event);
190111963SAfshin.Ardakani@Sun.COM }
190211963SAfshin.Ardakani@Sun.COM
190311963SAfshin.Ardakani@Sun.COM void
smb_event_destroy(smb_event_t * event)190411963SAfshin.Ardakani@Sun.COM smb_event_destroy(smb_event_t *event)
190511963SAfshin.Ardakani@Sun.COM {
190611963SAfshin.Ardakani@Sun.COM smb_server_t *sv;
190711963SAfshin.Ardakani@Sun.COM
190811963SAfshin.Ardakani@Sun.COM if (event == NULL)
190911963SAfshin.Ardakani@Sun.COM return;
191011963SAfshin.Ardakani@Sun.COM
191111963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event);
191211963SAfshin.Ardakani@Sun.COM ASSERT(event->se_waittime == 0);
191311963SAfshin.Ardakani@Sun.COM
191411963SAfshin.Ardakani@Sun.COM if (smb_server_lookup(&sv) != 0)
191511963SAfshin.Ardakani@Sun.COM return;
191611963SAfshin.Ardakani@Sun.COM
191711963SAfshin.Ardakani@Sun.COM smb_llist_enter(&sv->sv_event_list, RW_WRITER);
191811963SAfshin.Ardakani@Sun.COM smb_llist_remove(&sv->sv_event_list, event);
191911963SAfshin.Ardakani@Sun.COM smb_llist_exit(&sv->sv_event_list);
192011963SAfshin.Ardakani@Sun.COM
192111963SAfshin.Ardakani@Sun.COM event->se_magic = (uint32_t)~SMB_EVENT_MAGIC;
192211963SAfshin.Ardakani@Sun.COM cv_destroy(&event->se_cv);
192311963SAfshin.Ardakani@Sun.COM mutex_destroy(&event->se_mutex);
192411963SAfshin.Ardakani@Sun.COM
192511963SAfshin.Ardakani@Sun.COM kmem_cache_free(sv->si_cache_event, event);
192611963SAfshin.Ardakani@Sun.COM smb_server_release(sv);
192711963SAfshin.Ardakani@Sun.COM }
192811963SAfshin.Ardakani@Sun.COM
192911963SAfshin.Ardakani@Sun.COM /*
193011963SAfshin.Ardakani@Sun.COM * Get the txid for the specified event.
193111963SAfshin.Ardakani@Sun.COM */
193211963SAfshin.Ardakani@Sun.COM uint32_t
smb_event_txid(smb_event_t * event)193311963SAfshin.Ardakani@Sun.COM smb_event_txid(smb_event_t *event)
193411963SAfshin.Ardakani@Sun.COM {
193511963SAfshin.Ardakani@Sun.COM if (event != NULL) {
193611963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event);
193711963SAfshin.Ardakani@Sun.COM return (event->se_txid);
193811963SAfshin.Ardakani@Sun.COM }
193911963SAfshin.Ardakani@Sun.COM
194011963SAfshin.Ardakani@Sun.COM cmn_err(CE_NOTE, "smb_event_txid failed");
194111963SAfshin.Ardakani@Sun.COM return ((uint32_t)-1);
194211963SAfshin.Ardakani@Sun.COM }
194311963SAfshin.Ardakani@Sun.COM
194411963SAfshin.Ardakani@Sun.COM /*
194511963SAfshin.Ardakani@Sun.COM * Wait for event notification.
194611963SAfshin.Ardakani@Sun.COM */
194711963SAfshin.Ardakani@Sun.COM int
smb_event_wait(smb_event_t * event)194811963SAfshin.Ardakani@Sun.COM smb_event_wait(smb_event_t *event)
194911963SAfshin.Ardakani@Sun.COM {
195011963SAfshin.Ardakani@Sun.COM int seconds = 1;
195111963SAfshin.Ardakani@Sun.COM int ticks;
195211963SAfshin.Ardakani@Sun.COM
195311963SAfshin.Ardakani@Sun.COM if (event == NULL)
195411963SAfshin.Ardakani@Sun.COM return (EINVAL);
195511963SAfshin.Ardakani@Sun.COM
195611963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event);
195711963SAfshin.Ardakani@Sun.COM
195811963SAfshin.Ardakani@Sun.COM mutex_enter(&event->se_mutex);
195911963SAfshin.Ardakani@Sun.COM event->se_waittime = 1;
196011963SAfshin.Ardakani@Sun.COM event->se_errno = 0;
196111963SAfshin.Ardakani@Sun.COM
196211963SAfshin.Ardakani@Sun.COM while (!(event->se_notified)) {
196312065SKeyur.Desai@Sun.COM if (smb_event_debug && ((event->se_waittime % 30) == 0))
196411963SAfshin.Ardakani@Sun.COM cmn_err(CE_NOTE, "smb_event_wait[%d] (%d sec)",
196511963SAfshin.Ardakani@Sun.COM event->se_txid, event->se_waittime);
196611963SAfshin.Ardakani@Sun.COM
196711963SAfshin.Ardakani@Sun.COM if (event->se_errno != 0)
196811963SAfshin.Ardakani@Sun.COM break;
196911963SAfshin.Ardakani@Sun.COM
197012890SJoyce.McIntosh@Sun.COM if (event->se_waittime > event->se_timeout) {
197111963SAfshin.Ardakani@Sun.COM event->se_errno = ETIME;
197211963SAfshin.Ardakani@Sun.COM break;
197311963SAfshin.Ardakani@Sun.COM }
197411963SAfshin.Ardakani@Sun.COM
197511963SAfshin.Ardakani@Sun.COM ticks = SEC_TO_TICK(seconds);
197611963SAfshin.Ardakani@Sun.COM (void) cv_reltimedwait(&event->se_cv,
197711963SAfshin.Ardakani@Sun.COM &event->se_mutex, (clock_t)ticks, TR_CLOCK_TICK);
197811963SAfshin.Ardakani@Sun.COM ++event->se_waittime;
197911963SAfshin.Ardakani@Sun.COM }
198011963SAfshin.Ardakani@Sun.COM
198111963SAfshin.Ardakani@Sun.COM event->se_waittime = 0;
198211963SAfshin.Ardakani@Sun.COM event->se_notified = B_FALSE;
198311963SAfshin.Ardakani@Sun.COM cv_signal(&event->se_cv);
198411963SAfshin.Ardakani@Sun.COM mutex_exit(&event->se_mutex);
198511963SAfshin.Ardakani@Sun.COM return (event->se_errno);
198611963SAfshin.Ardakani@Sun.COM }
198711963SAfshin.Ardakani@Sun.COM
198811963SAfshin.Ardakani@Sun.COM /*
198911963SAfshin.Ardakani@Sun.COM * If txid is non-zero, cancel the specified event.
199011963SAfshin.Ardakani@Sun.COM * Otherwise, cancel all events.
199111963SAfshin.Ardakani@Sun.COM */
199211963SAfshin.Ardakani@Sun.COM static void
smb_event_cancel(smb_server_t * sv,uint32_t txid)199311963SAfshin.Ardakani@Sun.COM smb_event_cancel(smb_server_t *sv, uint32_t txid)
199411963SAfshin.Ardakani@Sun.COM {
199511963SAfshin.Ardakani@Sun.COM smb_event_t *event;
199611963SAfshin.Ardakani@Sun.COM smb_llist_t *event_list;
199711963SAfshin.Ardakani@Sun.COM
199811963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
199911963SAfshin.Ardakani@Sun.COM
200011963SAfshin.Ardakani@Sun.COM event_list = &sv->sv_event_list;
200111963SAfshin.Ardakani@Sun.COM smb_llist_enter(event_list, RW_WRITER);
200211963SAfshin.Ardakani@Sun.COM
200311963SAfshin.Ardakani@Sun.COM event = smb_llist_head(event_list);
200411963SAfshin.Ardakani@Sun.COM while (event) {
200511963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event);
200611963SAfshin.Ardakani@Sun.COM
200711963SAfshin.Ardakani@Sun.COM if (txid == 0 || event->se_txid == txid) {
200811963SAfshin.Ardakani@Sun.COM mutex_enter(&event->se_mutex);
200911963SAfshin.Ardakani@Sun.COM event->se_errno = ECANCELED;
201011963SAfshin.Ardakani@Sun.COM event->se_notified = B_TRUE;
201111963SAfshin.Ardakani@Sun.COM cv_signal(&event->se_cv);
201211963SAfshin.Ardakani@Sun.COM mutex_exit(&event->se_mutex);
201311963SAfshin.Ardakani@Sun.COM
201411963SAfshin.Ardakani@Sun.COM if (txid != 0)
201511963SAfshin.Ardakani@Sun.COM break;
201611963SAfshin.Ardakani@Sun.COM }
201711963SAfshin.Ardakani@Sun.COM
201811963SAfshin.Ardakani@Sun.COM event = smb_llist_next(event_list, event);
201911963SAfshin.Ardakani@Sun.COM }
202011963SAfshin.Ardakani@Sun.COM
202111963SAfshin.Ardakani@Sun.COM smb_llist_exit(event_list);
202211963SAfshin.Ardakani@Sun.COM }
202311963SAfshin.Ardakani@Sun.COM
202411963SAfshin.Ardakani@Sun.COM /*
202511963SAfshin.Ardakani@Sun.COM * If txid is non-zero, notify the specified event.
202611963SAfshin.Ardakani@Sun.COM * Otherwise, notify all events.
202711963SAfshin.Ardakani@Sun.COM */
202812890SJoyce.McIntosh@Sun.COM void
smb_event_notify(smb_server_t * sv,uint32_t txid)202911963SAfshin.Ardakani@Sun.COM smb_event_notify(smb_server_t *sv, uint32_t txid)
203011963SAfshin.Ardakani@Sun.COM {
203111963SAfshin.Ardakani@Sun.COM smb_event_t *event;
203211963SAfshin.Ardakani@Sun.COM smb_llist_t *event_list;
203311963SAfshin.Ardakani@Sun.COM
203411963SAfshin.Ardakani@Sun.COM SMB_SERVER_VALID(sv);
203511963SAfshin.Ardakani@Sun.COM
203611963SAfshin.Ardakani@Sun.COM event_list = &sv->sv_event_list;
203711963SAfshin.Ardakani@Sun.COM smb_llist_enter(event_list, RW_READER);
203811963SAfshin.Ardakani@Sun.COM
203911963SAfshin.Ardakani@Sun.COM event = smb_llist_head(event_list);
204011963SAfshin.Ardakani@Sun.COM while (event) {
204111963SAfshin.Ardakani@Sun.COM SMB_EVENT_VALID(event);
204211963SAfshin.Ardakani@Sun.COM
204311963SAfshin.Ardakani@Sun.COM if (txid == 0 || event->se_txid == txid) {
204411963SAfshin.Ardakani@Sun.COM mutex_enter(&event->se_mutex);
204511963SAfshin.Ardakani@Sun.COM event->se_notified = B_TRUE;
204611963SAfshin.Ardakani@Sun.COM cv_signal(&event->se_cv);
204711963SAfshin.Ardakani@Sun.COM mutex_exit(&event->se_mutex);
204811963SAfshin.Ardakani@Sun.COM
204911963SAfshin.Ardakani@Sun.COM if (txid != 0)
205011963SAfshin.Ardakani@Sun.COM break;
205111963SAfshin.Ardakani@Sun.COM }
205211963SAfshin.Ardakani@Sun.COM
205311963SAfshin.Ardakani@Sun.COM event = smb_llist_next(event_list, event);
205411963SAfshin.Ardakani@Sun.COM }
205511963SAfshin.Ardakani@Sun.COM
205611963SAfshin.Ardakani@Sun.COM smb_llist_exit(event_list);
205711963SAfshin.Ardakani@Sun.COM }
205811963SAfshin.Ardakani@Sun.COM
205911963SAfshin.Ardakani@Sun.COM /*
206011963SAfshin.Ardakani@Sun.COM * Allocate a new transaction id (txid).
206111963SAfshin.Ardakani@Sun.COM *
206211963SAfshin.Ardakani@Sun.COM * 0 or -1 are not assigned because they are used to detect invalid
206311963SAfshin.Ardakani@Sun.COM * conditions or to indicate all open id's.
206411963SAfshin.Ardakani@Sun.COM */
206511963SAfshin.Ardakani@Sun.COM static uint32_t
smb_event_alloc_txid(void)206611963SAfshin.Ardakani@Sun.COM smb_event_alloc_txid(void)
206711963SAfshin.Ardakani@Sun.COM {
206811963SAfshin.Ardakani@Sun.COM static kmutex_t txmutex;
206911963SAfshin.Ardakani@Sun.COM static uint32_t txid;
207011963SAfshin.Ardakani@Sun.COM uint32_t txid_ret;
207111963SAfshin.Ardakani@Sun.COM
207211963SAfshin.Ardakani@Sun.COM mutex_enter(&txmutex);
207311963SAfshin.Ardakani@Sun.COM
207411963SAfshin.Ardakani@Sun.COM if (txid == 0)
207511963SAfshin.Ardakani@Sun.COM txid = ddi_get_lbolt() << 11;
207611963SAfshin.Ardakani@Sun.COM
207711963SAfshin.Ardakani@Sun.COM do {
207811963SAfshin.Ardakani@Sun.COM ++txid;
207911963SAfshin.Ardakani@Sun.COM } while (txid == 0 || txid == (uint32_t)-1);
208011963SAfshin.Ardakani@Sun.COM
208111963SAfshin.Ardakani@Sun.COM txid_ret = txid;
208211963SAfshin.Ardakani@Sun.COM mutex_exit(&txmutex);
208311963SAfshin.Ardakani@Sun.COM
208411963SAfshin.Ardakani@Sun.COM return (txid_ret);
208511963SAfshin.Ardakani@Sun.COM }
208612890SJoyce.McIntosh@Sun.COM
208712890SJoyce.McIntosh@Sun.COM /*
208812890SJoyce.McIntosh@Sun.COM * Called by the ioctl to find the corresponding
208912890SJoyce.McIntosh@Sun.COM * spooldoc node. removes node on success
209012890SJoyce.McIntosh@Sun.COM *
209112890SJoyce.McIntosh@Sun.COM * Return values
209212890SJoyce.McIntosh@Sun.COM * rc
209312890SJoyce.McIntosh@Sun.COM * B_FALSE - not found
209412890SJoyce.McIntosh@Sun.COM * B_TRUE - found
209512890SJoyce.McIntosh@Sun.COM *
209612890SJoyce.McIntosh@Sun.COM */
209712890SJoyce.McIntosh@Sun.COM
209812890SJoyce.McIntosh@Sun.COM boolean_t
smb_spool_lookup_doc_byfid(uint16_t fid,smb_kspooldoc_t * spdoc)209912890SJoyce.McIntosh@Sun.COM smb_spool_lookup_doc_byfid(uint16_t fid, smb_kspooldoc_t *spdoc)
210012890SJoyce.McIntosh@Sun.COM {
210112890SJoyce.McIntosh@Sun.COM smb_kspooldoc_t *sp;
210212890SJoyce.McIntosh@Sun.COM smb_llist_t *splist;
210312890SJoyce.McIntosh@Sun.COM smb_server_t *sv;
210412890SJoyce.McIntosh@Sun.COM int rc;
210512890SJoyce.McIntosh@Sun.COM
210612890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv);
210712890SJoyce.McIntosh@Sun.COM if (rc)
210812890SJoyce.McIntosh@Sun.COM return (B_FALSE);
210912890SJoyce.McIntosh@Sun.COM
211012890SJoyce.McIntosh@Sun.COM splist = &sv->sp_info.sp_list;
211112890SJoyce.McIntosh@Sun.COM smb_llist_enter(splist, RW_WRITER);
211212890SJoyce.McIntosh@Sun.COM sp = smb_llist_head(splist);
211312890SJoyce.McIntosh@Sun.COM while (sp != NULL) {
211412890SJoyce.McIntosh@Sun.COM /*
211512890SJoyce.McIntosh@Sun.COM * check for a matching fid
211612890SJoyce.McIntosh@Sun.COM */
211712890SJoyce.McIntosh@Sun.COM if (sp->sd_fid == fid) {
211812890SJoyce.McIntosh@Sun.COM *spdoc = *sp;
211912890SJoyce.McIntosh@Sun.COM smb_llist_remove(splist, sp);
212012890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist);
212112890SJoyce.McIntosh@Sun.COM kmem_free(sp, sizeof (smb_kspooldoc_t));
212212890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
212312890SJoyce.McIntosh@Sun.COM return (B_TRUE);
212412890SJoyce.McIntosh@Sun.COM }
212512890SJoyce.McIntosh@Sun.COM sp = smb_llist_next(splist, sp);
212612890SJoyce.McIntosh@Sun.COM }
212712890SJoyce.McIntosh@Sun.COM cmn_err(CE_WARN, "smb_spool_lookup_user_byfid: no fid:%d", fid);
212812890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist);
212912890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
213012890SJoyce.McIntosh@Sun.COM return (B_FALSE);
213112890SJoyce.McIntosh@Sun.COM }
213212890SJoyce.McIntosh@Sun.COM
213312890SJoyce.McIntosh@Sun.COM /*
213412890SJoyce.McIntosh@Sun.COM * Adds the spool fid to a linked list to be used
213512890SJoyce.McIntosh@Sun.COM * as a search key in the spooldoc queue
213612890SJoyce.McIntosh@Sun.COM *
213712890SJoyce.McIntosh@Sun.COM * Return values
213812890SJoyce.McIntosh@Sun.COM * rc non-zero error
213912890SJoyce.McIntosh@Sun.COM * rc zero success
214012890SJoyce.McIntosh@Sun.COM *
214112890SJoyce.McIntosh@Sun.COM */
214212890SJoyce.McIntosh@Sun.COM
214312890SJoyce.McIntosh@Sun.COM int
smb_spool_add_fid(uint16_t fid)214412890SJoyce.McIntosh@Sun.COM smb_spool_add_fid(uint16_t fid)
214512890SJoyce.McIntosh@Sun.COM {
214612890SJoyce.McIntosh@Sun.COM smb_llist_t *fidlist;
214712890SJoyce.McIntosh@Sun.COM smb_server_t *sv;
214812890SJoyce.McIntosh@Sun.COM smb_spoolfid_t *sf;
214912890SJoyce.McIntosh@Sun.COM int rc = 0;
215012890SJoyce.McIntosh@Sun.COM
215112890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv);
215212890SJoyce.McIntosh@Sun.COM if (rc)
215312890SJoyce.McIntosh@Sun.COM return (rc);
215412890SJoyce.McIntosh@Sun.COM
215512890SJoyce.McIntosh@Sun.COM sf = kmem_zalloc(sizeof (smb_spoolfid_t), KM_SLEEP);
215612890SJoyce.McIntosh@Sun.COM fidlist = &sv->sp_info.sp_fidlist;
215712890SJoyce.McIntosh@Sun.COM smb_llist_enter(fidlist, RW_WRITER);
215812890SJoyce.McIntosh@Sun.COM sf->sf_fid = fid;
215912890SJoyce.McIntosh@Sun.COM smb_llist_insert_tail(fidlist, sf);
216012890SJoyce.McIntosh@Sun.COM smb_llist_exit(fidlist);
216112890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
216212890SJoyce.McIntosh@Sun.COM return (rc);
216312890SJoyce.McIntosh@Sun.COM }
216412890SJoyce.McIntosh@Sun.COM
216512890SJoyce.McIntosh@Sun.COM /*
216612890SJoyce.McIntosh@Sun.COM * Called by the ioctl to get and remove the head of the fid list
216712890SJoyce.McIntosh@Sun.COM *
216812890SJoyce.McIntosh@Sun.COM * Return values
216912890SJoyce.McIntosh@Sun.COM * int fd
217012890SJoyce.McIntosh@Sun.COM * greater than 0 success
217112890SJoyce.McIntosh@Sun.COM * 0 - error
217212890SJoyce.McIntosh@Sun.COM *
217312890SJoyce.McIntosh@Sun.COM */
217412890SJoyce.McIntosh@Sun.COM
217512890SJoyce.McIntosh@Sun.COM uint16_t
smb_spool_get_fid()217612890SJoyce.McIntosh@Sun.COM smb_spool_get_fid()
217712890SJoyce.McIntosh@Sun.COM {
217812890SJoyce.McIntosh@Sun.COM smb_spoolfid_t *spfid;
217912890SJoyce.McIntosh@Sun.COM smb_llist_t *splist;
218012890SJoyce.McIntosh@Sun.COM smb_server_t *sv;
218112890SJoyce.McIntosh@Sun.COM int rc = 0;
218212890SJoyce.McIntosh@Sun.COM uint16_t fid;
218312890SJoyce.McIntosh@Sun.COM
218412890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv);
218512890SJoyce.McIntosh@Sun.COM if (rc)
218612890SJoyce.McIntosh@Sun.COM return (0);
218712890SJoyce.McIntosh@Sun.COM
218812890SJoyce.McIntosh@Sun.COM splist = &sv->sp_info.sp_fidlist;
218912890SJoyce.McIntosh@Sun.COM smb_llist_enter(splist, RW_WRITER);
219012890SJoyce.McIntosh@Sun.COM spfid = smb_llist_head(splist);
219112890SJoyce.McIntosh@Sun.COM if (spfid != NULL) {
219212890SJoyce.McIntosh@Sun.COM fid = spfid->sf_fid;
219312890SJoyce.McIntosh@Sun.COM smb_llist_remove(&sv->sp_info.sp_fidlist, spfid);
219412890SJoyce.McIntosh@Sun.COM kmem_free(spfid, sizeof (smb_spoolfid_t));
219512890SJoyce.McIntosh@Sun.COM } else {
219612890SJoyce.McIntosh@Sun.COM fid = 0;
219712890SJoyce.McIntosh@Sun.COM }
219812890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist);
219912890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
220012890SJoyce.McIntosh@Sun.COM return (fid);
220112890SJoyce.McIntosh@Sun.COM }
220212890SJoyce.McIntosh@Sun.COM
220312890SJoyce.McIntosh@Sun.COM /*
220412890SJoyce.McIntosh@Sun.COM * Adds the spooldoc to the tail of the spooldoc list
220512890SJoyce.McIntosh@Sun.COM *
220612890SJoyce.McIntosh@Sun.COM * Return values
220712890SJoyce.McIntosh@Sun.COM * rc non-zero error
220812890SJoyce.McIntosh@Sun.COM * rc zero success
220912890SJoyce.McIntosh@Sun.COM */
221012890SJoyce.McIntosh@Sun.COM int
smb_spool_add_doc(smb_kspooldoc_t * sp)221112890SJoyce.McIntosh@Sun.COM smb_spool_add_doc(smb_kspooldoc_t *sp)
221212890SJoyce.McIntosh@Sun.COM {
221312890SJoyce.McIntosh@Sun.COM smb_llist_t *splist;
221412890SJoyce.McIntosh@Sun.COM smb_server_t *sv;
221512890SJoyce.McIntosh@Sun.COM int rc = 0;
221612890SJoyce.McIntosh@Sun.COM
221712890SJoyce.McIntosh@Sun.COM rc = smb_server_lookup(&sv);
221812890SJoyce.McIntosh@Sun.COM if (rc)
221912890SJoyce.McIntosh@Sun.COM return (rc);
222012890SJoyce.McIntosh@Sun.COM
222112890SJoyce.McIntosh@Sun.COM splist = &sv->sp_info.sp_list;
222212890SJoyce.McIntosh@Sun.COM smb_llist_enter(splist, RW_WRITER);
222312890SJoyce.McIntosh@Sun.COM sp->sd_spool_num = sv->sp_info.sp_cnt;
222412890SJoyce.McIntosh@Sun.COM smb_llist_insert_tail(splist, sp);
222512890SJoyce.McIntosh@Sun.COM smb_llist_exit(splist);
222612890SJoyce.McIntosh@Sun.COM smb_server_release(sv);
222712890SJoyce.McIntosh@Sun.COM return (rc);
222812890SJoyce.McIntosh@Sun.COM }
2229*13138SJose.Borrego@Sun.COM
2230*13138SJose.Borrego@Sun.COM /*
2231*13138SJose.Borrego@Sun.COM * smb_server_create_session
2232*13138SJose.Borrego@Sun.COM */
2233*13138SJose.Borrego@Sun.COM static void
smb_server_create_session(smb_listener_daemon_t * ld,ksocket_t s_so)2234*13138SJose.Borrego@Sun.COM smb_server_create_session(smb_listener_daemon_t *ld, ksocket_t s_so)
2235*13138SJose.Borrego@Sun.COM {
2236*13138SJose.Borrego@Sun.COM smb_session_t *session;
2237*13138SJose.Borrego@Sun.COM smb_receiver_arg_t *rarg;
2238*13138SJose.Borrego@Sun.COM
2239*13138SJose.Borrego@Sun.COM session = smb_session_create(s_so, ld->ld_port, ld->ld_sv,
2240*13138SJose.Borrego@Sun.COM ld->ld_family);
2241*13138SJose.Borrego@Sun.COM
2242*13138SJose.Borrego@Sun.COM if (session != NULL) {
2243*13138SJose.Borrego@Sun.COM smb_llist_enter(&ld->ld_session_list, RW_WRITER);
2244*13138SJose.Borrego@Sun.COM smb_llist_insert_tail(&ld->ld_session_list, session);
2245*13138SJose.Borrego@Sun.COM smb_llist_exit(&ld->ld_session_list);
2246*13138SJose.Borrego@Sun.COM
2247*13138SJose.Borrego@Sun.COM rarg = (smb_receiver_arg_t *)smb_mem_alloc(
2248*13138SJose.Borrego@Sun.COM sizeof (smb_receiver_arg_t));
2249*13138SJose.Borrego@Sun.COM rarg->ra_listener = ld;
2250*13138SJose.Borrego@Sun.COM rarg->ra_session = session;
2251*13138SJose.Borrego@Sun.COM
2252*13138SJose.Borrego@Sun.COM if (taskq_dispatch(ld->ld_sv->sv_receiver_pool,
2253*13138SJose.Borrego@Sun.COM smb_server_receiver, rarg, TQ_NOQUEUE) != 0)
2254*13138SJose.Borrego@Sun.COM return;
2255*13138SJose.Borrego@Sun.COM
2256*13138SJose.Borrego@Sun.COM smb_mem_free(rarg);
2257*13138SJose.Borrego@Sun.COM smb_session_disconnect(session);
2258*13138SJose.Borrego@Sun.COM smb_server_destroy_session(ld, session);
2259*13138SJose.Borrego@Sun.COM } else {
2260*13138SJose.Borrego@Sun.COM smb_soshutdown(s_so);
2261*13138SJose.Borrego@Sun.COM smb_sodestroy(s_so);
2262*13138SJose.Borrego@Sun.COM }
2263*13138SJose.Borrego@Sun.COM cmn_err(CE_WARN, "SMB Session: creation failed");
2264*13138SJose.Borrego@Sun.COM }
2265*13138SJose.Borrego@Sun.COM
2266*13138SJose.Borrego@Sun.COM static void
smb_server_destroy_session(smb_listener_daemon_t * ld,smb_session_t * session)2267*13138SJose.Borrego@Sun.COM smb_server_destroy_session(smb_listener_daemon_t *ld, smb_session_t *session)
2268*13138SJose.Borrego@Sun.COM {
2269*13138SJose.Borrego@Sun.COM smb_llist_enter(&ld->ld_session_list, RW_WRITER);
2270*13138SJose.Borrego@Sun.COM smb_llist_remove(&ld->ld_session_list, session);
2271*13138SJose.Borrego@Sun.COM smb_llist_exit(&ld->ld_session_list);
2272*13138SJose.Borrego@Sun.COM smb_session_delete(session);
2273*13138SJose.Borrego@Sun.COM }
2274