* nscd/nscd.h (prune_cache): Add fd argument to prototype.
authorUlrich Drepper <drepper@redhat.com>
Tue, 30 May 2006 17:32:08 +0000 (17:32 +0000)
committerUlrich Drepper <drepper@redhat.com>
Tue, 30 May 2006 17:32:08 +0000 (17:32 +0000)
* nscd/nscd.c (parse_opt): Read response from INVALIDATE request
to make sure the database has been already invalidated.
* nscd/cache.c (prune_cache): Add fd argument.  Write response to fd
after the cache has been invalidated.  Use pthread_mutex_lock rather
than pthread_mutex_trylock if fd != -1.
* nscd/connections.c (invalidate_cache): Add fd argument, write
response to fd if not calling prune_cache, pass fd to prune_cache.
(handle_request): Adjust invalidate_cache caller.
(nscd_run): Pass -1 as fd to prune_cache.

ChangeLog
nscd/cache.c
nscd/connections.c
nscd/nscd.c
nscd/nscd.h

index 2718e6b..0fca57d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,16 @@
+2006-05-30  Jakub Jelinek  <jakub@redhat.com>
+
+       * nscd/nscd.h (prune_cache): Add fd argument to prototype.
+       * nscd/nscd.c (parse_opt): Read response from INVALIDATE request
+       to make sure the database has been already invalidated.
+       * nscd/cache.c (prune_cache): Add fd argument.  Write response to fd
+       after the cache has been invalidated.  Use pthread_mutex_lock rather
+       than pthread_mutex_trylock if fd != -1.
+       * nscd/connections.c (invalidate_cache): Add fd argument, write
+       response to fd if not calling prune_cache, pass fd to prune_cache.
+       (handle_request): Adjust invalidate_cache caller.
+       (nscd_run): Pass -1 as fd to prune_cache.
+
 2006-05-30  Ulrich Drepper  <drepper@redhat.com>
 
        * sysdeps/posix/getaddrinfo.c (gaiconf_init): Initialize bits in
