| 1 | <?xml version="1.0" encoding="iso-8859-1"?> | 
|---|
| 2 | <!DOCTYPE chapter PUBLIC "-//Samba-Team//DTD DocBook V4.2-Based Variant V1.0//EN" "http://www.samba.org/samba/DTD/samba-doc"> | 
|---|
| 3 | <chapter id="tracing"> | 
|---|
| 4 | <chapterinfo> | 
|---|
| 5 | <author> | 
|---|
| 6 | <firstname>Andrew</firstname><surname>Tridgell</surname> | 
|---|
| 7 | <affiliation> | 
|---|
| 8 | <orgname>Samba Team</orgname> | 
|---|
| 9 | </affiliation> | 
|---|
| 10 | </author> | 
|---|
| 11 | </chapterinfo> | 
|---|
| 12 |  | 
|---|
| 13 | <title>Tracing samba system calls</title> | 
|---|
| 14 |  | 
|---|
| 15 | <para> | 
|---|
| 16 | This file describes how to do a system call trace on Samba to work out | 
|---|
| 17 | what its doing wrong. This is not for the faint of heart, but if you | 
|---|
| 18 | are reading this then you are probably desperate. | 
|---|
| 19 | </para> | 
|---|
| 20 |  | 
|---|
| 21 | <para> | 
|---|
| 22 | Actually its not as bad as the the above makes it sound, just don't | 
|---|
| 23 | expect the output to be very pretty :-) | 
|---|
| 24 | </para> | 
|---|
| 25 |  | 
|---|
| 26 | <para> | 
|---|
| 27 | Ok, down to business. One of the big advantages of unix systems is | 
|---|
| 28 | that they nearly all come with a system trace utility that allows you | 
|---|
| 29 | to monitor all system calls that a program is making. This is | 
|---|
| 30 | extremely using for debugging and also helps when trying to work out | 
|---|
| 31 | why something is slower than you expect. You can use system tracing | 
|---|
| 32 | without any special compilation options. | 
|---|
| 33 | </para> | 
|---|
| 34 |  | 
|---|
| 35 | <para> | 
|---|
| 36 | The system trace utility is called different things on different | 
|---|
| 37 | systems. On Linux systems its called strace. Under SunOS 4 its called | 
|---|
| 38 | trace. Under SVR4 style systems (including solaris) its called | 
|---|
| 39 | truss. Under many BSD systems its called ktrace. | 
|---|
| 40 | </para> | 
|---|
| 41 |  | 
|---|
| 42 | <para> | 
|---|
| 43 | The first thing you should do is read the man page for your native | 
|---|
| 44 | system call tracer. In the discussion below I'll assume its called | 
|---|
| 45 | strace as strace is the only portable system tracer (its available for | 
|---|
| 46 | free for many unix types) and its also got some of the nicest | 
|---|
| 47 | features. | 
|---|
| 48 | </para> | 
|---|
| 49 |  | 
|---|
| 50 | <para> | 
|---|
| 51 | Next, try using strace on some simple commands. For example, <command>strace | 
|---|
| 52 | ls</command> or <command>strace echo hello</command>. | 
|---|
| 53 | </para> | 
|---|
| 54 |  | 
|---|
| 55 | <para> | 
|---|
| 56 | You'll notice that it produces a LOT of output. It is showing you the | 
|---|
| 57 | arguments to every system call that the program makes and the | 
|---|
| 58 | result. Very little happens in a program without a system call so you | 
|---|
| 59 | get lots of output. You'll also find that it produces a lot of | 
|---|
| 60 | "preamble" stuff showing the loading of shared libraries etc. Ignore | 
|---|
| 61 | this (unless its going wrong!) | 
|---|
| 62 | </para> | 
|---|
| 63 |  | 
|---|
| 64 | <para> | 
|---|
| 65 | For example, the only line that really matters in the <command>strace echo | 
|---|
| 66 | hello</command> output is: | 
|---|
| 67 | </para> | 
|---|
| 68 |  | 
|---|
| 69 | <para><programlisting> | 
|---|
| 70 | write(1, "hello\n", 6)                  = 6 | 
|---|
| 71 | </programlisting></para> | 
|---|
| 72 |  | 
|---|
| 73 | <para>all the rest is just setting up to run the program.</para> | 
|---|
| 74 |  | 
|---|
| 75 | <para> | 
|---|
| 76 | Ok, now you're familiar with strace. To use it on Samba you need to | 
|---|
| 77 | strace the running smbd daemon. The way I tend ot use it is to first | 
|---|
| 78 | login from my Windows PC to the Samba server, then use smbstatus to | 
|---|
| 79 | find which process ID that client is attached to, then as root I do | 
|---|
| 80 | <command>strace -p PID</command> to attach to that process. I normally redirect the | 
|---|
| 81 | stderr output from this command to a file for later perusal. For | 
|---|
| 82 | example, if I'm using a csh style shell: | 
|---|
| 83 | </para> | 
|---|
| 84 |  | 
|---|
| 85 | <para><command>strace -f -p 3872 >& strace.out</command></para> | 
|---|
| 86 |  | 
|---|
| 87 | <para>or with a sh style shell:</para> | 
|---|
| 88 |  | 
|---|
| 89 | <para><command>strace -f -p 3872 > strace.out 2>&1</command></para> | 
|---|
| 90 |  | 
|---|
| 91 | <para> | 
|---|
| 92 | Note the "-f" option. This is only available on some systems, and | 
|---|
| 93 | allows you to trace not just the current process, but any children it | 
|---|
| 94 | forks. This is great for finding printing problems caused by the | 
|---|
| 95 | "print command" being wrong. | 
|---|
| 96 | </para> | 
|---|
| 97 |  | 
|---|
| 98 | <para> | 
|---|
| 99 | Once you are attached you then can do whatever it is on the client | 
|---|
| 100 | that is causing problems and you will capture all the system calls | 
|---|
| 101 | that smbd makes. | 
|---|
| 102 | </para> | 
|---|
| 103 |  | 
|---|
| 104 | <para> | 
|---|
| 105 | So how do you interpret the results? Generally I search through the | 
|---|
| 106 | output for strings that I know will appear when the problem | 
|---|
| 107 | happens. For example, if I am having touble with permissions on a file | 
|---|
| 108 | I would search for that files name in the strace output and look at | 
|---|
| 109 | the surrounding lines. Another trick is to match up file descriptor | 
|---|
| 110 | numbers and "follow" what happens to an open file until it is closed. | 
|---|
| 111 | </para> | 
|---|
| 112 |  | 
|---|
| 113 | <para> | 
|---|
| 114 | Beyond this you will have to use your initiative. To give you an idea | 
|---|
| 115 | of what you are looking for here is a piece of strace output that | 
|---|
| 116 | shows that <filename>/dev/null</filename> is not world writeable, which | 
|---|
| 117 | causes printing to fail with Samba: | 
|---|
| 118 | </para> | 
|---|
| 119 |  | 
|---|
| 120 | <para><programlisting> | 
|---|
| 121 | [pid 28268] open("/dev/null", O_RDWR)   = -1 EACCES (Permission denied) | 
|---|
| 122 | [pid 28268] open("/dev/null", O_WRONLY) = -1 EACCES (Permission denied) | 
|---|
| 123 | </programlisting></para> | 
|---|
| 124 |  | 
|---|
| 125 | <para> | 
|---|
| 126 | The process is trying to first open <filename>/dev/null</filename> read-write | 
|---|
| 127 | then read-only. Both fail. This means <filename>/dev/null</filename> has | 
|---|
| 128 | incorrect permissions. | 
|---|
| 129 | </para> | 
|---|
| 130 |  | 
|---|
| 131 | </chapter> | 
|---|