Hello community,

here is the log from the commit of package libvirt for openSUSE:Factory checked 
in at 2018-02-13 10:27:04
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/libvirt (Old)
 and      /work/SRC/openSUSE:Factory/.libvirt.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "libvirt"

Tue Feb 13 10:27:04 2018 rev:250 rq:575802 version:4.0.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/libvirt/libvirt.changes  2018-01-30 
15:38:46.922352045 +0100
+++ /work/SRC/openSUSE:Factory/.libvirt.new/libvirt.changes     2018-02-13 
10:27:05.794080712 +0100
@@ -1,0 +2,15 @@
+Fri Feb  9 13:28:14 UTC 2018 - cbosdon...@suse.com
+
+- Remove all uses of python2 during the build (bsc#1080034)
+    6b3d716e-keycodemap-py3.patch
+    apibuild-py3.patch
+- Determine hostname early to avoid code injection
+  in lxc driver. (bsc#1080042)
+    759b4d1b-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch
+    c2dc6698-fix-deadlock-obtaining-hostname.patch
+- Add basic support of connectGetAllDomainStats for lxc driver
+  (fate#323742)
+    0001-Extract-stats-functions-from-the-qemu-driver.patch
+    0002-lxc-implement-connectGetAllDomainStats.patch
+
+-------------------------------------------------------------------

New:
----
  0001-Extract-stats-functions-from-the-qemu-driver.patch
  0002-lxc-implement-connectGetAllDomainStats.patch
  6b3d716e-keycodemap-py3.patch
  759b4d1b-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch
  apibuild-py3.patch
  c2dc6698-fix-deadlock-obtaining-hostname.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ libvirt.spec ++++++
--- /var/tmp/diff_new_pack.nJG3X3/_old  2018-02-13 10:27:07.130032578 +0100
+++ /var/tmp/diff_new_pack.nJG3X3/_new  2018-02-13 10:27:07.134032433 +0100
@@ -236,7 +236,7 @@
 BuildRequires:  libxslt
 BuildRequires:  ncurses-devel
 BuildRequires:  perl
-BuildRequires:  python
+BuildRequires:  python3
 BuildRequires:  readline-devel
 # perl XPath is needed since we have a patch touching files that cause
 # hvsupport.html to be regenerated
@@ -322,6 +322,9 @@
 Patch2:         68eed56b-conf-smbios-oem-strings.patch
 Patch3:         76977061-qemu-smbios-oem-strings.patch
 Patch4:         0c710a37-libxl-resume-lock-on-mig-failure.patch
+Patch5:         6b3d716e-keycodemap-py3.patch
+Patch6:         
759b4d1b-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch
+Patch7:         c2dc6698-fix-deadlock-obtaining-hostname.patch
 # Patches pending upstream review
 Patch100:       libxl-dom-reset.patch
 Patch101:       network-don-t-use-dhcp-authoritative-on-static-netwo.patch
@@ -332,6 +335,9 @@
 Patch153:       ppc64le-canonical-name.patch
 Patch154:       libxl-set-migration-constraints.patch
 Patch155:       libxl-set-cach-mode.patch
+Patch156:       0001-Extract-stats-functions-from-the-qemu-driver.patch
+Patch157:       0002-lxc-implement-connectGetAllDomainStats.patch
+Patch158:       apibuild-py3.patch
 # Our patches
 Patch200:       suse-libvirtd-disable-tls.patch
 Patch201:       suse-libvirtd-sysconfig-settings.patch
@@ -912,6 +918,12 @@
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+# it is submodule in git
+pushd src/keycodemapdb
+%patch5 -p1
+popd
+%patch6 -p1
+%patch7 -p1
 %patch100 -p1
 %patch101 -p1
 %patch150 -p1
@@ -920,6 +932,9 @@
 %patch153 -p1
 %patch154 -p1
 %patch155 -p1
+%patch156 -p1
+%patch157 -p1
+%patch158 -p1
 %patch200 -p1
 %patch201 -p1
 %patch202 -p1
@@ -1064,6 +1079,7 @@
 
 autoreconf -f -i
 export CFLAGS="%{optflags}"
+export PYTHON=%{_bindir}/python3
 %configure --disable-static \
            %{?arg_xen} \
            %{?arg_qemu} \

++++++ 0001-Extract-stats-functions-from-the-qemu-driver.patch ++++++
>From 6609ed5a377c3beaf8389e870b6851856cee42c7 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdon...@suse.com>
Date: Thu, 4 Jan 2018 12:04:07 +0100
Subject: [PATCH 1/3] Extract stats functions from the qemu driver

Some of the qemu functions getting statistics can easily be reused in
other drivers. Create a conf/domain_stats.[ch] pair to host some of
them.
---
 src/Makefile.am          |   1 +
 src/conf/domain_stats.c  | 139 +++++++++++++++++++++++++++++++++++++++++
 src/conf/domain_stats.h  |  64 +++++++++++++++++++
 src/libvirt_private.syms |   4 ++
 src/qemu/qemu_driver.c   | 158 +++--------------------------------------------
 src/util/vircgroup.c     |  46 ++++++++++++++
 src/util/vircgroup.h     |   4 ++
 7 files changed, 265 insertions(+), 151 deletions(-)
 create mode 100644 src/conf/domain_stats.c
 create mode 100644 src/conf/domain_stats.h

diff --git a/src/Makefile.am b/src/Makefile.am
index 166c9a8e9..25f913a5f 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -404,6 +404,7 @@ DOMAIN_CONF_SOURCES = \
                conf/domain_conf.c conf/domain_conf.h \
                conf/domain_audit.c conf/domain_audit.h \
                conf/domain_nwfilter.c conf/domain_nwfilter.h \
+               conf/domain_stats.c conf/domain_stats.h \
                conf/virsavecookie.c conf/virsavecookie.h \
                conf/snapshot_conf.c conf/snapshot_conf.h \
                conf/numa_conf.c conf/numa_conf.h \
diff --git a/src/conf/domain_stats.c b/src/conf/domain_stats.c
new file mode 100644
index 000000000..beb3c09d5
--- /dev/null
+++ b/src/conf/domain_stats.c
@@ -0,0 +1,139 @@
+/*
+ * domain_stats.c: domain stats extraction helpers
+ *
+ * Copyright (C) 2006-2016 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2018 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berra...@redhat.com>
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+
+#include "virlog.h"
+#include "domain_stats.h"
+#include "virtypedparam.h"
+#include "virnetdevtap.h"
+#include "virnetdevopenvswitch.h"
+
+#define VIR_FROM_THIS VIR_FROM_DOMAIN
+
+VIR_LOG_INIT("conf.domain_stats");
+
+int
+virDomainStatsGetState(virDomainObjPtr dom,
+                       virDomainStatsRecordPtr record,
+                       int *maxparams)
+{
+    if (virTypedParamsAddInt(&record->params,
+                             &record->nparams,
+                             maxparams,
+                             "state.state",
+                             dom->state.state) < 0)
+        return -1;
+
+    if (virTypedParamsAddInt(&record->params,
+                             &record->nparams,
+                             maxparams,
+                             "state.reason",
+                             dom->state.reason) < 0)
+        return -1;
+
+    return 0;
+}
+
+#define STATS_ADD_NET_PARAM(record, maxparams, num, name, value) \
+do { \
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
+             "net.%zu.%s", num, name); \
+    if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
+                                              &(record)->nparams, \
+                                              maxparams, \
+                                              param_name, \
+                                              value) < 0) \
+        return -1; \
+} while (0)
+
+int
+virDomainStatsGetInterface(virDomainObjPtr dom,
+                           virDomainStatsRecordPtr record,
+                           int *maxparams)
+{
+    size_t i;
+    struct _virDomainInterfaceStats tmp;
+    int ret = -1;
+
+    if (!virDomainObjIsActive(dom))
+        return 0;
+
+    VIR_DOMAIN_STATS_ADD_COUNT_PARAM(record, maxparams, "net", 
dom->def->nnets);
+
+    /* Check the path is one of the domain's network interfaces. */
+    for (i = 0; i < dom->def->nnets; i++) {
+        virDomainNetDefPtr net = dom->def->nets[i];
+        virDomainNetType actualType;
+
+        if (!net->ifname)
+            continue;
+
+        memset(&tmp, 0, sizeof(tmp));
+
+        actualType = virDomainNetGetActualType(net);
+
+        VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams,
+                            "net", "name", i, net->ifname);
+
+        if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
+            if (virNetDevOpenvswitchInterfaceStats(net->ifname, &tmp) < 0) {
+                virResetLastError();
+                continue;
+            }
+        } else {
+            if (virNetDevTapInterfaceStats(net->ifname, &tmp,
+                                           
!virDomainNetTypeSharesHostView(net)) < 0) {
+                virResetLastError();
+                continue;
+            }
+        }
+
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.bytes", tmp.rx_bytes);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.pkts", tmp.rx_packets);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.errs", tmp.rx_errs);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "rx.drop", tmp.rx_drop);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.bytes", tmp.tx_bytes);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.pkts", tmp.tx_packets);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.errs", tmp.tx_errs);
+        STATS_ADD_NET_PARAM(record, maxparams, i,
+                           "tx.drop", tmp.tx_drop);
+    }
+
+    ret = 0;
+ cleanup:
+    return ret;
+}
+
+#undef STATS_ADD_NET_PARAM
diff --git a/src/conf/domain_stats.h b/src/conf/domain_stats.h
new file mode 100644
index 000000000..42f8cb6d3
--- /dev/null
+++ b/src/conf/domain_stats.h
@@ -0,0 +1,64 @@
+/*
+ * domain_stats.h: domain stats extraction helpers
+ *
+ * Copyright (C) 2006-2016 Red Hat, Inc.
+ * Copyright (C) 2006-2008 Daniel P. Berrange
+ * Copyright (c) 2018 SUSE LINUX Products GmbH, Nuernberg, Germany.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * Author: Daniel P. Berrange <berra...@redhat.com>
+ */
+#ifndef __DOMAIN_STATS_H
+# define __DOMAIN_STATS_H
+
+# include "internal.h"
+# include "domain_conf.h"
+
+
+# define VIR_DOMAIN_STATS_ADD_COUNT_PARAM(record, maxparams, type, count) \
+do { \
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "%s.count", type); \
+    if (virTypedParamsAddUInt(&(record)->params, \
+                              &(record)->nparams, \
+                              maxparams, \
+                              param_name, \
+                              count) < 0) \
+        goto cleanup; \
+} while (0)
+
+# define VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams, type, subtype, 
num, name) \
+do { \
+    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
+    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
+             "%s.%zu.%s", type, num, subtype); \
+    if (virTypedParamsAddString(&(record)->params, \
+                                &(record)->nparams, \
+                                maxparams, \
+                                param_name, \
+                                name) < 0) \
+        goto cleanup; \
+} while (0)
+
+int virDomainStatsGetState(virDomainObjPtr dom,
+                           virDomainStatsRecordPtr record,
+                           int *maxparams);
+
+int virDomainStatsGetInterface(virDomainObjPtr dom,
+                               virDomainStatsRecordPtr record,
+                               int *maxparams);
+
+#endif /* __DOMAIN_STATS_H */
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index bc8cc1fba..2e22abcec 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -630,6 +630,9 @@ virDomainConfNWFilterRegister;
 virDomainConfNWFilterTeardown;
 virDomainConfVMNWFilterTeardown;
 
+# conf/domain_stats.h
+virDomainStatsGetInterface;
+virDomainStatsGetState;
 
 # conf/interface_conf.h
 virInterfaceDefFormat;
@@ -1468,6 +1471,7 @@ virCgroupGetMemoryUsage;
 virCgroupGetMemSwapHardLimit;
 virCgroupGetMemSwapUsage;
 virCgroupGetPercpuStats;
+virCgroupGetStatsCpu;
 virCgroupHasController;
 virCgroupHasEmptyTasks;
 virCgroupKill;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index a203c9297..f60436e4c 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -72,6 +72,7 @@
 #include "viralloc.h"
 #include "viruuid.h"
 #include "domain_conf.h"
+#include "domain_stats.h"
 #include "domain_audit.h"
 #include "node_device_conf.h"
 #include "virpci.h"
@@ -19380,21 +19381,7 @@ qemuDomainGetStatsState(virQEMUDriverPtr driver 
ATTRIBUTE_UNUSED,
                         int *maxparams,
                         unsigned int privflags ATTRIBUTE_UNUSED)
 {
-    if (virTypedParamsAddInt(&record->params,
-                             &record->nparams,
-                             maxparams,
-                             "state.state",
-                             dom->state.state) < 0)
-        return -1;
-
-    if (virTypedParamsAddInt(&record->params,
-                             &record->nparams,
-                             maxparams,
-                             "state.reason",
-                             dom->state.reason) < 0)
-        return -1;
-
-    return 0;
+    return virDomainStatsGetState(dom, record, maxparams);
 }
 
 
@@ -19417,37 +19404,7 @@ qemuDomainGetStatsCpu(virQEMUDriverPtr driver 
ATTRIBUTE_UNUSED,
                       unsigned int privflags ATTRIBUTE_UNUSED)
 {
     qemuDomainObjPrivatePtr priv = dom->privateData;
-    unsigned long long cpu_time = 0;
-    unsigned long long user_time = 0;
-    unsigned long long sys_time = 0;
-    int err = 0;
-
-    if (!priv->cgroup)
-        return 0;
-
-    err = virCgroupGetCpuacctUsage(priv->cgroup, &cpu_time);
-    if (!err && virTypedParamsAddULLong(&record->params,
-                                        &record->nparams,
-                                        maxparams,
-                                        "cpu.time",
-                                        cpu_time) < 0)
-        return -1;
-
-    err = virCgroupGetCpuacctStat(priv->cgroup, &user_time, &sys_time);
-    if (!err && virTypedParamsAddULLong(&record->params,
-                                        &record->nparams,
-                                        maxparams,
-                                        "cpu.user",
-                                        user_time) < 0)
-        return -1;
-    if (!err && virTypedParamsAddULLong(&record->params,
-                                        &record->nparams,
-                                        maxparams,
-                                        "cpu.system",
-                                        sys_time) < 0)
-        return -1;
-
-    return 0;
+    return virCgroupGetStatsCpu(priv->cgroup, record, maxparams);
 }
 
 static int
@@ -19624,44 +19581,6 @@ qemuDomainGetStatsVcpu(virQEMUDriverPtr driver,
     return ret;
 }
 
