Add SIGCHLD handler to pause container

This allows pause to reap zombies in the upcoming Shared PID namespace
(#1615). Uses the better defined sigaction() instead of signal() for all
signals both for consistency (SIGCHLD handler avoids SA_RESTART) and to
avoid the implicit signal()->sigaction() translation of various libc
versions.

Also makes warnings errors and includes a tool to make orphaned zombies
for manual testing.
This commit is contained in:
Lee Verberne
2016-11-14 11:30:33 +00:00
parent 15059e6a5b
commit 81d27aa239
3 changed files with 64 additions and 5 deletions

View File

@@ -12,7 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
.PHONY: all push push-legacy container clean
.PHONY: all push push-legacy container clean orphan
REGISTRY ?= gcr.io/google_containers
IMAGE = $(REGISTRY)/pause-$(ARCH)
@@ -25,7 +25,7 @@ ARCH ?= amd64
ALL_ARCH = amd64 arm arm64 ppc64le s390x
CFLAGS = -Os -Wall -static
CFLAGS = -Os -Wall -Werror -static
KUBE_CROSS_IMAGE ?= gcr.io/google_containers/kube-cross
KUBE_CROSS_VERSION ?= $(shell cat ../build-image/cross/VERSION)
@@ -97,5 +97,16 @@ ifeq ($(ARCH),amd64)
endif
touch $@
# Useful for testing, not automatically included in container image
orphan: bin/orphan-$(ARCH)
bin/orphan-$(ARCH): orphan.c
mkdir -p bin
docker run -u $$(id -u):$$(id -g) -v $$(pwd):/build \
$(KUBE_CROSS_IMAGE):$(KUBE_CROSS_VERSION) \
/bin/bash -c "\
cd /build && \
$(TRIPLE)-gcc $(CFLAGS) -o $@ $^ && \
$(TRIPLE)-strip $@"
clean:
rm -rf .container-* .push-* bin/

View File

@@ -17,6 +17,8 @@ limitations under the License.
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
static void sigdown(int signo) {
@@ -24,12 +26,23 @@ static void sigdown(int signo) {
exit(0);
}
static void sigreap(int signo) {
while (waitpid(-1, NULL, WNOHANG) > 0);
}
int main() {
if (signal(SIGINT, sigdown) == SIG_ERR)
if (getpid() != 1) {
fprintf(stderr, "Warning: pause should be the first process in a pod\n");
}
if (sigaction(SIGINT, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
return 1;
if (signal(SIGTERM, sigdown) == SIG_ERR)
if (sigaction(SIGTERM, &(struct sigaction){.sa_handler = sigdown}, NULL) < 0)
return 2;
signal(SIGKILL, sigdown);
if (sigaction(SIGCHLD, &(struct sigaction){.sa_handler = sigreap, .sa_flags = SA_NOCLDSTOP}, NULL) < 0)
return 3;
sigaction(SIGKILL, &(struct sigaction){.sa_handler = sigdown}, NULL);
for (;;) pause();
fprintf(stderr, "error: infinite loop terminated\n");
return 42;