Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 29 Sep 2005 10:59:00 GMT
From:      soc-bushman <soc-bushman@FreeBSD.org>
To:        Perforce Change Reviews <perforce@freebsd.org>
Subject:   PERFORCE change 84475 for review
Message-ID:  <200509291059.j8TAx0MZ011170@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=84475

Change 84475 by soc-bushman@soc-bushman_stinger on 2005/09/29 10:58:33

	negative responses are now cached - client side needs to be modified to support this

Affected files ...

.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/Makefile#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.8#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf.5#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/hashtable.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.c#4 edit
.. //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.h#4 edit
.. //depot/projects/soc2005/nsswitch_cached/tests/nsdispatch_test/nsdispatch.c#8 edit

Differences ...

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/Makefile#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.8#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cached.conf.5#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.c#4 (text+ko) ====

@@ -61,7 +61,7 @@
 		int (*)(struct cache_common_entry_ *, 
 		struct cache_policy_item_ *));
 static int ht_items_cmp_func(const void *, const void *);
-static hashtable_index_t ht_item_hash_func(const void *);	
+static hashtable_index_t ht_item_hash_func(const void *, size_t);	
 		
 static int
 ht_items_cmp_func(const void *p1, const void *p2)
@@ -81,7 +81,7 @@
 }
 
 static hashtable_index_t 
-ht_item_hash_func(const void *p)
+ht_item_hash_func(const void *p, size_t cache_entries_size)
 {
     	struct cache_ht_item_data_ *hp;
 	size_t i;
@@ -93,7 +93,8 @@
 	
 	retval = 0;
 	for (i = 0; i < hp->key_size; ++i)
-	    retval = (127 * retval + (unsigned char)hp->key[i]) % CACHE_HT_SIZE;
+	    retval = (127 * retval + (unsigned char)hp->key[i]) % 
+		cache_entries_size;
 	
 	return retval;
 }
@@ -324,9 +325,10 @@
 		ht_key.key = item->key;
 		ht_key.key_size = item->key_size;
 
-		hash = HASHTABLE_CALCULATE_HASH(cache_ht_, &ht_key);
+		hash = HASHTABLE_CALCULATE_HASH(cache_ht_, &entry->items, 
+			&ht_key);
 		assert(hash >= 0);
-		assert(hash < CACHE_HT_SIZE);
+		assert(hash < HASHTABLE_ENTRIES_COUNT(&entry->items));
 					
 		ht_item = HASHTABLE_GET_ENTRY(&(entry->items), hash);
 		ht_item_data = HASHTABLE_ENTRY_FIND(cache_ht_, ht_item, &ht_key);
@@ -509,8 +511,11 @@
 		new_common_entry->name = new_common_entry->common_params.entry_name;
 		TRACE_STR(new_common_entry->name);
 		
+		TRACE_POINT();
 		HASHTABLE_INIT(&(new_common_entry->items), 
-			struct cache_ht_item_data_, data);
+			struct cache_ht_item_data_, data, 
+			new_common_entry->common_params.cache_entries_size);
+		TRACE_POINT();
 		
 		if (new_common_entry->common_params.policy == CPT_FIFO)
 			policies_size = 1;
@@ -648,9 +653,10 @@
 	item_data.key = (char *)key;
 	item_data.key_size = key_size;
 	
-	hash = HASHTABLE_CALCULATE_HASH(cache_ht_, &item_data);
+	hash = HASHTABLE_CALCULATE_HASH(cache_ht_, &common_entry->items, 
+		&item_data);
 	assert(hash >= 0);
-	assert(hash < CACHE_HT_SIZE);
+	assert(hash < HASHTABLE_ENTRIES_COUNT(&common_entry->items));
 		
 	item = HASHTABLE_GET_ENTRY(&(common_entry->items), hash);
 	find_res = HASHTABLE_ENTRY_FIND(cache_ht_, item, &item_data);
@@ -747,9 +753,10 @@
 	item_data.key = (char *)key;
 	item_data.key_size = key_size;
 	
-	hash = HASHTABLE_CALCULATE_HASH(cache_ht_, &item_data);
+	hash = HASHTABLE_CALCULATE_HASH(cache_ht_, &common_entry->items,
+		&item_data);
 	assert(hash >= 0);
