From: "Daniel P. Berrange" <berrange(a)redhat.com>
Implement the new API for sending signals to processes in a guest
for the LXC driver. Only support sending signals to the init
process for now, because
- The kernel does not appear to expose the mapping between
container PID numbers and host PID numbers anywhere in the
host OS namespace
- There is no race-free validate whether a host PID corresponds
to a process in a container.
* src/lxc/lxc_driver.c: Allow sending processes signals
---
src/lxc/lxc_driver.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 991b593..c9b8d86 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -2666,6 +2666,78 @@ cleanup:
return ret;
}
+
+static int
+lxcDomainSendProcessSignal(virDomainPtr dom,
+ unsigned int pid_value,
+ unsigned int signum,
+ unsigned int flags)
+{
+ virLXCDriverPtr driver = dom->conn->privateData;
+ virDomainObjPtr vm = NULL;
+ virLXCDomainObjPrivatePtr priv;
+ char uuidstr[VIR_UUID_STRING_BUFLEN];
+ pid_t victim;
+ int ret = -1;
+
+ virCheckFlags(0, -1);
+
+ lxcDriverLock(driver);
+ virUUIDFormat(dom->uuid, uuidstr);
+ vm = virDomainFindByUUID(&driver->domains, dom->uuid);
+ lxcDriverUnlock(driver);
+ if (!vm) {
+ virReportError(VIR_ERR_NO_DOMAIN,
+ _("no domain with matching uuid '%s'"),
uuidstr);
+ goto cleanup;
+ }
+ priv = vm->privateData;
+
+ if (!virDomainObjIsActive(vm)) {
+ virReportError(VIR_ERR_OPERATION_INVALID,
+ "%s", _("domain is not running"));
+ goto cleanup;
+ }
+
+ /*
+ * XXX if the kernel has /proc/$PID/ns/pid we can
+ * switch into container namespace & that way be
+ * able to kill any PID. Alternatively if there
+ * is a way to find a mapping of guest<->host PIDs
+ * we can kill that way.
+ */
+ if (pid_value != 1) {
+ virReportError(VIR_ERR_ARGUMENT_UNSUPPORTED, "%s",
+ _("Only the init process may be killed"));
+ goto cleanup;
+ }
+
+ if (!priv->initpid) {
+ virReportError(VIR_ERR_OPERATION_INVALID, "%s",
+ _("Init pid is not yet available"));
+ goto cleanup;
+ }
+ victim = priv->initpid;
+
+ /* We're relying on fact libvirt header signal numbers
+ * are taken from Linux, to avoid mapping
+ */
+ if (kill(victim, signum) < 0) {
+ virReportSystemError(errno,
+ _("Unable to send %d signal to process %d"),
+ signum, victim);
+ goto cleanup;
+ }
+
+ ret = 0;
+
+cleanup:
+ if (vm)
+ virDomainObjUnlock(vm);
+ return ret;
+}
+
+
static int
lxcListAllDomains(virConnectPtr conn,
virDomainPtr **domains,
@@ -2751,6 +2823,7 @@ static virDriver lxcDriver = {
.nodeSuspendForDuration = nodeSuspendForDuration, /* 0.9.8 */
.nodeGetMemoryParameters = nodeGetMemoryParameters, /* 0.10.2 */
.nodeSetMemoryParameters = nodeSetMemoryParameters, /* 0.10.2 */
+ .domainSendProcessSignal = lxcDomainSendProcessSignal, /* 1.0.1 */
};
static virStateDriver lxcStateDriver = {
--
1.7.11.7