From 4a48f1cf6caab40fa3741d93f8c825078e4820f2 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 04 May 2007 21:15:31 +0000
Subject: [PATCH] Fix a number of issues with David's approval:
---
opends/src/build-tools/windows/service.c | 264 ++++++++++++++++++++++++++++++++++++++++------------
1 files changed, 202 insertions(+), 62 deletions(-)
diff --git a/opends/src/build-tools/windows/service.c b/opends/src/build-tools/windows/service.c
index f476653..fe1ca4c 100644
--- a/opends/src/build-tools/windows/service.c
+++ b/opends/src/build-tools/windows/service.c
@@ -32,6 +32,7 @@
HANDLE _terminationEvent = NULL;
char *_instanceDir = NULL;
HANDLE _eventLog = NULL;
+char * _logFile = NULL;
BOOL DEBUG = FALSE;
@@ -73,15 +74,15 @@
} // registerServiceHandler
// ---------------------------------------------------
-// Debug utility. If the _eventLog is not NULL and the DEBUG variable is
-// TRUE send the message to the event log.
-// If the _eventLog is NULL and the DEBUG variable is TRUE send the message
-// to the standard output.
+// Debug utility.
+// If the _eventLog is NULL and the DEBUG variable is TRUE write the message
+// in a log file.
// ---------------------------------------------------
void debug(char* msg)
{
if (DEBUG == TRUE)
{
+ /*
if (_eventLog != NULL)
{
const char* args[1];
@@ -100,9 +101,55 @@
NULL // no war data
);
}
+ */
+
+ // Log to the file
+ FILE *fp;
+ if (_logFile == NULL)
+ {
+ char path [MAX_PATH];
+ if (_instanceDir != NULL)
+ {
+ int length = strlen(_instanceDir);
+ if ((length > 0) && (_instanceDir[length - 1] == '\\'))
+ {
+ sprintf(path, "%slogs\\windows-service.out", _instanceDir);
+ _logFile = strdup(path);
+ }
+ else
+ {
+ sprintf(path, "%s\\logs\\windows-service.out", _instanceDir);
+ _logFile = strdup(path);
+ }
+ }
+ else
+ {
+ char execName [MAX_PATH];
+ char instanceDir [MAX_PATH];
+ int length;
+ GetModuleFileName (
+ NULL,
+ execName,
+ MAX_PATH
+ );
+ length = strlen(execName) - strlen("lib\\opends_service.exe");
+ if (length > 0)
+ {
+ strncpy(instanceDir, execName, length);
+ instanceDir[length] = '\0';
+ sprintf(path, "%slogs\\windows-service.out", instanceDir);
+ _logFile = strdup(path);
+ }
+ }
+ }
+ if ((_logFile != NULL) && ((fp = fopen(_logFile, "a")) != NULL))
+ {
+ fprintf(fp, "%s\n", msg);
+ fclose(fp);
+ }
else
{
- fprintf(stdout, "%s\n", msg);
+ fprintf(stdout, "Could not create log file.\n");
}
}
}
@@ -454,6 +501,7 @@
if(_locking(fd, LK_NBLCK, 1) != -1)
{
*running = FALSE;
+ _locking(fd, LK_UNLCK, 1);
}
else
{
@@ -472,12 +520,14 @@
}
else
{
+ debug("Could not open lock file.");
*running = FALSE;
returnValue = SERVICE_RETURN_ERROR;
}
}
else
{
+ debug("Lock file path is too long.");
*running = FALSE;
returnValue = SERVICE_RETURN_ERROR;
}
@@ -495,16 +545,21 @@
// init out params
char* relativePath = "\\bat\\start-ds.bat";
char command[COMMAND_SIZE];
+
if (strlen(relativePath)+strlen(_instanceDir)+1 < COMMAND_SIZE)
{
sprintf(command, "\"%s%s\" --windowsNetStart", _instanceDir, relativePath);
// launch the command
- if (spawn(command, FALSE) != 0)
+ if (spawn(command, FALSE) != -1)
{
// Try to see if server is really running
int nTries = 10;
BOOL running = FALSE;
+
+ debug("doStartApplication: the spawn of the process worked.");
+ debug("Command:");
+ debug(command);
// Wait to be able to launch the java process in order it to free the lock
// on the file.
Sleep(3000);
@@ -518,24 +573,31 @@
{
Sleep(2000);
}
+ nTries--;
}
if (running)
{
returnValue = SERVICE_RETURN_OK;
+ debug("doStartApplication: server running.");
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStartApplication: server not running.");
}
}
else
{
+
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStartApplication: spawn failed. Sent command:");
+ debug(command);
}
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStartApplication: the command path name is too long.");
}
return returnValue;
} // doStartApplication
@@ -556,11 +618,14 @@
sprintf(command, "\"%s%s\" --windowsNetStop", _instanceDir, relativePath);
// launch the command
- if (spawn(command, FALSE) != 0)
+ if (spawn(command, FALSE) != -1)
{
// Try to see if server is really stopped
int nTries = 10;
BOOL running = TRUE;
+
+ debug("doStopApplication: the spawn of the process worked.");
+
// Wait to be able to launch the java process in order it to free the lock
// on the file.
Sleep(3000);
@@ -578,20 +643,25 @@
if (!running)
{
returnValue = SERVICE_RETURN_OK;
+ debug("doStopApplication: server stopped.");
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStopApplication: server NOT stopped.");
}
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStopApplication: spawn failed. Sent command:");
+ debug(command);
}
}
else
{
returnValue = SERVICE_RETURN_ERROR;
+ debug("doStopApplication: the command path name is too long.");
}
return returnValue;
} // doStopApplication
@@ -604,7 +674,7 @@
// The string stored in serviceBinPath looks like
// <SERVER_ROOT>/lib/service.exe start <_instanceDir>
// It is up to the caller of the function to allocate
-// at least MAX_PATH bytes in serviceBinPath.
+// at least COMMAND_SIZE bytes in serviceBinPath.
// The function returns SERVICE_RETURN_OK if we could create the binary
// path name and SERVICE_RETURN_ERROR otherwise.
// ---------------------------------------------------------------
@@ -625,6 +695,7 @@
{
// failed to get the path of the executable file
returnValue = SERVICE_RETURN_ERROR;
+ debug("Could not get the path of the executable file.\n");
}
else
{
@@ -632,11 +703,12 @@
{
// buffer was too small, executable name is probably not valid
returnValue = SERVICE_RETURN_ERROR;
+ debug("The name of the module file is too long.");
}
else
{
if (strlen(fileName) + strlen(" start ") + strlen(_instanceDir)
- < MAX_PATH)
+ < COMMAND_SIZE)
{
sprintf(serviceBinPath, "%s start \"%s\"", fileName,
_instanceDir);
@@ -645,6 +717,8 @@
{
// buffer was too small, executable name is probably not valid
returnValue = SERVICE_RETURN_ERROR;
+ fprintf(stdout,
+ "The name of the resulting windows service command is too long.\n");
}
}
}
@@ -657,7 +731,7 @@
// product. All commands are supposed to be unique because they have
// the instance dir as parameter.
//
-// The functions returns SERVICE_RETURN_OK if we could create a service name
+// The functions returns SERVICE_RETURN_OK if we could get a service name
// and SERVICE_RETURN_ERROR otherwise.
// The serviceName buffer must be allocated OUTSIDE the function and its
// minimum size must be of 256 (the maximum string length of a Service Name).
@@ -696,6 +770,11 @@
sprintf(serviceName, curService.serviceName);
returnValue = SERVICE_RETURN_OK;
}
+ else
+ {
+ debug("The service name found is too long:");
+ debug(curService.serviceName);
+ }
break;
}
}
@@ -811,18 +890,28 @@
void serviceMain(int argc, char* argv[])
{
// returned status
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
char serviceName[MAX_SERVICE_NAME];
ServiceReturnCode code;
// a checkpoint value indicate the progress of an operation
DWORD checkPoint = CHECKPOINT_FIRST_VALUE;
SERVICE_STATUS_HANDLE serviceStatusHandle;
+ debug("serviceMain called.");
+
code = createServiceBinPath(cmdToRun);
if (code == SERVICE_RETURN_OK)
{
code = getServiceName(cmdToRun, serviceName);
+ if (code != SERVICE_RETURN_OK)
+ {
+ debug("serviceMain: could not get service name.");
+ }
+ }
+ else
+ {
+ debug("serviceMain: failed to create service bin path.");
}
if (code == SERVICE_RETURN_OK)
@@ -835,6 +924,10 @@
{
_serviceStatusHandle = &serviceStatusHandle;
}
+ else
+ {
+ debug("serviceMain: failed to register service handler.");
+ }
}
@@ -978,15 +1071,17 @@
ServiceReturnCode code;
DWORD checkpoint;
BOOL running;
+ debug("serviceHandler called.");
switch (controlCode)
{
case SERVICE_CONTROL_SHUTDOWN:
// If system is shuting down then stop the service
// -> no break here
+ debug("serviceHandler: Shutdown.");
case SERVICE_CONTROL_STOP:
{
// update service status to STOP_PENDING
- debug("Stop called");
+ debug("serviceHandler: Stop.");
_serviceCurStatus = SERVICE_STOP_PENDING;
checkpoint = CHECKPOINT_FIRST_VALUE;
updateServiceStatus (
@@ -1042,39 +1137,44 @@
// Request to pause the service
// ----------------------------
case SERVICE_CONTROL_PAUSE:
- // not supported
- break;
+ // not supported
+ debug("serviceHandler: pause.");
+ break;
// Request to resume the service
// -----------------------------
case SERVICE_CONTROL_CONTINUE:
- // not supported
- break;
+ // not supported
+ debug("serviceHandler: continue.");
+ break;
// Interrogate the service status
// ------------------------------
case SERVICE_CONTROL_INTERROGATE:
- code = isServerRunning(&running);
- if (code != SERVICE_RETURN_OK)
- {
-
- }
- else if (running)
- {
- _serviceCurStatus = SERVICE_RUNNING;
- }
- else
- {
- _serviceCurStatus = SERVICE_STOPPED;
- }
- updateServiceStatus (
- _serviceCurStatus,
- NO_ERROR,
- 0,
- CHECKPOINT_NO_ONGOING_OPERATION,
- TIMEOUT_NONE,
- _serviceStatusHandle
- );
+ debug("serviceHandler: interrogate.");
+ code = isServerRunning(&running);
+ if (code != SERVICE_RETURN_OK)
+ {
+ debug("serviceHandler: error interrogating.");
+ }
+ else if (running)
+ {
+ _serviceCurStatus = SERVICE_RUNNING;
+ debug("serviceHandler: service running.");
+ }
+ else
+ {
+ _serviceCurStatus = SERVICE_STOPPED;
+ debug("serviceHandler: service stopped.");
+ }
+ updateServiceStatus (
+ _serviceCurStatus,
+ NO_ERROR,
+ 0,
+ CHECKPOINT_NO_ONGOING_OPERATION,
+ TIMEOUT_NONE,
+ _serviceStatusHandle
+ );
break;
// Other codes are ignored
@@ -1090,7 +1190,7 @@
//
// scm is the SCM handler (must not be NULL)
// serviceName the name of the service.
-// It is up to the caller of the function to allocate at least MAX_PATH bytes
+// It is up to the caller of the function to allocate at least COMMAND_SIZE bytes
// in binPathName.
// The function returns SERVICE_RETURN_OK if we could create the binary
// path name and SERVICE_RETURN_ERROR otherwise.
@@ -1100,8 +1200,6 @@
char* binPathName)
{
ServiceReturnCode returnValue;
- // pathtname to return
- char* binPathname = NULL;
// handle to the service
SC_HANDLE myService = NULL;
@@ -1150,16 +1248,31 @@
}
else
{
+ char msg[200];
+ sprintf(msg,
+ "getBinaryPath: error calling QueryServiceConfig. Code [%d]",
+ errCode);
+ // error
+ debug(msg);
break;
}
}
else
{
- if (strlen(serviceConfig->lpBinaryPathName) < MAX_PATH)
+ if (strlen(serviceConfig->lpBinaryPathName) < COMMAND_SIZE)
{
sprintf(binPathName, serviceConfig->lpBinaryPathName);
returnValue = SERVICE_RETURN_OK;
}
+ else
+ {
+ debug(
+ "getBinaryPath: the length of the binary path name is too big.");
+ debug("serviceName:");
+ debug(serviceName);
+ debug("binary path:");
+ debug(serviceConfig->lpBinaryPathName);
+ }
}
}
}
@@ -1225,7 +1338,6 @@
}
else
{
- debug("getServiceList: error More Data.");
// buffer is not big enough: try again with a proper size
dataSize += neededSize;
lpServiceData = (ENUM_SERVICE_STATUS*)calloc(
@@ -1247,7 +1359,10 @@
DWORD lastError = GetLastError();
if (lastError != ERROR_MORE_DATA)
{
+ char msg[200];
returnValue = SERVICE_RETURN_ERROR;
+ sprintf(msg, "getServiceList: second try generic error. Code [%d]",
+ lastError);
}
else
{
@@ -1271,6 +1386,7 @@
}
else
{
+ debug("getServiceList: error opening scm.");
returnValue = SERVICE_RETURN_ERROR;
}
@@ -1286,7 +1402,7 @@
*nbServices = aux;
if (aux > 0)
{
- char binPath[MAX_PATH];
+ char binPath[COMMAND_SIZE];
l = (ServiceDescriptor*)calloc(sizeof(ServiceDescriptor), aux);
for (i = 0; i < aux; i++)
{
@@ -1298,6 +1414,11 @@
{
l[i].cmdToRun = strdup(binPath);
}
+ else
+ {
+ debug("Error getting binary path name of service:");
+ debug(l[i].serviceName);
+ }
curService++;
}
*serviceList = l;
@@ -1506,7 +1627,6 @@
BOOL success;
SERVICE_DESCRIPTION serviceDescription;
serviceDescription.lpDescription = description;
-
success = ChangeServiceConfig2(
myService,
SERVICE_CONFIG_DESCRIPTION,
@@ -1661,9 +1781,10 @@
int createService(char* displayName, char* description)
{
int returnCode = 0;
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
ServiceReturnCode code;
+ debug("Creating service.");
code = createServiceBinPath(cmdToRun);
if (code == SERVICE_RETURN_OK)
@@ -1676,7 +1797,6 @@
// OpenDS is registered as a service.
code = SERVICE_ALREADY_EXISTS;
createRegistryKey(serviceName);
- debug("createService: service already exists for this instance.");
}
else
{
@@ -1690,23 +1810,34 @@
{
createRegistryKey(serviceName);
}
+ else
+ {
+ debug("Could not get a service name for command to run");
+ }
}
}
}
-
+ else
+ {
+ debug("createService could not create bin path.");
+ }
switch (code)
{
case SERVICE_RETURN_OK:
returnCode = 0;
+ debug("Service successfully created.");
break;
case SERVICE_ALREADY_EXISTS:
returnCode = 1;
+ debug("Service already exists.");
break;
case DUPLICATED_SERVICE_NAME:
returnCode = 2;
+ debug("Duplicated service name.");
break;
default:
returnCode = 3;
+ debug("Unexpected error creating service.");
}
return returnCode;
@@ -1724,10 +1855,11 @@
int serviceState()
{
int returnCode = 0;
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
char serviceName[MAX_SERVICE_NAME];
ServiceReturnCode code;
+ debug("Getting service state.");
code = createServiceBinPath(cmdToRun);
if (code == SERVICE_RETURN_OK)
@@ -1739,15 +1871,18 @@
// OpenDS is registered as a service.
fprintf(stdout, serviceName);
returnCode = 0;
+ debug("Service is enabled.");
}
else
{
returnCode = 1;
+ debug("Service is disabled.");
}
}
else
{
returnCode = 2;
+ debug("An error occurred getting the service status.");
}
return returnCode;
@@ -1766,10 +1901,13 @@
{
int returnCode = 0;
ServiceReturnCode code = serviceNameInUse(serviceName);
-
+
+ debug("Removing service.");
+
if (code != SERVICE_IN_USE)
{
returnCode = 1;
+ debug("Service does not exist.");
}
else
{
@@ -1780,16 +1918,19 @@
case SERVICE_RETURN_OK:
removeRegistryKey(serviceName);
returnCode = 0;
+ debug("Service successfully removed.");
break;
case SERVICE_MARKED_FOR_DELETION:
removeRegistryKey(serviceName);
returnCode = 2;
+ debug("Service marked for deletion.");
break;
default:
returnCode = 3;
+ debug("Unexpected error removing service.");
}
}
-
+
return returnCode;
} // removeServiceWithServiceName
@@ -1805,7 +1946,7 @@
int removeService()
{
int returnCode = 0;
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
char serviceName[MAX_SERVICE_NAME];
ServiceReturnCode code;
@@ -1843,7 +1984,7 @@
{
int returnCode;
char serviceName[MAX_SERVICE_NAME];
- char cmdToRun[MAX_PATH];
+ char cmdToRun[COMMAND_SIZE];
ServiceReturnCode code;
code = createServiceBinPath(cmdToRun);
@@ -1945,10 +2086,9 @@
{
char* subcommand;
int returnCode = 0;
-
if (argc <= 1)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand required: create, state, remove, start or cleanup.\n");
returnCode = -1;
}
@@ -1959,7 +2099,7 @@
{
if (argc <= 4)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand create requires instance dir, service name and description.\n");
returnCode = -1;
}
@@ -1975,7 +2115,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand state requires instance dir.\n");
returnCode = -1;
}
@@ -1991,7 +2131,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand remove requires instance dir.\n");
returnCode = -1;
}
@@ -2007,14 +2147,14 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand start requires instance dir.\n");
returnCode = -1;
}
else
{
_instanceDir = strdup(argv[2]);
- updateDebugFlag(argv, argc, 3);
+ DEBUG = TRUE;
returnCode = startService();
free(_instanceDir);
}
@@ -2023,7 +2163,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand isrunning requires instance dir.\n");
returnCode = -1;
}
@@ -2050,7 +2190,7 @@
{
if (argc <= 2)
{
- fprintf(stderr,
+ fprintf(stdout,
"Subcommand cleanup requires service name.\n");
returnCode = -1;
}
@@ -2065,7 +2205,7 @@
else
{
- fprintf(stderr, "Unknown subcommand: [%s]\n", subcommand);
+ fprintf(stdout, "Unknown subcommand: [%s]\n", subcommand);
returnCode = -1;
}
}
--
Gitblit v1.10.0