smb_server.c revision a90cf9f29973990687fa61de9f1f6ea22e924e40
2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. 2N/A * Copyright 2015 Nexenta Systems, Inc. All rights reserved. 2N/A * General Structures Layout 2N/A * ------------------------- 2N/A * This is a simplified diagram showing the relationship between most of the 2N/A * +-------------------+ 2N/A * +-------------------+ 2N/A * +-------------------+ +-------------------+ +-------------------+ 2N/A * | SESSION |<----->| SESSION |......| SESSION | 2N/A * +-------------------+ +-------------------+ +-------------------+ 2N/A * +-------------------+ +-------------------+ +-------------------+ 2N/A * | USER |<----->| USER |......| USER | * +-------------------+ +-------------------+ +-------------------+ * +-------------------+ +-------------------+ +-------------------+ * | TREE |<----->| TREE |......| TREE | * +-------------------+ +-------------------+ +-------------------+ * | +-------+ +-------+ +-------+ * | | OFILE |<----->| OFILE |......| OFILE | * | +-------+ +-------+ +-------+ * +-------+ +------+ +------+ * | ODIR |<----->| ODIR |......| ODIR | * +-------+ +------+ +------+ * Module Interface Overview * ------------------------- * +===================================+ * +===================================+ * -----------|--------------|----------------|-------------------------------- * +=========|==============|================|=================+ * | +-----------+ +--------------------+ +------------------+ | * | | IO | | Kernel Door Server | | User Door Servers| | * | | Interface | | Interface | | Interface | | * | +-----------+ +--------------------+ +------------------+ | * | v v | | | +=========+ * | +-----------------------------------+ | | | | * | + SMB Server Management (this file) |<------------------| ZFS | * | +-----------------------------------+ | | | | * | +-----------------------------------+ | | | | * | + SMB Server Internal Layers |------+ | +=========+ * | +-----------------------------------+ | * +===========================================================+ * +-----------------------------+ * | SMB_SERVER_STATE_CREATED | * +-----------------------------+ * +-----------------------------+ * | SMB_SERVER_STATE_CONFIGURED | * +-----------------------------+ * +-----------------------------+ * | SMB_SERVER_STATE_RUNNING / | * | SMB_SERVER_STATE_STOPPING | * +-----------------------------+ * +-----------------------------+ * | SMB_SERVER_STATE_DELETING | * +-----------------------------+ * SMB_SERVER_STATE_CREATED * This is the state of the server just after creation. * SMB_SERVER_STATE_CONFIGURED * The server has been configured. * SMB_SERVER_STATE_RUNNING * The server has been started. While in this state the threads listening on * the sockets are started. * When a client establishes a connection the thread listening dispatches * a task with the new session as an argument. If the dispatch fails the new * session context is destroyed. * SMB_SERVER_STATE_STOPPING * The threads listening on the NBT and TCP sockets are being terminated. * The daemon smbd triggers its creation by opening the smbsrv device. If * the zone where the daemon lives doesn't have an smb server yet it is * smb_drv_open() --> smb_server_create() * This transition occurs in smb_server_configure(). It is triggered by the * daemon through an Ioctl. * smb_drv_ioctl(SMB_IOC_CONFIG) --> smb_server_configure() * This transition occurs in smb_server_start(). It is triggered by the * daemon through an Ioctl. * smb_drv_ioctl(SMB_IOC_START) --> smb_server_start() * This transition occurs in smb_server_delete(). It is triggered by the * daemon when closing the smbsrv device * smb_drv_close() --> smb_server_delete() * This files assumes that there will one SMB server per zone. For now the * smb server works only in global zone. There's nothing in this file preventing * an smb server from being created in a non global zone. That limitation is * enforced in user space. * ***************************************************************************** * **************** Functions called from the device interface ***************** * ***************************************************************************** * These functions typically have to determine the relevant smb server * to which the call applies. * How many zones have an SMB server active? * This function must be called from smb_drv_attach(). * This function must called from smb_drv_detach(). It will fail if servers * This function will fail if there's already a server associated with the * This function will delete the server passed in. It will make sure that all * activity associated that server has ceased before destroying it. * NB: the proc passed here has to be a "system" one. * Normally that's p0, or the NGZ eqivalent. /* Fake kernel does not use the kshare_door */ * An smbd is shutting down. * Waits for print file close broadcast. * Gets the head of the fid list, * then searches the spooldoc list and returns * this info via the ioctl to user land. /* Did not find that print job. */ * Enumerate objects within the server. The svcenum provides the * enumeration context, i.e. what the caller want to get back. * Look for sessions to disconnect by client and user name. * Close a file by uniqid. * These functions determine the relevant smb server to which the call apply. * Gets the vnode of the specified share path. * A hold on the returned vnode pointer is taken so the caller * This is a special interface that will be utilized by ZFS to cause a share to * arg is either a lmshare_info_t or share_name from userspace. * It will need to be copied into the kernel. It is lmshare_info_t * for add operations and share_name for delete operations. * Disconnect the specified share. * Typically called when a share has been removed. * ***************************************************************************** * **************** Functions called from the internal layers ****************** * ***************************************************************************** * These functions are provided the relevant smb server by the caller. * ***************************************************************************** * *************************** Static Functions ******************************** * ***************************************************************************** * This just kills old inactive sessions. No urgency. * The session code expects one call per minute. * smb_server_kstat_update * Latency & Throughput of the requests * Stop the listeners first, so we don't get any more * new work while we're trying to shut down. * Wake up any threads we might have blocked. * Must precede kdoor_close etc. because those will * wait for such threads to get out. * smb_kshare_export may have a request on here. * Normal sessions do this in smb_session_cancel() * but this is a "fake" session used only for the * requests used by the kshare thread(s). * smb_server_listener_init * Initializes listener contexts. * smb_server_listener_destroy * Destroyes listener contexts. * Note that if startup fails early, we can legitimately * get here with an all-zeros object. * smb_server_listener_start * Starts the listener associated with the context passed in. * smb_server_listener_stop * Stops the listener associated with the context passed in. * Entry point of the listeners. * Create a session for this connection. /* Disconnect all the sessions this listener created. */ * Entry point of the receiver threads. * This function finds the server associated with the zone of the * caller. Note: requires a fix in the dynamic taskq code: * 1501 taskq_create_proc ... TQ_DYNAMIC puts tasks in p0 * This function decrements the reference count of the server and signals its * condition variable if the state of the server is SMB_SERVER_STATE_DELETING. * Enumerate the users associated with a session list. * Enumerate the trees/files associated with a session list. * Disconnect sessions associated with the specified client and username. * Empty strings are treated as wildcards. * Close a file by its unique id. /* See also: libsmb smb_kmod_setcfg */ * Get the txid for the specified event. * Wait for event notification. * If txid is non-zero, cancel the specified event. * Otherwise, cancel all events. * If txid is non-zero, notify the specified event. * Otherwise, notify all events. * Allocate a new transaction id (txid). * 0 or -1 are not assigned because they are used to detect invalid * conditions or to indicate all open id's. * Called by the ioctl to find the corresponding * spooldoc node. removes node on success * check for a matching fid * Adds the spool fid to a linked list to be used * as a search key in the spooldoc queue * Called by the ioctl to get and remove the head of the fid list * Adds the spooldoc to the tail of the spooldoc list * smb_server_create_session * These taskq entries must run independently of one another, * so TQ_NOQUEUE. TQ_SLEEP (==0) just for clarity. /* handy for debugging */