[lxc-devel] [lxd/master] exec: report exit code when we got killed by signal

brauner on Github lxc-bot at linuxcontainers.org
Thu Jan 19 22:42:53 UTC 2017


A non-text attachment was scrubbed...
Name: not available
Type: text/x-mailbox
Size: 1839 bytes
Desc: not available
URL: <http://lists.linuxcontainers.org/pipermail/lxc-devel/attachments/20170119/f63792d5/attachment.bin>
-------------- next part --------------
From 3132d618306c3f5349be16d879feca7ccd285020 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner at ubuntu.com>
Date: Thu, 19 Jan 2017 23:25:03 +0100
Subject: [PATCH] exec: report exit code when we got killed by signal

The standard shell convention is to report 128 + n where n := signal that killed
the process. This signal number is usually within a reasonable range so that the
magic 8-bit wall of sound is not breached. Essentially, we now report exit codes
like a standard shell would:

1.
	chb at conventiont|~/source/go/bin
	> ./lxc exec zest1 sleep 100
	chb at conventiont|~/source/go/bin
	> echo $?
	143

caused by sending:

	kill -15 $(pidof sleep 100)

2.
	chb at conventiont|~/source/go/bin
	> ./lxc exec zest1 sleep 100
	chb at conventiont|~/source/go/bin
	> echo $?
	129

caused by sending:

	kill -HUP $(pidof sleep 100)

3.
	chb at conventiont|~/source/go/bin
	> ./lxc exec zest1 sleep 100
	chb at conventiont|~/source/go/bin
	> echo $?
	137

caused by sending:

	kill -KILL $(pidof sleep 100)

This is way more fine-grained than what ssh does and more in line with standard
shell exit codes. Also, this allows us to even report back SIGKILL in the sense
that we can tell the user, "Hey, this was the grim 137 aka the ultimate 9.".

Note that there is a caveat: If a user were to write a program that uses one of
those 128 + n exit codes as exit code than being killed by a signal would be
indistinguishable for him from success. However, the user would face the same
problem running the program in a local shell or otherwise. So I wouldn't count
this as a counter-argument. (Also, there is the fact that these exit codes are
actually reserved.)

Signed-off-by: Christian Brauner <christian.brauner at ubuntu.com>
---
 lxd/container_exec.go | 3 ++-
 lxd/container_lxc.go  | 5 +++++
 lxd/main_forkexec.go  | 9 +++++----
 3 files changed, 12 insertions(+), 5 deletions(-)

diff --git a/lxd/container_exec.go b/lxd/container_exec.go
index ec2f3d7..ba535f5 100644
--- a/lxd/container_exec.go
+++ b/lxd/container_exec.go
@@ -284,7 +284,8 @@ func (s *execWs) Do(op *operation) error {
 		}
 
 		if status.Signaled() {
-			return finisher(-1, nil)
+			// COMMENT(brauner): 128 + n == Fatal error signal "n"
+			return finisher(128+int(status.Signal()), nil)
 		}
 	}
 
diff --git a/lxd/container_lxc.go b/lxd/container_lxc.go
index de2fe14..4ba8031 100644
--- a/lxd/container_lxc.go
+++ b/lxd/container_lxc.go
@@ -4556,6 +4556,11 @@ func (c *containerLXC) Exec(command []string, env map[string]string, stdin *os.F
 			if ok {
 				return status.ExitStatus(), attachedPid, nil
 			}
+
+			if status.Signaled() {
+				// COMMENT(brauner): 128 + n == Fatal error signal "n"
+				return 128 + int(status.Signal()), attachedPid, nil
+			}
 		}
 		return -1, -1, err
 	}
diff --git a/lxd/main_forkexec.go b/lxd/main_forkexec.go
index 9f361de..3492fac 100644
--- a/lxd/main_forkexec.go
+++ b/lxd/main_forkexec.go
@@ -119,12 +119,13 @@ func cmdForkExec(args []string) (int, error) {
 
 	exCode, ok := procState.Sys().(syscall.WaitStatus)
 	if ok {
-		if exCode.Exited() {
-			return exCode.ExitStatus(), nil
+		if exCode.Signaled() {
+			// COMMENT(brauner): 128 + n == Fatal error signal "n"
+			return 128 + int(exCode.Signal()), nil
 		}
 
-		if exCode.Signaled() {
-			return -1, nil
+		if exCode.Exited() {
+			return exCode.ExitStatus(), nil
 		}
 	}
 


More information about the lxc-devel mailing list