diff options
author | Jakub Jelinek <jakub@redhat.com> | 2005-08-24 07:23:32 +0000 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2005-08-24 07:23:32 +0000 |
commit | 8bf34d8a27ffed48c7a43b7c7347235d389b0946 (patch) | |
tree | 36a2efd2a73c3d642829770b47f753e0160dd411 /nscd | |
parent | d2b0f6344275bc3624e47a4d02b67a7e131f6f56 (diff) | |
download | glibc-8bf34d8a27ffed48c7a43b7c7347235d389b0946.tar.gz glibc-8bf34d8a27ffed48c7a43b7c7347235d389b0946.tar.xz glibc-8bf34d8a27ffed48c7a43b7c7347235d389b0946.zip |
Updated to fedora-glibc-20050824T0705
Diffstat (limited to 'nscd')
-rw-r--r-- | nscd/aicache.c | 2 | ||||
-rw-r--r-- | nscd/connections.c | 32 | ||||
-rw-r--r-- | nscd/grpcache.c | 3 | ||||
-rw-r--r-- | nscd/hstcache.c | 3 | ||||
-rw-r--r-- | nscd/initgrcache.c | 3 | ||||
-rw-r--r-- | nscd/mem.c | 18 | ||||
-rw-r--r-- | nscd/nscd.c | 15 | ||||
-rw-r--r-- | nscd/nscd.conf | 4 | ||||
-rw-r--r-- | nscd/nscd.h | 17 | ||||
-rw-r--r-- | nscd/nscd_conf.c | 163 | ||||
-rw-r--r-- | nscd/nscd_stat.c | 6 | ||||
-rw-r--r-- | nscd/pwdcache.c | 3 |
12 files changed, 161 insertions, 108 deletions
diff --git a/nscd/aicache.c b/nscd/aicache.c index fb75dc199d..992c6ef023 100644 --- a/nscd/aicache.c +++ b/nscd/aicache.c @@ -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. */ diff --git a/nscd/connections.c b/nscd/connections.c index 33cde99cdf..900dfb1a4c 100644 --- a/nscd/connections.c +++ b/nscd/connections.c @@ -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) { diff --git a/nscd/grpcache.c b/nscd/grpcache.c index c938554b25..6543ef354d 100644 --- a/nscd/grpcache.c +++ b/nscd/grpcache.c @@ -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. */ diff --git a/nscd/hstcache.c b/nscd/hstcache.c index 377f02387d..29bce99819 100644 --- a/nscd/hstcache.c +++ b/nscd/hstcache.c @@ -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. */ diff --git a/nscd/initgrcache.c b/nscd/initgrcache.c index db01f1bc28..bb6dee2b4e 100644 --- a/nscd/initgrcache.c +++ b/nscd/initgrcache.c @@ -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. */ diff --git a/nscd/mem.c b/nscd/mem.c index 823eda1019..96f0170c6c 100644 --- a/nscd/mem.c +++ b/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; diff --git a/nscd/nscd.c b/nscd/nscd.c index 4d14f06ecf..8f299a3aa4 100644 --- a/nscd/nscd.c +++ b/nscd/nscd.c @@ -153,12 +153,10 @@ main (int argc, char **argv) /* Read the configuration file. */ if (nscd_parse_file (conffile, dbs) != 0) - { - /* We couldn't read the configuration file. We don't start the - server. */ - dbg_log (_("cannot read configuration file; this is fatal")); - exit (1); - } + /* We couldn't read the configuration file. We don't start the + server. */ + error (EXIT_FAILURE, 0, + _("failure while reading configuration file; this is fatal")); /* Do we only get statistics? */ if (get_stats) @@ -319,8 +317,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); } diff --git a/nscd/nscd.conf b/nscd/nscd.conf index 9cb9fa292d..bde8e36219 100644 --- a/nscd/nscd.conf +++ b/nscd/nscd.conf @@ -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 diff --git a/nscd/nscd.h b/nscd/nscd.h index 25a4b38eb4..3859d95d01 100644 --- a/nscd/nscd.h +++ b/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 */ diff --git a/nscd/nscd_conf.c b/nscd/nscd_conf.c index d21f2fc501..1039250f48 100644 --- a/nscd/nscd_conf.c +++ b/nscd/nscd_conf.c @@ -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. @@ -19,6 +19,7 @@ #include <ctype.h> #include <errno.h> +#include <error.h> #include <libintl.h> #include <malloc.h> #include <pwd.h> @@ -45,6 +46,18 @@ const char *dbnames[lastdb] = [hstdb] = "hosts" }; + +static int +find_db (const char *name) +{ + for (int cnt = 0; cnt < lastdb; ++cnt) + if (strcmp (name, dbnames[cnt]) == 0) + return cnt; + + error (0, 0, _("database %s is not supported\n"), name); + return -1; +} + int nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) { @@ -52,6 +65,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) char *line, *cp, *entry, *arg1, *arg2; size_t len; int cnt; + const unsigned int initial_error_message_count = error_message_count; /* Open the configuration file. */ fp = fopen (fname, "r"); @@ -91,7 +105,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) ++arg1; *cp = '\0'; if (strlen (entry) == 0) - dbg_log (_("Parse error: %s"), line); + error (0, 0, _("Parse error: %s"), line); while (isspace (*arg1) && *arg1 != '\0') ++arg1; cp = arg1; @@ -112,64 +126,49 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) if (strcmp (entry, "positive-time-to-live") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - dbs[cnt].postimeout = atol (arg2); - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + dbs[idx].postimeout = atol (arg2); } else if (strcmp (entry, "negative-time-to-live") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - dbs[cnt].negtimeout = atol (arg2); - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + dbs[idx].negtimeout = atol (arg2); } else if (strcmp (entry, "suggested-size") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - dbs[cnt].suggested_module = atol (arg2); - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + dbs[idx].suggested_module = atol (arg2); } else if (strcmp (entry, "enable-cache") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - if (strcmp (arg2, "no") == 0) - dbs[cnt].enabled = 0; - else if (strcmp (arg2, "yes") == 0) - dbs[cnt].enabled = 1; - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + { + if (strcmp (arg2, "no") == 0) + dbs[idx].enabled = 0; + else if (strcmp (arg2, "yes") == 0) + dbs[idx].enabled = 1; + } } else if (strcmp (entry, "check-files") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - if (strcmp (arg2, "no") == 0) - dbs[cnt].check_file = 0; - else if (strcmp (arg2, "yes") == 0) - dbs[cnt].check_file = 1; - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + { + if (strcmp (arg2, "no") == 0) + dbs[idx].check_file = 0; + else if (strcmp (arg2, "yes") == 0) + dbs[idx].check_file = 1; + } + } + else if (strcmp (entry, "max-db-size") == 0) + { + int idx = find_db (arg1); + if (idx >= 0) + dbs[idx].max_db_size = atol (arg2); } else if (strcmp (entry, "logfile") == 0) set_logfile (arg1); @@ -191,14 +190,14 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) else if (strcmp (entry, "server-user") == 0) { if (!arg1) - dbg_log (_("Must specify user name for server-user option")); + error (0, 0, _("Must specify user name for server-user option")); else server_user = xstrdup (arg1); } else if (strcmp (entry, "stat-user") == 0) { if (arg1 == NULL) - dbg_log (_("Must specify user name for stat-user option")); + error (0, 0, _("Must specify user name for stat-user option")); else { stat_user = xstrdup (arg1); @@ -210,31 +209,25 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) } else if (strcmp (entry, "persistent") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - if (strcmp (arg2, "no") == 0) - dbs[cnt].persistent = 0; - else if (strcmp (arg2, "yes") == 0) - dbs[cnt].persistent = 1; - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + { + if (strcmp (arg2, "no") == 0) + dbs[idx].persistent = 0; + else if (strcmp (arg2, "yes") == 0) + dbs[idx].persistent = 1; + } } else if (strcmp (entry, "shared") == 0) { - for (cnt = 0; cnt < lastdb; ++cnt) - if (strcmp (arg1, dbnames[cnt]) == 0) - { - if (strcmp (arg2, "no") == 0) - dbs[cnt].shared = 0; - else if (strcmp (arg2, "yes") == 0) - dbs[cnt].shared = 1; - break; - } - if (cnt == lastdb) - dbg_log ("database %s is not supported\n", arg1); + int idx = find_db (arg1); + if (idx >= 0) + { + if (strcmp (arg2, "no") == 0) + dbs[idx].shared = 0; + else if (strcmp (arg2, "yes") == 0) + dbs[idx].shared = 1; + } } else if (strcmp (entry, "reload-count") == 0) { @@ -248,7 +241,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) else if (count >= 0) reload_count = count; else - dbg_log (_("invalid value for 'reload-count': %u"), count); + error (0, 0, _("invalid value for 'reload-count': %u"), count); } } else if (strcmp (entry, "paranoia") == 0) @@ -263,10 +256,10 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) if (arg1 != NULL) restart_interval = atol (arg1); else - dbg_log (_("Must specify value for restart-interval option")); + error (0, 0, _("Must specify value for restart-interval option")); } else - dbg_log (_("Unknown option: %s %s %s"), entry, arg1, arg2); + error (0, 0, _("Unknown option: %s %s %s"), entry, arg1, arg2); } while (!feof_unlocked (fp)); @@ -279,7 +272,7 @@ nscd_parse_file (const char *fname, struct database_dyn dbs[lastdb]) oldcwd = get_current_dir_name (); if (oldcwd == NULL) { - dbg_log (_("\ + error (0, 0, _("\ cannot get current working directory: %s; disabling paranoia mode"), strerror (errno)); paranoia = 0; @@ -290,10 +283,26 @@ 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) + { + error (0, 0, _("maximum file size for %s database too small"), + dbnames[cnt]); + dbs[cnt].max_db_size = datasize; + } + + } + /* Free the buffer. */ free (line); /* Close configuration file. */ fclose (fp); - return 0; + return error_message_count != initial_error_message_count; } diff --git a/nscd/nscd_stat.c b/nscd/nscd_stat.c index 43f6266c6e..c1d0bffe20 100644 --- a/nscd/nscd_stat.c +++ b/nscd/nscd_stat.c @@ -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; diff --git a/nscd/pwdcache.c b/nscd/pwdcache.c index 34265c3f39..6b25968f71 100644 --- a/nscd/pwdcache.c +++ b/nscd/pwdcache.c @@ -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. */ |