Hi Daniel, On Wed, 2015-01-14 at 14:05 +0000, Daniel P. Berrange wrote: > 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; If WITH_DBUS was not defined, compilation fault would occur on in here. Regards, Zhu > + 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 { \ -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list