-#define QEMU_ADD_COUNT_PARAM(record, maxparams, type, count) \
-do { \
-    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
-    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, "%s.count", type); \
-    if (virTypedParamsAddUInt(&(record)->params, \
-                              &(record)->nparams, \
-                              maxparams, \
-                              param_name, \
-                              count) < 0) \
-        goto cleanup; \
-} while (0)
-
-#define QEMU_ADD_NAME_PARAM(record, maxparams, type, subtype, num, name) \
-do { \
-    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
-    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
-             "%s.%zu.%s", type, num, subtype); \
-    if (virTypedParamsAddString(&(record)->params, \
-                                &(record)->nparams, \
-                                maxparams, \
-                                param_name, \
-                                name) < 0) \
-        goto cleanup; \
-} while (0)
-
-#define QEMU_ADD_NET_PARAM(record, maxparams, num, name, value) \
-do { \
-    char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
-    snprintf(param_name, VIR_TYPED_PARAM_FIELD_LENGTH, \
-             "net.%zu.%s", num, name); \
-    if (value >= 0 && virTypedParamsAddULLong(&(record)->params, \
-                                              &(record)->nparams, \
-                                              maxparams, \
-                                              param_name, \
-                                              value) < 0) \
-        return -1; \
-} while (0)
-
 static int
 qemuDomainGetStatsInterface(virQEMUDriverPtr driver ATTRIBUTE_UNUSED,
                             virDomainObjPtr dom,
@@ -19669,68 +19588,9 @@ qemuDomainGetStatsInterface(virQEMUDriverPtr driver 
ATTRIBUTE_UNUSED,
                             int *maxparams,
                             unsigned int privflags ATTRIBUTE_UNUSED)
 {
-    size_t i;
-    struct _virDomainInterfaceStats tmp;
-    int ret = -1;
-
-    if (!virDomainObjIsActive(dom))
-        return 0;
-
-    QEMU_ADD_COUNT_PARAM(record, maxparams, "net", dom->def->nnets);
-
-    /* Check the path is one of the domain's network interfaces. */
-    for (i = 0; i < dom->def->nnets; i++) {
-        virDomainNetDefPtr net = dom->def->nets[i];
-        virDomainNetType actualType;
-
-        if (!net->ifname)
-            continue;
-
-        memset(&tmp, 0, sizeof(tmp));
-
-        actualType = virDomainNetGetActualType(net);
-
-        QEMU_ADD_NAME_PARAM(record, maxparams,
-                            "net", "name", i, net->ifname);
-
-        if (actualType == VIR_DOMAIN_NET_TYPE_VHOSTUSER) {
-            if (virNetDevOpenvswitchInterfaceStats(net->ifname, &tmp) < 0) {
-                virResetLastError();
-                continue;
-            }
-        } else {
-            if (virNetDevTapInterfaceStats(net->ifname, &tmp,
-                                           
!virDomainNetTypeSharesHostView(net)) < 0) {
-                virResetLastError();
-                continue;
-            }
-        }
-
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.bytes", tmp.rx_bytes);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.pkts", tmp.rx_packets);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.errs", tmp.rx_errs);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "rx.drop", tmp.rx_drop);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.bytes", tmp.tx_bytes);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.pkts", tmp.tx_packets);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.errs", tmp.tx_errs);
-        QEMU_ADD_NET_PARAM(record, maxparams, i,
-                           "tx.drop", tmp.tx_drop);
-    }
-
-    ret = 0;
- cleanup:
-    return ret;
+    return virDomainStatsGetInterface(dom, record, maxparams);
 }
 