-	assert(hash < CACHE_HT_SIZE);
+	assert(hash < HASHTABLE_ENTRIES_COUNT(&common_entry->items));
 		
 	item = HASHTABLE_GET_ENTRY(&(common_entry->items), hash);
 	find_res = HASHTABLE_ENTRY_FIND(cache_ht_, item, &item_data);

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cachelib.h#4 (text+ko) ====

@@ -34,8 +34,6 @@
 #include "hashtable.h"
 #include "cacheplcs.h"
 
-#define CACHE_HT_SIZE 257
-
 enum cache_entry_t	{ 
 	CET_COMMON = 0,	/* cache item is atomic */
 	CET_MULTIPART	/* cache item is formed part by part */
@@ -86,6 +84,8 @@
 
 	/* unique fields */
 	char	*entry_name;
+	size_t	cache_entries_size;
+	
 	size_t	max_elemsize;		/* if 0 then no check is made */
 	size_t	satisf_elemsize;	
 	struct timeval	max_lifetime;	/* if 0 then no check is made */
@@ -136,7 +136,7 @@
 		
 	struct common_cache_entry_params common_params;
 		
-	HASHTABLE_HEAD(cache_ht_, cache_ht_item_, CACHE_HT_SIZE) items;
+	HASHTABLE_HEAD(cache_ht_, cache_ht_item_) items;
 	size_t items_size;
 	
 	struct cache_policy_ ** policies;

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/cacheplcs.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.c#4 (text+ko) ====

@@ -49,18 +49,6 @@
 static int configuration_entry_cmp(const void *, const void *);
 static struct configuration_entry *create_configuration_entry(const char *,
 	uid_t, int, struct timeval const *, struct cache_entry_params const *);
-/*static void destroy_configuration_entry(struct configuration_entry *);
-static int add_configuration_entry(struct configuration *,
-	struct configuration_entry *);*/
-		
-/*static int process_root_parser_pair(struct configuration *, 
-	struct parser_pair_ *, char const **, int *);
-static int process_parser_common_group_pair(struct common_cache_entry_params *, 
-	struct parser_pair_ *, char const **, int *);
-static int process_parser_mp_group_pair(struct mp_cache_entry_params *, 
-	struct parser_pair_ *, char const **, int *);
-static int process_parser_group(struct configuration *, 
-	struct parser_group_ *, char const **, int *);*/
 
 static int
 configuration_entry_cmp(const void *e1, const void *e2)
@@ -183,6 +171,7 @@
 			sizeof(struct common_cache_entry_params));
 		common_params.entry_type = CET_COMMON;
 		common_params.entry_name = (char *)name;
+		common_params.cache_entries_size = DEFAULT_CACHE_HT_SIZE;
 		common_params.max_elemsize = 2048;
 		common_params.satisf_elemsize = 1024;
 		common_params.max_lifetime.tv_sec = 60 * 60 * 12;

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/config.h#4 (text+ko) ====

@@ -37,6 +37,7 @@
 
 #define DEFAULT_COMMON_ENTRY_TIMEOUT	10
 #define DEFAULT_MP_ENTRY_TIMEOUT	60
+#define DEFAULT_CACHE_HT_SIZE		257
 
 extern const char *c_default_entries[6];
 

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/debug.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/hashtable.h#4 (text+ko) ====

@@ -40,16 +40,21 @@
 	size_t size;							\
 }
 
-#define HASHTABLE_HEAD(name, entry, size) struct name {			\
-	struct entry entries[size];					\
+#define HASHTABLE_HEAD(name, entry) struct name {			\
+	struct entry	*entries;					\
+	size_t		entries_size;					\
 }
 
-#define HASHTABLE_ENTRIES_COUNT(table) ((sizeof(*(table))) / 		\
-	(sizeof(*((table)->entries))))
+#define HASHTABLE_ENTRIES_COUNT(table) ((table)->entries_size)
 
-#define HASHTABLE_INIT(table, type, field)				\
+#define HASHTABLE_INIT(table, type, field, _entries_size)		\
 	do {								\
 		hashtable_index_t var;					\
+		(table)->entries = (void *)malloc(			\
+			sizeof(*(table)->entries) * (_entries_size));	\
+		memset((table)->entries, 0, 				\
+			sizeof(*(table)->entries) * (_entries_size));	\
+		(table)->entries_size = (_entries_size);		\
 		for (var = 0; var < HASHTABLE_ENTRIES_COUNT(table); ++var) {\
 			(table)->entries[var].field.capacity = 		\
 				HASHTABLE_INITIAL_ENTRIES_CAPACITY;	\
@@ -101,15 +106,15 @@
 		(entry)->field.capacity * sizeof(type));
 
 #define HASHTABLE_PROTOTYPE(name, entry_, type)				\
-hashtable_index_t name##_CALCULATE_HASH(type *);			\
+hashtable_index_t name##_CALCULATE_HASH(struct name *, type *);		\
 void name##_ENTRY_STORE(struct entry_*, type *);			\
 type *name##_ENTRY_FIND(struct entry_*, type *);			\
 void name##_ENTRY_REMOVE(struct entry_*, type *);			\
 
 #define HASHTABLE_GENERATE(name, entry_, type, field, HASH, CMP)	\
-hashtable_index_t name##_CALCULATE_HASH(type *data)			\
+hashtable_index_t name##_CALCULATE_HASH(struct name *table, type *data)	\
 {									\
-	return HASH(data);						\
+	return HASH(data, table->entries_size);				\
 }									\
 									\
 void name##_ENTRY_STORE(struct entry_ *the_entry, type *data)		\
@@ -137,8 +142,8 @@
 			sizeof(type));					\
 }
 
-#define HASHTABLE_CALCULATE_HASH(name, data)				\
-	(name##_CALCULATE_HASH(data))
+#define HASHTABLE_CALCULATE_HASH(name, table, data)			\
+	(name##_CALCULATE_HASH((table), data))
 
 #define HASHTABLE_ENTRY_STORE(name, entry, data)			\
 	name##_ENTRY_STORE((entry), data)

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/log.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_rs_query.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/mp_ws_query.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.c#4 (text+ko) ====

@@ -60,7 +60,7 @@
 static void set_positive_time_to_live(struct configuration *,
 	const char *, int);
 static void set_suggested_size(struct configuration *, const char *, 
-	enum cache_policy_t);
+	int size);
 static int strbreak(char *, char **, int);
 
 static int
@@ -291,9 +291,27 @@
 
 static void
 set_suggested_size(struct configuration *config,
-	const char *entry_name, enum cache_policy_t policy)
+	const char *entry_name, int size)
 {
+	struct configuration_entry	*entry;
+	
 	TRACE_IN(set_suggested_size);
+	assert(config != NULL);
+	assert(entry_name != NULL);
+	assert(size > 0);
+	
+	entry = find_create_entry(config, entry_name, EUT_COMMON);
+	assert(entry != NULL);
+	assert(entry->c_params->entry_type == CET_COMMON);
+	((struct common_cache_entry_params *)
+			entry->c_params)->cache_entries_size = size;
+	
+	entry = find_create_entry(config, entry_name, EUT_NEGATIVE);
+	assert(entry != NULL);
+	assert(entry->c_params->entry_type == CET_COMMON);
+	((struct common_cache_entry_params *)
+			entry->c_params)->cache_entries_size = size;
+	
 	TRACE_OUT(set_suggested_size);
 }
 
@@ -457,7 +475,7 @@
 			if ((field_count == 3) &&
 			(strcmp(fields[0], "set-suggested-size") == 0) &&
 			(check_cachename(fields[1]) == 0) &&
-			((value = get_number(fields[2], 0, -1)) != -1)) {
+			((value = get_number(fields[2], 1, -1)) != -1)) {
 				set_suggested_size(config, fields[1], value);
 				continue;
 			}

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/parser.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/protocol.h#4 (text+ko) ====

@@ -50,7 +50,7 @@
 
 struct cache_write_response
 {
-	int		error_code;
+	int	error_code;
 };
 
 struct cache_read_request
@@ -67,7 +67,7 @@
 	char	*data;			// ignored if error_code is not 0
 	size_t	data_size;		// ignored if error_code is not 0
 
-	int		error_code;
+	int	error_code;
 };
 
 struct cache_transform_request
@@ -75,12 +75,12 @@
 	char	*entry; 		// ignored if entry_length is 0
 	size_t	entry_length;
 
