mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / mysql-test / lib / v1 / mtr_im.pl
blobc34acc9c82ff375f282dfa992aa61d1040a0647a
1 # -*- cperl -*-
2 # Copyright (c) 2006 MySQL AB, 2008 Sun Microsystems, Inc.
3 # Use is subject to license terms.
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; version 2 of the License.
8 #
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License
15 # along with this program; if not, write to the Free Software
16 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 # This is a library file used by the Perl version of mysql-test-run,
19 # and is part of the translation of the Bourne shell script with the
20 # same name.
22 use strict;
24 # Private IM-related operations.
26 sub mtr_im_kill_process ($$$$);
27 sub mtr_im_load_pids ($);
28 sub mtr_im_terminate ($);
29 sub mtr_im_check_alive ($);
30 sub mtr_im_check_main_alive ($);
31 sub mtr_im_check_angel_alive ($);
32 sub mtr_im_check_mysqlds_alive ($);
33 sub mtr_im_check_mysqld_alive ($);
34 sub mtr_im_cleanup ($);
35 sub mtr_im_rm_file ($);
36 sub mtr_im_errlog ($);
37 sub mtr_im_kill ($);
38 sub mtr_im_wait_for_connection ($$$);
39 sub mtr_im_wait_for_mysqld($$$);
41 # Public IM-related operations.
43 sub mtr_im_start ($$);
44 sub mtr_im_stop ($);
46 ##############################################################################
48 # Private operations.
50 ##############################################################################
52 sub mtr_im_kill_process ($$$$) {
53 my $pid_lst= shift;
54 my $signal= shift;
55 my $total_retries= shift;
56 my $timeout= shift;
58 my %pids;
60 foreach my $pid ( @{$pid_lst} )
62 $pids{$pid}= 1;
65 for ( my $cur_attempt= 1; $cur_attempt <= $total_retries; ++$cur_attempt )
67 foreach my $pid ( keys %pids )
69 mtr_debug("Sending $signal to $pid...");
71 kill($signal, $pid);
73 unless ( kill (0, $pid) )
75 mtr_debug("Process $pid died.");
76 delete $pids{$pid};
80 return if scalar keys %pids == 0;
82 mtr_debug("Sleeping $timeout second(s) waiting for processes to die...");
84 sleep($timeout);
87 mtr_debug("Process(es) " .
88 join(' ', keys %pids) .
89 " is still alive after $total_retries " .
90 "of sending signal $signal.");
93 ###########################################################################
95 sub mtr_im_load_pids($) {
96 my $im= shift;
98 mtr_debug("Loading PID files...");
100 # Obtain mysqld-process pids.
102 my $instances = $im->{'instances'};
104 for ( my $idx= 0; $idx < 2; ++$idx )
106 mtr_debug("IM-guarded mysqld[$idx] PID file: '" .
107 $instances->[$idx]->{'path_pid'} . "'.");
109 my $mysqld_pid;
111 if ( -r $instances->[$idx]->{'path_pid'} )
113 $mysqld_pid= mtr_get_pid_from_file($instances->[$idx]->{'path_pid'});
114 mtr_debug("IM-guarded mysqld[$idx] PID: $mysqld_pid.");
116 else
118 $mysqld_pid= undef;
119 mtr_debug("IM-guarded mysqld[$idx]: no PID file.");
122 $instances->[$idx]->{'pid'}= $mysqld_pid;
125 # Re-read Instance Manager PIDs from the file, since during tests Instance
126 # Manager could have been restarted, so its PIDs could have been changed.
128 # - IM-main
130 mtr_debug("IM-main PID file: '$im->{path_pid}'.");
132 if ( -f $im->{'path_pid'} )
134 $im->{'pid'} =
135 mtr_get_pid_from_file($im->{'path_pid'});
137 mtr_debug("IM-main PID: $im->{pid}.");
139 else
141 mtr_debug("IM-main: no PID file.");
142 $im->{'pid'}= undef;
145 # - IM-angel
147 mtr_debug("IM-angel PID file: '$im->{path_angel_pid}'.");
149 if ( -f $im->{'path_angel_pid'} )
151 $im->{'angel_pid'} =
152 mtr_get_pid_from_file($im->{'path_angel_pid'});
154 mtr_debug("IM-angel PID: $im->{'angel_pid'}.");
156 else
158 mtr_debug("IM-angel: no PID file.");
159 $im->{'angel_pid'} = undef;
163 ###########################################################################
165 sub mtr_im_terminate($) {
166 my $im= shift;
168 # Load pids from pid-files. We should do it first of all, because IM deletes
169 # them on shutdown.
171 mtr_im_load_pids($im);
173 mtr_debug("Shutting Instance Manager down...");
175 # Ignoring SIGCHLD so that all children could rest in peace.
177 start_reap_all();
179 # Send SIGTERM to IM-main.
181 if ( defined $im->{'pid'} )
183 mtr_debug("IM-main pid: $im->{pid}.");
184 mtr_debug("Stopping IM-main...");
186 mtr_im_kill_process([ $im->{'pid'} ], 'TERM', 10, 1);
188 else
190 mtr_debug("IM-main pid: n/a.");
193 # If IM-angel was alive, wait for it to die.
195 if ( defined $im->{'angel_pid'} )
197 mtr_debug("IM-angel pid: $im->{'angel_pid'}.");
198 mtr_debug("Waiting for IM-angel to die...");
200 my $total_attempts= 10;
202 for ( my $cur_attempt=1; $cur_attempt <= $total_attempts; ++$cur_attempt )
204 unless ( kill (0, $im->{'angel_pid'}) )
206 mtr_debug("IM-angel died.");
207 last;
210 sleep(1);
213 else
215 mtr_debug("IM-angel pid: n/a.");
218 stop_reap_all();
220 # Re-load PIDs.
222 mtr_im_load_pids($im);
225 ###########################################################################
227 sub mtr_im_check_alive($) {
228 my $im= shift;
230 mtr_debug("Checking whether IM-components are alive...");
232 return 1 if mtr_im_check_main_alive($im);
234 return 1 if mtr_im_check_angel_alive($im);
236 return 1 if mtr_im_check_mysqlds_alive($im);
238 return 0;
241 ###########################################################################
243 sub mtr_im_check_main_alive($) {
244 my $im= shift;
246 # Check that the process, that we know to be IM's, is dead.
248 if ( defined $im->{'pid'} )
250 if ( kill (0, $im->{'pid'}) )
252 mtr_debug("IM-main (PID: $im->{pid}) is alive.");
253 return 1;
255 else
257 mtr_debug("IM-main (PID: $im->{pid}) is dead.");
260 else
262 mtr_debug("No PID file for IM-main.");
265 # Check that IM does not accept client connections.
267 if ( mtr_ping_port($im->{'port'}) )
269 mtr_debug("IM-main (port: $im->{port}) " .
270 "is accepting connections.");
272 mtr_im_errlog("IM-main is accepting connections on port " .
273 "$im->{port}, but there is no " .
274 "process information.");
275 return 1;
277 else
279 mtr_debug("IM-main (port: $im->{port}) " .
280 "does not accept connections.");
281 return 0;
285 ###########################################################################
287 sub mtr_im_check_angel_alive($) {
288 my $im= shift;
290 # Check that the process, that we know to be the Angel, is dead.
292 if ( defined $im->{'angel_pid'} )
294 if ( kill (0, $im->{'angel_pid'}) )
296 mtr_debug("IM-angel (PID: $im->{angel_pid}) is alive.");
297 return 1;
299 else
301 mtr_debug("IM-angel (PID: $im->{angel_pid}) is dead.");
302 return 0;
305 else
307 mtr_debug("No PID file for IM-angel.");
308 return 0;
312 ###########################################################################
314 sub mtr_im_check_mysqlds_alive($) {
315 my $im= shift;
317 mtr_debug("Checking for IM-guarded mysqld instances...");
319 my $instances = $im->{'instances'};
321 for ( my $idx= 0; $idx < 2; ++$idx )
323 mtr_debug("Checking mysqld[$idx]...");
325 return 1
326 if mtr_im_check_mysqld_alive($instances->[$idx]);
330 ###########################################################################
332 sub mtr_im_check_mysqld_alive($) {
333 my $mysqld_instance= shift;
335 # Check that the process is dead.
337 if ( defined $mysqld_instance->{'pid'} )
339 if ( kill (0, $mysqld_instance->{'pid'}) )
341 mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is alive.");
342 return 1;
344 else
346 mtr_debug("Mysqld instance (PID: $mysqld_instance->{pid}) is dead.");
349 else
351 mtr_debug("No PID file for mysqld instance.");
354 # Check that mysqld does not accept client connections.
356 if ( mtr_ping_port($mysqld_instance->{'port'}) )
358 mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
359 "is accepting connections.");
361 mtr_im_errlog("Mysqld is accepting connections on port " .
362 "$mysqld_instance->{port}, but there is no " .
363 "process information.");
364 return 1;
366 else
368 mtr_debug("Mysqld instance (port: $mysqld_instance->{port}) " .
369 "does not accept connections.");
370 return 0;
374 ###########################################################################
376 sub mtr_im_cleanup($) {
377 my $im= shift;
379 mtr_im_rm_file($im->{'path_pid'});
380 mtr_im_rm_file($im->{'path_sock'});
382 mtr_im_rm_file($im->{'path_angel_pid'});
384 for ( my $idx= 0; $idx < 2; ++$idx )
386 mtr_im_rm_file($im->{'instances'}->[$idx]->{'path_pid'});
387 mtr_im_rm_file($im->{'instances'}->[$idx]->{'path_sock'});
391 ###########################################################################
393 sub mtr_im_rm_file($)
395 my $file_path= shift;
397 if ( -f $file_path )
399 mtr_debug("Removing '$file_path'...");
401 unless ( unlink($file_path) )
403 mtr_warning("Can not remove '$file_path'.")
406 else
408 mtr_debug("File '$file_path' does not exist already.");
412 ###########################################################################
414 sub mtr_im_errlog($) {
415 my $msg= shift;
417 # Complain in error log so that a warning will be shown.
419 # TODO: unless BUG#20761 is fixed, we will print the warning to stdout, so
420 # that it can be seen on console and does not produce pushbuild error.
422 # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err";
424 # open (ERRLOG, ">>$errlog") ||
425 # mtr_error("Can not open error log ($errlog)");
427 # my $ts= localtime();
428 # print ERRLOG
429 # "Warning: [$ts] $msg\n";
431 # close ERRLOG;
433 my $ts= localtime();
434 print "Warning: [$ts] $msg\n";
437 ###########################################################################
439 sub mtr_im_kill($) {
440 my $im= shift;
442 # Re-load PIDs. That can be useful because some processes could have been
443 # restarted.
445 mtr_im_load_pids($im);
447 # Ignoring SIGCHLD so that all children could rest in peace.
449 start_reap_all();
451 # Kill IM-angel first of all.
453 if ( defined $im->{'angel_pid'} )
455 mtr_debug("Killing IM-angel (PID: $im->{angel_pid})...");
456 mtr_im_kill_process([ $im->{'angel_pid'} ], 'KILL', 10, 1)
458 else
460 mtr_debug("IM-angel is dead.");
463 # Re-load PIDs again.
465 mtr_im_load_pids($im);
467 # Kill IM-main.
469 if ( defined $im->{'pid'} )
471 mtr_debug("Killing IM-main (PID: $im->pid})...");
472 mtr_im_kill_process([ $im->{'pid'} ], 'KILL', 10, 1);
474 else
476 mtr_debug("IM-main is dead.");
479 # Re-load PIDs again.
481 mtr_im_load_pids($im);
483 # Kill guarded mysqld instances.
485 my @mysqld_pids;
487 mtr_debug("Collecting PIDs of mysqld instances to kill...");
489 for ( my $idx= 0; $idx < 2; ++$idx )
491 my $pid= $im->{'instances'}->[$idx]->{'pid'};
493 unless ( defined $pid )
495 next;
498 mtr_debug(" - IM-guarded mysqld[$idx] PID: $pid.");
500 push (@mysqld_pids, $pid);
503 if ( scalar @mysqld_pids > 0 )
505 mtr_debug("Killing IM-guarded mysqld instances...");
506 mtr_im_kill_process(\@mysqld_pids, 'KILL', 10, 1);
509 # That's all.
511 stop_reap_all();
514 ##############################################################################
516 sub mtr_im_wait_for_connection($$$) {
517 my $im= shift;
518 my $total_attempts= shift;
519 my $connect_timeout= shift;
521 mtr_debug("Waiting for IM on port $im->{port} " .
522 "to start accepting connections...");
524 for ( my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt )
526 mtr_debug("Trying to connect to IM ($cur_attempt of $total_attempts)...");
528 if ( mtr_ping_port($im->{'port'}) )
530 mtr_debug("IM is accepting connections " .
531 "on port $im->{port}.");
532 return 1;
535 mtr_debug("Sleeping $connect_timeout...");
536 sleep($connect_timeout);
539 mtr_debug("IM does not accept connections " .
540 "on port $im->{port} after " .
541 ($total_attempts * $connect_timeout) . " seconds.");
543 return 0;
546 ##############################################################################
548 sub mtr_im_wait_for_mysqld($$$) {
549 my $mysqld= shift;
550 my $total_attempts= shift;
551 my $connect_timeout= shift;
553 mtr_debug("Waiting for IM-guarded mysqld on port $mysqld->{port} " .
554 "to start accepting connections...");
556 for ( my $cur_attempt= 1; $cur_attempt <= $total_attempts; ++$cur_attempt )
558 mtr_debug("Trying to connect to mysqld " .
559 "($cur_attempt of $total_attempts)...");
561 if ( mtr_ping_port($mysqld->{'port'}) )
563 mtr_debug("Mysqld is accepting connections " .
564 "on port $mysqld->{port}.");
565 return 1;
568 mtr_debug("Sleeping $connect_timeout...");
569 sleep($connect_timeout);
572 mtr_debug("Mysqld does not accept connections " .
573 "on port $mysqld->{port} after " .
574 ($total_attempts * $connect_timeout) . " seconds.");
576 return 0;
579 ##############################################################################
581 # Public operations.
583 ##############################################################################
585 sub mtr_im_start($$) {
586 my $im = shift;
587 my $opts = shift;
589 mtr_debug("Starting Instance Manager...");
591 my $args;
592 mtr_init_args(\$args);
593 mtr_add_arg($args, "--defaults-file=%s", $im->{'defaults_file'});
595 foreach my $opt ( @{$opts} )
597 mtr_add_arg($args, $opt);
600 $im->{'spawner_pid'} =
601 mtr_spawn(
602 $::exe_im, # path to the executable
603 $args, # cmd-line args
604 '', # stdin
605 $im->{'path_log'}, # stdout
606 $im->{'path_err'}, # stderr
607 '', # pid file path (not used)
608 { append_log_file => 1 } # append log files
611 unless ( $im->{'spawner_pid'} )
613 mtr_error('Could not start Instance Manager.')
616 # Instance Manager can be run in daemon mode. In this case, it creates
617 # several processes and the parent process, created by mtr_spawn(), exits just
618 # after start. So, we have to obtain Instance Manager PID from the PID file.
620 mtr_debug("Waiting for IM to create PID file (" .
621 "path: '$im->{path_pid}'; " .
622 "timeout: $im->{start_timeout})...");
624 unless ( sleep_until_file_created($im->{'path_pid'},
625 $im->{'start_timeout'},
626 -1) ) # real PID is still unknown
628 mtr_debug("IM has not created PID file in $im->{start_timeout} secs.");
629 mtr_debug("Aborting test suite...");
631 mtr_kill_leftovers();
633 mtr_report("IM has not created PID file in $im->{start_timeout} secs.");
634 return 0;
637 $im->{'pid'}= mtr_get_pid_from_file($im->{'path_pid'});
639 mtr_debug("Instance Manager started. PID: $im->{pid}.");
641 # Wait until we can connect to IM.
643 my $IM_CONNECT_TIMEOUT= 30;
645 unless ( mtr_im_wait_for_connection($im,
646 $IM_CONNECT_TIMEOUT, 1) )
648 mtr_debug("Can not connect to Instance Manager " .
649 "in $IM_CONNECT_TIMEOUT seconds after start.");
650 mtr_debug("Aborting test suite...");
652 mtr_kill_leftovers();
654 mtr_report("Can not connect to Instance Manager " .
655 "in $IM_CONNECT_TIMEOUT seconds after start.");
656 return 0;
659 # Wait for IM to start guarded instances:
660 # - wait for PID files;
662 mtr_debug("Waiting for guarded mysqlds instances to create PID files...");
664 for ( my $idx= 0; $idx < 2; ++$idx )
666 my $mysqld= $im->{'instances'}->[$idx];
668 if ( exists $mysqld->{'nonguarded'} )
670 next;
673 mtr_debug("Waiting for mysqld[$idx] to create PID file (" .
674 "path: '$mysqld->{path_pid}'; " .
675 "timeout: $mysqld->{start_timeout})...");
677 unless ( sleep_until_file_created($mysqld->{'path_pid'},
678 $mysqld->{'start_timeout'},
679 -1) ) # real PID is still unknown
681 mtr_debug("mysqld[$idx] has not created PID file in " .
682 "$mysqld->{start_timeout} secs.");
683 mtr_debug("Aborting test suite...");
685 mtr_kill_leftovers();
687 mtr_report("mysqld[$idx] has not created PID file in " .
688 "$mysqld->{start_timeout} secs.");
689 return 0;
692 mtr_debug("PID file for mysqld[$idx] ($mysqld->{path_pid} created.");
695 # Wait until we can connect to guarded mysqld-instances
696 # (in other words -- wait for IM to start guarded instances).
698 mtr_debug("Waiting for guarded mysqlds to start accepting connections...");
700 for ( my $idx= 0; $idx < 2; ++$idx )
702 my $mysqld= $im->{'instances'}->[$idx];
704 if ( exists $mysqld->{'nonguarded'} )
706 next;
709 mtr_debug("Waiting for mysqld[$idx] to accept connection...");
711 unless ( mtr_im_wait_for_mysqld($mysqld, 30, 1) )
713 mtr_debug("Can not connect to mysqld[$idx] " .
714 "in $IM_CONNECT_TIMEOUT seconds after start.");
715 mtr_debug("Aborting test suite...");
717 mtr_kill_leftovers();
719 mtr_report("Can not connect to mysqld[$idx] " .
720 "in $IM_CONNECT_TIMEOUT seconds after start.");
721 return 0;
724 mtr_debug("mysqld[$idx] started.");
727 mtr_debug("Instance Manager and its components are up and running.");
729 return 1;
732 ##############################################################################
734 sub mtr_im_stop($) {
735 my $im= shift;
737 mtr_debug("Stopping Instance Manager...");
739 # Try graceful shutdown.
741 mtr_im_terminate($im);
743 # Check that all processes died.
745 unless ( mtr_im_check_alive($im) )
747 mtr_debug("Instance Manager has been stopped successfully.");
748 mtr_im_cleanup($im);
749 return 1;
752 # Instance Manager don't want to die. We should kill it.
754 mtr_im_errlog("Instance Manager did not shutdown gracefully.");
756 mtr_im_kill($im);
758 # Check again that all IM-related processes have been killed.
760 my $im_is_alive= mtr_im_check_alive($im);
762 mtr_im_cleanup($im);
764 if ( $im_is_alive )
766 mtr_debug("Can not kill Instance Manager or its children.");
767 return 0;
770 mtr_debug("Instance Manager has been killed successfully.");
771 return 1;
774 ###########################################################################