the first cut of the internal messaging system.
authorAndrew Tridgell <tridge@samba.org>
Mon, 11 Sep 2000 07:02:43 +0000 (07:02 +0000)
committerAndrew Tridgell <tridge@samba.org>
Mon, 11 Sep 2000 07:02:43 +0000 (07:02 +0000)
The motivation for this system is to replace the UDP message for
oplocks, but this commit only does the "set debug level" message.
(This used to be commit 2a34ee95f3929cff131db6c5a2b4820194c05b2d)

12 files changed:
source3/Makefile.in
source3/include/includes.h
source3/include/messages.h [new file with mode: 0644]
source3/include/proto.h
source3/lib/debug.c
source3/lib/messages.c [new file with mode: 0644]
source3/locking/locking.c
source3/nmbd/nmbd.c
source3/nmbd/nmbd_packets.c
source3/nsswitch/winbindd.c
source3/smbd/process.c
source3/smbd/server.c

index 018086b40b23f84d75777f7624b40f347db05954..7d242ea569b3627e90dc1802c781b0dac6905e9e 100644 (file)
@@ -108,7 +108,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \
          lib/util_unistr.o lib/util_file.o \
          lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \
          lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \
-         lib/ms_fnmatch.o lib/select.o lib/error.o \
+         lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \
          $(TDB_OBJ)
 
 UBIQX_OBJ = ubiqx/ubi_BinTree.o ubiqx/ubi_Cache.o ubiqx/ubi_SplayTree.o \
@@ -226,6 +226,9 @@ MAKE_PRINTERDEF_OBJ = utils/make_printerdef.o $(PARAM_OBJ) \
 STATUS_OBJ = utils/status.o $(LOCKING_OBJ) $(PARAM_OBJ) \
              $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
 
+MSGTEST_OBJ = utils/msgtest.o $(LOCKING_OBJ) $(PARAM_OBJ) \
+             $(UBIQX_OBJ) $(PROFILE_OBJ) $(LIB_OBJ)
+
 TESTPARM_OBJ = utils/testparm.o \
                $(PARAM_OBJ) $(UBIQX_OBJ) $(LIB_OBJ)
 
