]> xenbits.xensource.com Git - libvirt.git/commitdiff
Add support for systemd-machined CreateMachineWithNetwork
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 11 Nov 2014 17:38:43 +0000 (17:38 +0000)
committerDaniel P. Berrange <berrange@redhat.com>
Thu, 15 Jan 2015 11:07:07 +0000 (11:07 +0000)
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 CreateMachine method when the new
one is not supported.

po/POTFILES.in
src/lxc/lxc_cgroup.c
src/qemu/qemu_cgroup.c
src/util/vircgroup.c
src/util/vircgroup.h
src/util/virsystemd.c
src/util/virsystemd.h
tests/virsystemdtest.c

index 094c8e370432698d26e862e7b556d950a89903b5..2db87862ce716d82fe5ecf64f07ca93d1bb05193 100644 (file)
@@ -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
index eb671913045a7e4a076e7adc1e90b1798405de92..728e8e500db78ad734fd192800d56e8003ee1bea 100644 (file)
@@ -486,6 +486,7 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def)
                             NULL,
                             getpid(),
                             true,
+                            0, NULL,
                             def->resource->partition,
                             -1,
                             &cgroup) < 0)
index 1acb77d253e3ed6fc6332bc2071253becbebc172..d71ffbcf209c01b8744221cb1a8ecb7a2091b217 100644 (file)
@@ -769,6 +769,7 @@ qemuInitCgroup(virQEMUDriverPtr driver,
                             NULL,
                             vm->pid,
                             false,
+                            0, NULL,
                             vm->def->resource->partition,
                             cfg->cgroupControllers,
                             &priv->cgroup) < 0) {
index 64bc647db828299d45a3adda48699c8a3d8b1b25..f5f617ed67de8a455b6d4b10f599ac383548de07 100644 (file)
@@ -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)
index f07c1a74eecc1e2bab27dc52eb2361e163d461c3..9f984e787d1f6273074ecfa8be86e6f314214abe 100644 (file)
@@ -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)
index ddfc0474a783adffcdaa05e3ed17a803e3baf80f..3eea5c27004e1fac3057990d17abd55fab599e51 100644 (file)
@@ -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;
 
index 491c9b7de3be6cc5089563b4d41ad510c2aa4ea9..7a29dbafffe5d890b1984fcac881ba8d99609cc3 100644 (file)
@@ -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,
index 0d57a6aae14d6a298de8a44e63dc5c6f51975499..261c4cc345f4121c87350675e09fd9cfca5f6910 100644 (file)
@@ -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 {                                                                \