mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Ludovic Poitou
08.26.2013 161fa81eb1a6a9f0d647966ee38acb36d6ad00dd
Fix for OPENDJ-617.
Resolve race condition in Windows Services when stopping the server.
8 files modified
101 ■■■■ changed files
opendj-sdk/opends/lib/launcher_administrator.exe patch | view | raw | blame | history
opendj-sdk/opends/lib/opendj_service.exe patch | view | raw | blame | history
opendj-sdk/opends/lib/winlauncher.exe patch | view | raw | blame | history
opendj-sdk/opends/src/build-tools/windows/service.c 61 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/build-tools/windows/service.h 2 ●●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java 13 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java 4 ●●● patch | view | raw | blame | history
opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java 21 ●●●● patch | view | raw | blame | history
opendj-sdk/opends/lib/launcher_administrator.exe
Binary files differ
opendj-sdk/opends/lib/opendj_service.exe
Binary files differ
opendj-sdk/opends/lib/winlauncher.exe
Binary files differ
opendj-sdk/opends/src/build-tools/windows/service.c
@@ -23,7 +23,7 @@
*
*
*      Copyright 2008-2010 Sun Microsystems, Inc.
*      Portions Copyright 2011 ForgeRock AS
*      Portions Copyright 2011-2013 ForgeRock AS
*/
#include "service.h"
@@ -658,7 +658,7 @@
// ----------------------------------------------------
// Start the application using stop-ds.bat
// Stop the application using stop-ds.bat
// The functions returns SERVICE_RETURN_OK if we could stop the server
// and SERVICE_RETURN_ERROR otherwise.
// ----------------------------------------------------
@@ -956,6 +956,53 @@
}  // updateServiceStatus
// ----------------------------------------------------
// Query the current status of the service serviceName into returnedStatus
// return true if it was successful, false otherwise
// ----------------------------------------------------
BOOL getServiceStatus(char *serviceName, LPDWORD returnedState)
{
  SC_HANDLE hScm;
  SC_HANDLE hService;
  BOOL ret = FALSE;
  if (openScm(SC_MANAGER_ALL_ACCESS, &hScm) != SERVICE_RETURN_OK)
  {
    debugError("getServiceStatus: openScm did not work. Last error = %d",
    GetLastError());
    return FALSE;
  }
  hService = OpenService(hScm, serviceName, SERVICE_QUERY_STATUS);
  if(hService == NULL)
  {
    debugError("getServiceStatus: openService did not work. Last error = %d",
      GetLastError());
  }
  else
  {
    SERVICE_STATUS ss;
    memset(&ss, 0, sizeof(ss));
    if (QueryServiceStatus(hService, &ss))
    {
      *returnedState = ss.dwCurrentState;
    ret = TRUE;
  }
  else
  {
    debugError("getServiceStatus: Failed to query the service status. Last error = %d",
                  GetLastError());
    }
    // close the service handle
    CloseServiceHandle(hService);
  }
  // close the service control manager handle
  CloseServiceHandle(hScm);
  return ret;
}
// ----------------------------------------------------
// This function is the "main" of the service. It has been registered
// to the SCM by the main right after the service has been started through
// NET START command.
@@ -1156,10 +1203,17 @@
        }
        else
        {
      // Check current Status
      DWORD state;
      BOOL success = getServiceStatus(serviceName, &state);
          if (!(success &&
               ((state == SERVICE_STOPPED) ||
                (state == SERVICE_STOP_PENDING))))
          {
          WORD argCount = 1;
          const char *argc[] = {_instanceDir};    
          _serviceCurStatus = SERVICE_STOPPED;
          debug("checking in serviceMain serviceHandler: service stopped.");
            debug("checking in serviceMain serviceHandler: service stopped with error.");
          updateServiceStatus (
              _serviceCurStatus,
@@ -1172,6 +1226,7 @@
              EVENTLOG_ERROR_TYPE,
              WIN_EVENT_ID_SERVER_STOPPED_OUTSIDE_SCM,
              argCount, argc);
           }
          break;
        }
      }
opendj-sdk/opends/src/build-tools/windows/service.h
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS.
 */
#include "common.h"
@@ -106,4 +107,5 @@
   SERVICE_STATUS_HANDLE *serviceStatusHandle
   );