-#undef QEMU_ADD_NET_PARAM
-
 #define QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, num, name, value) \
     do { \
         char param_name[VIR_TYPED_PARAM_FIELD_LENGTH]; \
@@ -19852,10 +19712,10 @@ qemuDomainGetStatsOneBlock(virQEMUDriverPtr driver,
     if (disk->info.alias)
         alias = qemuDomainStorageAlias(disk->info.alias, backing_idx);
 
-    QEMU_ADD_NAME_PARAM(record, maxparams, "block", "name", block_idx,
+    VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams, "block", "name", 
block_idx,
                         disk->dst);
     if (virStorageSourceIsLocalStorage(src) && src->path)
-        QEMU_ADD_NAME_PARAM(record, maxparams, "block", "path",
+        VIR_DOMAIN_STATS_ADD_NAME_PARAM(record, maxparams, "block", "path",
                             block_idx, src->path);
     if (backing_idx)
         QEMU_ADD_BLOCK_PARAM_UI(record, maxparams, block_idx, "backingIndex",
@@ -19971,7 +19831,7 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
      * after the iteration than it is to iterate twice; but we still
      * want count listed first.  */
     count_index = record->nparams;
-    QEMU_ADD_COUNT_PARAM(record, maxparams, "block", 0);
+    VIR_DOMAIN_STATS_ADD_COUNT_PARAM(record, maxparams, "block", 0);
 
     for (i = 0; i < dom->def->ndisks; i++) {
         virDomainDiskDefPtr disk = dom->def->disks[i];
@@ -20005,10 +19865,6 @@ qemuDomainGetStatsBlock(virQEMUDriverPtr driver,
 
 #undef QEMU_ADD_BLOCK_PARAM_ULL
 
-#undef QEMU_ADD_NAME_PARAM
-
-#undef QEMU_ADD_COUNT_PARAM
-
 static int
 qemuDomainGetStatsPerfOneEvent(virPerfPtr perf,
                                virPerfEventType type,
diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c
index 0a31947b0..04ef4c1a7 100644
--- a/src/util/vircgroup.c
+++ b/src/util/vircgroup.c
@@ -4122,6 +4122,44 @@ virCgroupControllerAvailable(int controller)
     return ret;
 }
 
+int
+virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                     virDomainStatsRecordPtr record,
+                     int *maxparams)
+{
+    unsigned long long cpu_time = 0;
+    unsigned long long user_time = 0;
+    unsigned long long sys_time = 0;
+    int err = 0;
+
+    if (!cgroup)
+        return 0;
+
+    err = virCgroupGetCpuacctUsage(cgroup, &cpu_time);
+    if (!err && virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        "cpu.time",
+                                        cpu_time) < 0)
+        return -1;
+
+    err = virCgroupGetCpuacctStat(cgroup, &user_time, &sys_time);
+    if (!err && virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        "cpu.user",
+                                        user_time) < 0)
+        return -1;
+    if (!err && virTypedParamsAddULLong(&record->params,
+                                        &record->nparams,
+                                        maxparams,
+                                        "cpu.system",
+                                        sys_time) < 0)
+        return -1;
+
+    return 0;
+}
+
 #else /* !VIR_CGROUP_SUPPORTED */
 
 bool
@@ -4899,6 +4937,14 @@ virCgroupControllerAvailable(int controller 
ATTRIBUTE_UNUSED)
 {
     return false;
 }
+
+int
+virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                     virDomainStatsRecordPtr record,
+                     int *maxparams)
+{
+    return 0;
+}
 #endif /* !VIR_CGROUP_SUPPORTED */
 
 
diff --git a/src/util/vircgroup.h b/src/util/vircgroup.h
index d83392767..2ebdf9505 100644
--- a/src/util/vircgroup.h
+++ b/src/util/vircgroup.h
@@ -297,4 +297,8 @@ int virCgroupSetOwner(virCgroupPtr cgroup,
 int virCgroupHasEmptyTasks(virCgroupPtr cgroup, int controller);
 
 bool virCgroupControllerAvailable(int controller);
+
+int virCgroupGetStatsCpu(virCgroupPtr cgroup,
+                         virDomainStatsRecordPtr record,
+                         int *maxparams);
 #endif /* __VIR_CGROUP_H__ */
-- 
2.15.1

++++++ 0002-lxc-implement-connectGetAllDomainStats.patch ++++++
>From 1a2be7098cf5acfd893153abb52b65e69631dcec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdon...@suse.com>
Date: Tue, 2 Jan 2018 14:44:39 +0100
Subject: [PATCH 2/3] lxc: implement connectGetAllDomainStats

LXC containers can also provide some statistics. Allow users to fetch
them using the existing API.
---
 src/lxc/lxc_driver.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)

diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index b3447100f..10667c134 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -81,6 +81,7 @@
 #include "viraccessapichecklxc.h"
 #include "virhostdev.h"
 #include "netdev_bandwidth_conf.h"
+#include "domain_stats.h"
 
 #define VIR_FROM_THIS VIR_FROM_LXC
 
@@ -5485,6 +5486,142 @@ lxcDomainHasManagedSaveImage(virDomainPtr dom, unsigned 
int flags)
     return ret;
 }
 
+static int
+lxcDomainGetStatsCpu(virDomainObjPtr dom,
+                     virDomainStatsRecordPtr record,
+                     int *maxparams)
+{
+    virLXCDomainObjPrivatePtr priv = dom->privateData;
+    return virCgroupGetStatsCpu(priv->cgroup, record, maxparams);
+}
+
+typedef int
+(*lxcDomainGetStatsFunc)(virDomainObjPtr dom,
+                         virDomainStatsRecordPtr record,
+                         int *maxparams);
+
+struct lxcDomainGetStatsWorker {
+    lxcDomainGetStatsFunc func;
+    unsigned int stats;
+};
+
+static struct lxcDomainGetStatsWorker lxcDomainGetStatsWorkers[] = {
+    { virDomainStatsGetState, VIR_DOMAIN_STATS_STATE },
+    { lxcDomainGetStatsCpu, VIR_DOMAIN_STATS_CPU_TOTAL },
+    { virDomainStatsGetInterface, VIR_DOMAIN_STATS_INTERFACE },
+    { NULL, 0 }
+};
+
+static int
+lxcDomainGetStats(virConnectPtr conn,
+                  virDomainObjPtr dom,
+                  unsigned int stats,
+                  virDomainStatsRecordPtr *record)
+{
+    int maxparams = 0;
+    virDomainStatsRecordPtr tmp;
+    size_t i;
+    int ret = -1;
+
+    if (VIR_ALLOC(tmp) < 0)
+        goto cleanup;
+
+    for (i = 0; lxcDomainGetStatsWorkers[i].func; i++) {
+        if (stats & lxcDomainGetStatsWorkers[i].stats) {
+            if (lxcDomainGetStatsWorkers[i].func(dom, tmp, &maxparams) < 0)
+                goto cleanup;
+        }
+    }
+
+    if (!(tmp->dom = virGetDomain(conn, dom->def->name,
+                                  dom->def->uuid, dom->def->id)))
+        goto cleanup;
+
+    *record = tmp;
+    tmp = NULL;
+    ret = 0;
+
+ cleanup:
+    if (tmp) {
+        virTypedParamsFree(tmp->params, tmp->nparams);
+        VIR_FREE(tmp);
+    }
+
+    return ret;
+}
+
+static int
+lxcConnectGetAllDomainStats(virConnectPtr conn,
+                            virDomainPtr *doms,
+                            unsigned int ndoms,
+                            unsigned int stats,
+                            virDomainStatsRecordPtr **retStats,
+                            unsigned int flags)
+{
+    virLXCDriverPtr driver = conn->privateData;
+    virDomainObjPtr *vms = NULL;
+    virDomainObjPtr vm;
+    size_t nvms;
+    virDomainStatsRecordPtr *tmpstats = NULL;
+    int nstats = 0;
+    size_t i;
+    int ret = -1;
+    unsigned int lflags = flags & (VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
+                                   VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT 
|
+                                   VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE);
+
+    virCheckFlags(VIR_CONNECT_LIST_DOMAINS_FILTERS_ACTIVE |
+                  VIR_CONNECT_LIST_DOMAINS_FILTERS_PERSISTENT |
+                  VIR_CONNECT_LIST_DOMAINS_FILTERS_STATE, -1);
+
+    if (virConnectGetAllDomainStatsEnsureACL(conn) < 0)
+        return -1;
+
+    /* TODO Check stats support */
+
+    if (ndoms) {
+        if (virDomainObjListConvert(driver->domains, conn, doms, ndoms, &vms,
+                                    &nvms, virConnectGetAllDomainStatsCheckACL,
+                                    lflags, true) < 0)
+            return -1;
+    } else {
+        if (virDomainObjListCollect(driver->domains, conn, &vms, &nvms,
+                                    virConnectGetAllDomainStatsCheckACL,
+                                    lflags) < 0)
+            return -1;
+    }
+
+    if (VIR_ALLOC_N(tmpstats, nvms + 1) < 0)
+        return -1;
+
+    for (i = 0; i < nvms; i++) {
+        virDomainStatsRecordPtr tmp = NULL;
+        vm = vms[i];
+
+        virObjectLock(vm);
+
+        if (lxcDomainGetStats(conn, vm, stats, &tmp) < 0) {
+            virObjectUnlock(vm);
+            goto cleanup;
+        }
+
+        if (tmp)
+            tmpstats[nstats++] = tmp;
+
+        virObjectUnlock(vm);
+    }
+
+    *retStats = tmpstats;
+    tmpstats = NULL;
+
+    ret = nstats;
+
+ cleanup:
+    virDomainStatsRecordListFree(tmpstats);
+    virObjectListFreeCount(vms, nvms);
+
+    return ret;
+}
 
 /* Function Tables */
 static virHypervisorDriver lxcHypervisorDriver = {
@@ -5579,6 +5716,7 @@ static virHypervisorDriver lxcHypervisorDriver = {
     .nodeGetFreePages = lxcNodeGetFreePages, /* 1.2.6 */
     .nodeAllocPages = lxcNodeAllocPages, /* 1.2.9 */
     .domainHasManagedSaveImage = lxcDomainHasManagedSaveImage, /* 1.2.13 */
+    .connectGetAllDomainStats = lxcConnectGetAllDomainStats, /* 3.11.0 */
 };
 
 static virConnectDriver lxcConnectDriver = {
-- 
2.15.1

++++++ 6b3d716e-keycodemap-py3.patch ++++++
>From 6b3d716e2b6472eb7189d3220552280ef3d832ce Mon Sep 17 00:00:00 2001
From: Daniel P. Berrange <berra...@redhat.com>
Date: Fri, 12 Jan 2018 13:53:44 +0000
Subject: [PATCH] Fix compat with py3 dict keys/values data types

Signed-off-by: Daniel P. Berrange <berra...@redhat.com>
---
 tools/keymap-gen | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/tools/keymap-gen b/tools/keymap-gen
index d4594b4..f0269e3 100755
--- a/tools/keymap-gen
+++ b/tools/keymap-gen
@@ -356,19 +356,19 @@ class LanguageSrcGenerator(LanguageGenerator):
 
         if frommapname in database.ENUM_COLUMNS:
             fromtype = self.TYPE_ENUM
-        elif type(tolinux.keys()[0]) == str:
+        elif type(list(tolinux.keys())[0]) == str:
             fromtype = self.TYPE_STRING
         else:
             fromtype = self.TYPE_INT
 
         if tomapname in database.ENUM_COLUMNS:
             totype = self.TYPE_ENUM
-        elif type(fromlinux.values()[0]) == str:
+        elif type(list(fromlinux.values())[0]) == str:
             totype = self.TYPE_STRING
         else:
             totype = self.TYPE_INT
 
-        keys = tolinux.keys()
+        keys = list(tolinux.keys())
         keys.sort()
         if fromtype == self.TYPE_INT:
             keys = range(keys[-1] + 1)
@@ -402,7 +402,7 @@ class LanguageSrcGenerator(LanguageGenerator):
             raise Exception("Unknown map %s, expected one of %s" % (
                             mapname, ", ".join(database.mapto.keys())))
 
-        keys = database.mapto[Database.MAP_LINUX].keys()
+        keys = list(database.mapto[Database.MAP_LINUX].keys())
         keys.sort()
         names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for 
key in keys]
 
@@ -411,7 +411,7 @@ class LanguageSrcGenerator(LanguageGenerator):
 
         if mapname in database.ENUM_COLUMNS:
             totype = self.TYPE_ENUM
-        elif type(database.mapto[mapname].values()[0]) == str:
+        elif type(list(database.mapto[mapname].values())[0]) == str:
             totype = self.TYPE_STRING
         else:
             totype = self.TYPE_INT
@@ -440,7 +440,7 @@ class LanguageSrcGenerator(LanguageGenerator):
         if varname is None:
             varname = "name_map_%s_to_%s" % (frommapname, tomapname)
 
-        keys = tolinux.keys()
+        keys = list(tolinux.keys())
         keys.sort()
         if type(keys[0]) == int:
             keys = range(keys[-1] + 1)
@@ -470,7 +470,7 @@ class LanguageSrcGenerator(LanguageGenerator):
             raise Exception("Unknown map %s, expected one of %s" % (
                             mapname, ", ".join(database.mapname.keys())))
 
-        keys = database.mapto[Database.MAP_LINUX].keys()
+        keys = list(database.mapto[Database.MAP_LINUX].keys())
         keys.sort()
         names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for 
key in keys]
 
@@ -514,7 +514,7 @@ class LanguageDocGenerator(LanguageGenerator):
             raise Exception("Unknown map %s, expected one of %s" % (
                             mapname, ", ".join(database.mapname.keys())))
 
-        keys = database.mapto[Database.MAP_LINUX].keys()
+        keys = list(database.mapto[Database.MAP_LINUX].keys())
         keys.sort()
         names = [database.mapname[Database.MAP_LINUX].get(key, "unnamed") for 
key in keys]
 
@@ -537,7 +537,7 @@ class LanguageDocGenerator(LanguageGenerator):
                             mapname, ", ".join(database.mapfrom.keys())))
 
         tolinux = database.mapfrom[mapname]
