mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
60dd4e8da4
MTR gives up if wanted port not available Try next range if set to 'auto' Also, use next number for additional threads if explicitly set
197 lines
4.3 KiB
Perl
197 lines
4.3 KiB
Perl
# -*- 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;
|
|
|
|
if(!IS_WINDOWS)
|
|
{
|
|
$file= "/tmp/mysql-test-ports";
|
|
}
|
|
else
|
|
{
|
|
$file= $ENV{'TEMP'}."/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)) {
|
|
print "Removing slot $id used by missing process $pid\n";
|
|
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;
|
|
|
|
delete $mtr_unique_ids{$$};
|
|
}
|
|
|
|
|
|
1;
|
|
|