@@ -467,6 +470,10 @@ bin/smbstatus: $(STATUS_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(STATUS_OBJ) $(LDFLAGS) $(LIBS)
 
+bin/msgtest: $(MSGTEST_OBJ) bin/.dummy
+       @echo Linking $@
+       @$(CC) $(FLAGS) -o $@ $(MSGTEST_OBJ) $(LDFLAGS) $(LIBS)
+
 bin/smbpasswd: $(SMBPASSWD_OBJ) bin/.dummy
        @echo Linking $@
        @$(CC) $(FLAGS) -o $@ $(SMBPASSWD_OBJ) $(LDFLAGS) $(LIBS)
index eb2f23b6fe5ade77be7436e5ef5bf5ca8530f99c..a18c8b6d5cbe00bc4365ef08bb2bafe25c018a40 100644 (file)
@@ -612,6 +612,7 @@ extern int errno;
 #include "trans2.h"
 #include "nterr.h"
 #include "secrets.h"
+#include "messages.h"
 #include "util_list.h"
 
 #ifndef UBI_BINTREE_H
diff --git a/source3/include/messages.h b/source3/include/messages.h
new file mode 100644 (file)
index 0000000..4bc4014
--- /dev/null
@@ -0,0 +1,27 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   messages.c header
+   Copyright (C) Andrew Tridgell 2000
+   
+   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
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#ifndef _MESSAGES_H_
+#define _MESSAGES_H_
+
+enum message_type {MSG_DEBUG};
+
+#endif
index 737053a2a3d3219bf854ba91a568fde6d3e2961d..754c51ee9d04417893d1a1ddff0875c55c180913 100644 (file)
@@ -59,8 +59,8 @@ uint32 crc32_calc_buffer( char *buffer, uint32 count);
 
 /*The following definitions come from  lib/debug.c  */
 
-void sig_usr2( int sig );
-void sig_usr1( int sig );
+void debug_message(pid_t src, void *buf, int len);
+void debug_message_send(pid_t pid, int level);
 void setup_logging( char *pname, BOOL interactive );
 void reopen_logs( void );
 void force_check_log_size( void );
@@ -150,6 +150,12 @@ void initialize_multibyte_vectors( int client_codepage);
 
 void mdfour(unsigned char *out, unsigned char *in, int n);
 
+/*The following definitions come from  lib/messages.c  */
+
+BOOL message_init(void);
+BOOL message_send_pid(pid_t pid, enum message_type msg_type, void *buf, size_t len);
+void message_dispatch(void);
+
 /*The following definitions come from  lib/ms_fnmatch.c  */
 
 int ms_fnmatch(char *pattern, char *string);
index bfb638a38aca4fed55172fafbcc5df44b5ee6e82..5279dda2e35c1ee7d1b1fdd24b1e8ea8c5f4afe5 100644 (file)
@@ -119,51 +119,24 @@ static size_t     format_pos     = 0;
  * Functions...
  */
 
-#if defined(SIGUSR2)
-/* ************************************************************************** **
- * catch a sigusr2 - decrease the debug log level.
- * ************************************************************************** **
- */
-void sig_usr2( int sig )
-  {
-  DEBUGLEVEL--;
-  if( DEBUGLEVEL < 0 )
-    DEBUGLEVEL = 0;
-
-  DEBUG( 0, ( "Got SIGUSR2; set debug level to %d.\n", DEBUGLEVEL ) );
-
-  sys_select_signal();
-
-#if !defined(HAVE_SIGACTION)
-  CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif
-
-  } /* sig_usr2 */
-#endif /* SIGUSR2 */
-
-#if defined(SIGUSR1)
-/* ************************************************************************** **
- * catch a sigusr1 - increase the debug log level. 
- * ************************************************************************** **
- */
-void sig_usr1( int sig )
-  {
-
-  DEBUGLEVEL++;
-
-  if( DEBUGLEVEL > 10 )
-    DEBUGLEVEL = 10;
-
-  DEBUG( 0, ( "Got SIGUSR1; set debug level to %d.\n", DEBUGLEVEL ) );
-
-  sys_select_signal();
-
-#if !defined(HAVE_SIGACTION)
-  CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif
+/****************************************************************************
+receive a "set debug level" message
+****************************************************************************/
+void debug_message(pid_t src, void *buf, int len)
+{
+       int level;
+       memcpy(&level, buf, sizeof(int));
+       DEBUGLEVEL = level;
+       DEBUG(1,("Debug level set to %d from pid %d\n", level, (int)src));
+}
 
-  } /* sig_usr1 */
-#endif /* SIGUSR1 */
+/****************************************************************************
+send a "set debug level" message
+****************************************************************************/
+void debug_message_send(pid_t pid, int level)
+{
+       message_send_pid(pid, MSG_DEBUG, &level, sizeof(int));
+}
 
 
 /* ************************************************************************** **
diff --git a/source3/lib/messages.c b/source3/lib/messages.c
new file mode 100644 (file)
index 0000000..30eef40
--- /dev/null
@@ -0,0 +1,237 @@
+/* 
+   Unix SMB/Netbios implementation.
+   Version 3.0
+   Samba internal messaging functions
+   Copyright (C) Andrew Tridgell 2000
+   
+   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
+   the Free Software Foundation; either version 2 of the License, or
+   (at your option) any later version.
+   
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+   
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, write to the Free Software
+   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+/* this module is used for internal messaging between Samba daemons. */
+
+#include "includes.h"
+
+/* the locking database handle */
+static TDB_CONTEXT *tdb;
+static int received_signal;
+
+/* change the message version with any incompatible changes in the protocol */
+#define MESSAGE_VERSION 1
+
+struct message_rec {
+       int msg_version;
+       enum message_type msg_type;
+       pid_t dest;
+       pid_t src;
+       size_t len;
+};
+
+/****************************************************************************
+notifications come in as signals
+****************************************************************************/
+static void sig_usr1(void)
+{
+       received_signal = 1;
+       sys_select_signal();
+}
+
+/****************************************************************************
+ Initialise the messaging functions. 
+****************************************************************************/
+BOOL message_init(void)
+{
+       if (tdb) return True;
+
+       tdb = tdb_open(lock_path("messages.tdb"), 
+                      0, TDB_CLEAR_IF_FIRST, 
+                      O_RDWR|O_CREAT,0600);
+
+       if (!tdb) {
+               DEBUG(0,("ERROR: Failed to initialise messages database\n"));
+               return False;
+       }
+
+       CatchSignal(SIGUSR1, sig_usr1);
+
+       return True;
+}
+
+
+/*******************************************************************
+ form a static tdb key from a pid
+******************************************************************/
+static TDB_DATA message_key_pid(pid_t pid)
+{
+       static char key[20];
+       TDB_DATA kbuf;
+
+       slprintf(key, sizeof(key), "PID/%d", (int)pid);
+
+       kbuf.dptr = (char *)key;
+       kbuf.dsize = sizeof(key);
+       return kbuf;
+}
+
+
+/****************************************************************************
+notify a process that it has a message. If the process doesn't exist 
+then delete its record in the database
+****************************************************************************/
+static BOOL message_notify(pid_t pid)
+{
+       if (kill(pid, SIGUSR1) == -1) {
+               if (errno == ESRCH) {
+                       DEBUG(2,("pid %d doesn't exist - deleting messages record\n", (int)pid));
+                       tdb_delete(tdb, message_key_pid(pid));
+               } else {
+                       DEBUG(2,("message to process %d failed - %s\n", (int)pid, strerror(errno)));
+               }
+               return False;
+       }
+       return True;
+}
+
+/****************************************************************************
+send a message to a particular pid
+****************************************************************************/
+BOOL message_send_pid(pid_t pid, enum message_type msg_type, void *buf, size_t len)
+{
+       TDB_DATA kbuf;
+       TDB_DATA dbuf;
+       struct message_rec rec;
+       void *p;
+
+       rec.msg_version = MESSAGE_VERSION;
+       rec.msg_type = msg_type;
+       rec.dest = pid;
+       rec.src = sys_getpid();
+       rec.len = len;
+
+       kbuf = message_key_pid(pid);
+
+       /* lock the record for the destination */
+       tdb_lockchain(tdb, kbuf);
+
+       dbuf = tdb_fetch(tdb, kbuf);
+
+       if (!dbuf.dptr) {
+               /* its a new record */
+               p = (void *)malloc(len + sizeof(rec));
+               if (!p) goto failed;
+
+               memcpy(p, &rec, sizeof(rec));
+               memcpy(p+sizeof(rec), buf, len);
+
+               dbuf.dptr = p;
+               dbuf.dsize = len + sizeof(rec);
+               tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+               free(p);
+               goto ok;
+       }
+
+       /* we're adding to an existing entry */
+       p = (void *)malloc(dbuf.dsize + len + sizeof(rec));
+       if (!p) goto failed;
+
+       memcpy(p, dbuf.dptr, dbuf.dsize);
+       memcpy(p+dbuf.dsize, &rec, sizeof(rec));
+       memcpy(p+dbuf.dsize+sizeof(rec), buf, len);
+
+       dbuf.dptr = p;
+       dbuf.dsize += len + sizeof(rec);
+       tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+       free(dbuf.dptr);
+       free(p);
+
+ ok:
+       tdb_unlockchain(tdb, kbuf);
+       return message_notify(pid);
+
+ failed:
+       tdb_unlockchain(tdb, kbuf);
+       return False;
+}
+
+
+
+/****************************************************************************
+retrieve the next message for the current process
+****************************************************************************/
+static BOOL message_recv(enum message_type *msg_type, pid_t *src, void **buf, size_t *len)
+{
+       TDB_DATA kbuf;
+       TDB_DATA dbuf;
+       struct message_rec rec;
+
+       kbuf = message_key_pid(sys_getpid());
+
+       tdb_lockchain(tdb, kbuf);
+       
+       dbuf = tdb_fetch(tdb, kbuf);
+       if (dbuf.dptr == NULL || dbuf.dsize == 0) goto failed;
+
+       memcpy(&rec, dbuf.dptr, sizeof(rec));
+
+       if (rec.msg_version != MESSAGE_VERSION) {
+               DEBUG(0,("message version %d received (expected %d)\n", rec.msg_version, MESSAGE_VERSION));
+               goto failed;
+       }
+
+       (*buf) = (void *)malloc(rec.len);
+       if (!(*buf)) goto failed;
+
+       memcpy(*buf, dbuf.dptr+sizeof(rec), rec.len);
+       *len = rec.len;
+       *msg_type = rec.msg_type;
+       *src = rec.src;
+
+       memmove(dbuf.dptr, dbuf.dptr+sizeof(rec)+rec.len, dbuf.dsize - (sizeof(rec)+rec.len));
+       dbuf.dsize -= sizeof(rec)+rec.len;
+       tdb_store(tdb, kbuf, dbuf, TDB_REPLACE);
+
+       free(dbuf.dptr);
+       tdb_unlockchain(tdb, kbuf);
+       return True;
+
+ failed:
+       tdb_unlockchain(tdb, kbuf);
+       return False;
+}
+
+
+/****************************************************************************
+receive and dispatch any messages pending for this process
+****************************************************************************/
+void message_dispatch(void)
+{
+       enum message_type msg_type;
+       pid_t src;
+       void *buf;
+       size_t len;
+
+       if (!received_signal) return;
+       received_signal = 0;
+
+       while (message_recv(&msg_type, &src, &buf, &len)) {
+               switch (msg_type) {
+               case MSG_DEBUG:
+                       debug_message(src, buf, len);
+                       break;
+               default:
+                       DEBUG(0,("Unknown message type %d from %d\n", msg_type, (int)src));
+                       break;
+               }
+       }
+}
index 8fc1c4a4bcdd627c2bae7d5471dc5eac68d1c577..58e6b06e667a401040d3187a2f53ca75559960c7 100644 (file)
@@ -229,7 +229,7 @@ BOOL locking_init(int read_only)
                       0644);
 
        if (!tdb) {
-               DEBUG(0,("ERROR: Failed to initialise share modes\n"));
+               DEBUG(0,("ERROR: Failed to initialise locking database\n"));
                return False;
        }
        
