mirror of
https://github.com/MariaDB/server.git
synced 2025-01-19 13:32:33 +01:00
Merge bk-internal.mysql.com:/home/bk/mysql-5.0-runtime
into mysql.com:/mnt/raid/MySQL/devel/5.0-bug14106
This commit is contained in:
commit
2038148c59
7 changed files with 169 additions and 18 deletions
|
@ -20,6 +20,7 @@ sub mtr_record_dead_children ();
|
|||
sub mtr_exit ($);
|
||||
sub sleep_until_file_created ($$$);
|
||||
sub mtr_kill_processes ($);
|
||||
sub mtr_kill_process ($$$$);
|
||||
|
||||
# static in C
|
||||
sub spawn_impl ($$$$$$$$);
|
||||
|
@ -885,6 +886,25 @@ sub mtr_kill_processes ($) {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
sub mtr_kill_process ($$$$) {
|
||||
my $pid= shift;
|
||||
my $signal= shift;
|
||||
my $retries= shift;
|
||||
my $timeout= shift;
|
||||
|
||||
while (1)
|
||||
{
|
||||
kill($signal, $pid);
|
||||
|
||||
last unless kill (0, $pid) and $retries--;
|
||||
|
||||
mtr_debug("Sleep $timeout second waiting for processes to die");
|
||||
|
||||
sleep($timeout);
|
||||
}
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# When we exit, we kill off all children
|
||||
|
|
|
@ -924,6 +924,7 @@ sub command_line_setup () {
|
|||
path_err => "$opt_vardir/log/im.err",
|
||||
path_log => "$opt_vardir/log/im.log",
|
||||
path_pid => "$opt_vardir/run/im.pid",
|
||||
path_angel_pid => "$opt_vardir/run/im.angel.pid",
|
||||
path_sock => "$sockdir/im.sock",
|
||||
port => $im_port,
|
||||
start_timeout => $master->[0]->{'start_timeout'},
|
||||
|
@ -1179,6 +1180,7 @@ sub environment_setup () {
|
|||
$ENV{'NDB_STATUS_OK'}= "YES";
|
||||
|
||||
$ENV{'IM_PATH_PID'}= $instance_manager->{path_pid};
|
||||
$ENV{'IM_PATH_ANGEL_PID'}= $instance_manager->{path_angel_pid};
|
||||
$ENV{'IM_PORT'}= $instance_manager->{port};
|
||||
|
||||
$ENV{'IM_MYSQLD1_SOCK'}= $instance_manager->{instances}->[0]->{path_sock};
|
||||
|
@ -1803,6 +1805,7 @@ sub im_create_defaults_file($) {
|
|||
|
||||
[manager]
|
||||
pid-file = $instance_manager->{path_pid}
|
||||
angel-pid-file = $instance_manager->{path_angel_pid}
|
||||
socket = $instance_manager->{path_sock}
|
||||
port = $instance_manager->{port}
|
||||
password-file = $instance_manager->{password_file}
|
||||
|
@ -1827,7 +1830,7 @@ log-slow-queries = $instance->{path_datadir}/mysqld$server_id.slow.log
|
|||
language = $path_language
|
||||
character-sets-dir = $path_charsetsdir
|
||||
basedir = $path_my_basedir
|
||||
server_id =$server_id
|
||||
server_id = $server_id
|
||||
skip-stack-trace
|
||||
skip-innodb
|
||||
skip-bdb
|
||||
|
@ -2786,6 +2789,18 @@ sub im_start($$) {
|
|||
sub im_stop($) {
|
||||
my $instance_manager = shift;
|
||||
|
||||
# Obtain mysqld-process pids before we start stopping IM (it can delete pid
|
||||
# files).
|
||||
|
||||
my @mysqld_pids = ();
|
||||
my $instances = $instance_manager->{'instances'};
|
||||
|
||||
push(@mysqld_pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}))
|
||||
if -r $instances->[0]->{'path_pid'};
|
||||
|
||||
push(@mysqld_pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}))
|
||||
if -r $instances->[1]->{'path_pid'};
|
||||
|
||||
# Re-read pid from the file, since during tests Instance Manager could have
|
||||
# been restarted, so its pid could have been changed.
|
||||
|
||||
|
@ -2793,34 +2808,79 @@ sub im_stop($) {
|
|||
mtr_get_pid_from_file($instance_manager->{'path_pid'})
|
||||
if -f $instance_manager->{'path_pid'};
|
||||
|
||||
if (-f $instance_manager->{'path_angel_pid'})
|
||||
{
|
||||
$instance_manager->{'angel_pid'} =
|
||||
mtr_get_pid_from_file($instance_manager->{'path_angel_pid'})
|
||||
}
|
||||
else
|
||||
{
|
||||
$instance_manager->{'angel_pid'} = undef;
|
||||
}
|
||||
|
||||
# Inspired from mtr_stop_mysqld_servers().
|
||||
|
||||
start_reap_all();
|
||||
|
||||
# Create list of pids. We should stop Instance Manager and all started
|
||||
# mysqld-instances. Some of them may be nonguarded, so IM will not stop them
|
||||
# on shutdown.
|
||||
# Try graceful shutdown.
|
||||
|
||||
my @pids = ( $instance_manager->{'pid'} );
|
||||
my $instances = $instance_manager->{'instances'};
|
||||
mtr_kill_process($instance_manager->{'pid'}, 'TERM', 10, 1);
|
||||
|
||||
if ( -r $instances->[0]->{'path_pid'} )
|
||||
# Check that all processes died.
|
||||
|
||||
my $clean_shutdown= 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
push(@pids, mtr_get_pid_from_file($instances->[0]->{'path_pid'}));
|
||||
last if kill (0, $instance_manager->{'pid'});
|
||||
|
||||
last if (defined $instance_manager->{'angel_pid'}) &&
|
||||
kill (0, $instance_manager->{'angel_pid'});
|
||||
|
||||
foreach my $pid (@mysqld_pids)
|
||||
{
|
||||
last if kill (0, $pid);
|
||||
}
|
||||
|
||||
$clean_shutdown= 1;
|
||||
last;
|
||||
}
|
||||
|
||||
if ( -r $instances->[1]->{'path_pid'} )
|
||||
# Kill leftovers (the order is important).
|
||||
|
||||
unless ($clean_shutdown)
|
||||
{
|
||||
push(@pids, mtr_get_pid_from_file($instances->[1]->{'path_pid'}));
|
||||
mtr_kill_process($instance_manager->{'angel_pid'}, 'KILL', 10, 1)
|
||||
if defined $instance_manager->{'angel_pid'};
|
||||
|
||||
mtr_kill_process($instance_manager->{'pid'}, 'KILL', 10, 1);
|
||||
|
||||
# Shutdown managed mysqld-processes. Some of them may be nonguarded, so IM
|
||||
# will not stop them on shutdown. So, we should firstly try to end them
|
||||
# legally.
|
||||
|
||||
mtr_kill_processes(\@mysqld_pids);
|
||||
|
||||
# Complain in error log so that a warning will be shown.
|
||||
|
||||
my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
|
||||
|
||||
open (ERRLOG, ">>$errlog") ||
|
||||
mtr_error("Can not open error log ($errlog)");
|
||||
|
||||
my $ts= localtime();
|
||||
print ERRLOG
|
||||
"Warning: [$ts] Instance Manager did not shutdown gracefully.\n";
|
||||
|
||||
close ERRLOG;
|
||||
}
|
||||
|
||||
# Kill processes.
|
||||
|
||||
mtr_kill_processes(\@pids);
|
||||
# That's all.
|
||||
|
||||
stop_reap_all();
|
||||
|
||||
$instance_manager->{'pid'} = undef;
|
||||
$instance_manager->{'angel_pid'} = undef;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -35,12 +35,12 @@
|
|||
#endif
|
||||
|
||||
|
||||
static int create_pid_file(const char *pid_file_name)
|
||||
int create_pid_file(const char *pid_file_name, int pid)
|
||||
{
|
||||
if (FILE *pid_file= my_fopen(pid_file_name,
|
||||
O_WRONLY | O_CREAT | O_BINARY, MYF(0)))
|
||||
{
|
||||
fprintf(pid_file, "%d\n", (int) getpid());
|
||||
fprintf(pid_file, "%d\n", (int) pid);
|
||||
my_fclose(pid_file, MYF(0));
|
||||
return 0;
|
||||
}
|
||||
|
@ -138,8 +138,13 @@ void manager(const Options &options)
|
|||
if (user_map.load(options.password_file_name))
|
||||
return;
|
||||
|
||||
/* write pid file */
|
||||
if (create_pid_file(options.pid_file_name))
|
||||
/* write Instance Manager pid file */
|
||||
|
||||
log_info("IM pid file: '%s'; PID: %d.",
|
||||
(const char *) options.pid_file_name,
|
||||
(int) manager_pid);
|
||||
|
||||
if (create_pid_file(options.pid_file_name, manager_pid))
|
||||
return;
|
||||
|
||||
sigset_t mask;
|
||||
|
|
|
@ -20,4 +20,6 @@ struct Options;
|
|||
|
||||
void manager(const Options &options);
|
||||
|
||||
int create_pid_file(const char *pid_file_name, int pid);
|
||||
|
||||
#endif // INCLUDES_MYSQL_INSTANCE_MANAGER_MANAGER_H
|
||||
|
|
|
@ -338,6 +338,14 @@ spawn:
|
|||
/* Here we return to main, and fall into manager */
|
||||
break;
|
||||
default: // parent, success
|
||||
pid= getpid(); /* Get our pid. */
|
||||
|
||||
log_info("Angel pid file: '%s'; PID: %d.",
|
||||
(const char *) options.angel_pid_file_name,
|
||||
(int) pid);
|
||||
|
||||
create_pid_file(Options::angel_pid_file_name, pid);
|
||||
|
||||
while (child_status == CHILD_OK && is_terminated == 0)
|
||||
sigsuspend(&zeromask);
|
||||
|
||||
|
|
|
@ -44,6 +44,7 @@ const char *Options::user= 0; /* No default value */
|
|||
const char *default_password_file_name= QUOTE(DEFAULT_PASSWORD_FILE_NAME);
|
||||
const char *default_log_file_name= QUOTE(DEFAULT_LOG_FILE_NAME);
|
||||
const char *Options::config_file= QUOTE(DEFAULT_CONFIG_FILE);
|
||||
const char *Options::angel_pid_file_name= NULL;
|
||||
#endif
|
||||
const char *Options::log_file_name= default_log_file_name;
|
||||
const char *Options::pid_file_name= QUOTE(DEFAULT_PID_FILE_NAME);
|
||||
|
@ -58,6 +59,9 @@ char **Options::saved_argv= NULL;
|
|||
/* Remember if the config file was forced */
|
||||
bool Options::is_forced_default_file= 0;
|
||||
|
||||
static const char * const ANGEL_PID_FILE_SUFFIX= ".angel.pid";
|
||||
static const int ANGEL_PID_FILE_SUFFIX_LEN= strlen(ANGEL_PID_FILE_SUFFIX);
|
||||
|
||||
/*
|
||||
List of options, accepted by the instance manager.
|
||||
List must be closed with empty option.
|
||||
|
@ -72,6 +76,7 @@ enum options {
|
|||
#ifndef __WIN__
|
||||
OPT_RUN_AS_SERVICE,
|
||||
OPT_USER,
|
||||
OPT_ANGEL_PID_FILE,
|
||||
#else
|
||||
OPT_INSTALL_SERVICE,
|
||||
OPT_REMOVE_SERVICE,
|
||||
|
@ -94,7 +99,14 @@ static struct my_option my_long_options[] =
|
|||
|
||||
{ "pid-file", OPT_PID_FILE, "Pid file to use.",
|
||||
(gptr *) &Options::pid_file_name, (gptr *) &Options::pid_file_name,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
|
||||
#ifndef __WIN__
|
||||
{ "angel-pid-file", OPT_ANGEL_PID_FILE, "Pid file for angel process.",
|
||||
(gptr *) &Options::angel_pid_file_name,
|
||||
(gptr *) &Options::angel_pid_file_name,
|
||||
0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
|
||||
#endif
|
||||
|
||||
{ "socket", OPT_SOCKET, "Socket file to use for connection.",
|
||||
(gptr *) &Options::socket_file_name, (gptr *) &Options::socket_file_name,
|
||||
|
@ -290,6 +302,46 @@ int Options::load(int argc, char **argv)
|
|||
get_one_option)) != 0)
|
||||
goto err;
|
||||
|
||||
#ifndef __WIN__
|
||||
if (Options::run_as_service)
|
||||
{
|
||||
if (Options::angel_pid_file_name == NULL)
|
||||
{
|
||||
/*
|
||||
Calculate angel pid file on the IM pid file basis: replace the
|
||||
extension (everything after the last dot) of the pid file basename to
|
||||
'.angel.pid'.
|
||||
*/
|
||||
|
||||
char *angel_pid_file_name;
|
||||
char *base_name_ptr;
|
||||
char *ext_ptr;
|
||||
|
||||
angel_pid_file_name= (char *) malloc(strlen(Options::pid_file_name) +
|
||||
ANGEL_PID_FILE_SUFFIX_LEN);
|
||||
|
||||
strcpy(angel_pid_file_name, Options::pid_file_name);
|
||||
|
||||
base_name_ptr= strrchr(angel_pid_file_name, '/');
|
||||
|
||||
if (!base_name_ptr)
|
||||
base_name_ptr= angel_pid_file_name + 1;
|
||||
|
||||
ext_ptr= strrchr(base_name_ptr, '.');
|
||||
if (ext_ptr)
|
||||
*ext_ptr= 0;
|
||||
|
||||
strcat(angel_pid_file_name, ANGEL_PID_FILE_SUFFIX);
|
||||
|
||||
Options::angel_pid_file_name= angel_pid_file_name;
|
||||
}
|
||||
else
|
||||
{
|
||||
Options::angel_pid_file_name= strdup(Options::angel_pid_file_name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
|
@ -301,6 +353,9 @@ void Options::cleanup()
|
|||
/* free_defaults returns nothing */
|
||||
if (Options::saved_argv != NULL)
|
||||
free_defaults(Options::saved_argv);
|
||||
|
||||
if (Options::run_as_service)
|
||||
free((void *) Options::angel_pid_file_name);
|
||||
}
|
||||
|
||||
#ifdef __WIN__
|
||||
|
|
|
@ -35,6 +35,7 @@ struct Options
|
|||
#else
|
||||
static char run_as_service; /* handle_options doesn't support bool */
|
||||
static const char *user;
|
||||
static const char *angel_pid_file_name;
|
||||
#endif
|
||||
static bool is_forced_default_file;
|
||||
static const char *log_file_name;
|
||||
|
|
Loading…
Reference in a new issue