-	int		transformation_type;
+	int	transformation_type;
 };
 
 struct cache_transform_response
 {
-	int		error_code;
+	int	error_code;
 };
 
 struct cache_mp_write_session_request {
@@ -89,7 +89,7 @@
 };
 
 struct cache_mp_write_session_response {
-	int		error_code;
+	int	error_code;
 };
 
 struct cache_mp_write_session_write_request {
@@ -98,7 +98,7 @@
 };
 
 struct cache_mp_write_session_write_response {
-	int		error_code;
+	int	error_code;
 };
 
 struct cache_mp_read_session_request {
@@ -107,14 +107,14 @@
 };
 
 struct cache_mp_read_session_response {
-	int		error_code;
+	int	error_code;
 };
 
 struct cache_mp_read_session_read_response {
 	char	*data;
 	size_t	data_size;
 
-	int		error_code;	
+	int	error_code;	
 };
 
 

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.c#4 (text+ko) ====

@@ -43,6 +43,8 @@
 #include "mp_rs_query.h"
 #include "singletons.h"
 
+static const char negative_data[1] = { 0 };
+
 extern	void get_time_func(struct timeval *);
 
 static	int on_query_startup(struct query_state *);
@@ -60,6 +62,7 @@
 
 static	int on_write_request_read1(struct query_state *);
 static	int on_write_request_read2(struct query_state *);
+static	int on_negative_write_request_process(struct query_state *);
 static	int on_write_request_process(struct query_state *);
 static	int on_write_response_write1(struct query_state *);
 	
@@ -220,7 +223,8 @@
 		
 		if (BUFSIZE_INVALID(write_request->entry_length) ||
 			BUFSIZE_INVALID(write_request->cache_key_size) ||
-			BUFSIZE_INVALID(write_request->data_size)) {
+			(BUFSIZE_INVALID(write_request->data_size) &&
+			(write_request->data_size != 0))) {
 			TRACE_OUT(on_write_request_read1);
 			return (-1);
 		}
@@ -239,9 +243,13 @@
 		memset(write_request->cache_key + qstate->eid_str_length, 0, 
 			write_request->cache_key_size);
 		
-		write_request->data = (char *)malloc(write_request->data_size);
-		assert(write_request->data != NULL);
-		memset(write_request->data, 0, write_request->data_size);
+		if (write_request->data_size != 0) {
+			write_request->data = (char *)malloc(
+				write_request->data_size);
+			assert(write_request->data != NULL);
+			memset(write_request->data, 0, 
+				write_request->data_size);
+		}
 
 		qstate->kevent_watermark = write_request->entry_length +
 			write_request->cache_key_size + 
@@ -266,8 +274,9 @@
 		write_request->entry_length);
 	result += qstate->read_func(qstate, write_request->cache_key + 
 		qstate->eid_str_length, write_request->cache_key_size);
-	result += qstate->read_func(qstate, write_request->data, 
-		write_request->data_size);
+	if (write_request->data_size != 0)
+		result += qstate->read_func(qstate, write_request->data, 
+			write_request->data_size);
 	
 	if (result != qstate->kevent_watermark) {
 		TRACE_INT(result);
@@ -277,7 +286,10 @@
 	write_request->cache_key_size += qstate->eid_str_length;
 	
 	qstate->kevent_watermark = 0;
-	qstate->process_func = on_write_request_process;
+	if (write_request->data_size != 0) 
+		qstate->process_func = on_write_request_process;
+	else
+	    	qstate->process_func = on_negative_write_request_process;
 	TRACE_OUT(on_write_request_read2);
 	return (0);
 }
@@ -329,13 +341,14 @@
 	    		write_request->cache_key_size,
 	    		write_request->data, 
 			write_request->data_size);
-		configuration_unlock_entry(qstate->config_entry);
-		
+
 		if ((qstate->config_entry->query_timeout.tv_sec != 0) || 
 			(qstate->config_entry->query_timeout.tv_usec != 0))
 			memcpy(&qstate->timeout, 
 				&qstate->config_entry->query_timeout, 
 				sizeof(struct timeval));
