From: Juergen Perlinger Date: Tue, 3 Jul 2018 20:51:08 +0000 (+0200) Subject: [Bug 3506] NTPD/SCM interact not well X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=422a57bf467309316f0f860a9f4539fdcd8942c6;p=thirdparty%2Fntp.git [Bug 3506] NTPD/SCM interact not well bk: 5b3be1bcZR9VdQNbk6hQwF54M3dT4A --- diff --git a/ChangeLog b/ChangeLog index 25bb8f082..f730238ec 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,7 @@ --- +* [Bug 3506] NTPD/SCM interact not well + - changed interaction with SCM to signal pending startup * [Bug 3486] Buffer overflow in ntpq/ntpq.c:tstflags() - applied patch by Gerry Garvey * [Bug 3485] Undefined sockaddr used in error messages in ntp_config.c diff --git a/ntpd/ntpd.c b/ntpd/ntpd.c index 645099f05..7d8f1186d 100644 --- a/ntpd/ntpd.c +++ b/ntpd/ntpd.c @@ -104,6 +104,10 @@ #endif #endif +#ifdef SYS_WINNT +# include "ntservice.h" +#endif + #ifdef _AIX # include #endif /* _AIX */ @@ -522,7 +526,7 @@ set_process_priority(void) } #endif /* !SIM */ -#ifndef SIM +#if !defined(SIM) && !defined(SYS_WINNT) /* * Detach from terminal (much like daemon()) * Nothe that this function calls exit() @@ -923,6 +927,11 @@ ntpdmain( init_lib(); # ifdef SYS_WINNT + /* + * Make sure the service is initialized before we do anything else + */ + ntservice_init(); + /* * Start interpolation thread, must occur before first * get_systime() @@ -1320,6 +1329,10 @@ int scmp_sc[] = { } #endif /* LIBSECCOMP and KERN_SECCOMP */ +#ifdef SYS_WINNT + ntservice_isup(); +#endif + # ifdef HAVE_IO_COMPLETION_PORT for (;;) { diff --git a/ports/winnt/include/ntservice.h b/ports/winnt/include/ntservice.h index f44335fdb..46c5bd657 100644 --- a/ports/winnt/include/ntservice.h +++ b/ports/winnt/include/ntservice.h @@ -22,6 +22,7 @@ #define NTP_SERVICE_NAME "ntpd" void ntservice_init(void); +void ntservice_isup(void); void UpdateSCM(DWORD); void WINAPI ServiceControl(DWORD dwCtrlCode); void ntservice_shutdown(void); diff --git a/ports/winnt/ntpd/nt_clockstuff.c b/ports/winnt/ntpd/nt_clockstuff.c index fdb3c475f..b937c3403 100644 --- a/ports/winnt/ntpd/nt_clockstuff.c +++ b/ports/winnt/ntpd/nt_clockstuff.c @@ -659,12 +659,6 @@ init_winnt_time(void) if (winnt_time_initialized) return; - /* - * Make sure the service is initialized - * before we do anything else - */ - ntservice_init(); - /* Set up the Console Handler */ if (!SetConsoleCtrlHandler(OnConsoleEvent, TRUE)) { msyslog(LOG_ERR, "Can't set console control handler: %m"); diff --git a/ports/winnt/ntpd/ntservice.c b/ports/winnt/ntpd/ntservice.c index 2b9bc64ca..01aad4784 100644 --- a/ports/winnt/ntpd/ntservice.c +++ b/ports/winnt/ntpd/ntservice.c @@ -46,10 +46,10 @@ extern int accept_wildcard_if_for_winnt; /* * Forward declarations */ -void uninit_io_completion_port(); -int ntpdmain(int argc, char *argv[]); -void WINAPI ServiceControl(DWORD dwCtrlCode); -void ntservice_exit(void); +extern void uninit_io_completion_port(); +extern int ntpdmain(int argc, char *argv[]); +extern void WINAPI ServiceControl(DWORD dwCtrlCode); +extern void ntservice_exit(void); #ifdef WRAP_DBG_MALLOC void *wrap_dbg_malloc(size_t s, const char *f, int l); @@ -147,7 +147,8 @@ int main( * Initialize the Service by registering it. */ void -ntservice_init() { +ntservice_init(void) +{ char ConsoleTitle[256]; if (!foreground) { @@ -156,10 +157,10 @@ ntservice_init() { ServiceControl); if (!hServiceStatus) { NTReportError(NTP_SERVICE_NAME, - "could not register service control handler"); + "could not register with SCM"); exit(1); } - UpdateSCM(SERVICE_RUNNING); + UpdateSCM(SERVICE_START_PENDING); } else { snprintf(ConsoleTitle, sizeof(ConsoleTitle), "NTP Version %s", Version); @@ -192,18 +193,32 @@ ntservice_init() { atexit( ntservice_exit ); } +void +ntservice_isup(void) +{ + if (!foreground) { + /* Register handler with the SCM */ + if (!hServiceStatus) { + NTReportError(NTP_SERVICE_NAME, + "could not report to SCM"); + exit(1); + } + UpdateSCM(SERVICE_RUNNING); + } +} /* * Routine to check if the service is stopping * because the computer is shutting down */ BOOL -ntservice_systemisshuttingdown() { +ntservice_systemisshuttingdown(void) +{ return computer_shutting_down; } void -ntservice_exit( void ) +ntservice_exit(void) { uninit_io_completion_port(); Sleep( 200 ); //##++ @@ -266,9 +281,15 @@ ServiceControl( /* * Tell the Service Control Manager the state of the service. */ -void UpdateSCM(DWORD state) { - SERVICE_STATUS ss; +void +UpdateSCM( + DWORD state + ) +{ static DWORD dwState = SERVICE_STOPPED; + static DWORD dwCheck = 0; + + SERVICE_STATUS ss; if (hServiceStatus) { if (state) @@ -277,12 +298,26 @@ void UpdateSCM(DWORD state) { ZERO(ss); ss.dwServiceType |= SERVICE_WIN32_OWN_PROCESS; ss.dwCurrentState = dwState; - ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | - SERVICE_ACCEPT_SHUTDOWN; - ss.dwCheckPoint = 0; - ss.dwServiceSpecificExitCode = 0; - ss.dwWin32ExitCode = NO_ERROR; - ss.dwWaitHint = dwState == SERVICE_STOP_PENDING ? 5000 : 1000; + /* ss.dwServiceSpecificExitCode = 0; default by ZERO(ss) */ + /* ss.dwWin32ExitCode = NO_ERROR; default by ZERO(ss) */ + + switch (dwState) { + case SERVICE_START_PENDING: + ss.dwControlsAccepted = 0; + ss.dwWaitHint = 15000; + ss.dwCheckPoint = ++dwCheck; + break; + case SERVICE_STOP_PENDING: + ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; + ss.dwWaitHint = 3000; + ss.dwCheckPoint = ++dwCheck; + break; + default: + ss.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN; + ss.dwWaitHint = 1000; + ss.dwCheckPoint = dwCheck = 0; + break; + } SetServiceStatus(hServiceStatus, &ss); }