Samba4 libsmb* design draft
tridge at samba.org
tridge at samba.org
Wed Nov 26 21:59:57 GMT 2003
> I've been browsing through the samba4 libcli/* code the last few days
> and I must say that I'm impressed by it's cleanness.
> First, a random question:
> Why is sock->port = 445 in cli_sock_init() while we could be more
> failsafe by using sock->port = 0 because cli_sock_connect tries 445 and
> 139 (in that order) when port==0 ?
yes, well spotted! Fixed.
> Draft design for libsmb*:
> - libsmbcli:
> The lower level API. Uses the lowest level cli_raw* functions to talk to
> SMB servers. The API should be completely async. This is quite a large
> job but adding asyncness will be very usefull.
I'm not sure I understand. The cli_raw*() API is already async for
nearly every call, so I'm not really clear on what the difference
would be between libsmbcli and the existing libcli/raw/ APIs. There
are a couple of calls in libcli/raw/ that don't offer an async
varient, and certainly those should be fixed, but that shouldn't be a
Of course, right now the low-level read/write ops on the socket are
still done sync, but that isn't an API issue. The APIs above have been
designed to cope with an async io layer, and it shouldn't be more than
a day or twos work to enhance the cli_socket layer to add an io buffer
and async io calls.
> If everything is async, the need for reentrant code at this level
> is low, locking can be done on large structures (for example
> cli_state structures) because we will not be waiting for IO
> operations to complete.
One thing I'm trying to do is phase out cli_state. You may have
noticed it has shrunk a lot in Samba4 (it now just has 5 elements) and
if ideally I think it should disappear completely at some stage.
The reason for this is that the basic idea behind cli_state is flawed
as its design just doesn't match the protocol. In SMB you can have
multiple trees on a session, multiple sessions on a tree, multiple
files on a tree etc so it makes no sense to have a single structure
that contains "the session" and "the tree". This just leads to
horrible code where programmers play games like saving away bits of
the cli_state structure, performing an operation on a different tree
then restoring the elements.
Instead, I'd like to see the primary APIs reflect the protocols
capabilities. That's why Jim and I put in separate cli_tree,
cli_session etc structures, all reference counted. I think it would be
unfortunate to lose this capability.
> This will be a minor performance impact, but it greatly simplifies
> locking and thus reduces the probability of deadlock-bugs and its
> friends. As I already mentioned, everything that does IO should be
> async. It should be useable by client apps like smbclient so bugs
> have to be fixed at one single point.
I'd like to see smbclient recoded to not use cli_state, and instead
use cli_tree, cli_session etc. In fact, smbclient is probably the main
reason for keeping cli_state at the moment, just because I haven't had
time to recode it yet (any volunteers?). Once we fix that we should be
able to remove cli_state.
> - libsmbclient_async
> This lib will have a posix-like API that can use the power of asyncness.
> It will not be reentrant because that's not necessary. You can call it
> posix with callback if you like.
Ok, what if we had a libcli/posix/ library, that called the sync
versions of the libcli/raw/ calls and did an approximate mapping to
I think it is reasonable to assume that if an application wants the
simplicity of an approximate "POSIX on SMB" interface, then the
application probably wants sync calls. If you look at libcli/raw/ then
you will notice that Jim and I have implemented both sync and async
versions of all the calls (well, nearly all the calls), so this
libcli/posix/ library could just use the sync varients. That would
mean that libcli/posix/ would have a very simple structure and could
concentrate on getting the POSIX semantics right without worrying
More information about the samba-technical