⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mtr_process.pl

📁 这是linux下运行的mysql软件包,可用于linux 下安装 php + mysql + apach 的网络配置
💻 PL
📖 第 1 页 / 共 2 页
字号:
# -*- cperl -*-# This is a library file used by the Perl version of mysql-test-run,# and is part of the translation of the Bourne shell script with the# same name.#use Carp qw(cluck);use Socket;use Errno;use strict;#use POSIX ":sys_wait_h";use POSIX 'WNOHANG';sub mtr_run ($$$$$$;$);sub mtr_spawn ($$$$$$;$);sub mtr_stop_mysqld_servers ($);sub mtr_kill_leftovers ();sub mtr_record_dead_children ();sub mtr_exit ($);sub sleep_until_file_created ($$$);sub mtr_kill_processes ($);# static in Csub spawn_impl ($$$$$$$$);################################################################################  Execute an external command################################################################################ This function try to mimic the C version used in "netware/mysql_test_run.c"# FIXME learn it to handle append mode as well, a "new" flag or a "append"sub mtr_run ($$$$$$;$) {  my $path=       shift;  my $arg_list_t= shift;  my $input=      shift;  my $output=     shift;  my $error=      shift;  my $pid_file=   shift;  my $spawn_opts= shift;  return spawn_impl($path,$arg_list_t,'run',$input,$output,$error,$pid_file,    $spawn_opts);}sub mtr_run_test ($$$$$$;$) {  my $path=       shift;  my $arg_list_t= shift;  my $input=      shift;  my $output=     shift;  my $error=      shift;  my $pid_file=   shift;  my $spawn_opts= shift;  return spawn_impl($path,$arg_list_t,'test',$input,$output,$error,$pid_file,    $spawn_opts);}sub mtr_spawn ($$$$$$;$) {  my $path=       shift;  my $arg_list_t= shift;  my $input=      shift;  my $output=     shift;  my $error=      shift;  my $pid_file=   shift;  my $spawn_opts= shift;  return spawn_impl($path,$arg_list_t,'spawn',$input,$output,$error,$pid_file,    $spawn_opts);}################################################################################  If $join is set, we return the error code, else we return the PID###############################################################################sub spawn_impl ($$$$$$$$) {  my $path=       shift;  my $arg_list_t= shift;  my $mode=       shift;  my $input=      shift;  my $output=     shift;  my $error=      shift;  my $pid_file=   shift;                 # FIXME  my $spawn_opts= shift;  if ( $::opt_script_debug )  {    print STDERR "\n";    print STDERR "#### ", "-" x 78, "\n";    print STDERR "#### ", "STDIN  $input\n" if $input;    print STDERR "#### ", "STDOUT $output\n" if $output;    print STDERR "#### ", "STDERR $error\n" if $error;    print STDERR "#### ", "$mode : $path ", join(" ",@$arg_list_t), "\n";    print STDERR "#### ", "spawn options:\n";    if ($spawn_opts)    {      foreach my $key (sort keys %{$spawn_opts})      {        print STDERR "#### ", "  - $key: $spawn_opts->{$key}\n";      }    }    else    {      print STDERR "#### ", "  none\n";    }    print STDERR "#### ", "-" x 78, "\n";  } FORK:  {    my $pid= fork();    if ( ! defined $pid )    {      if ( $! == $!{EAGAIN} )           # See "perldoc Errno"      {        mtr_debug("Got EAGAIN from fork(), sleep 1 second and redo");        sleep(1);        redo FORK;      }      else      {        mtr_error("$path ($pid) can't be forked");      }    }    if ( $pid )    {      spawn_parent_impl($pid,$mode,$path);    }    else    {      # Child, redirect output and exec      # FIXME I tried POSIX::setsid() here to detach and, I hoped,      # avoid zombies. But everything went wild, somehow the parent      # became a deamon as well, and was hard to kill ;-)      # Need to catch SIGCHLD and do waitpid or something instead......      $SIG{INT}= 'DEFAULT';         # Parent do some stuff, we don't      if ( $::glob_cygwin_shell and $mode eq 'test' )      {        # Programs started from mysqltest under Cygwin, are to        # execute them within Cygwin. Else simple things in test        # files like        # --system "echo 1 > file"        # will fail.        # FIXME not working :-(#       $ENV{'COMSPEC'}= "$::glob_cygwin_shell -c";      }      my $log_file_open_mode = '>';      if ($spawn_opts and $spawn_opts->{'append_log_file'})      {        $log_file_open_mode = '>>';      }      if ( $output )      {        if ( ! open(STDOUT,$log_file_open_mode,$output) )        {          mtr_child_error("can't redirect STDOUT to \"$output\": $!");        }      }      if ( $error )      {        if ( $output eq $error )        {          if ( ! open(STDERR,">&STDOUT") )          {            mtr_child_error("can't dup STDOUT: $!");          }        }        else        {          if ( ! open(STDERR,$log_file_open_mode,$error) )          {            mtr_child_error("can't redirect STDERR to \"$error\": $!");          }        }      }      if ( $input )      {        if ( ! open(STDIN,"<",$input) )        {          mtr_child_error("can't redirect STDIN to \"$input\": $!");        }      }      if ( ! exec($path,@$arg_list_t) )      {        mtr_child_error("failed to execute \"$path\": $!");      }    }  }}sub spawn_parent_impl {  my $pid=  shift;  my $mode= shift;  my $path= shift;  if ( $mode eq 'run' or $mode eq 'test' )  {    if ( $mode eq 'run' )    {      # Simple run of command, we wait for it to return      my $ret_pid= waitpid($pid,0);      if ( $ret_pid <= 0 )      {        mtr_error("$path ($pid) got lost somehow");      }      return mtr_process_exit_status($?);    }    else    {      # We run mysqltest and wait for it to return. But we try to      # catch dying mysqld processes as well.      #      # We do blocking waitpid() until we get the return from the      # "mysqltest" call. But if a mysqld process dies that we      # started, we take this as an error, and kill mysqltest.      #      # FIXME is this as it should be? Can't mysqld terminate      # normally from running a test case?      my $exit_value= -1;      my $saved_exit_value;      my $ret_pid;                      # What waitpid() returns      while ( ($ret_pid= waitpid(-1,0)) != -1 )      {        # Someone terminated, don't know who. Collect        # status info first before $? is lost,        # but not $exit_value, this is flagged from        #         my $timer_name= mtr_timer_timeout($::glob_timers, $ret_pid);        if ( $timer_name )        {          if ( $timer_name eq "suite" )          {            # We give up here            # FIXME we should only give up the suite, not all of the run?            print STDERR "\n";            mtr_error("Test suite timeout");          }          elsif ( $timer_name eq "testcase" )          {            $saved_exit_value=  63;       # Mark as timeout            kill(9, $pid);                # Kill mysqltest            next;                         # Go on and catch the termination          }        }        if ( $ret_pid == $pid )        {          # We got termination of mysqltest, we are done          $exit_value= mtr_process_exit_status($?);          last;        }        # If one of the mysqld processes died, we want to        # mark this, and kill the mysqltest process.        foreach my $idx (0..1)        {          if ( $::master->[$idx]->{'pid'} eq $ret_pid )          {            mtr_debug("child $ret_pid was master[$idx], " .                      "exit during mysqltest run");            $::master->[$idx]->{'pid'}= 0;            last;          }        }        foreach my $idx (0..2)        {          if ( $::slave->[$idx]->{'pid'} eq $ret_pid )          {            mtr_debug("child $ret_pid was slave[$idx], " .                      "exit during mysqltest run");            $::slave->[$idx]->{'pid'}= 0;            last;          }        }        mtr_debug("waitpid() catched exit of unknown child $ret_pid, " .                  "exit during mysqltest run");      }      if ( $ret_pid != $pid )      {        # We terminated the waiting because a "mysqld" process died.        # Kill the mysqltest process.        kill(9,$pid);        $ret_pid= waitpid($pid,0);        if ( $ret_pid == -1 )        {          mtr_error("$path ($pid) got lost somehow");        }      }      return $saved_exit_value || $exit_value;    }  }  else  {    # We spawned a process we don't wait for    return $pid;  }}# ----------------------------------------------------------------------# We try to emulate how an Unix shell calculates the exit code# ----------------------------------------------------------------------sub mtr_process_exit_status {  my $raw_status= shift;  if ( $raw_status & 127 )  {    return ($raw_status & 127) + 128;  # Signal num + 128  }  else  {    return $raw_status >> 8;           # Exit code  }}################################################################################  Kill processes left from previous runs################################################################################ We just "ping" on the ports, and if we can't do a socket connect# we assume the server is dead. So we don't *really* know a server# is dead, we just hope that it after letting the listen port go,# it is dead enough for us to start a new server.sub mtr_kill_leftovers () {  # First, kill all masters and slaves that would conflict with  # this run. Make sure to remove the PID file, if any.  # FIXME kill IM manager first, else it will restart the servers, how?!  my @args;  for ( my $idx; $idx < 2; $idx++ )  {    push(@args,{                pid      => 0,          # We don't know the PID                pidfile  => $::instance_manager->{'instances'}->[$idx]->{'path_pid'},                sockfile => $::instance_manager->{'instances'}->[$idx]->{'path_sock'},                port     => $::instance_manager->{'instances'}->[$idx]->{'port'},               });  }  for ( my $idx; $idx < 2; $idx++ )  {    push(@args,{                pid      => 0,          # We don't know the PID                pidfile  => $::master->[$idx]->{'path_mypid'},                sockfile => $::master->[$idx]->{'path_mysock'},                port     => $::master->[$idx]->{'path_myport'},               });  }  for ( my $idx; $idx < 3; $idx++ )  {    push(@args,{                pid       => 0,         # We don't know the PID                pidfile   => $::slave->[$idx]->{'path_mypid'},                sockfile  => $::slave->[$idx]->{'path_mysock'},                port      => $::slave->[$idx]->{'path_myport'},               });  }  mtr_mysqladmin_shutdown(\@args, 20);  # We now have tried to terminate nice. We have waited for the listen  # port to be free, but can't really tell if the mysqld process died  # or not. We now try to find the process PID from the PID file, and  # send a kill to that process. Note that Perl let kill(0,@pids) be  # a way to just return the numer of processes the kernel can send  # signals to. So this can be used (except on Cygwin) to determine  # if there are processes left running that we cound out might exists.  #  # But still after all this work, all we know is that we have  # the ports free.  # We scan the "var/run/" directory for other process id's to kill  # FIXME $path_run_dir or something  my $rundir= "$::opt_vardir/run";  if ( -d $rundir )  {    opendir(RUNDIR, $rundir)      or mtr_error("can't open directory \"$rundir\": $!");    my @pids;    while ( my $elem= readdir(RUNDIR) )    {      my $pidfile= "$rundir/$elem";      if ( -f $pidfile )      {        my $pid= mtr_get_pid_from_file($pidfile);        # Race, could have been removed between I tested with -f        # and the unlink() below, so I better check again with -f        if ( ! unlink($pidfile) and -f $pidfile )        {          mtr_error("can't remove $pidfile");        }        if ( $::glob_cygwin_perl or kill(0, $pid) )        {          push(@pids, $pid);            # We know (cygwin guess) it exists        }      }    }    closedir(RUNDIR);    if ( @pids )    {      if ( $::glob_cygwin_perl )      {        # We have no (easy) way of knowing the Cygwin controlling        # process, in the PID file we only have the Windows process id.        system("kill -f " . join(" ",@pids)); # Hope for the best....        mtr_debug("Sleep 5 seconds waiting for processes to die");        sleep(5);      }      else      {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -