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
Show replies by date