-        keys = tolinux.keys()
+        keys = list(tolinux.keys())
         keys.sort()
         if mapname in database.mapname:
             names = database.mapname[mapname]
--
libgit2 0.26.0

++++++ 759b4d1b-virlog-determine-the-hostname-on-startup-CVE-2018-67.patch 
++++++
>From 759b4d1b0fe5f4d84d98b99153dfa7ac289dd167 Mon Sep 17 00:00:00 2001
From: Lubomir Rintel <lkund...@v3.sk>
Date: Sat, 27 Jan 2018 23:43:58 +0100
Subject: [PATCH] virlog: determine the hostname on startup CVE-2018-6764

At later point it might not be possible or even safe to use getaddrinfo(). It
can in turn result in a load of NSS module.

Notably, on a LXC container startup we may find ourselves with the guest
filesystem already having replaced the host one. Loading a NSS module
from the guest tree would allow a malicous guest to escape the
confinement of its container environment because libvirt will not yet
have locked it down.
---
 src/util/virlog.c | 14 +++++++++-----
 1 file changed, 9 insertions(+), 5 deletions(-)

diff --git a/src/util/virlog.c b/src/util/virlog.c
index 68439b919..9105337ce 100644
--- a/src/util/virlog.c
+++ b/src/util/virlog.c
@@ -64,6 +64,7 @@
 VIR_LOG_INIT("util.log");
 
 static regex_t *virLogRegex;
