On Thu, Jun 5, 2014 at 11:14 AM, Daniel P. Berrange <berrange(a)redhat.com> wrote:
On Mon, Jun 02, 2014 at 02:44:16PM +0100, George Dunlap wrote:
> == Libvirt's interface ==
>
> I've had a brief look at libvirt's USB interface, and learned a bit
> about libvirt's general approach to things at the Xen Hackathon last
> week. One of the goals of libvirt is to be able to specify the
> virtual hardware in enough detail to keep it from changing when you
> upgrade the hypervisor, so that certain proprietary operating systems
> which are sensitive to this kind of thing continue to work.
>
> Instead of specifying a controller name, you specify a controller
> index (which is different than qemu). But instead of specifying a USB
> version number, you specify a model for the USB controller (which
> happens to be the exact name that qemu uses): "piix3-uhci",
> "piix4-uhci", "ehci", "ich9-ehci1",
"ich9-uhci1", "ich9-uhci2",
> "ich9-uhci3", "vt82c686b-uhci", "pci-ohci" or
"nec-xhci".
>
> When specifying a USB device, libvirt has the concept of an "address"
> where you will plug it into. Here is what the page says about it:
>
> "USB addresses have the following additional attributes: bus (a hex
> value between 0 and 0xfff, inclusive), and port (a dotted notation of
> up to four octets, such as 1.2 or 2.1.3.1)."
>
> It's not exactly clear to me what those numbers mean. But after
> chatting with Daniel Berrange at the Hackathon, it looks like the
> "bus" in the address corresponds to the "index" in the
controller
> specification. It also appears that this "index" is internal to
> libvirt and is not exposed to the guest: so it should in theory be
> possible to have index 0 be a Xen PVUSB controller, 1 be an emulated
> qemu controller, 3 be an emulated PVUSB controller, and so on.
This structure/concept is something that libvirt uses more generally
than just USB. Any kind of device which has further devices attached
as a child is represented as a "controller" in libvirt. eg PCI bus,
PCI bridge, USB controller, USB hub, IDE controller, SCSI controller
etc, etc. Any device then has an <address/> element whose 'type'
attribute specifies what type of controller it connects to, and which
maps to the specific <controller> element via its index number.
The validate attributes for the <address> vary depending on the address
type / controller type.
You are correct that the index is completely internal to libvirt,
not exposed to QEMU or the guest. So in USB case the 'bus' attribute
on <address type='usb'/> maps to the <controller> index for the USB
controller.
WRT to choosing the type of controller, libvirt always aims to use
the name of a real hardware model if there is one, since this is
something that can be standardized across hypervisors if they're
emulating the same underlying hardware. The specific model name
we pick is first-come-first-served. So if choose 'piix3-uhci'
based on QEMU name and later we add VMWare support and it has
called it 'piix3-usb', we'd still use 'piix3-uhci' in libvirt
XML and re-write to the VMWare specific name internally. Or the
opposite if we standardized on the VMWare name first and later
wnated to add QEMU support.
That makes sense.
In the case of totally invented paravirt devices, we'll come up
with a name that seems most appropriate for the hypervisor which
invented the device type.
> == Draft design proposal ==
>
> I've given it some thought, and based on the below is a suggested
> design for people to have a go at.
>
> Basic idea: Specify named controllers. It's controllers that are PV
> or emulated, and may have a backend domain. When adding devices,
> specify which controller to attach it to. Allow most things to have
> intelligent defaults.
>
> * libxl functions
>
> usb_controller_add
> usb_controller_remove/destroy
> usb_controller_list
> device struct:
> name # If empty, default to hciN/pvN, where N starts at 0
> type = {PV, EMULATED, AUTO}
> backend_{domname,domid} # PV only
> usbversion = {1, 2, 3}
> numports # default 16
So with this kind of syntax, libvirt is going to have to try to
map a model name 'piix3-uhci' to a pair of type,usbversion
eg type=emulated,usbversion=1.
Right -- if we went with an interface where you cannot specify via
libxl exactly which controller qemu uses, then we would try to make
sure that repeated invocations of the same parameters got the same
controller, so that things don't change under the guest OS's feet. So
it should be OK for libvirt to magically know that "{ .type=EMULATED,
.usbversion=1}" would map to 'piix3-uhci', and use that to implement
libvirt's 'piix3-uhci' model. Anything not exposed by libxl would
have to just be unimplemented until the interface was extended to
allow them.
At the moment the mapping exposed by the "usbversion" seems to be: {1,
2, 3} -> {piix3-uhci, ich9-usb-ehci1, nec-usb-xhci}. Does that seem
like a reasonable choice?
Personally I wouldn't mind being able to either pass in "usbversion",
or a string requesting a specific controller name -- but I think IanJ
would prefer to keep those details secret.
We'd likely give the paravirt
controller model names of xenusb1, xenusb2, xenusb3 for USB-1
USB-2 and USB-3 respectively, and again map these to type=pv,usbversion=N.
That sounds reasonable.
-George