[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[Libvir] [PATCH] lxc: shutdown and destroy domain



This patch contains the shutdown and destroy domain support for Linux Containers.

A shutdown of the container is requested by sending a SIGINT to the container
root process.
A container is destroyed by sending a SIGKILL to the container root process.
When this process exits, it takes all container child processes with it.

Thanks!

-- 
Best Regards,
Dave Leskovec
IBM Linux Technology Center
Open Virtualization

---
 src/lxc_container.c |   19 ++++++++++++
 src/lxc_driver.c    |   77 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 93 insertions(+), 3 deletions(-)

Index: b/src/lxc_driver.c
===================================================================
--- a/src/lxc_driver.c	2008-03-24 16:46:48.000000000 -0700
+++ b/src/lxc_driver.c	2008-03-24 17:16:38.000000000 -0700
@@ -583,6 +583,79 @@
     return dom;
 }
 
+static int lxcDomainShutdown(virDomainPtr dom)
+{
+    int rc = -1;
+    lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
+    lxc_vm_t *vm = lxcFindVMByID(driver, dom->id);
+
+    if (!vm) {
+        lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
+                 _("no domain with id %d"), dom->id);
+        goto error_out;
+    }
+
+    vm->state = VIR_DOMAIN_SHUTDOWN;
+
+    if (0 > (kill(vm->def->id, SIGINT))) {
+        if (ESRCH != errno) {
+            lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+                     _("sending SIGTERM failed: %s"), strerror(errno));
+
+            vm->state = VIR_DOMAIN_RUNNING;
+
+            goto error_out;
+        }
+    }
+
+    rc = 0;
+
+error_out:
+    return rc;
+}
+
+static int lxcDomainDestroy(virDomainPtr dom)
+{
+    int rc = -1;
+    lxc_driver_t *driver = (lxc_driver_t*)dom->conn->privateData;
+    lxc_vm_t *vm = lxcFindVMByID(driver, dom->id);
+    int childStatus;
+
+    if (!vm) {
+        lxcError(dom->conn, dom, VIR_ERR_INVALID_DOMAIN,
+                 _("no domain with id %d"), dom->id);
+        goto error_out;
+    }
+
+    vm->state = VIR_DOMAIN_SHUTDOWN;
+
+    if (0 > (kill(vm->def->id, SIGKILL))) {
+        if (ESRCH != errno) {
+            lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+                     _("sending SIGKILL failed: %s"), strerror(errno));
+
+            vm->state = VIR_DOMAIN_RUNNING;
+
+            goto error_out;
+        }
+    }
+
+    waitpid(vm->def->id, &childStatus, 0);
+    rc = WEXITSTATUS(childStatus);
+    DEBUG("container exited with rc: %d", rc);
+
+    vm->state = VIR_DOMAIN_SHUTOFF;
+    vm->pid = -1;
+    vm->def->id = -1;
+    driver->nactivevms--;
+    driver->ninactivevms++;
+
+    rc = 0;
+
+error_out:
+    return rc;
+}
+
 static int lxcStartup(void)
 {
     lxc_driver = calloc(1, sizeof(lxc_driver_t));
@@ -672,9 +745,9 @@
     lxcDomainLookupByName, /* domainLookupByName */
     NULL, /* domainSuspend */
     NULL, /* domainResume */
-    NULL, /* domainShutdown */
+    lxcDomainShutdown, /* domainShutdown */
     NULL, /* domainReboot */
-    NULL, /* domainDestroy */
+    lxcDomainDestroy, /* domainDestroy */
     lxcGetOSType, /* domainGetOSType */
     NULL, /* domainGetMaxMemory */
     NULL, /* domainSetMaxMemory */
Index: b/src/lxc_container.c
===================================================================
--- a/src/lxc_container.c	2008-03-24 16:28:47.000000000 -0700
+++ b/src/lxc_container.c	2008-03-24 16:53:45.000000000 -0700
@@ -222,6 +222,14 @@
 
 }
 
+static void lxcExecSigintHandler(int sig ATTRIBUTE_UNUSED,
+                                 siginfo_t *signalInfo,
+                                 void *context ATTRIBUTE_UNUSED)
+{
+    DEBUG("container received SIGINT from %d", signalInfo->si_pid);
+    kill(SIGINT, initPid);
+}
+
 static int lxcExecWithTty(lxc_vm_t *vm)
 {
     int rc = -1;
@@ -241,7 +249,16 @@
     sigAction.sa_mask = sigMask;
     sigAction.sa_flags = SA_SIGINFO;
     if (0 != sigaction(SIGCHLD, &sigAction, NULL)) {
-        DEBUG("sigaction failed: %s\n", strerror(errno));
+        DEBUG("sigaction failed for SIGCHLD: %s\n", strerror(errno));
+        goto exit_with_error;
+    }
+
+    sigAction.sa_sigaction = lxcExecSigintHandler;
+    sigfillset(&sigMask);
+    sigAction.sa_mask = sigMask;
+    sigAction.sa_flags = SA_SIGINFO;
+    if (0 != sigaction(SIGINT, &sigAction, NULL)) {
+        DEBUG("sigaction failed for SIGINT: %s\n", strerror(errno));
         goto exit_with_error;
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]