Cleanup slapd-specific NT service support

This commit is contained in:
Howard Chu 2003-03-03 11:46:05 +00:00
parent 13b96bc479
commit 3b01c9a99e
7 changed files with 89 additions and 123 deletions

View File

@ -6,7 +6,6 @@
/*
* NT Service manager utilities for OpenLDAP services
* these should NOT be slapd specific, but are
*/
#include "portable.h"
@ -23,17 +22,6 @@
#include <ldap.h>
/*
* The whole debug implementation is a bit of a hack.
* We have to define this LDAP_SLAPD_V macro here since the slap.h
* header file isn't included (and really shouldn't be).
* TODO: re-implement debug functions so that the debug level can
* be passed around instead of having to count on the existence of
* ldap_debug, slap_debug, etc.
*/
#define ldap_debug slap_debug
LDAP_SLAPD_V (int) slap_debug;
#include "ldap_log.h"
#include "ldap_pvt_thread.h"
@ -47,8 +35,8 @@ LDAP_SLAPD_V (int) slap_debug;
int is_NT_Service; /* is this is an NT service? */
SERVICE_STATUS SLAPDServiceStatus;
SERVICE_STATUS_HANDLE hSLAPDServiceStatus;
SERVICE_STATUS lutil_ServiceStatus;
SERVICE_STATUS_HANDLE hlutil_ServiceStatus;
ldap_pvt_thread_cond_t started_event, stopped_event;
ldap_pvt_thread_t start_status_tid, stop_status_tid;
@ -57,8 +45,8 @@ void (*stopfunc)(int);
static char *GetLastErrorString( void );
int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
LPCTSTR lpszBinaryPathName, BOOL auto_start)
int lutil_srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
LPCTSTR lpszBinaryPathName, int auto_start)
{
HKEY hKey;
DWORD dwValue, dwDisposition;
@ -129,7 +117,7 @@ int srv_install(LPCTSTR lpszServiceName, LPCTSTR lpszDisplayName,
}
int srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
int lutil_srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
{
SC_HANDLE schSCManager, schService;
@ -162,6 +150,7 @@ int srv_remove(LPCTSTR lpszServiceName, LPCTSTR lpszBinaryPathName)
}
#if 0 /* unused */
DWORD
svc_installed (LPTSTR lpszServiceName, LPTSTR lpszBinaryPathName)
{
@ -212,7 +201,7 @@ svc_running (LPTSTR lpszServiceName)
CloseServiceHandle(scm);
return(rc);
}
#endif
static void *start_status_routine( void *ptr )
{
@ -229,27 +218,27 @@ static void *start_status_routine( void *ptr )
/* the object that we were waiting for has been destroyed (ABANDONED) or
* signalled (TIMEOUT_0). We can assume that the startup process is
* complete and tell the Service Control Manager that we are now runnng */
SLAPDServiceStatus.dwCurrentState = SERVICE_RUNNING;
SLAPDServiceStatus.dwWin32ExitCode = NO_ERROR;
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = 1000;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
lutil_ServiceStatus.dwWin32ExitCode = NO_ERROR;
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = 1000;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
done = 1;
break;
case WAIT_TIMEOUT:
/* We've waited for the required time, so send an update to the Service Control
* Manager saying to wait again. */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
break;
case WAIT_FAILED:
/* theres been some problem with WaitForSingleObject so tell the Service
* Control Manager to wait 30 seconds before deploying its assasin and
* then leave the thread. */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
done = 1;
break;
}
@ -281,17 +270,17 @@ static void *stop_status_routine( void *ptr )
case WAIT_TIMEOUT:
/* We've waited for the required time, so send an update to the Service Control
* Manager saying to wait again. */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
break;
case WAIT_FAILED:
/* theres been some problem with WaitForSingleObject so tell the Service
* Control Manager to wait 30 seconds before deploying its assasin and
* then leave the thread. */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
done = 1;
break;
}
@ -302,27 +291,26 @@ static void *stop_status_routine( void *ptr )
void WINAPI SLAPDServiceCtrlHandler( IN DWORD Opcode)
void WINAPI lutil_ServiceCtrlHandler( IN DWORD Opcode)
{
switch (Opcode)
{
case SERVICE_CONTROL_STOP:
case SERVICE_CONTROL_SHUTDOWN:
Debug( LDAP_DEBUG_TRACE, "Service Shutdown ordered\n", 0, 0, 0 );
SLAPDServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
ldap_pvt_thread_cond_init( &stopped_event );
if ( stopped_event == NULL )
{
/* the event was not created. We will ask the service control manager for 30
* seconds to shutdown */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
}
else
{
@ -337,22 +325,22 @@ void WINAPI SLAPDServiceCtrlHandler( IN DWORD Opcode)
* service stopping is proceeding.
* tell the Service Control Manager to wait another 30 seconds before deploying its
* assasin. */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
}
}
stopfunc( -1 );
break;
case SERVICE_CONTROL_INTERROGATE:
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
break;
}
return;
}
void *getRegParam( char *svc, char *value )
void *lutil_getRegParam( char *svc, char *value )
{
HKEY hkey;
char path[255];
@ -367,13 +355,11 @@ void *getRegParam( char *svc, char *value )
if ( RegOpenKeyEx( HKEY_LOCAL_MACHINE, path, 0, KEY_READ, &hkey ) != ERROR_SUCCESS )
{
/*Debug( LDAP_DEBUG_ANY, "RegOpenKeyEx() %s\n", GetLastErrorString(), 0, 0); */
return NULL;
}
if ( RegQueryValueEx( hkey, value, NULL, &vType, vValue, &valLen ) != ERROR_SUCCESS )
{
/*Debug( LDAP_DEBUG_ANY, "RegQueryValueEx() %s\n", GetLastErrorString(), 0, 0 );*/
RegCloseKey( hkey );
return NULL;
}
@ -390,7 +376,7 @@ void *getRegParam( char *svc, char *value )
return (void*)NULL;
}
void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *urls )
void lutil_LogStartedEvent( char *svc, int slap_debug, char *configfile, char *urls )
{
char *Inserts[5];
WORD i = 0, j;
@ -402,10 +388,9 @@ void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *ur
itoa( slap_debug, Inserts[i++], 10 );
Inserts[i++] = strdup( configfile );
Inserts[i++] = strdup( urls ? urls : "ldap:///" );
Inserts[i++] = strdup( is_NT_Service ? "svc" : "cmd" );
ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,
MSG_SLAPD_STARTED, NULL, i, 0, (LPCSTR *) Inserts, NULL );
MSG_SVC_STARTED, NULL, i, 0, (LPCSTR *) Inserts, NULL );
for ( j = 0; j < i; j++ )
ldap_memfree( Inserts[j] );
@ -414,34 +399,34 @@ void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *ur
void LogSlapdStoppedEvent( char *svc )
void lutil_LogStoppedEvent( char *svc )
{
HANDLE hEventLog;
hEventLog = RegisterEventSource( NULL, svc );
ReportEvent( hEventLog, EVENTLOG_INFORMATION_TYPE, 0,
MSG_SLAPD_STOPPED, NULL, 0, 0, NULL, NULL );
MSG_SVC_STOPPED, NULL, 0, 0, NULL, NULL );
DeregisterEventSource( hEventLog );
}
void CommenceStartupProcessing( LPCTSTR lpszServiceName,
void lutil_CommenceStartupProcessing( char *lpszServiceName,
void (*stopper)(int) )
{
hSLAPDServiceStatus = RegisterServiceCtrlHandler( lpszServiceName, (LPHANDLER_FUNCTION)SLAPDServiceCtrlHandler);
hlutil_ServiceStatus = RegisterServiceCtrlHandler( lpszServiceName, (LPHANDLER_FUNCTION)lutil_ServiceCtrlHandler);
stopfunc = stopper;
/* initialize the Service Status structure */
SLAPDServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
SLAPDServiceStatus.dwCurrentState = SERVICE_START_PENDING;
SLAPDServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
SLAPDServiceStatus.dwWin32ExitCode = NO_ERROR;
SLAPDServiceStatus.dwServiceSpecificExitCode = 0;
SLAPDServiceStatus.dwCheckPoint = 1;
SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
lutil_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
lutil_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
lutil_ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
lutil_ServiceStatus.dwWin32ExitCode = NO_ERROR;
lutil_ServiceStatus.dwServiceSpecificExitCode = 0;
lutil_ServiceStatus.dwCheckPoint = 1;
lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL * 2;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
/* start up a thread to keep sending SERVICE_START_PENDING to the Service Control Manager
* until the slapd listener is completed and listening. Only then should we send
@ -452,9 +437,9 @@ void CommenceStartupProcessing( LPCTSTR lpszServiceName,
/* failed to create the event to determine when the startup process is complete so
* tell the Service Control Manager to wait another 30 seconds before deploying its
* assasin */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
}
else
{
@ -469,14 +454,14 @@ void CommenceStartupProcessing( LPCTSTR lpszServiceName,
* service startup is proceeding.
* tell the Service Control Manager to wait another 30 seconds before deploying its
* assasin. */
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = THIRTY_SECONDS;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
}
}
}
void ReportSlapdShutdownComplete( )
void lutil_ReportShutdownComplete( )
{
if ( is_NT_Service )
{
@ -489,10 +474,10 @@ void ReportSlapdShutdownComplete( )
if (ldap_pvt_thread_join( stop_status_tid, (void *) NULL ) == -1)
ldap_pvt_thread_sleep( SCM_NOTIFICATION_INTERVAL / 2 );
SLAPDServiceStatus.dwCurrentState = SERVICE_STOPPED;
SLAPDServiceStatus.dwCheckPoint++;
SLAPDServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL;
SetServiceStatus(hSLAPDServiceStatus, &SLAPDServiceStatus);
lutil_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
lutil_ServiceStatus.dwCheckPoint++;
lutil_ServiceStatus.dwWaitHint = SCM_NOTIFICATION_INTERVAL;
SetServiceStatus(hlutil_ServiceStatus, &lutil_ServiceStatus);
}
}

