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 Libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list