Bug 2655 - "Resource temporary unavailable" message on stdout when listing directories
Summary: "Resource temporary unavailable" message on stdout when listing directories
Status: CLOSED FIXED
Alias: None
Product: Samba 3.0
Classification: Unclassified
Component: libsmbclient (show other bugs)
Version: 3.0.14a
Hardware: x86 FreeBSD
: P3 normal
Target Milestone: none
Assignee: Samba Bugzilla Account
QA Contact: Samba QA Contact
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-04-26 18:26 UTC by sergei
Modified: 2005-08-24 10:24 UTC (History)
0 users

See Also:


Attachments
patch to fix this problem (1.45 KB, patch)
2005-04-26 18:30 UTC, sergei
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description sergei 2005-04-26 18:26:20 UTC
OS: FreeBSD 5.2.1
Software: libsmbclient 3.0.14a
Situation: sometimes program with this library says to stdout:
"read_socket_data: recv failure for 1032. Error = Resource temporarily 
unavailable" (digits may vary).

Source code (fragments):

void auth_fn (const char *server, const char *share, char *_workgroup, int 
wgmaxlen, char *_username
, int unmaxlen, char *_password, int pwmaxlen)
{
        strncpy(_workgroup, workgroup.c_str(), wgmaxlen-1);
        strncpy(_username ,  username.c_str(), unmaxlen-1);
        strncpy(_password ,  password.c_str(), pwmaxlen-1);
}
...............
ctx = smbc_new_context();
if (!ctx)
{throw e_samba("Can not allocate context for smbclient.");}
ctx->debug = 10;
ctx->timeout = timeout;
ctx->netbios_name = strdup(selfname.c_str());
ctx->workgroup = strdup(workgroup.c_str());
ctx->callbacks.auth_fn = auth_fn;
if (!smbc_init_context(ctx))
{
smbc_free_context(ctx, false); ctx = NULL;
throw e_samba("Can not initialize smbclient.", strerror(errno));
}
ctx->timeout = timeout;
...................
SMBCFILE * dir = ctx->opendir(ctx, openpathstr.c_str());
if (!dir)
{
   cerr << "    " << "Could not open [" << openpathstr << "] (" << setw(0) << 
dec << errno << "):" << strerror(errno) << endl;
} else {
.................




It said on stdout (debug level 10):

Connecting to 10.10.1.148 at port 139
socket option SO_KEEPALIVE = 0
socket option SO_REUSEADDR = 0
socket option SO_BROADCAST = 0
socket option TCP_NODELAY = 4
socket option IPTOS_LOWDELAY = 0
socket option IPTOS_THROUGHPUT = 0
socket option SO_REUSEPORT = 0
socket option SO_SNDBUF = 33120
socket option SO_RCVBUF = 66240
socket option SO_SNDLOWAT = 2048
socket option SO_RCVLOWAT = 1
socket option SO_SNDTIMEO = 0
socket option SO_RCVTIMEO = 0
..................................................
 session setup ok
...............................................
[000] 00 44 20 16 00 00 02 06  00 04 01 00 00 00 00 5C  .D ..... .......\
[010] 2A 00                                             *.
write_socket(6,87)
write_socket(6,87) wrote 87
got smb length of 2468
read_socket_data: recv failure for 1032. Error = Resource temporarily 
unavailable
client_receive_smb failed
size=2468
smb_com=0x32
smb_rcls=0
smb_reh=0
smb_err=0
smb_flg=136
smb_flg2=65
smb_tid=1
smb_pid=22833
smb_uid=0
smb_mid=5
smt_wct=10
smb_vwv[ 0]=   10 (0xA)
smb_vwv[ 1]= 2400 (0x960)
smb_vwv[ 2]=    0 (0x0)
smb_vwv[ 3]=   10 (0xA)
smb_vwv[ 4]=   56 (0x38)
smb_vwv[ 5]=    0 (0x0)
smb_vwv[ 6]= 2400 (0x960)
smb_vwv[ 7]=   68 (0x44)
smb_vwv[ 8]=    0 (0x0)
smb_vwv[ 9]=    0 (0x0)
smb_bcc=2413








Seems that libsmbclient want to receive 2468 bytes, but got only some number
of bytes and there were 1032 bytes it didn't get for some reason. And because of
"Resource temporarily unavailable" is a message for EAGAIN error code, I think 
that in some while() cycles when read()'ing or sys_read()'ing (source/lib/
util_sock.c) from fd when error checking (in read_data(), read_socket_data(), 
and in read_socket_with_timeout()) is made by "if (ret == -1)" it should 
actually be made by "if (ret == -1 && errno != EAGAIN)". Because EAGAIN is not 
really an error, but some condition, when program should retry to do what it 
want to do. And later when buffer pointer increases it shoudl check if returned 
value (number of bytes read) was not -1.
Comment 1 sergei 2005-04-26 18:30:11 UTC
Created attachment 1177 [details]
patch to fix this problem

This patch solves the problem with "Resource temporary unavailable" message
described above.

But it is not as good as it have to be. First, it will rotate in infinite
while() trying to read data from socket, and make processor work hardly. Really
there should be select(2) call before read()'ing from socket - this is work for
samba developers.

Second, I know it have fixed my current problem with EAGAIN error, but I dont
know if it makes new problem to libsmbclient or other samba components. This
should be tested carefully before releasing patched version.

Patch is alose available at
http://numeri.net/storage/smbclient-socketsread.patch for downloading if you
need it :)
Comment 2 Derrell Lipman 2005-05-10 14:25:14 UTC
djl implementation concept:

1. check to see if libsmbclient is entering non-blocking mode (and not exiting
it) for some reason

2. if that's not it, then check for EAGAIN in receive_smb_raw() and if so, then
read remainder of packet with read_socket_with_timeout().
Comment 3 Derrell Lipman 2005-05-27 14:23:00 UTC
Fixed by checkin r7039
Comment 4 Gerald (Jerry) Carter (dead mail address) 2005-08-24 10:24:32 UTC
sorry for the same, cleaning up the database to prevent unecessary reopens of bugs.