diff options
Diffstat (limited to 'nscd')
-rw-r--r-- | nscd/nscd_getai.c | 40 | ||||
-rw-r--r-- | nscd/nscd_getgr_r.c | 47 | ||||
-rw-r--r-- | nscd/nscd_gethst_r.c | 35 | ||||
-rw-r--r-- | nscd/nscd_getpw_r.c | 34 | ||||
-rw-r--r-- | nscd/nscd_helper.c | 2 | ||||
-rw-r--r-- | nscd/nscd_initgroups.c | 33 |
6 files changed, 131 insertions, 60 deletions
diff --git a/nscd/nscd_getai.c b/nscd/nscd_getai.c index 6a4476fa7c..e717dd85a0 100644 --- a/nscd/nscd_getai.c +++ b/nscd/nscd_getai.c @@ -49,19 +49,21 @@ int __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop) { size_t keylen = strlen (key) + 1; + int gc_cycle; + + /* If the mapping is available, try to search there instead of + communicating with the nscd. */ + struct mapped_database *mapped; + mapped = __nscd_get_map_ref (GETFDHST, "hosts", &map_handle, &gc_cycle); + + retry:; const ai_response_header *ai_resp = NULL; struct nscd_ai_result *resultbuf = NULL; const char *recend = (const char *) ~UINTMAX_C (0); char *respdata = NULL; int retval = -1; int sock = -1; - int gc_cycle; - /* If the mapping is available, try to search there instead of - communicating with the nscd. */ - struct mapped_database *mapped = __nscd_get_map_ref (GETFDHST, "hosts", - &map_handle, &gc_cycle); - retry: if (mapped != NO_MAPPING) { const struct datahead *found = __nscd_cache_search (GETAI, key, keylen, @@ -130,6 +132,11 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop) retval = 0; *result = resultbuf; } + else + { + free (resultbuf); + *h_errnop = NETDB_INTERNAL; + } } else { @@ -154,11 +161,22 @@ __nscd_getai (const char *key, struct nscd_ai_result **result, int *h_errnop) if (sock != -1) close_not_cancel_no_status (sock); out: - if (__nscd_drop_map_ref (mapped, gc_cycle) != 0) - /* When we come here this means there has been a GC cycle while we - were looking for the data. This means the data might have been - inconsistent. Retry. */ - goto retry; + if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1) + { + /* When we come here this means there has been a GC cycle while we + were looking for the data. This means the data might have been + inconsistent. Retry if possible. */ + if ((gc_cycle & 1) != 0) + { + /* nscd is just running gc now. Disable using the mapping. */ + __nscd_unmap (mapped); + mapped = NO_MAPPING; + } + + free (resultbuf); + + goto retry; + } return retval; } diff --git a/nscd/nscd_getgr_r.c b/nscd/nscd_getgr_r.c index 3a66bb849b..9e8170f0f2 100644 --- a/nscd/nscd_getgr_r.c +++ b/nscd/nscd_getgr_r.c @@ -18,6 +18,7 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ +#include <alloca.h> #include <assert.h> #include <errno.h> #include <grp.h> @@ -84,19 +85,21 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, struct group *resultbuf, char *buffer, size_t buflen, struct group **result) { - const gr_response_header *gr_resp = NULL; - const uint32_t *len = NULL; - const char *gr_name = NULL; - size_t gr_name_len = 0; - int retval = -1; int gc_cycle; - const char *recend = (const char *) ~UINTMAX_C (0); + const uint32_t *len = NULL; + size_t lensize = 0; /* If the mapping is available, try to search there instead of communicating with the nscd. */ struct mapped_database *mapped = __nscd_get_map_ref (GETFDGR, "group", &map_handle, &gc_cycle); - retry: + retry:; + const gr_response_header *gr_resp = NULL; + const char *gr_name = NULL; + size_t gr_name_len = 0; + int retval = -1; + const char *recend = (const char *) ~UINTMAX_C (0); + if (mapped != NO_MAPPING) { const struct datahead *found = __nscd_cache_search (type, key, keylen, @@ -176,10 +179,17 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, resultbuf->gr_gid = gr_resp->gr_gid; /* Read the length information, group name, and password. */ - if (len == NULL) + if (gr_name == NULL) { /* Allocate array to store lengths. */ - len = (uint32_t *) alloca (gr_resp->gr_mem_cnt * sizeof (uint32_t)); + if (lensize == 0) + { + lensize = gr_resp->gr_mem_cnt * sizeof (uint32_t); + len = (uint32_t *) alloca (lensize); + } + else if (gr_resp->gr_mem_cnt * sizeof (uint32_t) > lensize) + len = extend_alloca (len, lensize, + gr_resp->gr_mem_cnt * sizeof (uint32_t)); vec[0].iov_base = (void *) len; vec[0].iov_len = gr_resp->gr_mem_cnt * sizeof (uint32_t); @@ -248,11 +258,20 @@ nscd_getgr_r (const char *key, size_t keylen, request_type type, if (sock != -1) close_not_cancel_no_status (sock); out: - if (__nscd_drop_map_ref (mapped, gc_cycle) != 0) - /* When we come here this means there has been a GC cycle while we - were looking for the data. This means the data might have been - inconsistent. Retry. */ - goto retry; + if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1) + { + /* When we come here this means there has been a GC cycle while we + were looking for the data. This means the data might have been + inconsistent. Retry if possible. */ + if ((gc_cycle & 1) != 0) + { + /* nscd is just running gc now. Disable using the mapping. */ + __nscd_unmap (mapped); + mapped = NO_MAPPING; + } + + goto retry; + } return retval; } diff --git a/nscd/nscd_gethst_r.c b/nscd/nscd_gethst_r.c index 5bd5997de0..25553babf4 100644 --- a/nscd/nscd_gethst_r.c +++ b/nscd/nscd_gethst_r.c @@ -105,21 +105,23 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type, struct hostent *resultbuf, char *buffer, size_t buflen, struct hostent **result, int *h_errnop) { + int gc_cycle; + int nretries = 0; + + /* If the mapping is available, try to search there instead of + communicating with the nscd. */ + struct mapped_database *mapped; + mapped = __nscd_get_map_ref (GETFDHST, "hosts", &map_handle, &gc_cycle); + + retry:; const hst_response_header *hst_resp = NULL; const char *h_name = NULL; const uint32_t *aliases_len = NULL; const char *addr_list = NULL; size_t addr_list_len = 0; int retval = -1; - int gc_cycle; const char *recend = (const char *) ~UINTMAX_C (0); int sock = -1; - - /* If the mapping is available, try to search there instead of - communicating with the nscd. */ - struct mapped_database *mapped = __nscd_get_map_ref (GETFDHST, "hosts", - &map_handle, &gc_cycle); - retry: if (mapped != NO_MAPPING) { const struct datahead *found = __nscd_cache_search (type, key, keylen, @@ -354,11 +356,20 @@ nscd_gethst_r (const char *key, size_t keylen, request_type type, if (sock != -1) close_not_cancel_no_status (sock); out: - if (__nscd_drop_map_ref (mapped, gc_cycle) != 0) - /* When we come here this means there has been a GC cycle while we - were looking for the data. This means the data might have been - inconsistent. Retry. */ - goto retry; + if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1) + { + /* When we come here this means there has been a GC cycle while we + were looking for the data. This means the data might have been + inconsistent. Retry if possible. */ + if ((gc_cycle & 1) != 0 || ++nretries == 5) + { + /* nscd is just running gc now. Disable using the mapping. */ + __nscd_unmap (mapped); + mapped = NO_MAPPING; + } + + goto retry; + } return retval; } diff --git a/nscd/nscd_getpw_r.c b/nscd/nscd_getpw_r.c index 0d15a0cc3f..9af3858454 100644 --- a/nscd/nscd_getpw_r.c +++ b/nscd/nscd_getpw_r.c @@ -84,17 +84,18 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type, struct passwd *resultbuf, char *buffer, size_t buflen, struct passwd **result) { + int gc_cycle; + /* If the mapping is available, try to search there instead of + communicating with the nscd. */ + struct mapped_database *mapped; + mapped = __nscd_get_map_ref (GETFDPW, "passwd", &map_handle, &gc_cycle); + + retry:; const pw_response_header *pw_resp = NULL; const char *pw_name = NULL; int retval = -1; - int gc_cycle; const char *recend = (const char *) ~UINTMAX_C (0); - /* If the mapping is available, try to search there instead of - communicating with the nscd. */ - struct mapped_database *mapped = __nscd_get_map_ref (GETFDPW, "passwd", - &map_handle, &gc_cycle); - retry: if (mapped != NO_MAPPING) { const struct datahead *found = __nscd_cache_search (type, key, keylen, @@ -199,11 +200,22 @@ nscd_getpw_r (const char *key, size_t keylen, request_type type, if (sock != -1) close_not_cancel_no_status (sock); out: - if (__nscd_drop_map_ref (mapped, gc_cycle) != 0) - /* When we come here this means there has been a GC cycle while we - were looking for the data. This means the data might have been - inconsistent. Retry. */ - goto retry; + if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1) + { + /* When we come here this means there has been a GC cycle while we + were looking for the data. This means the data might have been + inconsistent. Retry if possible. */ + if ((gc_cycle & 1) != 0) + { + /* nscd is just running gc now. Disable using the mapping. */ + __nscd_unmap (mapped); + mapped = NO_MAPPING; + } + + free (resultbuf); + + goto retry; + } return retval; } diff --git a/nscd/nscd_helper.c b/nscd/nscd_helper.c index ae8dd6c91f..3c8693a93d 100644 --- a/nscd/nscd_helper.c +++ b/nscd/nscd_helper.c @@ -214,7 +214,7 @@ get_mapping (request_type type, const char *key, struct mapped_database * __nscd_get_map_ref (request_type type, const char *name, - struct locked_map_ptr *mapptr, volatile int *gc_cyclep) + struct locked_map_ptr *mapptr, int *gc_cyclep) { struct mapped_database *cur = mapptr->mapped; if (cur == NO_MAPPING) diff --git a/nscd/nscd_initgroups.c b/nscd/nscd_initgroups.c index 513d35d1e1..c33c76dfb3 100644 --- a/nscd/nscd_initgroups.c +++ b/nscd/nscd_initgroups.c @@ -46,17 +46,19 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size, gid_t **groupsp, long int limit) { size_t userlen = strlen (user) + 1; + int gc_cycle; + + /* If the mapping is available, try to search there instead of + communicating with the nscd. */ + struct mapped_database *mapped; + mapped = __nscd_get_map_ref (GETFDGR, "group", &map_handle, &gc_cycle); + + retry:; const initgr_response_header *initgr_resp = NULL; char *respdata = NULL; int retval = -1; int sock = -1; - int gc_cycle; - /* If the mapping is available, try to search there instead of - communicating with the nscd. */ - struct mapped_database *mapped = __nscd_get_map_ref (GETFDGR, "group", - &map_handle, &gc_cycle); - retry: if (mapped != NO_MAPPING) { const struct datahead *found = __nscd_cache_search (INITGROUPS, user, @@ -148,11 +150,20 @@ __nscd_getgrouplist (const char *user, gid_t group, long int *size, if (sock != -1) close_not_cancel_no_status (sock); out: - if (__nscd_drop_map_ref (mapped, gc_cycle) != 0) - /* When we come here this means there has been a GC cycle while we - were looking for the data. This means the data might have been - inconsistent. Retry. */ - goto retry; + if (__nscd_drop_map_ref (mapped, &gc_cycle) != 0 && retval != -1) + { + /* When we come here this means there has been a GC cycle while we + were looking for the data. This means the data might have been + inconsistent. Retry if possible. */ + if ((gc_cycle & 1) != 0) + { + /* nscd is just running gc now. Disable using the mapping. */ + __nscd_unmap (mapped); + mapped = NO_MAPPING; + } + + goto retry; + } return retval; } |