Use entities and add overview of directories
[kai/samba.git] / docs / docbook / devdoc / architecture.sgml
1 <chapter id="architecture">
2 <chapterinfo>
3         <author>
4                 <firstname>Dan</firstname><surname>Shearer</surname>
5         </author>
6         <pubdate> November 1997</pubdate>
7         &author.jelmer;
8 </chapterinfo>
9
10 <title>Samba Architecture</title>
11
12 <sect1>
13 <title>Introduction</title>
14
15 <para>
16 This document gives a general overview of how Samba works
17 internally. The Samba Team has tried to come up with a model which is
18 the best possible compromise between elegance, portability, security
19 and the constraints imposed by the very messy SMB and CIFS
20 protocol. 
21 </para>
22
23 <para>
24 It also tries to answer some of the frequently asked questions such as:
25 </para>
26
27 <orderedlist>
28 <listitem><para>
29         Is Samba secure when running on Unix? The xyz platform?
30         What about the root priveliges issue?
31 </para></listitem>
32
33 <listitem><para>Pros and cons of multithreading in various parts of Samba</para></listitem>
34
35 <listitem><para>Why not have a separate process for name resolution, WINS, and browsing?</para></listitem>
36
37 </orderedlist>
38
39 </sect1>
40
41 <sect1>
42 <title>Multithreading and Samba</title>
43
44 <para>
45 People sometimes tout threads as a uniformly good thing. They are very
46 nice in their place but are quite inappropriate for smbd. nmbd is
47 another matter, and multi-threading it would be very nice. 
48 </para>
49
50 <para>
51 The short version is that smbd is not multithreaded, and alternative
52 servers that take this approach under Unix (such as Syntax, at the
53 time of writing) suffer tremendous performance penalties and are less
54 robust. nmbd is not threaded either, but this is because it is not
55 possible to do it while keeping code consistent and portable across 35
56 or more platforms. (This drawback also applies to threading smbd.)
57 </para>
58
59 <para>
60 The longer versions is that there are very good reasons for not making
61 smbd multi-threaded.  Multi-threading would actually make Samba much
62 slower, less scalable, less portable and much less robust. The fact
63 that we use a separate process for each connection is one of Samba's
64 biggest advantages.
65 </para>
66
67 </sect1>
68
69 <sect1>
70 <title>Threading smbd</title>
71
72 <para>
73 A few problems that would arise from a threaded smbd are:
74 </para>
75
76 <orderedlist>
77 <listitem><para>
78         It's not only to create threads instead of processes, but you
79         must care about all variables if they have to be thread specific
80         (currently they would be global).
81 </para></listitem>
82
83 <listitem><para>
84         if one thread dies (eg. a seg fault) then all threads die. We can
85         immediately throw robustness out the window.
86 </para></listitem>
87
88 <listitem><para>
89         many of the system calls we make are blocking. Non-blocking
90         equivalents of many calls are either not available or are awkward (and
91         slow) to use. So while we block in one thread all clients are
92         waiting. Imagine if one share is a slow NFS filesystem and the others 
93         are fast, we will end up slowing all clients to the speed of NFS.
94 </para></listitem>
95
96 <listitem><para>
97         you can't run as a different uid in different threads. This means
98         we would have to switch uid/gid on _every_ SMB packet. It would be
99         horrendously slow.
100 </para></listitem>
101
102 <listitem><para>
103         the per process file descriptor limit would mean that we could only
104         support a limited number of clients.
105 </para></listitem>
106
107 <listitem><para>
108         we couldn't use the system locking calls as the locking context of
109         fcntl() is a process, not a thread.
110 </para></listitem>
111
112 </orderedlist>
113
114 </sect1>
115
116 <sect1>
117 <title>Threading nmbd</title>
118
119 <para>
120 This would be ideal, but gets sunk by portability requirements.
121 </para>
122
123 <para>
124 Andrew tried to write a test threads library for nmbd that used only
125 ansi-C constructs (using setjmp and longjmp). Unfortunately some OSes
126 defeat this by restricting longjmp to calling addresses that are
127 shallower than the current address on the stack (apparently AIX does
128 this). This makes a truly portable threads library impossible. So to
129 support all our current platforms we would have to code nmbd both with
130 and without threads, and as the real aim of threads is to make the
131 code clearer we would not have gained anything. (it is a myth that
132 threads make things faster. threading is like recursion, it can make
133 things clear but the same thing can always be done faster by some
134 other method)
135 </para>
136
137 <para>
138 Chris tried to spec out a general design that would abstract threading
139 vs separate processes (vs other methods?) and make them accessible
140 through some general API. This doesn't work because of the data
141 sharing requirements of the protocol (packets in the future depending
142 on packets now, etc.) At least, the code would work but would be very
143 clumsy, and besides the fork() type model would never work on Unix. (Is there an OS that it would work on, for nmbd?)
144 </para>
145
146 <para>
147 A fork() is cheap, but not nearly cheap enough to do on every UDP
148 packet that arrives. Having a pool of processes is possible but is
149 nasty to program cleanly due to the enormous amount of shared data (in
150 complex structures) between the processes. We can't rely on each
151 platform having a shared memory system.
152 </para>
153
154 </sect1>
155
156 <sect1>
157 <title>nbmd Design</title>
158
159 <para>
160 Originally Andrew used recursion to simulate a multi-threaded
161 environment, which use the stack enormously and made for really
162 confusing debugging sessions. Luke Leighton rewrote it to use a
163 queuing system that keeps state information on each packet.  The
164 first version used a single structure which was used by all the
165 pending states.  As the initialisation of this structure was
166 done by adding arguments, as the functionality developed, it got
167 pretty messy.  So, it was replaced with a higher-order function
168 and a pointer to a user-defined memory block.  This suddenly
169 made things much simpler: large numbers of functions could be
170 made static, and modularised.  This is the same principle as used
171 in NT's kernel, and achieves the same effect as threads, but in
172 a single process.
173 </para>
174
175 <para>
176 Then Jeremy rewrote nmbd. The packet data in nmbd isn't what's on the
177 wire. It's a nice format that is very amenable to processing but still
178 keeps the idea of a distinct packet. See "struct packet_struct" in
179 nameserv.h.  It has all the detail but none of the on-the-wire
180 mess. This makes it ideal for using in disk or memory-based databases
181 for browsing and WINS support. 
182 </para>
183
184 </sect1>
185
186 <sect1>
187 <title>Samba's subsystems</title>
188
189 <para>Samba's <filename>source/</filename> directory contains quite some directories. Here's a small explanation of what each of them contains.</para>
190
191 <simplelist>
192 <member>aparser - Obsolete</member>
193 <member>auth - The authentication subsystem, maintained by Andrew Bartlett</member>
194 <member>bin - Output directory for all the binary files</member>
195 <member>client - Contains 'plain' SMB client sources: smbclient and 
196 some mount help utilities</member>
197 <member>groupdb - Group database and mapping code</member>
198 <member>include - All of samba's include files</member>
199 <member>intl - Internationalization files. Not used at the moment.</member>
200 <member>lib - General C helper functions. Not SMB-specific.</member>
201 <member>libads - Library with ActiveDirectory related functions.</member>
202 <member>libsmb - Library with SMB specific functions.</member>
203 <member>locking - Locking functions!</member>
204 <member>modules - Source files for various modules (VFS and charset).</member>
205 <member>msdfs - DCE-DFS code</member>
206 <member>nmbd - Code for the nmbd daemon</member>
207 <member>nsswitch - Winbind source code</member>
208 <member>pam_smbpass - Source code for pam module for authenticating against samba's passdb</member>
209 <member>param - smb.conf parsing code</member>
210 <member>passdb - User database(SAM) code with the various backends</member>
211 <member>po - Internationalisation code - not used atm</member>
212 <member>popt - Samba's internal copy of the popt library</member>
213 <member>printing - Printing stuff</member>
214 <member>profile - Profiling support</member>
215 <member>python - Python bindings for various libsmb functions</member>
216 <member>registry - Registry backend</member>
217 <member>rpc_client - RPC Client library for making remote procedure calls</member>
218 <member>rpc_parse - Functions for parsing RPC structures (???)</member>
219 <member>rpc_server - Functions for being an RPC server</member>
220 <member>rpcclient - Command-line client that is a basically a front-end to rpc_client/</member>
221 <member>sam - Code for the new (but unused) SAM</member>
222 <member>script - Various scripts</member>
223 <member>smbd - Source code for the smbd daemon</member>
224 <member>smbwrapper - Source code for library that overloads VFS function calls, for usage with LD_PRELOAD=...</member>
225 <member>stf - Testsuite system?</member>
226 <member>tdb - Source code of samba's Trivial Database (much like gdbm)</member>
227 <member>tests - Source code for the larger tests used by configure</member>
228 <member>torture - 'Torture' utilities, used for testing samba and other cifs servers</member>
229 <member>ubiqx - The ubiqx library from Chris Hertel</member>
230 <member>utils - Various small utilities(pdbedit, net, etc)</member>
231 <member>web - SWAT sourcecode</member>
232 <member>wrepld - Sourcecode of the WINS replication daemon</member>
233 </simplelist>
234
235 </sect1>
236
237 </chapter>