line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package MogileFS::ReplicationRequest; |
2
|
21
|
|
|
21
|
|
175
|
use strict; |
|
21
|
|
|
|
|
52
|
|
|
21
|
|
|
|
|
988
|
|
3
|
21
|
|
|
21
|
|
556
|
use MogileFS::Server; |
|
21
|
|
|
|
|
45
|
|
|
21
|
|
|
|
|
15802
|
|
4
|
|
|
|
|
|
|
require Exporter; |
5
|
|
|
|
|
|
|
our @ISA = qw(Exporter); |
6
|
|
|
|
|
|
|
our @EXPORT_OK = qw(rr_upgrade ALL_GOOD TOO_GOOD TEMP_NO_ANSWER); |
7
|
|
|
|
|
|
|
|
8
|
|
|
|
|
|
|
my $no_answer = bless { temp_fail => 1 }; |
9
|
1
|
|
|
1
|
0
|
9
|
sub TEMP_NO_ANSWER () { $no_answer } |
10
|
|
|
|
|
|
|
my $all_good = bless { all_good => 1 }; |
11
|
8
|
|
|
8
|
0
|
55
|
sub ALL_GOOD () { $all_good } |
12
|
|
|
|
|
|
|
my $too_good = bless { all_good => 1, too_good => 1 }; |
13
|
7
|
|
|
7
|
0
|
36
|
sub TOO_GOOD () { $too_good } |
14
|
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
# upgrades the return values from old-style ReplicationPolicy classes |
16
|
|
|
|
|
|
|
# to MogileFS::ReplicationRequest objects, unless they already are, |
17
|
|
|
|
|
|
|
# in which case they're passed through unchanged. provides peaceful |
18
|
|
|
|
|
|
|
# upgrade path for old plugins. |
19
|
|
|
|
|
|
|
sub rr_upgrade { |
20
|
0
|
|
|
0
|
0
|
0
|
my ($rv) = @_; |
21
|
0
|
0
|
|
|
|
0
|
return $rv if ref $rv; |
22
|
0
|
0
|
|
|
|
0
|
return TEMP_NO_ANSWER if !defined $rv; |
23
|
0
|
0
|
|
|
|
0
|
return ALL_GOOD if !$rv; |
24
|
0
|
|
|
|
|
0
|
return MogileFS::ReplicationRequest->replicate_to($rv); |
25
|
|
|
|
|
|
|
} |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
# for ideal replications |
28
|
|
|
|
|
|
|
sub replicate_to { |
29
|
0
|
|
|
0
|
0
|
0
|
my ($class, @devs) = @_; |
30
|
0
|
0
|
|
|
|
0
|
@devs = map { ref $_ ? $_ : Mgd::device_factory()->get_by_id($_) } @devs; |
|
0
|
|
|
|
|
0
|
|
31
|
0
|
|
|
|
|
0
|
return bless { |
32
|
|
|
|
|
|
|
ideal_next => \@devs, |
33
|
|
|
|
|
|
|
}, $class; |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
sub new { |
37
|
19
|
|
|
19
|
0
|
71
|
my ($class, %opts) = @_; |
38
|
19
|
|
|
|
|
60
|
my $self = bless {}, $class; |
39
|
19
|
|
50
|
|
|
91
|
$self->{ideal_next} = delete $opts{ideal} || []; |
40
|
19
|
|
50
|
|
|
77
|
$self->{desperate_next} = delete $opts{desperate} || []; |
41
|
19
|
50
|
|
|
|
44
|
Carp::croak("unknown args") if %opts; |
42
|
19
|
|
|
|
|
102
|
return $self; |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
|
45
|
|
|
|
|
|
|
############################################################################ |
46
|
|
|
|
|
|
|
|
47
|
|
|
|
|
|
|
sub is_happy { |
48
|
4
|
|
|
4
|
0
|
19
|
my $self = shift; |
49
|
4
|
|
|
|
|
28
|
return $self->{all_good}; |
50
|
|
|
|
|
|
|
} |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
sub too_happy { |
53
|
2
|
|
|
2
|
0
|
3
|
my $self = shift; |
54
|
2
|
|
|
|
|
7
|
return $self->{too_good}; |
55
|
|
|
|
|
|
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub temp_fail { |
58
|
1
|
|
|
1
|
0
|
6
|
my $self = shift; |
59
|
1
|
|
|
|
|
5
|
return $self->{temp_fail}; |
60
|
|
|
|
|
|
|
} |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# returns array of MogileFS::Device objs, in preferred order, one of |
63
|
|
|
|
|
|
|
# which (but not multiple) would satisfy the replication policy |
64
|
|
|
|
|
|
|
# for its next step. at which point the replication policy needs |
65
|
|
|
|
|
|
|
# to be asked again what the next step is. |
66
|
|
|
|
|
|
|
sub copy_to_one_of_ideally { |
67
|
19
|
|
|
19
|
0
|
28
|
my $self = shift; |
68
|
19
|
50
|
|
|
|
21
|
return @{ $self->{ideal_next} || [] }; |
|
19
|
|
|
|
|
103
|
|
69
|
|
|
|
|
|
|
} |
70
|
|
|
|
|
|
|
|
71
|
|
|
|
|
|
|
# like above, but replication policy isn't happy about these choices, |
72
|
|
|
|
|
|
|
# so a reevaluation of this replication decision should be made in the |
73
|
|
|
|
|
|
|
# future, when new disks/hosts might be available. |
74
|
|
|
|
|
|
|
sub copy_to_one_of_desperate { |
75
|
4
|
|
|
4
|
0
|
625
|
my $self = shift; |
76
|
4
|
50
|
|
|
|
6
|
return @{ $self->{desperate_next} || [] }; |
|
4
|
|
|
|
|
24
|
|
77
|
|
|
|
|
|
|
} |
78
|
|
|
|
|
|
|
|
79
|
|
|
|
|
|
|
# for test suite.. |
80
|
|
|
|
|
|
|
sub t_as_string { |
81
|
30
|
|
|
30
|
0
|
139
|
my $self = shift; |
82
|
30
|
100
|
|
|
|
147
|
return "too_good" if $self->{too_good}; |
83
|
24
|
100
|
|
|
|
154
|
return "all_good" if $self->{all_good}; |
84
|
17
|
50
|
|
|
|
39
|
return "temp_fail" if $self->{temp_fail}; |
85
|
17
|
|
|
|
|
18
|
my @devs; |
86
|
17
|
100
|
|
|
|
43
|
if (@devs = $self->copy_to_one_of_ideally) { |
87
|
15
|
|
|
|
|
32
|
return "ideal(" . join(",", sort {$a<=>$b} map { $_->id } @devs) . ")"; |
|
25
|
|
|
|
|
219
|
|
|
34
|
|
|
|
|
170
|
|
88
|
|
|
|
|
|
|
} |
89
|
2
|
50
|
|
|
|
9
|
if (@devs = $self->copy_to_one_of_desperate) { |
90
|
2
|
|
|
|
|
5
|
return "desperate(" . join(",", sort {$a<=>$b} map { $_->id } @devs) . ")"; |
|
1
|
|
|
|
|
14
|
|
|
3
|
|
|
|
|
10
|
|
91
|
|
|
|
|
|
|
} |
92
|
0
|
|
|
|
|
|
die "unknown $self type"; |
93
|
|
|
|
|
|
|
} |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
1; |
96
|
|
|
|
|
|
|
|