This is a repost of the shutdown and destroy container support. Changes in this
version:
* Moved state changes to after the signal is successfully sent rather than
restoring if it failed.
* Signal handling in lxc_container goes away since the tty forwarding process is
no longer the container root process.
* Since the tty forwarding process is now outside the container, we have to kill
and wait for it in the destroy.
Thanks!
--
Best Regards,
Dave Leskovec
IBM Linux Technology Center
Open Virtualization
---
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 */
--
Libvir-list mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/libvir-list