Binary file not shown.

View File

@ -46,20 +46,20 @@
//
// MessageId: MSG_SLAPD_STARTED
// MessageId: MSG_SVC_STARTED
//
// MessageText:
//
// OpenLDAP SLAPD service started. debuglevel=%1, conffile=%2, urls=%3, mode=%4
// OpenLDAP service started. debuglevel=%1, conffile=%2, urls=%3
//
#define MSG_SLAPD_STARTED 0x40000500L
#define MSG_SVC_STARTED 0x40000500L
//
// MessageId: MSG_SLAPD_STOPPED
// MessageId: MSG_SVC_STOPPED
//
// MessageText:
//
// OpenLDAP SLAPD service stopped.
// OpenLDAP service stopped.
//
#define MSG_SLAPD_STOPPED 0x40000501L
#define MSG_SVC_STOPPED 0x40000501L

View File

@ -12,17 +12,17 @@
MessageID=0x500
Severity=Informational
SymbolicName=MSG_SLAPD_STARTED
SymbolicName=MSG_SVC_STARTED
Facility=Application
Language=English
OpenLDAP SLAPD service started. debuglevel=%1, conffile=%2, urls=%3, mode=%4
OpenLDAP service started. debuglevel=%1, conffile=%2, urls=%3
.
MessageID=0x501
Severity=Informational
SymbolicName=MSG_SLAPD_STOPPED
SymbolicName=MSG_SVC_STOPPED
Facility=Application
Language=English
OpenLDAP SLAPD service stopped.
OpenLDAP service stopped.
.

