File Coverage

blib/lib/Cluster/Init/Process.pm
Criterion Covered Total %
statement 19 21 90.4
branch n/a
condition n/a
subroutine 7 7 100.0
pod n/a
total 26 28 92.8


line stmt bran cond sub pod time code
1             package Cluster::Init::Process;
2 2     2   415745 use strict;
  2         5  
  2         87  
3 2     2   14 use warnings;
  2         3  
  2         80  
4 2     2   959 use Data::Dump qw(dump);
  2         10904  
  2         172  
5 2     2   1290 use Carp::Assert;
  2         1423  
  2         18  
6 2     2   1385 use Time::HiRes qw(time);
  2         1969  
  2         12  
7 2     2   2246 use POSIX qw(:signal_h :errno_h :sys_wait_h);
  2         16396  
  2         17  
8             my $debug=$ENV{DEBUG} || 0;
9 2     2   5651 use Cluster::Init::Util qw(debug NOOP);
  0            
  0            
10              
11             use Cluster::Init::DFA::Process qw(:constants);
12             use base qw(Cluster::Init::DFA::Process Cluster::Init::Util);
13              
14             sub init
15             {
16             my $self = shift;
17             # $self->Cluster::Init::Util::init;
18             # $self->fields qw(pid);
19             $self->state(CONFIGURED);
20             # $self->idle(IDLE);
21             return $self;
22             }
23              
24             sub start
25             {
26             my $self=shift;
27             $self->event(START);
28             }
29              
30             sub stop
31             {
32             my $self=shift;
33             $self->event(STOP);
34             }
35              
36             sub XXXstate
37             {
38             my ($self,$state)=@_;
39             my $oldstate=$self->SUPER::state || "";
40             my $newstate=$self->SUPER::state($state);
41             kill 'USR2', $$ if $oldstate ne $newstate;
42             return $newstate;
43             }
44              
45             sub error
46             {
47             my ($self,$data)=@_;
48             return ($self,$data) unless $self->{'log'};
49             return ($self,$data) unless $data->{'msg'};
50             open(LOG,">>$self->{'log'}") || die $!;
51             print LOG $data->{msg};
52             close LOG;
53             return ($self,$data);
54             }
55              
56             sub ckmode
57             {
58             my ($self,$data)=@_;
59             for ($self->{mode})
60             {
61             /^wait$/ && (return(WAIT,$data));
62             /^respawn$/ && (return(RESPAWN,$data));
63             /^once$/ && (return(ONCE,$data));
64             /^test$/ && (return(TEST,$data));
65             /^off$/ && (return(OFF,$data));
66             die "invalid mode: $_";
67             }
68             }
69              
70             sub ckfreq
71             {
72             my ($self,$data)=@_;
73             my $last = $self->{ckfreq}{'last'} || 0;
74             my $hits = $self->{ckfreq}{'hits'} || 0;
75             my $elapsed = time() - $last;
76             $hits++ if $elapsed < 1;
77             $hits-- if $elapsed > 1;
78             $hits = 0 if $hits < 0;
79             debug $self->{tag}." $hits $elapsed";
80             $self->{ckfreq}{'last'}=time();
81             $self->{ckfreq}{'hits'}=$hits;
82             if ($hits > 5)
83             {
84             warn $self->{tag}." respawning too rapidly: sleeping 60 seconds\n";
85             $self->timer(CONTINUE,{at=>time+60},$data);
86             return(TOO_RAPID,$data);
87             }
88             return(CONTINUE,$data);
89             }
90              
91             sub xeq
92             {
93             my ($self,$data)=@_;
94             my $cmd=$self->{cmd};
95             my $tag=$self->{tag};
96             $self->sigevent(CHLD,{signal=>'CHLD'}) unless $self->{xeqs};
97             $self->{xeqs}++;
98             my $pid = fork();
99             unless (defined($pid))
100             {
101             $data->{msg}=$!;
102             return(EXECFAILED,$data);
103             }
104             unless ($pid)
105             {
106             debug "$tag exec $cmd";
107             exec $cmd;
108             die $!;
109             }
110             debug "$tag forked $pid for $cmd";
111             $self->{pid}=$pid;
112             return(STARTED,$data);
113             }
114              
115             sub ckpid
116             {
117             my ($self,$data)=@_;
118             my $pid = $self->{pid};
119             debug "checking $pid ".$self->{tag};
120             affirm { $pid };
121             my $waitpid = waitpid($pid, &WNOHANG);
122             my $rc = $?;
123             unless (kill(0,$pid) == 0)
124             {
125             # still running
126             debug $self->{tag}." $pid still running";
127             return(PROCRUNNING,$data);
128             }
129             # $pid exited
130             debug "$pid returned $rc";
131             $self->{rc}=$rc unless $rc == -1;
132             return(EXITED,$data);
133             }
134              
135             sub ckrc
136             {
137             my ($self,$data)=@_;
138             debug $self->{pid}." returned ".$self->{rc};
139             return(RC_NONZERO,$data) unless defined $self->{rc};
140             return(RC_NONZERO,$data) if $self->{rc};
141             return(RC_ZERO,$data);
142             }
143              
144             sub STOPPING_enter
145             {
146             my ($self,$oldstate,$newstate,$action,$data)=@_;
147             debug __PACKAGE__.": newstate=>'$newstate', action=>'".$newstate."_enter'\n";
148             my $tag = $self->{tag};
149             my $pid = $self->{pid};
150             debug "stopping $tag $pid";
151             $self->{sig}=2;
152             $self->{timeout}=0;
153             $self->timer(TIMEOUT,{at=>time+$self->{timeout}});
154             }
155              
156             sub killproc
157             {
158             my ($self,$data)=@_;
159             my $tag = $self->{tag};
160             my $pid = $self->{pid};
161             my $sig = $self->{sig};
162             debug "kill $sig,$pid ($tag)";
163             kill($sig,$pid);
164             $self->{sig}=9 if $sig == 15;
165             $self->{sig}=15 if $sig == 2;
166             $self->{timeout}+=5;
167             $self->timer(TIMEOUT,{at=>time+$self->{timeout}});
168             return(NOOP,$data);
169             }
170              
171             sub haslevel
172             {
173             my ($self,$cklevel)=@_;
174             my $level=$self->{level};
175             my @level;
176             if ($level eq $cklevel)
177             {
178             return $level;
179             }
180             if ($level =~/,/)
181             {
182             @level = split(',',$level);
183             }
184             else
185             {
186             @level = split('',$level);
187             }
188             return grep /^$cklevel$/, @level;
189             }
190              
191             sub done
192             {
193             my ($self,$state)=@_;
194             return 1 if $self->state eq DONE;
195             return 0;
196             }
197              
198             sub pass
199             {
200             my ($self,$state)=@_;
201             return 1 if $self->state eq PASS;
202             return 0;
203             }
204              
205             sub fail
206             {
207             my ($self,$state)=@_;
208             return 1 if $self->state eq FAIL;
209             return 0;
210             }
211              
212             sub configured
213             {
214             my ($self,$state)=@_;
215             return 1 if $self->state eq CONFIGURED;
216             return 0;
217             }
218              
219             sub running
220             {
221             my ($self,$state)=@_;
222             return 1 if $self->state eq SETUP;
223             return 1 if $self->state eq RUNFG;
224             return 1 if $self->state eq RUNBG;
225             return 1 if $self->state eq RUNNING;
226             return 1 if $self->state eq RUNTEST;
227             return 1 if $self->state eq TESTING;
228             return 1 if $self->state eq PAUSING;
229             return 1 if $self->state eq STOPPING;
230             return 0;
231             }
232              
233             sub ran
234             {
235             my ($self,$state)=@_;
236             return 1 if $self->done;
237             return 1 if $self->pass;
238             return 1 if $self->fail;
239             return 0;
240             }
241              
242             1;