+		configuration_unlock_entry(qstate->config_entry);
+		
 	} else {
 		TRACE_POINT();
 		write_response->error_code = -1;
@@ -351,6 +364,70 @@
 }
 
 static int
+on_negative_write_request_process(struct query_state *qstate)
+{
+	struct cache_write_request	*write_request;
+	struct cache_write_response	*write_response;
+	cache_entry c_entry;
+	char *neg_entry_name;
+	
+	TRACE_IN(on_negative_write_request_process);
+	init_comm_element(&qstate->response, CET_WRITE_RESPONSE);
+	write_response = get_cache_write_response(&qstate->response);
+	write_request = get_cache_write_request(&qstate->request);	
+	
+	asprintf(&neg_entry_name, "%s_neg", write_request->entry);
+	assert(neg_entry_name != NULL);
+	qstate->config_entry = find_config_entry_by_name_and_euid(
+		s_configuration, neg_entry_name, qstate->euid);	
+	free(neg_entry_name);
+	
+	if (qstate->config_entry == NULL) {
+		TRACE_MSG("can't find corresponding configuration"
+		    " entry. aborting request");
+		TRACE_OUT(on_negative_write_request_process);
+		return (-1);
+	}
+	
+	if (qstate->config_entry->perform_actual_lookups != 0) {
+		TRACE_MSG(
+			"entry performs lookups by itself: can't write to it");
+		TRACE_OUT(on_negative_write_request_process);
+		return (-1);
+	}	
+	
+	configuration_lock_rdlock(s_configuration);
+	c_entry = find_cache_entry(s_cache, 
+    		qstate->config_entry->c_params->entry_name);	
+	configuration_unlock(s_configuration);
+	if (c_entry != NULL) {
+		//TRACE_STR(write_request->cache_key);
+		configuration_lock_entry(qstate->config_entry);
+		write_response->error_code = cache_write(c_entry, 
+			write_request->cache_key, 
+	    		write_request->cache_key_size,
+	    		negative_data, 
+			sizeof(negative_data));
+
+		if ((qstate->config_entry->query_timeout.tv_sec != 0) || 
+			(qstate->config_entry->query_timeout.tv_usec != 0))
+			memcpy(&qstate->timeout, 
+				&qstate->config_entry->query_timeout, 
+				sizeof(struct timeval));
+		configuration_unlock_entry(qstate->config_entry);		
+	} else {
+		TRACE_POINT();
+		write_response->error_code = -1;
+	}
+	
+	qstate->kevent_filter = EVFILT_WRITE;
+	qstate->kevent_watermark = sizeof(int);
+	qstate->process_func = on_write_response_write1;
+	TRACE_OUT(on_negative_write_request_process);
+	return (0);
+}
+
+static int
 on_write_response_write1(struct query_state *qstate)
 {
 	struct cache_write_response	*write_response;
@@ -460,9 +537,12 @@
 static int
 on_read_request_process(struct query_state *qstate)
 {		
+	struct configuration_entry *neg_entry, *timeout_entry;
+	char	*neg_entry_name;
+	
 	struct cache_read_request *read_request;
 	struct cache_read_response *read_response;
-	cache_entry	c_entry;
+	cache_entry	c_entry, neg_c_entry;
 	struct agent	*lookup_agent;
 	
 	TRACE_IN(on_read_request_process);
@@ -480,18 +560,33 @@
 	if (qstate->config_entry == NULL) {
 		TRACE_MSG("can't find corresponding configuration "
 	    		"entry. aborting request");
-		TRACE_OUT(on_write_request_process);
+		TRACE_OUT(on_read_request_process);
 		return (-1);
 	}
+	
+	asprintf(&neg_entry_name, "%s_neg", read_request->entry);
+	assert(neg_entry_name != NULL);
+	neg_entry = find_config_entry_by_name_and_euid(
+		s_configuration, neg_entry_name, qstate->euid);
+	free(neg_entry_name);
+	if (neg_entry == NULL) {
+		TRACE_MSG("can't find corresponding configuration "
+	    		"entry. aborting request");
+		TRACE_OUT(on_read_request_process);
+		return (-1);		
+	}
 
 	configuration_lock_rdlock(s_configuration);
 	c_entry = find_cache_entry(s_cache, 
     		qstate->config_entry->c_params->entry_name);	
+	neg_c_entry = find_cache_entry(s_cache, 
+		neg_entry->c_params->entry_name);
 	configuration_unlock(s_configuration);
-	if (c_entry != NULL) {
+	if ((c_entry != NULL) && (neg_c_entry != NULL)) {
 		TRACE_POINT();
 		//TRACE_STR(read_request->cache_key);
-		configuration_lock_entry(qstate->config_entry);
+		timeout_entry = qstate->config_entry;
+		configuration_lock_entry(qstate->config_entry);		
 		read_response->error_code = cache_read(c_entry, 
 	    		read_request->cache_key,
 	    		read_request->cache_key_size, NULL, 
@@ -508,9 +603,26 @@
 		    		read_response->data, 
 		    		&read_response->data_size);
 		}
+		configuration_unlock_entry(qstate->config_entry);
 		
-		if ((read_response->error_code == -1) 
-		    && (qstate->config_entry->perform_actual_lookups != 0)){
+		configuration_lock_entry(neg_entry);
+		if (read_response->error_code == -1) {
+			read_response->error_code = cache_read(neg_c_entry,
+				read_request->cache_key,
+				read_request->cache_key_size, NULL,
+				&read_response->data_size);
+			
+			if (read_response->error_code == -2) {
+				timeout_entry = neg_entry;
+				read_response->error_code = 0;
+				read_response->data = NULL;
+				read_response->data_size = 0;
+			}
+		}
+		configuration_unlock_entry(neg_entry);
+		
+		if ((read_response->error_code == -1) && 
+			(qstate->config_entry->perform_actual_lookups != 0)) {
 			free(read_response->data);
 			read_response->data = NULL;
 			read_response->data_size = 0;
@@ -532,21 +644,37 @@
 				
 				if (res == NS_SUCCESS) {
 					read_response->error_code = 0;
+					configuration_lock_entry(qstate->config_entry);
 					cache_write(c_entry, 
 						read_request->cache_key, 
 	    					read_request->cache_key_size,
 	    					read_response->data, 
 						read_response->data_size);
+					configuration_unlock_entry(qstate->config_entry);
+				} else if (res & NS_TERMINATE) {
+					configuration_lock_entry(neg_entry);
+					cache_write(neg_c_entry,
+						read_request->cache_key,
+						read_request->cache_key_size,
+						negative_data,
+						sizeof(negative_data));
+					configuration_unlock_entry(neg_entry);
+					
+					timeout_entry = neg_entry;
+					read_response->error_code = 0;
+					read_response->data = NULL;
+					read_response->data_size = 0;
 				}
 			}						
 		}
-		configuration_unlock_entry(qstate->config_entry);
-		
+
+		configuration_lock_entry(timeout_entry);
 		if ((qstate->config_entry->query_timeout.tv_sec != 0) || 
 			(qstate->config_entry->query_timeout.tv_usec != 0))
 			memcpy(&qstate->timeout, 
 				&qstate->config_entry->query_timeout, 
 				sizeof(struct timeval));
+		configuration_unlock_entry(timeout_entry);
 	} else {
 		TRACE_POINT();
 		read_response->error_code = -1;
@@ -614,8 +742,9 @@
 	
 	TRACE_IN(on_read_response_write2);
 	read_response = get_cache_read_response(&qstate->response);
-	result = qstate->write_func(qstate, read_response->data, 
-		read_response->data_size);
+	if (read_response->data_size > 0)
+		result = qstate->write_func(qstate, read_response->data, 
+			read_response->data_size);
 	if (result != qstate->kevent_watermark) {
 		TRACE_POINT();
 		TRACE_OUT(on_read_response_write2);

==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/query.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.c#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/release/cached-0.2/cached/singletons.h#4 (text+ko) ====


==== //depot/projects/soc2005/nsswitch_cached/tests/nsdispatch_test/nsdispatch.c#8 (text+ko) ====

@@ -696,7 +696,7 @@
 				result = nss_mp_cache_write_submit(retval, 
 			    		cache_data_p, ap);
 			} else {
-				result = nss_common_cache_write_negative(cache_data_p);
+//				result = nss_common_cache_write_negative(cache_data_p);
 			}
 		}
 		va_end(ap);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200509291059.j8TAx0MZ011170>