Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
7782bca1
Commit
7782bca1
authored
Aug 04, 2005
by
unknown
Browse files
Options
Browse Files
Download
Plain Diff
Merge rburnett@bk-internal.mysql.com:/home/bk/mysql-5.0
into fedora.(none):/home/reggie/bk/im_patch
parents
548ff2a3
9a2ea370
Changes
25
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
1231 additions
and
218 deletions
+1231
-218
server-tools/instance-manager/IMService.cpp
server-tools/instance-manager/IMService.cpp
+72
-0
server-tools/instance-manager/IMService.h
server-tools/instance-manager/IMService.h
+14
-0
server-tools/instance-manager/WindowsService.cpp
server-tools/instance-manager/WindowsService.cpp
+205
-0
server-tools/instance-manager/WindowsService.h
server-tools/instance-manager/WindowsService.h
+44
-0
server-tools/instance-manager/commands.cc
server-tools/instance-manager/commands.cc
+3
-4
server-tools/instance-manager/guardian.cc
server-tools/instance-manager/guardian.cc
+11
-1
server-tools/instance-manager/instance.cc
server-tools/instance-manager/instance.cc
+175
-37
server-tools/instance-manager/instance.h
server-tools/instance-manager/instance.h
+3
-0
server-tools/instance-manager/instance_map.cc
server-tools/instance-manager/instance_map.cc
+10
-0
server-tools/instance-manager/instance_options.h
server-tools/instance-manager/instance_options.h
+1
-0
server-tools/instance-manager/listener.cc
server-tools/instance-manager/listener.cc
+175
-125
server-tools/instance-manager/listener.h
server-tools/instance-manager/listener.h
+1
-1
server-tools/instance-manager/log.cc
server-tools/instance-manager/log.cc
+1
-1
server-tools/instance-manager/manager.cc
server-tools/instance-manager/manager.cc
+66
-29
server-tools/instance-manager/manager.h
server-tools/instance-manager/manager.h
+1
-1
server-tools/instance-manager/mysqlmanager.cc
server-tools/instance-manager/mysqlmanager.cc
+20
-4
server-tools/instance-manager/mysqlmanager.vcproj
server-tools/instance-manager/mysqlmanager.vcproj
+295
-0
server-tools/instance-manager/options.cc
server-tools/instance-manager/options.cc
+74
-8
server-tools/instance-manager/options.h
server-tools/instance-manager/options.h
+10
-2
server-tools/instance-manager/parse_output.cc
server-tools/instance-manager/parse_output.cc
+1
-0
server-tools/instance-manager/port.h
server-tools/instance-manager/port.h
+25
-0
server-tools/instance-manager/priv.cc
server-tools/instance-manager/priv.cc
+2
-0
server-tools/instance-manager/priv.h
server-tools/instance-manager/priv.h
+6
-0
server-tools/instance-manager/thread_registry.cc
server-tools/instance-manager/thread_registry.cc
+7
-2
server-tools/instance-manager/user_map.cc
server-tools/instance-manager/user_map.cc
+9
-3
No files found.
server-tools/instance-manager/IMService.cpp
0 → 100755
View file @
7782bca1
#include <windows.h>
#include "log.h"
#include "options.h"
#include "IMService.h"
IMService
::
IMService
(
void
)
{
serviceName
=
"MySqlManager"
;
displayName
=
"MySQL Manager"
;
}
IMService
::~
IMService
(
void
)
{
}
void
IMService
::
Stop
()
{
ReportStatus
(
SERVICE_STOP_PENDING
);
// stop the IM work
}
void
IMService
::
Run
()
{
// report to the SCM that we're about to start
ReportStatus
((
DWORD
)
SERVICE_START_PENDING
);
// init goes here
ReportStatus
((
DWORD
)
SERVICE_RUNNING
);
// wait for main loop to terminate
}
void
IMService
::
Log
(
const
char
*
msg
)
{
log_info
(
msg
);
}
int
HandleServiceOptions
(
Options
options
)
{
int
ret_val
=
0
;
IMService
winService
;
if
(
options
.
install_as_service
)
{
if
(
winService
.
IsInstalled
())
log_info
(
"Service is already installed
\n
"
);
else
if
(
winService
.
Install
())
log_info
(
"Service installed successfully
\n
"
);
else
{
log_info
(
"Service failed to install
\n
"
);
ret_val
=
-
1
;
}
}
else
if
(
options
.
remove_service
)
{
if
(
!
winService
.
IsInstalled
())
log_info
(
"Service is not installed
\n
"
);
else
if
(
winService
.
Remove
())
log_info
(
"Service removed successfully
\n
"
);
else
{
log_info
(
"Service failed to remove
\n
"
);
ret_val
=
-
1
;
}
}
else
return
(
int
)
winService
.
Init
();
return
ret_val
;
}
server-tools/instance-manager/IMService.h
0 → 100755
View file @
7782bca1
#pragma once
#include "windowsservice.h"
class
IMService
:
public
WindowsService
{
public:
IMService
(
void
);
~
IMService
(
void
);
protected:
void
Log
(
const
char
*
msg
);
void
Stop
();
void
Run
();
};
server-tools/instance-manager/WindowsService.cpp
0 → 100755
View file @
7782bca1
#include <windows.h>
#include <assert.h>
#include ".\windowsservice.h"
static
WindowsService
*
gService
;
WindowsService
::
WindowsService
(
void
)
:
statusCheckpoint
(
0
),
serviceName
(
NULL
),
inited
(
false
),
dwAcceptedControls
(
SERVICE_ACCEPT_STOP
)
{
gService
=
this
;
status
.
dwServiceType
=
SERVICE_WIN32_OWN_PROCESS
;
status
.
dwServiceSpecificExitCode
=
0
;
}
WindowsService
::~
WindowsService
(
void
)
{
}
BOOL
WindowsService
::
Install
()
{
bool
ret_val
=
false
;
SC_HANDLE
newService
;
SC_HANDLE
scm
;
if
(
IsInstalled
())
return
true
;
// determine the name of the currently executing file
char
szFilePath
[
_MAX_PATH
];
GetModuleFileName
(
NULL
,
szFilePath
,
sizeof
(
szFilePath
));
// open a connection to the SCM
if
(
!
(
scm
=
OpenSCManager
(
0
,
0
,
SC_MANAGER_CREATE_SERVICE
)))
return
false
;
newService
=
CreateService
(
scm
,
serviceName
,
displayName
,
SERVICE_ALL_ACCESS
,
SERVICE_WIN32_OWN_PROCESS
,
SERVICE_AUTO_START
,
SERVICE_ERROR_NORMAL
,
szFilePath
,
NULL
,
NULL
,
NULL
,
username
,
password
);
if
(
newService
)
{
CloseServiceHandle
(
newService
);
ret_val
=
true
;
}
CloseServiceHandle
(
scm
);
return
ret_val
;
}
BOOL
WindowsService
::
Init
()
{
assert
(
serviceName
!=
NULL
);
if
(
inited
)
return
true
;
SERVICE_TABLE_ENTRY
stb
[]
=
{
{
(
LPSTR
)
serviceName
,
(
LPSERVICE_MAIN_FUNCTION
)
ServiceMain
},
{
NULL
,
NULL
}
};
inited
=
true
;
return
StartServiceCtrlDispatcher
(
stb
);
//register with the Service Manager
}
BOOL
WindowsService
::
Remove
()
{
bool
ret_val
=
false
;
if
(
!
IsInstalled
())
return
true
;
// open a connection to the SCM
SC_HANDLE
scm
=
OpenSCManager
(
0
,
0
,
SC_MANAGER_CREATE_SERVICE
);
if
(
!
scm
)
return
false
;
SC_HANDLE
service
=
OpenService
(
scm
,
serviceName
,
DELETE
);
if
(
service
)
{
if
(
DeleteService
(
service
))
ret_val
=
true
;
DWORD
dw
=
::
GetLastError
();
CloseServiceHandle
(
service
);
}
CloseServiceHandle
(
scm
);
return
ret_val
;
}
BOOL
WindowsService
::
IsInstalled
()
{
BOOL
ret_val
=
FALSE
;
SC_HANDLE
scm
=
::
OpenSCManager
(
NULL
,
NULL
,
SC_MANAGER_CONNECT
);
SC_HANDLE
serv_handle
=
::
OpenService
(
scm
,
serviceName
,
SERVICE_QUERY_STATUS
);
ret_val
=
serv_handle
!=
NULL
;
::
CloseServiceHandle
(
serv_handle
);
::
CloseServiceHandle
(
scm
);
return
ret_val
;
}
void
WindowsService
::
SetAcceptedControls
(
DWORD
acceptedControls
)
{
dwAcceptedControls
=
acceptedControls
;
}
BOOL
WindowsService
::
ReportStatus
(
DWORD
currentState
,
DWORD
waitHint
,
DWORD
dwError
)
{
if
(
debugging
)
return
TRUE
;
if
(
currentState
==
SERVICE_START_PENDING
)
status
.
dwControlsAccepted
=
0
;
else
status
.
dwControlsAccepted
=
dwAcceptedControls
;
status
.
dwCurrentState
=
currentState
;
status
.
dwWin32ExitCode
=
dwError
!=
0
?
ERROR_SERVICE_SPECIFIC_ERROR
:
NO_ERROR
;
status
.
dwWaitHint
=
waitHint
;
status
.
dwServiceSpecificExitCode
=
dwError
;
if
(
currentState
==
SERVICE_RUNNING
||
currentState
==
SERVICE_STOPPED
)
{
status
.
dwCheckPoint
=
0
;
statusCheckpoint
=
0
;
}
else
status
.
dwCheckPoint
=
++
statusCheckpoint
;
// Report the status of the service to the service control manager.
BOOL
result
=
SetServiceStatus
(
statusHandle
,
&
status
);
if
(
!
result
)
Log
(
"ReportStatus failed"
);
return
result
;
}
void
WindowsService
::
RegisterAndRun
(
DWORD
argc
,
LPTSTR
*
argv
)
{
statusHandle
=
::
RegisterServiceCtrlHandler
(
serviceName
,
ControlHandler
);
if
(
statusHandle
&&
ReportStatus
(
SERVICE_START_PENDING
))
Run
();
ReportStatus
(
SERVICE_STOPPED
);
}
void
WindowsService
::
HandleControlCode
(
DWORD
opcode
)
{
// Handle the requested control code.
switch
(
opcode
)
{
case
SERVICE_CONTROL_STOP
:
// Stop the service.
status
.
dwCurrentState
=
SERVICE_STOP_PENDING
;
Stop
();
break
;
case
SERVICE_CONTROL_PAUSE
:
status
.
dwCurrentState
=
SERVICE_PAUSE_PENDING
;
Pause
();
break
;
case
SERVICE_CONTROL_CONTINUE
:
status
.
dwCurrentState
=
SERVICE_CONTINUE_PENDING
;
Continue
();
break
;
case
SERVICE_CONTROL_SHUTDOWN
:
Shutdown
();
break
;
case
SERVICE_CONTROL_INTERROGATE
:
ReportStatus
(
status
.
dwCurrentState
);
break
;
default:
// invalid control code
break
;
}
}
void
WINAPI
WindowsService
::
ServiceMain
(
DWORD
argc
,
LPTSTR
*
argv
)
{
assert
(
gService
!=
NULL
);
// register our service control handler:
gService
->
RegisterAndRun
(
argc
,
argv
);
}
void
WINAPI
WindowsService
::
ControlHandler
(
DWORD
opcode
)
{
assert
(
gService
!=
NULL
);
return
gService
->
HandleControlCode
(
opcode
);
}
server-tools/instance-manager/WindowsService.h
0 → 100755
View file @
7782bca1
#pragma once
class
WindowsService
{
protected:
bool
inited
;
const
char
*
serviceName
;
const
char
*
displayName
;
const
char
*
username
;
const
char
*
password
;
SERVICE_STATUS_HANDLE
statusHandle
;
DWORD
statusCheckpoint
;
SERVICE_STATUS
status
;
DWORD
dwAcceptedControls
;
bool
debugging
;
public:
WindowsService
(
void
);
~
WindowsService
(
void
);
BOOL
Install
();
BOOL
Remove
();
BOOL
Init
();
BOOL
IsInstalled
();
void
SetAcceptedControls
(
DWORD
acceptedControls
);
void
Debug
(
bool
debugFlag
)
{
debugging
=
debugFlag
;
}
public:
static
void
WINAPI
ServiceMain
(
DWORD
argc
,
LPTSTR
*
argv
);
static
void
WINAPI
ControlHandler
(
DWORD
CtrlType
);
protected:
virtual
void
Run
()
=
0
;
virtual
void
Stop
()
{}
virtual
void
Shutdown
()
{}
virtual
void
Pause
()
{}
virtual
void
Continue
()
{}
virtual
void
Log
(
const
char
*
msg
)
{}
BOOL
ReportStatus
(
DWORD
currentStatus
,
DWORD
waitHint
=
3000
,
DWORD
dwError
=
0
);
void
HandleControlCode
(
DWORD
opcode
);
void
RegisterAndRun
(
DWORD
argc
,
LPTSTR
*
argv
);
};
server-tools/instance-manager/commands.cc
View file @
7782bca1
...
...
@@ -470,7 +470,7 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id)
size_t
buff_size
;
int
read_len
;
/* calculate buffer size */
struct
stat
file_stat
;
MY_STAT
file_stat
;
/* my_fstat doesn't use the flag parameter */
if
(
my_fstat
(
fd
,
&
file_stat
,
MYF
(
0
)))
...
...
@@ -482,7 +482,7 @@ int Show_instance_log::execute(struct st_net *net, ulong connection_id)
read_len
=
my_seek
(
fd
,
file_stat
.
st_size
-
size
,
MY_SEEK_SET
,
MYF
(
0
));
char
*
bf
=
(
char
*
)
malloc
(
sizeof
(
char
)
*
buff_size
);
if
((
read_len
=
my_read
(
fd
,
bf
,
buff_size
,
MYF
(
0
)))
<
0
)
if
((
read_len
=
my_read
(
fd
,
(
byte
*
)
bf
,
buff_size
,
MYF
(
0
)))
<
0
)
return
ER_READ_FILE
;
store_to_protocol_packet
(
&
send_buff
,
(
char
*
)
bf
,
&
position
,
read_len
);
close
(
fd
);
...
...
@@ -605,7 +605,7 @@ int Show_instance_log_files::execute(struct st_net *net, ulong connection_id)
store_to_protocol_packet
(
&
send_buff
,
""
,
&
position
);
store_to_protocol_packet
(
&
send_buff
,
(
char
*
)
"0"
,
&
position
);
}
else
if
(
S_ISREG
(
file_stat
.
st_mode
))
else
if
(
MY_
S_ISREG
(
file_stat
.
st_mode
))
{
store_to_protocol_packet
(
&
send_buff
,
(
char
*
)
log_files
->
value
,
...
...
@@ -693,7 +693,6 @@ int Set_option::correct_file(int skip)
error
=
modify_defaults_file
(
Options
::
config_file
,
option
,
option_value
,
instance_name
,
skip
);
switch
(
error
)
{
case
0
:
...
...
server-tools/instance-manager/guardian.cc
View file @
7782bca1
...
...
@@ -25,6 +25,7 @@
#include "instance.h"
#include "mysql_manager_error.h"
#include "log.h"
#include "port.h"
#include <string.h>
#include <sys/types.h>
...
...
@@ -32,7 +33,6 @@
C_MODE_START
pthread_handler_decl
(
guardian
,
arg
)
...
...
@@ -426,11 +426,21 @@ int Guardian_thread::stop_instances(bool stop_instances_arg)
int
Guardian_thread
::
lock
()
{
#ifdef __WIN__
pthread_mutex_lock
(
&
LOCK_guardian
);
return
0
;
#else
return
pthread_mutex_lock
(
&
LOCK_guardian
);
#endif
}
int
Guardian_thread
::
unlock
()
{
#ifdef __WIN__
pthread_mutex_unlock
(
&
LOCK_guardian
);
return
0
;
#else
return
pthread_mutex_unlock
(
&
LOCK_guardian
);
#endif
}
server-tools/instance-manager/instance.cc
View file @
7782bca1
...
...
@@ -18,14 +18,19 @@
#pragma implementation
#endif
#ifdef __WIN__
#include <process.h>
#endif
#include "instance.h"
#include "mysql_manager_error.h"
#include "log.h"
#include "instance_map.h"
#include "priv.h"
#include "port.h"
#ifndef __WIN__
#include <sys/wait.h>
#endif
#include <my_sys.h>
#include <signal.h>
#include <m_string.h>
...
...
@@ -50,6 +55,16 @@ pthread_handler_decl(proxy, arg)
C_MODE_END
void
Instance
::
remove_pid
()
{
int
pid
;
if
((
pid
=
options
.
get_pid
())
!=
0
)
/* check the pidfile */
if
(
options
.
unlink_pidfile
())
/* remove stalled pidfile */
log_error
(
"cannot remove pidfile for instance %i, this might be \
since IM lacks permmissions or hasn't found the pidifle"
,
options
.
instance_name
);
}
/*
The method starts an instance.
...
...
@@ -65,8 +80,6 @@ C_MODE_END
int
Instance
::
start
()
{
pid_t
pid
;
/* clear crash flag */
pthread_mutex_lock
(
&
LOCK_instance
);
crashed
=
0
;
...
...
@@ -75,11 +88,7 @@ int Instance::start()
if
(
!
is_running
())
{
if
((
pid
=
options
.
get_pid
())
!=
0
)
/* check the pidfile */
if
(
options
.
unlink_pidfile
())
/* remove stalled pidfile */
log_error
(
"cannot remove pidfile for instance %i, this might be \
since IM lacks permmissions or hasn't found the pidifle"
,
options
.
instance_name
);
remove_pid
();
/*
No need to monitor this thread in the Thread_registry, as all
...
...
@@ -107,20 +116,21 @@ int Instance::start()
return
ER_INSTANCE_ALREADY_STARTED
;
}
void
Instance
::
fork_and_monitor
()
#ifndef __WIN__
int
Instance
::
launch_and_wait
()
{
pid_t
pid
;
log_info
(
"starting instance %s"
,
options
.
instance_name
);
switch
(
pid
=
fork
())
{
case
0
:
execv
(
options
.
mysqld_path
,
options
.
argv
);
/* exec never returns */
exit
(
1
);
case
-
1
:
log_info
(
"cannot fork() to start instance %s"
,
options
.
instance_name
);
return
;
default:
pid_t
pid
=
fork
();
switch
(
pid
)
{
case
0
:
execv
(
options
.
mysqld_path
,
options
.
argv
);
/* exec never returns */
exit
(
1
);
case
-
1
:
log_info
(
"cannot fork() to start instance %s"
,
options
.
instance_name
);
return
-
1
;
default:
/*
Here we wait for the child created. This process differs for systems
running LinuxThreads and POSIX Threads compliant systems. This is because
...
...
@@ -141,22 +151,89 @@ void Instance::fork_and_monitor()
wait
(
NULL
);
/* LinuxThreads were detected */
else
waitpid
(
pid
,
NULL
,
0
);
/* set instance state to crashed */
pthread_mutex_lock
(
&
LOCK_instance
);
crashed
=
1
;
pthread_mutex_unlock
(
&
LOCK_instance
);
/*
Wake connection threads waiting for an instance to stop. This
is needed if a user issued command to stop an instance via
mysql connection. This is not the case if Guardian stop the thread.
*/
pthread_cond_signal
(
&
COND_instance_stopped
);
/* wake guardian */
pthread_cond_signal
(
&
instance_map
->
guardian
->
COND_guardian
);
/* thread exits */
return
;
}
return
0
;
}
#else
int
Instance
::
launch_and_wait
()
{
STARTUPINFO
si
;
PROCESS_INFORMATION
pi
;
ZeroMemory
(
&
si
,
sizeof
(
si
));
si
.
cb
=
sizeof
(
si
);
ZeroMemory
(
&
pi
,
sizeof
(
pi
));
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
++
)
{
strcat
(
cmdline
,
" "
);
strcat
(
cmdline
,
options
.
argv
[
i
]);
}
}
// Start the child process.
BOOL
result
=
CreateProcess
(
options
.
mysqld_path
,
// file to execute
cmdline
,
// Command line.
NULL
,
// Process handle not inheritable.
NULL
,
// Thread handle not inheritable.
FALSE
,
// Set handle inheritance to FALSE.
0
,
// No creation flags.
NULL
,
// Use parent's environment block.
NULL
,
// Use parent's starting directory.
&
si
,
// Pointer to STARTUPINFO structure.
&
pi
);
// Pointer to PROCESS_INFORMATION structure.
delete
cmdline
;
if
(
!
result
)
return
-
1
;
// Wait until child process exits.
WaitForSingleObject
(
pi
.
hProcess
,
INFINITE
);
DWORD
exitcode
;
::
GetExitCodeProcess
(
pi
.
hProcess
,
&
exitcode
);
// Close process and thread handles.
CloseHandle
(
pi
.
hProcess
);
CloseHandle
(
pi
.
hThread
);
return
exitcode
;
}
#endif
void
Instance
::
fork_and_monitor
()
{
log_info
(
"starting instance %s"
,
options
.
instance_name
);
int
result
=
launch_and_wait
();
if
(
result
==
-
1
)
return
;
/* set instance state to crashed */
pthread_mutex_lock
(
&
LOCK_instance
);
crashed
=
1
;
pthread_mutex_unlock
(
&
LOCK_instance
);
/*
Wake connection threads waiting for an instance to stop. This
is needed if a user issued command to stop an instance via
mysql connection. This is not the case if Guardian stop the thread.
*/
pthread_cond_signal
(
&
COND_instance_stopped
);
/* wake guardian */
pthread_cond_signal
(
&
instance_map
->
guardian
->
COND_guardian
);
/* thread exits */
return
;
/* we should never end up here */
DBUG_ASSERT
(
0
);
}
...
...
@@ -253,7 +330,6 @@ bool Instance::is_running()
int
Instance
::
stop
()
{
pid_t
pid
;
struct
timespec
timeout
;
uint
waitchild
=
(
uint
)
DEFAULT_SHUTDOWN_DELAY
;
...
...
@@ -290,6 +366,68 @@ int Instance::stop()
return
ER_STOP_INSTANCE
;
}
#ifdef __WIN__
BOOL
SafeTerminateProcess
(
HANDLE
hProcess
,
UINT
uExitCode
)
{
DWORD
dwTID
,
dwCode
,
dwErr
=
0
;
HANDLE
hProcessDup
=
INVALID_HANDLE_VALUE
;
HANDLE
hRT
=
NULL
;
HINSTANCE
hKernel
=
GetModuleHandle
(
"Kernel32"
);
BOOL
bSuccess
=
FALSE
;
BOOL
bDup
=
DuplicateHandle
(
GetCurrentProcess
(),
hProcess
,
GetCurrentProcess
(),
&
hProcessDup
,
PROCESS_ALL_ACCESS
,
FALSE
,
0
);
// Detect the special case where the process is
// already dead...
if
(
GetExitCodeProcess
((
bDup
)
?
hProcessDup
:
hProcess
,
&
dwCode
)
&&
(
dwCode
==
STILL_ACTIVE
))
{
FARPROC
pfnExitProc
;
pfnExitProc
=
GetProcAddress
(
hKernel
,
"ExitProcess"
);
hRT
=
CreateRemoteThread
((
bDup
)
?
hProcessDup
:
hProcess
,
NULL
,
0
,
(
LPTHREAD_START_ROUTINE
)
pfnExitProc
,
(
PVOID
)
uExitCode
,
0
,
&
dwTID
);
if
(
hRT
==
NULL
)
dwErr
=
GetLastError
();
}
else
dwErr
=
ERROR_PROCESS_ABORTED
;
if
(
hRT
)
{
// Must wait process to terminate to
// guarantee that it has exited...
WaitForSingleObject
((
bDup
)
?
hProcessDup
:
hProcess
,
INFINITE
);
CloseHandle
(
hRT
);
bSuccess
=
TRUE
;
}
if
(
bDup
)
CloseHandle
(
hProcessDup
);
if
(
!
bSuccess
)
SetLastError
(
dwErr
);
return
bSuccess
;
}
int
kill
(
pid_t
pid
,
int
signum
)
{
HANDLE
processhandle
=
::
OpenProcess
(
PROCESS_ALL_ACCESS
,
FALSE
,
pid
);
if
(
signum
==
SIGTERM
)
::
SafeTerminateProcess
(
processhandle
,
0
);
else
::
TerminateProcess
(
processhandle
,
-
1
);
return
0
;
}
#endif
void
Instance
::
kill_instance
(
int
signum
)
{
...
...
server-tools/instance-manager/instance.h
View file @
7782bca1
...
...
@@ -61,6 +61,9 @@ class Instance
*/
pthread_cond_t
COND_instance_stopped
;
Instance_map
*
instance_map
;
void
remove_pid
();
int
launch_and_wait
();
};
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_INSTANCE_H */
server-tools/instance-manager/instance_map.cc
View file @
7782bca1
...
...
@@ -139,13 +139,23 @@ Instance_map::~Instance_map()
int
Instance_map
::
lock
()
{
#ifdef __WIN__
pthread_mutex_lock
(
&
LOCK_instance_map
);
return
0
;
#else
return
pthread_mutex_lock
(
&
LOCK_instance_map
);
#endif
}
int
Instance_map
::
unlock
()
{
#ifdef __WIN__
pthread_mutex_unlock
(
&
LOCK_instance_map
);
return
0
;
#else
return
pthread_mutex_unlock
(
&
LOCK_instance_map
);
#endif
}
...
...
server-tools/instance-manager/instance_options.h
View file @
7782bca1
...
...
@@ -19,6 +19,7 @@
#include <my_global.h>
#include <my_sys.h>
#include "parse.h"
#include "port.h"
#ifdef __GNUC__
#pragma interface
...
...
server-tools/instance-manager/listener.cc
View file @
7782bca1
...
...
@@ -19,11 +19,13 @@
#endif
#include "listener.h"
#include "priv.h"
#include <m_string.h>
#include <mysql.h>
#include <violite.h>
#ifndef __WIN__
#include <sys/un.h>
#endif
#include <sys/stat.h>
#include "thread_registry.h"
...
...
@@ -31,7 +33,7 @@
#include "instance_map.h"
#include "log.h"
#include "mysql_connection.h"
#include "p
riv
.h"
#include "p
ort
.h"
/*
...
...
@@ -47,16 +49,24 @@ class Listener_thread: public Listener_thread_args
private:
ulong
total_connection_count
;
Thread_info
thread_info
;
int
sockets
[
2
];
int
num_sockets
;
fd_set
read_fds
;
private:
void
handle_new_mysql_connection
(
Vio
*
vio
);
int
create_tcp_socket
();
int
create_unix_socket
(
struct
sockaddr_un
&
unix_socket_address
);
};
const
int
LISTEN_BACK_LOG_SIZE
=
5
;
// standard backlog size
Listener_thread
::
Listener_thread
(
const
Listener_thread_args
&
args
)
:
Listener_thread_args
(
args
.
thread_registry
,
args
.
options
,
args
.
user_map
,
args
.
instance_map
)
,
total_connection_count
(
0
)
,
thread_info
(
pthread_self
())
,
num_sockets
(
0
)
{
}
...
...
@@ -78,30 +88,138 @@ Listener_thread::~Listener_thread()
void
Listener_thread
::
run
()
{
enum
{
LISTEN_BACK_LOG_SIZE
=
5
};
// standard backlog size
int
flags
;
int
arg
=
1
;
/* value to be set by setsockopt */
int
unix_socket
;
uint
im_port
;
/* we use this var to check whether we are running on LinuxThreads */
pid_t
thread_pid
;
int
n
;
thread_pid
=
getpid
();
#ifndef __WIN__
struct
sockaddr_un
unix_socket_address
;
/* set global variable */
linuxthreads
=
(
thread_pid
!=
manager_pid
);
#endif
thread_registry
.
register_thread
(
&
thread_info
);
my_thread_init
();
FD_ZERO
(
&
read_fds
);
/* I. prepare 'listen' sockets */
if
(
create_tcp_socket
())
goto
err
;
#ifndef __WIN__
if
(
create_unix_socket
(
unix_socket_address
))
goto
err
;
#endif
/* II. Listen sockets and spawn childs */
for
(
int
i
=
0
;
i
<
num_sockets
;
i
++
)
n
=
max
(
n
,
sockets
[
i
]);
n
++
;
while
(
!
thread_registry
.
is_shutdown
())
{
fd_set
read_fds_arg
=
read_fds
;
/*
When using valgrind 2.0 this syscall doesn't get kicked off by a
signal during shutdown. This results in failing assert
(Thread_registry::~Thread_registry). Valgrind 2.2 works fine.
*/
int
rc
=
select
(
n
,
&
read_fds_arg
,
0
,
0
,
0
);
if
(
rc
==
-
1
&&
errno
!=
EINTR
)
{
log_error
(
"Listener_thread::run(): select() failed, %s"
,
strerror
(
errno
));
continue
;
}
for
(
int
socket_index
=
0
;
socket_index
<
num_sockets
;
socket_index
++
)
{
/* Assuming that rc > 0 as we asked to wait forever */
if
(
FD_ISSET
(
sockets
[
socket_index
],
&
read_fds_arg
))
{
int
client_fd
=
accept
(
sockets
[
socket_index
],
0
,
0
);
/* accept may return -1 (failure or spurious wakeup) */
if
(
client_fd
>=
0
)
// connection established
{
Vio
*
vio
=
vio_new
(
client_fd
,
socket_index
==
0
?
VIO_TYPE_SOCKET
:
VIO_TYPE_TCPIP
,
socket_index
==
0
?
1
:
0
);
if
(
vio
!=
0
)
handle_new_mysql_connection
(
vio
);
else
{
shutdown
(
client_fd
,
SHUT_RDWR
);
close
(
client_fd
);
}
}
}
}
}
/* III. Release all resources and exit */
log_info
(
"Listener_thread::run(): shutdown requested, exiting..."
);
for
(
int
i
=
0
;
i
<
num_sockets
;
i
++
)
close
(
sockets
[
i
]);
#ifndef __WIN__
unlink
(
unix_socket_address
.
sun_path
);
#endif
thread_registry
.
unregister_thread
(
&
thread_info
);
my_thread_end
();
return
;
err:
// we have to close the ip sockets in case of error
for
(
int
i
=
0
;
i
<
num_sockets
;
i
++
)
close
(
sockets
[
i
]);
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
request_shutdown
();
my_thread_end
();
return
;
}
void
set_non_blocking
(
int
socket
)
{
#ifndef __WIN__
int
flags
=
fcntl
(
socket
,
F_GETFL
,
0
);
fcntl
(
socket
,
F_SETFL
,
flags
|
O_NONBLOCK
);
#else
u_long
arg
=
1
;
ioctlsocket
(
socket
,
FIONBIO
,
&
arg
);
#endif
}
void
set_no_inherit
(
int
socket
)
{
#ifndef __WIN__
int
flags
=
fcntl
(
socket
,
F_GETFD
,
0
);
fcntl
(
socket
,
F_SETFD
,
flags
|
FD_CLOEXEC
);
#else
#endif
}
int
Listener_thread
::
create_tcp_socket
()
{
/* value to be set by setsockopt */
int
arg
=
1
;
int
ip_socket
=
socket
(
AF_INET
,
SOCK_STREAM
,
0
);
if
(
ip_socket
==
INVALID_SOCKET
)
{
log_error
(
"Listener_thead::run(): socket(AF_INET) failed, %s"
,
strerror
(
errno
));
goto
err
;
return
-
1
;
}
struct
sockaddr_in
ip_socket_address
;
...
...
@@ -115,7 +233,7 @@ void Listener_thread::run()
}
else
im_bind_addr
=
htonl
(
INADDR_ANY
);
im_port
=
options
.
port_number
;
uint
im_port
=
options
.
port_number
;
ip_socket_address
.
sin_family
=
AF_INET
;
ip_socket_address
.
sin_addr
.
s_addr
=
im_bind_addr
;
...
...
@@ -130,154 +248,86 @@ void Listener_thread::run()
{
log_error
(
"Listener_thread::run(): bind(ip socket) failed, '%s'"
,
strerror
(
errno
));
goto
err
;
close
(
ip_socket
);
return
-
1
;
}
if
(
listen
(
ip_socket
,
LISTEN_BACK_LOG_SIZE
))
{
log_error
(
"Listener_thread::run(): listen(ip socket) failed, %s"
,
strerror
(
errno
));
goto
err
;
close
(
ip_socket
);
return
-
1
;
}
/* set the socket nonblocking */
flags
=
fcntl
(
ip_socket
,
F_GETFL
,
0
);
fcntl
(
ip_socket
,
F_SETFL
,
flags
|
O_NONBLOCK
);
/* make sure that instances won't be listening our sockets */
flags
=
fcntl
(
ip_socket
,
F_GETFD
,
0
);
fcntl
(
ip_socket
,
F_SETFD
,
flags
|
FD_CLOEXEC
);
/* set the socket nonblocking */
set_non_blocking
(
ip_socket
);
/* make sure that instances won't be listening our sockets */
set_no_inherit
(
ip_socket
);
FD_SET
(
ip_socket
,
&
read_fds
);
sockets
[
num_sockets
++
]
=
ip_socket
;
log_info
(
"accepting connections on ip socket"
);
return
0
;
}
/*--------------------------------------------------------------*/
unix_socket
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
);
#ifndef __WIN__
int
Listener_thread
::
create_unix_socket
(
struct
sockaddr_un
&
unix_socket_address
)
{
int
unix_socket
=
socket
(
AF_UNIX
,
SOCK_STREAM
,
0
);
if
(
unix_socket
==
INVALID_SOCKET
)
{
log_error
(
"Listener_thead::run(): socket(AF_UNIX) failed, %s"
,
strerror
(
errno
));
goto
err
;
return
-
1
;
}
struct
sockaddr_un
unix_socket_address
;
bzero
(
&
unix_socket_address
,
sizeof
(
unix_socket_address
));
unix_socket_address
.
sun_family
=
AF_UNIX
;
strmake
(
unix_socket_address
.
sun_path
,
options
.
socket_file_name
,
sizeof
(
unix_socket_address
.
sun_path
));
unlink
(
unix_socket_address
.
sun_path
);
/
* in case we have stale socket file */
unlink
(
unix_socket_address
.
sun_path
);
/
/ in case we have stale socket file
/*
POSIX specifies default permissions for a pathname created by bind
to be 0777. We need everybody to have access to the socket.
*/
mode_t
old_mask
=
umask
(
0
);
if
(
bind
(
unix_socket
,
(
struct
sockaddr
*
)
&
unix_socket_address
,
sizeof
(
unix_socket_address
)))
{
/*
POSIX specifies default permissions for a pathname created by bind
to be 0777. We need everybody to have access to the socket.
*/
mode_t
old_mask
=
umask
(
0
);
if
(
bind
(
unix_socket
,
(
struct
sockaddr
*
)
&
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'"
,
unix_socket_address
.
sun_path
,
strerror
(
errno
));
goto
err
;
}
umask
(
old_mask
);
if
(
listen
(
unix_socket
,
LISTEN_BACK_LOG_SIZE
))
{
log_error
(
"Listener_thread::run(): listen(unix socket) failed, %s"
,
strerror
(
errno
));
goto
err
;
}
/* set the socket nonblocking */
flags
=
fcntl
(
unix_socket
,
F_GETFL
,
0
);
fcntl
(
unix_socket
,
F_SETFL
,
flags
|
O_NONBLOCK
);
/* make sure that instances won't be listening our sockets */
flags
=
fcntl
(
unix_socket
,
F_GETFD
,
0
);
fcntl
(
unix_socket
,
F_SETFD
,
flags
|
FD_CLOEXEC
);
close
(
unix_socket
);
return
-
1
;
}
log_info
(
"accepting connections on unix socket %s"
,
unix_socket_address
.
sun_path
);
/* II. Listen sockets and spawn childs */
umask
(
old_mask
);
if
(
listen
(
unix_socket
,
LISTEN_BACK_LOG_SIZE
))
{
int
n
=
max
(
unix_socket
,
ip_socket
)
+
1
;
fd_set
read_fds
;
FD_ZERO
(
&
read_fds
);
FD_SET
(
unix_socket
,
&
read_fds
);
FD_SET
(
ip_socket
,
&
read_fds
);
while
(
thread_registry
.
is_shutdown
()
==
false
)
{
fd_set
read_fds_arg
=
read_fds
;
/*
When using valgrind 2.0 this syscall doesn't get kicked off by a
signal during shutdown. This results in failing assert
(Thread_registry::~Thread_registry). Valgrind 2.2 works fine.
*/
int
rc
=
select
(
n
,
&
read_fds_arg
,
0
,
0
,
0
);
if
(
rc
==
-
1
&&
errno
!=
EINTR
)
log_error
(
"Listener_thread::run(): select() failed, %s"
,
strerror
(
errno
));
else
{
/* Assuming that rc > 0 as we asked to wait forever */
if
(
FD_ISSET
(
unix_socket
,
&
read_fds_arg
))
{
int
client_fd
=
accept
(
unix_socket
,
0
,
0
);
/* accept may return -1 (failure or spurious wakeup) */
if
(
client_fd
>=
0
)
// connection established
{
if
(
Vio
*
vio
=
vio_new
(
client_fd
,
VIO_TYPE_SOCKET
,
1
))
handle_new_mysql_connection
(
vio
);
else
{
shutdown
(
client_fd
,
SHUT_RDWR
);
close
(
client_fd
);
}
}
}
else
if
(
FD_ISSET
(
ip_socket
,
&
read_fds_arg
))
{
int
client_fd
=
accept
(
ip_socket
,
0
,
0
);
/* accept may return -1 (failure or spurious wakeup) */
if
(
client_fd
>=
0
)
// connection established
{
if
(
Vio
*
vio
=
vio_new
(
client_fd
,
VIO_TYPE_TCPIP
,
0
))
handle_new_mysql_connection
(
vio
);
else
{
shutdown
(
client_fd
,
SHUT_RDWR
);
close
(
client_fd
);
}
}
}
}
}
log_error
(
"Listener_thread::run(): listen(unix socket) failed, %s"
,
strerror
(
errno
));
close
(
unix_socket
);
return
-
1
;
}
/* III. Release all resources and exit */
log_info
(
"Listener_thread::run(): shutdown requested, exiting..."
);
close
(
unix_socket
);
close
(
ip_socket
);
unlink
(
unix_socket_address
.
sun_path
);
/* set the socket nonblocking */
set_non_blocking
(
unix_socket
);
thread_registry
.
unregister_thread
(
&
thread_info
);
my_thread_end
();
return
;
/* make sure that instances won't be listening our sockets */
set_no_inherit
(
unix_socket
);
err:
thread_registry
.
unregister_thread
(
&
thread_info
);
thread_registry
.
request_shutdown
();
my_thread_end
();
return
;
log_info
(
"accepting connections on unix socket %s"
,
unix_socket_address
.
sun_path
);
sockets
[
num_sockets
++
]
=
unix_socket
;
FD_SET
(
unix_socket
,
&
read_fds
);
return
0
;
}
#endif
/*
...
...
server-tools/instance-manager/listener.h
View file @
7782bca1
...
...
@@ -31,7 +31,7 @@ pthread_handler_decl(listener, arg);
C_MODE_END
class
Thread_registry
;
class
Options
;
struct
Options
;
class
User_map
;
class
Instance_map
;
...
...
server-tools/instance-manager/log.cc
View file @
7782bca1
...
...
@@ -17,7 +17,7 @@
#include <my_global.h>
#include "log.h"
#include "port.h"
#include <stdarg.h>
#include <m_string.h>
#include <my_sys.h>
...
...
server-tools/instance-manager/manager.cc
View file @
7782bca1
...
...
@@ -30,7 +30,9 @@
#include <m_string.h>
#include <signal.h>
#include <thr_alarm.h>
#ifndef __WIN__
#include <sys/wait.h>
#endif
static
int
create_pid_file
(
const
char
*
pid_file_name
)
...
...
@@ -50,6 +52,61 @@ static int create_pid_file(const char *pid_file_name)
return
0
;
}
#ifndef __WIN__
void
set_signals
(
sigset_t
*
mask
)
{
/* block signals */
sigemptyset
(
mask
);
sigaddset
(
mask
,
SIGINT
);
sigaddset
(
mask
,
SIGTERM
);
sigaddset
(
mask
,
SIGPIPE
);
sigaddset
(
mask
,
SIGHUP
);
signal
(
SIGPIPE
,
SIG_IGN
);
/*
We want this signal to be blocked in all theads but the signal
one. It is needed for the thr_alarm subsystem to work.
*/
sigaddset
(
mask
,
THR_SERVER_ALARM
);
/* all new threads will inherite this signal mask */
pthread_sigmask
(
SIG_BLOCK
,
mask
,
NULL
);
/*
In our case the signal thread also implements functions of alarm thread.
Here we init alarm thread functionality. We suppose that we won't have
more then 10 alarms at the same time.
*/
init_thr_alarm
(
10
);
}
#else
bool
have_signal
;
void
onsignal
(
int
signo
)
{
have_signal
=
true
;
}
void
set_signals
(
sigset_t
*
set
)
{
signal
(
SIGINT
,
onsignal
);
signal
(
SIGTERM
,
onsignal
);
have_signal
=
false
;
}
int
my_sigwait
(
const
sigset_t
*
set
,
int
*
sig
)
{
// MSG msg;
while
(
!
have_signal
)
{
Sleep
(
100
);
}
return
0
;
}
#endif
/*
manager - entry point to the main instance manager process: start
...
...
@@ -98,21 +155,8 @@ void manager(const Options &options)
if
(
create_pid_file
(
options
.
pid_file_name
))
return
;
/* block signals */
sigset_t
mask
;
sigemptyset
(
&
mask
);
sigaddset
(
&
mask
,
SIGINT
);
sigaddset
(
&
mask
,
SIGTERM
);
sigaddset
(
&
mask
,
SIGPIPE
);
sigaddset
(
&
mask
,
SIGHUP
);
/*
We want this signal to be blocked in all theads but the signal
one. It is needed for the thr_alarm subsystem to work.
*/
sigaddset
(
&
mask
,
THR_SERVER_ALARM
);
/* all new threads will inherite this signal mask */
pthread_sigmask
(
SIG_BLOCK
,
&
mask
,
NULL
);
set_signals
(
&
mask
);
/* create the listener */
{
...
...
@@ -166,12 +210,7 @@ void manager(const Options &options)
bool
shutdown_complete
;
shutdown_complete
=
FALSE
;
/*
In our case the signal thread also implements functions of alarm thread.
Here we init alarm thread functionality. We suppose that we won't have
more then 10 alarms at the same time.
*/
init_thr_alarm
(
10
);
/* init list of guarded instances */
guardian_thread
.
lock
();
...
...
@@ -185,8 +224,6 @@ void manager(const Options &options)
*/
pthread_cond_signal
(
&
guardian_thread
.
COND_guardian
);
signal
(
SIGPIPE
,
SIG_IGN
);
while
(
!
shutdown_complete
)
{
int
status
=
0
;
...
...
@@ -197,11 +234,11 @@ void manager(const Options &options)
goto
err
;
}
switch
(
signo
)
{
case
THR_SERVER_ALARM
:
process_alarm
(
signo
);
break
;
default:
#ifndef __WIN__
if
(
THR_SERVER_ALARM
==
signo
)
process_alarm
(
signo
);
else
#endif
{
if
(
!
guardian_thread
.
is_stopped
())
{
...
...
@@ -215,16 +252,16 @@ void manager(const Options &options)
shutdown_complete
=
TRUE
;
}
}
break
;
}
}
err:
/* delete the pid file */
my_delete
(
options
.
pid_file_name
,
MYF
(
0
));
#ifndef __WIN__
/* free alarm structures */
end_thr_alarm
(
1
);
/* don't pthread_exit to kill all threads who did not shut down in time */
#endif
}
server-tools/instance-manager/manager.h
View file @
7782bca1
...
...
@@ -16,7 +16,7 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
class
Options
;
struct
Options
;
void
manager
(
const
Options
&
options
);
...
...
server-tools/instance-manager/mysqlmanager.cc
View file @
7782bca1
...
...
@@ -23,12 +23,16 @@
#include <my_sys.h>
#include <string.h>
#include <signal.h>
#ifndef __WIN__
#include <pwd.h>
#include <grp.h>
#include <sys/wait.h>
#endif
#include <sys/types.h>
#include <sys/stat.h>
#ifdef __WIN__
#include "windowsservice.h"
#endif
/*
Few notes about Instance Manager architecture:
...
...
@@ -55,10 +59,14 @@
*/
static
void
init_environment
(
char
*
progname
);
#ifndef __WIN__
static
void
daemonize
(
const
char
*
log_file_name
);
static
void
angel
(
const
Options
&
options
);
static
struct
passwd
*
check_user
(
const
char
*
user
);
static
int
set_user
(
const
char
*
user
,
struct
passwd
*
user_info
);
#else
int
HandleServiceOptions
(
Options
options
);
#endif
/*
...
...
@@ -78,6 +86,7 @@ int main(int argc, char *argv[])
if
(
options
.
load
(
argc
,
argv
))
goto
err
;
#ifndef __WIN__
if
((
user_info
=
check_user
(
options
.
user
)))
{
if
(
set_user
(
options
.
user
,
user_info
))
...
...
@@ -94,6 +103,12 @@ int main(int argc, char *argv[])
/* forks again, and returns only in child: parent becomes angel */
angel
(
options
);
}
#else
#ifdef NDEBUG
return
HandleServiceOptions
(
options
);
#endif
#endif
manager
(
options
);
options
.
cleanup
();
my_end
(
0
);
...
...
@@ -105,11 +120,11 @@ int main(int argc, char *argv[])
/******************* Auxilary functions implementation **********************/
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
/* Change to run as another user if started with --user */
static
struct
passwd
*
check_user
(
const
char
*
user
)
{
#if !defined(__WIN__) && !defined(OS2) && !defined(__NETWARE__)
struct
passwd
*
user_info
;
uid_t
user_id
=
geteuid
();
...
...
@@ -150,7 +165,6 @@ static struct passwd *check_user(const char *user)
err:
log_error
(
"Fatal error: Can't change to run as user '%s' ; Please check that the user exists!
\n
"
,
user
);
#endif
return
NULL
;
}
...
...
@@ -172,7 +186,7 @@ static int set_user(const char *user, struct passwd *user_info)
}
return
0
;
}
#endif
/*
...
...
@@ -188,6 +202,7 @@ static void init_environment(char *progname)
}
#ifndef __WIN__
/*
Become a UNIX service
SYNOPSYS
...
...
@@ -342,3 +357,4 @@ static void angel(const Options &options)
}
}
#endif
server-tools/instance-manager/mysqlmanager.vcproj
0 → 100755
View file @
7782bca1
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType=
"Visual C++"
Version=
"7.10"
Name=
"mysqlmanager"
ProjectGUID=
"{6D524B3E-210A-4FCD-8D41-FEC0D21E83AC}"
Keyword=
"Win32Proj"
>
<Platforms>
<Platform
Name=
"Win32"
/>
</Platforms>
<Configurations>
<Configuration
Name=
"Debug|Win32"
OutputDirectory=
"Debug"
IntermediateDirectory=
"Debug"
ConfigurationType=
"1"
CharacterSet=
"2"
>
<Tool
Name=
"VCCLCompilerTool"
Optimization=
"0"
AdditionalIncludeDirectories=
"..\include"
PreprocessorDefinitions=
"MYSQL_INSTANCE_MANAGER;MYSQL_SERVER;_DEBUG;SAFEMALLOC;SAFE_MUTEX;_WINDOWS;CONSOLE"
MinimalRebuild=
"TRUE"
ExceptionHandling=
"FALSE"
BasicRuntimeChecks=
"3"
RuntimeLibrary=
"1"
UsePrecompiledHeader=
"0"
WarningLevel=
"3"
Detect64BitPortabilityProblems=
"TRUE"
DebugInformationFormat=
"4"
/>
<Tool
Name=
"VCCustomBuildTool"
/>
<Tool
Name=
"VCLinkerTool"
AdditionalDependencies=
"wsock32.lib"
OutputFile=
"$(OutDir)/mysqlmanager.exe"
LinkIncremental=
"2"
GenerateDebugInformation=
"TRUE"
ProgramDatabaseFile=
"$(OutDir)/mysqlmanager.pdb"
SubSystem=
"1"
TargetMachine=
"1"
/>
<Tool
Name=
"VCMIDLTool"
/>
<Tool
Name=
"VCPostBuildEventTool"
/>
<Tool
Name=
"VCPreBuildEventTool"
/>
<Tool
Name=
"VCPreLinkEventTool"
/>
<Tool
Name=
"VCResourceCompilerTool"
/>
<Tool
Name=
"VCWebServiceProxyGeneratorTool"
/>
<Tool
Name=
"VCXMLDataGeneratorTool"
/>
<Tool
Name=
"VCWebDeploymentTool"
/>
<Tool
Name=
"VCManagedWrapperGeneratorTool"
/>
<Tool
Name=
"VCAuxiliaryManagedWrapperGeneratorTool"
/>
</Configuration>
<Configuration
Name=
"Release|Win32"
OutputDirectory=
"Release"
IntermediateDirectory=
"Release"
ConfigurationType=
"1"
CharacterSet=
"2"
>
<Tool
Name=
"VCCLCompilerTool"
AdditionalIncludeDirectories=
"..\include"
PreprocessorDefinitions=
"MYSQL_INSTANCE_MANAGER;MYSQL_SERVER;_WINDOWS;CONSOLE"
ExceptionHandling=
"FALSE"
RuntimeLibrary=
"0"
UsePrecompiledHeader=
"0"
WarningLevel=
"3"
Detect64BitPortabilityProblems=
"TRUE"
DebugInformationFormat=
"3"
/>
<Tool
Name=
"VCCustomBuildTool"
/>
<Tool
Name=
"VCLinkerTool"
AdditionalDependencies=
"wsock32.lib"
OutputFile=
"$(OutDir)/mysqlmanager.exe"
LinkIncremental=
"1"
GenerateDebugInformation=
"TRUE"
SubSystem=
"1"
OptimizeReferences=
"2"
EnableCOMDATFolding=
"2"
TargetMachine=
"1"
/>
<Tool
Name=
"VCMIDLTool"
/>
<Tool
Name=
"VCPostBuildEventTool"
/>
<Tool
Name=
"VCPreBuildEventTool"
/>
<Tool
Name=
"VCPreLinkEventTool"
/>
<Tool
Name=
"VCResourceCompilerTool"
/>
<Tool
Name=
"VCWebServiceProxyGeneratorTool"
/>
<Tool
Name=
"VCXMLDataGeneratorTool"
/>
<Tool
Name=
"VCWebDeploymentTool"
/>
<Tool
Name=
"VCManagedWrapperGeneratorTool"
/>
<Tool
Name=
"VCAuxiliaryManagedWrapperGeneratorTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name=
"Source Files"
Filter=
"cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
UniqueIdentifier=
"{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
>
<File
RelativePath=
".\buffer.cc"
>
</File>
<File
RelativePath=
"..\sql\client.c"
>
</File>
<File
RelativePath=
".\command.cc"
>
</File>
<File
RelativePath=
".\commands.cc"
>
</File>
<File
RelativePath=
".\factory.cc"
>
</File>
<File
RelativePath=
"..\libmysql\get_password.c"
>
</File>
<File
RelativePath=
".\guardian.cc"
>
</File>
<File
RelativePath=
".\IMService.cpp"
>
</File>
<File
RelativePath=
".\instance.cc"
>
</File>
<File
RelativePath=
".\instance_map.cc"
>
</File>
<File
RelativePath=
".\instance_options.cc"
>
</File>
<File
RelativePath=
".\listener.cc"
>
</File>
<File
RelativePath=
".\log.cc"
>
</File>
<File
RelativePath=
".\manager.cc"
>
</File>
<File
RelativePath=
".\messages.cc"
>
</File>
<File
RelativePath=
"..\sql\mini_client_errors.c"
>
</File>
<File
RelativePath=
".\mysql_connection.cc"
>
</File>
<File
RelativePath=
".\mysqlmanager.cc"
>
</File>
<File
RelativePath=
"..\sql\net_serv.cpp"
>
</File>
<File
RelativePath=
".\options.cc"
>
</File>
<File
RelativePath=
"..\sql\pack.c"
>
</File>
<File
RelativePath=
".\parse.cc"
>
</File>
<File
RelativePath=
".\parse_output.cc"
>
</File>
<File
RelativePath=
"..\sql\password.c"
>
</File>
<File
RelativePath=
".\priv.cc"
>
</File>
<File
RelativePath=
".\protocol.cc"
>
</File>
<File
RelativePath=
".\service_funcs.cpp"
>
</File>
<File
RelativePath=
"..\sql\sql_state.c"
>
</File>
<File
RelativePath=
".\thread_registry.cc"
>
</File>
<File
RelativePath=
".\user_map.cc"
>
</File>
<File
RelativePath=
".\WindowsService.cpp"
>
</File>
</Filter>
<Filter
Name=
"Header Files"
Filter=
"h;hpp;hxx;hm;inl;inc;xsd"
UniqueIdentifier=
"{93995380-89BD-4b04-88EB-625FBE52EBFB}"
>
<File
RelativePath=
".\buffer.h"
>
</File>
<File
RelativePath=
".\command.h"
>
</File>
<File
RelativePath=
".\commands.h"
>
</File>
<File
RelativePath=
".\factory.h"
>
</File>
<File
RelativePath=
".\guardian.h"
>
</File>
<File
RelativePath=
".\IMService.h"
>
</File>
<File
RelativePath=
".\instance.h"
>
</File>
<File
RelativePath=
".\instance_map.h"
>
</File>
<File
RelativePath=
".\instance_options.h"
>
</File>
<File
RelativePath=
".\listener.h"
>
</File>
<File
RelativePath=
".\log.h"
>
</File>
<File
RelativePath=
".\manager.h"
>
</File>
<File
RelativePath=
".\messages.h"
>
</File>
<File
RelativePath=
".\mysql_connection.h"
>
</File>
<File
RelativePath=
".\mysql_manager_error.h"
>
</File>
<File
RelativePath=
".\options.h"
>
</File>
<File
RelativePath=
".\parse.h"
>
</File>
<File
RelativePath=
".\parse_output.h"
>
</File>
<File
RelativePath=
".\port.h"
>
</File>
<File
RelativePath=
".\priv.h"
>
</File>
<File
RelativePath=
".\protocol.h"
>
</File>
<File
RelativePath=
".\thread_registry.h"
>
</File>
<File
RelativePath=
".\user_map.h"
>
</File>
<File
RelativePath=
".\WindowsService.h"
>
</File>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>
server-tools/instance-manager/options.cc
View file @
7782bca1
...
...
@@ -21,7 +21,7 @@
#include "options.h"
#include "priv.h"
#include "port.h"
#include <my_sys.h>
#include <my_getopt.h>
#include <m_string.h>
...
...
@@ -30,15 +30,25 @@
#define QUOTE2(x) #x
#define QUOTE(x) QUOTE2(x)
const
char
*
default_password_file_name
=
QUOTE
(
DEFAULT_PASSWORD_FILE_NAME
);
const
char
*
default_log_file_name
=
QUOTE
(
DEFAULT_LOG_FILE_NAME
);
char
default_config_file
[
FN_REFLEN
]
=
"/etc/my.cnf"
;
#ifndef __WIN__
char
Options
::
run_as_service
;
const
char
*
Options
::
log_file_name
=
QUOTE
(
DEFAULT_LOG_FILE_NAME
);
const
char
*
Options
::
user
=
0
;
/* No default value */
const
char
*
Options
::
config_file
=
NULL
;
#else
char
Options
::
install_as_service
;
char
Options
::
remove_service
;
const
char
*
Options
::
config_file
=
QUOTE
(
DEFAULT_CONFIG_FILE
);
#endif
const
char
*
Options
::
log_file_name
=
default_log_file_name
;
const
char
*
Options
::
pid_file_name
=
QUOTE
(
DEFAULT_PID_FILE_NAME
);
const
char
*
Options
::
socket_file_name
=
QUOTE
(
DEFAULT_SOCKET_FILE_NAME
);
const
char
*
Options
::
password_file_name
=
QUOTE
(
DEFAULT_PASSWORD_FILE_NAME
)
;
const
char
*
Options
::
password_file_name
=
default_password_file_name
;
const
char
*
Options
::
default_mysqld_path
=
QUOTE
(
DEFAULT_MYSQLD_PATH
);
const
char
*
Options
::
config_file
=
QUOTE
(
DEFAULT_CONFIG_FILE
);
const
char
*
Options
::
bind_address
=
0
;
/* No default value */
const
char
*
Options
::
user
=
0
;
/* No default value */
uint
Options
::
monitoring_interval
=
DEFAULT_MONITORING_INTERVAL
;
uint
Options
::
port_number
=
DEFAULT_PORT
;
/* just to declare */
...
...
@@ -55,8 +65,13 @@ enum options {
OPT_SOCKET
,
OPT_PASSWORD_FILE
,
OPT_MYSQLD_PATH
,
#ifndef __WIN__
OPT_RUN_AS_SERVICE
,
OPT_USER
,
#else
OPT_INSTALL_SERVICE
,
OPT_REMOVE_SERVICE
,
#endif
OPT_MONITORING_INTERVAL
,
OPT_PORT
,
OPT_BIND_ADDRESS
...
...
@@ -107,7 +122,14 @@ static struct my_option my_long_options[] =
(
gptr
*
)
&
Options
::
monitoring_interval
,
0
,
GET_UINT
,
REQUIRED_ARG
,
DEFAULT_MONITORING_INTERVAL
,
0
,
0
,
0
,
0
,
0
},
#ifdef __WIN__
{
"install"
,
OPT_INSTALL_SERVICE
,
"Install as system service."
,
(
gptr
*
)
&
Options
::
install_as_service
,
(
gptr
*
)
&
Options
::
install_as_service
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
1
,
0
,
0
,
0
},
{
"remove"
,
OPT_REMOVE_SERVICE
,
"Remove system service."
,
(
gptr
*
)
&
Options
::
remove_service
,
(
gptr
*
)
&
Options
::
remove_service
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
1
,
0
,
0
,
0
},
#else
{
"run-as-service"
,
OPT_RUN_AS_SERVICE
,
"Daemonize and start angel process."
,
(
gptr
*
)
&
Options
::
run_as_service
,
0
,
0
,
GET_BOOL
,
NO_ARG
,
0
,
0
,
1
,
0
,
0
,
0
},
...
...
@@ -116,7 +138,7 @@ static struct my_option my_long_options[] =
(
gptr
*
)
&
Options
::
user
,
(
gptr
*
)
&
Options
::
user
,
0
,
GET_STR
,
REQUIRED_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
#endif
{
"version"
,
'V'
,
"Output version information and exit."
,
0
,
0
,
0
,
GET_NO_ARG
,
NO_ARG
,
0
,
0
,
0
,
0
,
0
,
0
},
...
...
@@ -221,7 +243,7 @@ C_MODE_END
int
Options
::
load
(
int
argc
,
char
**
argv
)
{
saved_argv
=
argv
;
if
(
argc
>=
2
)
{
if
(
is_prefix
(
argv
[
1
],
"--defaults-file="
))
...
...
@@ -239,6 +261,22 @@ int Options::load(int argc, char **argv)
}
}
#ifdef __WIN__
setup_windows_defaults
(
*
argv
);
/*
On Windows, there are two possibilities. Either we are given
a defaults file on the command line or we use the my.ini file
that is in our app dir
*/
if
(
Options
::
config_file
==
NULL
)
{
::
GetModuleFileName
(
NULL
,
default_config_file
,
sizeof
(
default_config_file
));
char
*
filename
=
strrchr
(
default_config_file
,
"
\\
"
);
strcpy
(
filename
,
"
\\
my.ini"
);
Options
::
config_file
=
default_config_file
;
}
#endif
/* config-file options are prepended to command-line ones */
load_defaults
(
config_file
,
default_groups
,
&
argc
,
&
saved_argv
);
...
...
@@ -257,4 +295,32 @@ void Options::cleanup()
{
/* free_defaults returns nothing */
free_defaults
(
Options
::
saved_argv
);
#ifdef __WIN__
free
((
char
*
)
default_password_file_name
);
#endif
}
#ifdef __WIN__
char
*
change_extension
(
const
char
*
src
,
const
char
*
newext
)
{
char
*
dot
=
(
char
*
)
strrchr
(
src
,
'.'
);
if
(
!
dot
)
return
(
char
*
)
src
;
int
newlen
=
dot
-
src
+
strlen
(
newext
)
+
1
;
char
*
temp
=
(
char
*
)
malloc
(
newlen
);
bzero
(
temp
,
newlen
);
strncpy
(
temp
,
src
,
dot
-
src
+
1
);
strcat
(
temp
,
newext
);
return
temp
;
}
void
Options
::
setup_windows_defaults
(
const
char
*
progname
)
{
Options
::
password_file_name
=
default_password_file_name
=
change_extension
(
progname
,
"passwd"
);
Options
::
log_file_name
=
default_log_file_name
=
change_extension
(
progname
,
"log"
);
}
#endif
server-tools/instance-manager/options.h
View file @
7782bca1
...
...
@@ -28,13 +28,18 @@
struct
Options
{
#ifdef __WIN__
static
char
install_as_service
;
static
char
remove_service
;
#else
static
char
run_as_service
;
/* handle_options doesn't support bool */
static
const
char
*
user
;
#endif
static
const
char
*
log_file_name
;
static
const
char
*
pid_file_name
;
static
const
char
*
socket_file_name
;
static
const
char
*
password_file_name
;
static
const
char
*
default_mysqld_path
;
static
const
char
*
user
;
/* the option which should be passed to process_default_option_files */
static
uint
monitoring_interval
;
static
uint
port_number
;
...
...
@@ -44,8 +49,11 @@ struct Options
/* argv pointer returned by load_defaults() to be used by free_defaults() */
static
char
**
saved_argv
;
static
int
load
(
int
argc
,
char
**
argv
);
int
load
(
int
argc
,
char
**
argv
);
void
cleanup
();
#ifdef __WIN__
void
setup_windows_defaults
(
const
char
*
progname
);
#endif
};
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_OPTIONS_H
server-tools/instance-manager/parse_output.cc
View file @
7782bca1
...
...
@@ -21,6 +21,7 @@
#include <stdio.h>
#include <my_sys.h>
#include <m_string.h>
#include "port.h"
/*
...
...
server-tools/instance-manager/port.h
0 → 100755
View file @
7782bca1
#ifndef INCLUDES_MYSQL_INSTANCE_MANAGER_PORT_H
#define INCLUDES_MYSQL_INSTANCE_MANAGER_PORT_H
#ifdef __WIN__
#define vsnprintf _vsnprintf
#define SIGKILL 9
#define SHUT_RDWR 0x2
//TODO: fix this
#define DEFAULT_MONITORING_INTERVAL 20
#define DEFAULT_PORT 2273
#define PROTOCOL_VERSION 10
typedef
int
pid_t
;
#undef popen
#define popen(A,B) _popen(A,B)
#endif
/* __WIN__ */
#endif
/* INCLUDES_MYSQL_INSTANCE_MANAGER_PORT_H */
server-tools/instance-manager/priv.cc
View file @
7782bca1
...
...
@@ -14,7 +14,9 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <my_global.h>
#include "priv.h"
#include "port.h"
/* the pid of the manager process (of the signal thread on the LinuxThreads) */
pid_t
manager_pid
;
...
...
server-tools/instance-manager/priv.h
View file @
7782bca1
...
...
@@ -17,17 +17,23 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <sys/types.h>
#ifdef __WIN__
#include "port.h"
#else
#include <unistd.h>
#endif
/* the pid of the manager process (of the signal thread on the LinuxThreads) */
extern
pid_t
manager_pid
;
#ifndef __WIN__
/*
This flag is set if mysqlmanager has detected that it is running on the
system using LinuxThreads
*/
extern
bool
linuxthreads
;
#endif
extern
const
char
mysqlmanager_version
[];
extern
const
int
mysqlmanager_version_length
;
...
...
server-tools/instance-manager/thread_registry.cc
View file @
7782bca1
...
...
@@ -27,6 +27,7 @@
#include <thr_alarm.h>
#ifndef __WIN__
/* Kick-off signal handler */
enum
{
THREAD_KICK_OFF_SIGNAL
=
SIGUSR2
};
...
...
@@ -34,7 +35,7 @@ enum { THREAD_KICK_OFF_SIGNAL= SIGUSR2 };
static
void
handle_signal
(
int
__attribute__
((
unused
))
sig_no
)
{
}
#endif
/*
TODO: think about moving signal information (now it's shutdown_in_progress)
...
...
@@ -76,12 +77,13 @@ Thread_registry::~Thread_registry()
void
Thread_registry
::
register_thread
(
Thread_info
*
info
)
{
#ifndef __WIN__
struct
sigaction
sa
;
sa
.
sa_handler
=
handle_signal
;
sa
.
sa_flags
=
0
;
sigemptyset
(
&
sa
.
sa_mask
);
sigaction
(
THREAD_KICK_OFF_SIGNAL
,
&
sa
,
0
);
#endif
info
->
current_cond
=
0
;
pthread_mutex_lock
(
&
LOCK_thread_registry
);
...
...
@@ -156,6 +158,7 @@ void Thread_registry::deliver_shutdown()
pthread_mutex_lock
(
&
LOCK_thread_registry
);
shutdown_in_progress
=
true
;
#ifndef __WIN__
/* to stop reading from the network we need to flush alarm queue */
end_thr_alarm
(
0
);
/*
...
...
@@ -163,6 +166,8 @@ void Thread_registry::deliver_shutdown()
stopped alarm processing.
*/
process_alarm
(
THR_SERVER_ALARM
);
#endif
for
(
info
=
head
.
next
;
info
!=
&
head
;
info
=
info
->
next
)
{
pthread_kill
(
info
->
thread_id
,
THREAD_KICK_OFF_SIGNAL
);
...
...
server-tools/instance-manager/user_map.cc
View file @
7782bca1
...
...
@@ -36,7 +36,8 @@ struct User
int
User
::
init
(
const
char
*
line
)
{
const
char
*
name_begin
,
*
name_end
,
*
password
;
const
char
*
name_begin
,
*
name_end
;
char
*
password
;
if
(
line
[
0
]
==
'\''
||
line
[
0
]
==
'"'
)
{
...
...
@@ -44,7 +45,7 @@ int User::init(const char *line)
name_end
=
strchr
(
name_begin
,
line
[
0
]);
if
(
name_end
==
0
||
name_end
[
1
]
!=
':'
)
goto
err
;
password
=
name_end
+
2
;
password
=
(
char
*
)(
name_end
+
2
)
;
}
else
{
...
...
@@ -52,13 +53,18 @@ int User::init(const char *line)
name_end
=
strchr
(
name_begin
,
':'
);
if
(
name_end
==
0
)
goto
err
;
password
=
name_end
+
1
;
password
=
(
char
*
)(
name_end
+
1
)
;
}
user_length
=
name_end
-
name_begin
;
if
(
user_length
>
USERNAME_LENGTH
)
goto
err
;
/* assume that newline characater is present */
if
(
password
[
strlen
(
password
)
-
2
]
==
'\r'
)
{
password
[
strlen
(
password
)
-
2
]
=
'\n'
;
password
[
strlen
(
password
)
-
1
]
=
0
;
}
if
(
strlen
(
password
)
!=
SCRAMBLED_PASSWORD_CHAR_LENGTH
+
1
)
goto
err
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment