mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
IM port cleanup
This commit is contained in:
@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
IMService::IMService(void)
|
IMService::IMService(void)
|
||||||
{
|
{
|
||||||
serviceName = "MySqlManager";
|
serviceName= "MySqlManager";
|
||||||
displayName = "MySQL Manager";
|
displayName= "MySQL Manager";
|
||||||
}
|
}
|
||||||
|
|
||||||
IMService::~IMService(void)
|
IMService::~IMService(void)
|
||||||
@ -35,13 +35,13 @@ void IMService::Log(const char *msg)
|
|||||||
log_info(msg);
|
log_info(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
int HandleServiceOptions(Options options)
|
int HandleServiceOptions(Options options)
|
||||||
{
|
{
|
||||||
int ret_val= 0;
|
int ret_val= 0;
|
||||||
|
|
||||||
IMService winService;
|
IMService winService;
|
||||||
|
|
||||||
if (options.install_as_service)
|
if (options.install_as_service)
|
||||||
{
|
{
|
||||||
if (winService.IsInstalled())
|
if (winService.IsInstalled())
|
||||||
log_info("Service is already installed\n");
|
log_info("Service is already installed\n");
|
||||||
@ -59,7 +59,7 @@ int HandleServiceOptions(Options options)
|
|||||||
log_info("Service is not installed\n");
|
log_info("Service is not installed\n");
|
||||||
else if (winService.Remove())
|
else if (winService.Remove())
|
||||||
log_info("Service removed successfully\n");
|
log_info("Service removed successfully\n");
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
log_info("Service failed to remove\n");
|
log_info("Service failed to remove\n");
|
||||||
ret_val= -1;
|
ret_val= -1;
|
||||||
@ -69,4 +69,3 @@ int HandleServiceOptions(Options options)
|
|||||||
return (int)winService.Init();
|
return (int)winService.Init();
|
||||||
return ret_val;
|
return ret_val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,9 +4,9 @@
|
|||||||
|
|
||||||
static WindowsService *gService;
|
static WindowsService *gService;
|
||||||
|
|
||||||
WindowsService::WindowsService(void) :
|
WindowsService::WindowsService(void) :
|
||||||
statusCheckpoint(0),
|
statusCheckpoint(0),
|
||||||
serviceName(NULL),
|
serviceName(NULL),
|
||||||
inited(false),
|
inited(false),
|
||||||
dwAcceptedControls(SERVICE_ACCEPT_STOP)
|
dwAcceptedControls(SERVICE_ACCEPT_STOP)
|
||||||
{
|
{
|
||||||
@ -32,14 +32,14 @@ BOOL WindowsService::Install()
|
|||||||
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
|
GetModuleFileName(NULL, szFilePath, sizeof(szFilePath));
|
||||||
|
|
||||||
// open a connection to the SCM
|
// open a connection to the SCM
|
||||||
if (!(scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
|
if (!(scm= OpenSCManager(0, 0,SC_MANAGER_CREATE_SERVICE)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
newService= CreateService(scm, serviceName, displayName,
|
newService= CreateService(scm, serviceName, displayName,
|
||||||
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
|
SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS,
|
||||||
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
SERVICE_AUTO_START, SERVICE_ERROR_NORMAL,
|
||||||
szFilePath, NULL, NULL, NULL, username,
|
szFilePath, NULL, NULL, NULL, username,
|
||||||
password);
|
password);
|
||||||
|
|
||||||
if (newService)
|
if (newService)
|
||||||
{
|
{
|
||||||
@ -68,7 +68,7 @@ BOOL WindowsService::Init()
|
|||||||
|
|
||||||
BOOL WindowsService::Remove()
|
BOOL WindowsService::Remove()
|
||||||
{
|
{
|
||||||
bool ret_val= false;
|
bool ret_val= false;
|
||||||
|
|
||||||
if (! IsInstalled())
|
if (! IsInstalled())
|
||||||
return true;
|
return true;
|
||||||
@ -81,7 +81,7 @@ BOOL WindowsService::Remove()
|
|||||||
SC_HANDLE service= OpenService(scm, serviceName, DELETE);
|
SC_HANDLE service= OpenService(scm, serviceName, DELETE);
|
||||||
if (service)
|
if (service)
|
||||||
{
|
{
|
||||||
if (DeleteService(service))
|
if (DeleteService(service))
|
||||||
ret_val= true;
|
ret_val= true;
|
||||||
DWORD dw= ::GetLastError();
|
DWORD dw= ::GetLastError();
|
||||||
CloseServiceHandle(service);
|
CloseServiceHandle(service);
|
||||||
@ -112,18 +112,18 @@ void WindowsService::SetAcceptedControls(DWORD acceptedControls)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint,
|
BOOL WindowsService::ReportStatus(DWORD currentState, DWORD waitHint,
|
||||||
DWORD dwError)
|
DWORD dwError)
|
||||||
{
|
{
|
||||||
if(debugging) return TRUE;
|
if(debugging) return TRUE;
|
||||||
|
|
||||||
if(currentState == SERVICE_START_PENDING)
|
if(currentState == SERVICE_START_PENDING)
|
||||||
status.dwControlsAccepted= 0;
|
status.dwControlsAccepted= 0;
|
||||||
else
|
else
|
||||||
status.dwControlsAccepted= dwAcceptedControls;
|
status.dwControlsAccepted= dwAcceptedControls;
|
||||||
|
|
||||||
status.dwCurrentState= currentState;
|
status.dwCurrentState= currentState;
|
||||||
status.dwWin32ExitCode= dwError != 0 ?
|
status.dwWin32ExitCode= dwError != 0 ?
|
||||||
ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR;
|
ERROR_SERVICE_SPECIFIC_ERROR : NO_ERROR;
|
||||||
status.dwWaitHint= waitHint;
|
status.dwWaitHint= waitHint;
|
||||||
status.dwServiceSpecificExitCode= dwError;
|
status.dwServiceSpecificExitCode= dwError;
|
||||||
@ -155,35 +155,34 @@ void WindowsService::RegisterAndRun(DWORD argc, LPTSTR *argv)
|
|||||||
void WindowsService::HandleControlCode(DWORD opcode)
|
void WindowsService::HandleControlCode(DWORD opcode)
|
||||||
{
|
{
|
||||||
// Handle the requested control code.
|
// Handle the requested control code.
|
||||||
switch(opcode)
|
switch(opcode) {
|
||||||
{
|
case SERVICE_CONTROL_STOP:
|
||||||
case SERVICE_CONTROL_STOP:
|
// Stop the service.
|
||||||
// Stop the service.
|
status.dwCurrentState= SERVICE_STOP_PENDING;
|
||||||
status.dwCurrentState= SERVICE_STOP_PENDING;
|
Stop();
|
||||||
Stop();
|
break;
|
||||||
break;
|
|
||||||
|
|
||||||
case SERVICE_CONTROL_PAUSE:
|
case SERVICE_CONTROL_PAUSE:
|
||||||
status.dwCurrentState= SERVICE_PAUSE_PENDING;
|
status.dwCurrentState= SERVICE_PAUSE_PENDING;
|
||||||
Pause();
|
Pause();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_CONTROL_CONTINUE:
|
case SERVICE_CONTROL_CONTINUE:
|
||||||
status.dwCurrentState= SERVICE_CONTINUE_PENDING;
|
status.dwCurrentState= SERVICE_CONTINUE_PENDING;
|
||||||
Continue();
|
Continue();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_CONTROL_SHUTDOWN:
|
case SERVICE_CONTROL_SHUTDOWN:
|
||||||
Shutdown();
|
Shutdown();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SERVICE_CONTROL_INTERROGATE:
|
case SERVICE_CONTROL_INTERROGATE:
|
||||||
ReportStatus(status.dwCurrentState);
|
ReportStatus(status.dwCurrentState);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
// invalid control code
|
// invalid control code
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -201,5 +200,3 @@ void WINAPI WindowsService::ControlHandler(DWORD opcode)
|
|||||||
|
|
||||||
return gService->HandleControlCode(opcode);
|
return gService->HandleControlCode(opcode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
class WindowsService
|
class WindowsService
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
bool inited;
|
bool inited;
|
||||||
const char *serviceName;
|
const char *serviceName;
|
||||||
const char *displayName;
|
const char *displayName;
|
||||||
const char *username;
|
const char *username;
|
||||||
@ -23,11 +23,11 @@ public:
|
|||||||
BOOL Init();
|
BOOL Init();
|
||||||
BOOL IsInstalled();
|
BOOL IsInstalled();
|
||||||
void SetAcceptedControls(DWORD acceptedControls);
|
void SetAcceptedControls(DWORD acceptedControls);
|
||||||
void Debug(bool debugFlag) { debugging = debugFlag; }
|
void Debug(bool debugFlag) { debugging= debugFlag; }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
|
static void WINAPI ServiceMain(DWORD argc, LPTSTR *argv);
|
||||||
static void WINAPI ControlHandler(DWORD CtrlType);
|
static void WINAPI ControlHandler(DWORD CtrlType);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void Run()= 0;
|
virtual void Run()= 0;
|
||||||
@ -41,4 +41,3 @@ protected:
|
|||||||
void HandleControlCode(DWORD opcode);
|
void HandleControlCode(DWORD opcode);
|
||||||
void RegisterAndRun(DWORD argc, LPTSTR *argv);
|
void RegisterAndRun(DWORD argc, LPTSTR *argv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -57,12 +57,12 @@ C_MODE_END
|
|||||||
|
|
||||||
void Instance::remove_pid()
|
void Instance::remove_pid()
|
||||||
{
|
{
|
||||||
int pid;
|
int pid;
|
||||||
if ((pid= options.get_pid()) != 0) /* check the pidfile */
|
if ((pid= options.get_pid()) != 0) /* check the pidfile */
|
||||||
if (options.unlink_pidfile()) /* remove stalled pidfile */
|
if (options.unlink_pidfile()) /* remove stalled pidfile */
|
||||||
log_error("cannot remove pidfile for instance %i, this might be \
|
log_error("cannot remove pidfile for instance %i, this might be \
|
||||||
since IM lacks permmissions or hasn't found the pidifle",
|
since IM lacks permmissions or hasn't found the pidifle",
|
||||||
options.instance_name);
|
options.instance_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -121,16 +121,15 @@ int Instance::launch_and_wait()
|
|||||||
{
|
{
|
||||||
pid_t pid= fork();
|
pid_t pid= fork();
|
||||||
|
|
||||||
switch (pid)
|
switch (pid) {
|
||||||
{
|
case 0:
|
||||||
case 0:
|
execv(options.mysqld_path, options.argv);
|
||||||
execv(options.mysqld_path, options.argv);
|
/* exec never returns */
|
||||||
/* exec never returns */
|
exit(1);
|
||||||
exit(1);
|
case -1:
|
||||||
case -1:
|
log_info("cannot fork() to start instance %s", options.instance_name);
|
||||||
log_info("cannot fork() to start instance %s", options.instance_name);
|
return -1;
|
||||||
return -1;
|
default:
|
||||||
default:
|
|
||||||
/*
|
/*
|
||||||
Here we wait for the child created. This process differs for systems
|
Here we wait for the child created. This process differs for systems
|
||||||
running LinuxThreads and POSIX Threads compliant systems. This is because
|
running LinuxThreads and POSIX Threads compliant systems. This is because
|
||||||
@ -157,56 +156,56 @@ int Instance::launch_and_wait()
|
|||||||
#else
|
#else
|
||||||
int Instance::launch_and_wait()
|
int Instance::launch_and_wait()
|
||||||
{
|
{
|
||||||
STARTUPINFO si;
|
STARTUPINFO si;
|
||||||
PROCESS_INFORMATION pi;
|
PROCESS_INFORMATION pi;
|
||||||
|
|
||||||
ZeroMemory(&si, sizeof(si));
|
ZeroMemory(&si, sizeof(si));
|
||||||
si.cb = sizeof(si);
|
si.cb= sizeof(si);
|
||||||
ZeroMemory(&pi, sizeof(pi));
|
ZeroMemory(&pi, sizeof(pi));
|
||||||
|
|
||||||
int cmdlen= 0;
|
int cmdlen= 0;
|
||||||
|
for (int i= 1; options.argv[i] != 0; i++)
|
||||||
|
cmdlen+= strlen(options.argv[i]) + 1;
|
||||||
|
cmdlen++; // we have to add a single space for CreateProcess (read the docs)
|
||||||
|
|
||||||
|
char *cmdline= NULL;
|
||||||
|
if (cmdlen > 0)
|
||||||
|
{
|
||||||
|
cmdline= new char[cmdlen];
|
||||||
|
cmdline[0]= 0;
|
||||||
for (int i= 1; options.argv[i] != 0; i++)
|
for (int i= 1; options.argv[i] != 0; i++)
|
||||||
cmdlen+= strlen(options.argv[i]) + 1;
|
|
||||||
cmdlen++; // we have to add a single space for CreateProcess (read the docs)
|
|
||||||
|
|
||||||
char *cmdline= NULL;
|
|
||||||
if (cmdlen > 0)
|
|
||||||
{
|
{
|
||||||
cmdline= new char[cmdlen];
|
strcat(cmdline, " ");
|
||||||
cmdline[0]= 0;
|
strcat(cmdline, options.argv[i]);
|
||||||
for (int i= 1; options.argv[i] != 0; i++)
|
|
||||||
{
|
|
||||||
strcat(cmdline, " ");
|
|
||||||
strcat(cmdline, options.argv[i]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Start the child process.
|
// Start the child process.
|
||||||
BOOL result= CreateProcess(options.mysqld_path, // file to execute
|
BOOL result= CreateProcess(options.mysqld_path, // file to execute
|
||||||
cmdline, // Command line.
|
cmdline, // Command line.
|
||||||
NULL, // Process handle not inheritable.
|
NULL, // Process handle not inheritable.
|
||||||
NULL, // Thread handle not inheritable.
|
NULL, // Thread handle not inheritable.
|
||||||
FALSE, // Set handle inheritance to FALSE.
|
FALSE, // Set handle inheritance to FALSE.
|
||||||
0, // No creation flags.
|
0, // No creation flags.
|
||||||
NULL, // Use parent's environment block.
|
NULL, // Use parent's environment block.
|
||||||
NULL, // Use parent's starting directory.
|
NULL, // Use parent's starting directory.
|
||||||
&si, // Pointer to STARTUPINFO structure.
|
&si, // Pointer to STARTUPINFO structure.
|
||||||
&pi ); // Pointer to PROCESS_INFORMATION structure.
|
&pi ); // Pointer to PROCESS_INFORMATION structure.
|
||||||
delete cmdline;
|
delete cmdline;
|
||||||
if (! result)
|
if (! result)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
// Wait until child process exits.
|
|
||||||
WaitForSingleObject(pi.hProcess, INFINITE);
|
|
||||||
|
|
||||||
DWORD exitcode;
|
// Wait until child process exits.
|
||||||
::GetExitCodeProcess(pi.hProcess, &exitcode);
|
WaitForSingleObject(pi.hProcess, INFINITE);
|
||||||
|
|
||||||
// Close process and thread handles.
|
DWORD exitcode;
|
||||||
CloseHandle(pi.hProcess);
|
::GetExitCodeProcess(pi.hProcess, &exitcode);
|
||||||
CloseHandle(pi.hThread);
|
|
||||||
|
|
||||||
return exitcode;
|
// Close process and thread handles.
|
||||||
|
CloseHandle(pi.hProcess);
|
||||||
|
CloseHandle(pi.hThread);
|
||||||
|
|
||||||
|
return exitcode;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -214,9 +213,9 @@ int Instance::launch_and_wait()
|
|||||||
void Instance::fork_and_monitor()
|
void Instance::fork_and_monitor()
|
||||||
{
|
{
|
||||||
log_info("starting instance %s", options.instance_name);
|
log_info("starting instance %s", options.instance_name);
|
||||||
|
|
||||||
int result= launch_and_wait();
|
if (launch_and_wait())
|
||||||
if (result == -1) return;
|
return; /* error is logged */
|
||||||
|
|
||||||
/* set instance state to crashed */
|
/* set instance state to crashed */
|
||||||
pthread_mutex_lock(&LOCK_instance);
|
pthread_mutex_lock(&LOCK_instance);
|
||||||
@ -233,9 +232,6 @@ void Instance::fork_and_monitor()
|
|||||||
pthread_cond_signal(&instance_map->guardian->COND_guardian);
|
pthread_cond_signal(&instance_map->guardian->COND_guardian);
|
||||||
/* thread exits */
|
/* thread exits */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* we should never end up here */
|
|
||||||
DBUG_ASSERT(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -268,9 +264,9 @@ bool Instance::is_running()
|
|||||||
MYSQL mysql;
|
MYSQL mysql;
|
||||||
uint port= 0;
|
uint port= 0;
|
||||||
const char *socket= NULL;
|
const char *socket= NULL;
|
||||||
const char *password= "check_connection";
|
static const char *password= "check_connection";
|
||||||
const char *username= "MySQL_Instance_Manager";
|
static const char *username= "MySQL_Instance_Manager";
|
||||||
const char *access_denied_message= "Access denied for user";
|
static const char *access_denied_message= "Access denied for user";
|
||||||
bool return_val;
|
bool return_val;
|
||||||
|
|
||||||
if (options.mysqld_port)
|
if (options.mysqld_port)
|
||||||
@ -299,15 +295,8 @@ bool Instance::is_running()
|
|||||||
return_val= TRUE; /* server is alive */
|
return_val= TRUE; /* server is alive */
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
return_val= test(!strncmp(access_denied_message, mysql_error(&mysql),
|
||||||
if (!strncmp(access_denied_message, mysql_error(&mysql),
|
sizeof(access_denied_message) - 1));
|
||||||
sizeof(access_denied_message)-1))
|
|
||||||
{
|
|
||||||
return_val= TRUE;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return_val= FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
mysql_close(&mysql);
|
mysql_close(&mysql);
|
||||||
pthread_mutex_unlock(&LOCK_instance);
|
pthread_mutex_unlock(&LOCK_instance);
|
||||||
@ -370,53 +359,53 @@ err:
|
|||||||
|
|
||||||
BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
|
BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode)
|
||||||
{
|
{
|
||||||
DWORD dwTID, dwCode, dwErr = 0;
|
DWORD dwTID, dwCode, dwErr= 0;
|
||||||
HANDLE hProcessDup= INVALID_HANDLE_VALUE;
|
HANDLE hProcessDup= INVALID_HANDLE_VALUE;
|
||||||
HANDLE hRT= NULL;
|
HANDLE hRT= NULL;
|
||||||
HINSTANCE hKernel= GetModuleHandle("Kernel32");
|
HINSTANCE hKernel= GetModuleHandle("Kernel32");
|
||||||
BOOL bSuccess= FALSE;
|
BOOL bSuccess= FALSE;
|
||||||
|
|
||||||
BOOL bDup= DuplicateHandle(GetCurrentProcess(),
|
BOOL bDup= DuplicateHandle(GetCurrentProcess(),
|
||||||
hProcess, GetCurrentProcess(), &hProcessDup,
|
hProcess, GetCurrentProcess(), &hProcessDup,
|
||||||
PROCESS_ALL_ACCESS, FALSE, 0);
|
PROCESS_ALL_ACCESS, FALSE, 0);
|
||||||
|
|
||||||
// Detect the special case where the process is
|
// Detect the special case where the process is
|
||||||
// already dead...
|
// already dead...
|
||||||
if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
|
if (GetExitCodeProcess((bDup) ? hProcessDup : hProcess, &dwCode) &&
|
||||||
(dwCode == STILL_ACTIVE))
|
(dwCode == STILL_ACTIVE))
|
||||||
{
|
{
|
||||||
FARPROC pfnExitProc;
|
FARPROC pfnExitProc;
|
||||||
|
|
||||||
pfnExitProc= GetProcAddress(hKernel, "ExitProcess");
|
pfnExitProc= GetProcAddress(hKernel, "ExitProcess");
|
||||||
|
|
||||||
hRT= CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0,
|
hRT= CreateRemoteThread((bDup) ? hProcessDup : hProcess, NULL, 0,
|
||||||
(LPTHREAD_START_ROUTINE)pfnExitProc,
|
(LPTHREAD_START_ROUTINE)pfnExitProc,
|
||||||
(PVOID)uExitCode, 0, &dwTID);
|
(PVOID)uExitCode, 0, &dwTID);
|
||||||
|
|
||||||
if (hRT == NULL)
|
if (hRT == NULL)
|
||||||
dwErr= GetLastError();
|
dwErr= GetLastError();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
dwErr= ERROR_PROCESS_ABORTED;
|
dwErr= ERROR_PROCESS_ABORTED;
|
||||||
|
|
||||||
if (hRT)
|
if (hRT)
|
||||||
{
|
{
|
||||||
// Must wait process to terminate to
|
// Must wait process to terminate to
|
||||||
// guarantee that it has exited...
|
// guarantee that it has exited...
|
||||||
WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
|
WaitForSingleObject((bDup) ? hProcessDup : hProcess, INFINITE);
|
||||||
|
|
||||||
CloseHandle(hRT);
|
CloseHandle(hRT);
|
||||||
bSuccess= TRUE;
|
bSuccess= TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bDup)
|
if (bDup)
|
||||||
CloseHandle(hProcessDup);
|
CloseHandle(hProcessDup);
|
||||||
|
|
||||||
if (!bSuccess)
|
if (!bSuccess)
|
||||||
SetLastError(dwErr);
|
SetLastError(dwErr);
|
||||||
|
|
||||||
return bSuccess;
|
return bSuccess;
|
||||||
}
|
}
|
||||||
|
|
||||||
int kill(pid_t pid, int signum)
|
int kill(pid_t pid, int signum)
|
||||||
{
|
{
|
||||||
|
@ -108,11 +108,11 @@ void Listener_thread::run()
|
|||||||
FD_ZERO(&read_fds);
|
FD_ZERO(&read_fds);
|
||||||
|
|
||||||
/* I. prepare 'listen' sockets */
|
/* I. prepare 'listen' sockets */
|
||||||
if (create_tcp_socket())
|
if (create_tcp_socket())
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
#ifndef __WIN__
|
#ifndef __WIN__
|
||||||
if (create_unix_socket(unix_socket_address))
|
if (create_unix_socket(unix_socket_address))
|
||||||
goto err;
|
goto err;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -133,12 +133,12 @@ void Listener_thread::run()
|
|||||||
int rc= select(n, &read_fds_arg, 0, 0, 0);
|
int rc= select(n, &read_fds_arg, 0, 0, 0);
|
||||||
|
|
||||||
|
|
||||||
if (rc == -1 && errno != EINTR)
|
if (rc == -1 && errno != EINTR)
|
||||||
{
|
{
|
||||||
log_error("Listener_thread::run(): select() failed, %s",
|
log_error("Listener_thread::run(): select() failed, %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (int socket_index= 0; socket_index < num_sockets; socket_index++)
|
for (int socket_index= 0; socket_index < num_sockets; socket_index++)
|
||||||
@ -150,8 +150,8 @@ void Listener_thread::run()
|
|||||||
/* accept may return -1 (failure or spurious wakeup) */
|
/* accept may return -1 (failure or spurious wakeup) */
|
||||||
if (client_fd >= 0) // connection established
|
if (client_fd >= 0) // connection established
|
||||||
{
|
{
|
||||||
Vio *vio = vio_new(client_fd, socket_index==0?VIO_TYPE_SOCKET:
|
Vio *vio= vio_new(client_fd, socket_index==0?VIO_TYPE_SOCKET:
|
||||||
VIO_TYPE_TCPIP, socket_index==0?1:0);
|
VIO_TYPE_TCPIP, socket_index==0?1:0);
|
||||||
if (vio != 0)
|
if (vio != 0)
|
||||||
handle_new_mysql_connection(vio);
|
handle_new_mysql_connection(vio);
|
||||||
else
|
else
|
||||||
@ -212,7 +212,7 @@ void set_no_inherit(int socket)
|
|||||||
int Listener_thread::create_tcp_socket()
|
int Listener_thread::create_tcp_socket()
|
||||||
{
|
{
|
||||||
/* value to be set by setsockopt */
|
/* value to be set by setsockopt */
|
||||||
int arg= 1;
|
int arg= 1;
|
||||||
|
|
||||||
int ip_socket= socket(AF_INET, SOCK_STREAM, 0);
|
int ip_socket= socket(AF_INET, SOCK_STREAM, 0);
|
||||||
if (ip_socket == INVALID_SOCKET)
|
if (ip_socket == INVALID_SOCKET)
|
||||||
@ -236,11 +236,11 @@ int Listener_thread::create_tcp_socket()
|
|||||||
uint im_port= options.port_number;
|
uint im_port= options.port_number;
|
||||||
|
|
||||||
ip_socket_address.sin_family= AF_INET;
|
ip_socket_address.sin_family= AF_INET;
|
||||||
ip_socket_address.sin_addr.s_addr = im_bind_addr;
|
ip_socket_address.sin_addr.s_addr= im_bind_addr;
|
||||||
|
|
||||||
|
|
||||||
ip_socket_address.sin_port= (unsigned short)
|
ip_socket_address.sin_port= (unsigned short)
|
||||||
htons((unsigned short) im_port);
|
htons((unsigned short) im_port);
|
||||||
|
|
||||||
setsockopt(ip_socket, SOL_SOCKET, SO_REUSEADDR, (char*) &arg, sizeof(arg));
|
setsockopt(ip_socket, SOL_SOCKET, SO_REUSEADDR, (char*) &arg, sizeof(arg));
|
||||||
if (bind(ip_socket, (struct sockaddr *) &ip_socket_address,
|
if (bind(ip_socket, (struct sockaddr *) &ip_socket_address,
|
||||||
@ -273,8 +273,8 @@ int Listener_thread::create_tcp_socket()
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef __WIN__
|
#ifndef __WIN__
|
||||||
int Listener_thread::create_unix_socket(
|
int Listener_thread::create_unix_socket(struct sockaddr_un
|
||||||
struct sockaddr_un &unix_socket_address)
|
&unix_socket_address)
|
||||||
{
|
{
|
||||||
int unix_socket= socket(AF_UNIX, SOCK_STREAM, 0);
|
int unix_socket= socket(AF_UNIX, SOCK_STREAM, 0);
|
||||||
if (unix_socket == INVALID_SOCKET)
|
if (unix_socket == INVALID_SOCKET)
|
||||||
@ -297,20 +297,20 @@ int Listener_thread::create_unix_socket(
|
|||||||
*/
|
*/
|
||||||
mode_t old_mask= umask(0);
|
mode_t old_mask= umask(0);
|
||||||
if (bind(unix_socket, (struct sockaddr *) &unix_socket_address,
|
if (bind(unix_socket, (struct sockaddr *) &unix_socket_address,
|
||||||
sizeof(unix_socket_address)))
|
sizeof(unix_socket_address)))
|
||||||
{
|
{
|
||||||
log_error("Listener_thread::run(): bind(unix socket) failed, "
|
log_error("Listener_thread::run(): bind(unix socket) failed, "
|
||||||
"socket file name is '%s', error '%s'",
|
"socket file name is '%s', error '%s'",
|
||||||
unix_socket_address.sun_path, strerror(errno));
|
unix_socket_address.sun_path, strerror(errno));
|
||||||
close(unix_socket);
|
close(unix_socket);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
umask(old_mask);
|
umask(old_mask);
|
||||||
|
|
||||||
if (listen(unix_socket, LISTEN_BACK_LOG_SIZE))
|
if (listen(unix_socket, LISTEN_BACK_LOG_SIZE))
|
||||||
{
|
{
|
||||||
log_error("Listener_thread::run(): listen(unix socket) failed, %s",
|
log_error("Listener_thread::run(): listen(unix socket) failed, %s",
|
||||||
strerror(errno));
|
strerror(errno));
|
||||||
close(unix_socket);
|
close(unix_socket);
|
||||||
return -1;
|
return -1;
|
||||||
@ -322,8 +322,9 @@ int Listener_thread::create_unix_socket(
|
|||||||
/* make sure that instances won't be listening our sockets */
|
/* make sure that instances won't be listening our sockets */
|
||||||
set_no_inherit(unix_socket);
|
set_no_inherit(unix_socket);
|
||||||
|
|
||||||
log_info("accepting connections on unix socket %s", unix_socket_address.sun_path);
|
log_info("accepting connections on unix socket %s",
|
||||||
sockets[num_sockets++] = unix_socket;
|
unix_socket_address.sun_path);
|
||||||
|
sockets[num_sockets++]= unix_socket;
|
||||||
FD_SET(unix_socket, &read_fds);
|
FD_SET(unix_socket, &read_fds);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -238,20 +238,20 @@ void manager(const Options &options)
|
|||||||
process_alarm(signo);
|
process_alarm(signo);
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
{
|
||||||
|
if (!guardian_thread.is_stopped())
|
||||||
{
|
{
|
||||||
if (!guardian_thread.is_stopped())
|
bool stop_instances= true;
|
||||||
{
|
guardian_thread.request_shutdown(stop_instances);
|
||||||
bool stop_instances= true;
|
pthread_cond_signal(&guardian_thread.COND_guardian);
|
||||||
guardian_thread.request_shutdown(stop_instances);
|
}
|
||||||
pthread_cond_signal(&guardian_thread.COND_guardian);
|
else
|
||||||
}
|
{
|
||||||
else
|
thread_registry.deliver_shutdown();
|
||||||
{
|
shutdown_complete= TRUE;
|
||||||
thread_registry.deliver_shutdown();
|
|
||||||
shutdown_complete= TRUE;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
err:
|
err:
|
||||||
/* delete the pid file */
|
/* delete the pid file */
|
||||||
|
@ -111,22 +111,23 @@ static struct my_option my_long_options[] =
|
|||||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
|
|
||||||
{ "default-mysqld-path", OPT_MYSQLD_PATH, "Where to look for MySQL"
|
{ "default-mysqld-path", OPT_MYSQLD_PATH, "Where to look for MySQL"
|
||||||
" Server binary.",
|
" Server binary.",
|
||||||
(gptr *) &Options::default_mysqld_path, (gptr *) &Options::default_mysqld_path,
|
(gptr *) &Options::default_mysqld_path,
|
||||||
|
(gptr *) &Options::default_mysqld_path,
|
||||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
|
|
||||||
{ "monitoring-interval", OPT_MONITORING_INTERVAL, "Interval to monitor instances"
|
{ "monitoring-interval", OPT_MONITORING_INTERVAL, "Interval to monitor"
|
||||||
" in seconds.",
|
" instances in seconds.",
|
||||||
(gptr *) &Options::monitoring_interval,
|
(gptr *) &Options::monitoring_interval,
|
||||||
(gptr *) &Options::monitoring_interval,
|
(gptr *) &Options::monitoring_interval,
|
||||||
0, GET_UINT, REQUIRED_ARG, DEFAULT_MONITORING_INTERVAL,
|
0, GET_UINT, REQUIRED_ARG, DEFAULT_MONITORING_INTERVAL,
|
||||||
0, 0, 0, 0, 0 },
|
0, 0, 0, 0, 0 },
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
{ "install", OPT_INSTALL_SERVICE, "Install as system service.",
|
{ "install", OPT_INSTALL_SERVICE, "Install as system service.",
|
||||||
(gptr *) &Options::install_as_service, (gptr*) &Options::install_as_service,
|
(gptr *) &Options::install_as_service, (gptr*) &Options::install_as_service,
|
||||||
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
|
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
|
||||||
{ "remove", OPT_REMOVE_SERVICE, "Remove system service.",
|
{ "remove", OPT_REMOVE_SERVICE, "Remove system service.",
|
||||||
(gptr *)&Options::remove_service, (gptr*) &Options::remove_service,
|
(gptr *)&Options::remove_service, (gptr*) &Options::remove_service,
|
||||||
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0},
|
0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0},
|
||||||
#else
|
#else
|
||||||
{ "run-as-service", OPT_RUN_AS_SERVICE,
|
{ "run-as-service", OPT_RUN_AS_SERVICE,
|
||||||
@ -134,12 +135,12 @@ static struct my_option my_long_options[] =
|
|||||||
0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
|
0, 0, GET_BOOL, NO_ARG, 0, 0, 1, 0, 0, 0 },
|
||||||
|
|
||||||
{ "user", OPT_USER, "Username to start mysqlmanager",
|
{ "user", OPT_USER, "Username to start mysqlmanager",
|
||||||
(gptr *) &Options::user,
|
(gptr *) &Options::user,
|
||||||
(gptr *) &Options::user,
|
(gptr *) &Options::user,
|
||||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
#endif
|
#endif
|
||||||
{ "version", 'V', "Output version information and exit.", 0, 0, 0,
|
{ "version", 'V', "Output version information and exit.", 0, 0, 0,
|
||||||
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 },
|
||||||
|
|
||||||
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
|
{ 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
|
||||||
};
|
};
|
||||||
@ -242,7 +243,7 @@ C_MODE_END
|
|||||||
int Options::load(int argc, char **argv)
|
int Options::load(int argc, char **argv)
|
||||||
{
|
{
|
||||||
saved_argv= argv;
|
saved_argv= argv;
|
||||||
|
|
||||||
if (argc >= 2)
|
if (argc >= 2)
|
||||||
{
|
{
|
||||||
if (is_prefix(argv[1], "--defaults-file="))
|
if (is_prefix(argv[1], "--defaults-file="))
|
||||||
@ -254,19 +255,19 @@ int Options::load(int argc, char **argv)
|
|||||||
{
|
{
|
||||||
/* the log is not enabled yet */
|
/* the log is not enabled yet */
|
||||||
fprintf(stderr, "The --defaults-extra-file and --no-defaults options"
|
fprintf(stderr, "The --defaults-extra-file and --no-defaults options"
|
||||||
" are not supported by\n"
|
" are not supported by\n"
|
||||||
"Instance Manager. Program aborted.\n");
|
"Instance Manager. Program aborted.\n");
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef __WIN__
|
#ifdef __WIN__
|
||||||
setup_windows_defaults(*argv);
|
setup_windows_defaults(*argv);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
On Windows, there are two possibilities. Either we are given
|
On Windows, there are two possibilities. Either we are given
|
||||||
a defaults file on the command line or we use the my.ini file
|
a defaults file on the command line or we use the my.ini file
|
||||||
that is in our app dir
|
that is in our app dir
|
||||||
*/
|
*/
|
||||||
if (Options::config_file == NULL)
|
if (Options::config_file == NULL)
|
||||||
{
|
{
|
||||||
@ -274,7 +275,7 @@ int Options::load(int argc, char **argv)
|
|||||||
static const char default_win_config_file_name[]= "\\my.ini";
|
static const char default_win_config_file_name[]= "\\my.ini";
|
||||||
|
|
||||||
if (!GetModuleFileName(NULL, windows_config_file,
|
if (!GetModuleFileName(NULL, windows_config_file,
|
||||||
sizeof(windows_config_file)))
|
sizeof(windows_config_file)))
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
filename= strrchr(windows_config_file, "\\");
|
filename= strrchr(windows_config_file, "\\");
|
||||||
@ -316,7 +317,7 @@ char* change_extension(const char *src, const char *newext)
|
|||||||
{
|
{
|
||||||
char *dot= (char*)strrchr(src, '.');
|
char *dot= (char*)strrchr(src, '.');
|
||||||
if (!dot) return (char*)src;
|
if (!dot) return (char*)src;
|
||||||
|
|
||||||
int newlen= dot-src+strlen(newext)+1;
|
int newlen= dot-src+strlen(newext)+1;
|
||||||
char *temp= (char*)malloc(newlen);
|
char *temp= (char*)malloc(newlen);
|
||||||
bzero(temp, newlen);
|
bzero(temp, newlen);
|
||||||
@ -327,9 +328,9 @@ char* change_extension(const char *src, const char *newext)
|
|||||||
|
|
||||||
void Options::setup_windows_defaults(const char *progname)
|
void Options::setup_windows_defaults(const char *progname)
|
||||||
{
|
{
|
||||||
Options::password_file_name= default_password_file_name =
|
Options::password_file_name= default_password_file_name=
|
||||||
change_extension(progname, "passwd");
|
change_extension(progname, "passwd");
|
||||||
Options::log_file_name= default_log_file_name =
|
Options::log_file_name= default_log_file_name=
|
||||||
change_extension(progname, "log");
|
change_extension(progname, "log");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
||||||
|
|
||||||
#ifdef __GNUC__
|
#ifdef __GNUC__
|
||||||
#pragma interface
|
#pragma interface
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "user_map.h"
|
#include "user_map.h"
|
||||||
@ -25,6 +25,12 @@
|
|||||||
|
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
|
#ifdef __WIN__
|
||||||
|
#define NEWLINE_LEN 2
|
||||||
|
#else
|
||||||
|
#define NEWLINE_LEN 1
|
||||||
|
#endif
|
||||||
|
|
||||||
struct User
|
struct User
|
||||||
{
|
{
|
||||||
char user[USERNAME_LENGTH + 1];
|
char user[USERNAME_LENGTH + 1];
|
||||||
@ -36,8 +42,7 @@ struct User
|
|||||||
|
|
||||||
int User::init(const char *line)
|
int User::init(const char *line)
|
||||||
{
|
{
|
||||||
const char *name_begin, *name_end;
|
const char *name_begin, *name_end, *password;
|
||||||
char *password;
|
|
||||||
|
|
||||||
if (line[0] == '\'' || line[0] == '"')
|
if (line[0] == '\'' || line[0] == '"')
|
||||||
{
|
{
|
||||||
@ -45,7 +50,7 @@ int User::init(const char *line)
|
|||||||
name_end= strchr(name_begin, line[0]);
|
name_end= strchr(name_begin, line[0]);
|
||||||
if (name_end == 0 || name_end[1] != ':')
|
if (name_end == 0 || name_end[1] != ':')
|
||||||
goto err;
|
goto err;
|
||||||
password= (char*)(name_end + 2);
|
password= name_end + 2;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -53,19 +58,14 @@ int User::init(const char *line)
|
|||||||
name_end= strchr(name_begin, ':');
|
name_end= strchr(name_begin, ':');
|
||||||
if (name_end == 0)
|
if (name_end == 0)
|
||||||
goto err;
|
goto err;
|
||||||
password= (char*)(name_end + 1);
|
password= name_end + 1;
|
||||||
}
|
}
|
||||||
user_length= name_end - name_begin;
|
user_length= name_end - name_begin;
|
||||||
if (user_length > USERNAME_LENGTH)
|
if (user_length > USERNAME_LENGTH)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
/* assume that newline characater is present */
|
/* assume that newline characater is present */
|
||||||
if (password[strlen(password)-2] == '\r')
|
if (strlen(password) != SCRAMBLED_PASSWORD_CHAR_LENGTH + NEWLINE_LEN)
|
||||||
{
|
|
||||||
password[strlen(password)-2]= '\n';
|
|
||||||
password[strlen(password)-1]= 0;
|
|
||||||
}
|
|
||||||
if (strlen(password) != SCRAMBLED_PASSWORD_CHAR_LENGTH + 1)
|
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
memcpy(user, name_begin, user_length);
|
memcpy(user, name_begin, user_length);
|
||||||
@ -101,7 +101,7 @@ C_MODE_END
|
|||||||
|
|
||||||
int User_map::init()
|
int User_map::init()
|
||||||
{
|
{
|
||||||
enum { START_HASH_SIZE = 16 };
|
enum { START_HASH_SIZE= 16 };
|
||||||
if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
if (hash_init(&hash, default_charset_info, START_HASH_SIZE, 0, 0,
|
||||||
get_user_key, delete_user, 0))
|
get_user_key, delete_user, 0))
|
||||||
return 1;
|
return 1;
|
||||||
|
Reference in New Issue
Block a user