index af78af756ebc8355455fdb160057cf301d4db35c..cd47296774719e663de594f79ef2adb97d06c491 100644 (file)
@@ -682,19 +682,6 @@ static void usage(char *pname)
   BlockSignals(True,SIGFPE);
 #endif
 
-  /* Setup the signals that allow the debug log level
-     to by dynamically changed. */
-
-  /* If we are using the malloc debug code we can't use
-     SIGUSR1 and SIGUSR2 to do debug level changes. */
-#if defined(SIGUSR1)
-  CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif /* SIGUSR1 */
-
-#if defined(SIGUSR2)
-  CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif /* SIGUSR2 */
-
   while( EOF != 
          (opt = getopt( argc, argv, "Vaos:T:I:C:bAB:N:Rn:l:d:Dp:hSH:G:f:" )) )
     {
@@ -850,12 +837,6 @@ static void usage(char *pname)
 
   /* We can only take signals in the select. */
   BlockSignals( True, SIGTERM );
-#if defined(SIGUSR1)
-  BlockSignals( True, SIGUSR1);
-#endif /* SIGUSR1 */
-#if defined(SIGUSR2)
-  BlockSignals( True, SIGUSR2);
-#endif /* SIGUSR2 */
 
   process();
 
index cf00dc9083fa23e5e11b08c1aca65529c911d43f..605233f40d31de9d0f761a24917ced15a7db1f4d 100644 (file)
@@ -1808,24 +1808,12 @@ BOOL listen_for_packets(BOOL run_election)
   /* Prepare for the select - allow certain signals. */
 
   BlockSignals(False, SIGTERM);
-#if defined(SIGUSR1)
-  BlockSignals(False, SIGUSR1);
-#endif /* SIGUSR1 */
-#if defined(SIGUSR2)
-  BlockSignals(False, SIGUSR2);
-#endif /* SIGUSR2 */
 
   selrtn = sys_select_intr(FD_SETSIZE,&fds,&timeout);
 
   /* We can only take signals when we are in the select - block them again here. */
 
   BlockSignals(True, SIGTERM);
-#if defined(SIGUSR1)
-  BlockSignals(True, SIGUSR1);
-#endif /* SIGUSR1 */
-#if defined(SIGUSR2)
-  BlockSignals(True, SIGUSR2);
-#endif /* SIGUSR2 */
 
   if(selrtn > 0)
   {
index e05166e7168a073026d9b7df1b0a2cd91230e6de..7af1d09723be1364f672e7c412cb35a968fec10b 100644 (file)
@@ -91,13 +91,6 @@ static void termination_handler(int signum)
 
 static BOOL print_client_info;
 
-static void sigusr1_handler(int signum)
-{
-    BlockSignals(True, SIGUSR1);
-    print_client_info = True;
-    BlockSignals(False, SIGUSR1);
-}
-
 static BOOL flush_cache;
 
 static void sighup_handler(int signum)
@@ -645,7 +638,6 @@ int main(int argc, char **argv)
 
     CatchSignal(SIGPIPE, SIG_IGN);                    /* Ignore sigpipe */
 
-    CatchSignal(SIGUSR1, sigusr1_handler);            /* Debugging sigs */
     CatchSignal(SIGHUP, sighup_handler);
 
     /* Create UNIX domain socket */
index 37d8f8dd73a8fe60c4517584788a29ce763d9b24..1599ade12d6940af75147bb33b223a7457be2e10 100644 (file)
@@ -131,6 +131,9 @@ static void async_processing(fd_set *fds, char *buffer, int buffer_len)
                reload_services(False);
                reload_after_sighup = False;
        }
+
+       /* check for any pending internal messages */
+       message_dispatch();
 }
 
 /****************************************************************************
index 8691603eb33f41c4f0106df5ba03cc750f8041f8..4442a1f71f6b21dfba3c0e5a79dd67cef6bfd565 100644 (file)
@@ -685,20 +685,6 @@ static void usage(char *pname)
 
        CatchSignal(SIGHUP,SIGNAL_CAST sig_hup);
        
-       /* Setup the signals that allow the debug log level
-          to by dynamically changed. */
-       /* If we are using the malloc debug code we can't use
-          SIGUSR1 and SIGUSR2 to do debug level changes. */
-       
-#if defined(SIGUSR1)
-       CatchSignal( SIGUSR1, SIGNAL_CAST sig_usr1 );
-#endif /* SIGUSR1 */
-   
-#if defined(SIGUSR2)
-       CatchSignal( SIGUSR2, SIGNAL_CAST sig_usr2 );
-#endif /* SIGUSR2 */
-
        DEBUG(3,( "loaded services\n"));
 
        if (!is_daemon && !is_a_socket(0)) {
@@ -726,6 +712,10 @@ static void usage(char *pname)
         * everything after this point is run after the fork()
         */ 
 
+       if (!message_init()) {
+               exit(1);
+       }
+
        if (!locking_init(0)) {
                exit(1);
        }