1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

Fixup mtr_unique. Remove usage of ps and grep. Make it a module. Move _process_alive to Platform.pm. Rename opt_baseport to baseport, it's not an option

This commit is contained in:
Magnus Svensson
2008-08-10 19:46:43 +02:00
parent 36bebcc13c
commit 182b14114a
5 changed files with 209 additions and 200 deletions

View File

@ -21,7 +21,7 @@ use strict;
use base qw(Exporter);
our @EXPORT= qw(IS_CYGWIN IS_WINDOWS IS_WIN32PERL
native_path posix_path mixed_path
check_socket_path_length);
check_socket_path_length process_alive);
BEGIN {
if ($^O eq "cygwin") {
@ -123,4 +123,16 @@ sub check_socket_path_length {
}
sub process_alive {
my ($pid)= @_;
die "usage: process_alive(pid)" unless $pid;
return kill(0, $pid) unless IS_WINDOWS;
my @list= split(/,/, `tasklist /FI "PID eq $pid" /NH /FO CSV`);
my $ret_pid= eval($list[1]);
return ($ret_pid == $pid);
}
1;

View File

@ -100,17 +100,6 @@ else
}
sub _process_alive {
my ($pid)= @_;
return kill(0, $pid) unless IS_WINDOWS;
my @list= split(/,/, `tasklist /FI "PID eq $pid" /NH /FO CSV`);
my $ret_pid= eval($list[1]);
return ($ret_pid == $pid);
}
sub new {
my $class= shift;

View File

@ -1,178 +0,0 @@
# -*- cperl -*-
# Copyright (C) 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#
# This file is used from mysql-test-run.pl when choosing
# port numbers and directories to use for running mysqld.
#
use strict;
use Fcntl ':flock';
#
# Requested IDs are stored in a hash and released upon END.
#
my %mtr_unique_assigned_ids = ();
my $mtr_unique_pid;
BEGIN {
$mtr_unique_pid = $$ unless defined $mtr_unique_pid;
}
END {
if($mtr_unique_pid == $$) {
while(my ($id,$file) = each(%mtr_unique_assigned_ids)) {
print "Autoreleasing $file:$id\n";
mtr_release_unique_id($file, $id);
}
}
}
#
# Require a unique, numerical ID, given a file name (where all
# requested IDs are stored), a minimum and a maximum value.
#
# We use flock to implement locking for the ID file and ignore
# possible problems arising from lack of support for it on
# some platforms (it should work on most, and the possible
# race condition would occur rarely). The proper solution for
# this is a daemon that manages IDs, of course.
#
# If no unique ID within the specified parameters can be
# obtained, return undef.
#
sub mtr_require_unique_id($$$) {
my $file = shift;
my $min = shift;
my $max = shift;
my $ret = undef;
my $changed = 0;
my $can_use_ps = `ps -e | grep '^[ ]*$$ '`;
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
chmod 0777, "$file.sem";
open SEM, ">", "$file.sem" or die "can't write to $file.sem";
flock SEM, LOCK_EX or die "can't lock $file.sem";
if(! -e $file) {
open FILE, ">", $file or die "can't create $file";
close FILE;
}
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
chmod 0777, $file;
open FILE, "+<", $file or die "can't open $file";
select undef,undef,undef,0.2;
seek FILE, 0, 0;
my %taken = ();
while(<FILE>) {
chomp;
my ($id, $pid) = split / /;
$taken{$id} = $pid;
if($can_use_ps) {
my $res = `ps -e | grep '^[ ]*$pid '`;
if(!$res) {
print "Ignoring slot $id used by missing process $pid.\n";
delete $taken{$id};
++$changed;
}
}
}
for(my $i=$min; $i<=$max; ++$i) {
if(! exists $taken{$i}) {
$ret = $i;
$taken{$i} = $$;
++$changed;
last;
}
}
if($changed) {
seek FILE, 0, 0;
truncate FILE, 0 or die "can't truncate $file";
for my $k (keys %taken) {
print FILE $k . ' ' . $taken{$k} . "\n";
}
}
close FILE;
flock SEM, LOCK_UN or warn "can't unlock $file.sem";
close SEM;
$mtr_unique_assigned_ids{$ret} = $file if defined $ret;
return $ret;
}
#
# Require a unique ID like above, but sleep if no ID can be
# obtained immediately.
#
sub mtr_require_unique_id_and_wait($$$) {
my $ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
while(! defined $ret) {
sleep 30;
$ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
print "Waiting for unique id to become available...\n" unless $ret;
}
return $ret;
}
#
# Release a unique ID.
#
sub mtr_release_unique_id($$) {
my $file = shift;
my $myid = shift;
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
open SEM, ">", "$file.sem" or die "can't write to $file.sem";
flock SEM, LOCK_EX or die "can't lock $file.sem";
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
if(! -e $file) {
open FILE, ">", $file or die "can't create $file";
close FILE;
}
open FILE, "+<", $file or die "can't open $file";
select undef,undef,undef,0.2;
seek FILE, 0, 0;
my %taken = ();
while(<FILE>) {
chomp;
my ($id, $pid) = split / /;
$taken{$id} = $pid;
}
delete $taken{$myid};
seek FILE, 0, 0;
truncate FILE, 0 or die "can't truncate $file";
for my $k (keys %taken) {
print FILE $k . ' ' . $taken{$k} . "\n";
}
close FILE;
flock SEM, LOCK_UN or warn "can't unlock $file.sem";
close SEM;
delete $mtr_unique_assigned_ids{$myid};
}
1;

View File

@ -0,0 +1,184 @@
# -*- cperl -*-
# Copyright (C) 2006 MySQL AB
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
package mtr_unique;
use strict;
use Fcntl ':flock';
use base qw(Exporter);
our @EXPORT= qw(mtr_get_unique_id mtr_release_unique_id);
use My::Platform;
sub msg {
# print "### unique($$) - ", join(" ", @_), "\n";
}
my $file= "/tmp/mysql-test-ports";
my %mtr_unique_ids;
END {
my $allocated_id= $mtr_unique_ids{$$};
if (defined $allocated_id)
{
mtr_release_unique_id($allocated_id);
}
delete $mtr_unique_ids{$$};
}
#
# Get a unique, numerical ID, given a file name (where all
# requested IDs are stored), a minimum and a maximum value.
#
# If no unique ID within the specified parameters can be
# obtained, return undef.
#
sub mtr_get_unique_id($$) {
my ($min, $max)= @_;;
msg("get, '$file', $min-$max");
die "Can only get one unique id per process!" if $mtr_unique_ids{$$};
my $ret = undef;
my $changed = 0;
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
chmod 0777, "$file.sem";
open SEM, ">", "$file.sem" or die "can't write to $file.sem";
flock SEM, LOCK_EX or die "can't lock $file.sem";
if(! -e $file) {
open FILE, ">", $file or die "can't create $file";
close FILE;
}
msg("HAVE THE LOCK");
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
chmod 0777, $file;
open FILE, "+<", $file or die "can't open $file";
#select undef,undef,undef,0.2;
seek FILE, 0, 0;
my %taken = ();
while(<FILE>) {
chomp;
my ($id, $pid) = split / /;
$taken{$id} = $pid;
msg("taken: $id, $pid");
# Check if process with given pid is alive
if(!process_alive($pid)) {
msg("Removing slot $id used by missing process $pid");;
delete $taken{$id};
$changed++;
}
}
for(my $i=$min; $i<=$max; ++$i) {
if(! exists $taken{$i}) {
$ret = $i;
$taken{$i} = $$;
$changed++;
# Remember the id this process got
$mtr_unique_ids{$$}= $i;
msg(" got $i");
last;
}
}
if($changed) {
seek FILE, 0, 0;
truncate FILE, 0 or die "can't truncate $file";
for my $k (keys %taken) {
print FILE $k . ' ' . $taken{$k} . "\n";
}
}
close FILE;
msg("RELEASING THE LOCK");
flock SEM, LOCK_UN or warn "can't unlock $file.sem";
close SEM;
return $ret;
}
#
# Release a unique ID.
#
sub mtr_release_unique_id($) {
my ($myid)= @_;
msg("release, $myid");
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
open SEM, ">", "$file.sem" or die "can't write to $file.sem";
flock SEM, LOCK_EX or die "can't lock $file.sem";
msg("HAVE THE LOCK");
if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
die 'lock file is a symbolic link';
}
if(! -e $file) {
open FILE, ">", $file or die "can't create $file";
close FILE;
}
open FILE, "+<", $file or die "can't open $file";
#select undef,undef,undef,0.2;
seek FILE, 0, 0;
my %taken = ();
while(<FILE>) {
chomp;
my ($id, $pid) = split / /;
msg(" taken, $id $pid");
$taken{$id} = $pid;
}
if ($taken{$myid} != $$)
{
msg(" The unique id for this process does not match pid");
}
msg(" removing $myid");
delete $taken{$myid};
seek FILE, 0, 0;
truncate FILE, 0 or die "can't truncate $file";
for my $k (keys %taken) {
print FILE $k . ' ' . $taken{$k} . "\n";
}
close FILE;
msg("RELEASE THE LOCK");
flock SEM, LOCK_UN or warn "can't unlock $file.sem";
close SEM;
}
1;