]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 3506] NTPD/SCM interact not well
authorJuergen Perlinger <perlinger@ntp.org>
Tue, 3 Jul 2018 20:51:08 +0000 (22:51 +0200)
committerJuergen Perlinger <perlinger@ntp.org>
Tue, 3 Jul 2018 20:51:08 +0000 (22:51 +0200)
bk: 5b3be1bcZR9VdQNbk6hQwF54M3dT4A

ChangeLog
ntpd/ntpd.c
ports/winnt/include/ntservice.h
ports/winnt/ntpd/nt_clockstuff.c
ports/winnt/ntpd/ntservice.c

index 25bb8f0822355b0e64e235d115a29c650e2d4bd4..f730238ec9d8989c9ca68cd07aa90dba74121635 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,7 @@
 ---
 
+* [Bug 3506] NTPD/SCM interact not well <perlinger@ntp.org>
+  - changed interaction with SCM to signal pending startup
 * [Bug 3486] Buffer overflow in ntpq/ntpq.c:tstflags() <perlinger@ntp.org>
   - applied patch by Gerry Garvey
 * [Bug 3485] Undefined sockaddr used in error messages in ntp_config.c <perlinger@ntp.org>
index 645099f05155aa3f4a6703fa079884d73e7d4327..7d8f1186daba875204a26a4c48d9a6f8c4a1beaa 100644 (file)
 #endif
 #endif
 
+#ifdef SYS_WINNT
+# include "ntservice.h"
+#endif
+
 #ifdef _AIX
 # include <ulimit.h>
 #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 (;;) {
index f44335fdb3b9e1dabe2eef1e14ebde821cae3838..46c5bd657f08ab8408f1858457f16b4661208ef5 100644 (file)
@@ -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);
index fdb3c475fbd07eb17eeeb1656feda782bdf7c820..b937c34030f877a9ac3bd6bf6372dfdec448e3fc 100644 (file)
@@ -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");
index 2b9bc64caf5323cffb177632b25b903174a045b8..01aad478426a773a3a147c94a4850077165aed43 100644 (file)
@@ -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);
        }