No timeout for nss_ldap?

View: New views
12 Messages — Rating Filter:   Alert me  

No timeout for nss_ldap?

by tkircht :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

My problem is that, when using libnss_ldap (Debian 4.0/OpenLDAP 2.3.30)
every failure in the network link results in blocking all machines.
My setup looks like this:

-------
/etc/libnss_ldap.conf
URI ldaps://ldap.ipodion.at:636
base dc=int,dc=ipodion,dc=at
bind_timelimit 5
-------

bind_timelimit didn't show any effect, probably due to the ldap client
libs..

-------
/etc/nsswitch.conf
passwd:         compat ldap
group:          compat ldap
shadow:         compat ldap
[...]
-------

I tried both files and compat but without seeing any difference

nscd ist off on both client and server machine.

Using this setup everything seems to work perfectly. Simulating  a
network failure by changing URI ldaps://ldap.ipodion.at:636 to URI
ldaps://xxxldap.ipodion.at:636 results in "getent passwd" displaying the
local users and then hanging for a long time (I never waited long
enought but at least 20 minutes).
Any login attempts to that machine fail as well... i.e. hang
indefinitely....

I cannot believe that I can't find a solution to this probably simple
but serious problem.

--
=========================================================
iPodion GmbH
Rotensterngasse 20/3
A-1020 Wien, Austria
Mobil: +43-660-216 32 98
Tel.:+43-1-216 32 98-0      mailto:office@...
Fax: +43-1-216 32 98-28     http://www.iPodion.at
=========================================================
Achtung: Bitte beachten Sie meine neue
         Telefonnummer: 0660/2163298



smime.p7s (4K) Download Attachment

Re: No timeout for nss_ldap?

by Jamin W. Collins :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Kirchtag wrote:
> My problem is that, when using libnss_ldap (Debian 4.0/OpenLDAP 2.3.30)
> every failure in the network link results in blocking all machines.
...

> Using this setup everything seems to work perfectly. Simulating  a
> network failure by changing URI ldaps://ldap.ipodion.at:636 to URI
> ldaps://xxxldap.ipodion.at:636 results in "getent passwd" displaying the
> local users and then hanging for a long time (I never waited long
> enought but at least 20 minutes).
> Any login attempts to that machine fail as well... i.e. hang
> indefinitely....
>
> I cannot believe that I can't find a solution to this probably simple
> but serious problem.

Try changing your bind_policy, the defaults results in this never ending
attempt to connect.

# Reconnect policy:
#  hard_open: reconnect to DSA with exponential backoff if
#             opening connection failed
#  hard_init: reconnect to DSA with exponential backoff if
#             initializing connection failed
#  hard:      alias for hard_open
#  soft:      return immediately on server failure
bind_policy soft

--
Jamin W. Collins

Re: No timeout for nss_ldap?

by Tony Earnshaw-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Jamin W. Collins skrev, on 02-01-2008 12:20:

[...]

> bind_policy soft

Which, unless he alters other things, like nss_initgroups_ignoreusers
will most probably bring him to a never-ending hang on his next reboot.