void serviceHandler(DWORD controlCode);
BOOL getServiceStatus(char *serviceName, LPDWORD returnState);
opendj-sdk/opends/src/server/org/opends/server/tools/ConfigureWindowsService.java
@@ -23,7 +23,7 @@
 *
 *
 *      Copyright 2008-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011 ForgeRock AS
 *      Portions Copyright 2011-2013 ForgeRock AS
 */
package org.opends.server.tools;
@@ -686,6 +686,7 @@
      returnValue = SERVICE_CLEANUP_ERROR;
      msg = ERR_WINDOWS_SERVICE_CLEANUP_ERROR.get(serviceName);
      err.println(msg);
      err.println("Exception:" + t.toString());
    }
    return returnValue;
  }
@@ -763,10 +764,10 @@
        break;
      case 2:
        returnValue = SERVICE_STATE_ERROR;
        if (out != null)
        if (err != null)
        {
          msg = ERR_WINDOWS_SERVICE_STATE_ERROR.get();
          out.println(msg);
          err.println(msg);
        }
        break;
      default:
@@ -784,7 +785,8 @@
      if (err != null)
      {
        msg = ERR_WINDOWS_SERVICE_STATE_ERROR.get();
        err.println(wrapText(msg, MAX_LINE_WIDTH));
        err.println(msg);
        err.println(wrapText(t.toString(), MAX_LINE_WIDTH));
      }
    }
    return returnValue;
@@ -806,8 +808,7 @@
       * Do a best effort to avoid having a relative representation (for
       * instance to avoid having ../../../).
       */
      File canonical = f.getCanonicalFile();
      f = canonical;
      f = f.getCanonicalFile();
    }
    catch (IOException ioe)
    {
opendj-sdk/opends/src/server/org/opends/server/tools/StartWindowsService.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2013 ForgeRock AS.
 */
package org.opends.server.tools;
@@ -151,7 +152,8 @@
      {
        Message message = ERR_WINDOWS_SERVICE_START_ERROR.get();
        out.println(message);
        err.println(message);
        err.println("Exception:" + t.toString());
        returnValue = SERVICE_START_ERROR;
      }
    }
opendj-sdk/opends/src/server/org/opends/server/tools/StopWindowsService.java
@@ -23,7 +23,7 @@
 *
 *
 *      Copyright 2008-2009 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 *      Portions Copyright 2012-2013 ForgeRock AS
 */
package org.opends.server.tools;
@@ -55,10 +55,6 @@
    */
  public static final int SERVICE_NOT_FOUND = 1;
  /**
    * The service was already stopped.
    */
  public static final int SERVICE_ALREADY_STOPPED = 2;
  /**
    * The service could not be stopped.
    */
  public static final int SERVICE_STOP_ERROR = 3;
@@ -79,9 +75,8 @@
   * Invokes the net stop on the service corresponding to this server, it writes
   * information and error messages in the provided streams.
   * @return <CODE>SERVICE_STOP_SUCCESSFUL</CODE>,
   * <CODE>SERVICE_NOT_FOUND</CODE>, <CODE>SERVICE_ALREADY_STOPPED</CODE> or
   * <CODE>SERVICE_STOP_ERROR</CODE> depending on whether the service could be
   * stopped or not.
   * <CODE>SERVICE_NOT_FOUND</CODE> or <CODE>SERVICE_STOP_ERROR</CODE>
   * depending on whether the service could be stopped or not.
   * @param  outStream  The stream to write standard output messages.
   * @param  errStream  The stream to write error messages.
   */
@@ -143,7 +138,12 @@
      /* Check if is a running service */
      try
      {
        if (Runtime.getRuntime().exec(cmd).waitFor() == 0)
        int resultCode = Runtime.getRuntime().exec(cmd).waitFor();
        if (resultCode == 0)
        {
          returnValue = SERVICE_STOP_SUCCESSFUL;
        }
        else if (resultCode == 2)
        {
          returnValue = SERVICE_STOP_SUCCESSFUL;
        }
@@ -156,7 +156,8 @@
      {
        Message message = ERR_WINDOWS_SERVICE_STOP_ERROR.get();
        out.println(message);
        err.println(message);
        err.println("Exception:" + t.toString());
        returnValue = SERVICE_STOP_ERROR;
      }
    }