* nscd/connection.c (DEFAULT_DATASIZE_PER_BUCKET): Move to nscd.h.
(dbs): Initialize max_db_size fields. (nscd_init): When mapping the database, use max_db_size as the mapping size even if it is bigger than the file size. * nscd/mem.c (mempool_alloc): When resizing the file make sure the limit in max_db_size is not exceeded. Don't use mremap, just posix_fallocate is enough (according to Linus). Use posix_fallocate correctly. * nscd/nscd.conf: Add max-db-size parameters. * nscd/nscd.h (struct database_dyn): Add max_db_size field. Define DEFAULT_MAX_DB_SIZE and DEFAULT_DATASIZE_PER_BUCKET. Temporarily define TEMP_FAILURE_RETRY_VAL here. * nscd/nscd_conf.c (nscd_parse_file): Parse max-db-size parameter and add sanity checks for it. * nscd/aicache.c (addhstaiX): Use send with MSG_NOSIGNAL not write to send reply. * nscd/connection.c (writeall): Likewise. (handle_request): Likewise. * nscd/grpcache.c (cache_addgr): Likewise. * nscd/hstcache.c (cache_addhst): Likewise. * nscd/initgrcache.c (addinitgroupsX): Likewise. * nscd/nscd.c (parse_opt): Likewise. * nscd/nscd_stat.c (send_stats): Likewise. (receive_print_stats): Likewise. * nscd/pwdcache.c (cache_addpw): Likewise.
This commit is contained in:
parent
fd4af66481
commit
2c210d1eb8
27
ChangeLog
27
ChangeLog
@ -1,5 +1,32 @@
|
||||
2005-08-23 Ulrich Drepper <drepper@redhat.com>
|
||||
|
||||
* nscd/connection.c (DEFAULT_DATASIZE_PER_BUCKET): Move to nscd.h.
|
||||
(dbs): Initialize max_db_size fields.
|
||||
(nscd_init): When mapping the database, use max_db_size as the
|
||||
mapping size even if it is bigger than the file size.
|
||||
* nscd/mem.c (mempool_alloc): When resizing the file make sure the
|
||||
limit in max_db_size is not exceeded. Don't use mremap, just
|
||||
posix_fallocate is enough (according to Linus). Use posix_fallocate
|
||||
correctly.
|
||||
* nscd/nscd.conf: Add max-db-size parameters.
|
||||
* nscd/nscd.h (struct database_dyn): Add max_db_size field.
|
||||
Define DEFAULT_MAX_DB_SIZE and DEFAULT_DATASIZE_PER_BUCKET.
|
||||
Temporarily define TEMP_FAILURE_RETRY_VAL here.
|
||||
* nscd/nscd_conf.c (nscd_parse_file): Parse max-db-size parameter
|
||||
and add sanity checks for it.
|
||||
|
||||
* nscd/aicache.c (addhstaiX): Use send with MSG_NOSIGNAL not write to
|
||||
send reply.
|
||||
* nscd/connection.c (writeall): Likewise.
|
||||
(handle_request): Likewise.
|
||||
* nscd/grpcache.c (cache_addgr): Likewise.
|
||||
* nscd/hstcache.c (cache_addhst): Likewise.
|
||||
* nscd/initgrcache.c (addinitgroupsX): Likewise.
|
||||
* nscd/nscd.c (parse_opt): Likewise.
|
||||
* nscd/nscd_stat.c (send_stats): Likewise.
|
||||
(receive_print_stats): Likewise.
|
||||
* nscd/pwdcache.c (cache_addpw): Likewise.
|
||||
|
||||
* sysdeps/unix/sysv/linux/Versions: Export Inotify_* syscalls.
|
||||
|
||||
2005-08-22 Jakub Jelinek <jakub@redhat.com>
|
||||
|
@ -399,7 +399,7 @@ addhstaiX (struct database_dyn *db, int fd, request_header *req,
|
||||
total = sizeof (notfound);
|
||||
|
||||
if (fd != -1)
|
||||
TEMP_FAILURE_RETRY (write (fd, ¬found, total));
|
||||
TEMP_FAILURE_RETRY (send (fd, ¬found, total, MSG_NOSIGNAL));
|
||||
|
||||
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
|
||||
/* If we cannot permanently store the result, so be it. */
|
||||
|
@ -48,10 +48,6 @@
|
||||
#include "selinux.h"
|
||||
|
||||
|
||||
/* Number of bytes of data we initially reserve for each hash table bucket. */
|
||||
#define DEFAULT_DATASIZE_PER_BUCKET 1024
|
||||
|
||||
|
||||
/* Wrapper functions with error checking for standard functions. */
|
||||
extern void *xmalloc (size_t n);
|
||||
extern void *xcalloc (size_t n, size_t s);
|
||||
@ -104,6 +100,7 @@ struct database_dyn dbs[lastdb] =
|
||||
.check_file = 1,
|
||||
.persistent = 0,
|
||||
.shared = 0,
|
||||
.max_db_size = DEFAULT_MAX_DB_SIZE,
|
||||
.filename = "/etc/passwd",
|
||||
.db_filename = _PATH_NSCD_PASSWD_DB,
|
||||
.disabled_iov = &pwd_iov_disabled,
|
||||
@ -119,6 +116,7 @@ struct database_dyn dbs[lastdb] =
|
||||
.check_file = 1,
|
||||
.persistent = 0,
|
||||
.shared = 0,
|
||||
.max_db_size = DEFAULT_MAX_DB_SIZE,
|
||||
.filename = "/etc/group",
|
||||
.db_filename = _PATH_NSCD_GROUP_DB,
|
||||
.disabled_iov = &grp_iov_disabled,
|
||||
@ -134,6 +132,7 @@ struct database_dyn dbs[lastdb] =
|
||||
.check_file = 1,
|
||||
.persistent = 0,
|
||||
.shared = 0,
|
||||
.max_db_size = DEFAULT_MAX_DB_SIZE,
|
||||
.filename = "/etc/hosts",
|
||||
.db_filename = _PATH_NSCD_HOSTS_DB,
|
||||
.disabled_iov = &hst_iov_disabled,
|
||||
@ -188,7 +187,7 @@ writeall (int fd, const void *buf, size_t len)
|
||||
ssize_t ret;
|
||||
do
|
||||
{
|
||||
ret = TEMP_FAILURE_RETRY (write (fd, buf, n));
|
||||
ret = TEMP_FAILURE_RETRY (send (fd, buf, n, MSG_NOSIGNAL));
|
||||
if (ret <= 0)
|
||||
break;
|
||||
buf = (const char *) buf + ret;
|
||||
@ -473,8 +472,16 @@ nscd_init (void)
|
||||
_("file size does not match"));
|
||||
unlink (dbs[cnt].db_filename);
|
||||
}
|
||||
else if ((mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0)) == MAP_FAILED)
|
||||
/* Note we map with the maximum size allowed for the
|
||||
database. This is likely much larger than the
|
||||
actual file size. This is OK on most OSes since
|
||||
extensions of the underlying file will
|
||||
automatically translate more pages available for
|
||||
memory access. */
|
||||
else if ((mem = mmap (NULL, dbs[cnt].max_db_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0))
|
||||
== MAP_FAILED)
|
||||
goto fail_db;
|
||||
else if (!verify_persistent_db (mem, &head, cnt))
|
||||
{
|
||||
@ -638,8 +645,10 @@ cannot create read-only descriptor for \"%s\"; no mmap"),
|
||||
|
||||
if ((TEMP_FAILURE_RETRY (write (fd, &head, sizeof (head)))
|
||||
!= sizeof (head))
|
||||
|| posix_fallocate (fd, 0, total) != 0
|
||||
|| (mem = mmap (NULL, total, PROT_READ | PROT_WRITE,
|
||||
|| (TEMP_FAILURE_RETRY_VAL (posix_fallocate (fd, 0, total))
|
||||
!= 0)
|
||||
|| (mem = mmap (NULL, dbs[cnt].max_db_size,
|
||||
PROT_READ | PROT_WRITE,
|
||||
MAP_SHARED, fd, 0)) == MAP_FAILED)
|
||||
{
|
||||
write_fail:
|
||||
@ -901,8 +910,9 @@ cannot handle old request version %d; current version is %d"),
|
||||
if (!db->enabled)
|
||||
{
|
||||
/* No, sent the prepared record. */
|
||||
if (TEMP_FAILURE_RETRY (write (fd, db->disabled_iov->iov_base,
|
||||
db->disabled_iov->iov_len))
|
||||
if (TEMP_FAILURE_RETRY (send (fd, db->disabled_iov->iov_base,
|
||||
db->disabled_iov->iov_len,
|
||||
MSG_NOSIGNAL))
|
||||
!= (ssize_t) db->disabled_iov->iov_len
|
||||
&& __builtin_expect (debug_level, 0) > 0)
|
||||
{
|
||||
|
@ -107,7 +107,8 @@ cache_addgr (struct database_dyn *db, int fd, request_header *req,
|
||||
case. */
|
||||
total = sizeof (notfound);
|
||||
|
||||
written = TEMP_FAILURE_RETRY (write (fd, ¬found, total));
|
||||
written = TEMP_FAILURE_RETRY (send (fd, ¬found, total,
|
||||
MSG_NOSIGNAL));
|
||||
|
||||
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
|
||||
/* If we cannot permanently store the result, so be it. */
|
||||
|
@ -115,7 +115,8 @@ cache_addhst (struct database_dyn *db, int fd, request_header *req,
|
||||
written = total = sizeof (notfound);
|
||||
|
||||
if (fd != -1)
|
||||
written = TEMP_FAILURE_RETRY (write (fd, ¬found, total));
|
||||
written = TEMP_FAILURE_RETRY (send (fd, ¬found, total,
|
||||
MSG_NOSIGNAL));
|
||||
|
||||
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
|
||||
/* If we cannot permanently store the result, so be it. */
|
||||
|
@ -188,7 +188,8 @@ addinitgroupsX (struct database_dyn *db, int fd, request_header *req,
|
||||
/* We have no data. This means we send the standard reply for this
|
||||
case. */
|
||||
if (fd != -1)
|
||||
written = TEMP_FAILURE_RETRY (write (fd, ¬found, total));
|
||||
written = TEMP_FAILURE_RETRY (send (fd, ¬found, total,
|
||||
MSG_NOSIGNAL));
|
||||
|
||||
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
|
||||
/* If we cannot permanently store the result, so be it. */
|
||||
|
18
nscd/mem.c
18
nscd/mem.c
@ -481,18 +481,26 @@ mempool_alloc (struct database_dyn *db, size_t len)
|
||||
if (! tried_resize)
|
||||
{
|
||||
/* Try to resize the database. Grow size of 1/8th. */
|
||||
size_t new_data_size = db->head->data_size + db->head->data_size / 8;
|
||||
size_t oldtotal = (sizeof (struct database_pers_head)
|
||||
+ db->head->module * sizeof (ref_t)
|
||||
+ db->head->data_size);
|
||||
size_t new_data_size = (db->head->data_size
|
||||
+ MAX (2 * len, db->head->data_size / 8));
|
||||
size_t newtotal = (sizeof (struct database_pers_head)
|
||||
+ db->head->module * sizeof (ref_t)
|
||||
+ new_data_size);
|
||||
if (newtotal > db->max_db_size)
|
||||
{
|
||||
new_data_size -= newtotal - db->max_db_size;
|
||||
newtotal = db->max_db_size;
|
||||
}
|
||||
|
||||
if ((!db->mmap_used
|
||||
|| posix_fallocate (db->wr_fd, oldtotal, newtotal) != 0)
|
||||
/* Try to resize the mapping. Note: no MREMAP_MAYMOVE. */
|
||||
&& mremap (db->head, oldtotal, newtotal, 0) == 0)
|
||||
if (db->mmap_used && newtotal > oldtotal
|
||||
/* We only have to adjust the file size. The new pages
|
||||
become magically available. */
|
||||
&& TEMP_FAILURE_RETRY_VAL (posix_fallocate (db->wr_fd, oldtotal,
|
||||
newtotal
|
||||
- oldtotal)) == 0)
|
||||
{
|
||||
db->head->data_size = new_data_size;
|
||||
tried_resize = true;
|
||||
|
@ -315,8 +315,9 @@ parse_opt (int key, char *arg, struct argp_state *state)
|
||||
req.version = NSCD_VERSION;
|
||||
req.type = SHUTDOWN;
|
||||
req.key_len = 0;
|
||||
nbytes = TEMP_FAILURE_RETRY (write (sock, &req,
|
||||
sizeof (request_header)));
|
||||
nbytes = TEMP_FAILURE_RETRY (send (sock, &req,
|
||||
sizeof (request_header),
|
||||
MSG_NOSIGNAL));
|
||||
close (sock);
|
||||
exit (nbytes != sizeof (request_header) ? EXIT_FAILURE : EXIT_SUCCESS);
|
||||
}
|
||||
|
@ -23,6 +23,7 @@
|
||||
# check-files <service> <yes|no>
|
||||
# persistent <service> <yes|no>
|
||||
# shared <service> <yes|no>
|
||||
# max-db-szie <service> <number bytes>
|
||||
#
|
||||
# Currently supported cache names (services): passwd, group, hosts
|
||||
#
|
||||
@ -45,6 +46,7 @@
|
||||
check-files passwd yes
|
||||
persistent passwd yes
|
||||
shared passwd yes
|
||||
max-db-size passwd 33554432
|
||||
|
||||
enable-cache group yes
|
||||
positive-time-to-live group 3600
|
||||
@ -53,6 +55,7 @@
|
||||
check-files group yes
|
||||
persistent group yes
|
||||
shared group yes
|
||||
max-db-size group 33554432
|
||||
|
||||
enable-cache hosts yes
|
||||
positive-time-to-live hosts 3600
|
||||
@ -61,3 +64,4 @@
|
||||
check-files hosts yes
|
||||
persistent hosts yes
|
||||
shared hosts yes
|
||||
max-db-size hosts 33554432
|
||||
|
17
nscd/nscd.h
17
nscd/nscd.h
@ -63,6 +63,7 @@ struct database_dyn
|
||||
int check_file;
|
||||
int persistent;
|
||||
int shared;
|
||||
size_t max_db_size;
|
||||
const char *filename;
|
||||
const char *db_filename;
|
||||
time_t file_mtime;
|
||||
@ -99,6 +100,12 @@ struct database_dyn
|
||||
#define BLOCK_ALIGN (1 << BLOCK_ALIGN_LOG)
|
||||
#define BLOCK_ALIGN_M1 (BLOCK_ALIGN - 1)
|
||||
|
||||
/* Default value for the maximum size of the database files. */
|
||||
#define DEFAULT_MAX_DB_SIZE (32 * 1024 * 1024)
|
||||
|
||||
/* Number of bytes of data we initially reserve for each hash table bucket. */
|
||||
#define DEFAULT_DATASIZE_PER_BUCKET 1024
|
||||
|
||||
|
||||
/* Global variables. */
|
||||
extern struct database_dyn dbs[lastdb];
|
||||
@ -241,4 +248,14 @@ extern void gc (struct database_dyn *db);
|
||||
/* nscd_setup_thread.c */
|
||||
extern void setup_thread (struct database_dyn *db);
|
||||
|
||||
|
||||
/* Special version of TEMP_FAILURE_RETRY for functions returning error
|
||||
values. */
|
||||
#define TEMP_FAILURE_RETRY_VAL(expression) \
|
||||
(__extension__ \
|
||||
({ long int __result; \
|
||||
do __result = (long int) (expression); \
|
||||
while (__result == EINTR); \
|
||||
__result; }))
|
||||
|
||||
#endif /* nscd.h */
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* Copyright (c) 1998, 2000, 2003, 2004 Free Software Foundation, Inc.
|
||||
/* Copyright (c) 1998, 2000, 2003, 2004, 2005 Free Software Foundation, Inc.
|
||||
This file is part of the GNU C Library.
|
||||
Contributed by Thorsten Kukuk <kukuk@suse.de>, 1998.
|
||||
|
||||
@ -171,6 +171,17 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb])
|
||||
if (cnt == lastdb)
|
||||
dbg_log ("database %s is not supported\n", arg1);
|
||||
}
|
||||
else if (strcmp (entry, "max-db-size") == 0)
|
||||
{
|
||||
for (cnt = 0; cnt < lastdb; ++cnt)
|
||||
if (strcmp (arg1, dbnames[cnt]) == 0)
|
||||
{
|
||||
dbs[cnt].max_db_size = atol (arg2);
|
||||
break;
|
||||
}
|
||||
if (cnt == lastdb)
|
||||
dbg_log ("database %s is not supported\n", arg1);
|
||||
}
|
||||
else if (strcmp (entry, "logfile") == 0)
|
||||
set_logfile (arg1);
|
||||
else if (strcmp (entry, "debug-level") == 0)
|
||||
@ -290,6 +301,22 @@ cannot get current working directory: %s; disabling paranoia mode"),
|
||||
if (max_nthreads < nthreads)
|
||||
max_nthreads = nthreads;
|
||||
|
||||
for (cnt = 0; cnt < lastdb; ++cnt)
|
||||
{
|
||||
size_t datasize = (sizeof (struct database_pers_head)
|
||||
+ roundup (dbs[cnt].suggested_module
|
||||
* sizeof (ref_t), ALIGN)
|
||||
+ (dbs[cnt].suggested_module
|
||||
* DEFAULT_DATASIZE_PER_BUCKET));
|
||||
if (datasize > dbs[cnt].max_db_size)
|
||||
{
|
||||
dbg_log (_("maximum file size for %s database too small"),
|
||||
dbnames[cnt]);
|
||||
dbs[cnt].max_db_size = datasize;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* Free the buffer. */
|
||||
free (line);
|
||||
/* Close configuration file. */
|
||||
|
@ -133,7 +133,8 @@ send_stats (int fd, struct database_dyn dbs[lastdb])
|
||||
if (selinux_enabled)
|
||||
nscd_avc_cache_stats (&data.cstats);
|
||||
|
||||
if (TEMP_FAILURE_RETRY (write (fd, &data, sizeof (data))) != sizeof (data))
|
||||
if (TEMP_FAILURE_RETRY (send (fd, &data, sizeof (data), MSG_NOSIGNAL))
|
||||
!= sizeof (data))
|
||||
{
|
||||
char buf[256];
|
||||
dbg_log (_("cannot write statistics: %s"),
|
||||
@ -180,7 +181,8 @@ receive_print_stats (void)
|
||||
req.version = NSCD_VERSION;
|
||||
req.type = GETSTAT;
|
||||
req.key_len = 0;
|
||||
nbytes = TEMP_FAILURE_RETRY (write (fd, &req, sizeof (request_header)));
|
||||
nbytes = TEMP_FAILURE_RETRY (send (fd, &req, sizeof (request_header),
|
||||
MSG_NOSIGNAL));
|
||||
if (nbytes != sizeof (request_header))
|
||||
{
|
||||
int err = errno;
|
||||
|
@ -114,7 +114,8 @@ cache_addpw (struct database_dyn *db, int fd, request_header *req,
|
||||
written = total = sizeof (notfound);
|
||||
|
||||
if (fd != -1)
|
||||
written = TEMP_FAILURE_RETRY (write (fd, ¬found, total));
|
||||
written = TEMP_FAILURE_RETRY (send (fd, ¬found, total,
|
||||
MSG_NOSIGNAL));
|
||||
|
||||
dataset = mempool_alloc (db, sizeof (struct dataset) + req->key_len);
|
||||
/* If we cannot permanently store the result, so be it. */
|
||||
|
Loading…
Reference in New Issue
Block a user