~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

Viewing changes to mysql-test/lib/v1/mtr_unique.pl

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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.
 
13
 
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
 
17
 
 
18
#
 
19
# This file is used from mysql-test-run.pl when choosing
 
20
# port numbers and directories to use for running mysqld.
 
21
#
 
22
 
 
23
use strict;
 
24
use Fcntl ':flock';
 
25
 
 
26
#
 
27
# Requested IDs are stored in a hash and released upon END.
 
28
#
 
29
my %mtr_unique_assigned_ids = ();
 
30
my $mtr_unique_pid;
 
31
BEGIN {
 
32
        $mtr_unique_pid = $$ unless defined $mtr_unique_pid;
 
33
}
 
34
END { 
 
35
        if($mtr_unique_pid == $$) {
 
36
                while(my ($id,$file) = each(%mtr_unique_assigned_ids)) {
 
37
                        print "Autoreleasing $file:$id\n";
 
38
                        mtr_release_unique_id($file, $id);
 
39
                }
 
40
        }
 
41
}
 
42
 
 
43
#
 
44
# Require a unique, numerical ID, given a file name (where all
 
45
# requested IDs are stored), a minimum and a maximum value.
 
46
#
 
47
# We use flock to implement locking for the ID file and ignore
 
48
# possible problems arising from lack of support for it on 
 
49
# some platforms (it should work on most, and the possible
 
50
# race condition would occur rarely). The proper solution for
 
51
# this is a daemon that manages IDs, of course.
 
52
#
 
53
# If no unique ID within the specified parameters can be 
 
54
# obtained, return undef.
 
55
#
 
56
sub mtr_require_unique_id($$$) {
 
57
        my $file = shift;
 
58
        my $min = shift;
 
59
        my $max = shift;
 
60
        my $ret = undef;
 
61
        my $changed = 0;
 
62
 
 
63
        my $can_use_ps = `ps -e | grep '^[ ]*$$ '`;
 
64
 
 
65
        if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
 
66
                die 'lock file is a symbolic link';
 
67
        }
 
68
 
 
69
        chmod 0777, "$file.sem";
 
70
        open SEM, ">", "$file.sem" or die "can't write to $file.sem";
 
71
        flock SEM, LOCK_EX or die "can't lock $file.sem";
 
72
        if(! -e $file) {
 
73
                open FILE, ">", $file or die "can't create $file";
 
74
                close FILE;
 
75
        }
 
76
 
 
77
        if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
 
78
                die 'lock file is a symbolic link';
 
79
        }
 
80
 
 
81
        chmod 0777, $file;
 
82
        open FILE, "+<", $file or die "can't open $file";
 
83
        select undef,undef,undef,0.2;
 
84
        seek FILE, 0, 0;
 
85
        my %taken = ();
 
86
        while(<FILE>) {
 
87
                chomp;
 
88
                my ($id, $pid) = split / /;
 
89
                $taken{$id} = $pid;
 
90
                if($can_use_ps) {
 
91
                        my $res = `ps -e | grep '^[ ]*$pid '`;
 
92
                        if(!$res) {
 
93
                                print "Ignoring slot $id used by missing process $pid.\n";
 
94
                                delete $taken{$id};
 
95
                                ++$changed;
 
96
                        }
 
97
                }
 
98
        }
 
99
        for(my $i=$min; $i<=$max; ++$i) {
 
100
                if(! exists $taken{$i}) {
 
101
                        $ret = $i;
 
102
                        $taken{$i} = $$;
 
103
                        ++$changed;
 
104
                        last;
 
105
                }
 
106
        }
 
107
        if($changed) {
 
108
                seek FILE, 0, 0;
 
109
                truncate FILE, 0 or die "can't truncate $file";
 
110
                for my $k (keys %taken) {
 
111
                        print FILE $k . ' ' . $taken{$k} . "\n";
 
112
                }
 
113
        }
 
114
        close FILE;
 
115
        flock SEM, LOCK_UN or warn "can't unlock $file.sem";
 
116
        close SEM;
 
117
        $mtr_unique_assigned_ids{$ret} = $file if defined $ret;
 
118
        return $ret;
 
119
}
 
120
 
 
121
#
 
122
# Require a unique ID like above, but sleep if no ID can be
 
123
# obtained immediately.
 
124
#
 
125
sub mtr_require_unique_id_and_wait($$$) {
 
126
        my $ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
 
127
        while(! defined $ret) {
 
128
                sleep 30;
 
129
                $ret = mtr_require_unique_id($_[0],$_[1],$_[2]);
 
130
                print "Waiting for unique id to become available...\n" unless $ret;
 
131
        }
 
132
        return $ret;
 
133
}
 
134
 
 
135
#
 
136
# Release a unique ID.
 
137
#
 
138
sub mtr_release_unique_id($$) {
 
139
        my $file = shift;
 
140
        my $myid = shift;
 
141
 
 
142
        if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
 
143
                die 'lock file is a symbolic link';
 
144
        }
 
145
 
 
146
        open SEM, ">", "$file.sem" or die "can't write to $file.sem";
 
147
        flock SEM, LOCK_EX or die "can't lock $file.sem";
 
148
 
 
149
        if(eval("readlink '$file'") || eval("readlink '$file.sem'")) {
 
150
                die 'lock file is a symbolic link';
 
151
        }
 
152
 
 
153
        if(! -e $file) {
 
154
                open FILE, ">", $file or die "can't create $file";
 
155
                close FILE;
 
156
        }
 
157
        open FILE, "+<", $file or die "can't open $file";
 
158
        select undef,undef,undef,0.2;
 
159
        seek FILE, 0, 0;
 
160
        my %taken = ();
 
161
        while(<FILE>) {
 
162
                chomp;
 
163
                my ($id, $pid) = split / /;
 
164
                $taken{$id} = $pid;
 
165
        }
 
166
        delete $taken{$myid};
 
167
        seek FILE, 0, 0;
 
168
        truncate FILE, 0 or die "can't truncate $file";
 
169
        for my $k (keys %taken) {
 
170
                print FILE $k . ' ' . $taken{$k} . "\n";
 
171
        }
 
172
        close FILE;
 
173
        flock SEM, LOCK_UN or warn "can't unlock $file.sem";
 
174
        close SEM;
 
175
        delete $mtr_unique_assigned_ids{$myid};
 
176
}
 
177
 
 
178
1;
 
179