View File

@ -1,2 +1,2 @@
LANGUAGE 0x9,0x4
LANGUAGE 0x9,0x1
1 11 slapdmsg.bin

View File

@ -32,16 +32,10 @@ static RETSIGTYPE wait4child( int sig );
#define MAIN_RETURN(x) return
static struct sockaddr_in bind_addr;
/* FIXME: no externs should appear in a .c, should be in a .h instead */
extern void CommenceStartupProcessing( LPCTSTR serverName,
void(*stopper)(int));
extern void ReportSlapdShutdownComplete( void );
extern void *getRegParam( char *svc, char *value );
#define SERVICE_EXIT( e, n ) do { \
if ( is_NT_Service ) { \
SLAPDServiceStatus.dwWin32ExitCode = (e); \
SLAPDServiceStatus.dwServiceSpecificExitCode = (n); \
lutil_ServiceStatus.dwWin32ExitCode = (e); \
lutil_ServiceStatus.dwServiceSpecificExitCode = (n); \
} \
} while ( 0 )
@ -50,11 +44,6 @@ extern void *getRegParam( char *svc, char *value );
#define MAIN_RETURN(x) return(x)
#endif
#ifdef HAVE_NT_EVENT_LOG
void LogSlapdStartedEvent( char *svc, int slap_debug, char *configfile, char *urls );
void LogSlapdStoppedEvent( char *svc );
#endif
/*
* 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
@ -171,12 +160,12 @@ int main( int argc, char **argv )
if ( is_NT_Service ) {
serverName = argv[0];
CommenceStartupProcessing( serverName, slap_sig_shutdown );
lutil_CommenceStartupProcessing( serverName, slap_sig_shutdown );
if ( strcmp(serverName, SERVICE_NAME) )
regService = serverName;
}
i = (int*)getRegParam( regService, "DebugLevel" );
i = (int*)lutil_getRegParam( regService, "DebugLevel" );
if ( i != NULL )
{
slap_debug = *i;
@ -190,7 +179,7 @@ int main( int argc, char **argv )
#endif
}
newUrls = (char *) getRegParam(regService, "Urls");
newUrls = (char *) lutil_getRegParam(regService, "Urls");
if (newUrls)
{
if (urls)
@ -207,7 +196,7 @@ int main( int argc, char **argv )
}
newConfigFile = (char*)getRegParam( regService, "ConfigFile" );
newConfigFile = (char*)lutil_getRegParam( regService, "ConfigFile" );
if ( newConfigFile != NULL )
{
configfile = newConfigFile;
@ -574,7 +563,7 @@ int main( int argc, char **argv )
#ifdef HAVE_NT_EVENT_LOG
if (is_NT_Service)
LogSlapdStartedEvent( serverName, slap_debug, configfile, urls );
lutil_LogStartedEvent( serverName, slap_debug, configfile, urls );
#endif
rc = slapd_daemon();
@ -602,7 +591,7 @@ destroy:
stop:
#ifdef HAVE_NT_EVENT_LOG
if (is_NT_Service)
LogSlapdStoppedEvent( serverName );
lutil_LogStoppedEvent( serverName );
#endif
#ifdef NEW_LOGGING
@ -613,7 +602,7 @@ stop:
#ifdef HAVE_NT_SERVICE_MANAGER
ReportSlapdShutdownComplete();
lutil_ReportShutdownComplete();
#endif
#ifdef LOG_DEBUG

View File

@ -16,12 +16,6 @@
void WINAPI ServiceMain( DWORD argc, LPTSTR *argv );
/* in ntservice.c */
int srv_install( char* service, char * displayName, char* filename,
BOOL auto_start );
int srv_remove ( char* service, char* filename );
DWORD svc_installed (LPTSTR lpszServiceName, LPTSTR lpszBinaryPathName);
DWORD svc_running (LPTSTR lpszServiceName);
int main( int argc, LPTSTR *argv )
{
int length;
@ -30,10 +24,7 @@ int main( int argc, LPTSTR *argv )
/*
* Because the service was registered as SERVICE_WIN32_OWN_PROCESS,
* the lpServiceName element of the SERVICE_TABLE_ENTRY will be
* ignored. Since we don't even know the name of the service at
* this point (since it could have been installed under a name
* different than SERVICE_NAME), we might as well just provide
* the parameter as "".
* ignored.
*/
SERVICE_TABLE_ENTRY DispatchTable[] = {
@ -42,8 +33,9 @@ int main( int argc, LPTSTR *argv )
};
/*
// set the service's current directory to being the installation directory for the service.
// this way we don't have to write absolute paths in the configuration files
* set the service's current directory to the installation directory
* for the service. this way we don't have to write absolute paths
* in the configuration files
*/
GetModuleFileName( NULL, filename, sizeof( filename ) );
fname_start = strrchr( filename, *LDAP_DIRSEP );
@ -65,7 +57,7 @@ int main( int argc, LPTSTR *argv )
auto_start = TRUE;
strcat(filename, " service");
if ( !srv_install(svcName, displayName, filename, auto_start) )
if ( !lutil_srv_install(svcName, displayName, filename, auto_start) )
{
fputs( "service failed installation ...\n", stderr );
return EXIT_FAILURE;
@ -79,7 +71,7 @@ int main( int argc, LPTSTR *argv )
char *svcName = SERVICE_NAME;
if ( (argc > 2) && (argv[2] != NULL) )
svcName = argv[2];
if ( !srv_remove(svcName, filename) )
if ( !lutil_srv_remove(svcName, filename) )
{
fputs( "failed to remove the service ...\n", stderr );
return EXIT_FAILURE;