fix to util_sock.c
okuyamak at dd.iij4u.or.jp
okuyamak at dd.iij4u.or.jp
Sun Nov 12 12:56:57 GMT 2000
Dear all,
I don't think I can keep my promise (^^;). I found something
interesting in different part, which is easier to fix.
I've made fix against HEAD branch of ./source/lib/util_sock.c.
# Since this file is not being changed since 2.0.7, this also works
# for 2.0.7 or 2.2 as well.
Here's what I did.
1) Created new global function socket_read().
Since SSL_read() and read() calling stuff is spread all over,
I decided to make this into single function.
2) Instead of calling read() even for usual cases, I changed
it to use recv().
3) socket_read() have 'flags' option, which is passed to recv().
Also, when this function is called from read_socket_data()
and read_data(), option MSG_WAITALL is passed.
If your system supports MSG_WAITALL, recv() will not return
until required length of data is recieved entirely ( and if
you look at read_data() and read_socket_data(), you'll see
that's what you really requested for ).
If MSG_WAITALL is not being supported, configure will set
MSG_WAITALL to 0, so this will not take effect, and will work
exactly like original code ( except for recv() being called
instead of read() ).
This patch will not make samba FAST(*), but this will make samba
slightly LIGHER, for change made by 3 will prevent context switch
between user(smbd) and kernel mode.
When I counted system call using same netbench, original called
read() against socket over 500ktimes, but this code only calls
recv() 370ktimes now. CPU power being reduced, will be passed to
kernel, and make kernel to work more better ( stable usually ).
*) The reason why this will not make samba fast, is because
this routine will NOT speed up receiving. We can only receive
packet at speed of media. So if SMBrequest was 5000bytes,
This usually requiers 4 IP packets on ethernet. This is usually
somewhat around 48000bits which takes 480usec on 100Mbps ethernet
with FULL RATE, so no matter how fast CPU may be, we can't go
forward until we recieve all data.
We have no way to speed up the receiving, so, what we can do
against recieve phase is
i ) let's do whatever we can using information given from
first packet. This means, don't recieve entire packet at first
phase. But this requires large change.
ii) let's leave all the receiving to kernel by passing
MSG_WAITALL flag, whenever we can.
If you found that your server became faster with this patch,
it means your server is overloaded. You need more faster
CPU for server.
Testing this function is very easy. If you can't communicate between
client using this patch, then something is wrong ( but I'm writing
this mail on Windows machine, and made following patch against
source code on Linux machine using samba I patched. So, I don't
think there's any big problem. If problem occured... I think that's
because somebody is calling this socket_read() against non-socket
file descriptor, which we shouldn't ).
best regards,
----
Kenichi Okuyama at Tokyo Research Lab, IBM-Japan, Co.
and here comes the patch:
--- samba-2.2.orig/source/lib/util_sock.c Sat Oct 7 06:12:25 2000
+++ samba-2.2/source/lib/util_sock.c Sun Nov 12 20:40:53 2000
@@ -222,15 +222,7 @@
if (mincnt == 0) mincnt = maxcnt;
while (nread < mincnt) {
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf + nread, maxcnt - nread);
-#endif /* WITH_SSL */
+ readret = socket_read( fd, buf + nread, maxcnt - nread, 0 );
if (readret == 0) {
DEBUG(5,("read_socket_with_timeout: blocking read. EOF from client.\n"));
@@ -279,15 +271,7 @@
return -1;
}
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf+nread, maxcnt-nread);
-#endif /* WITH_SSL */
+ readret = socket_read( fd, buf + nread, maxcnt - nread, 0 );
if (readret == 0) {
/* we got EOF on the file descriptor */
@@ -334,15 +318,7 @@
if (mincnt == 0) mincnt = maxcnt;
while (nread < mincnt) {
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf + nread, maxcnt - nread);
-#endif /* WITH_SSL */
+ readret = socket_read( fd, buf + nread, maxcnt - nread, 0 );
if (readret <= 0)
return readret;
@@ -371,15 +347,7 @@
if(selrtn <= 0)
return selrtn;
-#ifdef WITH_SSL
- if(fd == sslFd){
- readret = SSL_read(ssl, buf + nread, maxcnt - nread);
- }else{
- readret = read(fd, buf + nread, maxcnt - nread);
- }
-#else /* WITH_SSL */
- readret = read(fd, buf+nread, maxcnt-nread);
-#endif /* WITH_SSL */
+ readret = socket_read( fd, buf + nread, maxcnt - nread, 0 );
if (readret <= 0)
return readret;
@@ -418,15 +386,7 @@
while (total < N)
{
-#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_read(ssl, buffer + total, N - total);
- }else{
- ret = read(fd,buffer + total,N - total);
- }
-#else /* WITH_SSL */
- ret = read(fd,buffer + total,N - total);
-#endif /* WITH_SSL */
+ ret = socket_read( fd, buffer + total, N - total, MSG_WAITALL );
if (ret == 0)
{
@@ -458,15 +418,7 @@
while (total < N)
{
-#ifdef WITH_SSL
- if(fd == sslFd){
- ret = SSL_read(ssl, buffer + total, N - total);
- }else{
- ret = read(fd,buffer + total,N - total);
- }
-#else /* WITH_SSL */
- ret = read(fd,buffer + total,N - total);
-#endif /* WITH_SSL */
+ ret = socket_read( fd, buffer + total, N - total, MSG_WAITALL );
if (ret == 0)
{
@@ -1188,4 +1140,18 @@
DEBUG(5,("unix socket opened: %s\n", path));
return s;
+}
+
+
+ssize_t socket_read( int fd, void *buf, size_t len, int flags )
+{
+#ifdef WITH_SSL
+ if(fd == sslFd){
+ return SSL_read(ssl, buf, len );
+ }else{
+ return recv( fd, buf, len, flags );
+ }
+#else /* WITH_SSL */
+ return recv( fd, buf, len, flags );
+#endif /* WITH_SSL */
}
More information about the samba-technical
mailing list