Been there, seen it, done it (on production machines: The clientèle is
*not* particularly forgiving until one's sassed it out).

--Tonni

--
Tony Earnshaw
Email: tonni at hetnet dot nl

Re: No timeout for nss_ldap?

by Tony Earnshaw-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Tony Earnshaw skrev, on 02-01-2008 18:14:

>> bind_policy soft
>
> Which, unless he alters other things, like nss_initgroups_ignoreusers
> will most probably bring him to a never-ending hang on his next reboot.
>
> Been there, seen it, done it (on production machines: The clientèle is
> *not* particularly forgiving until one's sassed it out).

I take this back, this is rubbish, written by me; Jamin W. Collins was
right.

However, the point is, that there are certain nss_ldap services that
need bind_policy hard/hard_open to work properly. Moving these to
"bind_policy soft" will effectively disenable them. So after a reboot
their config has to be changed back again to bind_policy hard/hard_open.
Granted that's crap, but it has to be done for those services, *unless*
one can isolate them and change services' startup order.

--Tonni

--
Tony Earnshaw
Email: tonni at hetnet dot nl

Re: No timeout for nss_ldap?

by tkircht :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Just so I know what awaits me - could you give me examples of which
services will break if I set bind_policy to soft?

Thanks

Thomas

Tony Earnshaw wrote:

> Tony Earnshaw skrev, on 02-01-2008 18:14:
>
>>> bind_policy soft
>>
>> Which, unless he alters other things, like nss_initgroups_ignoreusers
>> will most probably bring him to a never-ending hang on his next reboot.
>>
>> Been there, seen it, done it (on production machines: The clientèle is
>> *not* particularly forgiving until one's sassed it out).
>
> I take this back, this is rubbish, written by me; Jamin W. Collins was
> right.
>
> However, the point is, that there are certain nss_ldap services that
> need bind_policy hard/hard_open to work properly. Moving these to
> "bind_policy soft" will effectively disenable them. So after a reboot
> their config has to be changed back again to bind_policy hard/hard_open.
> Granted that's crap, but it has to be done for those services, *unless*
> one can isolate them and change services' startup order.
>
> --Tonni
>


--
=========================================================
iPodion GmbH
Rotensterngasse 20/3
A-1020 Wien, Austria
Mobil: +43-660-216 32 98
Tel.:+43-1-216 32 98-0      mailto:office@...
Fax: +43-1-216 32 98-28     http://www.iPodion.at
=========================================================
Achtung: Bitte beachten Sie meine neue
                Telefonnummer: 0660/2163298



Re: No timeout for nss_ldap?

by Jamin W. Collins :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Kirchtag wrote:
> Just so I know what awaits me - could you give me examples of which
> services will break if I set bind_policy to soft?

Using Debian stable, I haven't found any.  I have my bind_policy set to
soft on all systems and nscd installed.  The system spews a few lines on
start about not being able to bind to the ldap server and moves on
immediately.  After boot everything just works.

--
Jamin W. Collins

Re: No timeout for nss_ldap?

by Tony Earnshaw-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Kirchtag skrev, on 02-01-2008 20:05:

> Just so I know what awaits me - could you give me examples of which
> services will break if I set bind_policy to soft?

Actually, it's setting it to hard which breaks things. That's what I was
trying to repair in the content of my first mispost.

So why should it be set to hard anyway? When soft works for reboots?
Because soft never makes nss_ldap retries on a bind failure. Say that
you have a primary and a failover URI in ldap.conf, as we have on our 2
k12ltsp (Linux Terminal Server Project) servers:

uri ldap://192.168.1.25/ ldap://192.168.0.253/

For some reason 192.168.1.25 can't be contacted, nss_ldap should
failover to 192.168.0.253. But it won't with bind_policy soft. And all
sorts of desktop services make use of nss -> nssldap lookups the whole
time; the whole thing comes to a grinding halt (tail -f
/var/log/messages" on a RHEL5 server).

So one comments out "bind_policy soft" in ldap.conf and gets the default
hard_init and everything works again - BUT there's a new kernel update
and the machine has to be rebooted (this concerns multiple RHEL5
servers) and one forgets the bind_policy line in ldap.conf and the
machines never come up again. So the sysadmin has to go into the server
room, gain console access for each of multiple servers, enter run level
1 and fix and reboot. Then afterward change back /etc/ldap.conf to
"#bind_policy soft". He is not a happy bunny.

One can put most of them into ldap.conf as exceptions:

nss_initgroups_ignoreusers root,ldap,named,tonni

Only dbus can't be put in as an exception, since it "invents" a new,
unique UID for itself on each reboot. So the machine will hang on dbus.

A workaround is to make sure that LDAP is started at run level 1 as one
of the first services. dbus, by default, is started in run level 3 as
S22. This is easy to do on Red Hat-derived systems, I wouldn't know
where to start with, for example, Debian.

--Tonni

--
Tony Earnshaw
Email: tonni at hetnet dot nl

Re: No timeout for nss_ldap?

by tkircht :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

What I don't understand is wha bind_timeout is ignored the way it
appears... wouldn't it be preferable to have libnss_ldap retry for a
couple of seconds, fall back to secondary and ternary servers and than
act as if the policy were set to soft? I don't have a secondary yet
(having some problems with replicating userPassword attributes there)
but I do intend to setup redundancy and would like a simple, "automatic"
failover?
Does this work as intended or is this an open issue with libnss_ldap?

Thomas


Tony Earnshaw schrieb:

> Thomas Kirchtag skrev, on 02-01-2008 20:05:
>
>> Just so I know what awaits me - could you give me examples of which
>> services will break if I set bind_policy to soft?
>
> Actually, it's setting it to hard which breaks things. That's what I
> was trying to repair in the content of my first mispost.
>
> So why should it be set to hard anyway? When soft works for reboots?
> Because soft never makes nss_ldap retries on a bind failure. Say that
> you have a primary and a failover URI in ldap.conf, as we have on our
> 2 k12ltsp (Linux Terminal Server Project) servers:
>
> uri ldap://192.168.1.25/ ldap://192.168.0.253/
>
> For some reason 192.168.1.25 can't be contacted, nss_ldap should
> failover to 192.168.0.253. But it won't with bind_policy soft. And all
> sorts of desktop services make use of nss -> nssldap lookups the whole
> time; the whole thing comes to a grinding halt (tail -f
> /var/log/messages" on a RHEL5 server).
>
> So one comments out "bind_policy soft" in ldap.conf and gets the
> default hard_init and everything works again - BUT there's a new
> kernel update and the machine has to be rebooted (this concerns
> multiple RHEL5 servers) and one forgets the bind_policy line in
> ldap.conf and the machines never come up again. So the sysadmin has to
> go into the server room, gain console access for each of multiple
> servers, enter run level 1 and fix and reboot. Then afterward change
> back /etc/ldap.conf to "#bind_policy soft". He is not a happy bunny.
>
> One can put most of them into ldap.conf as exceptions:
>
> nss_initgroups_ignoreusers root,ldap,named,tonni
>
> Only dbus can't be put in as an exception, since it "invents" a new,
> unique UID for itself on each reboot. So the machine will hang on dbus.
>
> A workaround is to make sure that LDAP is started at run level 1 as
> one of the first services. dbus, by default, is started in run level 3
> as S22. This is easy to do on Red Hat-derived systems, I wouldn't know
> where to start with, for example, Debian.
>
> --Tonni
>

--
=========================================================
iPodion GmbH
Rotensterngasse 20/3
A-1020 Wien, Austria
Mobil: +43-660-216 32 98
Tel.:+43-1-216 32 98-0      mailto:office@...
Fax: +43-1-216 32 98-28     http://www.iPodion.at
=========================================================
Achtung: Bitte beachten Sie meine neue
         Telefonnummer: 0660/2163298



smime.p7s (4K) Download Attachment

Re: No timeout for nss_ldap?

by Tony Earnshaw-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Thomas Kirchtag skrev, on 03-01-2008 09:02:

> What I don't understand is wha bind_timeout is ignored the way it
> appears... wouldn't it be preferable to have libnss_ldap retry for a
> couple of seconds, fall back to secondary and ternary servers and than
> act as if the policy were set to soft? I don't have a secondary yet
> (having some problems with replicating userPassword attributes there)
> but I do intend to setup redundancy and would like a simple, "automatic"
> failover?
> Does this work as intended or is this an open issue with libnss_ldap?

You might like to look at Arthur de Jong's nss-ldap:
http://ch.tudelft.nl/~arthur/nss-ldapd/

Read especially the design doc.

--Tonni

--
Tony Earnshaw
Email: tonni at hetnet dot nl

Parent Message unknown Re: No timeout for nss_ldap?

by Tony Earnshaw-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Buchan Milne skrev, on 03-01-2008 14:23:

>>> Just so I know what awaits me - could you give me examples of which
>>> services will break if I set bind_policy to soft?
>> Actually, it's setting it to hard which breaks things. That's what I was
>> trying to repair in the content of my first mispost.
>>
>> So why should it be set to hard anyway? When soft works for reboots?
>> Because soft never makes nss_ldap retries on a bind failure. Say that
>> you have a primary and a failover URI in ldap.conf, as we have on our 2
>> k12ltsp (Linux Terminal Server Project) servers:
>>
>> uri ldap://192.168.1.25/ ldap://192.168.0.253/
>>
>> For some reason 192.168.1.25 can't be contacted, nss_ldap should
>> failover to 192.168.0.253. But it won't with bind_policy soft.
>
> Do you have proof of this ? Because I can't reproduce it.

[...]

With bind_policy soft:

Nov 25 06:43:42 opera verynice: nss_ldap: could not search LDAP server -
Server is unavailable
Nov 26 09:27:42 opera gdm[19570]: nss_ldap: could not search LDAP server
- Server is unavailable
Nov 26 09:27:42 opera gdm[4093]: gdm_child_action: Aborting display
ws039.leerlingen:0
Nov 26 09:39:42 opera firefox-bin: nss_ldap: could not search LDAP
server - Server is unavailable
Nov 26 09:46:03 opera soffice.bin: nss_ldap: could not search LDAP
server - Server is unavailable

[...]

With bind_policy hard_init (i.e. commented out):

Dec 21 11:25:30 opera soffice.bin: nss_ldap: reconnected to LDAP server
ldap://192.168.1.25/ after 1 attempt
Dec 21 11:25:32 opera gdm[4801]: nss_ldap: reconnected to LDAP server
ldap://192.168.1.25/ after 1 attempt
Dec 21 11:25:32 opera gconfd (dng-5168): Received signal 15, shutting
down cleanly
Dec 21 11:25:32 opera gconfd (dng-5168): Exiting
Dec 21 11:32:22 opera gconfd (mhoekstra-4931): Exiting
Dec 21 11:32:22 opera gdm[2516]: nss_ldap: reconnected to LDAP server
ldap://192.168.1.25/ after 1 attempt
Dec 21 11:36:26 opera gconfd (dklumper-4343): Exiting
Dec 21 11:36:26 opera gdm[4208]: nss_ldap: reconnected to LDAP server
ldap://192.168.1.25/ after 1 attempt

As the only OpenLDAP bod at the school I can assure you I spent enough
time listening to anguishings from my non-OL colleague demanding to know
the reason and what I was doing about it ... I finally found the answer
by Googleing, which we're all supposed not to do ;)

> (This is Mandriva 2008.0 x86_64, where nss_ldap has been patched - by me - to
> use soft by default - I don't have a RHEL5 handy that I can test with at
> present, but bind_policy soft hasn't given any problems that I've noticed on
> our few RHEL5 servers).

This is RHEL5.1 with one Buchan Milne's OL 2.3.38 stuff and which has
now gone over to ppolicy, fiddling about with which gave rise (in part)
to the above: "IT WASN'T DOING THIS LAST WEEK, WHY IS IT DOING IT NOW?"
Etc, etc.

I'm now trying gradually to put nss-ldapd in place instead of Red Hat's
$DEITY-awful nss_ldap, but it seems it has a bug with large Posix groups
at the moment (our largest has about 900+ memberUids).

Best and a really fine 2008 to you and everyone,

--Tonni

--
Tony Earnshaw
Email: tonni at hetnet dot nl

Re: No timeout for nss_ldap?

by Arthur de Jong-3 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Thu, 2008-01-03 at 14:56 +0100, Tony Earnshaw wrote:
> I'm now trying gradually to put nss-ldapd in place instead of Red
> Hat's $DEITY-awful nss_ldap, but it seems it has a bug with large
> Posix groups at the moment (our largest has about 900+ memberUids).

This is a known problem with nss-ldapd 0.5 and is fixed (partially) in
svn. The attached patch against 0.5 should solve this issue and is
tested with groups with up to 1000 members.

--
-- arthur - arthur@... - http://ch.tudelft.nl/~arthur --

[nss-ldapd-large-groups.patch]

diff -Naur nss-ldapd-0.5.orig/common/tio.c nss-ldapd-0.5/common/tio.c
--- nss-ldapd-0.5.orig/common/tio.c 2007-10-27 23:38:37.000000000 +0200
+++ nss-ldapd-0.5/common/tio.c 2008-01-03 17:15:55.000000000 +0100
@@ -2,7 +2,7 @@
    tio.c - timed io functions
    This file is part of the nss-ldapd library.
 
-   Copyright (C) 2007 Arthur de Jong
+   Copyright (C) 2007, 2008 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -60,6 +60,7 @@
   struct tio_buffer *writebuffer;
   struct timeval readtimeout;
   struct timeval writetimeout;
+  int read_resettable; /* whether the tio_reset() function can be called */
 #ifdef DEBUG_TIO_STATS
   /* this is used to collect statistics on the use of the streams
      and can be used to tune the buffer sizes */
@@ -156,6 +157,7 @@
   fp->readtimeout.tv_usec=readtimeout->tv_usec;
   fp->writetimeout.tv_sec=writetimeout->tv_sec;
   fp->writetimeout.tv_usec=writetimeout->tv_usec;
+  fp->read_resettable=0;
 #ifdef DEBUG_TIO_STATS
   fp->byteswritten=0;
   fp->bytesread=0;
@@ -221,10 +223,9 @@
   /* loop until we have returned all the needed data */
   while (1)
   {
-    /* return any data already in the buffer */
+    /* check if we have enough data in the buffer */
     if (fp->readbuffer->len >= count)
     {
-      /* we have enough data in our buffer */
       if (count>0)
       {
         if (ptr!=NULL)
@@ -235,26 +236,32 @@
       }
       return 0;
     }
-    else
+    /* empty what we have and continue from there */
+    if (fp->readbuffer->len > 0)
     {
-      /* empty what we have and continue from there */
-      if (fp->readbuffer->len > 0)
+      if (ptr!=NULL)
       {
-        if (ptr!=NULL)
-          memcpy(ptr,fp->readbuffer->buffer+fp->readbuffer->start,fp->readbuffer->len);
-        count-=fp->readbuffer->len;
-        if (ptr!=NULL)
-          ptr+=fp->readbuffer->len;
+        memcpy(ptr,fp->readbuffer->buffer+fp->readbuffer->start,fp->readbuffer->len);
+        ptr+=fp->readbuffer->len;
       }
-      /* flag the buffer as empty */
+      count-=fp->readbuffer->len;
+    }
+    /* if we have room in the buffer for more don't clear the buffer */
+    if ((fp->read_resettable)&&((fp->readbuffer->start+fp->readbuffer->len)<TIO_BUFFERSIZE))
+    {
+      fp->readbuffer->start+=fp->readbuffer->len;
+    }
+    else
+    {
       fp->readbuffer->start=0;
-      fp->readbuffer->len=0;
+      fp->read_resettable=0;
     }
+    fp->readbuffer->len=0;
     /* wait until we have input */
     if (tio_select(fp->fd,1,&deadline))
       return -1;
     /* read the input in the buffer */
-    rv=read(fp->fd,fp->readbuffer->buffer,TIO_BUFFERSIZE);
+    rv=read(fp->fd,fp->readbuffer->buffer+fp->readbuffer->start,TIO_BUFFERSIZE-fp->readbuffer->start);
     /* check for errors */
     if ((rv==0)||((rv<0)&&(errno!=EINTR)&&(errno!=EAGAIN)))
       return -1; /* something went wrong with the read */
@@ -386,3 +393,33 @@
   /* return the result of the earlier operations */
   return retv;
 }
+
+void tio_mark(TFILE *fp)
+{
+  /* ensure that we have a read buffer */
+  if (fp->readbuffer==NULL)
+  {
+    fp->readbuffer=tio_buffer_new();
+    if (fp->readbuffer==NULL)
+      return; /* error allocating buffer */
+  }
+  /* move any data in the buffer to the start of the buffer */
+  if ((fp->readbuffer->start>0)&&(fp->readbuffer->len>0))
+  {
+    memmove(fp->readbuffer->buffer,fp->readbuffer->buffer+fp->readbuffer->start,fp->readbuffer->len);
+    fp->readbuffer->start=0;
+  }
+  /* mark the stream as resettable */
+  fp->read_resettable=1;
+}
+
+int tio_reset(TFILE *fp)
+{
+  /* check if the stream is (still) resettable */
+  if ((!fp->read_resettable)||(fp->readbuffer==NULL))
+    return -1;
+  /* reset the buffer */
+  fp->readbuffer->len+=fp->readbuffer->start;
+  fp->readbuffer->start=0;
+  return 0;
+}
diff -Naur nss-ldapd-0.5.orig/common/tio.h nss-ldapd-0.5/common/tio.h
--- nss-ldapd-0.5.orig/common/tio.h 2007-07-23 23:15:19.000000000 +0200
+++ nss-ldapd-0.5/common/tio.h 2008-01-03 17:15:55.000000000 +0100
@@ -2,7 +2,7 @@
    tio.h - timed io functions
    This file is part of the nss-ldapd library.
 
-   Copyright (C) 2007 Arthur de Jong
+   Copyright (C) 2007, 2008 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -22,9 +22,14 @@
 
 /*
 
-   Add some documentation here.
+   TODO: Add some documentation here.
 
-   the SIGPIPE signal should be ignored
+   the SIGPIPE signal should be ignored (is ignored in this code)
+
+   This library is not thread safe. You cannot share TFILE objects between
+   threads and expect to be able to read and write from them in different
+   threads. All the state is in the TFILE object so calls to this library on
+   different objects can be done in parallel.
 
 */
 
@@ -36,29 +41,39 @@
 
 #include "compat/attrs.h"
 
-/* generic file handle used for reading and writing
-   (something like FILE from stdio.h) */
+/* This is a generic file handle used for reading and writing
+   (something like FILE from stdio.h). */
 typedef struct tio_fileinfo TFILE;
 
-/* Open a new TFILE based on the file descriptor.
-   The timeout is set for any operation.
-   the timeout value is copied so may be dereferenced after the call. */
+/* Open a new TFILE based on the file descriptor. The timeout is set for any
+   operation. The timeout value is copied so may be dereferenced after the
+   call. */
 TFILE *tio_fdopen(int fd,struct timeval *readtimeout,struct timeval *writetimeout)
   LIKE_MALLOC MUST_USE;
 
 /* Read the specified number of bytes from the stream. */
-int tio_read(TFILE *fp, void *buf, size_t count);
+int tio_read(TFILE *fp,void *buf,size_t count);
 
 /* Read and discard the specified number of bytes from the stream. */
-int tio_skip(TFILE *fp, size_t count);
+int tio_skip(TFILE *fp,size_t count);
 
 /* Write the specified buffer to the stream. */
-int tio_write(TFILE *fp, const void *buf, size_t count);
+int tio_write(TFILE *fp,const void *buf,size_t count);
 
 /* Write out all buffered data to the stream. */
 int tio_flush(TFILE *fp);
 
-/* this also closes the underlying file descriptor */
+/* Flush the streams and closes the underlying file descriptor. */
 int tio_close(TFILE *fp);
 
+/* Store the current position in the stream so that we can jump back to it
+   with the tio_reset() function. */
+void tio_mark(TFILE *fp);
+
+/* Rewinds the stream to the point set by tio_mark(). Note that this only
+   resets the read stream and not the write stream. This function returns
+   whether the reset was successful (this function may fail if the buffers
+   were full). */
+int tio_reset(TFILE *fp);
+
 #endif /* _TIO_H */
diff -Naur nss-ldapd-0.5.orig/nss/common.h nss-ldapd-0.5/nss/common.h
--- nss-ldapd-0.5.orig/nss/common.h 2007-07-23 23:15:19.000000000 +0200
+++ nss-ldapd-0.5/nss/common.h 2008-01-03 17:15:55.000000000 +0100
@@ -2,7 +2,7 @@
    common.h - common functions for NSS lookups
 
    Copyright (C) 2006 West Consulting
-   Copyright (C) 2006, 2007 Arthur de Jong
+   Copyright (C) 2006, 2007, 2008 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -94,8 +94,6 @@
    Something more inteligent (e.g. ungetting the read data from
    the stream) should be implemented. */
 #define ERROR_OUT_BUFERROR(fp) \
-  (void)tio_close(fp); \
-  fp=NULL; \
   *errnop=ERANGE; \
   return NSS_STATUS_TRYAGAIN;
 
@@ -125,14 +123,14 @@
    the result structure, the user buffer with length and the
    errno to return. This macro should be called through some of
    the customized ones below. */
-#define NSS_BYGEN(action,param,readfn) \
+#define NSS_BYGEN(action,writefn,readfn) \
   TFILE *fp; \
   int32_t tmpint32; \
   enum nss_status retv; \
   /* open socket and write request */ \
   OPEN_SOCK(fp); \
   WRITE_REQUEST(fp,action); \
-  param; \
+  writefn; \
   WRITE_FLUSH(fp); \
   /* read response header */ \
   READ_RESPONSEHEADER(fp,action); \
@@ -140,7 +138,7 @@
   READ_RESPONSE_CODE(fp); \
   retv=readfn; \
   /* close socket and we're done */ \
-  if (retv==NSS_STATUS_SUCCESS) \
+  if ((retv==NSS_STATUS_SUCCESS)||(retv==NSS_STATUS_TRYAGAIN)) \
     (void)tio_close(fp); \
   return retv;
 
@@ -189,11 +187,22 @@
     *errnop=ENOENT; \
     return NSS_STATUS_UNAVAIL; \
   } \
+  /* prepare for buffer errors */ \
+  tio_mark(fp); \
   /* read a response */ \
   READ_RESPONSE_CODE(fp); \
   retv=readfn; \
   /* check read result */ \
-  if (retv!=NSS_STATUS_SUCCESS) \
+  if (retv==NSS_STATUS_TRYAGAIN) \
+  { \
+    /* if we have a full buffer try to reset the stream */ \
+    if (tio_reset(fp)) \
+    { \
+      tio_close(fp); \
+      fp=NULL; \
+    } \
+  } \
+  else if (retv!=NSS_STATUS_SUCCESS) \
     fp=NULL; /* file should be closed by now */ \
   return retv;
 
diff -Naur nss-ldapd-0.5.orig/tests/test_tio.c nss-ldapd-0.5/tests/test_tio.c
--- nss-ldapd-0.5.orig/tests/test_tio.c 2007-08-19 16:20:40.000000000 +0200
+++ nss-ldapd-0.5/tests/test_tio.c 2008-01-03 17:15:55.000000000 +0100
@@ -2,7 +2,7 @@
    test_tio.c - simple test for the tio module
    This file is part of the nss-ldapd library.
 
-   Copyright (C) 2007 Arthur de Jong
+   Copyright (C) 2007, 2008 Arthur de Jong
 
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
@@ -55,7 +55,7 @@
   timeout.tv_sec=hargs->timeout;
   timeout.tv_usec=0;
   /* open the file */
-  fp = tio_fdopen(hargs->fd,&timeout,&timeout);
+  fp=tio_fdopen(hargs->fd,&timeout,&timeout);
   assert(fp!=NULL);
   /* write the blocks */
   i=0;
@@ -87,7 +87,7 @@
   timeout.tv_sec=hargs->timeout;
   timeout.tv_usec=0;
   /* open the file */
-  fp = tio_fdopen(hargs->fd,&timeout,&timeout);
+  fp=tio_fdopen(hargs->fd,&timeout,&timeout);
   assert(fp!=NULL);
   /* read the blocks */
   i=0;
@@ -115,7 +115,7 @@
   buf=(uint8_t *)malloc(hargs->blocksize);
   assert(buf!=NULL);
   /* open the file */
-  fp = fdopen(hargs->fd,"wb");
+  fp=fdopen(hargs->fd,"wb");
   assert(fp!=NULL);
   /* write the blocks */
   i=0;
@@ -139,7 +139,7 @@
   size_t i,j,k;
   struct helper_args *hargs=(struct helper_args *)arg;
   /* open the file */
-  fp = fdopen(hargs->fd,"rb");
+  fp=fdopen(hargs->fd,"rb");
   assert(fp!=NULL);
   /* read the blocks */
   i=0;
@@ -189,6 +189,73 @@
   return 0;
 }
 
+static void test_reset(void)
+{
+  int sp[2];
+  pthread_t wthread;
+  struct helper_args wargs;
+  TFILE *fp;
+  struct timeval timeout;
+  size_t i,j,k,save;
+  uint8_t buf[10];
+  /* set up the socket pair */
+  assert(socketpair(AF_UNIX,SOCK_STREAM,0,sp)==0);
+  /* start the writer thread */
+  wargs.fd=sp[0];
+  wargs.blocksize=4*1024; /* the current TIO_BUFFERSIZE */
+  wargs.blocks=5;
+  wargs.timeout=2;
+  assert(pthread_create(&wthread,NULL,help_tiowriter,&wargs)==0);
+  /* set up read handle */
+  timeout.tv_sec=2;
+  timeout.tv_usec=0;
+  fp=tio_fdopen(sp[1],&timeout,&timeout);
+  assert(fp!=NULL);
+  /* perform 20 reads */
+  i=0;
+  for (k=0;k<20;k++)
+  {
+    assert(tio_read(fp,buf,sizeof(buf))==0);
+    /* check the buffer */
+    for (j=0;j<sizeof(buf);j++)
+      assert(buf[j]==(uint8_t)(i++));
+  }
+  /* mark and perform another 2 reads */
+  tio_mark(fp);
+  save=i;
+  for (k=0;k<2;k++)
+  {
+    assert(tio_read(fp,buf,sizeof(buf))==0);
+    /* check the buffer */
+    for (j=0;j<sizeof(buf);j++)
+      assert(buf[j]==(uint8_t)(i++));
+  }
+  /* reset and perform the same 2 reads again and 500 more */
+  assert(tio_reset(fp)==0);
+  i=save;
+  for (k=0;k<502;k++)
+  {
+    assert(tio_read(fp,buf,sizeof(buf))==0);
+    /* check the buffer */
+    for (j=0;j<sizeof(buf);j++)
+      assert(buf[j]==(uint8_t)(i++));
+  }
+  /* check that reset is no longer possible */
+  assert(tio_reset(fp)!=0);
+  /* read the remainder of the data 1526 reads */
+  for (k=0;k<1526;k++)
+  {
+    assert(tio_read(fp,buf,sizeof(buf))==0);
+    /* check the buffer */
+    for (j=0;j<sizeof(buf);j++)
+      assert(buf[j]==(uint8_t)(i++));
+  }
+  /* close the file */
+  assert(tio_close(fp)==0);
+  /* wait for the writer thread to die */
+  assert(pthread_join(wthread,NULL)==0);
+}
+
 /* the main program... */
 int main(int UNUSED(argc),char UNUSED(*argv[]))
 {
@@ -202,5 +269,7 @@
   /* writer closes file sooner */
 /*  test_blocks(4*1023,20,20*1023,5); */
 /*  test_blocks(10,9,10,10); */
+  /* set tio_mark() and tio_reset() functions */
+  test_reset();
   return 0;
 }



signature.asc (196 bytes) Download Attachment

Re: No timeout for nss_ldap?

by Tony Earnshaw-4 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Arthur de Jong skrev, on 03-01-2008 17:26:

>> I'm now trying gradually to put nss-ldapd in place instead of Red
>> Hat's $DEITY-awful nss_ldap, but it seems it has a bug with large
>> Posix groups at the moment (our largest has about 900+ memberUids).

> This is a known problem with nss-ldapd 0.5 and is fixed (partially) in
> svn.

I (as Red Hat person) snooped on the Debian bug DB and saw your exchange
with UIO's Petter Reinholdtsen (whom I knew earlier from Norwegian
things). So I got interested and followed the debug thread about this
issue, which ended unresolved this morning and my ensuing post to this list.

> The attached patch against 0.5 should solve this issue and is
> tested with groups with up to 1000 members.

We'll apply it and then go and eat, and sleep. Tomorrow is another day ;)

Best,

--Tonni

--
Tony Earnshaw
Email: tonni at hetnet dot nl
LightInTheBox - Buy quality products at wholesale price