systemd-machined introduced a new method CreateMachineWithNetwork
that obsoletes CreateMachine. It expects to be given a list of
VETH/TAP device indexes for the host side device(s) associated
with a container/machine.
This falls back to the old CreateeMachine method when the new
one is not supported.
---
po/POTFILES.in | 1 +
src/lxc/lxc_cgroup.c | 1 +
src/qemu/qemu_cgroup.c | 1 +
src/util/vircgroup.c | 8 ++++
src/util/vircgroup.h | 2 +
src/util/virsystemd.c | 122 ++++++++++++++++++++++++++++++++++++++-----------
src/util/virsystemd.h | 2 +
tests/virsystemdtest.c | 36 +++++++++++++++
8 files changed, 147 insertions(+), 26 deletions(-)
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 094c8e3..2db8786 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -216,6 +216,7 @@ src/util/virstorageencryption.c
src/util/virstoragefile.c
src/util/virstring.c
src/util/virsysinfo.c
+src/util/virsystemd.c
src/util/virerror.c
src/util/virerror.h
src/util/virtime.c
diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c
index eb67191..728e8e5 100644
--- a/src/lxc/lxc_cgroup.c
+++ b/src/lxc/lxc_cgroup.c
@@ -486,6 +486,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
NULL,
getpid(),
true,
+ 0, NULL,
def->resource->partition,
-1,
&cgroup) < 0)
diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c
index 1acb77d..d71ffbc 100644
--- a/src/qemu/qemu_cgroup.c
+++ b/src/qemu/qemu_cgroup.c
@@ -769,6 +769,7 @@ qemuInitCgroup(virQEMUDriverPtr driver,
NULL,
vm->pid,
false,
+ 0, NULL,
vm->def->resource->partition,
cfg->cgroupControllers,
&priv->cgroup) < 0) {
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 64bc647..f5f617e 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -1584,6 +1584,8 @@ virCgroupNewMachineSystemd(const char *name,
const char *rootdir,
pid_t pidleader,
bool isContainer,
+ size_t nnicindexes,
+ int *nicindexes,
const char *partition,
int controllers,
virCgroupPtr *group)
@@ -1602,6 +1604,8 @@ virCgroupNewMachineSystemd(const char *name,
rootdir,
pidleader,
isContainer,
+ nnicindexes,
+ nicindexes,
partition)) < 0)
return rv;
@@ -1747,6 +1751,8 @@ virCgroupNewMachine(const char *name,
const char *rootdir,
pid_t pidleader,
bool isContainer,
+ size_t nnicindexes,
+ int *nicindexes,
const char *partition,
int controllers,
virCgroupPtr *group)
@@ -1762,6 +1768,8 @@ virCgroupNewMachine(const char *name,
rootdir,
pidleader,
isContainer,
+ nnicindexes,
+ nicindexes,
partition,
controllers,
group)) == 0)
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index f07c1a7..9f984e7 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -100,6 +100,8 @@ int virCgroupNewMachine(const char *name,
const char *rootdir,
pid_t pidleader,
bool isContainer,
+ size_t nnicindexes,
+ int *nicindexes,
const char *partition,
int controllers,
virCgroupPtr *group)
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
index ddfc047..3eea5c2 100644
--- a/src/util/virsystemd.c
+++ b/src/util/virsystemd.c
@@ -26,6 +26,7 @@
#endif
#include "virsystemd.h"
+#include "viratomic.h"
#include "virdbus.h"
#include "virstring.h"
#include "viralloc.h"
@@ -147,7 +148,10 @@ char *virSystemdMakeMachineName(const char *name,
* @uuid: globally unique UUID of the machine
* @rootdir: root directory of machine filesystem
* @pidleader: PID of the leader process
- * @slice: name of the slice to place the machine in
+ * @iscontainer: true if a container, false if a VM
+ * @nnicindexes: number of network interface indexes in list
+ * @nicindexes: list of network interface indexes
+ * @partition: name of the slice to place the machine in
*
* Returns 0 on success, -1 on fatal error, or -2 if systemd-machine is not available
*/
@@ -158,6 +162,8 @@ int virSystemdCreateMachine(const char *name,
const char *rootdir,
pid_t pidleader,
bool iscontainer,
+ size_t nnicindexes,
+ int *nicindexes,
const char *partition)
{
int ret;
@@ -165,6 +171,7 @@ int virSystemdCreateMachine(const char *name,
char *machinename = NULL;
char *creatorname = NULL;
char *slicename = NULL;
+ static int hasCreateWithNetwork = 1;
ret = virDBusIsServiceEnabled("org.freedesktop.machine1");
if (ret < 0)
@@ -192,8 +199,18 @@ int virSystemdCreateMachine(const char *name,
}
/*
- * The systemd DBus API we're invoking has the
- * following signature
+ * The systemd DBus APIs we're invoking have the
+ * following signature(s)
+ *
+ * CreateMachineWithNetwork(in s name,
+ * in ay id,
+ * in s service,
+ * in s class,
+ * in u leader,
+ * in s root_directory,
+ * in ai nicindexes
+ * in a(sv) scope_properties,
+ * out o path);
*
* CreateMachine(in s name,
* in ay id,
@@ -221,38 +238,91 @@ int virSystemdCreateMachine(const char *name,
* @root_directory: the root directory of the container, if
* this is known & visible in the host filesystem, or empty string
*
+ * @nicindexes: list of network interface indexes for the
+ * host end of the VETH device pairs.
+ *
* @scope_properties:an array (not a dict!) of properties that are
* passed on to PID 1 when creating a scope unit for your machine.
* Will allow initial settings for the cgroup & similar.
*
* @path: a bus path returned for the machine object created, to
* allow further API calls to be made against the object.
+ *
*/
VIR_DEBUG("Attempting to create machine via systemd");
- if (virDBusCallMethod(conn,
- NULL,
- NULL,
- "org.freedesktop.machine1",
- "/org/freedesktop/machine1",
- "org.freedesktop.machine1.Manager",
- "CreateMachine",
- "sayssusa(sv)",
- machinename,
- 16,
- uuid[0], uuid[1], uuid[2], uuid[3],
- uuid[4], uuid[5], uuid[6], uuid[7],
- uuid[8], uuid[9], uuid[10], uuid[11],
- uuid[12], uuid[13], uuid[14], uuid[15],
- creatorname,
- iscontainer ? "container" : "vm",
- (unsigned int)pidleader,
- rootdir ? rootdir : "",
- 3,
- "Slice", "s", slicename,
- "After", "as", 1,
"libvirtd.service",
- "Before", "as", 1,
"libvirt-guests.service") < 0)
- goto cleanup;
+ if (virAtomicIntGet(&hasCreateWithNetwork)) {
+ DBusError error;
+ dbus_error_init(&error);
+
+ if (virDBusCallMethod(conn,
+ NULL,
+ &error,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "CreateMachineWithNetwork",
+ "sayssusa&ia(sv)",
+ machinename,
+ 16,
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5], uuid[6], uuid[7],
+ uuid[8], uuid[9], uuid[10], uuid[11],
+ uuid[12], uuid[13], uuid[14], uuid[15],
+ creatorname,
+ iscontainer ? "container" : "vm",
+ (unsigned int)pidleader,
+ rootdir ? rootdir : "",
+ nnicindexes, nicindexes,
+ 3,
+ "Slice", "s", slicename,
+ "After", "as", 1,
"libvirtd.service",
+ "Before", "as", 1,
"libvirt-guests.service") < 0)
+ goto cleanup;
+
+ if (dbus_error_is_set(&error)) {
+ if (STREQ_NULLABLE("org.freedesktop.DBus.Error.UnknownMethod",
+ error.name)) {
+ VIR_INFO("CreateMachineWithNetwork isn't supported, switching
"
+ "to legacy CreateMachine method for
systemd-machined");
+ dbus_error_free(&error);
+ virAtomicIntSet(&hasCreateWithNetwork, 0);
+ /* Could re-structure without Using goto, but this
+ * avoids another atomic read which would trigger
+ * another memory barrier */
+ goto fallback;
+ }
+ virReportError(VIR_ERR_DBUS_SERVICE,
+ _("CreateMachineWithNetwork: %s"),
+ error.message ? error.message : _("unknown
error"));
+ goto cleanup;
+ }
+ } else {
+ fallback:
+ if (virDBusCallMethod(conn,
+ NULL,
+ NULL,
+ "org.freedesktop.machine1",
+ "/org/freedesktop/machine1",
+ "org.freedesktop.machine1.Manager",
+ "CreateMachine",
+ "sayssusa(sv)",
+ machinename,
+ 16,
+ uuid[0], uuid[1], uuid[2], uuid[3],
+ uuid[4], uuid[5], uuid[6], uuid[7],
+ uuid[8], uuid[9], uuid[10], uuid[11],
+ uuid[12], uuid[13], uuid[14], uuid[15],
+ creatorname,
+ iscontainer ? "container" : "vm",
+ (unsigned int)pidleader,
+ rootdir ? rootdir : "",
+ 3,
+ "Slice", "s", slicename,
+ "After", "as", 1,
"libvirtd.service",
+ "Before", "as", 1,
"libvirt-guests.service") < 0)
+ goto cleanup;
+ }
ret = 0;
diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h
index 491c9b7..7a29dba 100644
--- a/src/util/virsystemd.h
+++ b/src/util/virsystemd.h
@@ -40,6 +40,8 @@ int virSystemdCreateMachine(const char *name,
const char *rootdir,
pid_t pidleader,
bool iscontainer,
+ size_t nnicindexes,
+ int *nicindexes,
const char *partition);
int virSystemdTerminateMachine(const char *name,
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
index 0d57a6a..261c4cc 100644
--- a/tests/virsystemdtest.c
+++ b/tests/virsystemdtest.c
@@ -146,6 +146,7 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED)
"/proc/123/root",
123,
true,
+ 0, NULL,
"highpriority.slice") < 0) {
fprintf(stderr, "%s", "Failed to create LXC machine\n");
return -1;
@@ -181,6 +182,7 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED)
NULL,
123,
false,
+ 0, NULL,
NULL) < 0) {
fprintf(stderr, "%s", "Failed to create KVM machine\n");
return -1;
@@ -220,6 +222,7 @@ static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED)
NULL,
123,
false,
+ 0, NULL,
NULL)) == 0) {
unsetenv("FAIL_NO_SERVICE");
fprintf(stderr, "%s", "Unexpected create machine
success\n");
@@ -254,6 +257,7 @@ static int testCreateSystemdNotRunning(const void *opaque
ATTRIBUTE_UNUSED)
NULL,
123,
false,
+ 0, NULL,
NULL)) == 0) {
unsetenv("FAIL_NOT_REGISTERED");
fprintf(stderr, "%s", "Unexpected create machine
success\n");
@@ -288,6 +292,7 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
NULL,
123,
false,
+ 0, NULL,
NULL)) == 0) {
unsetenv("FAIL_BAD_SERVICE");
fprintf(stderr, "%s", "Unexpected create machine
success\n");
@@ -304,6 +309,35 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED)
}
+static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED)
+{
+ unsigned char uuid[VIR_UUID_BUFLEN] = {
+ 1, 1, 1, 1,
+ 2, 2, 2, 2,
+ 3, 3, 3, 3,
+ 4, 4, 4, 4
+ };
+ int nicindexes[] = {
+ 2, 1729, 87539319,
+ };
+ size_t nnicindexes = ARRAY_CARDINALITY(nicindexes);
+ if (virSystemdCreateMachine("demo",
+ "lxc",
+ true,
+ uuid,
+ "/proc/123/root",
+ 123,
+ true,
+ nnicindexes, nicindexes,
+ "highpriority.slice") < 0) {
+ fprintf(stderr, "%s", "Failed to create LXC machine\n");
+ return -1;
+ }
+
+ return 0;
+}
+
+
struct testScopeData {
const char *name;
const char *partition;
@@ -435,6 +469,8 @@ mymain(void)
ret = -1;
if (virtTestRun("Test create bad systemd ", testCreateBadSystemd, NULL)
< 0)
ret = -1;
+ if (virtTestRun("Test create with network ", testCreateNetwork, NULL) <
0)
+ ret = -1;
# define TEST_SCOPE(name, partition, unitname) \
do { \
--
2.1.0