d71922
From 81d3458e0534b76bc2de780b0b03428b383fb270 Mon Sep 17 00:00:00 2001
d71922
Message-Id: <81d3458e0534b76bc2de780b0b03428b383fb270@dist-git>
d71922
From: Martin Kletzander <mkletzan@redhat.com>
d71922
Date: Tue, 16 Feb 2016 11:55:07 +0100
d71922
Subject: [PATCH] systemd: Escape machine name for machined
d71922
d71922
https://bugzilla.redhat.com/show_bug.cgi?id=1308494
d71922
d71922
According to the documentation, CreateMachine accepts only 7bit ASCII
d71922
characters in the machinename parameter, so let's make sure we can start
d71922
machines with unicode names with systemd.  We already have a function
d71922
for that, we just forgot to use it.
d71922
d71922
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1062943
d71922
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1282846
d71922
d71922
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
d71922
(cherry picked from commit e24eda48cfae84a9003456b68eaf753a26123639)
d71922
Signed-off-by: Martin Kletzander <mkletzan@redhat.com>
d71922
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
d71922
---
d71922
 src/util/virsystemd.c  | 12 ++++++++----
d71922
 tests/virsystemdtest.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
d71922
 2 files changed, 50 insertions(+), 7 deletions(-)
d71922
d71922
diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c
d71922
index 54c409d..0c8f026 100644
d71922
--- a/src/util/virsystemd.c
d71922
+++ b/src/util/virsystemd.c
d71922
@@ -119,16 +119,20 @@ char *virSystemdMakeMachineName(const char *name,
d71922
 {
d71922
     char *machinename = NULL;
d71922
     char *username = NULL;
d71922
+    virBuffer buf = VIR_BUFFER_INITIALIZER;
d71922
+
d71922
     if (privileged) {
d71922
-        if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0)
d71922
-            goto cleanup;
d71922
+        virBufferAsprintf(&buf, "%s-", drivername);
d71922
     } else {
d71922
         if (!(username = virGetUserName(geteuid())))
d71922
             goto cleanup;
d71922
-        if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0)
d71922
-            goto cleanup;
d71922
+
d71922
+        virBufferAsprintf(&buf, "%s-%s-", username, drivername);
d71922
     }
d71922
 
d71922
+    virSystemdEscapeName(&buf, name);
d71922
+
d71922
+    machinename = virBufferContentAndReset(&buf;;
d71922
  cleanup:
d71922
     VIR_FREE(username);
d71922
 
d71922
diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c
d71922
index d0b9335..06fec54 100644
d71922
--- a/tests/virsystemdtest.c
d71922
+++ b/tests/virsystemdtest.c
d71922
@@ -338,7 +338,7 @@ static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED)
d71922
 }
d71922
 
d71922
 
d71922
-struct testScopeData {
d71922
+struct testNameData {
d71922
     const char *name;
d71922
     const char *expected;
d71922
 };
d71922
@@ -346,7 +346,7 @@ struct testScopeData {
d71922
 static int
d71922
 testScopeName(const void *opaque)
d71922
 {
d71922
-    const struct testScopeData *data = opaque;
d71922
+    const struct testNameData *data = opaque;
d71922
     int ret = -1;
d71922
     char *actual = NULL;
d71922
 
d71922
@@ -366,6 +366,29 @@ testScopeName(const void *opaque)
d71922
     return ret;
d71922
 }
d71922
 
d71922
+static int
d71922
+testMachineName(const void *opaque)
d71922
+{
d71922
+    const struct testNameData *data = opaque;
d71922
+    int ret = -1;
d71922
+    char *actual = NULL;
d71922
+
d71922
+    if (!(actual = virSystemdMakeMachineName(data->name, "qemu", true)))
d71922
+        goto cleanup;
d71922
+
d71922
+    if (STRNEQ(actual, data->expected)) {
d71922
+        fprintf(stderr, "Expected '%s' but got '%s'\n",
d71922
+                data->expected, actual);
d71922
+        goto cleanup;
d71922
+    }
d71922
+
d71922
+    ret = 0;
d71922
+
d71922
+ cleanup:
d71922
+    VIR_FREE(actual);
d71922
+    return ret;
d71922
+}
d71922
+
d71922
 typedef int (*virSystemdCanHelper)(bool * result);
d71922
 struct testPMSupportData {
d71922
     virSystemdCanHelper tested;
d71922
@@ -471,7 +494,7 @@ mymain(void)
d71922
 
d71922
 # define TEST_SCOPE(name, unitname)                                     \
d71922
     do {                                                                \
d71922
-        struct testScopeData data = {                                   \
d71922
+        struct testNameData data = {                                    \
d71922
             name, unitname                                              \
d71922
         };                                                              \
d71922
         if (virtTestRun("Test scopename", testScopeName, &data) < 0)    \
d71922
@@ -482,6 +505,22 @@ mymain(void)
d71922
     TEST_SCOPE("demo-name", "machine-lxc\\x2ddemo\\x2dname.scope");
d71922
     TEST_SCOPE("demo!name", "machine-lxc\\x2ddemo\\x21name.scope");
d71922
     TEST_SCOPE(".demo", "machine-lxc\\x2d\\x2edemo.scope");
d71922
+    TEST_SCOPE("bull💩", "machine-lxc\\x2dbull\\xf0\\x9f\\x92\\xa9.scope");
d71922
+
d71922
+# define TEST_MACHINE(name, machinename)                                \
d71922
+    do {                                                                \
d71922
+        struct testNameData data = {                                    \
d71922
+            name, machinename                                           \
d71922
+        };                                                              \
d71922
+        if (virtTestRun("Test scopename", testMachineName, &data) < 0)  \
d71922
+            ret = -1;                                                   \
d71922
+    } while (0)
d71922
+
d71922
+    TEST_MACHINE("demo", "qemu-demo");
d71922
+    TEST_MACHINE("demo-name", "qemu-demo\\x2dname");
d71922
+    TEST_MACHINE("demo!name", "qemu-demo\\x21name");
d71922
+    TEST_MACHINE(".demo", "qemu-\\x2edemo");
d71922
+    TEST_MACHINE("bull\U0001f4a9", "qemu-bull\\xf0\\x9f\\x92\\xa9");
d71922
 
d71922
 # define TESTS_PM_SUPPORT_HELPER(name, function)                        \
d71922
     do {                                                                \
d71922
-- 
d71922
2.7.2
d71922