[Libguestfs] translating CD-ROM device paths from i440fx to Q35 in virt-v2v (was: test-v2v-cdrom: update the CD-ROM's bus to SATA in the converted domain)
Daniel P. Berrangé
berrange at redhat.com
Thu Sep 30 11:54:21 UTC 2021
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 :|
More information about the Libguestfs
mailing list