svn commit: samba r18263 - in branches/tmp/vl-messaging/source: include lib

jmcd at samba.org jmcd at samba.org
Fri Sep 8 13:00:49 GMT 2006


Author: jmcd
Date: 2006-09-08 13:00:48 +0000 (Fri, 08 Sep 2006)
New Revision: 18263

WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=18263

Log:
>From Aleksey Fedoseev:
Add database traverse for lockd-based locking, allowing locks to be seen
in smbstatus.

Modified:
   branches/tmp/vl-messaging/source/include/messages.h
   branches/tmp/vl-messaging/source/lib/dbwrap_msg.c
   branches/tmp/vl-messaging/source/lib/messages.c


Changeset:
Modified: branches/tmp/vl-messaging/source/include/messages.h
===================================================================
--- branches/tmp/vl-messaging/source/include/messages.h	2006-09-08 12:48:51 UTC (rev 18262)
+++ branches/tmp/vl-messaging/source/include/messages.h	2006-09-08 13:00:48 UTC (rev 18263)
@@ -88,6 +88,7 @@
 #define MSG_DB_STORE			 5005
 #define MSG_DB_DELETE			 5006
 #define MSG_DB_REINIT			 5007
+#define MSG_DB_TRAVERSE			5008
 
 /* Flags to classify messages - used in message_send_all() */
 /* Sender will filter by flag. */

Modified: branches/tmp/vl-messaging/source/lib/dbwrap_msg.c
===================================================================
--- branches/tmp/vl-messaging/source/lib/dbwrap_msg.c	2006-09-08 12:48:51 UTC (rev 18262)
+++ branches/tmp/vl-messaging/source/lib/dbwrap_msg.c	2006-09-08 13:00:48 UTC (rev 18263)
@@ -445,13 +445,59 @@
 	return 0;
 }
 
+static void handle_traverse_return(int msg_type, struct process_id pid,
+				   void *buf, size_t len);
+
 static int db_msg_traverse(struct db_context *db,
 			   int (*fn)(TDB_DATA key, TDB_DATA value,
 				     void *private_data),
 			   void *private_data)
 {
-	/* TODO... but traverse will be VERY expensive */
-	return -1;
+	struct db_msg_ctx *ctx = talloc_get_type_abort(db->private_data,
+						       struct db_msg_ctx);
+	TDB_DATA null_data;
+	TDB_DATA buf;
+	static BOOL traverse_msg_reg = False;
+	int count = 0;
+	
+	null_data.dsize = 0;
+	null_data.dptr = NULL;
+	buf = msg_pack_data(ctx, ctx->db_index, null_data);
+
+	if(buf.dptr == NULL) {
+		return -1;
+	}
+
+	if(!traverse_msg_reg) {
+		message_register(MSG_DB_TRAVERSE, handle_traverse_return);
+		traverse_msg_reg = True;
+	}
+		
+	message_send_pid(ctx->lockd, MSG_DB_TRAVERSE,
+			 buf.dptr, buf.dsize, False);
+
+	TALLOC_FREE(buf.dptr);
+
+	SMB_ASSERT(ctx->record == NULL);
+	
+	wait_for_return(ctx);
+
+	while(ctx->record != NULL) {
+		count++;
+
+		if(fn && fn(ctx->record->key, ctx->record->value, private_data)) {
+			/* break the traversal */
+			TALLOC_FREE(ctx->record);
+			message_deregister(MSG_DB_TRAVERSE);
+			traverse_msg_reg = False;
+			break;
+		}
+
+		TALLOC_FREE(ctx->record);
+		wait_for_return(ctx);
+	}
+	
+	return count;
 }
 
 static BOOL db_msg_reinit(struct db_context *db)
@@ -584,6 +630,70 @@
 	ctx->record = result;
 }
 
+static void handle_traverse_return(int msg_type, struct process_id pid,
+				   void *buf, size_t len)
+{
+	struct db_record *result;
+	struct db_msg_ctx *ctx = ctx_list;	
+	uint8_t idx;
+	TDB_DATA key, value;
+
+	DEBUG(10, ("msg_traverse received with len %d\n", len));
+
+	if(!msg_unpack_double_data((const char *)buf, len, NULL, &idx, &key, &value)) {
+		DEBUG(2, ("Unpacking error\n"));
+		return ;
+	}
+
+	while(ctx) {
+		if(ctx->db_index == idx) break;
+		ctx = ctx->next;
+	}
+	
+	if(ctx == NULL) {
+		DEBUG(2, ("Bad database index %d\n", idx));
+		return ;
+	}
+
+	ctx->received = True;
+	ctx->record = NULL;
+
+	if(key.dsize > 0) {
+		result = TALLOC_ZERO_P(ctx, struct db_record);
+		if (result == NULL) {
+			DEBUG(0, ("talloc failed\n"));
+			return ;
+		}
+
+		result->key.dsize = key.dsize;
+		result->key.dptr = (char *)talloc_memdup(
+			result, key.dptr, key.dsize);
+
+		TALLOC_FREE(key.dptr);
+
+		if (result->key.dptr == NULL) {
+			DEBUG(0, ("talloc failed\n"));
+			TALLOC_FREE(result);
+			TALLOC_FREE(value.dptr);
+			return ;
+		}
+		
+		if(value.dsize > 0) {
+			result->value.dsize = value.dsize;
+			result->value.dptr = (char *)talloc_memdup(
+				result, value.dptr, value.dsize);
+			TALLOC_FREE(value.dptr);
+			if (result->value.dptr == NULL) {
+				DEBUG(0, ("talloc failed\n"));
+				TALLOC_FREE(result);
+				return ;
+			}
+		}
+		
+		ctx->record = result;
+	}
+}
+
 struct db_context *db_open_msg(TALLOC_CTX *mem_ctx, const char *name,
 				int hash_size, int tdb_flags,
 				int open_flags, mode_t mode)
