---
 src/lxc_container.c |   21 +++++++++++
 src/lxc_driver.c    |   94 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 2 files changed, 112 insertions(+), 3 deletions(-)

Index: b/src/lxc_container.c
===================================================================
--- a/src/lxc_container.c	2008-04-04 16:19:02.000000000 -0700
+++ b/src/lxc_container.c	2008-04-04 17:10:04.000000000 -0700
@@ -235,6 +235,16 @@
 }
 #endif
 
+#if 0
+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);
+}
+#endif
+
 static int lxcExecWithTty(lxc_vm_t *vm)
 {
     int rc = -1;
@@ -255,7 +265,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;
     }
 
Index: b/src/lxc_driver.c
===================================================================
--- a/src/lxc_driver.c	2008-04-04 16:50:35.000000000 -0700
+++ b/src/lxc_driver.c	2008-04-04 17:18:46.000000000 -0700
@@ -710,6 +710,96 @@
     return dom;
 }
 
+/**
+ * lxcDomainShutdown:
+ * @dom: Ptr to domain to shutdown
+ *
+ * Sends SIGINT to container root process to request it to shutdown
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+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;
+    }
+
+    if (0 > (kill(vm->def->id, SIGINT))) {
+        if (ESRCH != errno) {
+            lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+                     _("sending SIGTERM failed: %s"), strerror(errno));
+
+            goto error_out;
+        }
+    }
+
+    vm->state = VIR_DOMAIN_SHUTDOWN;
+
+    rc = 0;
+
+error_out:
+    return rc;
+}
+
+/**
+ * lxcDomainDestroy:
+ * @dom: Ptr to domain to destroy
+ *
+ * Sends SIGKILL to container root process to terminate the container
+ *
+ * Returns 0 on success or -1 in case of error
+ */
+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;
+    }
+
+    if (0 > (kill(vm->def->id, SIGKILL))) {
+        if (ESRCH != errno) {
+            lxcError(dom->conn, dom, VIR_ERR_INTERNAL_ERROR,
+                     _("sending SIGKILL failed: %s"), strerror(errno));
+
+            goto error_out;
+        }
+    }
+
+    vm->state = VIR_DOMAIN_SHUTDOWN;
+
+    waitpid(vm->def->id, &childStatus, 0);
+    rc = WEXITSTATUS(childStatus);
+    DEBUG("container exited with rc: %d", rc);
+
+    /* also need to kill tty forward process */
+    /* wrap this with error handling etc.  in the right place? */
+    /* also wait for the process */
+    kill(vm->pid, SIGKILL);
+
+    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)
 {
     uid_t uid = getuid();
@@ -811,9 +901,9 @@
     lxcDomainLookupByName, /* domainLookupByName */
     NULL, /* domainSuspend */
     NULL, /* domainResume */
-    NULL, /* domainShutdown */
+    lxcDomainShutdown, /* domainShutdown */
     NULL, /* domainReboot */
-    NULL, /* domainDestroy */
+    lxcDomainDestroy, /* domainDestroy */
     lxcGetOSType, /* domainGetOSType */
     NULL, /* domainGetMaxMemory */
     NULL, /* domainSetMaxMemory */
