[libvirt] [PATCH 1/4] Add support for systemd-machined CreateMachineWithNetwork
Zhu Guihua
zhugh.fnst at cn.fujitsu.com
Mon Jan 19 01:56:35 UTC 2015
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 { \
More information about the libvir-list
mailing list