@@ -839,8 +949,6 @@
 {
 	struct db_records_list *record;
 
-	DEBUG(10, ("%p, %d\n", key.dptr, key.dsize));
-	
 	if(key.dptr == NULL) {
 	    DEBUG(0, ("Fetching null key!\n"));
 	    return ;
@@ -897,8 +1005,8 @@
 		
 		data = msg_pack_data(NULL, database->idx, record->value);
 		if(data.dptr != NULL) {
-			DEBUG(10, ("Sending fetchlock response (len %d)\n",
-				   data.dsize));
+			DEBUG(10, ("Sending fetchlock response (len %d) to %s\n",
+				   data.dsize, procid_str_static(src_pid)));
 			
 			message_send_pid_stream(*lockd_pid, *src_pid,
 						MSG_DB_FETCHLOCK,
@@ -924,6 +1032,75 @@
 }
 
 /****************************************************************************
+ process database request - traverse
+****************************************************************************/
+
+struct msg_traverse_ctx {
+	struct process_id *lockd_pid, *src_pid;
+	uint8_t db_index;
+};
+
+static int msg_traverse_func(TDB_CONTEXT *tdb, TDB_DATA kbuf, TDB_DATA dbuf,
+			      void *private_data)
+{
+	struct msg_traverse_ctx *ctx = (struct msg_traverse_ctx *)private_data;
+	TDB_DATA data;
+
+	data = msg_pack_double_data(NULL, ctx->db_index,
+				    kbuf, dbuf);
+	if(data.dptr == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		return 1;
+	}
+
+	message_send_pid_stream(*ctx->lockd_pid, *ctx->src_pid,
+				MSG_DB_TRAVERSE,
+				data.dptr, data.dsize,
+				False, 0);
+
+	TALLOC_FREE(data.dptr);
+
+	return 0;
+}
+
+static void process_db_traverse(struct process_id *lockd_pid,
+				struct process_id *src_pid,
+				struct db_entry *database)
+{
+	struct msg_traverse_ctx ctx;
+	TDB_DATA data;
+	TDB_DATA null_data;
+
+	ctx.lockd_pid = lockd_pid;
+	ctx.src_pid = src_pid;
+	ctx.db_index = database->idx;
+
+	if(tdb_traverse(database->db, msg_traverse_func, &ctx) == -1) {
+		DEBUG(0, ("tdb_traverse error\n"));
+		return ;
+	}
+
+	/* final (empty) traverse message */
+
+	null_data.dsize = 0;
+	null_data.dptr = NULL;
+
+	data = msg_pack_double_data(NULL, database->idx,
+				    null_data, null_data);
+	if(data.dptr == NULL) {
+		DEBUG(0, ("talloc failed\n"));
+		return ;
+	}
+
+	message_send_pid_stream(*lockd_pid, *src_pid,
+				MSG_DB_TRAVERSE,
+				data.dptr, data.dsize,
+				False, 0);	
+
+	TALLOC_FREE(data.dptr);
+}
+
+/****************************************************************************
  process database request - unlock record
 ****************************************************************************/
 
@@ -951,8 +1128,8 @@
 		
 		data = msg_pack_data(NULL, database->idx, record->value);
 		
-		DEBUG(10, ("Sending fetchlock response (len %d)\n",
-			   data.dsize));
+		DEBUG(10, ("Sending fetchlock response (len %d) to %s\n",
+			   data.dsize, procid_str_static(&source)));
 		
 		message_send_pid_stream(*lockd_pid, source, MSG_DB_FETCHLOCK,
 					data.dptr, data.dsize, False, 0);
@@ -1075,6 +1252,10 @@
 
 			process_db_fetch(lockd_pid, src_pid, dbl, data1);
 
+		} else if(msg_type == MSG_DB_TRAVERSE) {
+
+			process_db_traverse(lockd_pid, src_pid, dbl);
+
 		} else {
 			
 			/* find the record */

Modified: branches/tmp/vl-messaging/source/lib/messages.c
===================================================================
--- branches/tmp/vl-messaging/source/lib/messages.c	2006-09-08 12:48:51 UTC (rev 18262)
+++ branches/tmp/vl-messaging/source/lib/messages.c	2006-09-08 13:00:48 UTC (rev 18263)
@@ -251,7 +251,7 @@
 ****************************************************************************/
 
 static BOOL retrieve_mask_messages(unsigned int mask,
-								   struct message_list **list)
+				   struct message_list **list)
 {
 	SMB_ASSERT(retrieve_mask_messages_func != NULL);
 	return retrieve_mask_messages_func(mask, list);



More information about the samba-cvs mailing list