Dan Kenigsberg has uploaded a new change for review.
Change subject: xen: hook: let oVirt run VMs on Xen hosts
......................................................................
xen: hook: let oVirt run VMs on Xen hosts
With this hook installed (and previous hacks applied) it is possible to
start oVirt VMs as Xen domU HVM guests.
Note that this hook has undergone very limited testing: migration was
not attempted, as well as no shared storage.
The hook is known to be limited, as it does not support qcow images, or
spice; no emulated devices, no hotplugging nor virtio. It is expected to
serve as a proof of concept and as a basis to further experimentation by
other parties.
Change-Id: Iaabda72bebde98d2884fe9fcfe87d266e2dcdde0
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M configure.ac
M debian/Makefile.am
A debian/vdsm-hook-xen.docs
A debian/vdsm-hook-xen.install
M vdsm.spec.in
M vdsm_hooks/Makefile.am
A vdsm_hooks/xen/Makefile.am
A vdsm_hooks/xen/after_get_caps.py
A vdsm_hooks/xen/before_vm_start.py
A vdsm_hooks/xen/empty.test.xml
10 files changed, 343 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/53/28353/1
diff --git a/configure.ac b/configure.ac
index 5e7f333..0d5bcaf 100644
--- a/configure.ac
+++ b/configure.ac
@@ -310,6 +310,7 @@
vdsm_hooks/vmdisk/Makefile
vdsm_hooks/vmfex/Makefile
vdsm_hooks/vmfex_dev/Makefile
+ vdsm_hooks/xen/Makefile
vdsm_reg/Makefile
])
diff --git a/debian/Makefile.am b/debian/Makefile.am
index 00b0d33..b65dd70 100644
--- a/debian/Makefile.am
+++ b/debian/Makefile.am
@@ -87,6 +87,8 @@
vdsm-hook-vmfex.install \
vdsm-hook-vmfex-dev.docs \
vdsm-hook-vmfex-dev.install \
+ vdsm-hook-xen.docs \
+ vdsm-hook-xen.install \
vdsm.install \
vdsm.postinst \
vdsm.postrm \
diff --git a/debian/vdsm-hook-xen.docs b/debian/vdsm-hook-xen.docs
new file mode 100644
index 0000000..5ecd9c6
--- /dev/null
+++ b/debian/vdsm-hook-xen.docs
@@ -0,0 +1 @@
+COPYING
diff --git a/debian/vdsm-hook-xen.install b/debian/vdsm-hook-xen.install
new file mode 100644
index 0000000..917f772
--- /dev/null
+++ b/debian/vdsm-hook-xen.install
@@ -0,0 +1,2 @@
+usr/libexec/vdsm/hooks/before_device_create/70_xen
+usr/libexec/vdsm/hooks/after_get_caps/70_xen
diff --git a/vdsm.spec.in b/vdsm.spec.in
index 35617ab..46d3d71 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -600,6 +600,16 @@
%description hook-vmdisk
Hook adds additional disk image for a VM (raw or qcow2)
+%package hook-xen
+Summary: Rum an oVirt VM as a Xen domU
+BuildArch: noarch
+Requires: %{name}
+
+%description hook-xen
+VDSM hook that allow oVirt to run its VMs as Xen domU.
+Install this hook on a Xen dom0 with HVM support, and add the host to Engine.
+
+
%if 0%{?with_gluster}
%package gluster
Summary: Gluster Plugin for VDSM
@@ -1385,7 +1395,13 @@
%{_libexecdir}/%{vdsm_name}/hooks/before_device_create/50_vmfex
%{_libexecdir}/%{vdsm_name}/hooks/before_device_migrate_destination/50_vmfex
%{_libexecdir}/%{vdsm_name}/hooks/before_nic_hotplug/50_vmfex
-%endif
+
+%files hook-xen
+%defattr(-, root, root, -)
+%{_libexecdir}/%{vdsm_name}/hooks/before_vm_start/70_xen
+%{_libexecdir}/%{vdsm_name}/hooks/after_get_caps/70_xen
+
+%endif # with_hooks
%files debug-plugin
%defattr(-, root, root, -)
diff --git a/vdsm_hooks/Makefile.am b/vdsm_hooks/Makefile.am
index 5e4d731..ef5a22a 100644
--- a/vdsm_hooks/Makefile.am
+++ b/vdsm_hooks/Makefile.am
@@ -48,6 +48,7 @@
vmdisk \
vmfex \
vmfex_dev \
+ xen \
$(NULL)
endif
diff --git a/vdsm_hooks/xen/Makefile.am b/vdsm_hooks/xen/Makefile.am
new file mode 100644
index 0000000..c6c76ca
--- /dev/null
+++ b/vdsm_hooks/xen/Makefile.am
@@ -0,0 +1,42 @@
+#
+# Copyright 2014 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 $(top_srcdir)/build-aux/Makefile.subs
+
+CLEANFILES = \
+ config.log
+
+EXTRA_DIST = \
+ after_get_caps.py \
+ before_vm_start.py \
+ empty.test.xml \
+ $(NULL)
+
+install-data-local:
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/after_get_caps
+ $(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
+ $(DESTDIR)$(vdsmhooksdir)/before_vm_start/70_xen
+ $(INSTALL_SCRIPT) $(srcdir)/after_get_caps.py \
+ $(DESTDIR)$(vdsmhooksdir)/after_get_caps/70_xen
+
+uninstall-local:
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/70_xen
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/after_get_caps/70_xen
diff --git a/vdsm_hooks/xen/after_get_caps.py b/vdsm_hooks/xen/after_get_caps.py
new file mode 100755
index 0000000..82f6ccb
--- /dev/null
+++ b/vdsm_hooks/xen/after_get_caps.py
@@ -0,0 +1,59 @@
+#!/usr/bin/python
+#
+# Copyright 2014 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 sys
+import traceback
+
+import hooking
+
+
+def fake_caps(capsdict):
+ """Report kvmEnable, even though it is not, so the Engine knows that
+ virualization is available on this host"""
+ capsdict['kvmEnabled'] = 'True'
+ flags = set(capsdict['cpuFlags'].split(','))
+
+ # vmx is not exposed to dom0, yet Engine expects to see it
+ flags.add('vmx')
+
+ capsdict['cpuFlags'] += ','.join(flags)
+
+ return capsdict
+
+
+def test():
+ from pprint import pprint
+ pprint(fake_caps({}))
+
+
+def main():
+ hooking.write_json(fake_caps(hooking.read_json()))
+
+
+if __name__ == '__main__':
+ if '--test' in sys.argv:
+ test()
+ else:
+ try:
+ main()
+ except:
+ hooking.exit_hook('[unexpected error]: %s\n'
+ % traceback.format_exc())
diff --git a/vdsm_hooks/xen/before_vm_start.py b/vdsm_hooks/xen/before_vm_start.py
new file mode 100755
index 0000000..17bea92
--- /dev/null
+++ b/vdsm_hooks/xen/before_vm_start.py
@@ -0,0 +1,135 @@
+#!/usr/bin/python
+#
+# Copyright 2014 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
+#
+
+from xml.dom import minidom
+import sys
+import traceback
+
+
+def drop_address(d):
+ addresses = d.getElementsByTagName('address')
+ if addresses:
+ d.removeChild(addresses[0])
+
+
+def drop_driver(d):
+ drivers = d.getElementsByTagName('driver')
+ if drivers:
+ d.removeChild(drivers[0])
+
+
+def xenify(domxml):
+ """Make a Vdsm-generate domxml runnable on a Xen host"""
+
+ # it's not kvm
+ domxml.getElementsByTagName('domain')[0].attributes['type'].value = 'xen'
+
+ # no vCPU hotplugging
+ vcpu = domxml.getElementsByTagName("vcpu")[0]
+ while vcpu.firstChild:
+ vcpu.removeChild(vcpu.firstChild)
+ vcpu.appendChild(domxml.createTextNode('1'))
+
+ devices = domxml.getElementsByTagName("devices")[0]
+ d = devices.firstChild
+ while d:
+ n = d.nextSibling
+ if d.nodeType == d.TEXT_NODE:
+ pass # skip whitespace
+
+ elif d.tagName == 'channel':
+ # no support for virtio channels.
+ devices.removeChild(d)
+
+ elif d.tagName == 'graphics' and d.attributes['type'].value == 'spice':
+ raise Exception('spice not supported, try vnc')
+
+ elif d.tagName == 'memballoon':
+ # no virtio balloon
+ devices.removeChild(d)
+
+ elif d.tagName == 'controller':
+ # no controllers
+ devices.removeChild(d)
+
+ elif d.tagName == 'video':
+ # use xen video device
+ drop_address(d)
+ d.getElementsByTagName('model')[0].attributes['type'].value = 'xen'
+
+ elif d.tagName == 'interface':
+ # xen interfaces are not pci devices
+ drop_address(d)
+ d.removeChild(d.getElementsByTagName('model')[0])
+ drop_driver(d)
+
+ elif d.tagName == 'disk' and d.attributes['device'].value == 'cdrom':
+ # bug: cdrom existence makes disk non-bootable
+ # bug: empty cdrom path is handled badly by libvirt
+ devices.removeChild(d)
+
+ elif d.tagName == 'disk':
+ # xen disks are not pci devices
+ drop_address(d)
+
+ target = d.getElementsByTagName('target')[0]
+ target.attributes['bus'].value = 'xen'
+ target.attributes['dev'].value = (
+ 'xvd' + target.attributes['dev'].value[2:])
+
+ driver = d.getElementsByTagName('driver')[0]
+ # most probably, enospace and co are missing, too.
+ if driver.attributes['type'].value != 'raw':
+ raise Exception(
+ 'I have no idea how to specify qcow to xen, '
+ 'please use raw')
+ d.removeChild(driver)
+
+ else:
+ pass
+ d = n
+
+ domxml.getElementsByTagName("features")[0].appendChild(
+ domxml.createElement('pae'))
+
+ return domxml
+
+
+def test():
+ domxml = minidom.parseString(sys.stdin.read())
+ print xenify(domxml).toxml(encoding='UTF-8')
+
+
+def main():
+ domxml = hooking.read_domxml()
+ hooking.write_domxml(xenify(domxml))
+
+
+if __name__ == '__main__':
+ if '--test' in sys.argv:
+ test()
+ else:
+ import hooking
+ try:
+ main()
+ except:
+ hooking.exit_hook('[unexpected error]: %s\n'
+ % traceback.format_exc())
diff --git a/vdsm_hooks/xen/empty.test.xml b/vdsm_hooks/xen/empty.test.xml
new file mode 100644
index 0000000..710e5b9
--- /dev/null
+++ b/vdsm_hooks/xen/empty.test.xml
@@ -0,0 +1,83 @@
+<?xml version="1.0" encoding="utf-8"?><domain type="kvm">
+
+ <!-- This is a domxml of a typical, yet extremely simple, oVirt VM.
+ It is supplied here to ease tests of the xenify script. -->
+
+ <name>empty</name>
+ <uuid>a6b0e0af-7f6d-4a18-95d6-f34477be340d</uuid>
+ <memory>20480</memory>
+ <currentMemory>20480</currentMemory>
+ <vcpu current="1">160</vcpu>
+ <memtune>
+ <min_guarantee>102400</min_guarantee>
+ </memtune>
+ <devices>
+ <channel type="unix">
+ <target name="com.redhat.rhevm.vdsm" type="virtio"/>
+ <source mode="bind" path="/var/lib/libvirt/qemu/channels/a6b0e0af-7f6d-4a18-95d6-f34477be340d.com.redhat.rhevm.vdsm"/>
+ </channel>
+ <channel type="unix">
+ <target name="org.qemu.guest_agent.0" type="virtio"/>
+ <source mode="bind" path="/var/lib/libvirt/qemu/channels/a6b0e0af-7f6d-4a18-95d6-f34477be340d.org.qemu.guest_agent.0"/>
+ </channel>
+ <input bus="ps2" type="mouse"/>
+ <channel type="spicevmc">
+ <target name="com.redhat.spice.0" type="virtio"/>
+ </channel>
+ <graphics autoport="yes" keymap="en-us" listen="0" type="vnc">
+ </graphics>
+ <memballoon model="virtio"/>
+ <controller index="0" model="virtio-scsi" type="scsi">
+ <address bus="0x00" domain="0x0000" function="0x0" slot="0x04" type="pci"/>
+ </controller>
+ <video>
+ <address bus="0x00" domain="0x0000" function="0x0" slot="0x02" type="pci"/>
+ <model type="vga"/>
+ </video>
+ <interface type="bridge">
+ <address bus="0x00" domain="0x0000" function="0x0" slot="0x03" type="pci"/>
+ <mac address="00:1a:4a:bd:c4:10"/>
+ <model type="virtio"/>
+ <source bridge="ovirtmgmt"/>
+ <filterref filter="vdsm-no-mac-spoofing"/>
+ <link state="up"/>
+ <driver queues="3"/>
+ </interface>
+ <disk device="cdrom" snapshot="no" type="file">
+ <address bus="1" controller="0" target="0" type="drive" unit="0"/>
+ <source file="" startupPolicy="optional"/>
+ <target bus="ide" dev="hdc"/>
+ <readonly/>
+ <serial/>
+ </disk>
+ <disk device="disk" snapshot="no" type="file">
+ <address bus="0x00" domain="0x0000" function="0x0" slot="0x06" type="pci"/>
+ <source file="/rhev/data-center/mnt/_var_lib_images/51dcf56a-371b-43f6-824e-1f2364d17a19/images/1ebbf8d0-853c-4c56-ad80-213afddbede1/79e8fb9c-39e8-48e6-b111-06d186e910d3"/>
+ <target bus="virtio" dev="vda"/>
+ <serial>1ebbf8d0-853c-4c56-ad80-213afddbede1</serial>
+ <driver cache="none" error_policy="stop" io="threads" name="qemu" type="raw"/>
+ </disk>
+ </devices>
+ <os>
+ <type arch="x86_64" machine="rhel6.5.0">hvm</type>
+ <smbios mode="sysinfo"/>
+ </os>
+ <sysinfo type="smbios">
+ <system>
+ <entry name="manufacturer">oVirt</entry>
+ <entry name="product">oVirt Node</entry>
+ <entry name="version">6-5.el6.centos.11.2</entry>
+ <entry name="serial">AEF32683-69FA-4EFB-AE8F-3555B2C1F6E5</entry>
+ <entry name="uuid">a6b0e0af-7f6d-4a18-95d6-f34477be340d</entry>
+ </system>
+ </sysinfo>
+ <clock adjustment="0" offset="variable">
+ <timer name="rtc" tickpolicy="catchup"/>
+ <timer name="pit" tickpolicy="delay"/>
+ <timer name="hpet" present="no"/>
+ </clock>
+ <features>
+ <acpi/>
+ </features>
+
+</domain>
--
To view, visit http://gerrit.ovirt.org/28353
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: Iaabda72bebde98d2884fe9fcfe87d266e2dcdde0
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
Dan Kenigsberg has uploaded a new change for review.
Change subject: faqemu: move hook logic out of vdsm
......................................................................
faqemu: move hook logic out of vdsm
Vdsm-proper has been aware of the faqemu hook. Now that we have an
after_get_caps hook point, this is no longer necessary. This patch move
the faking logic, so that it does not need to be shipped on production
systems and clutter the code.
Change-Id: I46d0079491f707b0abd3fbbe2d47f63697dac9c5
Signed-off-by: Dan Kenigsberg <danken(a)redhat.com>
---
M vdsm.spec.in
M vdsm/caps.py
M vdsm_hooks/faqemu/Makefile.am
A vdsm_hooks/faqemu/after_get_caps.py
4 files changed, 110 insertions(+), 42 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/05/27705/1
diff --git a/vdsm.spec.in b/vdsm.spec.in
index c620174..e6db372 100644
--- a/vdsm.spec.in
+++ b/vdsm.spec.in
@@ -1464,6 +1464,7 @@
%defattr(-, root, root, -)
%doc COPYING
%{_libexecdir}/%{vdsm_name}/hooks/before_vm_start/10_faqemu
+%{_libexecdir}/%{vdsm_name}/hooks/after_get_caps/10_faqemu
%if 0%{?with_gluster}
%files gluster
diff --git a/vdsm/caps.py b/vdsm/caps.py
index 46094f3..7c1e520 100644
--- a/vdsm/caps.py
+++ b/vdsm/caps.py
@@ -1,5 +1,5 @@
#
-# Copyright 2011 Red Hat, Inc.
+# Copyright 2011-2014 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
@@ -197,7 +197,7 @@
@utils.memoized
-def _getLiveSnapshotSupport(arch, capabilities=None):
+def getLiveSnapshotSupport(arch, capabilities=None):
if capabilities is None:
capabilities = _getCapsXMLStr()
caps = minidom.parseString(capabilities)
@@ -295,7 +295,7 @@
@utils.memoized
-def _getEmulatedMachines(arch, capabilities=None):
+def getEmulatedMachines(arch, capabilities=None):
if capabilities is None:
capabilities = _getCapsXMLStr()
caps = minidom.parseString(capabilities)
@@ -444,13 +444,6 @@
return dict(release=release, version=version, name=osname)
-def getTargetArch():
- if config.getboolean('vars', 'fake_kvm_support'):
- return config.get('vars', 'fake_kvm_architecture')
- else:
- return platform.machine()
-
-
def _getSELinuxEnforceMode():
"""
Returns the SELinux mode as reported by kernel.
@@ -480,13 +473,11 @@
def get():
- targetArch = getTargetArch()
+ targetArch = platform.machine()
caps = {}
- caps['kvmEnabled'] = \
- str(config.getboolean('vars', 'fake_kvm_support') or
- os.path.exists('/dev/kvm')).lower()
+ caps['kvmEnabled'] = str(os.path.exists('/dev/kvm')).lower()
cpuInfo = CpuInfo()
cpuTopology = CpuTopology()
@@ -498,30 +489,9 @@
caps['cpuThreads'] = str(cpuTopology.threads())
caps['cpuSockets'] = str(cpuTopology.sockets())
caps['cpuSpeed'] = cpuInfo.mhz()
- if config.getboolean('vars', 'fake_kvm_support'):
- if targetArch == Architecture.X86_64:
- caps['cpuModel'] = 'Intel(Fake) CPU'
-
- flagList = ['vmx', 'sse2', 'nx']
-
- if targetArch == platform.machine():
- flagList += cpuInfo.flags()
-
- flags = set(flagList)
-
- caps['cpuFlags'] = ','.join(flags) + ',model_486,model_pentium,' \
- 'model_pentium2,model_pentium3,model_pentiumpro,' \
- 'model_qemu32,model_coreduo,model_core2duo,model_n270,' \
- 'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1'
- elif targetArch == Architecture.PPC64:
- caps['cpuModel'] = 'POWER 7 (fake)'
- caps['cpuFlags'] = 'powernv,model_POWER7_v2.3'
- else:
- raise RuntimeError('Unsupported architecture: %s' % targetArch)
- else:
- caps['cpuModel'] = cpuInfo.model()
- caps['cpuFlags'] = ','.join(cpuInfo.flags() +
- _getCompatibleCpuModels())
+ caps['cpuModel'] = cpuInfo.model()
+ caps['cpuFlags'] = ','.join(cpuInfo.flags() +
+ _getCompatibleCpuModels())
caps.update(_getVersionInfo())
caps.update(netinfo.get())
@@ -534,7 +504,7 @@
caps['operatingSystem'] = osversion()
caps['uuid'] = utils.getHostUUID()
caps['packages2'] = _getKeyPackages()
- caps['emulatedMachines'] = _getEmulatedMachines(targetArch)
+ caps['emulatedMachines'] = getEmulatedMachines(targetArch)
caps['ISCSIInitiatorName'] = _getIscsiIniName()
caps['HBAInventory'] = storage.hba.HBAInventory()
caps['vmTypes'] = ['kvm']
@@ -550,7 +520,7 @@
caps['selinux'] = _getSELinux()
- liveSnapSupported = _getLiveSnapshotSupport(targetArch)
+ liveSnapSupported = getLiveSnapshotSupport(targetArch)
if liveSnapSupported is not None:
caps['liveSnapshot'] = str(liveSnapSupported).lower()
diff --git a/vdsm_hooks/faqemu/Makefile.am b/vdsm_hooks/faqemu/Makefile.am
index 3e1b0c0..e93c943 100644
--- a/vdsm_hooks/faqemu/Makefile.am
+++ b/vdsm_hooks/faqemu/Makefile.am
@@ -1,5 +1,5 @@
#
-# Copyright 2011-2012 Red Hat, Inc.
+# Copyright 2011-2014 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
@@ -24,12 +24,18 @@
config.log
EXTRA_DIST = \
- before_vm_start.py
+ before_vm_start.py \
+ after_get_caps.py \
+ $(NULL)
install-data-local:
$(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/before_vm_start
+ $(MKDIR_P) $(DESTDIR)$(vdsmhooksdir)/after_get_caps
$(INSTALL_SCRIPT) $(srcdir)/before_vm_start.py \
$(DESTDIR)$(vdsmhooksdir)/before_vm_start/10_faqemu
+ $(INSTALL_SCRIPT) $(srcdir)/after_get_caps.py \
+ $(DESTDIR)$(vdsmhooksdir)/after_get_caps/10_faqemu
uninstall-local:
$(RM) $(DESTDIR)$(vdsmhooksdir)/before_vm_start/10_faqemu
+ $(RM) $(DESTDIR)$(vdsmhooksdir)/after_get_caps/10_faqemu
diff --git a/vdsm_hooks/faqemu/after_get_caps.py b/vdsm_hooks/faqemu/after_get_caps.py
new file mode 100644
index 0000000..a4a008b
--- /dev/null
+++ b/vdsm_hooks/faqemu/after_get_caps.py
@@ -0,0 +1,91 @@
+#!/usr/bin/python
+#
+# Copyright 2014 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 platform
+import sys
+import traceback
+
+# using vdsm internals in a hook is dangerous and frowned upon,
+# as internal APIs may change without notice.
+# However, faqemu is a bit different, as it is not expected to be ever used in
+# production.
+sys.path.append('/usr/share/vdsm')
+import caps
+import hooking
+from vdsm.config import config
+
+
+def fake_caps(c, target_arch):
+ c['kvmEnabled'] = 'True'
+ cpu_info = caps.CpuInfo()
+ if target_arch == caps.Architecture.X86_64:
+ c['cpuModel'] = 'Intel(Fake) CPU'
+
+ flagList = ['vmx', 'sse2', 'nx']
+
+ if target_arch == platform.machine():
+ flagList += cpu_info.flags()
+
+ flags = set(flagList)
+
+ c['cpuFlags'] = ','.join(flags) + ',model_486,model_pentium,' \
+ 'model_pentium2,model_pentium3,model_pentiumpro,' \
+ 'model_qemu32,model_coreduo,model_core2duo,model_n270,' \
+ 'model_Conroe,model_Penryn,model_Nehalem,model_Opteron_G1'
+ elif target_arch == caps.Architecture.PPC64:
+ c['cpuModel'] = 'POWER 7 (fake)'
+ c['cpuFlags'] = 'powernv,model_POWER7_v2.3'
+ else:
+ raise RuntimeError('Unsupported architecture: %s' % target_arch)
+
+ if target_arch != platform.machine():
+ c['emulatedMachines'] = caps.getEmulatedMachines(target_arch)
+
+ liveSnapSupported = caps.getLiveSnapshotSupport(target_arch)
+ if liveSnapSupported is not None:
+ caps['liveSnapshot'] = str(liveSnapSupported).lower()
+
+ return c
+
+
+def main():
+ if config.getboolean('vars', 'fake_kvm_support'):
+ try:
+ c = hooking.read_json()
+ target_arch = config.get('vars', 'fake_kvm_architecture')
+ c = fake_caps(c, target_arch)
+ hooking.write_json(c)
+ except:
+ hooking.exit_hook('faqemu: %s\n'
+ % traceback.format_exc())
+ sys.exit(2)
+
+
+def test():
+ from pprint import pprint
+ pprint(fake_caps({}, 'ppc64'))
+
+
+if __name__ == '__main__':
+ if '--test' in sys.argv:
+ test()
+ else:
+ main()
--
To view, visit http://gerrit.ovirt.org/27705
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I46d0079491f707b0abd3fbbe2d47f63697dac9c5
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Dan Kenigsberg <danken(a)redhat.com>
Adam Litke has uploaded a new change for review.
Change subject: HACK: Use a monitor command to get watermarks
......................................................................
HACK: Use a monitor command to get watermarks
Change-Id: I6b3e408fda22ac4a4cb11f58d399b9d69906d72e
Signed-off-by: Adam Litke <alitke(a)redhat.com>
---
M vdsm/virt/vm.py
1 file changed, 27 insertions(+), 2 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/20/28620/1
diff --git a/vdsm/virt/vm.py b/vdsm/virt/vm.py
index 708872a..5c192f0 100644
--- a/vdsm/virt/vm.py
+++ b/vdsm/virt/vm.py
@@ -2293,8 +2293,33 @@
self.conf['timeOffset'] = newTimeOffset
def _getMergeWriteWatermarks(self):
- # TODO: Adopt the future libvirt API
- return {}
+ ret = {}
+ cmd = {'execute': 'query-blockstats'}
+ resp = self._internalQMPMonitorCommand(cmd)
+ for device in resp['return']:
+ name = device['device']
+ if not name.startswith('drive-'):
+ continue
+ alias = name[6:]
+ try:
+ drive = self._lookupDeviceByAlias(DISK_DEVICES, alias)
+ job = self.getBlockJob(drive)
+ except LookupError:
+ continue
+
+ volChain = job['chain']
+ stats = []
+ vol = device
+ while vol:
+ stats.insert(0, vol['parent']['stats']['wr_highest_offset'])
+ vol = vol.get('backing')
+ if len(volChain) != len(stats):
+ self.log.debug("The number of wr_highest_offset stats does "
+ "not match the number of volumes. Skipping.")
+ continue
+ for vol, stat in zip(volChain, stats):
+ ret[vol] = stat
+ return ret
def _getLiveMergeExtendCandidates(self):
ret = {}
--
To view, visit http://gerrit.ovirt.org/28620
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I6b3e408fda22ac4a4cb11f58d399b9d69906d72e
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Adam Litke <alitke(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: spbackends: do not set spmRole on forceFreeSpm
......................................................................
spbackends: do not set spmRole on forceFreeSpm
Setting the spmRole to SPM_FREE on forceFreeSpm is harmful. In fact the
release of the spm role (SPM_ACQUIRED) should go through the stopSpm
procedure where the master filesystem is unmounted, etc.
Change-Id: I2bd9a0d9749e49a97a31c535c92dd242eb8f74ec
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/spbackends.py
1 file changed, 0 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/18/27318/1
diff --git a/vdsm/storage/spbackends.py b/vdsm/storage/spbackends.py
index 86714a3..dddb749 100644
--- a/vdsm/storage/spbackends.py
+++ b/vdsm/storage/spbackends.py
@@ -327,7 +327,6 @@
# DO NOT USE, STUPID, HERE ONLY FOR BC
# TODO: SCSI Fence the 'lastOwner'
self.setSpmStatus(LVER_INVALID, SPM_ID_FREE, __securityOverride=True)
- self.pool.spmRole = SPM_FREE
@classmethod
def _getPoolMD(cls, domain):
--
To view, visit http://gerrit.ovirt.org/27318
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I2bd9a0d9749e49a97a31c535c92dd242eb8f74ec
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: [wip] sdcache: avoid extra refresh due samplingmethod
......................................................................
[wip] sdcache: avoid extra refresh due samplingmethod
In order to avoid an extra iscsi rescan (symptomatic of samplingmethod)
an additional lock has been introduced to queue the requests when the
storage is flagged as stale.
Bug-Url: https://bugzilla.redhat.com/show_bug.cgi?id=870768
Change-Id: If178a8eaeb94f1dfe9e0957036dde88f6a22829c
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/sdc.py
1 file changed, 25 insertions(+), 26 deletions(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/74/9274/1
diff --git a/vdsm/storage/sdc.py b/vdsm/storage/sdc.py
index f2f4534..978e3fa 100644
--- a/vdsm/storage/sdc.py
+++ b/vdsm/storage/sdc.py
@@ -62,32 +62,27 @@
STORAGE_UPDATED = 0
STORAGE_STALE = 1
- STORAGE_REFRESHING = 2
def __init__(self, storage_repo):
- self._syncroot = threading.Condition()
+ self._syncDomain = threading.Condition()
+ self._syncRefresh = threading.Lock()
self.__domainCache = {}
self.__inProgress = set()
self.__staleStatus = self.STORAGE_STALE
self.storage_repo = storage_repo
def invalidateStorage(self):
- with self._syncroot:
- self.__staleStatus = self.STORAGE_STALE
+ self.log.debug("The storages have been invalidated")
+ self.__staleStatus = self.STORAGE_STALE
@misc.samplingmethod
def refreshStorage(self):
- self.__staleStatus = self.STORAGE_REFRESHING
-
+ # We need to set the __staleStatus value at the beginning because we
+ # want to keep track of the future invalidateStorage calls that might
+ # arrive during the rescan procedure.
+ self.__staleStatus = self.STORAGE_UPDATED
multipath.rescan()
lvm.invalidateCache()
-
- # If a new invalidateStorage request came in after the refresh
- # started then we cannot flag the storages as updated (force a
- # new rescan later).
- with self._syncroot:
- if self.__staleStatus == self.STORAGE_REFRESHING:
- self.__staleStatus = self.STORAGE_UPDATED
def produce(self, sdUUID):
domain = DomainProxy(self, sdUUID)
@@ -98,7 +93,7 @@
return domain
def _realProduce(self, sdUUID):
- with self._syncroot:
+ with self._syncDomain:
while True:
domain = self.__domainCache.get(sdUUID)
@@ -109,25 +104,29 @@
self.__inProgress.add(sdUUID)
break
- self._syncroot.wait()
+ self._syncDomain.wait()
try:
- # If multiple calls reach this point and the storage is not
- # updated the refreshStorage() sampling method is called
- # serializing (and eventually grouping) the requests.
- if self.__staleStatus != self.STORAGE_UPDATED:
- self.refreshStorage()
+ # Here we cannot take full advantage of the refreshStorage
+ # samplingmethod since we might be scheduling an unneeded
+ # extra rescan. We need an additional lock (_syncRefresh)
+ # to make sure that __staleStatus is taken in account
+ # (without affecting all the other external refreshStorage
+ # calls as it would be if we move this check there).
+ with self._syncRefresh:
+ if self.__staleStatus != self.STORAGE_UPDATED:
+ self.refreshStorage()
domain = self._findDomain(sdUUID)
- with self._syncroot:
+ with self._syncDomain:
self.__domainCache[sdUUID] = domain
return domain
finally:
- with self._syncroot:
+ with self._syncDomain:
self.__inProgress.remove(sdUUID)
- self._syncroot.notifyAll()
+ self._syncDomain.notifyAll()
def _findDomain(self, sdUUID):
import blockSD
@@ -162,16 +161,16 @@
return uuids
def refresh(self):
- with self._syncroot:
+ with self._syncDomain:
lvm.invalidateCache()
self.__domainCache.clear()
def manuallyAddDomain(self, domain):
- with self._syncroot:
+ with self._syncDomain:
self.__domainCache[domain.sdUUID] = domain
def manuallyRemoveDomain(self, sdUUID):
- with self._syncroot:
+ with self._syncDomain:
try:
del self.__domainCache[sdUUID]
except KeyError:
--
To view, visit http://gerrit.ovirt.org/9274
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: If178a8eaeb94f1dfe9e0957036dde88f6a22829c
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>
Federico Simoncelli has uploaded a new change for review.
Change subject: sp: prevent master demotion on activation
......................................................................
sp: prevent master demotion on activation
Change-Id: I47a0c3ea16bcdefa99899e04c453eaf995344dfb
Signed-off-by: Federico Simoncelli <fsimonce(a)redhat.com>
---
M vdsm/storage/sp.py
1 file changed, 9 insertions(+), 1 deletion(-)
git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/32/28332/1
diff --git a/vdsm/storage/sp.py b/vdsm/storage/sp.py
index 3f983b6..3762c10 100644
--- a/vdsm/storage/sp.py
+++ b/vdsm/storage/sp.py
@@ -1041,7 +1041,15 @@
# Domain conversion requires the links to be present
self._refreshDomainLinks(dom)
- self._backend.setDomainRegularRole(dom)
+
+ # This should never happen because we're not deactivating the
+ # current master in deactivateStorageDomain if a new master is
+ # not provided. It is also impossible to connect to a pool
+ # where the master domain is not active. Anyway to be on the
+ # safe side we must prevent the current master domain from
+ # being demoted to regular.
+ if sdUUID != self.masterDomain.sdUUID:
+ self._backend.setDomainRegularRole(dom)
if dom.getDomainClass() == sd.DATA_DOMAIN:
self._convertDomain(dom)
--
To view, visit http://gerrit.ovirt.org/28332
To unsubscribe, visit http://gerrit.ovirt.org/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I47a0c3ea16bcdefa99899e04c453eaf995344dfb
Gerrit-PatchSet: 1
Gerrit-Project: vdsm
Gerrit-Branch: master
Gerrit-Owner: Federico Simoncelli <fsimonce(a)redhat.com>