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 :|