+static char *virLogHostname;
 
 
 #define VIR_LOG_DATE_REGEX "[0-9]{4}-[0-9]{2}-[0-9]{2}"
@@ -271,6 +272,12 @@ virLogOnceInit(void)
             VIR_FREE(virLogRegex);
     }
 
+    /* We get and remember the hostname early, because at later time
+     * it might not be possible to load NSS modules via getaddrinfo()
+     * (e.g. at container startup the host filesystem will not be
+     * accessible anymore. */
+    virLogHostname = virGetHostnameQuiet();
+
     virLogUnlock();
     return 0;
 }
@@ -466,17 +473,14 @@ static int
 virLogHostnameString(char **rawmsg,
                      char **msg)
 {
-    char *hostname = virGetHostnameQuiet();
     char *hoststr;
 
-    if (!hostname)
+    if (!virLogHostname)
         return -1;
 
-    if (virAsprintfQuiet(&hoststr, "hostname: %s", hostname) < 0) {
-        VIR_FREE(hostname);
+    if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0) {
         return -1;
     }
-    VIR_FREE(hostname);
 
     if (virLogFormatString(msg, 0, NULL, VIR_LOG_INFO, hoststr) < 0) {
         VIR_FREE(hoststr);
-- 
2.15.1

++++++ apibuild-py3.patch ++++++
++++ 989 lines (skipped)

++++++ c2dc6698-fix-deadlock-obtaining-hostname.patch ++++++
>From c2dc6698c88fb591639e542c8ecb0076c54f3dfb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berra...@redhat.com>
Date: Mon, 12 Feb 2018 10:03:08 +0000
Subject: [PATCH] log: fix deadlock obtaining hostname (related CVE-2018-6764)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The fix for CVE-2018-6764 introduced a potential deadlock scenario
that gets triggered by the NSS module when virGetHostname() calls
getaddrinfo to resolve the hostname:

 #0  0x00007f6e714b57e7 in futex_wait
 #1  futex_wait_simple
 #2  __pthread_once_slow
 #3  0x00007f6e71d16e7d in virOnce
 #4  0x00007f6e71d0997c in virLogInitialize
 #5  0x00007f6e71d0a09a in virLogVMessage
 #6  0x00007f6e71d09ffd in virLogMessage
 #7  0x00007f6e71d0db22 in virObjectNew
 #8  0x00007f6e71d0dbf1 in virObjectLockableNew
 #9  0x00007f6e71d0d3e5 in virMacMapNew
 #10 0x00007f6e71cdc50a in findLease
 #11 0x00007f6e71cdcc56 in _nss_libvirt_gethostbyname4_r
 #12 0x00007f6e724631fc in gaih_inet
 #13 0x00007f6e72464697 in __GI_getaddrinfo
 #14 0x00007f6e71d19e81 in virGetHostnameImpl
 #15 0x00007f6e71d1a057 in virGetHostnameQuiet
 #16 0x00007f6e71d09936 in virLogOnceInit
 #17 0x00007f6e71d09952 in virLogOnce
 #18 0x00007f6e714b5829 in __pthread_once_slow
 #19 0x00007f6e71d16e7d in virOnce
 #20 0x00007f6e71d0997c in virLogInitialize
 #21 0x00007f6e71d0a09a in virLogVMessage
 #22 0x00007f6e71d09ffd in virLogMessage
 #23 0x00007f6e71d0db22 in virObjectNew
 #24 0x00007f6e71d0dbf1 in virObjectLockableNew
 #25 0x00007f6e71d0d3e5 in virMacMapNew
 #26 0x00007f6e71cdc50a in findLease
 #27 0x00007f6e71cdc839 in _nss_libvirt_gethostbyname3_r
 #28 0x00007f6e71cdc724 in _nss_libvirt_gethostbyname2_r
 #29 0x00007f6e7248f72f in __gethostbyname2_r
 #30 0x00007f6e7248f494 in gethostbyname2
 #31 0x000056348c30c36d in hosts_keys
 #32 0x000056348c30b7d2 in main

Fortunately the extra stuff virGetHostname does is totally irrelevant to
the needs of the logging code, so we can just inline a call to the
native hostname() syscall directly.

Signed-off-by: Daniel P. Berrangé <berra...@redhat.com>
---
 cfg.mk            |  2 +-
 src/util/virlog.c | 20 ++++++++++++++------
 2 files changed, 15 insertions(+), 7 deletions(-)

Index: libvirt-4.0.0/cfg.mk
===================================================================
--- libvirt-4.0.0.orig/cfg.mk
+++ libvirt-4.0.0/cfg.mk
@@ -1183,7 +1183,7 @@ _src2=src/(util/vircommand|libvirt|lxc/l
 exclude_file_name_regexp--sc_prohibit_fork_wrappers = \
   (^($(_src2)|tests/testutils|daemon/libvirtd)\.c$$)
 
-exclude_file_name_regexp--sc_prohibit_gethostname = ^src/util/virutil\.c$$
+exclude_file_name_regexp--sc_prohibit_gethostname = 
^src/util/vir(util|log)\.c$$
 
 exclude_file_name_regexp--sc_prohibit_internal_functions = \
   ^src/(util/(viralloc|virutil|virfile)\.[hc]|esx/esx_vi\.c)$$
Index: libvirt-4.0.0/src/util/virlog.c
===================================================================
--- libvirt-4.0.0.orig/src/util/virlog.c
+++ libvirt-4.0.0/src/util/virlog.c
@@ -64,7 +64,7 @@
 VIR_LOG_INIT("util.log");
 
 static regex_t *virLogRegex;
-static char *virLogHostname;
+static char virLogHostname[HOST_NAME_MAX+1];
 
 
 #define VIR_LOG_DATE_REGEX "[0-9]{4}-[0-9]{2}-[0-9]{2}"
@@ -261,6 +261,8 @@ virLogPriorityString(virLogPriority lvl)
 static int
 virLogOnceInit(void)
 {
+    int r;
+
     if (virMutexInit(&virLogMutex) < 0)
         return -1;
 
@@ -275,8 +277,17 @@ virLogOnceInit(void)
     /* We get and remember the hostname early, because at later time
      * it might not be possible to load NSS modules via getaddrinfo()
      * (e.g. at container startup the host filesystem will not be
-     * accessible anymore. */
-    virLogHostname = virGetHostnameQuiet();
+     * accessible anymore.
+     * Must not use virGetHostname though as that causes re-entrancy
+     * problems if it triggers logging codepaths
+     */
+    r = gethostname(virLogHostname, sizeof(virLogHostname));
+    if (r == -1) {
+        ignore_value(virStrcpy(virLogHostname,
+                               "(unknown)", sizeof(virLogHostname)));
+    } else {
+        NUL_TERMINATE(virLogHostname);
+    }
 
     virLogUnlock();
     return 0;
@@ -475,9 +486,6 @@ virLogHostnameString(char **rawmsg,
 {
     char *hoststr;
 
-    if (!virLogHostname)
-        return -1;
-
     if (virAsprintfQuiet(&hoststr, "hostname: %s", virLogHostname) < 0) {
         return -1;
     }


Reply via email to