[vdsm/f20] vdsm 4.14.3-4
Douglas Schilling Landgraf
dougsland at fedoraproject.org
Tue Feb 18 19:22:15 UTC 2014
commit bad3b29a5649866bb1bfc207130355c9167a21bc
Author: Douglas Schilling Landgraf <dougsland at redhat.com>
Date: Tue Feb 18 16:21:27 2014 -0500
vdsm 4.14.3-4
- sos plugin should ignore var run vdsm storage
- vdsm fix RTC offset
- vdsm pre defined range for spice vnc ports
- netinfo.speed avoid log spam
- Avoid-going-into-Paused-status-during-long-lasting-m
- vm discover volume path from xml definition
- vdsm.spec vdsm should own vdsm.log
- Removing vdsm python cpopen rpm creation from vdsm
- vdsm.spec own metadata supervdsm mom logs
- vm iface statistics never report negative rates
- spec do not remove vdsm logs when pkg removed
...plugin-should-ignore-var-run-vdsm-storage.patch | 32 +
...dsm-pre-defined-range-for-spice-vnc-ports.patch | 56 ++
...-into-Paused-status-during-long-lasting-m.patch | 110 +++
0010-vdsm.spec-vdsm-should-own-vdsm.log.patch | 43 +
...vdsm.spec-own-metadata-supervdsm-mom-logs.patch | 52 ++
...-do-not-remove-vdsm-logs-when-pkg-removed.patch | 74 ++
0013-vdsm-fix-RTC-offset.patch | 51 ++
0014-netinfo.speed-avoid-log-spam.patch | 40 +
...-discover-volume-path-from-xml-definition.patch | 74 ++
...vdsm-python-cpopen-rpm-creation-from-vdsm.patch | 930 ++++++++++++++++++++
...ce-statistics-never-report-negative-rates.patch | 47 +
vdsm.spec | 71 ++-
12 files changed, 1565 insertions(+), 15 deletions(-)
---
diff --git a/0007-sos-plugin-should-ignore-var-run-vdsm-storage.patch b/0007-sos-plugin-should-ignore-var-run-vdsm-storage.patch
new file mode 100644
index 0000000..6c7b2e1
--- /dev/null
+++ b/0007-sos-plugin-should-ignore-var-run-vdsm-storage.patch
@@ -0,0 +1,32 @@
+From e3e158aa050a15981c07891ae96198f94eb1e033 Mon Sep 17 00:00:00 2001
+From: Douglas Schilling Landgraf <dougsland at redhat.com>
+Date: Thu, 30 Jan 2014 16:03:57 -0500
+Subject: [PATCH 07/17] sos: plugin should ignore /var/run/vdsm/storage
+
+In case sos plugin includes /var/run/vdsm/storage and it contains
+symlinks to block devices it can make the host fill the disk
+and eventually create a 0 sized sosreport.
+
+Change-Id: Ie60d681cc744f2407a0ddf9406225e73497ac648
+Signed-off-by: Douglas Schilling Landgraf <dougsland at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/23930
+Reviewed-by: Dan Kenigsberg <danken at redhat.com>
+---
+ vdsm/sos/vdsm.py.in | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/vdsm/sos/vdsm.py.in b/vdsm/sos/vdsm.py.in
+index 63a028c..6e4e60b 100644
+--- a/vdsm/sos/vdsm.py.in
++++ b/vdsm/sos/vdsm.py.in
+@@ -120,5 +120,6 @@ class vdsm(sos.plugintools.PluginBase):
+ import glob
+
+ for f in glob.glob("@VDSMRUNDIR@/*"):
+- if not f.endswith('.vfd') and not f.endswith('/isoUploader'):
++ if not f.endswith('.vfd') and not f.endswith('/isoUploader') \
++ and not f.endswith('/storage'):
+ self.addCopySpec(f)
+--
+1.7.1
+
diff --git a/0008-vdsm-pre-defined-range-for-spice-vnc-ports.patch b/0008-vdsm-pre-defined-range-for-spice-vnc-ports.patch
new file mode 100644
index 0000000..3e70ebf
--- /dev/null
+++ b/0008-vdsm-pre-defined-range-for-spice-vnc-ports.patch
@@ -0,0 +1,56 @@
+From b479bd1a4fae08c10b6e1d046623dd8f87f33e39 Mon Sep 17 00:00:00 2001
+From: Vinzenz Feenstra <vfeenstr at gmail.com>
+Date: Thu, 18 Jul 2013 10:57:02 +0200
+Subject: [PATCH 08/17] vdsm: pre-defined range for spice/vnc ports
+
+Libvirt's default port range 5900-65535 which is out of VDSM's
+documented range 5634 to 6166. But since the medieval time we
+already use libvirt's default. We'll define the new range as
+5900-6923 (1024 ports) So:
+
+1. Set some limited port range, that can be used in FW conf
+2. Use start port 5900 as it is already used by customers
+3. Use the endport as 6923
+4. Change VDSM documentation according to new port range
+
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1052162
+Signed-off-by: Peter V. Saveliev <peet at redhat.com>
+Signed-off-by: Vinzenz Feenstra <vfeenstr at redhat.com>
+Change-Id: Id42d41064e122f1b2dcc98506b58d0cc74239650
+Reviewed-on: http://gerrit.ovirt.org/17058
+Reviewed-by: Michal Skrivanek <michal.skrivanek at redhat.com>
+Tested-by: Michal Skrivanek <michal.skrivanek at redhat.com>
+Reviewed-by: Dan Kenigsberg <danken at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/23940
+Reviewed-by: Yaniv Bronhaim <ybronhei at redhat.com>
+---
+ lib/vdsm/tool/libvirt_configure.sh.in | 6 +++++-
+ 1 files changed, 5 insertions(+), 1 deletions(-)
+
+diff --git a/lib/vdsm/tool/libvirt_configure.sh.in b/lib/vdsm/tool/libvirt_configure.sh.in
+index cf70f59..ea0500c 100755
+--- a/lib/vdsm/tool/libvirt_configure.sh.in
++++ b/lib/vdsm/tool/libvirt_configure.sh.in
+@@ -156,7 +156,7 @@ configure() {
+ # package version, so anything meaningful can be used here. Since a hard
+ # coded version string has been already used, for compatibility we will
+ # continue to use this string.
+- local by_vdsm_vers="4.10.3"
++ local by_vdsm_vers="4.13.0"
+ local start_conf_section="## beginning of configuration section ${by_vdsm}"
+ local end_conf_section="## end of configuration section ${by_vdsm}"
+
+@@ -241,6 +241,10 @@ configure() {
+ set_if_default "${lconf}" listen_tls 0
+ fi
+
++ # Configure remote display port range
++ set_if_default "${qconf}" remote_display_port_min 5900
++ set_if_default "${qconf}" remote_display_port_max 6923
++
+ # Configuring sanlock
+ if [ "${ENABLE_LIBVIRT_SANLOCK}" = "yes" ]; then
+ set_if_default "${qconf}" lock_manager \"sanlock\"
+--
+1.7.1
+
diff --git a/0009-Avoid-going-into-Paused-status-during-long-lasting-m.patch b/0009-Avoid-going-into-Paused-status-during-long-lasting-m.patch
new file mode 100644
index 0000000..a8f8cd5
--- /dev/null
+++ b/0009-Avoid-going-into-Paused-status-during-long-lasting-m.patch
@@ -0,0 +1,110 @@
+From 9369b370369057832eff41793075fc1a63c42279 Mon Sep 17 00:00:00 2001
+From: Vinzenz Feenstra <vfeenstr at redhat.com>
+Date: Tue, 3 Dec 2013 15:26:18 +0100
+Subject: [PATCH 09/17] Avoid going into 'Paused' status during long lasting migrations
+
+If a migration is taking longer than 'migration_timeout' the VM
+moves into 'Paused' state on the destination host.
+This patch increases the timeout to 6 hours as an absolute maximum
+for the destination to wait for the migration to finish.
+This is now reflected as the migration_destination_timeout.
+
+If the VM after the timeout still has the state PAUSED and the
+reason is `migration` we're going to raise an MigrationError and
+will lead to the destruction of the VM on the destination.
+
+In all other cases we're keeping the previous behaviour and are
+continuing with normal VDSM tasks without touching the state of
+the VM. That means that if the VM is in PAUSED state due to other
+reasons than migration, it will stay PAUSED.
+
+Change-Id: I6bb1c9ae7ead92093c0d300df7c3567ab20b1e09
+Bug-Url: https://bugzilla.redhat.com/1059129
+Signed-off-by: Vinzenz Feenstra <vfeenstr at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/21963
+Reviewed-by: Dan Kenigsberg <danken at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/23939
+---
+ lib/vdsm/config.py.in | 3 +++
+ vdsm/vm.py | 36 +++++++++++++++++++++++++++---------
+ 2 files changed, 30 insertions(+), 9 deletions(-)
+
+diff --git a/lib/vdsm/config.py.in b/lib/vdsm/config.py.in
+index ff4cebe..c85ab88 100644
+--- a/lib/vdsm/config.py.in
++++ b/lib/vdsm/config.py.in
+@@ -52,6 +52,9 @@ parameters = [
+ 'recognized by kvm/qemu if a coma separated list given then a '
+ 'NIC per device will be created.'),
+
++ ('migration_destination_timeout', '21600',
++ 'Maximum time the destination waits for the migration to finish.'),
++
+ ('migration_timeout', '300',
+ 'Maximum time the destination waits since migration is stalled. '
+ 'Please note, that this is not overall migration timeout. '
+diff --git a/vdsm/vm.py b/vdsm/vm.py
+index f9b241e..d862839 100644
+--- a/vdsm/vm.py
++++ b/vdsm/vm.py
+@@ -1695,6 +1695,10 @@ class ConsoleDevice(VmDevice):
+ return m
+
+
++class MigrationError(Exception):
++ pass
++
++
+ class Vm(object):
+ """
+ Used for abstracting communication between various parts of the
+@@ -3465,23 +3469,37 @@ class Vm(object):
+ hooks.after_vm_dehibernate(self._dom.XMLDesc(0), self.conf,
+ {'FROM_SNAPSHOT': fromSnapshot})
+ elif 'migrationDest' in self.conf:
+- timeout = config.getint('vars', 'migration_timeout')
+- self.log.debug("Waiting %s seconds for end of migration" % timeout)
++ timeout = config.getint('vars', 'migration_destination_timeout')
++ self.log.debug("Waiting %s seconds for end of migration", timeout)
+ self._incomingMigrationFinished.wait(timeout)
++
+ try:
+ # Would fail if migration isn't successful,
+ # or restart vdsm if connection to libvirt was lost
+ self._dom = NotifyingVirDomain(
+ self._connection.lookupByUUIDString(self.id),
+ self._timeoutExperienced)
+- except Exception as e:
+- # Improve description of exception
++
+ if not self._incomingMigrationFinished.isSet():
+- newMsg = ('%s - Timed out '
+- '(did not receive success event)' %
+- (e.args[0] if len(e.args) else
+- 'Migration Error'))
+- e.args = (newMsg,) + e.args[1:]
++ state = self._dom.state(0)
++ if state[0] == libvirt.VIR_DOMAIN_PAUSED:
++ if state[1] == libvirt.VIR_DOMAIN_PAUSED_MIGRATION:
++ raise MigrationError("Migration Error - Timed out "
++ "(did not receive success "
++ "event)")
++ self.log.debug("NOTE: incomingMigrationFinished event has "
++ "not been set and wait timed out after %d "
++ "seconds. Current VM state: %d, reason %d. "
++ "Continuing with VM initialization anyway.",
++ timeout, state[0], state[1])
++ except libvirt.libvirtError as e:
++ if e.get_error_code() == libvirt.VIR_ERR_NO_DOMAIN:
++ if not self._incomingMigrationFinished.isSet():
++ newMsg = ('%s - Timed out '
++ '(did not receive success event)' %
++ (e.args[0] if len(e.args) else
++ 'Migration Error'))
++ e.args = (newMsg,) + e.args[1:]
+ raise
+
+ self._domDependentInit()
+--
+1.7.1
+
diff --git a/0010-vdsm.spec-vdsm-should-own-vdsm.log.patch b/0010-vdsm.spec-vdsm-should-own-vdsm.log.patch
new file mode 100644
index 0000000..cc65a70
--- /dev/null
+++ b/0010-vdsm.spec-vdsm-should-own-vdsm.log.patch
@@ -0,0 +1,43 @@
+From 3d4b53db34486407d88a0c98773f68ecf7d63a05 Mon Sep 17 00:00:00 2001
+From: Douglas Schilling Landgraf <dougsland at redhat.com>
+Date: Wed, 5 Feb 2014 14:57:41 -0500
+Subject: [PATCH 10/17] vdsm.spec: vdsm should own vdsm.log
+
+/var/log/vdsm/vdsm.log should be owned by VDSM.
+
+Change-Id: Id12a78f3243138cd95a13cc7c8a8d3d499ceee4a
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1061561
+Signed-off-by: Douglas Schilling Landgraf <dougsland at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24042
+Reviewed-by: Yaniv Bronhaim <ybronhei at redhat.com>
+---
+ vdsm.spec.in | 6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/vdsm.spec.in b/vdsm.spec.in
+index 1435e0a..cfcda05 100644
+--- a/vdsm.spec.in
++++ b/vdsm.spec.in
+@@ -567,6 +567,11 @@ sed -i -e 's/^software_version =.*/software_version = "'"${baseversion}"'"/' \
+ rm -rf %{buildroot}
+ make DESTDIR=%{buildroot} install
+
++# VDSM Log
++install -dDm 0755 %{buildroot}@VDSMLOGDIR@
++# Avoid rpmbuild complain about vdsm.log doesn't exist during the build
++touch %{buildroot}@VDSMLOGDIR@/vdsm.log
++
+ # Install the respawn utility
+ install -Dm 0755 init/sysvinit/respawn \
+ %{buildroot}%{_datadir}/%{vdsm_name}/respawn
+@@ -837,6 +842,7 @@ exit 0
+ %endif
+
+ %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@
++%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/vdsm.log
+ %ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@/hsm-tasks
+ %ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@/mnt
+ %dir %{_libexecdir}/%{vdsm_name}
+--
+1.7.1
+
diff --git a/0011-vdsm.spec-own-metadata-supervdsm-mom-logs.patch b/0011-vdsm.spec-own-metadata-supervdsm-mom-logs.patch
new file mode 100644
index 0000000..d221cfd
--- /dev/null
+++ b/0011-vdsm.spec-own-metadata-supervdsm-mom-logs.patch
@@ -0,0 +1,52 @@
+From 24a05f7937191df5277e5d827e8fe659d0b56020 Mon Sep 17 00:00:00 2001
+From: Douglas Schilling Landgraf <dougsland at redhat.com>
+Date: Wed, 5 Feb 2014 15:08:07 -0500
+Subject: [PATCH 11/17] vdsm.spec: own metadata supervdsm mom logs
+
+/var/log/vdsm/metadata.log /var/log/vdsm/supervdsm.log
+/var/log/vdsm/mom.log should be owned by VDSM.
+Additionaly, now are now creating with touch those files
+(and vdsm.log) during the vdsm rpm install.
+
+Change-Id: I2776b8518930393b281a1885268813f8d4d7c85b
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1061561
+Signed-off-by: Douglas Schilling Landgraf <dougsland at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24043
+Reviewed-by: Yaniv Bronhaim <ybronhei at redhat.com>
+---
+ vdsm.spec.in | 11 ++++++++---
+ 1 files changed, 8 insertions(+), 3 deletions(-)
+
+diff --git a/vdsm.spec.in b/vdsm.spec.in
+index cfcda05..8d63591 100644
+--- a/vdsm.spec.in
++++ b/vdsm.spec.in
+@@ -567,9 +567,11 @@ sed -i -e 's/^software_version =.*/software_version = "'"${baseversion}"'"/' \
+ rm -rf %{buildroot}
+ make DESTDIR=%{buildroot} install
+
+-# VDSM Log
++# Creating VDSM logs
+ install -dDm 0755 %{buildroot}@VDSMLOGDIR@
+-# Avoid rpmbuild complain about vdsm.log doesn't exist during the build
++touch %{buildroot}@VDSMLOGDIR@/metadata.log
++touch %{buildroot}@VDSMLOGDIR@/mom.log
++touch %{buildroot}@VDSMLOGDIR@/supervdsm.log
+ touch %{buildroot}@VDSMLOGDIR@/vdsm.log
+
+ # Install the respawn utility
+@@ -842,7 +844,10 @@ exit 0
+ %endif
+
+ %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@
+-%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/vdsm.log
++%config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/metadata.log
++%config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/mom.log
++%config %attr(0644, root, root) @VDSMLOGDIR@/supervdsm.log
++%config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/vdsm.log
+ %ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@/hsm-tasks
+ %ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@/mnt
+ %dir %{_libexecdir}/%{vdsm_name}
+--
+1.7.1
+
diff --git a/0012-spec-do-not-remove-vdsm-logs-when-pkg-removed.patch b/0012-spec-do-not-remove-vdsm-logs-when-pkg-removed.patch
new file mode 100644
index 0000000..9cdfe69
--- /dev/null
+++ b/0012-spec-do-not-remove-vdsm-logs-when-pkg-removed.patch
@@ -0,0 +1,74 @@
+From 2d21f15b5d898945117bea9a173f48da33b93bc3 Mon Sep 17 00:00:00 2001
+From: Douglas Schilling Landgraf <dougsland at redhat.com>
+Date: Wed, 5 Feb 2014 15:09:18 -0500
+Subject: [PATCH 12/17] spec: do not remove vdsm logs when pkg removed
+
+In the commits 4a07386 0b6035a we introduced the concept
+of creating of metadata.log, mom.log, supervdsm.log and vdsm.log
+logs during the rpm install and sets the proper
+user/group. However, now when removing vdsm the logs are removed too
+which is not the behaviour as before these commits. This patch will
+add ghost macro in the spec to keep logs available when vdsm is removed.
+
+Change-Id: Idc8e62d5a0a6166c9141fe9d6016a525a3331694
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1061561
+Signed-off-by: Douglas Schilling Landgraf <dougsland at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24044
+Reviewed-by: Yaniv Bronhaim <ybronhei at redhat.com>
+---
+ vdsm.spec.in | 24 +++++++++++++++---------
+ 1 files changed, 15 insertions(+), 9 deletions(-)
+
+diff --git a/vdsm.spec.in b/vdsm.spec.in
+index 8d63591..f5142a9 100644
+--- a/vdsm.spec.in
++++ b/vdsm.spec.in
+@@ -567,12 +567,10 @@ sed -i -e 's/^software_version =.*/software_version = "'"${baseversion}"'"/' \
+ rm -rf %{buildroot}
+ make DESTDIR=%{buildroot} install
+
+-# Creating VDSM logs
++# Creating VDSM logs in this session to avoid rpmbuild
++# complain during the build
+ install -dDm 0755 %{buildroot}@VDSMLOGDIR@
+-touch %{buildroot}@VDSMLOGDIR@/metadata.log
+-touch %{buildroot}@VDSMLOGDIR@/mom.log
+-touch %{buildroot}@VDSMLOGDIR@/supervdsm.log
+-touch %{buildroot}@VDSMLOGDIR@/vdsm.log
++touch %{buildroot}@VDSMLOGDIR@/{metadata.log,mom.log,supervdsm.log,vdsm.log}
+
+ # Install the respawn utility
+ install -Dm 0755 init/sysvinit/respawn \
+@@ -653,6 +651,14 @@ export LC_ALL=C
+ # set the vdsm "secret" password for libvirt
+ %{_bindir}/vdsm-tool set-saslpasswd
+
++# After vdsm install we should create the logs files.
++# In the install session we create it but since we use
++# the ghost macro (in files session) the files are not included
++touch @VDSMLOGDIR@/{metadata.log,mom.log,supervdsm.log,vdsm.log}
++chmod 0644 @VDSMLOGDIR@/{metadata.log,mom.log,supervdsm.log,vdsm.log}
++chown @VDSMUSER@:@VDSMGROUP@ @VDSMLOGDIR@/{metadata.log,mom.log,vdsm.log}
++chown root:root @VDSMLOGDIR@/supervdsm.log
++
+ # Have moved vdsm section in /etc/sysctl.conf to /etc/sysctl.d/vdsm.conf.
+ # So Remove them if it is played with /etc/sysctl.conf.
+ if grep -q "# VDSM section begin" /etc/sysctl.conf; then
+@@ -844,10 +850,10 @@ exit 0
+ %endif
+
+ %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@
+-%config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/metadata.log
+-%config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/mom.log
+-%config %attr(0644, root, root) @VDSMLOGDIR@/supervdsm.log
+-%config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/vdsm.log
++%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/metadata.log
++%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/mom.log
++%ghost %config %attr(0644, root, root) @VDSMLOGDIR@/supervdsm.log
++%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) @VDSMLOGDIR@/vdsm.log
+ %ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@/hsm-tasks
+ %ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) @vdsmrepo@/mnt
+ %dir %{_libexecdir}/%{vdsm_name}
+--
+1.7.1
+
diff --git a/0013-vdsm-fix-RTC-offset.patch b/0013-vdsm-fix-RTC-offset.patch
new file mode 100644
index 0000000..f8e1008
--- /dev/null
+++ b/0013-vdsm-fix-RTC-offset.patch
@@ -0,0 +1,51 @@
+From 23c80f518ff4f28fd81b31b659d08ad76d18105e Mon Sep 17 00:00:00 2001
+From: Peter V. Saveliev <peet at redhat.com>
+Date: Wed, 15 May 2013 16:04:58 +0200
+Subject: [PATCH 13/17] vdsm: fix RTC offset
+
+Upon RTC update (hwclock --systohc) on the guest side, libvirt sends the event
+with RTC offset from the qemu start -rtc value in seconds. The received offset
+should not replace the previous value, but should be added to it. Since the
+time update event is relative to the qemu start time, we should store the
+initial value and use it for the calculation.
+
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=956741
+Change-Id: I27c70a53f64fb05607e93bffbac25fdee7d1cd2a
+Signed-off-by: Peter V. Saveliev <peet at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/14750
+Tested-by: Martin Polednik <mpoledni at redhat.com>
+Reviewed-by: Dan Kenigsberg <danken at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24260
+Reviewed-by: Francesco Romani <fromani at redhat.com>
+---
+ vdsm/vm.py | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/vdsm/vm.py b/vdsm/vm.py
+index d862839..bb35f0e 100644
+--- a/vdsm/vm.py
++++ b/vdsm/vm.py
+@@ -1752,6 +1752,7 @@ class Vm(object):
+ self.id = self.conf['vmId']
+ self._volPrepareLock = threading.Lock()
+ self._initTimePauseCode = None
++ self._initTimeRTC = long(self.conf.get('timeOffset', 0))
+ self.guestAgent = None
+ self._guestEvent = 'Powering up'
+ self._guestEventTime = 0
+@@ -2278,9 +2279,10 @@ class Vm(object):
+ timer.start()
+
+ def _rtcUpdate(self, timeOffset):
+- self.log.debug('new rtc offset %s', timeOffset)
++ newTimeOffset = str(self._initTimeRTC + long(timeOffset))
++ self.log.debug('new rtc offset %s', newTimeOffset)
+ with self._confLock:
+- self.conf['timeOffset'] = timeOffset
++ self.conf['timeOffset'] = newTimeOffset
+
+ def extendDrivesIfNeeded(self):
+ extend = []
+--
+1.7.1
+
diff --git a/0014-netinfo.speed-avoid-log-spam.patch b/0014-netinfo.speed-avoid-log-spam.patch
new file mode 100644
index 0000000..d296fe5
--- /dev/null
+++ b/0014-netinfo.speed-avoid-log-spam.patch
@@ -0,0 +1,40 @@
+From 69bd9ff37ba0f2021a3b45a2c2d32471568e7bf5 Mon Sep 17 00:00:00 2001
+From: Dan Kenigsberg <danken at redhat.com>
+Date: Fri, 7 Feb 2014 10:58:48 +0000
+Subject: [PATCH 14/17] netinfo.speed: avoid log spam
+
+Some network device drivers, such as infiniband, do not expose their
+"speed". In such cases we report speed "0", and fill vdsm.log with a
+persistent exception traceback. With this patch, Vdsm no longer seem
+surprised by a nic with invalid speed pseudofile.
+
+Thanks for Trey Dockendorf for reporting the issue on
+http://lists.ovirt.org/pipermail/users/2014-February/020987.html
+
+Bug-Url: https://bugzilla.redhat.com/1063433
+Change-Id: I4b03470139fb383fd03eaa2dc356539eae80d1c0
+Signed-off-by: Dan Kenigsberg <danken at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24197
+Reviewed-by: Antoni Segura Puimedon <asegurap at redhat.com>
+Reviewed-by: Yaniv Bronhaim <ybronhei at redhat.com>
+---
+ lib/vdsm/netinfo.py | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/lib/vdsm/netinfo.py b/lib/vdsm/netinfo.py
+index 790c099..7d12bb3 100644
+--- a/lib/vdsm/netinfo.py
++++ b/lib/vdsm/netinfo.py
+@@ -297,6 +297,9 @@ def speed(dev):
+ s = int(speedFile.read())
+ if s not in (2 ** 16 - 1, 2 ** 32 - 1) or s > 0:
+ return s
++ except IOError as ose:
++ if ose.errno != errno.EINVAL:
++ logging.exception('cannot read %s nic speed', dev)
+ except Exception:
+ logging.exception('cannot read %s speed', dev)
+ return 0
+--
+1.7.1
+
diff --git a/0015-vm-discover-volume-path-from-xml-definition.patch b/0015-vm-discover-volume-path-from-xml-definition.patch
new file mode 100644
index 0000000..f111e2e
--- /dev/null
+++ b/0015-vm-discover-volume-path-from-xml-definition.patch
@@ -0,0 +1,74 @@
+From d8684126d6c87578de44cab694d9e0cdb66a7107 Mon Sep 17 00:00:00 2001
+From: Federico Simoncelli <fsimonce at redhat.com>
+Date: Fri, 7 Feb 2014 06:42:02 -0500
+Subject: [PATCH 15/17] vm: discover volume path from xml definition
+
+In a previous commit (c072945 One shot prepare) we involuntarily
+changed the path used for virtual machine images from:
+
+ /rhev/data-center/<spUUID>/<sdUUID>/images/<imgUUID>/<volUUID>
+
+to:
+
+ /rhev/data-center/mnt/blockSD/<sdUUID>/images/<imgUUID>/<volUUID>
+
+This generated an issue during live migration between different
+vdsm versions:
+
+ libvirtError: invalid argument: invalid path ... not assigned to
+ domain
+
+In this patch we inspect libvirt xml during live migration and vdsm
+restart to identify if it is necessary to update the path cached in
+the drive object (provided by prepareImage).
+
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1061621
+Change-Id: I322f1f879fbd5b6415789f3b307e8741d846d694
+Signed-off-by: Federico Simoncelli <fsimonce at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24202
+Reviewed-by: Dan Kenigsberg <danken at redhat.com>
+Signed-off-by: Federico Simoncelli <fsimonce at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24329
+---
+ vdsm/vm.py | 18 ++++++++++++++++++
+ 1 files changed, 18 insertions(+), 0 deletions(-)
+
+diff --git a/vdsm/vm.py b/vdsm/vm.py
+index bb35f0e..fd295eb 100644
+--- a/vdsm/vm.py
++++ b/vdsm/vm.py
+@@ -4743,6 +4743,16 @@ class Vm(object):
+ address = self._getUnderlyingDeviceAddress(x)
+
+ for d in self._devices[DISK_DEVICES]:
++ # When we analyze a disk device that was already discovered in
++ # the past (generally as soon as the VM is created) we should
++ # verify that the cached path is the one used in libvirt.
++ # We already hit few times the problem that after a live
++ # migration the paths were not in sync anymore (BZ#1059482).
++ if (hasattr(d, 'alias') and d.alias == alias
++ and d.path != devPath):
++ self.log.warning('updating drive %s path from %s to %s',
++ d.alias, d.path, devPath)
++ d.path = devPath
+ if d.path == devPath:
+ d.name = name
+ d.type = devType
+@@ -4755,6 +4765,14 @@ class Vm(object):
+ # Update vm's conf with address for known disk devices
+ knownDev = False
+ for dev in self.conf['devices']:
++ # See comment in previous loop. This part is used to update
++ # the vm configuration as well.
++ if ('alias' in dev and dev['alias'] == alias
++ and dev['path'] != devPath):
++ self.log.warning('updating drive %s config path from %s '
++ 'to %s', dev['alias'], dev['path'],
++ devPath)
++ dev['path'] = devPath
+ if dev['type'] == DISK_DEVICES and dev['path'] == devPath:
+ dev['name'] = name
+ dev['address'] = address
+--
+1.7.1
+
diff --git a/0016-Removing-vdsm-python-cpopen-rpm-creation-from-vdsm.patch b/0016-Removing-vdsm-python-cpopen-rpm-creation-from-vdsm.patch
new file mode 100644
index 0000000..f4af29d
--- /dev/null
+++ b/0016-Removing-vdsm-python-cpopen-rpm-creation-from-vdsm.patch
@@ -0,0 +1,930 @@
+From 6cb118c5fa55f5bca39790538fa7e3ca91756b40 Mon Sep 17 00:00:00 2001
+From: Yaniv Bronhaim <ybronhei at redhat.com>
+Date: Wed, 12 Feb 2014 10:35:46 +0200
+Subject: [PATCH 16/17] Removing vdsm-python-cpopen rpm creation from vdsm
+
+In vdsm 4.13.2 we replaced the dependency of python-cpopen (commit
+f3677ba1). Due to that change we are no longer required to provide
+vdsm-python-cpopen as part of vdsm build. This patch removes all cpopen
+related files from vdsm.
+
+Change-Id: Ib21f293075a9d1464f7f6a08fd689c9fd76f33e8
+Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=1063180
+Signed-off-by: Yaniv Bronhaim <ybronhei at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24360
+Reviewed-by: Antoni Segura Puimedon <asegurap at redhat.com>
+Reviewed-by: Kiril Nesenko <knesenko at redhat.com>
+Reviewed-by: Dan Kenigsberg <danken at redhat.com>
+---
+ Makefile.am | 1 -
+ configure.ac | 2 +-
+ debian/Makefile.am | 2 -
+ debian/control | 11 +-
+ debian/vdsm-python-cpopen.install | 2 -
+ lib/Makefile.am | 2 +-
+ lib/cpopen/Makefile.am | 48 -----
+ lib/cpopen/__init__.py | 74 -------
+ lib/cpopen/cpopen.c | 392 -------------------------------------
+ lib/cpopen/setup.py | 13 --
+ lib/cpopen/tests.py | 196 ------------------
+ vdsm.spec.in | 18 +--
+ 13 files changed, 8 insertions(+), 755 deletions(-)
+ delete mode 100644 debian/vdsm-python-cpopen.install
+ delete mode 100644 lib/cpopen/Makefile.am
+ delete mode 100644 lib/cpopen/__init__.py
+ delete mode 100644 lib/cpopen/cpopen.c
+ delete mode 100644 lib/cpopen/setup.py
+ delete mode 100644 lib/cpopen/tests.py
+
+diff --git a/Makefile.am b/Makefile.am
+index d71ee28..9b1a3c9 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -57,7 +57,6 @@ endif
+ # checkd from now on
+ PEP8_WHITELIST = \
+ client \
+- lib/cpopen/*.py \
+ lib/vdsm/*.py \
+ lib/vdsm/*.py.in \
+ tests \
+diff --git a/configure.ac b/configure.ac
+index 52105e9..aac15b7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -181,6 +181,7 @@ fi
+ AX_PYTHON_MODULE([ethtool], [fatal])
+ AX_PYTHON_MODULE([libvirt], [fatal])
+ AX_PYTHON_MODULE([pthreading], [fatal])
++AX_PYTHON_MODULE([cpopen], [fatal])
+
+ # External programs (sorted, please keep in order)
+ AC_PATH_PROG([BLKID_PATH], [blkid], [/sbin/blkid])
+@@ -254,7 +255,6 @@ AC_OUTPUT([
+ init/sysvinit/Makefile
+ init/upstart/Makefile
+ lib/Makefile
+- lib/cpopen/Makefile
+ lib/vdsm/Makefile
+ lib/vdsm/tool/Makefile
+ lib/yajsonrpc/Makefile
+diff --git a/debian/Makefile.am b/debian/Makefile.am
+index 25e79c3..732529d 100644
+--- a/debian/Makefile.am
++++ b/debian/Makefile.am
+@@ -84,8 +84,6 @@ EXTRA_DIST = \
+ vdsm.postrm \
+ vdsm.preinst \
+ vdsm.prerm \
+- vdsm-python-cpopen.docs \
+- vdsm-python-cpopen.install \
+ vdsm-python.docs \
+ vdsm-python.install \
+ vdsm-tests.docs \
+diff --git a/debian/control b/debian/control
+index da030ad..820bc26 100644
+--- a/debian/control
++++ b/debian/control
+@@ -31,13 +31,6 @@ Homepage: http://www.ovirt.org/wiki/Vdsm
+ Vcs-Git: git://gerrit.ovirt.org/vdsm
+ Vcs-Browser: http://gerrit.ovirt.org/gitweb?p=vdsm.git
+
+-Package: vdsm-python-cpopen
+-Architecture: any
+-Depends: ${shlibs:Depends}, ${misc:Depends}, ${python:Depends}, python (>=2.7.3)
+-Description: Creates a sub-process in simpler safer manner
+- Python package for creating sub-process in simpler and safer manner by using
+- C code.
+-
+ Package: vdsm-yajsonrpc
+ Architecture: all
+ Depends: ${shlibs:Depends}, ${misc:Depends}, python (>=2.7.3),
+@@ -54,7 +47,7 @@ Package: vdsm-client
+ Architecture: all
+ Depends: ${shlibs:Depends}, ${misc:Depends},
+ python (>=2.7.3),
+- vdsm-python-cpopen (>= ${source:Version}),
++ python-cpopen,
+ vdsm-python (= ${source:Version})
+ Description: VDSM command line interface
+ Call VDSM commands from the command line. Used for testing and debugging.
+@@ -93,7 +86,7 @@ Depends: ${shlibs:Depends}, ${misc:Depends},
+ policycoreutils (>= 2.1.10),
+ psmisc (>= 22.6),
+ python (>= 2.7.3),
+- vdsm-python-cpopen (= ${binary:Version}),
++ python-cpopen,
+ python-dmidecode,
+ python-ethtool (>= 0.8),
+ python-ethtool (>= 0.8),
+diff --git a/debian/vdsm-python-cpopen.install b/debian/vdsm-python-cpopen.install
+deleted file mode 100644
+index d38a40e..0000000
+--- a/debian/vdsm-python-cpopen.install
++++ /dev/null
+@@ -1,2 +0,0 @@
+-./usr/lib/python2.7/dist-packages/cpopen/__init__.py
+-./usr/lib/python2.7/dist-packages/cpopen/cpopen.so
+diff --git a/lib/Makefile.am b/lib/Makefile.am
+index b1a1a12..ff46328 100644
+--- a/lib/Makefile.am
++++ b/lib/Makefile.am
+@@ -19,4 +19,4 @@
+ #
+ include $(top_srcdir)/build-aux/Makefile.subs
+
+-SUBDIRS = vdsm cpopen yajsonrpc
++SUBDIRS = vdsm yajsonrpc
+diff --git a/lib/cpopen/Makefile.am b/lib/cpopen/Makefile.am
+deleted file mode 100644
+index c39ca24..0000000
+--- a/lib/cpopen/Makefile.am
++++ /dev/null
+@@ -1,48 +0,0 @@
+-#
+-# Copyright 2012 Red Hat, Inc.
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program 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 General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+-#
+-# Refer to the README and COPYING files for full details of the license
+-#
+-
+-cpopendir = $(pyexecdir)/cpopen
+-
+-dist_cpopen_PYTHON = \
+- __init__.py \
+- $(NULL)
+-
+-cpopen.so: cpopen.c setup.py
+- (cd $(srcdir); $(PYTHON) setup.py build \
+- --build-temp $(abs_builddir) --build-lib $(abs_builddir))
+-
+-all-local: cpopen.so
+-
+-install-data-local:
+- $(MKDIR_P) $(DESTDIR)$(cpopendir)
+- $(INSTALL_PROGRAM) cpopen.so \
+- $(DESTDIR)$(cpopendir)/cpopen.so
+-
+-check-local: tests.py
+- nosetests tests.py
+-
+-EXTRA_DIST = \
+- cpopen.c \
+- tests.py \
+- setup.py
+-
+-CLEANFILES = \
+- cpopen.o \
+- cpopen.so
+diff --git a/lib/cpopen/__init__.py b/lib/cpopen/__init__.py
+deleted file mode 100644
+index d671355..0000000
+--- a/lib/cpopen/__init__.py
++++ /dev/null
+@@ -1,74 +0,0 @@
+-#
+-# Copyright 2012 Red Hat, Inc.
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program 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 General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+-#
+-# Refer to the README and COPYING files for full details of the license
+-#
+-
+-"""
+-Python's implementation of Popen forks back to python before execing.
+-Forking a python proc is a very complex and volatile process.
+-
+-This is a simpler method of execing that doesn't go back to python after
+-forking. This allows for faster safer exec.
+-"""
+-
+-import os
+-from subprocess import Popen, PIPE
+-
+-from cpopen import createProcess
+-
+-
+-class CPopen(Popen):
+- def __init__(self, args, close_fds=False, cwd=None, env=None,
+- deathSignal=0):
+- if not isinstance(args, list):
+- args = list(args)
+-
+- if env is not None and not isinstance(env, list):
+- env = list(("=".join(item) for item in env.iteritems()))
+-
+- self._deathSignal = int(deathSignal)
+- Popen.__init__(self, args,
+- close_fds=close_fds, cwd=cwd, env=env,
+- stdin=PIPE, stdout=PIPE,
+- stderr=PIPE)
+-
+- def _execute_child(self, args, executable, preexec_fn, close_fds,
+- cwd, env, universal_newlines,
+- startupinfo, creationflags, shell,
+- p2cread, p2cwrite,
+- c2pread, c2pwrite,
+- errread, errwrite):
+-
+- try:
+- pid, stdin, stdout, stderr = \
+- createProcess(args, close_fds, p2cread, p2cwrite,
+- c2pread, c2pwrite, errread, errwrite,
+- cwd, env, self._deathSignal)
+-
+- self.pid = pid
+- self._closed = False
+- self._returncode = None
+- except:
+- os.close(p2cwrite)
+- os.close(errread)
+- os.close(c2pread)
+- raise
+- finally:
+- os.close(p2cread)
+- os.close(errwrite)
+- os.close(c2pwrite)
+diff --git a/lib/cpopen/cpopen.c b/lib/cpopen/cpopen.c
+deleted file mode 100644
+index 7b9ddce..0000000
+--- a/lib/cpopen/cpopen.c
++++ /dev/null
+@@ -1,392 +0,0 @@
+-/*
+-* Copyright 2012 Red Hat, Inc.
+-*
+-* This program is free software; you can redistribute it and/or modify
+-* it under the terms of the GNU General Public License as published by
+-* the Free Software Foundation; either version 2 of the License, or
+-* (at your option) any later version.
+-*
+-* This program 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 General Public License for more details.
+-*
+-* You should have received a copy of the GNU General Public License
+-* along with this program; if not, write to the Free Software
+-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+-*
+-* Refer to the README and COPYING files for full details of the license
+-*/
+-
+-#include <Python.h>
+-
+-#include <dirent.h>
+-#include <sys/types.h>
+-#include <sys/stat.h>
+-#include <fcntl.h>
+-#include <sys/prctl.h>
+-
+-static PyObject *createProcess(PyObject *self, PyObject *args);
+-static PyMethodDef CreateProcessMethods[];
+-static void closeFDs(int errnofd);
+-
+-/* Python boilerplate */
+-static PyMethodDef
+-CreateProcessMethods[] = {
+- {"createProcess", createProcess, METH_VARARGS,
+- "Execute a command."},
+- {NULL, NULL, 0, NULL} /* Sentinel */
+-};
+-
+-PyMODINIT_FUNC
+-initcpopen(void)
+-{
+- PyObject *m;
+-
+- m = Py_InitModule("cpopen", CreateProcessMethods);
+-
+- /* In the future put other init code after this condition. */
+- if (m == NULL)
+- return;
+-}
+-
+-/* Just like close() but retries on interrupt */
+-static int
+-safeClose(int fd) {
+- int rv;
+-
+-retry:
+- rv = close(fd);
+- if ((rv < 0) && (errno == EINTR)) {
+- goto retry;
+- }
+-
+- return rv;
+-}
+-
+-/* Just like read() but retries on interrupt and tries to fill the buffer */
+-static int
+-safeRead(int fd, void *buff, size_t count) {
+- size_t bread = 0;
+- char* cbuff = buff;
+- int rv = 0;
+- while (bread < count) {
+- rv = read(fd, cbuff + bread, count - bread);
+- if (rv == 0) { /* EOF */
+- return bread;
+- } else if (rv < 0) { /* ERROR */
+- switch (errno) {
+- case EINTR:
+- case EAGAIN:
+- break;
+- default:
+- return rv;
+- }
+- } else { /* Success */
+- bread += rv;
+- }
+- }
+-
+- return bread;
+-}
+-
+-static int
+-setCloseOnExec(int fd) {
+- int flags;
+-
+- flags = fcntl(fd, F_GETFD);
+- if (flags == -1) {
+- return -1;
+- }
+-
+- if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) == -1) {
+- return -1;
+- }
+-
+- return 0;
+-}
+-
+-/* Closes all open FDs except for stdin, stdout and stderr */
+-static void
+-closeFDs(int errnofd) {
+- DIR *dp;
+- int dfd;
+- struct dirent *ep;
+- int fdNum = -1;
+-
+- dfd = open("/proc/self/fd/", O_RDONLY);
+- dp = fdopendir(dfd);
+- while ((ep = readdir(dp))) {
+- if(sscanf(ep->d_name, "%d", &fdNum) < 1) {
+- continue;
+- }
+-
+- if (fdNum < 3) {
+- continue;
+- }
+-
+- if (fdNum == dfd) {
+- continue;
+- }
+-
+- if (fdNum == errnofd) {
+- continue;
+- }
+-
+- safeClose(fdNum);
+- }
+-
+- closedir(dp);
+- safeClose(dfd);
+-}
+-
+-static void
+-freeStringArray(char** arr) {
+- char** item;
+- for (item = arr; *item != NULL; item++) {
+- PyMem_Free(*item);
+- }
+-
+- free(arr);
+-}
+-
+-/* Copies the strings from a python list to a null terminated array.
+- * The strings are shallow copied and are owned by python.
+- * Don't keep this array after the call.
+- *
+- * Returns a NULL terminated array of null strings. On error returns NULL and
+- * sets the python error accordingly
+- */
+-static char**
+-pyListToArray(PyObject* list, int checkIfEmpty) {
+- int argn;
+- int i;
+- char** argv;
+-
+- if (!PyList_Check(list)) {
+- PyErr_SetString(PyExc_TypeError, "Argument must be a python list");
+- return NULL;
+- }
+-
+- argn = PyList_Size(list);
+- if ((checkIfEmpty) && (argn < 1)) {
+- PyErr_SetString(PyExc_ValueError, "List must not be empty");
+- return NULL;
+- }
+-
+- argv = calloc(argn + 1, sizeof(char*));
+- if (!argv) {
+- PyErr_SetFromErrno(PyExc_OSError);
+- return NULL;
+- }
+-
+- for (i = 0; i < argn; i++) {
+- if (!PyArg_Parse(PyList_GetItem(list, i),
+- "et;",
+- Py_FileSystemDefaultEncoding,
+- &argv[i])) {
+- PyErr_SetString(PyExc_TypeError,
+- "createProcess() arg 2 must contain only strings");
+- goto fail;
+- }
+- }
+-
+- return argv;
+-
+-fail:
+- freeStringArray(argv);
+- return NULL;
+-}
+-
+-/* Python's implementation of Popen forks back to python before execing.
+- * Forking a python proc is a very complex and volatile process.
+- *
+- * This is a simpler method of execing that doesn't go back to python after
+- * forking. This allows for faster safer exec.
+- *
+- * return NULL on error and sets the python error accordingly.
+- */
+-static PyObject *
+-createProcess(PyObject *self, PyObject *args)
+-{
+- int cpid;
+- int deathSignal = 0;
+- int rv;
+-
+- int outfd[2] = {-1, -1};
+- int in1fd[2] = {-1, -1};
+- int in2fd[2] = {-1, -1};
+-
+- int errnofd[2] = {-1, -1};
+- int childErrno = 0;
+-
+- PyObject* pyArgList;
+- PyObject* pyEnvList;
+- const char* cwd;
+- int close_fds = 0;
+-
+- char** argv = NULL;
+- char** envp = NULL;
+-
+- if (!PyArg_ParseTuple(args, "O!iiiiiiizOi:createProcess;",
+- &PyList_Type, &pyArgList, &close_fds,
+- &outfd[0], &outfd[1],
+- &in1fd[0], &in1fd[1],
+- &in2fd[0], &in2fd[1],
+- &cwd, &pyEnvList, &deathSignal)) {
+- return NULL;
+- }
+-
+- argv = pyListToArray(pyArgList, 1);
+- if (!argv) {
+- goto fail;
+- }
+-
+- if (PyList_Check(pyEnvList)) {
+- envp = pyListToArray(pyEnvList, 0);
+- if (!envp) {
+- goto fail;
+- }
+- }
+-
+- if(pipe(errnofd) < 0) {
+- PyErr_SetFromErrno(PyExc_OSError);
+- goto fail;
+- }
+-
+-try_fork:
+- cpid = fork();
+- if (cpid < 0) {
+- if (errno == EAGAIN ||
+- errno == EINTR ) {
+- goto try_fork;
+- }
+-
+- PyErr_SetFromErrno(PyExc_OSError);
+- goto fail;
+- }
+-
+- if (!cpid) {
+- safeClose(0);
+- safeClose(1);
+- safeClose(2);
+-
+- dup2(outfd[0], 0);
+- dup2(in1fd[1], 1);
+- dup2(in2fd[1], 2);
+-
+- safeClose(outfd[0]);
+- safeClose(outfd[1]);
+- safeClose(in1fd[0]);
+- safeClose(in1fd[1]);
+- safeClose(in2fd[0]);
+- safeClose(in2fd[1]);
+- safeClose(errnofd[0]);
+-
+- if (deathSignal) {
+- childErrno = prctl(PR_SET_PDEATHSIG, deathSignal);
+- if (childErrno < 0) {
+- childErrno = errno;
+- }
+- /* Check that parent did not already die between fork and us
+- * setting the death signal */
+- if (write(errnofd[1], &childErrno, sizeof(int)) < sizeof(int)) {
+- exit(-1);
+- }
+-
+- if (childErrno != 0) {
+- exit(-1);
+- }
+- }
+-
+- if (setCloseOnExec(errnofd[1]) < 0) {
+- goto sendErrno;
+- }
+-
+- if (close_fds) {
+- closeFDs(errnofd[1]);
+- }
+-
+- if (cwd) {
+- if (chdir(cwd) < 0) {
+- goto sendErrno;
+- }
+- setenv("PWD", cwd, 1);
+- }
+-exec:
+- if (envp) {
+- execvpe(argv[0], argv, envp);
+- } else {
+- execvp(argv[0], argv);
+- }
+-
+- if (errno == EINTR ||
+- errno == EAGAIN )
+- {
+- goto exec;
+- }
+-sendErrno:
+- if (write(errnofd[1], &errno, sizeof(int)) < 0) {
+- exit(errno);
+- }
+- exit(-1);
+- }
+-
+- safeClose(errnofd[1]);
+- errnofd[1] = -1;
+-
+- if (deathSignal) {
+- /* death signal sync point */
+- rv = safeRead(errnofd[0], &childErrno, sizeof(int));
+- if (rv != sizeof(int)) {
+- PyErr_SetFromErrno(PyExc_OSError);
+- goto fail;
+- } else if (childErrno != 0) {
+- PyErr_SetString(PyExc_OSError, strerror(childErrno));
+- goto fail;
+- }
+- }
+-
+- /* error sync point */
+- rv = safeRead(errnofd[0], &childErrno, sizeof(int));
+- if (rv == sizeof(int)) {
+- PyErr_SetString(PyExc_OSError, strerror(childErrno));
+- goto fail;
+- } else if (rv < 0) {
+- PyErr_SetFromErrno(PyExc_OSError);
+- goto fail;
+- }
+-
+- safeClose(errnofd[0]);
+- errnofd[0] = -1;
+-
+- /* From this point errors shouldn't occur, if they do something is very
+- * very very wrong */
+-
+- freeStringArray(argv);
+-
+- if (envp) {
+- freeStringArray(envp);
+- }
+-
+- return Py_BuildValue("(iiii)", cpid, outfd[1], in1fd[0], in2fd[0]);
+-
+-fail:
+- if (argv) {
+- freeStringArray(argv);
+- }
+-
+- if (envp) {
+- freeStringArray(envp);
+- }
+-
+- if (errnofd[0] >= 0) {
+- safeClose(errnofd[0]);
+- }
+-
+- if (errnofd[1] >= 0) {
+- safeClose(errnofd[1]);
+- }
+-
+- return NULL;
+-}
+diff --git a/lib/cpopen/setup.py b/lib/cpopen/setup.py
+deleted file mode 100644
+index 66fc157..0000000
+--- a/lib/cpopen/setup.py
++++ /dev/null
+@@ -1,13 +0,0 @@
+-from distutils.core import setup, Extension
+-
+-module1 = Extension('cpopen',
+- sources=['cpopen.c'])
+-
+-setup(name='cpopen',
+- version='1.2.1',
+- description='Creates a subprocess in simpler safer manner',
+- py_modules=['__init__'],
+- author='Yaniv Bronhaim',
+- author_email='ybronhei at redhat.com',
+- url='redhat.com',
+- ext_modules=[module1])
+diff --git a/lib/cpopen/tests.py b/lib/cpopen/tests.py
+deleted file mode 100644
+index 9dd1906..0000000
+--- a/lib/cpopen/tests.py
++++ /dev/null
+@@ -1,196 +0,0 @@
+-#
+-# Copyright 2012 Red Hat, Inc.
+-#
+-# This program is free software; you can redistribute it and/or modify
+-# it under the terms of the GNU General Public License as published by
+-# the Free Software Foundation; either version 2 of the License, or
+-# (at your option) any later version.
+-#
+-# This program 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 General Public License for more details.
+-#
+-# You should have received a copy of the GNU General Public License
+-# along with this program; if not, write to the Free Software
+-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+-#
+-# Refer to the README and COPYING files for full details of the license
+-#
+-import os
+-import sys
+-import subprocess
+-from nose.plugins.skip import SkipTest
+-import signal
+-import threading
+-import time
+-
+-from unittest import TestCase
+-
+-EXT_ECHO = "/bin/echo"
+-
+-if __name__ != "__main__":
+- # This will not be available when we use this module as a subprocess
+- import glob
+- for p in glob.glob("build/*/"):
+- sys.path.append(p)
+-
+- from . import CPopen
+-
+-
+-class TestCPopen(TestCase):
+- def testEcho(self):
+- data = "Hello"
+- p = CPopen([EXT_ECHO, "-n", data])
+- p.wait()
+- self.assertTrue(p.returncode == 0,
+- "Process failed: %s" % os.strerror(p.returncode))
+- self.assertEquals(p.stdout.read(), data)
+-
+- def testCat(self):
+- path = "/etc/passwd"
+- p = CPopen(["cat", path])
+- p.wait()
+- self.assertTrue(p.returncode == 0,
+- "Process failed: %s" % os.strerror(p.returncode))
+- with open(path, "r") as f:
+- self.assertEquals(p.stdout.read(), f.read())
+-
+- def _subTest(self, name, params, *args, **kwargs):
+- p = CPopen(["python", __file__, name] + params,
+- *args, **kwargs)
+- p.wait()
+- self.assertTrue(p.returncode == 0,
+- "Process failed: %s" % os.strerror(p.returncode))
+- self.assertEquals(p.stdout.read().strip(), "True")
+-
+- def testCloseFDs(self):
+- fds = os.pipe()
+- try:
+- self._subTest("fds", [str(fds[1])], close_fds=True)
+- finally:
+- os.close(fds[0])
+- os.close(fds[1])
+-
+- def testNoCloseFds(self):
+- fds = os.pipe()
+- try:
+- self._subTest("nofds", [str(fds[1])], close_fds=False)
+- finally:
+- os.close(fds[0])
+- os.close(fds[1])
+-
+- def testEnv(self):
+- env = os.environ.copy()
+- env["TEST"] = "True"
+- self._subTest("env", [], env=env)
+-
+- def testCwd(self):
+- cwd = "/proc"
+- p = CPopen(["python", "-c", "import os; print os.getcwd()"],
+- cwd=cwd)
+- p.wait()
+- self.assertTrue(p.returncode == 0,
+- "Process failed: %s" % os.strerror(p.returncode))
+- self.assertEquals(p.stdout.read().strip(), cwd)
+-
+- def testRunNonExecutable(self):
+- self.assertRaises(OSError, CPopen, ["/tmp"])
+-
+- def testBadCwd(self):
+- self.assertRaises(OSError, CPopen, ["echo", "hello"],
+- cwd="/~~~~~dasdas~~~~")
+-
+- def testUnicodeArg(self):
+- data = u'hello'
+- cmd = [EXT_ECHO, "-n", data]
+-
+- p = CPopen(cmd)
+- p.wait()
+- p2 = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+- p2.wait()
+- self.assertEquals(p.stdout.read(), p2.stdout.read())
+-
+- def testNonASCIIUnicodeArg(self):
+- data = u'\u05e9\u05dc\u05d5\u05dd'
+- # If the default encoding is not utf-8 the test *should* fail as non
+- # ascii conversion shouldn't work
+- if sys.getfilesystemencoding() != "UTF-8":
+- raise SkipTest("The default encoding isn't unicode")
+-
+- cmd = [EXT_ECHO, "-n", data]
+-
+- p = CPopen(cmd)
+- p.wait()
+- p2 = subprocess.Popen(cmd, stdin=subprocess.PIPE,
+- stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+- p2.wait()
+- self.assertEquals(p.stdout.read(), p2.stdout.read())
+-
+- def testStdin(self):
+- data = "Hello World"
+- p = CPopen(["cat"])
+- p.stdin.write(data)
+- p.stdin.flush()
+- p.stdin.close()
+- p.wait()
+- self.assertTrue(p.returncode == 0,
+- "Process failed: %s" % os.strerror(p.returncode))
+-
+- self.assertEquals(p.stdout.read(), data)
+-
+- def testStdinEpoll(self):
+- import select
+-
+- data = "Hello World"
+- p = CPopen(["cat"])
+- ep = select.epoll()
+- ep.register(p.stdin, select.EPOLLOUT)
+- fd, ev = ep.poll(1)[0]
+- ep.close()
+- os.write(fd, data)
+- p.stdin.close()
+- p.wait()
+- self.assertTrue(p.returncode == 0,
+- "Process failed: %s" % os.strerror(p.returncode))
+-
+- self.assertEquals(p.stdout.read(), data)
+-
+- def testDeathSignal(self):
+- # This is done because assignment in python doesn't cross scopes
+- procPtr = [None]
+-
+- def spawn():
+- procPtr[0] = CPopen(["sleep", "10"],
+- deathSignal=signal.SIGKILL)
+-
+- t = threading.Thread(target=spawn)
+- t.start()
+- t.join()
+- start = time.time()
+- procPtr[0].wait()
+- self.assertTrue(time.time() - start < 1)
+-
+-
+-if __name__ == "__main__":
+- cmd = sys.argv[1]
+- if cmd == "fds":
+- try:
+- os.close(int(sys.argv[2]))
+- print "False"
+- except:
+- print "True"
+-
+- elif cmd == "nofds":
+- try:
+- os.close(int(sys.argv[2]))
+- print "True"
+- except:
+- print "False"
+-
+- elif cmd == "env":
+- try:
+- print os.environ.get("TEST", "False")
+- except:
+- print "False"
+diff --git a/vdsm.spec.in b/vdsm.spec.in
+index f5142a9..41a4e19 100644
+--- a/vdsm.spec.in
++++ b/vdsm.spec.in
+@@ -308,16 +308,6 @@ Requires: openssl
+ VDSM registration package. Used to register a Linux host to a Virtualization
+ Manager.
+
+-%package python-cpopen
+-Summary: Creates a sub-process in simpler safer manner.
+-
+-BuildRequires: python2-devel
+-Conflicts: python-cpopen
+-
+-%description python-cpopen
+-Python package for creating sub-process in simpler and safer manner by using C
+-code.
+-
+ %package python
+ Summary: VDSM python libraries
+
+@@ -1332,11 +1322,11 @@ exit 0
+ %{_datadir}/%{vdsm_name}/gluster/services.py*
+ %endif
+
+-%files python-cpopen
+-%{python_sitearch}/cpopen/__init__.py*
+-%attr(755, root, root) %{python_sitearch}/cpopen/cpopen.so*
+-
+ %changelog
++* Wed Feb 12 2014 Yaniv Bronhaim <ybronhei at redhat.com> - 4.13.2
++- Removing creation of vdsm-python-cpopen package and replace it by
++python-cpopen requirement.
++
+ * Sun Apr 07 2013 Yaniv Bronhaim <ybronhei at redhat.com> - 4.9.0-1
+ - Adding cpopen package
+
+--
+1.7.1
+
diff --git a/0017-vm-iface-statistics-never-report-negative-rates.patch b/0017-vm-iface-statistics-never-report-negative-rates.patch
new file mode 100644
index 0000000..d19ae2d
--- /dev/null
+++ b/0017-vm-iface-statistics-never-report-negative-rates.patch
@@ -0,0 +1,47 @@
+From 79a0e17da7d09060bc12251242ac26911da5b5f3 Mon Sep 17 00:00:00 2001
+From: Dan Kenigsberg <danken at redhat.com>
+Date: Wed, 22 Jan 2014 15:56:56 +0000
+Subject: [PATCH 17/17] vm iface statistics: never report negative rates
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+When Linux tx/rx couters overflow their 32 bit limit, they wrap back to
+zero. This causes our reported rxRate/txRate to become negative for one
+nample. 51073875161d9b932b7
+
+Bug-Url: https://bugzilla.redhat.com/1064489
+Change-Id: I40daeb12172a7f54f135b3018405ef228983fa93
+Signed-off-by: Dan Kenigsberg <danken at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/23598
+Tested-by: Ondřej Svoboda <osvoboda at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24152
+Reviewed-by: Antoni Segura Puimedon <asegurap at redhat.com>
+Reviewed-by: Yaniv Bronhaim <ybronhei at redhat.com>
+Reviewed-on: http://gerrit.ovirt.org/24322
+---
+ vdsm/vm.py | 6 ++++--
+ 1 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/vdsm/vm.py b/vdsm/vm.py
+index fd295eb..7d4aa51 100644
+--- a/vdsm/vm.py
++++ b/vdsm/vm.py
+@@ -616,10 +616,12 @@ class VmStatsThread(sampling.AdvancedStatsThread):
+ ifStats['txDropped'] = str(eInfo[nic.name][7])
+
+ ifRxBytes = (100.0 *
+- (eInfo[nic.name][0] - sInfo[nic.name][0]) /
++ (eInfo[nic.name][0] - sInfo[nic.name][0]) %
++ 2 ** 32 /
+ sampleInterval / ifSpeed / self.MBPS_TO_BPS)
+ ifTxBytes = (100.0 *
+- (eInfo[nic.name][4] - sInfo[nic.name][4]) /
++ (eInfo[nic.name][4] - sInfo[nic.name][4]) %
++ 2 ** 32 /
+ sampleInterval / ifSpeed / self.MBPS_TO_BPS)
+
+ ifStats['rxRate'] = '%.1f' % ifRxBytes
+--
+1.7.1
+
diff --git a/vdsm.spec b/vdsm.spec
index a10cad2..d8c979d 100644
--- a/vdsm.spec
+++ b/vdsm.spec
@@ -46,7 +46,7 @@
Name: %{vdsm_name}
Version: 4.13.3
-Release: 3%{?dist}%{?extra_release}
+Release: 4%{?dist}%{?extra_release}
Summary: Virtual Desktop Server Manager
Group: Applications/System
@@ -67,10 +67,23 @@ Patch2: 0003-Revert-utils-Create-AsyncProcessOperation.patch
Patch3: 0004-Revert-iscsi-Iscsi-rescan-cleanup.patch
Patch4: 0005-Report-conflict-when-python-cpopen-is-installed.patch
Patch5: 0006-spec-replace-requires-vdsm-python-cpopen.patch
+# ovirt-3.3.4 patches
+Patch6: 0007-sos-plugin-should-ignore-var-run-vdsm-storage.patch
+Patch7: 0008-vdsm-pre-defined-range-for-spice-vnc-ports.patch
+Patch8: 0009-Avoid-going-into-Paused-status-during-long-lasting-m.patch
+Patch9: 0010-vdsm.spec-vdsm-should-own-vdsm.log.patch
+Patch10: 0011-vdsm.spec-own-metadata-supervdsm-mom-logs.patch
+Patch11: 0012-spec-do-not-remove-vdsm-logs-when-pkg-removed.patch
+Patch12: 0013-vdsm-fix-RTC-offset.patch
+Patch13: 0014-netinfo.speed-avoid-log-spam.patch
+Patch14: 0015-vm-discover-volume-path-from-xml-definition.patch
+Patch15: 0016-Removing-vdsm-python-cpopen-rpm-creation-from-vdsm.patch
+Patch16: 0017-vm-iface-statistics-never-report-negative-rates.patch
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires: python
+BuildRequires: python-cpopen
BuildRequires: python-devel
BuildRequires: python-nose
BuildRequires: python-netaddr
@@ -329,16 +342,6 @@ Requires: openssl
VDSM registration package. Used to register a Linux host to a Virtualization
Manager.
-%package python-cpopen
-Summary: Creates a sub-process in simpler safer manner.
-
-BuildRequires: python2-devel
-Conflicts: python-cpopen
-
-%description python-cpopen
-Python package for creating sub-process in simpler and safer manner by using C
-code.
-
%package python
Summary: VDSM python libraries
@@ -573,6 +576,18 @@ Gluster plugin enables VDSM to serve Gluster functionalities.
%patch3 -p1
%patch4 -p1
%patch5 -p1
+# ovirt-3.3.4 patches
+%patch6 -p1
+%patch7 -p1
+%patch8 -p1
+%patch9 -p1
+%patch10 -p1
+%patch11 -p1
+%patch12 -p1
+%patch13 -p1
+%patch14 -p1
+%patch15 -p1
+%patch16 -p1
%if 0%{?rhel} == 6
sed -i '/ su /d' vdsm/vdsm-logrotate.conf.in
@@ -596,6 +611,11 @@ sed -i -e 's/^software_version =.*/software_version = "'"${baseversion}"'"/' \
rm -rf %{buildroot}
make DESTDIR=%{buildroot} install
+# Creating VDSM logs in this session to avoid rpmbuild
+# complain during the build
+install -dDm 0755 %{buildroot}/var/log/vdsm
+touch %{buildroot}/var/log/vdsm/{metadata.log,mom.log,supervdsm.log,vdsm.log}
+
# Install the respawn utility
install -Dm 0755 init/sysvinit/respawn \
%{buildroot}%{_datadir}/%{vdsm_name}/respawn
@@ -677,6 +697,14 @@ export LC_ALL=C
# set the vdsm "secret" password for libvirt
%{_bindir}/vdsm-tool set-saslpasswd
+# After vdsm install we should create the logs files.
+# In the install session we create it but since we use
+# the ghost macro (in files session) the files are not included
+touch /var/log/vdsm/{metadata.log,mom.log,supervdsm.log,vdsm.log}
+chmod 0644 /var/log/vdsm/{metadata.log,mom.log,supervdsm.log,vdsm.log}
+chown vdsm:kvm /var/log/vdsm/{metadata.log,mom.log,vdsm.log}
+chown root:root /var/log/vdsm/supervdsm.log
+
# Have moved vdsm section in /etc/sysctl.conf to /etc/sysctl.d/vdsm.conf.
# So Remove them if it is played with /etc/sysctl.conf.
if grep -q "# VDSM section begin" /etc/sysctl.conf; then
@@ -857,6 +885,10 @@ exit 0
%endif
%dir %attr(-, %{vdsm_user}, %{vdsm_group}) /rhev/data-center
+%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) /var/log/vdsm/metadata.log
+%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) /var/log/vdsm/mom.log
+%ghost %config %attr(0644, root, root) /var/log/vdsm/supervdsm.log
+%ghost %config %attr(0644, %{vdsm_user}, %{vdsm_group}) /var/log/vdsm/vdsm.log
%ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) /rhev/data-center/hsm-tasks
%ghost %dir %attr(-, %{vdsm_user}, %{vdsm_group}) /rhev/data-center/mnt
%dir %{_libexecdir}/%{vdsm_name}
@@ -1333,11 +1365,20 @@ exit 0
%{_datadir}/%{vdsm_name}/gluster/services.py*
%endif
-%files python-cpopen
-%{python_sitearch}/cpopen/__init__.py*
-%attr(755, root, root) %{python_sitearch}/cpopen/cpopen.so*
-
%changelog
+* Tue Feb 18 2014 Douglas Schilling Landgraf <dougsland at redhat.com> - 4.14.3-4
+- sos plugin should ignore var run vdsm storage
+- vdsm fix RTC offset
+- vdsm pre defined range for spice vnc ports
+- netinfo.speed avoid log spam
+- Avoid-going-into-Paused-status-during-long-lasting-m
+- vm discover volume path from xml definition
+- vdsm.spec vdsm should own vdsm.log
+- Removing vdsm python cpopen rpm creation from vdsm
+- vdsm.spec own metadata supervdsm mom logs
+- vm iface statistics never report negative rates
+- spec do not remove vdsm logs when pkg removed
+
* Mon Feb 03 2014 Douglas Schilling Landgraf <dougsland at redhat.com> - 4.13.3-3
- spec: replace requires vdsm-python-cpopen
More information about the scm-commits
mailing list