about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJan Sembera <jsembera@suse.cz>2010-08-22 15:43:46 +0200
committerPetr Baudis <pasky@suse.cz>2010-11-16 02:38:24 +0100
commit75134e46476263ab116be341531cadb1e6ab87d6 (patch)
tree6772a3bda070489269183151e6e604077ee6018f
parent3540d66b669af54900b2e4bfc0ab82960e84a471 (diff)
downloadglibc-75134e46476263ab116be341531cadb1e6ab87d6.tar.gz
glibc-75134e46476263ab116be341531cadb1e6ab87d6.tar.xz
glibc-75134e46476263ab116be341531cadb1e6ab87d6.zip
nscd/hstcache.c: Propagate TRY_AGAIN properly to the clients.
When nscd host cache gets temporary error from nss, it should return
temporary error instead of permanent error to the application.
-rw-r--r--ChangeLog5
-rw-r--r--nscd/hstcache.c32
2 files changed, 31 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 7fc8af25f9..601f6f0f43 100644
--- 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.
diff --git a/nscd/hstcache.c b/nscd/hstcache.c
index 228f6fd8ab..5d3fbe2483 100644
--- a/nscd/hstcache.c
+++ b/nscd/hstcache.c
@@ -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);