On Thu, Sep 30, 2021 at 01:12:39PM +0200, Laszlo Ersek wrote:
On 09/29/21 21:22, Richard W.M. Jones wrote: Please correct me if I'm wrong: at the moment, I believe virt-v2v parses and manipulates the following elements and attributes in the domain XML:
<target dev='hda' bus='ide'/> <target dev='hdb' bus='ide'/> <target dev='hdc' bus='ide'/> <target dev='hdd' bus='ide'/> ^^^ ^^^
My understanding is however that the target/@dev attribute is mostly irrelevant:
https://libvirt.org/formatdomain.html#hard-drives-floppy-disks-cdroms
The dev attribute indicates the "logical" device name. The actual device name specified is not guaranteed to map to the device name in the guest OS. Treat it as a device ordering hint. [...]
I won't say it is irrelevant. Functionally @dev is absolutely still important, as it influences how the disk is attached to the VM. Rather I would say that the @dev attribute is misleading to users, because they mistakenly think it provides a guarantee that the disk will appear with this name inside the guest.
What actually matters is the target/@bus attribute, in combination with the sibling element <address>. Such as:
<target dev='hda' bus='ide'/> ^^^ <address type='drive' controller='0' bus='0' target='0' unit='0'/> ^ ^ ^
<target dev='hdb' bus='ide'/> ^^^ <address type='drive' controller='0' bus='0' target='0' unit='1'/> ^ ^ ^
<target dev='hdc' bus='ide'/> ^^^ <address type='drive' controller='0' bus='1' target='0' unit='0'/> ^ ^ ^
<target dev='hdd' bus='ide'/> ^^^ <address type='drive' controller='0' bus='1' target='0' unit='1'/> ^ ^ ^
So, target/@dev should be mostly ignored; what matters is the following tuple:
(target/@bus, address/@controller, address/@bus, address/@unit)
Yes, the <address/> is what libvirt internally drivers all configuration off, but in practice application developers almost never use the <address> element directly. They will just give target/@dev and libvirt will use that to automatically populate an <address/> element, in order to reliably fixate the guest ABI thereafter.
Extracting just the tuples:
(ide, 0, 0, 0) (ide, 0, 0, 1) (ide, 0, 1, 0) (ide, 0, 1, 1)
The first two components of each tuple -- i.e., (ide, 0) -- refer to the following IDE controller:
<controller type='ide' index='0'> ^^^^^^^^^^ ^^^^^^^^^ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/> </controller>
and then the rest of the components, such as (0, 0), (0, 1), (1, 0), (1, 1), identify the disk on that IDE controller.
Yes, that's correct for IDE.
(Side comment: the PCI location of the (first) IDE controller is fixed in QEMU; if one tries to change it, libvirt complains: "Primary IDE controller must have PCI address 0:0:1.1".)
Yep, its defined by the QEMU machine type and we just have to accept that for IDE/SATA.
Inside the guest, /dev/hd* nodes don't even exist, so it's unlikely that /etc/fstab would refer to them. /etc/fstab can however refer to symlinks under "/dev/disk/by-id" (for example):
lrwxrwxrwx. 1 root root 9 Sep 30 11:54 ata-QEMU_DVD-ROM_QM00001 -> ../../sr0 lrwxrwxrwx. 1 root root 9 Sep 30 11:54 ata-QEMU_DVD-ROM_QM00002 -> ../../sr1 lrwxrwxrwx. 1 root root 9 Sep 30 11:54 ata-QEMU_DVD-ROM_QM00003 -> ../../sr2 lrwxrwxrwx. 1 root root 9 Sep 30 11:54 ata-QEMU_DVD-ROM_QM00004 -> ../../sr3
Furthermore, we have pseudo-files (directories) such as:
/sys/devices/pci0000:00/0000:00:01.1/ata1/host0/target0:0:0/0:0:0:0/block/sr0 /sys/devices/pci0000:00/0000:00:01.1/ata1/host0/target0:0:1/0:0:1:0/block/sr1 /sys/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/block/sr2 /sys/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:1/1:0:1:0/block/sr3 ^ ^
So in order to map a device path from the original guest's "/etc/fstab", such as "/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00003", to the original domain XML's <disk> element, we have to do the following in the "source" appliance:
NODE=$(realpath /dev/disk/by-id/ata-QEMU_DVD-ROM_QM00003) # -> /dev/sr2 NODE=${NODE#/dev/} # -> sr2 DEVPATH=$(ls -d /sys/devices/pci0000:00/0000:00:01.1/ata?/host?/target?:0:?/?:0:?:0/block/$NODE) # -> /sys/devices/pci0000:00/0000:00:01.1/ata2/host1/target1:0:0/1:0:0:0/block/sr2
And then map the "1:0:0:0" pathname component from $DEVPATH to:
<target dev='hdc' bus='ide'/> <address type='drive' controller='0' bus='1' target='0' unit='0'/> ^^^^^^^ ^^^^^^^^ [1]:0:0:0 1:0:[0]:0
in the original domain XML. This tells us under what device node the original guest sees the host-side file (<source> element).
Yes, to map from the guest to the libvirt XML, you need to be working in terms of the hardware buses/addresses.
So, assuming we mapped the original (i440fx) "/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00003" guest device path to some <source> element (= host-side file) in the original domain XML, and assuming virt-v2v assigned the same <source> element to the following element on the Q35 board:
<target dev='sd*' bus='sata'/> <address type='drive' controller='0' bus='0' target='0' unit='4'/> ^^^^^^^^
we find the device node in the destination appliance as follows:
NODE=$(basename /sys/devices/pci0000:00/0000:00:1f.2/ata?/host?/target?:0:0/4:0:0:0/block/*) ^ unit='4' # -> sr4
and then replace "/dev/disk/by-id/ata-QEMU_DVD-ROM_QM00003" with "/dev/sr4" in "/etc/fstab".
I wouldn't recommend using any of the /dev/* devices, as those are all unstable when faced with changed guest configuration over time. /etc/fstab should really use a stable /dev/disk/ symlink, so it can be directly associated with the desired device based on the hardware topology, rather than guest OS device probe order.
/dev/disk/by-label and /dev/disk/by-uuid are based on media contents, and multiple CD-ROMs may (read-only) map the same host-side file, so those are not good for mapping either, I think. Also does not cover CD-ROM devices that are empty (have no medium) at the time of conversion, but "/etc/fstab" still refers to them (potentially with "noauto"). So I think the only reliable ID is the hardware device path.
Yep, the symlink based on hardware topology is the only thing that can be stable and unique. Regards, Daniel -- |: https://berrange.com -o- https://www.flickr.com/photos/dberrange :| |: https://libvirt.org -o- https://fstop138.berrange.com :| |: https://entangle-photo.org -o- https://www.instagram.com/dberrange :|