From 9c6d384b9a5c6b85f50438a7ef8c537e803df475 Mon Sep 17 00:00:00 2001 From: Kurt Spanier Date: Tue, 5 Jan 1999 15:40:58 +0000 Subject: [PATCH] - Make install creates $(RUNDIR)/var for pid and args files of slapd. - slapd's pid/args file names are based on the servers binary file names, providing for multiple servers beeing run on one host. - slapd supports the -l command line parameter for selection of a syslog LOCAL user (-lLOCAL0 .. -lLOCAL7) - db_appinit() is called during first ldbm_open() in DB 2.x to initialize DB debugging features (good to find bugs in the DB code :-) - a patch for a non-initialized variable in DB's 2.x db_open is provided. --- build/db.2.64.patch | 36 +++++++++++ build/db.2.64.patch.README | 11 ++++ include/ldapconfig.h.edit | 4 ++ libraries/libldap/getfilter.c | 2 + libraries/libldbm/ldbm.c | 67 +++++++++++++++++++- servers/slapd/Makefile.in | 1 + servers/slapd/back-ldbm/init.c | 3 + servers/slapd/daemon.c | 24 +++++++- servers/slapd/main.c | 108 ++++++++++++++++++++++++++++++--- 9 files changed, 245 insertions(+), 11 deletions(-) create mode 100644 build/db.2.64.patch create mode 100644 build/db.2.64.patch.README diff --git a/build/db.2.64.patch b/build/db.2.64.patch new file mode 100644 index 0000000000..d777593b7b --- /dev/null +++ b/build/db.2.64.patch @@ -0,0 +1,36 @@ +*** db/db.c.sleepy Sun Jan 3 20:02:51 1999 +--- db/db.c Sun Jan 3 20:28:25 1999 +*************** db_open(fname, type, flags, mode, dbenv, +*** 106,112 **** + DB_PGINFO pginfo; + HASHHDR *hashm; + size_t cachesize; +! ssize_t nr; + u_int32_t iopsize; + int fd, ftype, need_fileid, restore, ret, retry_cnt, swapped; + char *real_name, mbuf[512]; +--- 106,112 ---- + DB_PGINFO pginfo; + HASHHDR *hashm; + size_t cachesize; +! ssize_t nr = (ssize_t) 0; + u_int32_t iopsize; + int fd, ftype, need_fileid, restore, ret, retry_cnt, swapped; + char *real_name, mbuf[512]; +*************** open_retry: if (LF_ISSET(DB_CREATE)) { +*** 337,343 **** + if (nr != sizeof(mbuf)) { + if (nr != 0) { + __db_err(dbenv, +! "%s: unexpected file format", fname); + goto einval; + } + /* +--- 337,343 ---- + if (nr != sizeof(mbuf)) { + if (nr != 0) { + __db_err(dbenv, +! "%s: unexpected file format, %d bytes read", fname, nr); + goto einval; + } + /* diff --git a/build/db.2.64.patch.README b/build/db.2.64.patch.README new file mode 100644 index 0000000000..34abc6ab3e --- /dev/null +++ b/build/db.2.64.patch.README @@ -0,0 +1,11 @@ + +A bug in Sleepycat´s Berkeley DB (version 2.3.16 up to 2.6.4 beta), was +detected, that caused failure during opening of database files when +running a threaded slapd on a linux box. + +Apply the supported patch at the root directory of Sleepycat´s code. +Since the bug was reported to Sleepycat, it may not appear in DB +versions, later than 2.6.4 beta. + +Jan 5 1999, /KSp (ksp@openldap.org) + diff --git a/include/ldapconfig.h.edit b/include/ldapconfig.h.edit index 4acdfd8cd4..2b7e09cde9 100644 --- a/include/ldapconfig.h.edit +++ b/include/ldapconfig.h.edit @@ -215,8 +215,12 @@ Please try again later.\r\n" #define SLAPD_DEFAULT_TIMELIMIT 3600 /* location of the slapd pid file */ #define SLAPD_PIDFILE "%RUNDIR%/slapd.pid" +#define SLAPD_PIDDIR "%RUNDIR%/" +#define SLAPD_PIDEXT ".pid" /* location of the slapd args file */ #define SLAPD_ARGSFILE "%RUNDIR%/slapd.args" +#define SLAPD_ARGSDIR "%RUNDIR%/" +#define SLAPD_ARGSEXT ".args" /* dn of the special "monitor" entry */ #define SLAPD_MONITOR_DN "cn=monitor" /* dn of the special "config" entry */ diff --git a/libraries/libldap/getfilter.c b/libraries/libldap/getfilter.c index a780851688..0f41107a20 100644 --- a/libraries/libldap/getfilter.c +++ b/libraries/libldap/getfilter.c @@ -40,6 +40,7 @@ ldap_init_getfilter( char *fname ) int eof; LDAPFiltDesc *lfdp; + if (( fp = fopen( fname, "r" )) == NULL ) { return( NULL ); } @@ -89,6 +90,7 @@ ldap_init_getfilter_buf( char *buf, long buflen ) int rc; regex_t re; + if (( lfdp = (LDAPFiltDesc *)calloc( 1, sizeof( LDAPFiltDesc))) == NULL ) { return( NULL ); } diff --git a/libraries/libldbm/ldbm.c b/libraries/libldbm/ldbm.c index 72a212f8ca..35fd2154ca 100644 --- a/libraries/libldbm/ldbm.c +++ b/libraries/libldbm/ldbm.c @@ -2,12 +2,15 @@ /* Patched for Berkeley DB version 2.0; /KSp; 98/02/23 * - * - basic implementation; 1998/02/23, /KSp + * - DB version 2.6.4b ; 1998/12/28, /KSp * - DB_DBT_MALLOC ; 1998/03/22, /KSp + * - basic implementation; 1998/02/23, /KSp */ #include "portable.h" +#include "syslog.h" + #ifdef SLAPD_LDBM #include @@ -38,6 +41,21 @@ ldbm_malloc( size_t size ) return( calloc( 1, size )); } +/* a dbEnv for BERKELEYv2 */ +#include "lthread.h" + +DB_ENV dbEnv; +int dbEnvInit = 0; +pthread_mutex_t dbEnvInit_mutex; + +void +ldbm_db_errcall( char *prefix, char *message ) +{ + + syslog( LOG_INFO, "ldbm_db_errcall(): %s %s", prefix, message ); + +} + #endif @@ -49,12 +67,57 @@ ldbm_open( char *name, int rw, int mode, int dbcachesize ) #ifdef HAVE_BERKELEY_DB2 DB_INFO dbinfo; + /* initialize an environment for the DB application */ + pthread_mutex_lock( &dbEnvInit_mutex ); + + if ( !dbEnvInit ) { + char *dir; + char tmp[BUFSIZ]; + int err = 0; + int envFlags = DB_CREATE | DB_THREAD; + + strcpy( tmp, name ); + if ( ( dir = strrchr( tmp, '/' )) ) { + + *dir ='\0'; + dir = tmp; + + } else { + + dir = "/"; + + } + + memset( &dbEnv, 0, sizeof( dbEnv )); + + dbEnv.db_errcall = ldbm_db_errcall; + dbEnv.db_errpfx = "==>"; + + if ( ( err = db_appinit( NULL, NULL, &dbEnv, envFlags )) ) { + char error[BUFSIZ]; + + if ( err < 0 ) sprintf( error, "%ld\n", (long) err ); + else sprintf( error, "%s\n", strerror( err )); + + syslog( LOG_INFO, + "ldbm_open(): FATAL error in db_appinit(%s) : %s\n", + dir, error ); + + exit( 1 ); + + } + + dbEnvInit = 1; + + } + pthread_mutex_unlock( &dbEnvInit_mutex ); + memset( &dbinfo, 0, sizeof( dbinfo )); dbinfo.db_cachesize = dbcachesize; dbinfo.db_pagesize = DEFAULT_DB_PAGE_SIZE; dbinfo.db_malloc = ldbm_malloc; - (void) db_open( name, DB_TYPE, rw, mode, NULL, &dbinfo, &ret ); + (void) db_open( name, DB_TYPE, rw, mode, &dbEnv, &dbinfo, &ret ); #else void *info; diff --git a/servers/slapd/Makefile.in b/servers/slapd/Makefile.in index 059c8f2b18..5b0c6ed0d4 100644 --- a/servers/slapd/Makefile.in +++ b/servers/slapd/Makefile.in @@ -106,6 +106,7 @@ install-local-srv: install-slapd install-conf install-tools install-slapd: FORCE @-$(MKDIR) $(libexecdir) + @-$(MKDIR) $(localstatedir) $(LTINSTALL) $(INSTALLFLAGS) -m 755 slapd $(libexecdir) CFFILES=slapd.conf slapd.at.conf slapd.oc.conf diff --git a/servers/slapd/back-ldbm/init.c b/servers/slapd/back-ldbm/init.c index 1f322e67bc..8715779896 100644 --- a/servers/slapd/back-ldbm/init.c +++ b/servers/slapd/back-ldbm/init.c @@ -19,6 +19,8 @@ ldbm_back_init( char *argv[ 4 ]; int i; + extern pthread_mutex_t dbEnvInit_mutex; + /* allocate backend-specific stuff */ li = (struct ldbminfo *) ch_calloc( 1, sizeof(struct ldbminfo) ); @@ -74,6 +76,7 @@ ldbm_back_init( pthread_cond_init( &li->li_dbcache[i].dbc_cv, pthread_condattr_default ); } + pthread_mutex_init( &dbEnvInit_mutex, pthread_mutexattr_default ); be->be_private = li; } diff --git a/servers/slapd/daemon.c b/servers/slapd/daemon.c index 3412fec5e4..ae28246e5f 100644 --- a/servers/slapd/daemon.c +++ b/servers/slapd/daemon.c @@ -40,6 +40,12 @@ static volatile sig_atomic_t slapd_shutdown = 0; static void set_shutdown(int sig); static void do_nothing (int sig); +/* we need the server's name for constructing the pid/args file names */ +#if defined( SLAPD_PIDFILE ) || defined( SLAPD_ARGSFILE ) +extern char *serverName; +#define DEFAULT_SERVERNAME "slapd" +#endif + void * slapd_daemon( void *port @@ -56,6 +62,13 @@ slapd_daemon( FILE *fp; int on = 1; +#ifdef SLAPD_PIDFILE + char pidFile[BUFSIZ]; +#endif +#ifdef SLAPD_ARGSFILE + char argsFile[BUFSIZ]; +#endif + #ifdef HAVE_SYSCONF dtblsize = sysconf( _SC_OPEN_MAX ); #elif HAVE_GETDTABLESIZE @@ -135,14 +148,21 @@ slapd_daemon( (void) SIGNAL( SIGHUP, set_shutdown ); Debug( LDAP_DEBUG_ANY, "slapd starting\n", 0, 0, 0 ); + +#if defined( SLAPD_PIDFILE ) || defined( SLAPD_ARGSFILE ) + if ( !serverName ) serverName = DEFAULT_SERVERNAME; +#endif + #ifdef SLAPD_PIDFILE - if ( (fp = fopen( SLAPD_PIDFILE, "w" )) != NULL ) { + sprintf( pidFile, "%s%s%s", SLAPD_PIDDIR, serverName, SLAPD_PIDEXT ); + if ( (fp = fopen( pidFile, "w" )) != NULL ) { fprintf( fp, "%d\n", (int) getpid() ); fclose( fp ); } #endif #ifdef SLAPD_ARGSFILE - if ( (fp = fopen( SLAPD_ARGSFILE, "w" )) != NULL ) { + sprintf( argsFile, "%s%s%s", SLAPD_ARGSDIR, serverName, SLAPD_ARGSEXT ); + if ( (fp = fopen( argsFile, "w" )) != NULL ) { for ( i = 0; i < g_argc; i++ ) { fprintf( fp, "%s ", g_argv[i] ); } diff --git a/servers/slapd/main.c b/servers/slapd/main.c index afc42a316a..30dc6cf9af 100644 --- a/servers/slapd/main.c +++ b/servers/slapd/main.c @@ -58,10 +58,58 @@ pthread_mutex_t num_sent_mutex; pthread_mutex_t entry2str_mutex; pthread_mutex_t replog_mutex; +/* + * when more than one slapd is running on one machine, each one might have + * it's own LOCAL for syslogging and must have its own pid/args files + */ + +#ifdef LOG_LOCAL4 + +#define DEFAULT_SYSLOG_USER LOG_LOCAL4 + +typedef struct _str2intDispatch { + + char *stringVal; + int abbr; + int intVal; + +} STRDISP, *STRDISP_P; + + +/* table to compute syslog-options to integer */ +static STRDISP syslog_types[] = { + + { "LOCAL0", 6, LOG_LOCAL0 }, + { "LOCAL1", 6, LOG_LOCAL1 }, + { "LOCAL2", 6, LOG_LOCAL2 }, + { "LOCAL3", 6, LOG_LOCAL3 }, + { "LOCAL4", 6, LOG_LOCAL4 }, + { "LOCAL5", 6, LOG_LOCAL5 }, + { "LOCAL6", 6, LOG_LOCAL6 }, + { "LOCAL7", 6, LOG_LOCAL7 }, + NULL + +}; + +static int cnvt_str2int(); + +#endif /* LOG_LOCAL4 */ + +/* + * the server's name must be accessible from the daemon module, + * to construct the pid/args file names + */ +char *serverName = NULL; + + static void usage( char *name ) { - fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]\n", name ); + fprintf( stderr, "usage: %s [-d ?|debuglevel] [-f configfile] [-p portnumber] [-s sysloglevel]", name ); +#ifdef LOG_LOCAL4 + fprintf( stderr, " [-l sysloguser]" ); +#endif + fprintf( stderr, "\n" ); } int @@ -70,9 +118,11 @@ main( int argc, char **argv ) int i; int inetd = 0; int port; - char *myname; Backend *be = NULL; FILE *fp = NULL; +#ifdef LOG_LOCAL4 + int syslogUser = DEFAULT_SYSLOG_USER; +#endif configfile = SLAPD_DEFAULT_CONFIGFILE; port = LDAP_PORT; @@ -139,6 +189,15 @@ main( int argc, char **argv ) ldap_syslog = atoi( optarg ); break; +#ifdef LOG_LOCAL4 + + case 'l': /* set syslog local user */ + syslogUser = cnvt_str2int( optarg, syslog_types, + DEFAULT_SYSLOG_USER ); + break; + +#endif + case 'u': /* do udp */ udp = 1; break; @@ -155,10 +214,10 @@ main( int argc, char **argv ) Debug( LDAP_DEBUG_TRACE, "%s", Versionstr, 0, 0 ); - if ( (myname = strrchr( argv[0], '/' )) == NULL ) { - myname = ch_strdup( argv[0] ); + if ( (serverName = strrchr( argv[0], '/' )) == NULL ) { + serverName = ch_strdup( argv[0] ); } else { - myname = ch_strdup( myname + 1 ); + serverName = ch_strdup( serverName + 1 ); } if ( ! inetd ) { @@ -170,10 +229,11 @@ main( int argc, char **argv ) lutil_detach( 0, 0 ); #endif } + #ifdef LOG_LOCAL4 - openlog( myname, OPENLOG_OPTIONS, LOG_LOCAL4 ); + openlog( serverName, OPENLOG_OPTIONS, syslogUser ); #else - openlog( myname, OPENLOG_OPTIONS ); + openlog( serverName, OPENLOG_OPTIONS ); #endif init(); @@ -280,3 +340,37 @@ main( int argc, char **argv ) } return 1; } + + +#ifdef LOG_LOCAL4 + +/* + * Convert a string to an integer by means of a dispatcher table + * if the string is not in the table return the default + */ + +static int +cnvt_str2int (stringVal, dispatcher, defaultVal) +char *stringVal; +STRDISP_P dispatcher; +int defaultVal; +{ + int retVal = defaultVal; + STRDISP_P disp; + + for (disp = dispatcher; disp->stringVal; disp++) { + + if (!strncasecmp (stringVal, disp->stringVal, disp->abbr)) { + + retVal = disp->intVal; + break; + + } + } + + return (retVal); + +} /* cnvt_str2int */ + +#endif /* LOG_LOCAL4 */ + -- 2.39.5