[SCM] Samba Shared Repository - branch v3-3-test updated - release-3-2-0pre2-2744-g2a689aa

Volker Lendecke vlendec at samba.org
Sat Jun 7 06:33:37 GMT 2008


The branch, v3-3-test has been updated
       via  2a689aa66af1de3d2e0d08b51e33e9a7015d6cb7 (commit)
       via  097446c3c82c42ca4a7909201119c0cf431321ba (commit)
       via  f7f912a478af64b07beeb58673b605da0c46db94 (commit)
       via  8765eb8ad7bb978d3bb9c9ff8e557791fdc43009 (commit)
      from  516a067016955938988ab37c777102a14b41e100 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-3-test


- Log -----------------------------------------------------------------
commit 2a689aa66af1de3d2e0d08b51e33e9a7015d6cb7
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jun 5 09:36:34 2008 +0200

    Fix a crash in add_failed_connection_entry

commit 097446c3c82c42ca4a7909201119c0cf431321ba
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jun 5 09:36:13 2008 +0200

    Add prototype for delete_negative_conn_cache

commit f7f912a478af64b07beeb58673b605da0c46db94
Author: Volker Lendecke <vl at samba.org>
Date:   Thu Jun 5 09:00:37 2008 +0200

    Make the gencache based conncache use talloc_tos()

commit 8765eb8ad7bb978d3bb9c9ff8e557791fdc43009
Author: Marc VanHeyningen <marc.vanheyningen at isilon.com>
Date:   Wed Jun 4 15:22:50 2008 -0700

    Negative conn cache uses gencache

-----------------------------------------------------------------------

Summary of changes:
 source/include/proto.h    |    1 +
 source/libsmb/conncache.c |  325 +++++++++++++++++++++++++++------------------
 2 files changed, 196 insertions(+), 130 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source/include/proto.h b/source/include/proto.h
index 582300b..dfde0c7 100644
--- a/source/include/proto.h
+++ b/source/include/proto.h
@@ -4747,6 +4747,7 @@ bool cli_receive_nt_trans(struct cli_state *cli,
 NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout );
 NTSTATUS check_negative_conn_cache( const char *domain, const char *server);
 void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) ;
+void delete_negative_conn_cache(const char *domain, const char *server);
 void flush_negative_conn_cache( void );
 void flush_negative_conn_cache_for_domain(const char *domain);
 
diff --git a/source/libsmb/conncache.c b/source/libsmb/conncache.c
index c4a8762..05344f4 100644
--- a/source/libsmb/conncache.c
+++ b/source/libsmb/conncache.c
@@ -6,6 +6,7 @@
    Copyright (C) Tim Potter 		2001
    Copyright (C) Andrew Bartlett 	2002
    Copyright (C) Gerald (Jerry) Carter 	2003
+   Copyright (C) Marc VanHeyningen      2008
    
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
@@ -24,168 +25,232 @@
 
 #include "includes.h"
 
