1<html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>Chapter�3.�Samba Architecture</title><link rel="stylesheet" href="samba.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.71.0"><link rel="start" href="index.html" title="SAMBA Developers Guide"><link rel="up" href="pt02.html" title="Part�II.�Samba Basics"><link rel="prev" href="pt02.html" title="Part�II.�Samba Basics"><link rel="next" href="debug.html" title="Chapter�4.�The samba DEBUG system"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">Chapter�3.�Samba Architecture</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="pt02.html">Prev</a>�</td><th width="60%" align="center">Part�II.�Samba Basics</th><td width="20%" align="right">�<a accesskey="n" href="debug.html">Next</a></td></tr></table><hr></div><div class="chapter" lang="en"><div class="titlepage"><div><div><h2 class="title"><a name="architecture"></a>Chapter�3.�Samba Architecture</h2></div><div><div class="author"><h3 class="author"><span class="firstname">Dan</span> <span class="surname">Shearer</span></h3></div></div><div><p class="pubdate"> November 1997</p></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="sect1"><a href="architecture.html#id322541">Introduction</a></span></dt><dt><span class="sect1"><a href="architecture.html#id322580">Multithreading and Samba</a></span></dt><dt><span class="sect1"><a href="architecture.html#id322605">Threading smbd</a></span></dt><dt><span class="sect1"><a href="architecture.html#id322658">Threading nmbd</a></span></dt><dt><span class="sect1"><a href="architecture.html#id322690">nbmd Design</a></span></dt></dl></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322541"></a>Introduction</h2></div></div></div><p> 2This document gives a general overview of how Samba works 3internally. The Samba Team has tried to come up with a model which is 4the best possible compromise between elegance, portability, security 5and the constraints imposed by the very messy SMB and CIFS 6protocol. 7</p><p> 8It also tries to answer some of the frequently asked questions such as: 9</p><div class="orderedlist"><ol type="1"><li><p> 10 Is Samba secure when running on Unix? The xyz platform? 11 What about the root priveliges issue? 12</p></li><li><p>Pros and cons of multithreading in various parts of Samba</p></li><li><p>Why not have a separate process for name resolution, WINS, and browsing?</p></li></ol></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322580"></a>Multithreading and Samba</h2></div></div></div><p> 13People sometimes tout threads as a uniformly good thing. They are very 14nice in their place but are quite inappropriate for smbd. nmbd is 15another matter, and multi-threading it would be very nice. 16</p><p> 17The short version is that smbd is not multithreaded, and alternative 18servers that take this approach under Unix (such as Syntax, at the 19time of writing) suffer tremendous performance penalties and are less 20robust. nmbd is not threaded either, but this is because it is not 21possible to do it while keeping code consistent and portable across 35 22or more platforms. (This drawback also applies to threading smbd.) 23</p><p> 24The longer versions is that there are very good reasons for not making 25smbd multi-threaded. Multi-threading would actually make Samba much 26slower, less scalable, less portable and much less robust. The fact 27that we use a separate process for each connection is one of Samba's 28biggest advantages. 29</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322605"></a>Threading smbd</h2></div></div></div><p> 30A few problems that would arise from a threaded smbd are: 31</p><div class="orderedlist"><ol type="1"><li><p> 32 It's not only to create threads instead of processes, but you 33 must care about all variables if they have to be thread specific 34 (currently they would be global). 35</p></li><li><p> 36 if one thread dies (eg. a seg fault) then all threads die. We can 37 immediately throw robustness out the window. 38</p></li><li><p> 39 many of the system calls we make are blocking. Non-blocking 40 equivalents of many calls are either not available or are awkward (and 41 slow) to use. So while we block in one thread all clients are 42 waiting. Imagine if one share is a slow NFS filesystem and the others 43 are fast, we will end up slowing all clients to the speed of NFS. 44</p></li><li><p> 45 you can't run as a different uid in different threads. This means 46 we would have to switch uid/gid on _every_ SMB packet. It would be 47 horrendously slow. 48</p></li><li><p> 49 the per process file descriptor limit would mean that we could only 50 support a limited number of clients. 51</p></li><li><p> 52 we couldn't use the system locking calls as the locking context of 53 fcntl() is a process, not a thread. 54</p></li></ol></div></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322658"></a>Threading nmbd</h2></div></div></div><p> 55This would be ideal, but gets sunk by portability requirements. 56</p><p> 57Andrew tried to write a test threads library for nmbd that used only 58ansi-C constructs (using setjmp and longjmp). Unfortunately some OSes 59defeat this by restricting longjmp to calling addresses that are 60shallower than the current address on the stack (apparently AIX does 61this). This makes a truly portable threads library impossible. So to 62support all our current platforms we would have to code nmbd both with 63and without threads, and as the real aim of threads is to make the 64code clearer we would not have gained anything. (it is a myth that 65threads make things faster. threading is like recursion, it can make 66things clear but the same thing can always be done faster by some 67other method) 68</p><p> 69Chris tried to spec out a general design that would abstract threading 70vs separate processes (vs other methods?) and make them accessible 71through some general API. This doesn't work because of the data 72sharing requirements of the protocol (packets in the future depending 73on packets now, etc.) At least, the code would work but would be very 74clumsy, and besides the fork() type model would never work on Unix. (Is there an OS that it would work on, for nmbd?) 75</p><p> 76A fork() is cheap, but not nearly cheap enough to do on every UDP 77packet that arrives. Having a pool of processes is possible but is 78nasty to program cleanly due to the enormous amount of shared data (in 79complex structures) between the processes. We can't rely on each 80platform having a shared memory system. 81</p></div><div class="sect1" lang="en"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="id322690"></a>nbmd Design</h2></div></div></div><p> 82Originally Andrew used recursion to simulate a multi-threaded 83environment, which use the stack enormously and made for really 84confusing debugging sessions. Luke Leighton rewrote it to use a 85queuing system that keeps state information on each packet. The 86first version used a single structure which was used by all the 87pending states. As the initialisation of this structure was 88done by adding arguments, as the functionality developed, it got 89pretty messy. So, it was replaced with a higher-order function 90and a pointer to a user-defined memory block. This suddenly 91made things much simpler: large numbers of functions could be 92made static, and modularised. This is the same principle as used 93in NT's kernel, and achieves the same effect as threads, but in 94a single process. 95</p><p> 96Then Jeremy rewrote nmbd. The packet data in nmbd isn't what's on the 97wire. It's a nice format that is very amenable to processing but still 98keeps the idea of a distinct packet. See "struct packet_struct" in 99nameserv.h. It has all the detail but none of the on-the-wire 100mess. This makes it ideal for using in disk or memory-based databases 101for browsing and WINS support. 102</p></div></div><div class="navfooter"><hr><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="pt02.html">Prev</a>�</td><td width="20%" align="center"><a accesskey="u" href="pt02.html">Up</a></td><td width="40%" align="right">�<a accesskey="n" href="debug.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">Part�II.�Samba Basics�</td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top">�Chapter�4.�The samba DEBUG system</td></tr></table></div></body></html> 103