From: Andrew Tridgell Date: Mon, 11 Sep 2000 07:02:43 +0000 (+0000) Subject: the first cut of the internal messaging system. X-Git-Tag: release-4-0-0alpha6~801^2~19295 X-Git-Url: http://git.samba.org/samba.git/?a=commitdiff_plain;h=3689e4ffc10fceb4c39814ef58fe31697e7dd976;p=amitay%2Fsamba.git the first cut of the internal messaging system. 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) --- diff --git a/source3/Makefile.in b/source3/Makefile.in index 018086b40b2..7d242ea569b 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -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) diff --git a/source3/include/includes.h b/source3/include/includes.h index eb2f23b6fe5..a18c8b6d5cb 100644 --- a/source3/include/includes.h +++ b/source3/include/includes.h @@ -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 index 00000000000..4bc4014ca0e --- /dev/null +++ b/source3/include/messages.h @@ -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 diff --git a/source3/include/proto.h b/source3/include/proto.h index 737053a2a3d..754c51ee9d0 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -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); diff --git a/source3/lib/debug.c b/source3/lib/debug.c index bfb638a38ac..5279dda2e35 100644 --- a/source3/lib/debug.c +++ b/source3/lib/debug.c @@ -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 index 00000000000..30eef40ec91 --- /dev/null +++ b/source3/lib/messages.c @@ -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; + } + } +} diff --git a/source3/locking/locking.c b/source3/locking/locking.c index 8fc1c4a4bcd..58e6b06e667 100644 --- a/source3/locking/locking.c +++ b/source3/locking/locking.c @@ -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; } diff --git a/source3/nmbd/nmbd.c b/source3/nmbd/nmbd.c index af78af756eb..cd472967747 100644 --- a/source3/nmbd/nmbd.c +++ b/source3/nmbd/nmbd.c @@ -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(); diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c index cf00dc9083f..605233f40d3 100644 --- a/source3/nmbd/nmbd_packets.c +++ b/source3/nmbd/nmbd_packets.c @@ -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) { diff --git a/source3/nsswitch/winbindd.c b/source3/nsswitch/winbindd.c index e05166e7168..7af1d09723b 100644 --- a/source3/nsswitch/winbindd.c +++ b/source3/nsswitch/winbindd.c @@ -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 */ diff --git a/source3/smbd/process.c b/source3/smbd/process.c index 37d8f8dd73a..1599ade12d6 100644 --- a/source3/smbd/process.c +++ b/source3/smbd/process.c @@ -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(); } /**************************************************************************** diff --git a/source3/smbd/server.c b/source3/smbd/server.c index 8691603eb33..4442a1f71f6 100644 --- a/source3/smbd/server.c +++ b/source3/smbd/server.c @@ -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); }