-#define CONNCACHE_ADDR		1
-#define CONNCACHE_NAME		2
-
-/* cache entry contains either a server name **or** and IP address as 
-   the key.  This means that a server could have two entries (one for each key) */
-   
-struct failed_connection_cache {
-	fstring 	domain_name;
-	fstring 	controller;
-	time_t 		lookup_time;
-	NTSTATUS 	nt_status;
-	struct failed_connection_cache *prev, *next;
-};
-
-static struct failed_connection_cache *failed_connection_cache;
-
-/**********************************************************************
- Check for a previously failed connection.
- failed_cache_timeout is an a absolute number of seconds after which
- we should time this out. If failed_cache_timeout == 0 then time out
- immediately. If failed_cache_timeout == -1 then never time out.
-**********************************************************************/
-
-NTSTATUS check_negative_conn_cache_timeout( const char *domain, const char *server, unsigned int failed_cache_timeout )
+/**
+ * @file
+ * Negative connection cache implemented in terms of gencache API
+ *
+ * The negative connection cache stores names of servers which have
+ * been unresponsive so that we don't waste time repeatedly trying
+ * to contact them.  It used to use an in-memory linked list, but
+ * this limited its utility to a single process
+ */
+
+
+/**
+ * prefix used for all entries put into the general cache
+ */
+static const char NEGATIVE_CONN_CACHE_PREFIX[] = "NEG_CONN_CACHE";
+
+/**
+ * Marshalls the domain and server name into the key for the gencache
+ * record
+ *
+ * @param[in] domain required
+ * @param[in] server may be a FQDN or an IP address
+ * @return the resulting string, which the caller is responsible for
+ *   SAFE_FREE()ing
+ * @retval NULL returned on error
+ */
+static char *negative_conn_cache_keystr(const char *domain, const char *server)
 {
-	struct failed_connection_cache *fcc;
-	NTSTATUS result = NT_STATUS_UNSUCCESSFUL;
-	
-	/* can't check if we don't have strings */
-	
-	if ( !domain || !server )
-		return NT_STATUS_OK;
+	const char NEGATIVE_CONN_CACHE_KEY_FMT[] = "%s/%s,%s";
+	char *keystr = NULL;
 
-	for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {
-	
-		if (!(strequal(domain, fcc->domain_name) && strequal(server, fcc->controller))) {
-			continue; /* no match; check the next entry */
-		}
-		
-		/* we have a match so see if it is still current */
-		if (failed_cache_timeout != (unsigned int)-1) {
-			if (failed_cache_timeout == 0 ||
-					(time(NULL) - fcc->lookup_time) > (time_t)failed_cache_timeout) {
-				/* Cache entry has expired, delete it */
+	SMB_ASSERT(domain != NULL);
+	if (server == NULL)
+		server = "";
 
-				DEBUG(10, ("check_negative_conn_cache: cache entry expired for %s, %s\n", 
-					domain, server ));
+	keystr = talloc_asprintf(talloc_tos(),NEGATIVE_CONN_CACHE_KEY_FMT,
+				 NEGATIVE_CONN_CACHE_PREFIX, domain, server);
+	if (keystr == NULL) {
+		DEBUG(0, ("negative_conn_cache_keystr: malloc error\n"));
+	}
 
-				DLIST_REMOVE(failed_connection_cache, fcc);
-				SAFE_FREE(fcc);
+	return keystr;
+}
 
-				return NT_STATUS_OK;
-			}
-		}
+/**
+ * Marshalls the NT status into a printable value field for the gencache
+ * record
+ *
+ * @param[in] status
+ * @return the resulting string, which the caller is responsible for
+ *   SAFE_FREE()ing
+ * @retval NULL returned on error
+ */
+static char *negative_conn_cache_valuestr(NTSTATUS status)
+{
+	char *valuestr = NULL;
 
-		/* The timeout hasn't expired yet so return false */
+	valuestr = talloc_asprintf(talloc_tos(), "%x", NT_STATUS_V(status));
+	if (valuestr == NULL) {
+		DEBUG(0, ("negative_conn_cache_valuestr: malloc error\n"));
+	}
 
-		DEBUG(10, ("check_negative_conn_cache: returning negative entry for %s, %s\n", 
-			domain, server ));
+	return valuestr;
+}
 
-		result = fcc->nt_status;
-		return result;
-	}
+/**
+ * Un-marshalls the NT status from a printable field for the gencache
+ * record
+ *
+ * @param[in] value  The value field from the record
+ * @return the decoded NT status
+ * @retval NT_STATUS_OK returned on error
+ */
+static NTSTATUS negative_conn_cache_valuedecode(const char *value)
+{
+	NTSTATUS result = NT_STATUS_OK;
 
-	/* end of function means no cache entry */	
-	return NT_STATUS_OK;
+	SMB_ASSERT(value != NULL);
+	if (sscanf(value, "%x", &(NT_STATUS_V(result))) != 1)
+		DEBUG(0, ("negative_conn_cache_valuestr: unable to parse "
+			  "value field '%s'\n", value));
+	return result;
+}
+
+/**
+ * Function passed to gencache_iterate to remove any matching items
+ * from the list
+ *
+ * @param[in] key Key to the record found and to be deleted
+ * @param[in] value Value to the record (ignored)
+ * @param[in] timeout Timeout remaining for the record (ignored)
+ * @param[in] dptr Handle for passing additional data (ignored)
+ */
+static void delete_matches(const char *key, const char *value,
+    time_t timeout, void *dptr)
+{
+	gencache_del(key);
 }
 
+
+/**
+ * Checks for a given domain/server record in the negative cache
+ *
+ * @param[in] domain
+ * @param[in] server may be either a FQDN or an IP address
+ * @return The cached failure status
+ * @retval NT_STATUS_OK returned if no record is found or an error occurs
+ */
 NTSTATUS check_negative_conn_cache( const char *domain, const char *server)
 {
-	return check_negative_conn_cache_timeout(domain, server, FAILED_CONNECTION_CACHE_TIMEOUT);
+	NTSTATUS result = NT_STATUS_OK;
+	char *key = NULL;
+	char *value = NULL;
+
+	key = negative_conn_cache_keystr(domain, server);
+	if (key == NULL)
+		goto done;
+
+	if (gencache_get(key, &value, (time_t *) NULL))
+		result = negative_conn_cache_valuedecode(value);
+ done:
+	DEBUG(9,("check_negative_conn_cache returning result %d for domain %s "
+		  "server %s\n", NT_STATUS_V(result), domain, server));
+	TALLOC_FREE(key);
+	SAFE_FREE(value);
+	return result;
+}
+
+/**
+ * Delete any negative cache entry for the given domain/server
+ *
+ * @param[in] domain
+ * @param[in] server may be either a FQDN or an IP address
+ */
+void delete_negative_conn_cache(const char *domain, const char *server)
+{
+	char *key = NULL;
+
+	key = negative_conn_cache_keystr(domain, server);
+	if (key == NULL)
+		goto done;
+
+	gencache_del(key);
+	DEBUG(9,("delete_negative_conn_cache removing domain %s server %s\n",
+		  domain, server));
+ done:
+	TALLOC_FREE(key);
+	return;
 }
 
-/**********************************************************************
- Add an entry to the failed conneciton cache (aither a name of dotted 
- decimal IP
-**********************************************************************/
 
