File Coverage

lib/Ubic/Daemon/PidState.pm
Criterion Covered Total %
statement 54 81 66.6
branch 15 40 37.5
condition 7 12 58.3
subroutine 14 16 87.5
pod 7 7 100.0
total 97 156 62.1


line stmt bran cond sub pod time code
1             package Ubic::Daemon::PidState;
2             $Ubic::Daemon::PidState::VERSION = '1.59';
3 34     34   117 use strict;
  34         38  
  34         782  
4 34     34   110 use warnings;
  34         47  
  34         748  
5              
6             # ABSTRACT: internal object representing process info stored on disk
7              
8              
9 34     34   137 use Params::Validate qw(:all);
  34         36  
  34         4111  
10 34     34   136 use Ubic::Lockf;
  34         37  
  34         1242  
11 34     34   3351 use Ubic::AtomicFile;
  34         46  
  34         1473  
12              
13             use overload '""' => sub {
14 0     0   0 my $self = shift;
15 0         0 return $self->{dir};
16 34     34   133 };
  34         31  
  34         312  
17              
18             sub new {
19 923     923 1 1422 my $class = shift;
20 923         10207 my ($dir) = validate_pos(@_, { type => SCALAR });
21 923         5591 return bless { dir => $dir } => $class;
22             }
23              
24             sub is_empty {
25 763     763 1 3779 my ($self) = validate_pos(@_, 1);
26 763         2787 my $dir = $self->{dir};
27              
28 763 50 66     17125 return if not -d $dir and -s $dir; # old-style pidfile
29 763 100 100     13764 return if -d $dir and -s "$dir/pid"; # non-empty new-style pidfile
30              
31 340         4316 return 1;
32             }
33              
34             sub init {
35 160     160 1 857 my ($self) = validate_pos(@_, 1);
36 160         402 my $dir = $self->{dir};
37 160 50 66     1481 if (-e $dir and not -d $dir) {
38 0         0 print "converting $dir to dir\n";
39 0 0       0 unlink $dir or die "Can't unlink $dir: $!";
40             }
41 160 100       943 unless (-d $dir) {
42 110 50       5614 mkdir $dir or die "Can't create $dir: $!";
43             }
44              
45             }
46              
47             sub read {
48 423     423 1 2584 my ($self) = validate_pos(@_, 1);
49              
50 423         971 my $dir = $self->{dir};
51              
52 423         503 my $content;
53             my $parse_content = sub {
54 423 50   423   4423 if ($content =~ /\A pid \s+ (\d+) \n guid \s+ (.+) (?: \n daemon \s+ (\d+) )? \Z/x) {
    0          
55             # new format
56 423         10374 return { pid => $1, guid => $2, daemon => $3, format => 'new' };
57             }
58             elsif ($content eq '') {
59             # file is empty, probably lost after reboot - we didn't sync() pidfile to disk in old versions
60 0         0 return;
61             }
62             else {
63             # We consider invalid pidfile content as the fatal, unrecoverable error.
64             # Please report all cases of invalid pidfile as critical issues.
65             #
66             # (This policy will be changed if ubic become popular enough for this to annoy enough people,
67             # but collecting bugreports about weird stuff happening is more important by now.)
68 0         0 die "invalid pidfile content in pidfile $dir";
69             }
70 423         2410 };
71 423 50       3845 if (-d $dir) {
72             # pidfile as dir
73 423         10138 my $open_success = open my $fh, '<', "$dir/pid";
74 423 50       945 unless ($open_success) {
75 0 0   20   0 if ($!{ENOENT}) {
  20         14645  
  20         18064  
  20         7926  
76 0         0 return; # pidfile not found, daemon is not running
77             }
78             else {
79 0         0 die "Failed to open '$dir/pid': $!";
80             }
81             }
82 423         6722 $content = join '', <$fh>;
83 423         975 return $parse_content->();
84             }
85             else {
86             # deprecated - single pidfile without dir
87 0 0 0     0 if (-f $dir and not -s $dir) {
88 0         0 return; # empty pidfile - old way to stop services
89             }
90 0 0       0 open my $fh, '<', $dir or die "Failed to open $dir: $!";
91 0         0 $content = join '', <$fh>;
92 0 0       0 if ($content =~ /\A (\d+) \Z/x) {
93             # old format
94 0         0 return { pid => $1, format => 'old' };
95             }
96             else {
97 0         0 return $parse_content->();
98             }
99             }
100             }
101              
102             sub lock {
103 368     368 1 3766 my ($self, $timeout) = validate_pos(@_, 1, { type => SCALAR, default => 0 });
104              
105 368         1239 my $dir = $self->{dir};
106 368 50       3064 if (-d $dir) {
107             # new-style pidfile
108 368         3055 return lockf("$dir/lock", { timeout => $timeout });
109             }
110             else {
111 0         0 return lockf($dir, { blocking => 0 });
112             }
113             }
114              
115             sub remove {
116 23     23 1 208 my ($self) = validate_pos(@_, 1);
117 23         82 my $dir = $self->{dir};
118              
119 23 50       314 if (-d $dir) {
120 23 100       423 if (-e "$dir/pid") {
121 5 50       430 unlink "$dir/pid" or die "Can't remove $dir/pid: $!";
122             }
123             }
124             else {
125 0 0       0 unlink $dir or die "Can't remove $dir: $!";
126             }
127             }
128              
129             sub write {
130 0     0 1 0 my $self = shift;
131 0         0 my $dir = $self->{dir};
132 0 0       0 unless (-d $dir) {
133 0         0 die "piddir $dir not initialized";
134             }
135 0         0 my $params = validate(@_, {
136             pid => 1,
137             guid => 1,
138             });
139              
140 0         0 my ($pid, $guid) = @$params{qw/ pid guid /};
141 0         0 my $self_pid = $$;
142              
143 0         0 my $content =
144             "pid $self_pid\n".
145             "guid $guid\n".
146             "daemon $pid\n";
147 0         0 Ubic::AtomicFile::store( $content => "$dir/pid" );
148             }
149              
150              
151             1;
152              
153             __END__