[SCM] Samba Shared Repository - branch master updated

Volker Lendecke vlendec at samba.org
Wed Mar 24 01:57:56 MDT 2010


The branch, master has been updated
       via  fbdcaa9... s3: Optimize gencache for smbd exit
      from  a599319... libreplace: fixed declaration of dprintf() on FreeBSD

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit fbdcaa929c7270469cf6c31fd6fcf94ce4e7306e
Author: Volker Lendecke <vl at samba.org>
Date:   Tue Mar 23 18:36:55 2010 +0100

    s3: Optimize gencache for smbd exit
    
    If thousands of smbds try to gencache_stabilize at the same time because the
    network died, all of them might be sitting in transaction_start. Don't do the
    stabilize transaction if nothing has changed in gencache_notrans.tdb.
    
    Volker

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

Summary of changes:
 source3/lib/gencache.c |   89 ++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 75 insertions(+), 14 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source3/lib/gencache.c b/source3/lib/gencache.c
index 9a4cbc2..577ff12 100644
--- a/source3/lib/gencache.c
+++ b/source3/lib/gencache.c
@@ -40,6 +40,13 @@ static struct tdb_context *cache_notrans;
  * @brief Generic, persistent and shared between processes cache mechanism
  *        for use by various parts of the Samba code
  *
+ * We have two cache files, one with transactions (gencache.tdb) and
+ * one without (gencache_notrans.tdb) that is CLEAR_IF_FIRST. Normal
+ * writes go to the gencache_notrans.tdb to be fast. Every 100 writes
+ * to the gencache (settable with gencache:stabilize_count) or every 5
+ * minutes (settable with gencache:stabilize_interval) we stabilize
+ * gencache_notrans.tdb with one transaction to gencache.tdb.
+ *
  **/
 
 
@@ -107,7 +114,8 @@ again:
 
 	DEBUG(5, ("Opening cache file at %s\n", cache_fname));
 
-	cache_notrans = tdb_open_log(cache_fname, 0, TDB_CLEAR_IF_FIRST,
+	cache_notrans = tdb_open_log(cache_fname, 0,
+				     TDB_CLEAR_IF_FIRST | TDB_SEQNUM,
 				     open_flags, 0644);
 	if (cache_notrans == NULL) {
 		DEBUG(5, ("Opening %s failed: %s\n", cache_fname,
@@ -128,6 +136,51 @@ static TDB_DATA last_stabilize_key(void)
 	return result;
 }
 
+struct gencache_parse_last_stabilize_state {
+	bool found;
+	int last_time;
+	int last_seqnum;
+};
+
+static int gencache_parse_last_stabilize_fn(TDB_DATA key, TDB_DATA data,
+					    void *private_data)
+{
+	struct gencache_parse_last_stabilize_state *state =
+		(struct gencache_parse_last_stabilize_state *)private_data;
+
+	if ((data.dptr == NULL) || (data.dsize == 0) ||
+	    (data.dptr[data.dsize-1] != '\0')) {
+		return -1;
+	}
+
+	if (sscanf((char *)data.dptr, "%d/%d", &state->last_time,
+		   &state->last_seqnum) != 2) {
+		return -1;
+	}
+
+	state->found = true;
+	return 0;
+}
+
+static bool gencache_parse_last_stabilize(time_t *last_time, int *last_seqnum)
+{
+	struct gencache_parse_last_stabilize_state state;
+
+	state.found = false;
+
+	if (tdb_parse_record(cache_notrans, last_stabilize_key(),
+			     gencache_parse_last_stabilize_fn,
+			     &state) == -1) {
+		return false;
+	}
+	if (!state.found) {
+		return false;
+	}
+	*last_time = state.last_time;
+	*last_seqnum = state.last_seqnum;
+	return true;
+}
+
 /**
  * Set an entry in the cache file. If there's no such
  * one, then add it.
@@ -144,9 +197,9 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob,
 			    time_t timeout)
 {
 	int ret;
-	TDB_DATA databuf;
 	char* val;
 	time_t last_stabilize;
+	int last_seqnum;
 	static int writecount;
 
 	if (tdb_data_cmp(string_term_tdb_data(keystr),
@@ -206,17 +259,15 @@ bool gencache_set_data_blob(const char *keystr, const DATA_BLOB *blob,
 	 * gencache_notrans.tdb too large.
 	 */
 
-	last_stabilize = 0;
-	databuf = tdb_fetch(cache_notrans, last_stabilize_key());
-	if ((databuf.dptr != NULL)
-	    && (databuf.dptr[databuf.dsize-1] == '\0')) {
-		last_stabilize = atoi((char *)databuf.dptr);
-		SAFE_FREE(databuf.dptr);
-	}
-	if ((last_stabilize
-	     + lp_parm_int(-1, "gencache", "stabilize_interval", 300))
-	    < time(NULL)) {
-		gencache_stabilize();
+	if (gencache_parse_last_stabilize(&last_stabilize, &last_seqnum)) {
+		time_t next;
+
+		next = last_stabilize + lp_parm_int(
+			-1, "gencache", "stabilize_interval", 300);
+
+		if (next < time(NULL)) {
+			gencache_stabilize();
+		}
 	}
 
 done:
@@ -411,11 +462,19 @@ bool gencache_stabilize(void)
 	struct stabilize_state state;
 	int res;
 	char *now;
+	time_t last_time;
+	int last_seqnum;
 
 	if (!gencache_init()) {
 		return false;
 	}
 
+	if (gencache_parse_last_stabilize(&last_time, &last_seqnum)
+	    && (last_seqnum == tdb_get_seqnum(cache_notrans))) {
+		/* Nothing changed */
+		return true;
+	}
+
 	res = tdb_transaction_start(cache);
 	if (res == -1) {
 		DEBUG(10, ("Could not start transaction on gencache.tdb: "
@@ -468,7 +527,9 @@ bool gencache_stabilize(void)
 		return false;
 	}
 
-	now = talloc_asprintf(talloc_tos(), "%d", (int)time(NULL));
+	now = talloc_asprintf(talloc_tos(), "%d/%d",
+			      (int)time(NULL),
+			      tdb_get_seqnum(cache_notrans)+1);
 	if (now != NULL) {
 		tdb_store(cache_notrans, last_stabilize_key(),
 			  string_term_tdb_data(now), 0);


-- 
Samba Shared Repository


More information about the samba-cvs mailing list