-void add_failed_connection_entry(const char *domain, const char *server, NTSTATUS result) 
+/**
+ * Add an entry to the failed conneciton cache
+ *
+ * @param[in] domain
+ * @param[in] server may be a FQDN or an IP addr in printable form
+ * @param[in] result error to cache; must not be NT_STATUS_OK
+ */
+void add_failed_connection_entry(const char *domain, const char *server,
+    NTSTATUS result)
 {
-	struct failed_connection_cache *fcc;
+	char *key = NULL;
+	char *value = NULL;
 
 	SMB_ASSERT(!NT_STATUS_IS_OK(result));
 
-	/* Check we already aren't in the cache.  We always have to have 
-	   a domain, but maybe not a specific DC name. */
-
-	for (fcc = failed_connection_cache; fcc; fcc = fcc->next) {			
-		if ( strequal(fcc->domain_name, domain) && strequal(fcc->controller, server) ) {
-			DEBUG(10, ("add_failed_connection_entry: domain %s (%s) already tried and failed\n",
-				   domain, server ));
-			/* Update the failed time. */
-			fcc->lookup_time = time(NULL);
-			return;
-		}
+	key = negative_conn_cache_keystr(domain, server);
+	if (key == NULL) {
+		DEBUG(0, ("add_failed_connection_entry: key creation error\n"));
+		goto done;
 	}
 
-	/* Create negative lookup cache entry for this domain and controller */
-
-	if ( !(fcc = SMB_MALLOC_P(struct failed_connection_cache)) ) {
-		DEBUG(0, ("malloc failed in add_failed_connection_entry!\n"));
-		return;
+	value = negative_conn_cache_valuestr(result);
+	if (value == NULL) {
+		DEBUG(0, ("add_failed_connection_entry: value creation error\n"));
+		goto done;
 	}
+
+	if (gencache_set(key, value,
+			 time((time_t *) NULL)
+			 + FAILED_CONNECTION_CACHE_TIMEOUT))
+		DEBUG(9,("add_failed_connection_entry: added domain %s (%s) "
+			  "to failed conn cache\n", domain, server ));
+	else
+		DEBUG(1,("add_failed_connection_entry: failed to add "
+			  "domain %s (%s) to failed conn cache\n",
+			  domain, server));
 	
-	ZERO_STRUCTP(fcc);
-	
-	fstrcpy( fcc->domain_name, domain );
-	fstrcpy( fcc->controller, server );
-	fcc->lookup_time = time(NULL);
-	fcc->nt_status = result;
-	
-	DEBUG(10,("add_failed_connection_entry: added domain %s (%s) to failed conn cache\n",
-		domain, server ));
-	
-	DLIST_ADD(failed_connection_cache, fcc);
+ done:
+	TALLOC_FREE(key);
+	TALLOC_FREE(value);
+	return;
 }
 
-/****************************************************************************
-****************************************************************************/
- 
+/**
+ * Deletes all records from the negative connection cache in all domains
+ */
 void flush_negative_conn_cache( void )
 {
-	struct failed_connection_cache *fcc;
-	
-	fcc = failed_connection_cache;
-
-	while (fcc) {
-		struct failed_connection_cache *fcc_next;
-
-		fcc_next = fcc->next;
-		DLIST_REMOVE(failed_connection_cache, fcc);
-		free(fcc);
-
-		fcc = fcc_next;
-	}
-
+	flush_negative_conn_cache_for_domain("*");
 }
 
-/****************************************************************************
- Remove all negative entries for a domain. Used when going to online state in
- winbindd.
-****************************************************************************/
- 
+
+/**
+ * Deletes all records for a specified domain from the negative connection
+ * cache
+ *
+ * @param[in] domain String to match against domain portion of keys, or "*"
+ *  to match all domains
+ */
 void flush_negative_conn_cache_for_domain(const char *domain)
 {
-	struct failed_connection_cache *fcc;
-	
-	fcc = failed_connection_cache;
-
-	while (fcc) {
-		struct failed_connection_cache *fcc_next;
+	char *key_pattern = NULL;
 
-		fcc_next = fcc->next;
-
-		if (strequal(fcc->domain_name, domain)) {
-			DEBUG(10,("flush_negative_conn_cache_for_domain: removed server %s "
-				" from failed cache for domain %s\n",
-				fcc->controller, domain));
-			DLIST_REMOVE(failed_connection_cache, fcc);
-			free(fcc);
-		}
-
-		fcc = fcc_next;
+	key_pattern = negative_conn_cache_keystr(domain,"*");
+	if (key_pattern == NULL) {
+		DEBUG(0, ("flush_negative_conn_cache_for_domain: "
+			  "key creation error\n"));
+		goto done;
 	}
+
+	gencache_iterate(delete_matches, (void *) NULL, key_pattern);
+	DEBUG(8, ("flush_negative_conn_cache_for_domain: flushed domain %s\n",
+		  domain));
+	
+ done:
+	TALLOC_FREE(key_pattern);
+	return;
 }


-- 
Samba Shared Repository


More information about the samba-cvs mailing list