Poor performance, samba bug, DOS client

Frank Giessler giessler at biomag.uni-jena.de
Thu Aug 9 09:25:12 GMT 2001


Hi all,

This was a long way for me but I will tell it in detail so others might benefit. I have very
little experience in C-programming and the internals of Solaris. Maybe someone with more
experience can check my reasoning and my patch.

I had set up a samba server (2.0.4) on a SUN running Solaris 2.6. It used to be running
great with just one client (DOS PC running MS-DOS client 3.0).

After we had some problems with the SUN's HD I changed it and upgraded to Solaris 8 and
Samba 2.2.1a. After some some time I noticed that the writing speed from the client to the
server had gone down to a crawl while reading seemed to be quite normal. I did some
searching and tried several suggestions from others with similar problems (such as 'write
raw', 'read raw', 'socket options', etc.). Nothing helped. I got so frustrated that I
plugged the old HD back in and checked again. Wonderful performance! I upgraded to 2.2.1a on
the old HD to see if the Solaris version matters. Obviously, it did. Performance was still
high.

I put the new HD in and used tcpdump to check what was going on. Although I have no
experience with such dumps I compared two with good and bad connection, respectively. They
didn't look much different. In fact, it seemed that the number of packets were the same, but
on Solaris 8 they came with a very slow speed.

Then I tried to connect the PC client to some other servers. WinNT 4.0 gave good
performance, but Win2k was as slow as Samba. I checked at support.microsoft.com and got the
following:

http://support.microsoft.com/support/kb/articles/Q244/8/26.ASP

I checked the receive window size (netstat |grep .139) under Solaris 2.6 and 8, and indeed
SUN changed it from about 8k to about 24k. Setting 

'socket options = SO_RCVBUF=8192' 

in smb.conf didn't change anything, whereas 

'ndd -set /dev/tcp tcp_recv_hiwat 8192' 

worked!

The man page of setsockopt() on Solaris 8 finally revealed that the function chould be
called before any listen() or connect() call. After applying the following patch everything
worked fine:

diff -wc smbd/server.c smbd/server.c.new                                         ***
smbd/server.c       Fri Jul  6 04:02:03 2001                                          ---
smbd/server.c.new   Thu Aug  9 11:06:12 2001                                         
***************                                                                          
*** 159,164 ****                                                                         
--- 159,166 ----                                                                         
                        if(s == -1)                                                      
                                return False;                                            
                                /* ready to listen */                                     +                      
set_socket_options(s,"SO_KEEPALIVE");                            
+                       set_socket_options(s,user_socket_options);                       
                        if (listen(s, 5) == -1) {                                        
                                DEBUG(0,("listen: %s\n",strerror(errno)));               
                                close(s);                                                
***************                                                                          
*** 178,183 ****                                                                         
--- 180,187 ----                                                                         
                        return(False);                                                   
                                                                                         
                /* ready to listen */                                                     +              
set_socket_options(s,"SO_KEEPALIVE");                                    
+               set_socket_options(s,user_socket_options);                               
                if (listen(s, 5) == -1) {                                                
                        DEBUG(0,("open_sockets: listen: %s\n",                           
                                 strerror(errno)));                                      
***************                                                                          
*** 264,272 ****                                                                         
                                close_low_fds();                                         
                                am_parent = 0;                                           
                                                                                          -                              
set_socket_options(smbd_server_fd(),"SO_KEEPALIVE");     
-                               set_socket_options(smbd_server_fd(),user_socket_options); -                                                                                       

                                /* Reset global variables in util.c so                   
                                   that client substitutions will be                     
                                   done correctly in the process.  */                    
--- 268,273 ----                                                                         

The problems I see are:

1) I don't know what happens when smbd is called from inetd.
2) I don't know in what sequence setsockopt() and listen() should be called in OSs other
than Solaris 8.

So,  please, can someone have a look at it?

Thanks  

    Frank.
__
 Frank Giessler
 Klinikum der Universitaet Jena               Tel.: +49-3641-9 35259
 Biomagnetisches Zentrum                      Fax : +49-3641-9 35355





More information about the samba-technical mailing list