# util/virsystemd.h
virSystemdCreateMachine;
+virSystemdMakeMachineName;
virSystemdMakeScopeName;
virSystemdMakeSliceName;
+virSystemdTerminateMachine;
# util/virthread.h
#include "virstring.h"
#include "viratomic.h"
#include "virprocess.h"
+#include "virsystemd.h"
#define VIR_FROM_THIS VIR_FROM_LXC
virCgroupFree(&priv->cgroup);
}
+ /* Get machined to terminate the machine as it may not have cleaned it
+ * properly. See https://bugs.freedesktop.org/show_bug.cgi?id=68370 for
+ * the bug we are working around here.
+ */
+ virSystemdTerminateMachine(vm->def->name, "lxc", true);
+
+
/* now that we know it's stopped call the hook if present */
if (virHookPresent(VIR_HOOK_DRIVER_LXC)) {
char *xml = virDomainDefFormat(vm->def, 0);
return virBufferContentAndReset(&buf);
}
+char *virSystemdMakeMachineName(const char *name,
+ const char *drivername,
+ bool privileged)
+{
+ char *machinename = NULL;
+ char *username = NULL;
+ if (privileged) {
+ if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
+ goto cleanup;
+ } else {
+ if (!(username = virGetUserName(geteuid())))
+ goto cleanup;
+ if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
+ goto cleanup;
+ }
+
+cleanup:
+ VIR_FREE(username);
+
+ return machinename;
+}
/**
* virSystemdCreateMachine:
DBusConnection *conn;
char *machinename = NULL;
char *creatorname = NULL;
- char *username = NULL;
char *slicename = NULL;
ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
conn = virDBusGetSystemBus();
ret = -1;
- if (privileged) {
- if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
- goto cleanup;
- } else {
- if (!(username = virGetUserName(geteuid())))
- goto cleanup;
- if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
- goto cleanup;
- }
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
+ goto cleanup;
if (virAsprintf(&creatorname, "libvirt-%s", drivername) < 0)
goto cleanup;
ret = 0;
cleanup:
- VIR_FREE(username);
VIR_FREE(creatorname);
VIR_FREE(machinename);
VIR_FREE(slicename);
return ret;
}
+
+int virSystemdTerminateMachine(const char *name,
+ const char *drivername,
+ bool privileged)
+{
+ int ret;
+ DBusConnection *conn;
+ char *machinename = NULL;
+
+ ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
+ if (ret < 0)
+ return ret;
+
+ conn = virDBusGetSystemBus();
+
+ ret = -1;
+ if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged)))
+ goto cleanup;
+
+ /*
+ * The systemd DBus API we're invoking has the
+ * following signature
+ *
+ * TerminateMachine(in s name);
+ *
+ * @name a host unique name for the machine. shows up
+ * in 'ps' listing & similar
+ */
+
+ VIR_DEBUG("Attempting to terminate machine via systemd");
+ if (virDBusCallMethod(conn,
+ NULL,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "TerminateMachine",
+ "s",
+ machinename) < 0)
+ goto cleanup;
+
+ ret = 0;
+
+cleanup:
+ VIR_FREE(machinename);
+ return ret;
+}
const char *slicename);
char *virSystemdMakeSliceName(const char *partition);
+char *virSystemdMakeMachineName(const char *name,
+ const char *drivername,
+ bool privileged);
+
int virSystemdCreateMachine(const char *name,
const char *drivername,
bool privileged,
bool iscontainer,
const char *partition);
+int virSystemdTerminateMachine(const char *name,
+ const char *drivername,
+ bool privileged);
+
#endif /* __VIR_SYSTEMD_H__ */
return 0;
}
+static int testTerminateContainer(const void *opaque ATTRIBUTE_UNUSED)
+{
+ if (virSystemdTerminateMachine("demo",
+ "lxc",
+ true) < 0) {
+ fprintf(stderr, "%s", "Failed to terminate LXC machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
{
unsigned char uuid[VIR_UUID_BUFLEN] = {
return 0;
}
+static int testTerminateMachine(const void *opaque ATTRIBUTE_UNUSED)
+{
+ if (virSystemdTerminateMachine("demo",
+ "qemu",
+ false) < 0) {
+ fprintf(stderr, "%s", "Failed to terminate KVM machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
{
unsigned char uuid[VIR_UUID_BUFLEN] = {
if (virtTestRun("Test create container ", 1, testCreateContainer, NULL) < 0)
ret = -1;
+ if (virtTestRun("Test terminate container ", 1, testTerminateContainer, NULL) < 0)
+ ret = -1;
if (virtTestRun("Test create machine ", 1, testCreateMachine, NULL) < 0)
ret = -1;
+ if (virtTestRun("Test terminate machine ", 1, testTerminateMachine, NULL) < 0)
+ ret = -1;
if (virtTestRun("Test create no systemd ", 1, testCreateNoSystemd, NULL) < 0)
ret = -1;
if (virtTestRun("Test create bad systemd ", 1, testCreateBadSystemd, NULL) < 0)