index 899e2ca..be9be2a 100644 (file)
@@ -190,20 +190,34 @@ cache_add (int type, const void *key, size_t len, struct datahead *packet,
    free the data structures since some hash table entries share the same
    data.  */
 void
-prune_cache (struct database_dyn *table, time_t now)
+prune_cache (struct database_dyn *table, time_t now, int fd)
 {
   size_t cnt = table->head->module;
 
   /* If this table is not actually used don't do anything.  */
   if (cnt == 0)
-    return;
+    {
+      if (fd != -1)
+       {
+         /* Reply to the INVALIDATE initiator.  */
+         int32_t resp = 0;
+         writeall (fd, &resp, sizeof (resp));
+       }
+      return;
+    }
 
   /* This function can be called from the cleanup thread but also in
      response to an invalidate command.  Make sure only one thread is
-     running.  No need for the second to wait around.  */
-  if (pthread_mutex_trylock (&table->prunelock) != 0)
-    /* Te work is already being done.  */
-    return ;
+     running.  When not serving INVALIDATE request, no need for the
+     second to wait around.  */
+  if (fd == -1)
+    {
+      if (pthread_mutex_trylock (&table->prunelock) != 0)
+       /* The work is already being done.  */
+       return;
+    }
+  else
+    pthread_mutex_lock (&table->prunelock);
 
   /* If we check for the modification of the underlying file we invalidate
      the entries also in this case.  */
@@ -374,6 +388,14 @@ prune_cache (struct database_dyn *table, time_t now)
     }
   while (cnt > 0);
 
+  if (fd != -1)
+    {
+      /* Reply to the INVALIDATE initiator that the cache has been
+        invalidated.  */
+      int32_t resp = 0;
+      writeall (fd, &resp, sizeof (resp));
+    }
+
   if (first <= last)
     {
       struct hashentry *head = NULL;
index da837b5..c4269ce 100644 (file)
@@ -816,9 +816,10 @@ close_sockets (void)
 
 
 static void
-invalidate_cache (char *key)
+invalidate_cache (char *key, int fd)
 {
   dbtype number;
+  int32_t resp;
 
   if (strcmp (key, "passwd") == 0)
     number = pwddb;
@@ -832,10 +833,19 @@ invalidate_cache (char *key)
       res_init ();
     }
   else
-    return;
+    {
+      resp = EINVAL;
+      writeall (fd, &resp, sizeof (resp));
+      return;
+    }
 
   if (dbs[number].enabled)
-    prune_cache (&dbs[number], LONG_MAX);
+    prune_cache (&dbs[number], LONG_MAX, fd);
+  else
+    {
+      resp = 0;
+      writeall (fd, &resp, sizeof (resp));
+    }
 }
 
 
@@ -1092,7 +1102,7 @@ cannot handle old request version %d; current version is %d"),
       else if (uid == 0)
        {
          if (req->type == INVALIDATE)
-           invalidate_cache (key);
+           invalidate_cache (key, fd);
          else
            termination_handler (0);
        }
@@ -1438,7 +1448,7 @@ handle_request: request received (Version = %d)"), req.version);
          /* The pthread_cond_timedwait() call timed out.  It is time
                 to clean up the cache.  */
          assert (my_number < lastdb);
-         prune_cache (&dbs[my_number], time (NULL));
+         prune_cache (&dbs[my_number], time (NULL), -1);
 
          if (clock_gettime (timeout_clock, &prune_ts) == -1)
            /* Should never happen.  */
index 16f55cf..6d1e50a 100644 (file)
@@ -332,9 +332,6 @@ parse_opt (int key, char *arg, struct argp_state *state)
            exit (EXIT_FAILURE);
 
          request_header req;
-         ssize_t nbytes;
-         struct iovec iov[2];
-
          if (strcmp (arg, "passwd") == 0)
            req.key_len = sizeof "passwd";
          else if (strcmp (arg, "group") == 0)
@@ -347,17 +344,38 @@ parse_opt (int key, char *arg, struct argp_state *state)
          req.version = NSCD_VERSION;
          req.type = INVALIDATE;
 
+         struct iovec iov[2];
          iov[0].iov_base = &req;
          iov[0].iov_len = sizeof (req);
          iov[1].iov_base = arg;
          iov[1].iov_len = req.key_len;
 
-         nbytes = TEMP_FAILURE_RETRY (writev (sock, iov, 2));
+         ssize_t nbytes = TEMP_FAILURE_RETRY (writev (sock, iov, 2));
+
+         if (nbytes != iov[0].iov_len + iov[1].iov_len)
+           {
+             int err = errno;
+             close (sock);
+             error (EXIT_FAILURE, err, _("write incomplete"));
+           }
+
+         /* Wait for ack.  Older nscd just closed the socket when
+            prune_cache finished, silently ignore that.  */
+         int32_t resp = 0;
+         nbytes = TEMP_FAILURE_RETRY (read (sock, &resp, sizeof (resp)));
+         if (nbytes != 0 && nbytes != sizeof (resp))
+           {
+             int err = errno;
+             close (sock);
+             error (EXIT_FAILURE, err, _("cannot read invalidate ACK"));
+           }
 
          close (sock);
 
-         exit (nbytes != iov[0].iov_len + iov[1].iov_len
-               ? EXIT_FAILURE : EXIT_SUCCESS);
+         if (resp != 0)
+           error (EXIT_FAILURE, resp, _("invalidation failed"));
+
+         exit (0);
        }
 
     case 't':
index 4a95472..5c2ff3a 100644 (file)
@@ -185,7 +185,7 @@ extern struct datahead *cache_search (request_type, void *key, size_t len,
 extern int cache_add (int type, const void *key, size_t len,
                      struct datahead *packet, bool first,
                      struct database_dyn *table, uid_t owner);
-extern void prune_cache (struct database_dyn *table, time_t now);
+extern void prune_cache (struct database_dyn *table, time_t now, int fd);
 
 /* pwdcache.c */
 extern void addpwbyname (struct database_dyn *db, int fd, request_header *req,