提交 0713fce7 编写于 作者: J jonathan pickett

issue 123: changed error output in Win32_service and Win32_QFork to use...

issue 123: changed error output in Win32_service and Win32_QFork to use redisLog. Also fixed a few compiler warnings.
上级 c83b639b
......@@ -35,8 +35,18 @@
#include <time.h>
static int verbosity = REDIS_WARNING;
static int syslogEnabled = 0;
static char syslogIdent[MAX_PATH];
static char* logFile = NULL;
void setSyslogEnabled(int flag) {
syslogEnabled = flag;
}
void setSyslogIdent(const char* ident) {
strcpy_s(syslogIdent, MAX_PATH, ident);
}
void setLogVerbosityLevel(int level)
{
verbosity = level;
......@@ -48,11 +58,12 @@ void setLogFile(const char* logFileName)
free((void*)logFile);
logFile = NULL;
}
logFile = (char*)malloc(strlen(logFileName));
logFile = (char*)malloc(strlen(logFileName)+1);
if (logFile==NULL) {
redisLog(REDIS_WARNING, "memory allocation failure");
return;
}
memset(logFile, 0, strlen(logFileName) + 1);
strcpy (logFile,logFileName);
}
......@@ -107,7 +118,7 @@ void redisLogRaw(int level, const char *msg) {
if (log_to_stdout == 0) fclose(fp);
#ifdef _WIN32
if (server.syslog_enabled) WriteEventLog(server.syslog_ident, msg);
if (syslogEnabled) WriteEventLog(syslogIdent, msg);
#else
if (server.syslog_enabled) syslog(syslogLevelMap[level], "%s", msg);
#endif
......
#include "Win32_CommandLine.h"
#include <Windows.h>
#include <algorithm>
#include <fstream>
#include <iostream>
#include <sstream>
#include <exception>
ArgumentMap g_argMap;
// Map of argument name to number of parameters for this argument.
typedef map<string, int> argumentCountVector;
static argumentCountVector g_argCountVector =
{
{ cQFork, 2 },
{ cServiceName, 1 },
{ cServiceRun, 0 },
{ cServiceInstall, 0 },
{ cServiceUninstall, 0 },
{ cServiceStart, 0 },
{ cServiceStop, 0 }
};
string stripQuotes(string s) {
if (s.at(0) == '\'' && s.at(s.length()-1) == '\'') {
if (s.length() > 2) {
return s.substr(1, s.length() - 2);
} else {
return string("");
}
}
if (s.at(0) == '\"' && s.at(s.length()-1) == '\"') {
if (s.length() > 2) {
return s.substr(1, s.length() - 2);
} else {
return string("");
}
}
return s;
}
void ParseConfFile(string confFile, ArgumentMap& argMap) {
ifstream config;
string line;
string token;
string value;
#ifdef _DEBUG
cout << "processing " << confFile << endl;
#endif
config.open(confFile);
if (config.fail()) {
stringstream ss;
char buffer[MAX_PATH];
::GetCurrentDirectoryA(MAX_PATH, buffer);
ss << "Failed to open the .conf file: " << confFile << " CWD=" << buffer;
throw runtime_error(ss.str());
}
while (!config.eof()) {
getline(config, line);
istringstream iss(line);
if (getline(iss, token, ' ')) {
if (token.compare("#") == 0) continue;
if (getline(iss, value, ' ')) {
if (token.compare("include") == 0) {
ParseConfFile(value, argMap);
} else {
transform(token.begin(), token.end(), token.begin(), ::tolower);
transform(value.begin(), value.end(), value.begin(), ::tolower);
value = stripQuotes(value);
vector<string> params;
params.push_back(value);
argMap[token].push_back(params);
}
} else {
stringstream ss;
ss << "Failed to get value for argument " << token << " in " << confFile;
throw runtime_error(ss.str());
}
}
}
}
void ParseCommandLineArguments(int argc, char** argv) {
if (argc < 2) return;
bool confFile = (string(argv[1]).substr(0, 2).compare("--") != 0);
for (int n = (confFile ? 2 : 1); n < argc; n++) {
string argument = string(argv[n]).substr(2, argument.length() - 2);
transform(argument.begin(), argument.end(), argument.begin(), ::tolower);
// All of the redis commandline/conf file arguemnts have one parameter. The Windows
// port intorduces other arguments with diffreent parameter counts.
int paramCount = 1;
if (g_argCountVector.find(argument) != g_argCountVector.end()) {
paramCount = g_argCountVector[argument];
}
vector<string> params;
for (int pi = 0; pi < paramCount; pi++) {
n++;
if (n >= argc) {
stringstream ss;
ss << "No parameter value for argument on command line. argument = '" << argument << "'";
throw runtime_error(ss.str());
}
string paramValue = argv[n];
transform(paramValue.begin(), paramValue.end(), paramValue.begin(), ::tolower);
paramValue = stripQuotes(paramValue);
params.push_back(paramValue);
}
g_argMap[argument].push_back(params);
}
if (confFile) ParseConfFile(argv[1], g_argMap);
#ifdef _DEBUG
cout << "arguments seen:" << endl;
for (auto key : g_argMap) {
cout << key.first << endl;
bool first = true;
for (auto params : key.second) {
cout << "\t";
bool firstParam = true;
for (auto param : params) {
if (firstParam == true) {
firstParam = false;
} else {
cout << ", ";
}
cout << param;
}
cout << endl;
}
}
#endif
}
\ No newline at end of file
#pragma once
#include <map>
#include <vector>
#include <string>
using namespace std;
// A map of arguments encountered to the set of parameters for those arguments, in the order in which they
// were encountered. If 'maxmemory' is encountered 3 times, ArgumentMap["maxmemory"] will return a vector
// of an array of values, with the first being the value od the first 'maxmemory' instance enountered.
// Order of encounter is command line, conf file, nested conf file #1 (via include statement), ...
typedef map<string, vector<vector<string>>> ArgumentMap;
extern ArgumentMap g_argMap;
void ParseConfFile(string confFile, ArgumentMap& argMap);
void ParseCommandLineArguments(int argc, char** argv);
const string cQFork = "qfork";
const string cServiceRun = "service-run";
const string cServiceInstall = "service-install";
const string cServiceUninstall = "service-uninstall";
const string cServiceStart = "service-start";
const string cServiceStop = "service-stop";
const string cServiceName = "service-name";
const string cSyslogEnabled = "syslog-enabled";
const string cSyslogIdent= "syslog-ident";
const string cLogfile = "logfile";
const string cMaxHeap = "maxheap";
const string cMaxMemory = "maxmemory";
const string cYes = "yes";
const string cNo = "no";
const string cDefaultSyslogIdent = "redis";
const string cDefaultLogfile = "stdout";
......@@ -29,9 +29,10 @@
#include "Win32_variadicFunctor.h"
#include "Win32_ANSI.h"
#include <string>
#include "..\redisLog.h"
using namespace std;
#define CATCH_AND_REPORT() catch(const std::exception &){printf("std exception");}catch(...){printf("other exception");}
#define CATCH_AND_REPORT() catch(const std::exception &){::redisLog(REDIS_WARNING, "FDAPI: std exception");}catch(...){::redisLog(REDIS_WARNING, "FDAPI: other exception");}
extern "C" {
// FD lookup Winsock equivalents for Win32_wsiocp.c
......@@ -455,7 +456,6 @@ int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
return -1;
}
int n = 0;
nfds_t i;
for (i = 0; i < nfds; i++) {
if (fds[i].fd < 0) {
......@@ -469,22 +469,15 @@ int redis_poll_impl(struct pollfd *fds, nfds_t nfds, int timeout) {
if (pollCopy[i].events & POLLIN) FD_SET(pollCopy[i].fd, &readSet);
if (pollCopy[i].events & POLLOUT) FD_SET(pollCopy[i].fd, &writeSet);
if (pollCopy[i].events & POLLERR) FD_SET(pollCopy[i].fd, &excepSet);
if (pollCopy[i].fd >= n) {
n = pollCopy[i].fd + 1;
}
}
if (n == 0) {
return 0;
}
if (timeout < 0) {
ret = select(n, &readSet, &writeSet, &excepSet, NULL);
ret = select(0, &readSet, &writeSet, &excepSet, NULL);
} else {
struct timeval tv;
tv.tv_sec = timeout / 1000;
tv.tv_usec = 1000 * (timeout % 1000);
ret = select(n, &readSet, &writeSet, &excepSet, &tv);
ret = select(0, &readSet, &writeSet, &excepSet, &tv);
}
if (ret < 0) {
......@@ -591,17 +584,17 @@ ssize_t redis_write_impl(int fd, const void *buf, size_t count) {
} else {
int posixFD = RFDMap::getInstance().lookupPosixFD( fd );
if( posixFD != -1 ) {
if (posixFD == fileno(stdout)) {
if (posixFD == _fileno(stdout)) {
DWORD bytesWritten = 0;
if (FALSE != ParseAndPrintANSIString(GetStdHandle(STD_OUTPUT_HANDLE), buf, count, &bytesWritten)) {
if (FALSE != ParseAndPrintANSIString(GetStdHandle(STD_OUTPUT_HANDLE), buf, (DWORD)count, &bytesWritten)) {
return (int)bytesWritten;
} else {
errno = GetLastError();
return 0;
}
} else if (posixFD == fileno(stderr)) {
} else if (posixFD == _fileno(stderr)) {
DWORD bytesWritten = 0;
if (FALSE != ParseAndPrintANSIString(GetStdHandle(STD_ERROR_HANDLE), buf, count, &bytesWritten)) {
if (FALSE != ParseAndPrintANSIString(GetStdHandle(STD_ERROR_HANDLE), buf, (DWORD)count, &bytesWritten)) {
return (int)bytesWritten;
} else {
errno = GetLastError();
......
......@@ -22,6 +22,7 @@
<ClCompile Include="..\RedisLog.c" />
<ClCompile Include="win32fixes.c" />
<ClCompile Include="Win32_ANSI.c" />
<ClCompile Include="Win32_CommandLine.cpp" />
<ClCompile Include="Win32_dlmalloc.c" />
<ClCompile Include="Win32_EventLog.cpp" />
<ClCompile Include="Win32_FDAPI.cpp" />
......@@ -37,6 +38,7 @@
<ClInclude Include="..\redisLog.h" />
<ClInclude Include="win32fixes.h" />
<ClInclude Include="Win32_ANSI.h" />
<ClInclude Include="Win32_CommandLine.h" />
<ClInclude Include="Win32_dlmalloc.h" />
<ClInclude Include="Win32_EventLog.h" />
<ClInclude Include="Win32_FDAPI.h" />
......
......@@ -33,9 +33,12 @@
#include "Win32_dlmalloc.h"
#include "Win32_SmartHandle.h"
#include "Win32_Service.h"
#include "Win32_CommandLine.h"
#include "..\redisLog.h"
#include <vector>
#include <map>
#include <iostream>
#include <fstream>
#include <sstream>
#include <stdint.h>
#include <exception>
......@@ -134,10 +137,6 @@ How the parent invokes the QFork process:
const SIZE_T cAllocationGranularity = 1 << 18; // 256KB per heap block (matches large block allocation threshold of dlmalloc)
const int cMaxBlocks = 1 << 24; // 256KB * 16M heap blocks = 4TB. 4TB is the largest memory config Windows supports at present.
const wchar_t* cMapFileBaseName = L"RedisQFork";
const char* qforkFlag = "--QFork";
const char* maxmemoryFlag = "maxmemory";
const char* maxheapFlag = "maxheap";
const char* includeFlag = "include";
const int cDeadForkWait = 30000;
size_t pageSize = 0;
......@@ -258,7 +257,7 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
return TRUE;
}
catch(std::system_error syserr) {
printf("QForkSlaveInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "QForkSlaveInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
g_pQForkControl = NULL;
if(g_pQForkControl != NULL) {
if(g_pQForkControl->operationFailed != NULL) {
......@@ -268,7 +267,7 @@ BOOL QForkSlaveInit(HANDLE QForkConrolMemoryMapHandle, DWORD ParentProcessID) {
return FALSE;
}
catch(std::runtime_error runerr) {
printf("QForkSlaveInit: runtime error caught. message=%s\n", runerr.what());
::redisLog(REDIS_WARNING, "QForkSlaveInit: runtime error caught. message=%s\n", runerr.what());
g_pQForkControl = NULL;
SetEvent(g_pQForkControl->operationFailed);
return FALSE;
......@@ -476,13 +475,13 @@ BOOL QForkMasterInit( __int64 maxheapBytes ) {
return TRUE;
}
catch(std::system_error syserr) {
printf("QForkMasterInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "QForkMasterInit: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
}
catch(std::runtime_error runerr) {
printf("QForkMasterInit: runtime error caught. message=%s\n", runerr.what());
::redisLog(REDIS_WARNING, "QForkMasterInit: runtime error caught. message=%s\n", runerr.what());
}
catch(...) {
printf("QForkMasterInit: other exception caught.\n");
::redisLog(REDIS_WARNING, "QForkMasterInit: other exception caught.\n");
}
return FALSE;
}
......@@ -515,15 +514,15 @@ LONG CALLBACK VectoredHeapMapper(PEXCEPTION_POINTERS info) {
}
else
{
printf("\nF(0x%p)", startOfMapping);
printf( "\t MapViewOfFileEx failed with error 0x%08X. \n", GetLastError() );
printf( "\t heapStart 0x%p\n", heapStart);
printf( "\t heapEnd 0x%p\n", heapEnd);
printf( "\t failing access location 0x%p\n", failingMemoryAddress);
printf( "\t offset into mmf to start mapping 0x%016X\n", mmfOffset);
printf( "\t start of new mapping 0x%p \n", startOfMapping);
printf( "\t bytes to map 0x%08x \n", bytesToMap);
printf( "\t continuing exception handler search \n" );
::redisLog(REDIS_WARNING, "\nF(0x%p)", startOfMapping);
::redisLog(REDIS_WARNING, "\t MapViewOfFileEx failed with error 0x%08X. \n", GetLastError());
::redisLog(REDIS_WARNING, "\t heapStart 0x%p\n", heapStart);
::redisLog(REDIS_WARNING, "\t heapEnd 0x%p\n", heapEnd);
::redisLog(REDIS_WARNING, "\t failing access location 0x%p\n", failingMemoryAddress);
::redisLog(REDIS_WARNING, "\t offset into mmf to start mapping 0x%016X\n", mmfOffset);
::redisLog(REDIS_WARNING, "\t start of new mapping 0x%p \n", startOfMapping);
::redisLog(REDIS_WARNING, "\t bytes to map 0x%08x \n", bytesToMap);
::redisLog(REDIS_WARNING, "\t continuing exception handler search \n");
}
}
}
......@@ -531,68 +530,6 @@ LONG CALLBACK VectoredHeapMapper(PEXCEPTION_POINTERS info) {
return EXCEPTION_CONTINUE_SEARCH;
}
/*
Returns true if we have successfully parsed the conf file and its recursive includes.
If maxheap and/or maxmemory is specified these will be set on exit. If maxheap/maxmemory
are specified in master and/or recursive conf files, the first encountered flag is taken.
*/
bool ParseConfFile(string file, __int64& maxheapBytes, __int64& maxmemoryBytes) {
int memtollerr = 0;
ifstream config;
config.open(file);
if (config.fail()) {
return false;
}
while (!config.eof()) {
string line;
getline(config, line);
istringstream iss(line);
string token;
if (getline(iss, token, ' ')) {
if (_stricmp(token.c_str(), maxmemoryFlag) == 0) {
string maxmemoryString;
if (getline(iss, maxmemoryString, ' ')) {
if (maxmemoryBytes == -1) {
maxmemoryBytes = memtoll(maxmemoryString.c_str(), &memtollerr);
if (memtollerr != 0) {
printf(
"Unable to convert %s to the number of bytes for the maxmemory flag.\n",
maxmemoryString.c_str());
printf("Failing startup.\n");
return false;
}
}
}
} else if (_stricmp(token.c_str(), maxheapFlag) == 0) {
string maxheapString;
if (getline(iss, maxheapString, ' ')) {
if (maxheapBytes == -1) {
maxheapBytes = memtoll(maxheapString.c_str(), &memtollerr);
if (memtollerr != 0) {
printf(
"Unable to convert %s to the number of bytes for the maxmemory flag.\n",
maxheapString.c_str());
printf("Failing startup.\n");
return false;
}
}
}
} else if (_stricmp(token.c_str(), includeFlag) == 0) {
string includeFile;
if (getline(iss, includeFile, ' ')) {
if (!ParseConfFile(includeFile, maxheapBytes, maxmemoryBytes)) {
return false;
}
}
}
}
}
return true;
}
// QFork API
StartupStatus QForkStartup(int argc, char** argv) {
bool foundSlaveFlag = false;
......@@ -606,54 +543,29 @@ StartupStatus QForkStartup(int argc, char** argv) {
GetSystemInfo(&si);
g_systemAllocationGranularity = si.dwAllocationGranularity;
if ((argc == 3) && (strcmp(argv[0], qforkFlag) == 0)) {
if (g_argMap.find(cQFork) != g_argMap.end()) {
// slave command line looks like: --QFork [QForkConrolMemoryMap handle] [parent process id]
foundSlaveFlag = true;
char* endPtr;
QForkConrolMemoryMapHandle = (HANDLE)strtoul(argv[1],&endPtr,10);
QForkConrolMemoryMapHandle = (HANDLE)strtoul(g_argMap[cQFork].at(0).at(0).c_str(),&endPtr,10);
char* end = NULL;
PPID = strtoul(argv[2], &end, 10);
PPID = strtoul(g_argMap[cQFork].at(0).at(1).c_str(), &end, 10);
} else {
for (int n = 1; n < argc; n++) {
// check for flags in .conf file
if( n == 1 && strncmp(argv[n],"--",2) != 0 ) {
if (!ParseConfFile(argv[1], maxheapBytes, maxmemoryBytes)) {
return StartupStatus::ssFAILED;
} else {
continue;
}
}
if( strncmp(argv[n],"--", 2) == 0) {
if (_stricmp(argv[n]+2,maxmemoryFlag) == 0) {
maxmemoryBytes = memtoll(argv[n+1],&memtollerr);
if( memtollerr != 0) {
printf (
"%s specified. Unable to convert %s to the number of bytes for the maxmemory flag.\n",
maxmemoryBytes,
argv[n+1] );
printf( "Failing startup.\n");
return StartupStatus::ssFAILED;
}
} else if(_stricmp(argv[n]+2,maxheapFlag) == 0) {
maxheapBytes = memtoll(argv[n+1],&memtollerr);
if( memtollerr != 0) {
printf (
"%s specified. Unable to convert %s to the number of bytes for the maxmemory flag.\n",
maxmemoryBytes,
argv[n+1] );
printf( "Failing startup.\n");
return StartupStatus::ssFAILED;
}
}
}
if (g_argMap.find(cMaxHeap) != g_argMap.end()) {
int mtollerr = 0;
maxheapBytes = memtoll(g_argMap[cMaxHeap].at(0).at(0).c_str(), &memtollerr);
}
if (g_argMap.find(cMaxMemory) != g_argMap.end()) {
int mtollerr = 0;
maxmemoryBytes = memtoll(g_argMap[cMaxMemory].at(0).at(0).c_str(), &memtollerr);
}
}
PERFORMANCE_INFORMATION perfinfo;
perfinfo.cb = sizeof(PERFORMANCE_INFORMATION);
if (FALSE == GetPerformanceInfo(&perfinfo, sizeof(PERFORMANCE_INFORMATION))) {
printf ( "GetPerformanceInfo failed.\n" );
printf( "Failing startup.\n" );
::redisLog(REDIS_WARNING, "GetPerformanceInfo failed.\n");
::redisLog(REDIS_WARNING, "Failing startup.\n");
return StartupStatus::ssFAILED;
}
pageSize = perfinfo.PageSize;
......@@ -862,7 +774,7 @@ BOOL BeginForkOperation(OperationType type, char* fileName, LPVOID globalData, i
char arguments[_MAX_PATH];
memset(arguments,0,_MAX_PATH);
PROCESS_INFORMATION pi;
sprintf_s(arguments, _MAX_PATH, "%s %llu %lu", qforkFlag, (uint64_t)g_hQForkControlFileMap, GetCurrentProcessId());
sprintf_s(arguments, _MAX_PATH, "%s --%s %llu %lu", fileName, cQFork.c_str(), (uint64_t)g_hQForkControlFileMap, GetCurrentProcessId());
if (FALSE == CreateProcessA(fileName, arguments, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
throw system_error(
GetLastError(),
......@@ -887,13 +799,13 @@ BOOL BeginForkOperation(OperationType type, char* fileName, LPVOID globalData, i
return TRUE;
}
catch(std::system_error syserr) {
printf("BeginForkOperation: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "BeginForkOperation: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
}
catch(std::runtime_error runerr) {
printf("BeginForkOperation: runtime error caught. message=%s\n", runerr.what());
::redisLog(REDIS_WARNING, "BeginForkOperation: runtime error caught. message=%s\n", runerr.what());
}
catch(...) {
printf("BeginForkOperation: other exception caught.\n");
::redisLog(REDIS_WARNING, "BeginForkOperation: other exception caught.\n");
}
return FALSE;
}
......@@ -932,13 +844,13 @@ BOOL AbortForkOperation()
return EndForkOperation(NULL);
}
catch(std::system_error syserr) {
printf("0x%08x - %s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "AbortForkOperation(): 0x%08x - %s\n", syserr.code().value(), syserr.what());
// If we can not properly restore fork state, then another fork operation is not possible.
exit(1);
}
catch( ... ) {
printf("Some other exception caught in EndForkOperation().\n");
::redisLog(REDIS_WARNING, "Some other exception caught in EndForkOperation().\n");
exit(1);
}
return FALSE;
......@@ -1150,13 +1062,13 @@ BOOL EndForkOperation(int * pExitCode) {
return TRUE;
}
catch(std::system_error syserr) {
printf("0x%08x - %s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "EndForkOperation: 0x%08x - %s\n", syserr.code().value(), syserr.what());
// If we can not properly restore fork state, then another fork operation is not possible.
exit(1);
}
catch( ... ) {
printf("Some other exception caught in EndForkOperation().\n");
::redisLog(REDIS_WARNING, "Some other exception caught in EndForkOperation().\n");
exit(1);
}
return FALSE;
......@@ -1249,6 +1161,20 @@ BOOL FreeHeapBlock(LPVOID block, size_t size)
return TRUE;
}
void SetupLogging() {
bool serviceRun = g_argMap.find(cServiceRun) != g_argMap.end();
string syslogEnabledValue = (g_argMap.find(cSyslogEnabled) != g_argMap.end() ? g_argMap[cSyslogEnabled].at(0).at(0) : cNo);
bool syslogEnabled = (syslogEnabledValue.compare(cYes) == 0) || serviceRun;
string syslogIdent = (g_argMap.find(cSyslogIdent) != g_argMap.end() ? g_argMap[cSyslogIdent].at(0).at(0) : cDefaultSyslogIdent);
string logFileName = (g_argMap.find(cLogfile) != g_argMap.end() ? g_argMap[cLogfile].at(0).at(0) : cDefaultLogfile);
setSyslogEnabled(syslogEnabled);
if (syslogEnabled) {
setSyslogIdent(syslogIdent.c_str());
} else {
setLogFile(logFileName.c_str());
}
}
extern "C"
{
......@@ -1257,20 +1183,28 @@ extern "C"
// is invoked so that the QFork allocator can be setup prior to anything
// Redis will allocate.
int main(int argc, char* argv[]) {
try {
try {
ParseCommandLineArguments(argc, argv);
SetupLogging();
} catch (runtime_error &re) {
cout << re.what() << endl;
exit(-1);
}
try {
#ifdef DEBUG_WITH_PROCMON
hProcMonDevice =
CreateFile(
L"\\\\.\\Global\\ProcmonDebugLogger",
GENERIC_READ|GENERIC_WRITE,
FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
hProcMonDevice =
CreateFile(
L"\\\\.\\Global\\ProcmonDebugLogger",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL);
#endif
// service commands do not launch an instance of redis directly
// service commands do not launch an instance of redis directly
if (HandleServiceCommands(argc, argv) == TRUE)
return 0;
......@@ -1291,11 +1225,11 @@ extern "C"
return 2;
}
} catch (std::system_error syserr) {
printf("main: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
::redisLog(REDIS_WARNING, "main: system error caught. error code=0x%08x, message=%s\n", syserr.code().value(), syserr.what());
} catch (std::runtime_error runerr) {
printf("main: runtime error caught. message=%s\n", runerr.what());
::redisLog(REDIS_WARNING, "main: runtime error caught. message=%s\n", runerr.what());
} catch (...) {
printf("main: other exception caught.\n");
::redisLog(REDIS_WARNING, "main: other exception caught.\n");
}
}
}
......@@ -67,6 +67,7 @@ this should preceed the other arguments passed to redis. For instance:
#include <vector>
#include <iostream>
#include "..\redisLog.h"
#include "Win32_CommandLine.h"
using namespace std;
#include "Win32_SmartHandle.h"
......@@ -98,7 +99,7 @@ void WriteServiceInstallMessage(string message) {
WriteFile(pipe, message.c_str(), (DWORD)message.length(), &bytesWritten, NULL);
CloseHandle(pipe);
} else {
cout << message;
::redisLog(REDIS_WARNING, message.c_str());
}
}
......@@ -143,7 +144,7 @@ BOOL RelaunchAsElevatedProcess(int argc, char** argv) {
DWORD result = ReadFile(pipe, buffer, messageBufferSize, &bytesRead, NULL);
if (result != 0 && bytesRead > 0) {
buffer[bytesRead] = '\0'; // ensure received message is null terminated;
cout << buffer;
::redisLog(REDIS_WARNING, (const char*)buffer);
}
}
CloseHandle(sei.hProcess);
......@@ -174,17 +175,12 @@ bool IsProcessElevated() {
return (elevation.TokenIsElevated != 0);
}
VOID InitializeServiceName(int argc, char** argv) {
for (int a = 0; a < argc; a++) {
if (_stricmp(argv[a], "--service-name") == 0) {
if (a + 1 <= argc) {
if (strlen(argv[a + 1]) > MAX_SERVICE_NAME_LENGTH) {
throw std::runtime_error("Service name too long.");
}
strcpy_s(g_serviceName, MAX_SERVICE_NAME_LENGTH, argv[a + 1]);
return;
}
VOID InitializeServiceName() {
if (g_argMap.find(cServiceName) != g_argMap.end()) {
if (g_argMap[cServiceName].at(0).at(0).length() > MAX_SERVICE_NAME_LENGTH) {
throw std::runtime_error("Service name too long.");
}
strcpy_s(g_serviceName, MAX_SERVICE_NAME_LENGTH, g_argMap[cServiceName].at(0).at(0).c_str());
}
}
......@@ -209,7 +205,7 @@ DWORD AddAceToObjectsSecurityDescriptor(
DACL_SECURITY_INFORMATION,
NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) {
printf("GetNamedSecurityInfo Error %u\n", dwRes);
::redisLog(REDIS_WARNING, "GetNamedSecurityInfo Error %u\n", dwRes);
goto Cleanup;
}
......@@ -222,7 +218,7 @@ DWORD AddAceToObjectsSecurityDescriptor(
dwRes = SetEntriesInAclA(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes) {
printf("SetEntriesInAcl Error %u\n", dwRes);
::redisLog(REDIS_WARNING, "SetEntriesInAcl Error %u\n", dwRes);
goto Cleanup;
}
......@@ -230,7 +226,7 @@ DWORD AddAceToObjectsSecurityDescriptor(
DACL_SECURITY_INFORMATION,
NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes) {
printf("SetNamedSecurityInfo Error %u\n", dwRes);
::redisLog(REDIS_WARNING, "SetNamedSecurityInfo Error %u\n", dwRes);
goto Cleanup;
}
......@@ -259,7 +255,7 @@ VOID ServiceInstall(int argc, char ** argv) {
CHAR szPath[MAX_PATH];
string userName = "NT AUTHORITY\\NetworkService";
InitializeServiceName(argc, argv);
InitializeServiceName();
// build arguments to pass to service when it auto starts
if (GetModuleFileNameA(NULL, szPath, MAX_PATH) == 0) {
......@@ -273,7 +269,7 @@ VOID ServiceInstall(int argc, char ** argv) {
args << " ";
if (a == 1) {
// replace --service-install argument with --service-run
args << "--service-run";
args << "--" << cServiceRun;
} else {
args << argv[a];
}
......@@ -320,7 +316,7 @@ VOID ServiceStart(int argc, char ** argv) {
SmartServiceHandle shSCManager;
SmartServiceHandle shService;
InitializeServiceName(argc, argv);
InitializeServiceName();
shSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (shSCManager.Invalid()) {
......@@ -361,7 +357,7 @@ VOID ServiceStop(int argc, char ** argv) {
SmartServiceHandle shSCManager;
SmartServiceHandle shService;
InitializeServiceName(argc, argv);
InitializeServiceName();
shSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (shSCManager.Invalid()) {
......@@ -394,7 +390,7 @@ VOID ServiceUninstall(int argc, char** argv) {
SmartServiceHandle shSCManager;
SmartServiceHandle shService;
InitializeServiceName(argc, argv);
InitializeServiceName();
shSCManager = OpenSCManager(NULL, NULL, SC_MANAGER_ALL_ACCESS);
if (shSCManager.Invalid()) {
......@@ -476,47 +472,47 @@ DWORD WINAPI ServiceCtrlHandler(DWORD dwControl, DWORD dwEventType, LPVOID lpEve
switch (dwControl) {
case SERVICE_CONTROL_PRESHUTDOWN:
{
SetEvent(g_ServiceStopEvent);
SetEvent(g_ServiceStopEvent);
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE) {
throw std::system_error(GetLastError(), system_category(), "SetServiceStatus failed");
}
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE) {
throw std::system_error(GetLastError(), system_category(), "SetServiceStatus failed");
}
break;
break;
}
case SERVICE_CONTROL_STOP:
{
DWORD start = GetTickCount();
while (GetTickCount() - start > cPreshutdownInterval) {
if (WaitForSingleObject(g_ServiceStoppedEvent, cPreshutdownInterval / 10) == WAIT_OBJECT_0) {
break;
}
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE) {
throw std::system_error(GetLastError(), system_category(), "SetServiceStatus failed");
}
}
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE) {
throw std::system_error(GetLastError(), system_category(), "SetServiceStatus failed");
}
break;
DWORD start = GetTickCount();
while (GetTickCount() - start > cPreshutdownInterval) {
if (WaitForSingleObject(g_ServiceStoppedEvent, cPreshutdownInterval / 10) == WAIT_OBJECT_0) {
break;
}
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE) {
throw std::system_error(GetLastError(), system_category(), "SetServiceStatus failed");
}
}
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
if (SetServiceStatus(g_StatusHandle, &g_ServiceStatus) == FALSE) {
throw std::system_error(GetLastError(), system_category(), "SetServiceStatus failed");
}
break;
}
default:
......@@ -601,7 +597,7 @@ void ServiceRun() {
}
void BuildServiceRunArguments(int argc, char** argv) {
InitializeServiceName(argc, argv);
InitializeServiceName();
// build argument list to be used by ServiceRun
for (int n = 0; n < argc; n++) {
......@@ -617,7 +613,7 @@ void BuildServiceRunArguments(int argc, char** argv) {
// bypass --service-run argument
continue;
} else {
if (_stricmp(argv[n], "--service-name") == 0) {
if (_stricmp(argv[n], cServiceName.c_str()) == 0) {
// bypass --service-name argument and the name of the service
n++;
continue;
......@@ -631,35 +627,36 @@ void BuildServiceRunArguments(int argc, char** argv) {
extern "C" BOOL HandleServiceCommands(int argc, char **argv) {
try {
if (argc > 1) {
string servicearg = argv[1];
string servicearg = string(argv[1]);
servicearg = servicearg.substr(2, servicearg.length());
std::transform(servicearg.begin(), servicearg.end(), servicearg.begin(), ::tolower);
if (servicearg == "--service-install") {
if (servicearg == cServiceInstall) {
if (!IsProcessElevated()) {
return RelaunchAsElevatedProcess(argc, argv);
} else {
ServiceInstall(argc, argv);
return TRUE;
}
} else if (servicearg == "--service-uninstall") {
} else if (servicearg == cServiceUninstall) {
if (!IsProcessElevated()) {
return RelaunchAsElevatedProcess(argc, argv);
} else {
ServiceUninstall(argc, argv);
return TRUE;
}
} else if (servicearg == "--service-run") {
} else if (servicearg == cServiceRun) {
g_isRunningAsService = TRUE;
BuildServiceRunArguments(argc, argv);
ServiceRun();
return TRUE;
} else if (servicearg == "--service-start") {
} else if (servicearg == cServiceStart) {
if (!IsProcessElevated()) {
return RelaunchAsElevatedProcess(argc, argv);
} else {
ServiceStart(argc, argv);
return TRUE;
}
} else if (servicearg == "--service-stop") {
} else if (servicearg == cServiceStop) {
if (!IsProcessElevated()) {
return RelaunchAsElevatedProcess(argc, argv);
} else {
......@@ -678,7 +675,7 @@ extern "C" BOOL HandleServiceCommands(int argc, char **argv) {
exit(1);
} catch (std::runtime_error runerr) {
stringstream err;
cout << "HandleServiceCommands: runtime error caught. message=" << runerr.what() << endl;
err << "HandleServiceCommands: runtime error caught. message=" << runerr.what() << endl;
WriteServiceInstallMessage(err.str());
exit(1);
} catch (...) {
......
......@@ -185,7 +185,24 @@ void loadServerConfigFromString(char *config) {
FILE *logfp;
zfree(server.logfile);
#ifdef _WIN32
int length = strlen(argv[1]);
if ((argv[0] == '\'' && argv[length-1] == '\'') ||
(argv[0] == '\"' && argv[length-1] == '\"')) {
if (length == 2) {
server.logfile[0] = zstrdup("\0");
} else {
size_t l = length - 2 + 1;
char *p = zmalloc(l);
memcpy(p, argv[1]+1, l);
server.logfile[0] = p;
}
} else {
server.logfile = zstrdup(argv[1]);
}
#else
server.logfile = zstrdup(argv[1]);
#endif
if (server.logfile[0] != '\0') {
/* Test if we are able to open the file. The server will not
* be able to abort just for this problem later... */
......@@ -206,14 +223,18 @@ void loadServerConfigFromString(char *config) {
if ((server.syslog_enabled = yesnotoi(argv[1])) == -1) {
err = "argument must be 'yes' or 'no'"; goto loaderr;
}
#ifdef _WIN32
setSyslogEnabled(server.syslog_enabled);
#endif
} else if (!strcasecmp(argv[0],"syslog-ident") && argc == 2) {
if (server.syslog_ident) zfree(server.syslog_ident);
server.syslog_ident = zstrdup(argv[1]);
} else if (!strcasecmp(argv[0],"syslog-facility") && argc == 2) {
#ifdef _WIN32
// Skip error - just ignore Syslog
// err "Syslog is not supported on Windows platform.";
// goto loaderr;
setSyslogIdent(server.syslog_ident);
#endif
} else if (!strcasecmp(argv[0], "syslog-facility") && argc == 2) {
#ifdef _WIN32
// Skip error - just ignore syslog-facility
#else
int i;
......
......@@ -45,6 +45,7 @@
#ifdef _WIN32
#include "win32_Interop/win32fixes.h"
int fmode = _O_BINARY;
#include <time.h>
#endif
#include "ae.h"
......
......@@ -169,9 +169,9 @@ int main(int argc, char **argv) {
long long diff;
_fmode = _O_BINARY;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
setmode(_fileno(stdin), _O_BINARY);
setmode(_fileno(stdout), _O_BINARY);
setmode(_fileno(stderr), _O_BINARY);
#else
off_t size;
off_t pos;
......
......@@ -773,9 +773,9 @@ int main(int argc, char **argv) {
#ifdef _WIN32
_fmode = _O_BINARY;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
setmode(_fileno(stdin), _O_BINARY);
setmode(_fileno(stdout), _O_BINARY);
setmode(_fileno(stderr), _O_BINARY);
fd = open(argv[1], O_RDONLY|_O_BINARY,0);
#else
......
......@@ -1921,9 +1921,9 @@ int main(int argc, char **argv) {
#ifdef _WIN32
_fmode = _O_BINARY;
_setmode(_fileno(stdin), _O_BINARY);
_setmode(_fileno(stdout), _O_BINARY);
_setmode(_fileno(stderr), _O_BINARY);
setmode(_fileno(stdin), _O_BINARY);
setmode(_fileno(stdout), _O_BINARY);
setmode(_fileno(stderr), _O_BINARY);
#endif
firstarg = parseOptions(argc,argv);
argc -= firstarg;
......
......@@ -1366,8 +1366,10 @@ void initServerConfig() {
server.syslog_ident = zstrdup(REDIS_DEFAULT_SYSLOG_IDENT);
server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED;
}
setSyslogEnabled(server.syslog_enabled);
setSyslogIdent(server.syslog_ident);
#else
server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED;
server.syslog_enabled = REDIS_DEFAULT_SYSLOG_ENABLED;
server.syslog_ident = zstrdup(REDIS_DEFAULT_SYSLOG_IDENT);
#endif
server.syslog_facility = LOG_LOCAL0;
......
......@@ -34,7 +34,9 @@
extern "C" {
#endif
void setLogVerbosityLevel (int level);
void setSyslogEnabled(int flag);
void setSyslogIdent(const char* ident);
void setLogVerbosityLevel(int level);
void setLogFile (const char* logFileName);
void redisLogRaw(int level, const char *msg);
void redisLog(int level, const char *fmt, ...);
......
......@@ -41,6 +41,8 @@
#include "release.h"
#endif
#include <string.h>
#include "version.h"
#include "crc64.h"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册