compute: normalize cross-HV BDM device names - #653
Conversation
Customers can set their own BDM device paths. VMware does not pass these paths to the guest as disk targets. It uses them to keep a stable volume attachment order, while the guest still sees normal SCSI devices and /dev/sdX device names in guest. This is not compatible with the current libvirt/KVM path. Nova passes the BDM device name to libvirt as the disk target, and libvirt expects a guest disk target name for the selected bus. During VMware-to-KVM resize, journal the original root and BDM names. Then assign /dev/vdX target device names following the VMware order: root first, then remaining volumes by original device name. On revert, restore the journaled root name, BDM names, and disk buses exactly. Change-Id: Id130a3ef18be29bfb8bab3681c75554b23862ba5
|
|
||
| def _journal_cross_hv_bdms(self, instance, bdms): | ||
| sysmeta = instance.system_metadata | ||
| root_name_key = 'cross_hv_orig_root_device_name' |
There was a problem hiding this comment.
Could be a constant instead of the same string 3 times but probably won't ever change.
| def original_bdm_device_name(bdm): | ||
| bdm_name_key = ( | ||
| 'cross_hv_orig_bdm_device_name_%s' % bdm.volume_id) | ||
| if bdm_name_key in sysmeta: | ||
| return self._cross_hv_restore_journal_value( | ||
| sysmeta[bdm_name_key]) | ||
| return bdm.device_name |
There was a problem hiding this comment.
Could also be a staticmethod _original_bdm_device_name(sysmeta, bdm) for one less copy.
| return (not is_root_bdm(bdm), | ||
| original_bdm_device_name(bdm) or '', | ||
| bdm.volume_id) |
There was a problem hiding this comment.
So root comes first because it's the only False in the tuple. Second would be any bdm without an original device name because they'd evaluate to ''. Is that the correct order of VMWare?
There was a problem hiding this comment.
hm, true. maybe it should be or 'zzzzzzz' or something? this is just for ordering, so the string itself wouldn't matter.
There was a problem hiding this comment.
It's a genuine question I don't know the answer to, this might be the actual way how VMWare orders it.
| self.assertEqual('virtio', root_bdm.disk_bus) | ||
| self.assertEqual('virtio', data_bdm.disk_bus) | ||
|
|
||
| def test_sanitize_cross_hv_bdms_forward_keeps_existing_journal(self): |
There was a problem hiding this comment.
Just out of interest, when would a journal exist already? On a VM that was resized and reverted?
| if root_device_name != instance.root_device_name: | ||
| instance.root_device_name = root_device_name | ||
| def _cross_hv_journal_value(value): | ||
| return value if value is not None else '__NONE__' |
There was a problem hiding this comment.
We don't really expect empty string or 0, do we?
| return value if value is not None else '__NONE__' | |
| return value or '__NONE__' |
... and then one could almost inline the function again.
| def original_bdm_device_name(bdm): | ||
| bdm_name_key = ( | ||
| 'cross_hv_orig_bdm_device_name_%s' % bdm.volume_id) | ||
| if bdm_name_key in sysmeta: | ||
| return self._cross_hv_restore_journal_value( | ||
| sysmeta[bdm_name_key]) | ||
| return bdm.device_name |
There was a problem hiding this comment.
that's a duplicate with the one in _journal_cross_hv_bdms() -- i'd pull it out into a static member function...
| return (not is_root_bdm(bdm), | ||
| original_bdm_device_name(bdm) or '', | ||
| bdm.volume_id) |
There was a problem hiding this comment.
hm, true. maybe it should be or 'zzzzzzz' or something? this is just for ordering, so the string itself wouldn't matter.
Customers can set their own BDM device paths. VMware does not pass these paths to the guest as disk targets. It uses them to keep a stable volume attachment order, while the guest still sees normal SCSI devices and /dev/sdX device names in guest.
This is not compatible with the current libvirt/KVM path. Nova passes the BDM device name to libvirt as the disk target, and libvirt expects a guest disk target name for the selected bus.
During VMware-to-KVM resize, journal the original root and BDM names. Then assign /dev/vdX target device names following the VMware order: root first, then remaining volumes by original device name.
On revert, restore the journaled root name, BDM names, and disk buses exactly.
Change-Id: Id130a3ef18be29bfb8bab3681c75554b23862ba5