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);

Reply via email to