1
0
mirror of /repos/baseimage-docker.git synced 2025-12-30 08:01:31 +01:00

Fixed various process waiting issues in my_init.

Closes GH-27. Closes GH-82. Closes GH-83.
Thanks to André Luiz dos Santos and Paul Annesley.
This commit is contained in:
Hongli Lai (Phusion) 2014-06-17 14:35:05 +02:00
parent c431f2d151
commit 5806f51ea3
No known key found for this signature in database
GPG Key ID: 2AF96EB85EF4DA0D
2 changed files with 29 additions and 9 deletions

View File

@ -1,5 +1,6 @@
## 0.9.11 (not yet released)
* Fixed various process waiting issues in `my_init`. Closes GH-27, GH-82 and GH-83. Thanks to André Luiz dos Santos and Paul Annesley.
* The `ca-certificates` package is now installed by default. This is because we include `apt-transport-https`, but Ubuntu 14.04 no longer installs `ca-certificates` by default anymore. Closes GH-73.
* `add-apt-repository` is now installed by default. Closes GH-74.
* Various minor fixes thanks to yebyen and John Eckhart.

View File

@ -11,6 +11,8 @@ LOG_LEVEL_DEBUG = 3
log_level = None
terminated_child_processes = {}
class AlarmException(Exception):
pass
@ -95,19 +97,36 @@ def shquote(s):
# the string $'b is then quoted as '$'"'"'b'
return "'" + s.replace("'", "'\"'\"'") + "'"
# Waits for the child process with the given PID, while at the same time
# reaping any other child processes that have exited (e.g. adopted child
# processes that have terminated).
def waitpid_reap_other_children(pid):
global terminated_child_processes
status = terminated_child_processes.get(pid)
if status:
# A previous call to waitpid_reap_other_children(),
# with an argument not equal to the current argument,
# already waited for this process. Return the status
# that was obtained back then.
del terminated_child_processes[pid]
return status
done = False
status = None
try:
this_pid, status = os.waitpid(pid, os.WNOHANG)
except OSError as e:
if e.errno == errno.ECHILD or e.errno == errno.ESRCH:
return None
else:
raise
while not done:
this_pid, status = os.waitpid(-1, 0)
done = this_pid == pid
try:
this_pid, status = os.waitpid(-1, 0)
if this_pid == pid:
done = True
else:
# Save status for later.
terminated_child_processes[this_pid] = status
except OSError as e:
if e.errno == errno.ECHILD or e.errno == errno.ESRCH:
return None
else:
raise
return status
def stop_child_process(name, pid, signo = signal.SIGTERM, time_limit = KILL_PROCESS_TIMEOUT):