This change improves the reporting of container stop reason. Before this change if the init process of lxc container has crashed or returned non zero status, the domain state listeners would be notified that a domain has stopped due to normal shutdown. This maps to VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN and is exactly the same as the stop reason reported when the init process ends without errors. After this patch, when the container init process exits with a non zero status (or crashes) the reported stop reason will be VIR_DOMAIN_EVENT_STOPPED_CRASHED. --- src/lxc/lxc_controller.c | 16 ++++++++++++++-- src/lxc/lxc_monitor_protocol.x | 3 ++- src/lxc/lxc_process.c | 3 +++ src/lxc_monitor_protocol-structs | 1 + 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/src/lxc/lxc_controller.c b/src/lxc/lxc_controller.c index 2d220eb..e8ff1c4 100644 --- a/src/lxc/lxc_controller.c +++ b/src/lxc/lxc_controller.c @@ -821,7 +821,7 @@ static int lxcControllerClearCapabilities(void) static bool wantReboot = false; static virMutex lock = VIR_MUTEX_INITIALIZER; - +static int initProcessExitCode = 0; static void virLXCControllerSignalChildIO(virNetServerPtr server, siginfo_t *info ATTRIBUTE_UNUSED, @@ -834,6 +834,11 @@ static void virLXCControllerSignalChildIO(virNetServerPtr server, ret = waitpid(-1, &status, WNOHANG); VIR_DEBUG("Got sig child %d vs %lld", ret, (unsigned long long)ctrl->initpid); if (ret == ctrl->initpid) { + VIR_DEBUG("Init process waitpid status 0x%x", status); + if (WIFEXITED(status)) { + initProcessExitCode = WEXITSTATUS(status); + VIR_INFO("Init process exited. Exit code = %d", initProcessExitCode); + } virNetServerQuit(server); virMutexLock(&lock); if (WIFSIGNALED(status) && @@ -841,6 +846,10 @@ static void virLXCControllerSignalChildIO(virNetServerPtr server, VIR_DEBUG("Status indicates reboot"); wantReboot = true; } + else if (WIFSIGNALED(status)) { + initProcessExitCode = 0x80 + WTERMSIG(status); + VIR_INFO("Init process received a signal %d. Exit code = %d", WTERMSIG(status), initProcessExitCode); + } virMutexUnlock(&lock); } } @@ -2080,7 +2089,10 @@ virLXCControllerEventSendExit(virLXCControllerPtr ctrl, memset(&msg, 0, sizeof(msg)); switch (exitstatus) { case 0: - msg.status = VIR_LXC_MONITOR_EXIT_STATUS_SHUTDOWN; + if (initProcessExitCode == 0) + msg.status = VIR_LXC_MONITOR_EXIT_STATUS_SHUTDOWN; + else + msg.status = VIR_LXC_MONITOR_EXIT_STATUS_INIT_PROCESS_ERROR; break; case 1: msg.status = VIR_LXC_MONITOR_EXIT_STATUS_REBOOT; diff --git a/src/lxc/lxc_monitor_protocol.x b/src/lxc/lxc_monitor_protocol.x index 0926e26..beb2272 100644 --- a/src/lxc/lxc_monitor_protocol.x +++ b/src/lxc/lxc_monitor_protocol.x @@ -7,7 +7,8 @@ enum virLXCMonitorExitStatus { VIR_LXC_MONITOR_EXIT_STATUS_ERROR, VIR_LXC_MONITOR_EXIT_STATUS_SHUTDOWN, - VIR_LXC_MONITOR_EXIT_STATUS_REBOOT + VIR_LXC_MONITOR_EXIT_STATUS_REBOOT, + VIR_LXC_MONITOR_EXIT_STATUS_INIT_PROCESS_ERROR }; struct virLXCMonitorExitEventMsg { diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c index 3353dc1..fb65919 100644 --- a/src/lxc/lxc_process.c +++ b/src/lxc/lxc_process.c @@ -553,6 +553,9 @@ static void virLXCProcessMonitorExitNotify(virLXCMonitorPtr mon ATTRIBUTE_UNUSED case VIR_LXC_MONITOR_EXIT_STATUS_SHUTDOWN: priv->stopReason = VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN; break; + case VIR_LXC_MONITOR_EXIT_STATUS_INIT_PROCESS_ERROR: + priv->stopReason = VIR_DOMAIN_EVENT_STOPPED_CRASHED; + break; case VIR_LXC_MONITOR_EXIT_STATUS_ERROR: priv->stopReason = VIR_DOMAIN_EVENT_STOPPED_FAILED; break; diff --git a/src/lxc_monitor_protocol-structs b/src/lxc_monitor_protocol-structs index da72ec0..b3877d3 100644 --- a/src/lxc_monitor_protocol-structs +++ b/src/lxc_monitor_protocol-structs @@ -3,6 +3,7 @@ enum virLXCMonitorExitStatus { VIR_LXC_MONITOR_EXIT_STATUS_ERROR = 0, VIR_LXC_MONITOR_EXIT_STATUS_SHUTDOWN = 1, VIR_LXC_MONITOR_EXIT_STATUS_REBOOT = 2, + VIR_LXC_MONITOR_EXIT_STATUS_INIT_PROCESS_ERROR = 3, }; struct virLXCMonitorExitEventMsg { enum virLXCMonitorExitStatus status; -- 1.9.3 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list