Skip to content

Commit

Permalink
lxc exec: Fix exit codes for signaled processes (#14252)
Browse files Browse the repository at this point in the history
With this, processes spawned by `lxc exec` stopped due to being signaled
now return the proper exit code to LXD.

From the [docs](https://pkg.go.dev/os#ProcessState.Sys):

> Sys returns system-dependent exit information about the process.
Convert it to the appropriate underlying type, such as
[syscall.WaitStatus](https://pkg.go.dev/syscall#WaitStatus) on Unix, to
access its contents.
  • Loading branch information
tomponline authored Oct 10, 2024
2 parents dac2b45 + 0a5b448 commit 4ebf245
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 12 deletions.
3 changes: 2 additions & 1 deletion shared/util_linux.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"path/filepath"
"reflect"
"strings"
"syscall"
"time"
"unsafe"

Expand Down Expand Up @@ -397,7 +398,7 @@ func ExitStatus(err error) (int, error) {
// Detect and extract ExitError to check the embedded exit status.
if errors.As(err, &exitErr) {
// If the process was signaled, extract the signal.
status, isWaitStatus := exitErr.Sys().(unix.WaitStatus)
status, isWaitStatus := exitErr.Sys().(syscall.WaitStatus)
if isWaitStatus && status.Signaled() {
return 128 + int(status.Signal()), nil // 128 + n == Fatal error signal "n"
}
Expand Down
28 changes: 17 additions & 11 deletions test/suites/exec.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,25 @@ test_exec_exit_code() {
lxc exec x1 -- invalid-command || exitCode=$?
[ "${exitCode:-0}" -eq 127 ]

# Try disconnecting a container stopping forcefully and gracefully to make sure they differ appropriately.
(sleep 1 && lxc stop -f x1) &
lxc exec x1 -- sleep 10 || exitCode=$?
# Signaling the process spawned by lxc exec and checking its exit code.
# Simulates what can happen if the container stops in the middle of lxc exec.
(sleep 5 && lxc exec x1 -- killall -s SIGTERM sleep) &
lxc exec x1 -- sleep 60 || exitCode=$?
[ "${exitCode:-0}" -eq 143 ] # 128 + 15(SIGTERM)

(sleep 5 && lxc exec x1 -- killall -s SIGHUP sleep) &
lxc exec x1 -- sleep 60 || exitCode=$?
[ "${exitCode:-0}" -eq 129 ] # 128 + 1(SIGHUP)

(sleep 5 && lxc exec x1 -- killall -s SIGKILL sleep) &
lxc exec x1 -- sleep 60 || exitCode=$?
[ "${exitCode:-0}" -eq 137 ] # 128 + 9(SIGKILL)

# Try disconnecting a container stopping forcefully.
(sleep 5 && lxc stop -f x1) &
lxc exec x1 -- sleep 60 || exitCode=$?
[ "${exitCode:-0}" -eq 137 ]

wait $!
lxc start x1
sleep 2
(sleep 1 && lxc stop x1) &
lxc exec x1 -- sleep 10 || exitCode=$?
# Both 129 and 143 have been seen and both make sense here.
[ "${exitCode:-0}" -eq 129 ] || [ "${exitCode:-0}" -eq 143 ]

wait $!
lxc delete --force x1
}

0 comments on commit 4ebf245

Please sign in to comment.