[Kimchi-devel] [PATCH] [Kimchi] USB xhci hotplug: Check controller, define in template, add test in Power
Aline Manera
alinefm at linux.vnet.ibm.com
Mon Oct 17 11:55:10 UTC 2016
On 10/14/2016 05:55 PM, Lucio Correia wrote:
> - Today it is not possible to hotplug a PCI in Power Systems without an
> USB xhci controller existing in the VM. This commit checks if there
> is such controller in the VM, displaying an error message if not.
> - When creating VMs using Kimchi in a Power System, the USB xhci
> controller is defined by default to have PCI hotplug support.
> - From now on all templates are created with xhci usb controller, so a
> hotplug must be performed flawlessly. If anything wrong the test case
> will fail.
>
> Signed-off-by: Jose Ricardo Ziviani <joserz at linux.vnet.ibm.com>
> Signed-off-by: Lucio Correia <luciojhc at linux.vnet.ibm.com>
> ---
> i18n.py | 1 +
> model/vmhostdevs.py | 34 ++++++++++++++++++++++++++++++++++
> tests/test_model.py | 25 +++++++++++++++++++++++++
> vmtemplate.py | 17 +++++++++++++++++
> 4 files changed, 77 insertions(+)
>
> diff --git a/i18n.py b/i18n.py
> index 82c679b..159021d 100644
> --- a/i18n.py
> +++ b/i18n.py
> @@ -150,6 +150,7 @@ messages = {
> "KCHVMHDEV0005E": _('The device %(name)s is probably in use by the host. Unable to attach it to the guest.'),
> "KCHVMHDEV0006E": _('Hot-(un)plug of device %(name)s is not supported.'),
> "KCHVMHDEV0007E": _('Failed to attach %(device)s to %(vm)s'),
> + "KCHVMHDEV0008E": _('VM %(vmid)s does not have an USB XHCI controller to accept PCI hotplug.'),
>
> "KCHVMIF0001E": _("Interface %(iface)s does not exist in virtual machine %(name)s"),
> "KCHVMIF0002E": _("Network %(network)s specified for virtual machine %(name)s does not exist"),
> diff --git a/model/vmhostdevs.py b/model/vmhostdevs.py
> index e289f03..edb6e36 100644
> --- a/model/vmhostdevs.py
> +++ b/model/vmhostdevs.py
> @@ -43,6 +43,9 @@ from wok.plugins.kimchi.xmlutils.qemucmdline import QEMU_NAMESPACE
>
>
> CMDLINE_FIELD_NAME = 'spapr-pci-host-bridge.mem_win_size'
> +USB_MODELS_PCI_HOTPLUG = ["piix3-uhci", "piix4-uhci", "ehci", "ich9-ehci1",
> + "ich9-uhci1", "ich9-uhci2", "ich9-uhci3",
> + "vt82c686b-uhci", "pci-ohci", "nec-xhci"]
> WINDOW_SIZE_BAR = 0x800000000
>
>
> @@ -135,6 +138,28 @@ class VMHostDevsModel(object):
>
> return '<devices>%s</devices>' % hostdevs
>
> + def have_xhci_usb_controller(self, vmid):
> + dom = VMModel.get_vm(vmid, self.conn)
> +
> + root = objectify.fromstring(dom.XMLDesc(0))
> +
> + try:
> + controllers = root.devices.controller
> +
> + except AttributeError:
> + return False
> +
> + for controller in controllers:
> +
> + if 'model' not in controller.attrib:
> + continue
> +
> + if controller.attrib['type'] == 'usb' and \
> + controller.attrib['model'] in USB_MODELS_PCI_HOTPLUG:
> + return True
> +
> + return False
> +
> def _get_pci_device_xml(self, dev_info, slot, is_multifunction):
> if 'detach_driver' not in dev_info:
> dev_info['detach_driver'] = 'kvm'
> @@ -234,6 +259,15 @@ class VMHostDevsModel(object):
> dom = VMModel.get_vm(vmid, self.conn)
> driver = 'vfio' if self.caps.kernel_vfio else 'kvm'
>
> + # 'vfio' systems requires a xhci usb controller in order to support
> + # pci hotplug on Power.
> + if driver == 'vfio' and platform.machine().startswith('ppc') and \
> + DOM_STATE_MAP[dom.info()[0]] != "shutoff" and \
> + not self.have_xhci_usb_controller(vmid):
> + msg = WokMessage('KCHVMHDEV0008E', {'vmid': vmid})
> + cb(msg.get_text(), False)
> + raise InvalidOperation("KCHVMHDEV0008E", {'vmid': vmid})
> +
> # Attach all PCI devices in the same IOMMU group
> affected_names = self.devs_model.get_list(
> _passthrough_affected_by=dev_info['name'])
> diff --git a/tests/test_model.py b/tests/test_model.py
> index 082cb9d..4ddd0d2 100644
> --- a/tests/test_model.py
> +++ b/tests/test_model.py
> @@ -1626,6 +1626,31 @@ class ModelTests(unittest.TestCase):
> volumes = inst.storagevolumes_get_list(args['name'])
> self.assertEquals(len(volumes), 2)
>
> + def _host_is_power():
> + import platform
Move the import to the import block at the top of file.
> + return platform.machine().startswith('ppc')
> +
> + @unittest.skipUnless(_host_is_power(), 'Only required for Power hosts')
> + def test_pci_hotplug_requires_xhci_usb_controller(self):
> + config.set("authentication", "method", "pam")
> + inst = model.Model(None, objstore_loc=self.tmp_store)
> + tpl_params = {'name': 'test', 'memory': 1024, 'cdrom': UBUNTU_ISO}
> + inst.templates_create(tpl_params)
> +
> + with RollbackContext() as rollback:
> + vm_params = {'name': 'kimchi-vm1', 'template': '/templates/test'}
> + task1 = inst.vms_create(vm_params)
> + inst.task_wait(task1['id'])
> + rollback.prependDefer(utils.rollback_wrapper, inst.vm_delete,
> + 'kimchi-vm1')
> + # Start vm
> + inst.vm_start('kimchi-vm1')
> + rollback.prependDefer(utils.rollback_wrapper, inst.vm_poweroff,
> + 'kimchi-vm1')
> + # check if create VM has USB XHCI controller
> + self.assertTrue(
> + inst.vmhostdevs_have_xhci_usb_controller('kimchi-vm1'))
> +
>
> class BaseModelTests(unittest.TestCase):
> class FoosModel(object):
> diff --git a/vmtemplate.py b/vmtemplate.py
> index 0288330..56b339f 100644
> --- a/vmtemplate.py
> +++ b/vmtemplate.py
> @@ -18,6 +18,7 @@
> # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
>
> import os
> +import platform
> import stat
> import time
> import urlparse
> @@ -358,6 +359,18 @@ class VMTemplate(object):
> self.info['os_version'])
> return unicode(interfaces, 'utf-8')
>
> + def _get_usb_controller(self):
> + # powerkvm systems must include xhci controller model
> + if not platform.machine().startswith('ppc'):
> + return ''
> +
> + return """
> + <controller type='usb' index='0' model='nec-xhci'>
> + <address type='pci' domain='0x0000'
> + bus='0x00' slot='0x0f' function='0x0'/>
> + </controller>
If it is not exist, please, add a new module to /xmlutils to generated
the above XML by using lxml module instead of using plan text.
> + """
> +
> def _get_input_output_xml(self):
> sound = """
> <sound model='%(sound_model)s' />
> @@ -469,6 +482,9 @@ class VMTemplate(object):
> # cpu_info element
> params['cpu_info_xml'] = self._get_cpu_xml()
>
> + # usb controller xhci
> + params['usb_controller'] = self._get_usb_controller()
> +
> xml = """
> <domain type='%(domain)s'>
> %(qemu-stream-cmdline)s
> @@ -503,6 +519,7 @@ class VMTemplate(object):
> %(interfaces)s
> %(graphics)s
> %(input_output)s
> + %(usb_controller)s
> %(serial)s
> <memballoon model='virtio' />
> </devices>
More information about the Kimchi-devel
mailing list