[jcifs] threaded network crawler code examples (transport problem)

Dan Dumont ddumont at us.ibm.com
Tue Jul 29 03:46:09 EST 2003


>So my question is:  what is actually happening within jCIFS?  Is jCIFS 
>setting the global MaxMpxCount to the minimum it sees?  How does 
>MaxMpxCount interact with a "deficient" server?


This is what would happen when i was at  school:


I ran Overseer with about 80 threads using the unmodified transport.  It 
would launch all 80 threads, and after a while, it would start executing 
them in a linear fashion.  SO, I debugged the code and found that after 
the threads lined up, when you went and looked at the transport, 
maxmpxcount was set to 1.      only 1 thread was allowed to talk at a 
time, all the rest were blocking.


/me = confused

 




"Christopher R. Hertel" <crh at ubiqx.mn.org>
Sent by: jcifs-bounces+ddumont=us.ibm.com at lists.samba.org
07/28/2003 01:35 PM
 
        To:     Dan Dumont <Dan at canofsleep.com>
        cc:     jcifs at samba.org
        Subject:        Re: [jcifs] threaded network crawler code examples 
(transport problem)


I've let Dan's message through the e'mail filter (which considered it 
oversized).

On Mon, Jul 28, 2003 at 12:17:51AM -0400, Dan Dumont wrote:
:
> Now, this is a description of the problem with the jcifs package
> (unmodified)
> 
> The maxmpxcount variable gets decremented when it meets a deficient 
server.
> However, this adversely affects the performance (actually that running) 
of
> any other thread that wants to use the transport. 
> 
> Mike has told me that you don't want to have a transport for each 
thread,
> but that is the only solution that will make this code work correctly. I
> modified the transport to never decrement maxmpxcount and while may get 
a
> lot of transports, you get the performance you expect from multiple 
threads
> running independently.

Okay, let me approach this from a theory perspective (my strength).

Maxmpxcount stands for "Maximum Multiplex Count" and it refers
specifically to the number of separate client SMB requests that may be
outstanding with a given server at a given time.  The client should have a 

default maxmpxcount, and the server will also present a maxmpxcount.  The 
session between the client and server should use the minimum of those 
two.

Separately, Windows systems assume (generally) that a client will open 
only *one* transport session with the server.  That assumption is easily 
broken, however, and Windows systems do not seem to mind as long as the VC 

(Virtual Circuit) number is set to something other than zero.  There is a 
discussion of VC's (and MaxMpxCount) here:

  http://ubiqx.org/cifs/SMB.html#SMB.7

Anyway, as far as I can tell the maxmpxcount is valid on a per
transport-layer session basis.  That is, each NBT or TCP transport session
opened between the client and the server may have maxmpxcount requests
outstanding.

Sidebar:
  On a Windows system, all of the SMB traffic is handled by the kernel,
  which means that the Windows kernel can make sure that there is only one
  transport session per client/server pair.  It can also keep track of VCs
  (if they are implemented) if it wants to open multiple transport 
  sessions.

  This cannot be done if the SMB client implementation is not somehow
  centralized (in kernel, or via an SMB client daemon, or somesuch).  So
  for Samba client code (smbfs, cifsvfs, smbclient) and jCIFS there is no
  way to keep track of VCs or to ensure that the maxmpxcount is global
  across all running clients on the system.

  That being the case, it is a good thing that the maxmpxcount is 
  negotiated on a per-transport-level-session basis.  Otherwise, 
  non-Windows clients would either have to be redesigned or would 
  constantly be breaking the MPX limit.

  Note that Microsoft ran into trouble with this design a while back when
  they found that Windows clients behind a NAT device appeared as if they
  were all one client trying to open multiple sessions with the (remote)
  server.  When a client opened a session it would send a VC number of
  zero, which would cause W2K to disconnect any other session from the
  NAT, with the result that only one client at a time could connect and 
  the newest client would disconnect the previous.

Anyway, read on...

> The multithreaded example that Mike has provided works great with the
> unmodified transport because it only deals with one host.  Whereas this 
> code comes into contact with a wide variety of hosts.

So, this confuses me. 

Speaking once again from the theory perspective, the MaxMpxCount
negotiated between the client and the server should be:

  MaxMpxCount = min( Client.MaxMpxCount, Server.MaxMpxCount )

and that should apply on a per-transport basis.  The maximum number of
threads active on that given transport should be limited to MaxMpxCount,
but if the thread pool is larger then those additional threads could be 
made available to operate on separate sessions with different servers.

In theory, you could also open up multiple sessions with a given server,
but that might be a bad idea, since it requests more resources from the
server.  If you are filling the MaxMpxCount limit with that server, then 
the server is obviously already performing too slowly and additional 
sessions won't speed things up much.  If you're not hitting the 
MaxMpxCount limit then the server is fast enough to handle as much as you 
can through at it anyway, and you don't really need any more threads since 

you can't keep the ones you've got busy anyway.

> To see the problem in its entirety, you may need a large network.  (it's
> been a while since ive tested using the original package, and I forget 
if it
> needed actual hosts that time out, or if it will err the same way with 
non
> existent hosts. I believe the latter to be the case)

So my question is:  what is actually happening within jCIFS?  Is jCIFS 
setting the global MaxMpxCount to the minimum it sees?  How does 
MaxMpxCount interact with a "deficient" server?

> But in any case, try the current version of jcifs and let my code fly on 
a
> file filled with 10.0.*.* or something along that size.   Set the thread
> count around 80.
> 
> I have included a sample ip text file, and again, the source is in the 
jar
> along with the modified jcifs that I am using.

Still trying to wrap my brain around this one...

Chris -)-----

-- 
"Implementing CIFS - the Common Internet FileSystem" ISBN: 013047116X
Samba Team -- http://www.samba.org/     -)-----   Christopher R. Hertel
jCIFS Team -- http://jcifs.samba.org/   -)-----   ubiqx development, 
uninq.
ubiqx Team -- http://www.ubiqx.org/     -)-----   crh at ubiqx.mn.org
OnLineBook -- http://ubiqx.org/cifs/    -)-----   crh at ubiqx.org





More information about the jcifs mailing list