From d7192236d3c0510c5debbd75087d36d481a4ead1 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 31 2016 14:24:25 +0000 Subject: import libvirt-1.2.17-13.el7_2.4 --- diff --git a/SOURCES/libvirt-dbus-Don-t-unref-NULL-messages.patch b/SOURCES/libvirt-dbus-Don-t-unref-NULL-messages.patch new file mode 100644 index 0000000..e3f9ead --- /dev/null +++ b/SOURCES/libvirt-dbus-Don-t-unref-NULL-messages.patch @@ -0,0 +1,327 @@ +From 58235a6cc62f33a6934d214e967b6ef879a77ec0 Mon Sep 17 00:00:00 2001 +Message-Id: <58235a6cc62f33a6934d214e967b6ef879a77ec0@dist-git> +From: Michal Privoznik +Date: Tue, 16 Feb 2016 11:55:12 +0100 +Subject: [PATCH] dbus: Don't unref NULL messages + +https://bugzilla.redhat.com/show_bug.cgi?id=1308494 + +Apparently we are not the only ones with dumb free functions +because dbus_message_unref() does not accept NULL either. But if +I were to vote, this one is even more evil. Instead of returning +an error just like we do it immediately dereference any pointer +passed and thus crash you app. Well done DBus! + + Program received signal SIGSEGV, Segmentation fault. + [Switching to Thread 0x7f878ebda700 (LWP 31264)] + 0x00007f87be4016e5 in ?? () from /usr/lib64/libdbus-1.so.3 + (gdb) bt + #0 0x00007f87be4016e5 in ?? () from /usr/lib64/libdbus-1.so.3 + #1 0x00007f87be3f004e in dbus_message_unref () from /usr/lib64/libdbus-1.so.3 + #2 0x00007f87bf6ecf95 in virSystemdGetMachineNameByPID (pid=9849) at util/virsystemd.c:228 + #3 0x00007f879761bd4d in qemuConnectCgroup (driver=0x7f87600a32a0, vm=0x7f87600c7550) at qemu/qemu_cgroup.c:909 + #4 0x00007f87976386b7 in qemuProcessReconnect (opaque=0x7f87600db840) at qemu/qemu_process.c:3386 + #5 0x00007f87bf6edfff in virThreadHelper (data=0x7f87600d5580) at util/virthread.c:206 + #6 0x00007f87bb602334 in start_thread (arg=0x7f878ebda700) at pthread_create.c:333 + #7 0x00007f87bb3481bd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:109 + (gdb) frame 2 + #2 0x00007f87bf6ecf95 in virSystemdGetMachineNameByPID (pid=9849) at util/virsystemd.c:228 + 228 dbus_message_unref(reply); + (gdb) p reply + $1 = (DBusMessage *) 0x0 + +Signed-off-by: Michal Privoznik +(cherry picked from commit 862298a2e7bef059b73f477e8a88d403c523e10b) +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/libvirt_private.syms | 1 + + src/rpc/virnetdaemon.c | 4 ++-- + src/util/virdbus.c | 14 +++++++------- + src/util/virdbus.h | 1 - + src/util/virfirewall.c | 3 +-- + src/util/virsystemd.c | 2 +- + tests/virdbustest.c | 20 ++++++++++---------- + tests/virfirewalltest.c | 3 +-- + tests/virpolkittest.c | 2 +- + tests/virsystemdtest.c | 3 ++- + 10 files changed, 26 insertions(+), 27 deletions(-) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 4ad9266..86909c1 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -1348,6 +1348,7 @@ virDBusHasSystemBus; + virDBusMessageDecode; + virDBusMessageEncode; + virDBusMessageRead; ++virDBusMessageUnref; + virDBusSetSharedBus; + + +diff --git a/src/rpc/virnetdaemon.c b/src/rpc/virnetdaemon.c +index 910f266..18c962c 100644 +--- a/src/rpc/virnetdaemon.c ++++ b/src/rpc/virnetdaemon.c +@@ -374,7 +374,7 @@ virNetDaemonGotInhibitReply(DBusPendingCall *pending, + VIR_FORCE_CLOSE(fd); + } + } +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + + cleanup: + virObjectUnlock(dmn); +@@ -426,7 +426,7 @@ virNetDaemonCallInhibit(virNetDaemonPtr dmn, + dmn, NULL); + dmn->autoShutdownCallingInhibit = true; + } +- dbus_message_unref(message); ++ virDBusMessageUnref(message); + } + #endif + +diff --git a/src/util/virdbus.c b/src/util/virdbus.c +index 1cf1eef..a34e845 100644 +--- a/src/util/virdbus.c ++++ b/src/util/virdbus.c +@@ -1394,7 +1394,7 @@ int virDBusCreateMethodV(DBusMessage **call, + } + + if (virDBusMessageEncodeArgs(*call, types, args) < 0) { +- dbus_message_unref(*call); ++ virDBusMessageUnref(*call); + *call = NULL; + goto cleanup; + } +@@ -1463,7 +1463,7 @@ int virDBusCreateReplyV(DBusMessage **reply, + } + + if (virDBusMessageEncodeArgs(*reply, types, args) < 0) { +- dbus_message_unref(*reply); ++ virDBusMessageUnref(*reply); + *reply = NULL; + goto cleanup; + } +@@ -1582,7 +1582,7 @@ virDBusCall(DBusConnection *conn, + if (ret == 0 && replyout) + *replyout = reply; + else +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + } + return ret; + } +@@ -1646,8 +1646,7 @@ int virDBusCallMethod(DBusConnection *conn, + ret = virDBusCall(conn, call, replyout, error); + + cleanup: +- if (call) +- dbus_message_unref(call); ++ virDBusMessageUnref(call); + return ret; + } + +@@ -1723,7 +1722,7 @@ static int virDBusIsServiceInList(const char *listMethod, const char *name) + } + + cleanup: +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + return ret; + } + +@@ -1759,7 +1758,8 @@ int virDBusIsServiceRegistered(const char *name) + + void virDBusMessageUnref(DBusMessage *msg) + { +- dbus_message_unref(msg); ++ if (msg) ++ dbus_message_unref(msg); + } + + #else /* ! WITH_DBUS */ +diff --git a/src/util/virdbus.h b/src/util/virdbus.h +index 9e86538..86b4223 100644 +--- a/src/util/virdbus.h ++++ b/src/util/virdbus.h +@@ -28,7 +28,6 @@ + # else + # define DBusConnection void + # define DBusMessage void +-# define dbus_message_unref(m) do {} while (0) + # endif + # include "internal.h" + +diff --git a/src/util/virfirewall.c b/src/util/virfirewall.c +index a972c05..f26fd86 100644 +--- a/src/util/virfirewall.c ++++ b/src/util/virfirewall.c +@@ -822,8 +822,7 @@ virFirewallApplyRuleFirewallD(virFirewallRulePtr rule, + + cleanup: + virResetError(&error); +- if (reply) +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + return ret; + } + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 7bc5d55..08fd6bb 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -225,7 +225,7 @@ virSystemdGetMachineNameByPID(pid_t pid) + + cleanup: + VIR_FREE(object); +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + + return name; + } +diff --git a/tests/virdbustest.c b/tests/virdbustest.c +index 4ec3c0d..1622b03 100644 +--- a/tests/virdbustest.c ++++ b/tests/virdbustest.c +@@ -121,7 +121,7 @@ static int testMessageSimple(const void *args ATTRIBUTE_UNUSED) + VIR_FREE(out_string); + VIR_FREE(out_signature); + VIR_FREE(out_objectpath); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -171,7 +171,7 @@ static int testMessageVariant(const void *args ATTRIBUTE_UNUSED) + cleanup: + VIR_FREE(out_str1); + VIR_FREE(out_str2); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -230,7 +230,7 @@ static int testMessageArray(const void *args ATTRIBUTE_UNUSED) + cleanup: + VIR_FREE(out_str1); + VIR_FREE(out_str2); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -274,7 +274,7 @@ static int testMessageEmptyArrayRef(const void *args ATTRIBUTE_UNUSED) + ret = 0; + + cleanup: +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -323,7 +323,7 @@ static int testMessageSingleArrayRef(const void *args ATTRIBUTE_UNUSED) + cleanup: + if (out_strv1) + VIR_FREE(out_strv1[0]); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -436,7 +436,7 @@ static int testMessageArrayRef(const void *args ATTRIBUTE_UNUSED) + for (i = 0; i < out_nstrv2; i++) + VIR_FREE(out_strv2[i]); + VIR_FREE(out_strv2); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -511,7 +511,7 @@ static int testMessageStruct(const void *args ATTRIBUTE_UNUSED) + VIR_FREE(out_string); + VIR_FREE(out_signature); + VIR_FREE(out_objectpath); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -581,7 +581,7 @@ static int testMessageDict(const void *args ATTRIBUTE_UNUSED) + VIR_FREE(out_key1); + VIR_FREE(out_key2); + VIR_FREE(out_key3); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -652,7 +652,7 @@ static int testMessageDictRef(const void *args ATTRIBUTE_UNUSED) + VIR_FREE(out_strv1[5]); + } + VIR_FREE(out_strv1); +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +@@ -695,7 +695,7 @@ static int testMessageEmptyDictRef(const void *args ATTRIBUTE_UNUSED) + ret = 0; + + cleanup: +- dbus_message_unref(msg); ++ virDBusMessageUnref(msg); + return ret; + } + +diff --git a/tests/virfirewalltest.c b/tests/virfirewalltest.c +index 1f8d8f1..8f6fc9e 100644 +--- a/tests/virfirewalltest.c ++++ b/tests/virfirewalltest.c +@@ -179,8 +179,7 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + return reply; + + error: +- if (reply) +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + reply = NULL; + if (error && !dbus_error_is_set(error)) + dbus_set_error_const(error, +diff --git a/tests/virpolkittest.c b/tests/virpolkittest.c +index cdf78f5..b39beed 100644 +--- a/tests/virpolkittest.c ++++ b/tests/virpolkittest.c +@@ -140,7 +140,7 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + return reply; + + error: +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + return NULL; + } + +diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c +index 46452dd..101f5e0 100644 +--- a/tests/virsystemdtest.c ++++ b/tests/virsystemdtest.c +@@ -28,6 +28,7 @@ + # include + + # include "virsystemd.h" ++# include "virdbus.h" + # include "virlog.h" + # include "virmock.h" + # define VIR_FROM_THIS VIR_FROM_NONE +@@ -151,7 +152,7 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + return reply; + + error: +- dbus_message_unref(reply); ++ virDBusMessageUnref(reply); + return NULL; + } + +-- +2.7.2 + diff --git a/SOURCES/libvirt-systemd-Add-virSystemdGetMachineNameByPID.patch b/SOURCES/libvirt-systemd-Add-virSystemdGetMachineNameByPID.patch new file mode 100644 index 0000000..b98184e --- /dev/null +++ b/SOURCES/libvirt-systemd-Add-virSystemdGetMachineNameByPID.patch @@ -0,0 +1,190 @@ +From 108e6134a8f61d2c809b7d0e423fba4a5f796e00 Mon Sep 17 00:00:00 2001 +Message-Id: <108e6134a8f61d2c809b7d0e423fba4a5f796e00@dist-git> +From: Martin Kletzander +Date: Tue, 16 Feb 2016 11:55:08 +0100 +Subject: [PATCH] systemd: Add virSystemdGetMachineNameByPID + +https://bugzilla.redhat.com/show_bug.cgi?id=1308494 + +Signed-off-by: Martin Kletzander +(cherry picked from commit 92757d4d2d108cf612916928e733739d40a31942) +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/libvirt_private.syms | 1 + + src/util/virsystemd.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++ + src/util/virsystemd.h | 2 ++ + tests/virsystemdtest.c | 46 +++++++++++++++++++++++++++++++++++++++ + 4 files changed, 105 insertions(+) + +diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms +index 16ae24f..4ad9266 100644 +--- a/src/libvirt_private.syms ++++ b/src/libvirt_private.syms +@@ -2228,6 +2228,7 @@ virSystemdCanHibernate; + virSystemdCanHybridSleep; + virSystemdCanSuspend; + virSystemdCreateMachine; ++virSystemdGetMachineNameByPID; + virSystemdMakeMachineName; + virSystemdMakeScopeName; + virSystemdMakeSliceName; +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 0c8f026..daaa37c 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -113,6 +113,7 @@ char *virSystemdMakeSliceName(const char *partition) + return virBufferContentAndReset(&buf); + } + ++ + char *virSystemdMakeMachineName(const char *name, + const char *drivername, + bool privileged) +@@ -139,6 +140,61 @@ char *virSystemdMakeMachineName(const char *name, + return machinename; + } + ++ ++char * ++virSystemdGetMachineNameByPID(pid_t pid) ++{ ++ DBusConnection *conn; ++ DBusMessage *reply; ++ char *name = NULL, *object = NULL; ++ ++ if (virDBusIsServiceEnabled("org.freedesktop.machine1") < 0) ++ goto cleanup; ++ ++ if (virDBusIsServiceRegistered("org.freedesktop.systemd1") < 0) ++ goto cleanup; ++ ++ if (!(conn = virDBusGetSystemBus())) ++ goto cleanup; ++ ++ if (virDBusCallMethod(conn, &reply, NULL, ++ "org.freedesktop.machine1", ++ "/org/freedesktop/machine1", ++ "org.freedesktop.machine1.Manager", ++ "GetMachineByPID", ++ "u", pid) < 0) ++ goto cleanup; ++ ++ if (virDBusMessageRead(reply, "o", &object) < 0) ++ goto cleanup; ++ ++ VIR_DEBUG("Domain with pid %llu has object path '%s'", ++ (unsigned long long)pid, object); ++ ++ if (virDBusCallMethod(conn, &reply, NULL, ++ "org.freedesktop.machine1", ++ object, ++ "org.freedesktop.DBus.Properties", ++ "Get", ++ "ss", ++ "org.freedesktop.machine1.Machine", ++ "Name") < 0) ++ goto cleanup; ++ ++ if (virDBusMessageRead(reply, "v", "s", &name) < 0) ++ goto cleanup; ++ ++ VIR_DEBUG("Domain with pid %llu has machine name '%s'", ++ (unsigned long long)pid, name); ++ ++ cleanup: ++ VIR_FREE(object); ++ dbus_message_unref(reply); ++ ++ return name; ++} ++ ++ + /** + * virSystemdCreateMachine: + * @name: driver unique name of the machine +diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h +index 8af2169..a13a4c0 100644 +--- a/src/util/virsystemd.h ++++ b/src/util/virsystemd.h +@@ -55,4 +55,6 @@ int virSystemdCanHibernate(bool *result); + + int virSystemdCanHybridSleep(bool *result); + ++char *virSystemdGetMachineNameByPID(pid_t pid); ++ + #endif /* __VIR_SYSTEMD_H__ */ +diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c +index 06fec54..3a3cd99 100644 +--- a/tests/virsystemdtest.c ++++ b/tests/virsystemdtest.c +@@ -54,6 +54,31 @@ VIR_MOCK_WRAP_RET_ARGS(dbus_connection_send_with_reply_and_block, + "Something went wrong creating the machine"); + } else { + reply = dbus_message_new(DBUS_MESSAGE_TYPE_METHOD_RETURN); ++ ++ if (STREQ(member, "GetMachineByPID")) { ++ const char *object_path = "/org/freedesktop/machine1/machine/qemu_2ddemo"; ++ DBusMessageIter iter; ++ ++ dbus_message_iter_init_append(reply, &iter); ++ if (!dbus_message_iter_append_basic(&iter, ++ DBUS_TYPE_OBJECT_PATH, ++ &object_path)) ++ goto error; ++ } else if (STREQ(member, "Get")) { ++ const char *name = "qemu-demo"; ++ DBusMessageIter iter; ++ DBusMessageIter sub; ++ ++ dbus_message_iter_init_append(reply, &iter); ++ dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, ++ "s", &sub); ++ ++ if (!dbus_message_iter_append_basic(&sub, ++ DBUS_TYPE_STRING, ++ &name)) ++ goto error; ++ dbus_message_iter_close_container(&iter, &sub); ++ } + } + } else if (STREQ(service, "org.freedesktop.login1")) { + char *supported = getenv("RESULT_SUPPORT"); +@@ -338,6 +363,25 @@ static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED) + } + + ++static int ++testGetMachineName(const void *opaque ATTRIBUTE_UNUSED) ++{ ++ char *tmp = virSystemdGetMachineNameByPID(1234); ++ int ret = -1; ++ ++ if (!tmp) { ++ fprintf(stderr, "%s", "Failed to create LXC machine\n"); ++ return ret; ++ } ++ ++ if (STREQ(tmp, "qemu-demo")) ++ ret = 0; ++ ++ VIR_FREE(tmp); ++ return ret; ++} ++ ++ + struct testNameData { + const char *name; + const char *expected; +@@ -491,6 +535,8 @@ mymain(void) + ret = -1; + if (virtTestRun("Test create with network ", testCreateNetwork, NULL) < 0) + ret = -1; ++ if (virtTestRun("Test getting machine name ", testGetMachineName, NULL) < 0) ++ ret = -1; + + # define TEST_SCOPE(name, unitname) \ + do { \ +-- +2.7.2 + diff --git a/SOURCES/libvirt-systemd-Escape-machine-name-for-machined.patch b/SOURCES/libvirt-systemd-Escape-machine-name-for-machined.patch new file mode 100644 index 0000000..f9f055c --- /dev/null +++ b/SOURCES/libvirt-systemd-Escape-machine-name-for-machined.patch @@ -0,0 +1,141 @@ +From 81d3458e0534b76bc2de780b0b03428b383fb270 Mon Sep 17 00:00:00 2001 +Message-Id: <81d3458e0534b76bc2de780b0b03428b383fb270@dist-git> +From: Martin Kletzander +Date: Tue, 16 Feb 2016 11:55:07 +0100 +Subject: [PATCH] systemd: Escape machine name for machined + +https://bugzilla.redhat.com/show_bug.cgi?id=1308494 + +According to the documentation, CreateMachine accepts only 7bit ASCII +characters in the machinename parameter, so let's make sure we can start +machines with unicode names with systemd. We already have a function +for that, we just forgot to use it. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1062943 +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1282846 + +Signed-off-by: Martin Kletzander +(cherry picked from commit e24eda48cfae84a9003456b68eaf753a26123639) +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/util/virsystemd.c | 12 ++++++++---- + tests/virsystemdtest.c | 45 ++++++++++++++++++++++++++++++++++++++++++--- + 2 files changed, 50 insertions(+), 7 deletions(-) + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 54c409d..0c8f026 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -119,16 +119,20 @@ char *virSystemdMakeMachineName(const char *name, + { + char *machinename = NULL; + char *username = NULL; ++ virBuffer buf = VIR_BUFFER_INITIALIZER; ++ + if (privileged) { +- if (virAsprintf(&machinename, "%s-%s", drivername, name) < 0) +- goto cleanup; ++ virBufferAsprintf(&buf, "%s-", drivername); + } else { + if (!(username = virGetUserName(geteuid()))) + goto cleanup; +- if (virAsprintf(&machinename, "%s-%s-%s", username, drivername, name) < 0) +- goto cleanup; ++ ++ virBufferAsprintf(&buf, "%s-%s-", username, drivername); + } + ++ virSystemdEscapeName(&buf, name); ++ ++ machinename = virBufferContentAndReset(&buf); + cleanup: + VIR_FREE(username); + +diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c +index d0b9335..06fec54 100644 +--- a/tests/virsystemdtest.c ++++ b/tests/virsystemdtest.c +@@ -338,7 +338,7 @@ static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED) + } + + +-struct testScopeData { ++struct testNameData { + const char *name; + const char *expected; + }; +@@ -346,7 +346,7 @@ struct testScopeData { + static int + testScopeName(const void *opaque) + { +- const struct testScopeData *data = opaque; ++ const struct testNameData *data = opaque; + int ret = -1; + char *actual = NULL; + +@@ -366,6 +366,29 @@ testScopeName(const void *opaque) + return ret; + } + ++static int ++testMachineName(const void *opaque) ++{ ++ const struct testNameData *data = opaque; ++ int ret = -1; ++ char *actual = NULL; ++ ++ if (!(actual = virSystemdMakeMachineName(data->name, "qemu", true))) ++ goto cleanup; ++ ++ if (STRNEQ(actual, data->expected)) { ++ fprintf(stderr, "Expected '%s' but got '%s'\n", ++ data->expected, actual); ++ goto cleanup; ++ } ++ ++ ret = 0; ++ ++ cleanup: ++ VIR_FREE(actual); ++ return ret; ++} ++ + typedef int (*virSystemdCanHelper)(bool * result); + struct testPMSupportData { + virSystemdCanHelper tested; +@@ -471,7 +494,7 @@ mymain(void) + + # define TEST_SCOPE(name, unitname) \ + do { \ +- struct testScopeData data = { \ ++ struct testNameData data = { \ + name, unitname \ + }; \ + if (virtTestRun("Test scopename", testScopeName, &data) < 0) \ +@@ -482,6 +505,22 @@ mymain(void) + TEST_SCOPE("demo-name", "machine-lxc\\x2ddemo\\x2dname.scope"); + TEST_SCOPE("demo!name", "machine-lxc\\x2ddemo\\x21name.scope"); + TEST_SCOPE(".demo", "machine-lxc\\x2d\\x2edemo.scope"); ++ TEST_SCOPE("bull💩", "machine-lxc\\x2dbull\\xf0\\x9f\\x92\\xa9.scope"); ++ ++# define TEST_MACHINE(name, machinename) \ ++ do { \ ++ struct testNameData data = { \ ++ name, machinename \ ++ }; \ ++ if (virtTestRun("Test scopename", testMachineName, &data) < 0) \ ++ ret = -1; \ ++ } while (0) ++ ++ TEST_MACHINE("demo", "qemu-demo"); ++ TEST_MACHINE("demo-name", "qemu-demo\\x2dname"); ++ TEST_MACHINE("demo!name", "qemu-demo\\x21name"); ++ TEST_MACHINE(".demo", "qemu-\\x2edemo"); ++ TEST_MACHINE("bull\U0001f4a9", "qemu-bull\\xf0\\x9f\\x92\\xa9"); + + # define TESTS_PM_SUPPORT_HELPER(name, function) \ + do { \ +-- +2.7.2 + diff --git a/SOURCES/libvirt-systemd-Modernize-machine-naming.patch b/SOURCES/libvirt-systemd-Modernize-machine-naming.patch new file mode 100644 index 0000000..be1046c --- /dev/null +++ b/SOURCES/libvirt-systemd-Modernize-machine-naming.patch @@ -0,0 +1,905 @@ +From fdceac0494012ade9dddac2afe2965538f26206e Mon Sep 17 00:00:00 2001 +Message-Id: +From: Martin Kletzander +Date: Tue, 16 Feb 2016 11:55:09 +0100 +Subject: [PATCH] systemd: Modernize machine naming + +https://bugzilla.redhat.com/show_bug.cgi?id=1308494 + +So, systemd-machined has this philosophy that machine names are like +hostnames and hence should follow the same rules. But we always allowed +international characters in domain names. Thus we need to modify the +machine name we are passing to systemd. + +In order to change some machine names that we will be passing to systemd, +we also need to call TerminateMachine at the end of a lifetime of a +domain. Even for domains that were started with older libvirt. That +can be achieved thanks to virSystemdGetMachineNameByPID(). And because +we can change machine names, we can get rid of the inconsistent and +pointless escaping of domain names when creating machine names. + +So this patch modifies the naming in the following way. It creates the +name as -- where invalid hostname characters are +stripped out of the name and if the resulting name is longer, it +truncates it to 64 characters. That way we can start domains we +couldn't start before. Well, at least on systemd. + +To make it work all together, the machineName (which is needed only with +systemd) is saved in domain's private data. That way the generation is +moved to the driver and we don't need to pass various unnecessary +arguments to cgroup functions. + +The only thing this complicates a bit is the scope generation when +validating a cgroup where we must check both old and new naming, so a +slight modification was needed there. + +Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1282846 + +Signed-off-by: Martin Kletzander +(cherry picked from commit c3bd0019c0e3f080dbf0d4bd08245ffb2daa2765) +Signed-off-by: Martin Kletzander + +Conflicts: + src/qemu/qemu_process.c - fe422b673b4b8 (context) + +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/lxc/lxc_cgroup.c | 13 +++++++-- + src/lxc/lxc_domain.h | 1 + + src/lxc/lxc_process.c | 20 +++++++++---- + src/qemu/qemu_cgroup.c | 28 +++++++++++++----- + src/qemu/qemu_cgroup.h | 2 +- + src/qemu/qemu_domain.h | 1 + + src/qemu/qemu_process.c | 4 +-- + src/util/vircgroup.c | 59 ++++++++++++++++++++++++-------------- + src/util/vircgroup.h | 12 ++++---- + src/util/virsystemd.c | 75 +++++++++++++++++++++++++++++++++---------------- + src/util/virsystemd.h | 13 ++++----- + tests/virsystemdtest.c | 67 +++++++++++++++++++++++++------------------ + 12 files changed, 191 insertions(+), 104 deletions(-) + +diff --git a/src/lxc/lxc_cgroup.c b/src/lxc/lxc_cgroup.c +index ad254e4..3148946 100644 +--- a/src/lxc/lxc_cgroup.c ++++ b/src/lxc/lxc_cgroup.c +@@ -29,6 +29,7 @@ + #include "viralloc.h" + #include "vircgroup.h" + #include "virstring.h" ++#include "virsystemd.h" + + #define VIR_FROM_THIS VIR_FROM_LXC + +@@ -483,6 +484,13 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, + int *nicindexes) + { + virCgroupPtr cgroup = NULL; ++ char *machineName = virSystemdMakeMachineName("lxc", ++ def->id, ++ def->name, ++ true); ++ ++ if (!machineName) ++ goto cleanup; + + if (def->resource->partition[0] != '/') { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, +@@ -491,9 +499,8 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, + goto cleanup; + } + +- if (virCgroupNewMachine(def->name, ++ if (virCgroupNewMachine(machineName, + "lxc", +- true, + def->uuid, + NULL, + initpid, +@@ -517,6 +524,8 @@ virCgroupPtr virLXCCgroupCreate(virDomainDefPtr def, + } + + cleanup: ++ VIR_FREE(machineName); ++ + return cgroup; + } + +diff --git a/src/lxc/lxc_domain.h b/src/lxc/lxc_domain.h +index 751aece..a9e319c 100644 +--- a/src/lxc/lxc_domain.h ++++ b/src/lxc/lxc_domain.h +@@ -39,6 +39,7 @@ struct _virLXCDomainObjPrivate { + pid_t initpid; + + virCgroupPtr cgroup; ++ char *machineName; + }; + + extern virDomainXMLPrivateDataCallbacks virLXCDriverPrivateDataCallbacks; +diff --git a/src/lxc/lxc_process.c b/src/lxc/lxc_process.c +index 87ee484..2eaad7d 100644 +--- a/src/lxc/lxc_process.c ++++ b/src/lxc/lxc_process.c +@@ -216,8 +216,7 @@ static void virLXCProcessCleanup(virLXCDriverPtr driver, + * properly. See https://bugs.freedesktop.org/show_bug.cgi?id=68370 for + * the bug we are working around here. + */ +- virSystemdTerminateMachine(vm->def->name, "lxc", true); +- ++ virCgroupTerminateMachine(priv->machineName); + + /* The "release" hook cleans up additional resources */ + if (virHookPresent(VIR_HOOK_DRIVER_LXC)) { +@@ -1318,8 +1317,9 @@ int virLXCProcessStart(virConnectPtr conn, + * point so lets detect that first, since it gives us a + * more reliable way to kill everything off if something + * goes wrong from here onwards ... */ +- if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid, +- -1, &priv->cgroup) < 0) ++ if (virCgroupNewDetectMachine(vm->def->name, "lxc", ++ vm->def->id, true, ++ vm->pid, -1, &priv->cgroup) < 0) + goto cleanup; + + if (!priv->cgroup) { +@@ -1329,6 +1329,11 @@ int virLXCProcessStart(virConnectPtr conn, + goto cleanup; + } + ++ /* Get the machine name so we can properly delete it through ++ * systemd later */ ++ if (!(priv->machineName = virSystemdGetMachineNameByPID(vm->pid))) ++ virResetLastError(); ++ + /* And we can get the first monitor connection now too */ + if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm))) { + /* Intentionally overwrite the real monitor error message, +@@ -1501,8 +1506,8 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm, + if (!(priv->monitor = virLXCProcessConnectMonitor(driver, vm))) + goto error; + +- if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->pid, +- -1, &priv->cgroup) < 0) ++ if (virCgroupNewDetectMachine(vm->def->name, "lxc", vm->def->id, true, ++ vm->pid, -1, &priv->cgroup) < 0) + goto error; + + if (!priv->cgroup) { +@@ -1512,6 +1517,9 @@ virLXCProcessReconnectDomain(virDomainObjPtr vm, + goto error; + } + ++ if (!(priv->machineName = virSystemdGetMachineNameByPID(vm->pid))) ++ virResetLastError(); ++ + if (virLXCUpdateActiveUSBHostdevs(driver, vm->def) < 0) + goto error; + +diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c +index 0da6c02..448183f 100644 +--- a/src/qemu/qemu_cgroup.c ++++ b/src/qemu/qemu_cgroup.c +@@ -36,6 +36,7 @@ + #include "virfile.h" + #include "virtypedparam.h" + #include "virnuma.h" ++#include "virsystemd.h" + + #define VIR_FROM_THIS VIR_FROM_QEMU + +@@ -753,9 +754,19 @@ qemuInitCgroup(virQEMUDriverPtr driver, + goto cleanup; + } + +- if (virCgroupNewMachine(vm->def->name, ++ /* ++ * We need to do this because of systemd-machined, because ++ * CreateMachine requires the name to be a valid hostname. ++ */ ++ priv->machineName = virSystemdMakeMachineName("qemu", ++ vm->def->id, ++ vm->def->name, ++ virQEMUDriverIsPrivileged(driver)); ++ if (!priv->machineName) ++ goto cleanup; ++ ++ if (virCgroupNewMachine(priv->machineName, + "qemu", +- true, + vm->def->uuid, + NULL, + vm->pid, +@@ -864,11 +875,17 @@ qemuConnectCgroup(virQEMUDriverPtr driver, + + if (virCgroupNewDetectMachine(vm->def->name, + "qemu", ++ vm->def->id, ++ virQEMUDriverIsPrivileged(driver), + vm->pid, + cfg->cgroupControllers, + &priv->cgroup) < 0) + goto cleanup; + ++ priv->machineName = virSystemdGetMachineNameByPID(vm->pid); ++ if (!priv->machineName) ++ virResetLastError(); ++ + qemuRestoreCgroupState(vm); + + done: +@@ -1250,17 +1267,14 @@ qemuSetupCgroupForIOThreads(virDomainObjPtr vm) + } + + int +-qemuRemoveCgroup(virQEMUDriverPtr driver, +- virDomainObjPtr vm) ++qemuRemoveCgroup(virDomainObjPtr vm) + { + qemuDomainObjPrivatePtr priv = vm->privateData; + + if (priv->cgroup == NULL) + return 0; /* Not supported, so claim success */ + +- if (virCgroupTerminateMachine(vm->def->name, +- "qemu", +- virQEMUDriverIsPrivileged(driver)) < 0) { ++ if (virCgroupTerminateMachine(priv->machineName) < 0) { + if (!virCgroupNewIgnoreError()) + VIR_DEBUG("Failed to terminate cgroup for %s", vm->def->name); + } +diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h +index 711a6de..3fc313f 100644 +--- a/src/qemu/qemu_cgroup.h ++++ b/src/qemu/qemu_cgroup.h +@@ -56,7 +56,7 @@ int qemuSetupCgroupCpusetCpus(virCgroupPtr cgroup, virBitmapPtr cpumask); + int qemuSetupCgroupForVcpu(virDomainObjPtr vm); + int qemuSetupCgroupForIOThreads(virDomainObjPtr vm); + int qemuSetupCgroupForEmulator(virDomainObjPtr vm); +-int qemuRemoveCgroup(virQEMUDriverPtr driver, virDomainObjPtr vm); ++int qemuRemoveCgroup(virDomainObjPtr vm); + int qemuAddToCgroup(virDomainObjPtr vm); + + #endif /* __QEMU_CGROUP_H__ */ +diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h +index 32f713b..8d4e099 100644 +--- a/src/qemu/qemu_domain.h ++++ b/src/qemu/qemu_domain.h +@@ -202,6 +202,7 @@ struct _qemuDomainObjPrivate { + + bool signalIOError; /* true if the domain condition should be signalled on + I/O error */ ++ char *machineName; + }; + + # define QEMU_DOMAIN_DISK_PRIVATE(disk) \ +diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c +index ed01bf4..1d06b6d 100644 +--- a/src/qemu/qemu_process.c ++++ b/src/qemu/qemu_process.c +@@ -4540,7 +4540,7 @@ int qemuProcessStart(virConnectPtr conn, + /* Ensure no historical cgroup for this VM is lying around bogus + * settings */ + VIR_DEBUG("Ensuring no historical cgroup is lying around"); +- qemuRemoveCgroup(driver, vm); ++ qemuRemoveCgroup(vm); + + for (i = 0; i < vm->def->ngraphics; ++i) { + virDomainGraphicsDefPtr graphics = vm->def->graphics[i]; +@@ -5390,7 +5390,7 @@ void qemuProcessStop(virQEMUDriverPtr driver, + } + + retry: +- if ((ret = qemuRemoveCgroup(driver, vm)) < 0) { ++ if ((ret = qemuRemoveCgroup(vm)) < 0) { + if (ret == -EBUSY && (retries++ < 5)) { + usleep(200*1000); + goto retry; +diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c +index c94512a..b43edb2 100644 +--- a/src/util/vircgroup.c ++++ b/src/util/vircgroup.c +@@ -243,12 +243,17 @@ static bool + virCgroupValidateMachineGroup(virCgroupPtr group, + const char *name, + const char *drivername, ++ int id, ++ bool privileged, + bool stripEmulatorSuffix) + { + size_t i; + bool valid = false; +- char *partname; +- char *scopename; ++ char *partname = NULL; ++ char *scopename_old = NULL; ++ char *scopename_new = NULL; ++ char *machinename = virSystemdMakeMachineName(drivername, id, ++ name, privileged); + + if (virAsprintf(&partname, "%s.libvirt-%s", + name, drivername) < 0) +@@ -257,10 +262,21 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + if (virCgroupPartitionEscape(&partname) < 0) + goto cleanup; + +- if (!(scopename = virSystemdMakeScopeName(name, drivername))) ++ if (!(scopename_old = virSystemdMakeScopeName(name, drivername, true))) + goto cleanup; + +- if (virCgroupPartitionEscape(&scopename) < 0) ++ /* We should keep trying even if this failed */ ++ if (!machinename) ++ virResetLastError(); ++ else if (!(scopename_new = virSystemdMakeScopeName(machinename, ++ drivername, false))) ++ goto cleanup; ++ ++ if (virCgroupPartitionEscape(&scopename_old) < 0) ++ goto cleanup; ++ ++ if (scopename_new && ++ virCgroupPartitionEscape(&scopename_new) < 0) + goto cleanup; + + for (i = 0; i < VIR_CGROUP_CONTROLLER_LAST; i++) { +@@ -290,12 +306,15 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + tmp++; + + if (STRNEQ(tmp, name) && ++ STRNEQ_NULLABLE(tmp, machinename) && + STRNEQ(tmp, partname) && +- STRNEQ(tmp, scopename)) { ++ STRNEQ(tmp, scopename_old) && ++ STRNEQ_NULLABLE(tmp, scopename_new)) { + VIR_DEBUG("Name '%s' for controller '%s' does not match " +- "'%s', '%s' or '%s'", ++ "'%s', '%s', '%s', '%s' or '%s'", + tmp, virCgroupControllerTypeToString(i), +- name, partname, scopename); ++ name, NULLSTR(machinename), partname, ++ scopename_old, NULLSTR(scopename_new)); + goto cleanup; + } + } +@@ -304,7 +323,9 @@ virCgroupValidateMachineGroup(virCgroupPtr group, + + cleanup: + VIR_FREE(partname); +- VIR_FREE(scopename); ++ VIR_FREE(scopename_old); ++ VIR_FREE(scopename_new); ++ VIR_FREE(machinename); + return valid; + } + +@@ -1555,6 +1576,8 @@ virCgroupNewDetect(pid_t pid, + int + virCgroupNewDetectMachine(const char *name, + const char *drivername, ++ int id, ++ bool privileged, + pid_t pid, + int controllers, + virCgroupPtr *group) +@@ -1565,7 +1588,8 @@ virCgroupNewDetectMachine(const char *name, + return -1; + } + +- if (!virCgroupValidateMachineGroup(*group, name, drivername, true)) { ++ if (!virCgroupValidateMachineGroup(*group, name, drivername, ++ id, privileged, true)) { + VIR_DEBUG("Failed to validate machine name for '%s' driver '%s'", + name, drivername); + virCgroupFree(group); +@@ -1582,7 +1606,6 @@ virCgroupNewDetectMachine(const char *name, + static int + virCgroupNewMachineSystemd(const char *name, + const char *drivername, +- bool privileged, + const unsigned char *uuid, + const char *rootdir, + pid_t pidleader, +@@ -1602,7 +1625,6 @@ virCgroupNewMachineSystemd(const char *name, + VIR_DEBUG("Trying to setup machine '%s' via systemd", name); + if ((rv = virSystemdCreateMachine(name, + drivername, +- privileged, + uuid, + rootdir, + pidleader, +@@ -1690,11 +1712,9 @@ virCgroupNewMachineSystemd(const char *name, + /* + * Returns 0 on success, -1 on fatal error + */ +-int virCgroupTerminateMachine(const char *name, +- const char *drivername, +- bool privileged) ++int virCgroupTerminateMachine(const char *name) + { +- return virSystemdTerminateMachine(name, drivername, privileged); ++ return virSystemdTerminateMachine(name); + } + + +@@ -1749,7 +1769,6 @@ virCgroupNewMachineManual(const char *name, + int + virCgroupNewMachine(const char *name, + const char *drivername, +- bool privileged, + const unsigned char *uuid, + const char *rootdir, + pid_t pidleader, +@@ -1766,7 +1785,6 @@ virCgroupNewMachine(const char *name, + + if ((rv = virCgroupNewMachineSystemd(name, + drivername, +- privileged, + uuid, + rootdir, + pidleader, +@@ -4220,6 +4238,8 @@ virCgroupNewDetect(pid_t pid ATTRIBUTE_UNUSED, + int + virCgroupNewDetectMachine(const char *name ATTRIBUTE_UNUSED, + const char *drivername ATTRIBUTE_UNUSED, ++ int id ATTRIBUTE_UNUSED, ++ bool privileged ATTRIBUTE_UNUSED, + pid_t pid ATTRIBUTE_UNUSED, + int controllers ATTRIBUTE_UNUSED, + virCgroupPtr *group ATTRIBUTE_UNUSED) +@@ -4230,9 +4250,7 @@ virCgroupNewDetectMachine(const char *name ATTRIBUTE_UNUSED, + } + + +-int virCgroupTerminateMachine(const char *name ATTRIBUTE_UNUSED, +- const char *drivername ATTRIBUTE_UNUSED, +- bool privileged ATTRIBUTE_UNUSED) ++int virCgroupTerminateMachine(const char *name ATTRIBUTE_UNUSED) + { + virReportSystemError(ENXIO, "%s", + _("Control groups not supported on this platform")); +@@ -4243,7 +4261,6 @@ int virCgroupTerminateMachine(const char *name ATTRIBUTE_UNUSED, + int + virCgroupNewMachine(const char *name ATTRIBUTE_UNUSED, + const char *drivername ATTRIBUTE_UNUSED, +- bool privileged ATTRIBUTE_UNUSED, + const unsigned char *uuid ATTRIBUTE_UNUSED, + const char *rootdir ATTRIBUTE_UNUSED, + pid_t pidleader ATTRIBUTE_UNUSED, +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 63a9e1c..6570cb3 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -91,13 +91,15 @@ int virCgroupNewDetect(pid_t pid, + + int virCgroupNewDetectMachine(const char *name, + const char *drivername, ++ int id, ++ bool privileged, + pid_t pid, + int controllers, +- virCgroupPtr *group); ++ virCgroupPtr *group) ++ ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); + + int virCgroupNewMachine(const char *name, + const char *drivername, +- bool privileged, + const unsigned char *uuid, + const char *rootdir, + pid_t pidleader, +@@ -110,10 +112,8 @@ int virCgroupNewMachine(const char *name, + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) + ATTRIBUTE_NONNULL(4); + +-int virCgroupTerminateMachine(const char *name, +- const char *drivername, +- bool privileged) +- ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2); ++int virCgroupTerminateMachine(const char *name) ++ ATTRIBUTE_NONNULL(1); + + bool virCgroupNewIgnoreError(void); + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index daaa37c..0f4e1f0 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -27,6 +27,7 @@ + + #include "virsystemd.h" + #include "viratomic.h" ++#include "virbuffer.h" + #include "virdbus.h" + #include "virstring.h" + #include "viralloc.h" +@@ -78,15 +79,17 @@ static void virSystemdEscapeName(virBufferPtr buf, + #undef VALID_CHARS + } + +- + char *virSystemdMakeScopeName(const char *name, +- const char *drivername) ++ const char *drivername, ++ bool legacy_behaviour) + { + virBuffer buf = VIR_BUFFER_INITIALIZER; + + virBufferAddLit(&buf, "machine-"); +- virSystemdEscapeName(&buf, drivername); +- virBufferAddLit(&buf, "\\x2d"); ++ if (legacy_behaviour) { ++ virSystemdEscapeName(&buf, drivername); ++ virBufferAddLit(&buf, "\\x2d"); ++ } + virSystemdEscapeName(&buf, name); + virBufferAddLit(&buf, ".scope"); + +@@ -113,10 +116,42 @@ char *virSystemdMakeSliceName(const char *partition) + return virBufferContentAndReset(&buf); + } + ++#define HOSTNAME_CHARS \ ++ "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-" + +-char *virSystemdMakeMachineName(const char *name, +- const char *drivername, +- bool privileged) ++static void ++virSystemdAppendValidMachineName(virBufferPtr buf, ++ const char *name) ++{ ++ bool skip_dot = false; ++ ++ for (; *name; name++) { ++ if (strlen(virBufferCurrentContent(buf)) >= 64) ++ break; ++ ++ if (*name == '.') { ++ if (!skip_dot) ++ virBufferAddChar(buf, *name); ++ skip_dot = true; ++ continue; ++ } ++ ++ skip_dot = false; ++ ++ if (!strchr(HOSTNAME_CHARS, *name)) ++ continue; ++ ++ virBufferAddChar(buf, *name); ++ } ++} ++ ++#undef HOSTNAME_CHARS ++ ++char * ++virSystemdMakeMachineName(const char *drivername, ++ int id, ++ const char *name, ++ bool privileged) + { + char *machinename = NULL; + char *username = NULL; +@@ -131,7 +166,8 @@ char *virSystemdMakeMachineName(const char *name, + virBufferAsprintf(&buf, "%s-%s-", username, drivername); + } + +- virSystemdEscapeName(&buf, name); ++ virBufferAsprintf(&buf, "%d-", id); ++ virSystemdAppendValidMachineName(&buf, name); + + machinename = virBufferContentAndReset(&buf); + cleanup: +@@ -212,7 +248,6 @@ virSystemdGetMachineNameByPID(pid_t pid) + */ + int virSystemdCreateMachine(const char *name, + const char *drivername, +- bool privileged, + const unsigned char *uuid, + const char *rootdir, + pid_t pidleader, +@@ -223,7 +258,6 @@ int virSystemdCreateMachine(const char *name, + { + int ret; + DBusConnection *conn; +- char *machinename = NULL; + char *creatorname = NULL; + char *slicename = NULL; + static int hasCreateWithNetwork = 1; +@@ -239,8 +273,6 @@ int virSystemdCreateMachine(const char *name, + return -1; + + ret = -1; +- if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged))) +- goto cleanup; + + if (virAsprintf(&creatorname, "libvirt-%s", drivername) < 0) + goto cleanup; +@@ -318,7 +350,7 @@ int virSystemdCreateMachine(const char *name, + "org.freedesktop.machine1.Manager", + "CreateMachineWithNetwork", + "sayssusa&ia(sv)", +- machinename, ++ name, + 16, + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], +@@ -360,7 +392,7 @@ int virSystemdCreateMachine(const char *name, + "org.freedesktop.machine1.Manager", + "CreateMachine", + "sayssusa(sv)", +- machinename, ++ name, + 16, + uuid[0], uuid[1], uuid[2], uuid[3], + uuid[4], uuid[5], uuid[6], uuid[7], +@@ -381,20 +413,19 @@ int virSystemdCreateMachine(const char *name, + + cleanup: + VIR_FREE(creatorname); +- VIR_FREE(machinename); + VIR_FREE(slicename); + return ret; + } + +-int virSystemdTerminateMachine(const char *name, +- const char *drivername, +- bool privileged) ++int virSystemdTerminateMachine(const char *name) + { + int ret; + DBusConnection *conn; +- char *machinename = NULL; + virError error; + ++ if (!name) ++ return 0; ++ + memset(&error, 0, sizeof(error)); + + ret = virDBusIsServiceEnabled("org.freedesktop.machine1"); +@@ -409,9 +440,6 @@ int virSystemdTerminateMachine(const char *name, + if (!(conn = virDBusGetSystemBus())) + goto cleanup; + +- if (!(machinename = virSystemdMakeMachineName(name, drivername, privileged))) +- goto cleanup; +- + /* + * The systemd DBus API we're invoking has the + * following signature +@@ -431,7 +459,7 @@ int virSystemdTerminateMachine(const char *name, + "org.freedesktop.machine1.Manager", + "TerminateMachine", + "s", +- machinename) < 0) ++ name) < 0) + goto cleanup; + + if (error.code == VIR_ERR_ERROR && +@@ -446,7 +474,6 @@ int virSystemdTerminateMachine(const char *name, + cleanup: + virResetError(&error); + +- VIR_FREE(machinename); + return ret; + } + +diff --git a/src/util/virsystemd.h b/src/util/virsystemd.h +index a13a4c0..93b0aae 100644 +--- a/src/util/virsystemd.h ++++ b/src/util/virsystemd.h +@@ -25,16 +25,17 @@ + # include "internal.h" + + char *virSystemdMakeScopeName(const char *name, +- const char *drivername); ++ const char *drivername, ++ bool legacy_behaviour); + char *virSystemdMakeSliceName(const char *partition); + +-char *virSystemdMakeMachineName(const char *name, +- const char *drivername, ++char *virSystemdMakeMachineName(const char *drivername, ++ int id, ++ const char *name, + bool privileged); + + int virSystemdCreateMachine(const char *name, + const char *drivername, +- bool privileged, + const unsigned char *uuid, + const char *rootdir, + pid_t pidleader, +@@ -43,9 +44,7 @@ int virSystemdCreateMachine(const char *name, + int *nicindexes, + const char *partition); + +-int virSystemdTerminateMachine(const char *name, +- const char *drivername, +- bool privileged); ++int virSystemdTerminateMachine(const char *name); + + void virSystemdNotifyStartup(void); + +diff --git a/tests/virsystemdtest.c b/tests/virsystemdtest.c +index 3a3cd99..46452dd 100644 +--- a/tests/virsystemdtest.c ++++ b/tests/virsystemdtest.c +@@ -166,7 +166,6 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED) + }; + if (virSystemdCreateMachine("demo", + "lxc", +- true, + uuid, + "/proc/123/root", + 123, +@@ -182,9 +181,7 @@ static int testCreateContainer(const void *opaque ATTRIBUTE_UNUSED) + + static int testTerminateContainer(const void *opaque ATTRIBUTE_UNUSED) + { +- if (virSystemdTerminateMachine("demo", +- "lxc", +- true) < 0) { ++ if (virSystemdTerminateMachine("lxc-demo") < 0) { + fprintf(stderr, "%s", "Failed to terminate LXC machine\n"); + return -1; + } +@@ -202,7 +199,6 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED) + }; + if (virSystemdCreateMachine("demo", + "qemu", +- false, + uuid, + NULL, + 123, +@@ -218,9 +214,7 @@ static int testCreateMachine(const void *opaque ATTRIBUTE_UNUSED) + + static int testTerminateMachine(const void *opaque ATTRIBUTE_UNUSED) + { +- if (virSystemdTerminateMachine("demo", +- "qemu", +- false) < 0) { ++ if (virSystemdTerminateMachine("test-qemu-demo") < 0) { + fprintf(stderr, "%s", "Failed to terminate KVM machine\n"); + return -1; + } +@@ -242,7 +236,6 @@ static int testCreateNoSystemd(const void *opaque ATTRIBUTE_UNUSED) + + if ((rv = virSystemdCreateMachine("demo", + "qemu", +- true, + uuid, + NULL, + 123, +@@ -277,7 +270,6 @@ static int testCreateSystemdNotRunning(const void *opaque ATTRIBUTE_UNUSED) + + if ((rv = virSystemdCreateMachine("demo", + "qemu", +- true, + uuid, + NULL, + 123, +@@ -312,7 +304,6 @@ static int testCreateBadSystemd(const void *opaque ATTRIBUTE_UNUSED) + + if ((rv = virSystemdCreateMachine("demo", + "qemu", +- true, + uuid, + NULL, + 123, +@@ -348,7 +339,6 @@ static int testCreateNetwork(const void *opaque ATTRIBUTE_UNUSED) + size_t nnicindexes = ARRAY_CARDINALITY(nicindexes); + if (virSystemdCreateMachine("demo", + "lxc", +- true, + uuid, + "/proc/123/root", + 123, +@@ -385,6 +375,8 @@ testGetMachineName(const void *opaque ATTRIBUTE_UNUSED) + struct testNameData { + const char *name; + const char *expected; ++ int id; ++ bool legacy; + }; + + static int +@@ -394,7 +386,7 @@ testScopeName(const void *opaque) + int ret = -1; + char *actual = NULL; + +- if (!(actual = virSystemdMakeScopeName(data->name, "lxc"))) ++ if (!(actual = virSystemdMakeScopeName(data->name, "lxc", data->legacy))) + goto cleanup; + + if (STRNEQ(actual, data->expected)) { +@@ -417,7 +409,8 @@ testMachineName(const void *opaque) + int ret = -1; + char *actual = NULL; + +- if (!(actual = virSystemdMakeMachineName(data->name, "qemu", true))) ++ if (!(actual = virSystemdMakeMachineName("qemu", data->id, ++ data->name, true))) + goto cleanup; + + if (STRNEQ(actual, data->expected)) { +@@ -518,6 +511,12 @@ mymain(void) + { + int ret = 0; + ++ unsigned char uuid[VIR_UUID_BUFLEN]; ++ ++ /* The one we use in tests quite often */ ++ if (virUUIDParse("c7a5fdbd-edaf-9455-926a-d65c16db1809", uuid) < 0) ++ return EXIT_FAILURE; ++ + if (virtTestRun("Test create container ", testCreateContainer, NULL) < 0) + ret = -1; + if (virtTestRun("Test terminate container ", testTerminateContainer, NULL) < 0) +@@ -538,35 +537,47 @@ mymain(void) + if (virtTestRun("Test getting machine name ", testGetMachineName, NULL) < 0) + ret = -1; + +-# define TEST_SCOPE(name, unitname) \ ++# define TEST_SCOPE(_name, unitname, _legacy) \ + do { \ + struct testNameData data = { \ +- name, unitname \ ++ .name = _name, .expected = unitname, .legacy = _legacy, \ + }; \ + if (virtTestRun("Test scopename", testScopeName, &data) < 0) \ + ret = -1; \ + } while (0) + +- TEST_SCOPE("demo", "machine-lxc\\x2ddemo.scope"); +- TEST_SCOPE("demo-name", "machine-lxc\\x2ddemo\\x2dname.scope"); +- TEST_SCOPE("demo!name", "machine-lxc\\x2ddemo\\x21name.scope"); +- TEST_SCOPE(".demo", "machine-lxc\\x2d\\x2edemo.scope"); +- TEST_SCOPE("bull💩", "machine-lxc\\x2dbull\\xf0\\x9f\\x92\\xa9.scope"); ++# define TEST_SCOPE_OLD(name, unitname) \ ++ TEST_SCOPE(name, unitname, true) ++# define TEST_SCOPE_NEW(name, unitname) \ ++ TEST_SCOPE(name, unitname, false) + +-# define TEST_MACHINE(name, machinename) \ ++ TEST_SCOPE_OLD("demo", "machine-lxc\\x2ddemo.scope"); ++ TEST_SCOPE_OLD("demo-name", "machine-lxc\\x2ddemo\\x2dname.scope"); ++ TEST_SCOPE_OLD("demo!name", "machine-lxc\\x2ddemo\\x21name.scope"); ++ TEST_SCOPE_OLD(".demo", "machine-lxc\\x2d\\x2edemo.scope"); ++ TEST_SCOPE_OLD("bull💩", "machine-lxc\\x2dbull\\xf0\\x9f\\x92\\xa9.scope"); ++ ++ TEST_SCOPE_NEW("qemu-3-demo", "machine-qemu\\x2d3\\x2ddemo.scope"); ++ ++# define TEST_MACHINE(_name, _id, machinename) \ + do { \ + struct testNameData data = { \ +- name, machinename \ ++ .name = _name, .expected = machinename, .id = _id, \ + }; \ + if (virtTestRun("Test scopename", testMachineName, &data) < 0) \ + ret = -1; \ + } while (0) + +- TEST_MACHINE("demo", "qemu-demo"); +- TEST_MACHINE("demo-name", "qemu-demo\\x2dname"); +- TEST_MACHINE("demo!name", "qemu-demo\\x21name"); +- TEST_MACHINE(".demo", "qemu-\\x2edemo"); +- TEST_MACHINE("bull\U0001f4a9", "qemu-bull\\xf0\\x9f\\x92\\xa9"); ++ TEST_MACHINE("demo", 1, "qemu-1-demo"); ++ TEST_MACHINE("demo-name", 2, "qemu-2-demo-name"); ++ TEST_MACHINE("demo!name", 3, "qemu-3-demoname"); ++ TEST_MACHINE(".demo", 4, "qemu-4-.demo"); ++ TEST_MACHINE("bull\U0001f4a9", 5, "qemu-5-bull"); ++ TEST_MACHINE("demo..name", 6, "qemu-6-demo.name"); ++ TEST_MACHINE("12345678901234567890123456789012345678901234567890123456789", 7, ++ "qemu-7-123456789012345678901234567890123456789012345678901234567"); ++ TEST_MACHINE("123456789012345678901234567890123456789012345678901234567890", 8, ++ "qemu-8-123456789012345678901234567890123456789012345678901234567"); + + # define TESTS_PM_SUPPORT_HELPER(name, function) \ + do { \ +-- +2.7.2 + diff --git a/SOURCES/libvirt-util-Fix-virCgroupNewMachine-ATTRIBUTE_NONNULL-args.patch b/SOURCES/libvirt-util-Fix-virCgroupNewMachine-ATTRIBUTE_NONNULL-args.patch new file mode 100644 index 0000000..1d35557 --- /dev/null +++ b/SOURCES/libvirt-util-Fix-virCgroupNewMachine-ATTRIBUTE_NONNULL-args.patch @@ -0,0 +1,34 @@ +From 8ff6234dc3f9d3d83bc104b4b3c0515f48aa305a Mon Sep 17 00:00:00 2001 +Message-Id: <8ff6234dc3f9d3d83bc104b4b3c0515f48aa305a@dist-git> +From: John Ferlan +Date: Tue, 16 Feb 2016 11:55:11 +0100 +Subject: [PATCH] util: Fix virCgroupNewMachine ATTRIBUTE_NONNULL args + +https://bugzilla.redhat.com/show_bug.cgi?id=1308494 + +Commit id 'c3bd0019c0' removed arg3, but forgot to adjust the numbers +for NONNULL - caused build failure for coverity + +(cherry picked from commit b8c0f186543c01cbda95c7251a0a992823764df5) +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/util/vircgroup.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h +index 6570cb3..b98e416 100644 +--- a/src/util/vircgroup.h ++++ b/src/util/vircgroup.h +@@ -110,7 +110,7 @@ int virCgroupNewMachine(const char *name, + int controllers, + virCgroupPtr *group) + ATTRIBUTE_NONNULL(1) ATTRIBUTE_NONNULL(2) +- ATTRIBUTE_NONNULL(4); ++ ATTRIBUTE_NONNULL(3); + + int virCgroupTerminateMachine(const char *name) + ATTRIBUTE_NONNULL(1); +-- +2.7.2 + diff --git a/SOURCES/libvirt-virSystemdGetMachineNameByPID-Initialize-reply.patch b/SOURCES/libvirt-virSystemdGetMachineNameByPID-Initialize-reply.patch new file mode 100644 index 0000000..55da3e7 --- /dev/null +++ b/SOURCES/libvirt-virSystemdGetMachineNameByPID-Initialize-reply.patch @@ -0,0 +1,38 @@ +From 704cb78bdb0b5bbb8409d2795b82d3936aae6f2b Mon Sep 17 00:00:00 2001 +Message-Id: <704cb78bdb0b5bbb8409d2795b82d3936aae6f2b@dist-git> +From: Michal Privoznik +Date: Tue, 16 Feb 2016 11:55:10 +0100 +Subject: [PATCH] virSystemdGetMachineNameByPID: Initialize @reply + +https://bugzilla.redhat.com/show_bug.cgi?id=1308494 + +I've noticed that variable @reply is not initialized and if +something at the beginning of the function fails, e.g. +virDBusGetSystemBus(), the control jump straight to cleanup label +where dbus_message_unref() is then called over this uninitialized +variable. + +Signed-off-by: Michal Privoznik +(cherry picked from commit a3b168d01a6254a5972d4eda87d7cbc3d9cdb3ef) +Signed-off-by: Martin Kletzander +Signed-off-by: Jiri Denemark +--- + src/util/virsystemd.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/util/virsystemd.c b/src/util/virsystemd.c +index 0f4e1f0..7bc5d55 100644 +--- a/src/util/virsystemd.c ++++ b/src/util/virsystemd.c +@@ -181,7 +181,7 @@ char * + virSystemdGetMachineNameByPID(pid_t pid) + { + DBusConnection *conn; +- DBusMessage *reply; ++ DBusMessage *reply = NULL; + char *name = NULL, *object = NULL; + + if (virDBusIsServiceEnabled("org.freedesktop.machine1") < 0) +-- +2.7.2 + diff --git a/SOURCES/libvirt-vmx-Expose-datacenter-path-in-domain-XML.patch b/SOURCES/libvirt-vmx-Expose-datacenter-path-in-domain-XML.patch new file mode 100644 index 0000000..757741d --- /dev/null +++ b/SOURCES/libvirt-vmx-Expose-datacenter-path-in-domain-XML.patch @@ -0,0 +1,384 @@ +From 70e32568957d60bbea5f50fc2d9210e2faaca5cd Mon Sep 17 00:00:00 2001 +Message-Id: <70e32568957d60bbea5f50fc2d9210e2faaca5cd@dist-git> +From: Matthias Bolte +Date: Mon, 8 Feb 2016 13:47:35 +0100 +Subject: [PATCH] vmx: Expose datacenter path in domain XML + +RHEL-7.3: https://bugzilla.redhat.com/show_bug.cgi?id=1263574 +RHEL-7.2.z: https://bugzilla.redhat.com/show_bug.cgi?id=1305489 + +Tool such as libguestfs need the datacenter path to get access to disk +images. The ESX driver knows the correct datacenter path, but this +information cannot be accessed using libvirt API yet. Also, it cannot +be deduced from the connection URI in a robust way. + +Expose the datacenter path in the domain XML as +node similar to the way the node works. The new node +is ignored while parsing the domain XML. In contrast to +it is output only. + +(cherry picked from commit 636a99058758a0447482f3baad94de8de3ab1151) +Signed-off-by: Michal Privoznik +Signed-off-by: Jiri Denemark +--- + src/esx/esx_driver.c | 4 ++ + src/vmware/vmware_conf.c | 3 ++ + src/vmware/vmware_driver.c | 9 ++++ + src/vmx/vmx.c | 68 +++++++++++++++++++++++----- + src/vmx/vmx.h | 10 ++-- + tests/vmx2xmldata/vmx2xml-datacenterpath.vmx | 2 + + tests/vmx2xmldata/vmx2xml-datacenterpath.xml | 19 ++++++++ + tests/vmx2xmltest.c | 5 ++ + tests/xml2vmxdata/xml2vmx-datacenterpath.vmx | 10 ++++ + tests/xml2vmxdata/xml2vmx-datacenterpath.xml | 9 ++++ + tests/xml2vmxtest.c | 3 ++ + 11 files changed, 126 insertions(+), 16 deletions(-) + create mode 100644 tests/vmx2xmldata/vmx2xml-datacenterpath.vmx + create mode 100644 tests/vmx2xmldata/vmx2xml-datacenterpath.xml + create mode 100644 tests/xml2vmxdata/xml2vmx-datacenterpath.vmx + create mode 100644 tests/xml2vmxdata/xml2vmx-datacenterpath.xml + +diff --git a/src/esx/esx_driver.c b/src/esx/esx_driver.c +index c304ff3..5944947 100644 +--- a/src/esx/esx_driver.c ++++ b/src/esx/esx_driver.c +@@ -2741,6 +2741,7 @@ esxDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) + ctx.parseFileName = esxParseVMXFileName; + ctx.formatFileName = NULL; + ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = priv->primary->datacenterPath; + + def = virVMXParseConfig(&ctx, priv->xmlopt, vmx); + +@@ -2799,6 +2800,7 @@ esxConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, + ctx.parseFileName = esxParseVMXFileName; + ctx.formatFileName = NULL; + ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = NULL; + + def = virVMXParseConfig(&ctx, priv->xmlopt, nativeConfig); + +@@ -2853,6 +2855,7 @@ esxConnectDomainXMLToNative(virConnectPtr conn, const char *nativeFormat, + ctx.parseFileName = NULL; + ctx.formatFileName = esxFormatVMXFileName; + ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel; ++ ctx.datacenterPath = NULL; + + vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version); + +@@ -3096,6 +3099,7 @@ esxDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int flags) + ctx.parseFileName = NULL; + ctx.formatFileName = esxFormatVMXFileName; + ctx.autodetectSCSIControllerModel = esxAutodetectSCSIControllerModel; ++ ctx.datacenterPath = NULL; + + vmx = virVMXFormatConfig(&ctx, priv->xmlopt, def, virtualHW_version); + +diff --git a/src/vmware/vmware_conf.c b/src/vmware/vmware_conf.c +index 21cf333..f3cbbf5 100644 +--- a/src/vmware/vmware_conf.c ++++ b/src/vmware/vmware_conf.c +@@ -145,6 +145,9 @@ vmwareLoadDomains(struct vmware_driver *driver) + virCommandPtr cmd; + + ctx.parseFileName = vmwareCopyVMXFileName; ++ ctx.formatFileName = NULL; ++ ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = NULL; + + cmd = virCommandNewArgList(driver->vmrun, "-T", + vmwareDriverTypeToString(driver->type), +diff --git a/src/vmware/vmware_driver.c b/src/vmware/vmware_driver.c +index ec74fe3..e228aaa 100644 +--- a/src/vmware/vmware_driver.c ++++ b/src/vmware/vmware_driver.c +@@ -381,7 +381,10 @@ vmwareDomainDefineXMLFlags(virConnectPtr conn, const char *xml, unsigned int fla + if (flags & VIR_DOMAIN_DEFINE_VALIDATE) + parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE; + ++ ctx.parseFileName = NULL; + ctx.formatFileName = vmwareCopyVMXFileName; ++ ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = NULL; + + vmwareDriverLock(driver); + if ((vmdef = virDomainDefParseString(xml, driver->caps, driver->xmlopt, +@@ -671,7 +674,10 @@ vmwareDomainCreateXML(virConnectPtr conn, const char *xml, + if (flags & VIR_DOMAIN_START_VALIDATE) + parse_flags |= VIR_DOMAIN_DEF_PARSE_VALIDATE; + ++ ctx.parseFileName = NULL; + ctx.formatFileName = vmwareCopyVMXFileName; ++ ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = NULL; + + vmwareDriverLock(driver); + +@@ -1022,6 +1028,9 @@ vmwareConnectDomainXMLFromNative(virConnectPtr conn, const char *nativeFormat, + } + + ctx.parseFileName = vmwareCopyVMXFileName; ++ ctx.formatFileName = NULL; ++ ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = NULL; + + def = virVMXParseConfig(&ctx, driver->xmlopt, nativeConfig); + +diff --git a/src/vmx/vmx.c b/src/vmx/vmx.c +index 805ad60..2befdb2 100644 +--- a/src/vmx/vmx.c ++++ b/src/vmx/vmx.c +@@ -523,10 +523,11 @@ VIR_ENUM_IMPL(virVMXControllerModelSCSI, VIR_DOMAIN_CONTROLLER_MODEL_SCSI_LAST, + /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * + * Helpers + */ ++ + static int +-vmxDomainDefPostParse(virDomainDefPtr def, +- virCapsPtr caps ATTRIBUTE_UNUSED, +- void *opaque ATTRIBUTE_UNUSED) ++virVMXDomainDefPostParse(virDomainDefPtr def, ++ virCapsPtr caps ATTRIBUTE_UNUSED, ++ void *opaque ATTRIBUTE_UNUSED) + { + /* memory hotplug tunables are not supported by this driver */ + if (virDomainDefCheckUnsupportedMemoryHotplug(def) < 0) +@@ -536,27 +537,60 @@ vmxDomainDefPostParse(virDomainDefPtr def, + } + + static int +-vmxDomainDeviceDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, +- const virDomainDef *def ATTRIBUTE_UNUSED, +- virCapsPtr caps ATTRIBUTE_UNUSED, +- void *opaque ATTRIBUTE_UNUSED) ++virVMXDomainDevicesDefPostParse(virDomainDeviceDefPtr dev ATTRIBUTE_UNUSED, ++ const virDomainDef *def ATTRIBUTE_UNUSED, ++ virCapsPtr caps ATTRIBUTE_UNUSED, ++ void *opaque ATTRIBUTE_UNUSED) + { + return 0; + } + +-virDomainDefParserConfig virVMXDomainDefParserConfig = { ++static virDomainDefParserConfig virVMXDomainDefParserConfig = { + .hasWideSCSIBus = true, + .macPrefix = {0x00, 0x0c, 0x29}, +- .devicesPostParseCallback = vmxDomainDeviceDefPostParse, +- .domainPostParseCallback = vmxDomainDefPostParse, ++ .devicesPostParseCallback = virVMXDomainDevicesDefPostParse, ++ .domainPostParseCallback = virVMXDomainDefPostParse, + }; + ++static void ++virVMXDomainDefNamespaceFree(void *nsdata) ++{ ++ VIR_FREE(nsdata); ++} ++ ++static int ++virVMXDomainDefNamespaceFormatXML(virBufferPtr buf, void *nsdata) ++{ ++ const char *datacenterPath = nsdata; ++ ++ if (!datacenterPath) ++ return 0; ++ ++ virBufferAddLit(buf, ""); ++ virBufferEscapeString(buf, "%s", datacenterPath); ++ virBufferAddLit(buf, "\n"); ++ ++ return 0; ++} ++ ++static const char * ++virVMXDomainDefNamespaceHref(void) ++{ ++ return "xmlns:vmware='http://libvirt.org/schemas/domain/vmware/1.0'"; ++} ++ ++static virDomainXMLNamespace virVMXDomainXMLNamespace = { ++ .parse = NULL, ++ .free = virVMXDomainDefNamespaceFree, ++ .format = virVMXDomainDefNamespaceFormatXML, ++ .href = virVMXDomainDefNamespaceHref, ++}; + + virDomainXMLOptionPtr + virVMXDomainXMLConfInit(void) + { +- return virDomainXMLOptionNew(&virVMXDomainDefParserConfig, +- NULL, NULL); ++ return virDomainXMLOptionNew(&virVMXDomainDefParserConfig, NULL, ++ &virVMXDomainXMLNamespace); + } + + char * +@@ -1266,6 +1300,7 @@ virVMXParseConfig(virVMXContext *ctx, + bool hgfs_disabled = true; + long long sharedFolder_maxNum = 0; + int cpumasklen; ++ char *namespaceData; + + if (ctx->parseFileName == NULL) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", +@@ -1765,6 +1800,15 @@ virVMXParseConfig(virVMXContext *ctx, + ++def->nparallels; + } + ++ /* ctx:datacenterPath -> def:namespaceData */ ++ if (ctx->datacenterPath) { ++ if (VIR_STRDUP(namespaceData, ctx->datacenterPath) < 0) ++ goto cleanup; ++ ++ def->ns = *virDomainXMLOptionGetNamespace(xmlopt); ++ def->namespaceData = namespaceData; ++ } ++ + success = true; + + cleanup: +diff --git a/src/vmx/vmx.h b/src/vmx/vmx.h +index 6a68c8b..0f012fd 100644 +--- a/src/vmx/vmx.h ++++ b/src/vmx/vmx.h +@@ -1,7 +1,7 @@ + /* + * vmx.h: VMware VMX parsing/formatting functions + * +- * Copyright (C) 2009-2010 Matthias Bolte ++ * Copyright (C) 2009-2011, 2015 Matthias Bolte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -41,15 +41,17 @@ typedef int (*virVMXAutodetectSCSIControllerModel)(virDomainDiskDefPtr def, + int *model, void *opaque); + + /* +- * virVMXParseFileName is only used by virVMXParseConfig. +- * virVMXFormatFileName is only used by virVMXFormatConfig. +- * virVMXAutodetectSCSIControllerModel is optionally used by virVMXFormatConfig. ++ * parseFileName is only used by virVMXParseConfig. ++ * formatFileName is only used by virVMXFormatConfig. ++ * autodetectSCSIControllerModel is optionally used by virVMXFormatConfig. ++ * datacenterPath is only used by virVMXFormatConfig. + */ + struct _virVMXContext { + void *opaque; + virVMXParseFileName parseFileName; + virVMXFormatFileName formatFileName; + virVMXAutodetectSCSIControllerModel autodetectSCSIControllerModel; ++ const char *datacenterPath; /* including folders */ + }; + + +diff --git a/tests/vmx2xmldata/vmx2xml-datacenterpath.vmx b/tests/vmx2xmldata/vmx2xml-datacenterpath.vmx +new file mode 100644 +index 0000000..a8e5db3 +--- /dev/null ++++ b/tests/vmx2xmldata/vmx2xml-datacenterpath.vmx +@@ -0,0 +1,2 @@ ++config.version = "8" ++virtualHW.version = "4" +diff --git a/tests/vmx2xmldata/vmx2xml-datacenterpath.xml b/tests/vmx2xmldata/vmx2xml-datacenterpath.xml +new file mode 100644 +index 0000000..a690c0f +--- /dev/null ++++ b/tests/vmx2xmldata/vmx2xml-datacenterpath.xml +@@ -0,0 +1,19 @@ ++ ++ 00000000-0000-0000-0000-000000000000 ++ 32768 ++ 32768 ++ 1 ++ ++ hvm ++ ++ ++ destroy ++ restart ++ destroy ++ ++ ++ ++ folder1/folder2/datacenter1 ++ +diff --git a/tests/vmx2xmltest.c b/tests/vmx2xmltest.c +index b8dbd31..258cba3 100644 +--- a/tests/vmx2xmltest.c ++++ b/tests/vmx2xmltest.c +@@ -201,6 +201,7 @@ mymain(void) + ctx.parseFileName = testParseVMXFileName; + ctx.formatFileName = NULL; + ctx.autodetectSCSIControllerModel = NULL; ++ ctx.datacenterPath = NULL; + + DO_TEST("case-insensitive-1", "case-insensitive-1"); + DO_TEST("case-insensitive-2", "case-insensitive-2"); +@@ -283,6 +284,10 @@ mymain(void) + + DO_TEST("svga", "svga"); + ++ ctx.datacenterPath = "folder1/folder2/datacenter1"; ++ ++ DO_TEST("datacenterpath", "datacenterpath"); ++ + virObjectUnref(caps); + virObjectUnref(xmlopt); + +diff --git a/tests/xml2vmxdata/xml2vmx-datacenterpath.vmx b/tests/xml2vmxdata/xml2vmx-datacenterpath.vmx +new file mode 100644 +index 0000000..59bde03 +--- /dev/null ++++ b/tests/xml2vmxdata/xml2vmx-datacenterpath.vmx +@@ -0,0 +1,10 @@ ++.encoding = "UTF-8" ++config.version = "8" ++virtualHW.version = "4" ++guestOS = "other" ++uuid.bios = "56 4d 9b ef ac d9 b4 e0-c8 f0 ae a8 b9 10 35 15" ++displayName = "datacenterpath" ++memsize = "4" ++numvcpus = "1" ++floppy0.present = "false" ++floppy1.present = "false" +diff --git a/tests/xml2vmxdata/xml2vmx-datacenterpath.xml b/tests/xml2vmxdata/xml2vmx-datacenterpath.xml +new file mode 100644 +index 0000000..048e13d +--- /dev/null ++++ b/tests/xml2vmxdata/xml2vmx-datacenterpath.xml +@@ -0,0 +1,9 @@ ++ ++ datacenterpath ++ 564d9bef-acd9-b4e0-c8f0-aea8b9103515 ++ 4096 ++ ++ hvm ++ ++ folder1/folder2/datacenter1 ++ +diff --git a/tests/xml2vmxtest.c b/tests/xml2vmxtest.c +index 0efd278..d970240 100644 +--- a/tests/xml2vmxtest.c ++++ b/tests/xml2vmxtest.c +@@ -221,6 +221,7 @@ mymain(void) + ctx.parseFileName = NULL; + ctx.formatFileName = testFormatVMXFileName; + ctx.autodetectSCSIControllerModel = testAutodetectSCSIControllerModel; ++ ctx.datacenterPath = NULL; + + DO_TEST("minimal", "minimal", 4); + DO_TEST("minimal-64bit", "minimal-64bit", 4); +@@ -295,6 +296,8 @@ mymain(void) + + DO_TEST("svga", "svga", 4); + ++ DO_TEST("datacenterpath", "datacenterpath", 4); ++ + virObjectUnref(caps); + virObjectUnref(xmlopt); + +-- +2.7.2 + diff --git a/SPECS/libvirt.spec b/SPECS/libvirt.spec index dea75a0..6043680 100644 --- a/SPECS/libvirt.spec +++ b/SPECS/libvirt.spec @@ -382,7 +382,7 @@ Summary: Library providing a simple virtualization API Name: libvirt Version: 1.2.17 -Release: 13%{?dist}.3%{?extra_release} +Release: 13%{?dist}.4%{?extra_release} License: LGPLv2+ Group: Development/Libraries BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root @@ -648,6 +648,13 @@ Patch252: libvirt-qemu-Add-ppc64-specific-math-to-qemuDomainGetMlockLimitBytes.p Patch253: libvirt-qemu-Always-set-locked-memory-limit-for-ppc64-domains.patch Patch254: libvirt-qemu-Support-vhost-user-multiqueue-with-QEMU-2.3.patch Patch255: libvirt-vmx-Adapt-to-emptyBackingString-for-cdrom-image.patch +Patch256: libvirt-systemd-Escape-machine-name-for-machined.patch +Patch257: libvirt-systemd-Add-virSystemdGetMachineNameByPID.patch +Patch258: libvirt-systemd-Modernize-machine-naming.patch +Patch259: libvirt-virSystemdGetMachineNameByPID-Initialize-reply.patch +Patch260: libvirt-util-Fix-virCgroupNewMachine-ATTRIBUTE_NONNULL-args.patch +Patch261: libvirt-dbus-Don-t-unref-NULL-messages.patch +Patch262: libvirt-vmx-Expose-datacenter-path-in-domain-XML.patch %if %{with_libvirtd} @@ -2599,6 +2606,15 @@ exit 0 %doc examples/systemtap %changelog +* Wed Mar 2 2016 Jiri Denemark - 1.2.17-13.el7_2.4 +- systemd: Escape machine name for machined (rhbz#1308494) +- systemd: Add virSystemdGetMachineNameByPID (rhbz#1308494) +- systemd: Modernize machine naming (rhbz#1308494) +- virSystemdGetMachineNameByPID: Initialize @reply (rhbz#1308494) +- util: Fix virCgroupNewMachine ATTRIBUTE_NONNULL args (rhbz#1308494) +- dbus: Don't unref NULL messages (rhbz#1308494) +- vmx: Expose datacenter path in domain XML (rhbz#1305489) + * Wed Jan 27 2016 Jiri Denemark - 1.2.17-13.el7_2.3 - vmx: Adapt to emptyBackingString for cdrom-image (rhbz#1301892)