[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