]>
Commit | Line | Data |
---|---|---|
40daaeb8 | 1 | /* |
77b1029d | 2 | * Copyright (C) 1996-2020 The Squid Software Foundation and contributors |
40daaeb8 | 3 | * |
bbc27441 AJ |
4 | * Squid software is distributed under GPLv2+ license and includes |
5 | * contributions from numerous individuals and organizations. | |
6 | * Please see the COPYING and CONTRIBUTORS files for details. | |
40daaeb8 AR |
7 | */ |
8 | ||
bbc27441 AJ |
9 | /* DEBUG: section 54 Interprocess Communication */ |
10 | ||
f7f3304a | 11 | #include "squid.h" |
ca4b9ee6 | 12 | #include "globals.h" |
40daaeb8 | 13 | #include "ipc/Kid.h" |
00e2479d | 14 | #include "SquidConfig.h" |
40daaeb8 | 15 | |
074d6a40 | 16 | #include <ctime> |
541b39f3 AJ |
17 | #if HAVE_SYS_WAIT_H |
18 | #include <sys/wait.h> | |
19 | #endif | |
20 | ||
095ec2b1 AR |
21 | int TheProcessKind = pkOther; |
22 | ||
28bca1f7 | 23 | Kid::Kid() |
40daaeb8 AR |
24 | { |
25 | } | |
26 | ||
28bca1f7 EB |
27 | Kid::Kid(const char *aRole, const int anId): |
28 | processRole(aRole), | |
29 | processId(anId) | |
40daaeb8 AR |
30 | { |
31 | } | |
32 | ||
33 | /// called when this kid got started, records PID | |
34 | void Kid::start(pid_t cpid) | |
35 | { | |
36 | assert(!running()); | |
37 | assert(cpid > 0); | |
38 | ||
39 | isRunning = true; | |
00e2479d | 40 | stopTime = 0; |
40daaeb8 | 41 | pid = cpid; |
00e2479d | 42 | startTime = squid_curtime; |
40daaeb8 AR |
43 | } |
44 | ||
45 | /// called when kid terminates, sets exiting status | |
dbf55289 CT |
46 | void |
47 | Kid::stop(PidStatus const theExitStatus) | |
40daaeb8 AR |
48 | { |
49 | assert(running()); | |
50 | assert(startTime != 0); | |
51 | ||
52 | isRunning = false; | |
00e2479d AR |
53 | stopTime = squid_curtime; |
54 | status = theExitStatus; | |
40daaeb8 | 55 | |
00e2479d | 56 | if ((stopTime - startTime) < fastFailureTimeLimit) |
d7ae3534 | 57 | ++badFailures; |
40daaeb8 AR |
58 | else |
59 | badFailures = 0; // the failures are not "frequent" [any more] | |
60 | ||
00e2479d AR |
61 | reportStopped(); // after all state changes |
62 | } | |
63 | ||
64 | /// describes a recently stopped kid | |
65 | void | |
66 | Kid::reportStopped() const | |
67 | { | |
68 | if (calledExit()) { | |
69 | syslog(LOG_NOTICE, | |
70 | "Squid Parent: %s process %d exited with status %d", | |
28bca1f7 | 71 | gist().c_str(), pid, exitStatus()); |
00e2479d AR |
72 | } else if (signaled()) { |
73 | syslog(LOG_NOTICE, | |
74 | "Squid Parent: %s process %d exited due to signal %d with status %d", | |
28bca1f7 | 75 | gist().c_str(), pid, termSignal(), exitStatus()); |
00e2479d AR |
76 | } else { |
77 | syslog(LOG_NOTICE, "Squid Parent: %s process %d exited", | |
28bca1f7 | 78 | gist().c_str(), pid); |
00e2479d AR |
79 | } |
80 | ||
81 | if (hopeless() && Config.hopelessKidRevivalDelay) { | |
82 | syslog(LOG_NOTICE, "Squid Parent: %s process %d will not be restarted for %ld " | |
83 | "seconds due to repeated, frequent failures", | |
28bca1f7 | 84 | gist().c_str(), |
5ef3cbbd AR |
85 | pid, |
86 | static_cast<long int>(Config.hopelessKidRevivalDelay)); | |
00e2479d | 87 | } |
40daaeb8 AR |
88 | } |
89 | ||
90 | /// returns true if tracking of kid is stopped | |
91 | bool Kid::running() const | |
92 | { | |
93 | return isRunning; | |
94 | } | |
95 | ||
ca4b9ee6 DK |
96 | /// returns true if master process should restart this kid |
97 | bool Kid::shouldRestart() const | |
98 | { | |
99 | return !(running() || | |
100 | exitedHappy() || | |
101 | hopeless() || | |
102 | shutting_down || | |
103 | signaled(SIGKILL) || // squid -k kill | |
104 | signaled(SIGINT) || // unexpected forced shutdown | |
105 | signaled(SIGTERM)); // unexpected forced shutdown | |
106 | } | |
107 | ||
40daaeb8 AR |
108 | /// returns current pid for a running kid and last pid for a stopped kid |
109 | pid_t Kid::getPid() const | |
110 | { | |
111 | assert(pid > 0); | |
112 | return pid; | |
113 | } | |
114 | ||
115 | /// whether the failures are "repeated and frequent" | |
116 | bool Kid::hopeless() const | |
117 | { | |
118 | return badFailures > badFailureLimit; | |
119 | } | |
120 | ||
121 | /// returns true if the process terminated normally | |
122 | bool Kid::calledExit() const | |
123 | { | |
124 | return (pid > 0) && !running() && WIFEXITED(status); | |
125 | } | |
126 | ||
127 | /// returns the exit status of the process | |
128 | int Kid::exitStatus() const | |
129 | { | |
130 | return WEXITSTATUS(status); | |
131 | } | |
132 | ||
133 | /// whether the process exited with a given exit status code | |
134 | bool Kid::calledExit(int code) const | |
135 | { | |
136 | return calledExit() && (exitStatus() == code); | |
137 | } | |
138 | ||
139 | /// whether the process exited with code 0 | |
140 | bool Kid::exitedHappy() const | |
141 | { | |
142 | return calledExit(0); | |
143 | } | |
144 | ||
145 | /// returns true if the kid was terminated by a signal | |
146 | bool Kid::signaled() const | |
147 | { | |
148 | return (pid > 0) && !running() && WIFSIGNALED(status); | |
149 | } | |
150 | ||
151 | /// returns the number of the signal that caused the kid to terminate | |
152 | int Kid::termSignal() const | |
153 | { | |
154 | return WTERMSIG(status); | |
155 | } | |
156 | ||
157 | /// whether the process was terminated by a given signal | |
158 | bool Kid::signaled(int sgnl) const | |
159 | { | |
160 | return signaled() && (termSignal() == sgnl); | |
161 | } | |
162 | ||
163 | /// returns kid name | |
28bca1f7 | 164 | SBuf Kid::processName() const |
40daaeb8 | 165 | { |
28bca1f7 EB |
166 | SBuf name("("); |
167 | name.append(gist()); | |
168 | name.append(")"); | |
169 | return name; | |
170 | } | |
171 | ||
172 | SBuf Kid::gist() const | |
173 | { | |
174 | SBuf name(processRole); | |
175 | name.appendf("-%d", processId); | |
176 | return name; | |
40daaeb8 | 177 | } |
f53969cc | 178 | |
00e2479d AR |
179 | time_t |
180 | Kid::deathDuration() const | |
181 | { | |
182 | return squid_curtime > stopTime ? squid_curtime - stopTime : 0; | |
183 | } | |
184 |