* 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.
This commit is contained in:
Ulrich Drepper 2006-05-30 17:32:08 +00:00
parent ecc6856848
commit 902c429174
5 changed files with 81 additions and 18 deletions

View file

@ -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

View 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;

View 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. */

View 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':

View 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,