]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
authorJan Sembera <jsembera@suse.cz>
Sun, 22 Aug 2010 13:43:46 +0000 (15:43 +0200)
committerPetr Baudis <pasky@suse.cz>
Tue, 16 Nov 2010 01:38:24 +0000 (02:38 +0100)
When nscd host cache gets temporary error from nss, it should return
temporary error instead of permanent error to the application.

ChangeLog
nscd/hstcache.c

index 7fc8af25f935d4b63afb5193b2b0a7265e8c2bdd..601f6f0f433b9c1b1996aa25108dede8975a7658 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2010-06-01  Jan Sembera  <jsembera@suse.cz>
+
+       [BZ #6812]
+       * nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
+
 2010-11-11  Andreas Schwab  <schwab@redhat.com>
 
        * posix/fnmatch_loop.c (NEW_PATTERN): Fix use of alloca.
index 228f6fd8ab1a7f54ac6644f702eec19d118bb5ab..5d3fbe248340692dc4de468d96a143cb840bbe35 100644 (file)
@@ -77,6 +77,20 @@ static const hst_response_header notfound =
 };
 
 
+/* This is the standard reply in case of temporary error */
+static const hst_response_header tryagain =
+{
+  .version = NSCD_VERSION,
+  .found = 0,
+  .h_name_len = 0,
+  .h_aliases_cnt = 0,
+  .h_addrtype = -1,
+  .h_length = -1,
+  .h_addr_list_cnt = 0,
+  .error = TRY_AGAIN
+};
+
+
 static void
 cache_addhst (struct database_dyn *db, int fd, request_header *req,
              const void *key, struct hostent *hst, uid_t owner,
@@ -85,6 +99,7 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
 {
   bool all_written = true;
   time_t t = time (NULL);
+  hst_response_header *errhdr;
 
   /* We allocate all data in one memory block: the iov vector,
      the response header and the dataset itself.  */
@@ -112,15 +127,20 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
        {
          /* We have no data.  This means we send the standard reply for this
             case.  */
-         ssize_t total = sizeof (notfound);
+         ssize_t total = sizeof (hst_response_header);
+         errhdr = (errval == EAGAIN) ? &tryagain : &notfound;
 
          if (fd != -1 &&
-             TEMP_FAILURE_RETRY (send (fd, &notfound, total,
+             TEMP_FAILURE_RETRY (send (fd, errhdr, total,
                                        MSG_NOSIGNAL)) != total)
            all_written = false;
 
-         dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
-                                  1);
+         if (errval == EAGAIN)
+             /* Don't store temporary resolver errors at all */
+             dataset = NULL;
+         else
+             dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len,
+                                      IDX_result_data);
          /* If we cannot permanently store the result, so be it.  */
          if (dataset != NULL)
            {
@@ -490,7 +510,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
              /* We set the error to indicate this is (possibly) a
                 temporary error and that it does not mean the entry
                 is not available at all.  */
-             errval = EAGAIN;
+             h_errno = TRY_AGAIN;
              break;
            }
          use_malloc = true;
@@ -502,7 +522,7 @@ addhstbyX (struct database_dyn *db, int fd, request_header *req,
     }
 
   cache_addhst (db, fd, req, key, hst, uid, he, dh,
-               h_errno == TRY_AGAIN ? errval : 0, ttl);
+               h_errno == TRY_AGAIN ? EAGAIN : 0, ttl);
 
   if (use_malloc)
     free (buffer);