-
Notifications
You must be signed in to change notification settings - Fork 328
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Resolve device names for attached Cinder volumes #1240
base: master
Are you sure you want to change the base?
Conversation
This patch aims to resolve the issue with hypervisors not honoring device names suggested by Cinder, by resolving the device names from the symlinks created under /dev/disk/by-id
Codecov Report
@@ Coverage Diff @@
## master #1240 +/- ##
==========================================
+ Coverage 34.25% 34.54% +0.29%
==========================================
Files 36 36
Lines 2362 2362
==========================================
+ Hits 809 816 +7
+ Misses 1450 1442 -8
- Partials 103 104 +1
Continue to review full report at Codecov.
|
When can we expect this pull request to come through? We're really waiting for this fix :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My concern here is that this only works when running REX-Ray in an all-in-one configuration, but not in client/server.
Additionally, does this only work when using KVM+virtio? I think part of the reason there wasn't specific parsing of paths right now is due to the fact that OpenStack can be using multiple hypervisors, and potentially different device drivers. meaning, there's no guarantee of what specific device path you could rely on (e.g. /dev/disk/by-id/virtio-*
). I mean that as a question, as I don't actually know.
If it's true there could me multiple places that volumes could be attached, but KVM+virtio is most common, we could make this configurable, and also make it the default. Thoughts?
return volume, resolveDeviceName(volumeID, volumeAttach.Device), nil | ||
} | ||
|
||
func getDeviceLink( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolving devices that are on the node by peaking in /dev
cannot be done in this code, as it may not be running on the same node. REX-Ray supports a client/server mode of operation, where a single REX-Ray instance running in server mode is configured with the Cinder API credentials, but all client nodes are just talking to the master REX-Ray instance.
Any code that is specific to a single node/instance needs to be in the executor, not here.
The way this should be handled is in the LocalDevices
function in the executor. This function returns a map of attached devices, with their actual path to their volume ID. Right now, this function is returning all attached devices, and an empty volume ID. This would need to modified to extract the volume ID from your virtio
path used below...
func getDeviceLink( | ||
volumeID string) string { | ||
|
||
return fmt.Sprintf("/dev/disk/by-id/virtio-%s", volumeID[:20]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The bit about the executor aside, is this universal across OpenStack/Cinder? I think one of the reasons things are the way they are now is because not everything is using virtio, correct? What if this was on a Xen hypervisor? Would this path be the same?
I recognize things are broken right now, and we should target the most common usecase, which is probably KVM with virtio. But if that's not universal, this needs to be a configurable behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wouldn't it be sufficient for now to use /dev/disk/by-id/virtio-%s if it exists (and obviously virtio is used), and fallback to /dev/devicename if not?
From what I could find, using Cinder with Xen will not make the volume ID available to the OS, so if Xen + Cinder is facing similar issues with the devicename order in case of read errors, then there is no way to fix it in rexray...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
virtio-%s
this won't work in all cases, as for example in my case, devices are named as:
/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_2afa0091-d1c5-46e2-9
/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_426c308d-a355-4cca-a
/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_4dfda350-9cd9-4901-8
/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_52645ecc-2ac0-4534-a
/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_5569888b-5d88-4a57-9
/dev/disk/by-id/scsi-0QEMU_QEMU_HARDDISK_698a3ded-990a-420b-8
(Openstack from OVH)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ICYMI, for OVH/Openstack I hacked a variant and made the plugin available here: https://hub.docker.com/r/hervenicol/rexray.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
...it appears the hack is not enough, we still have a lot of issues: wrong volume mounted, volumes created although already existing, unable to mount volumes...
So I decided to go to a simpler, cinder-dedicated plugin: https://github.com/hervenicol/docker-plugin-cinder
It means a lot less code, easier to understand / debug / evolve.
It seems rexray was overkill for my use case. And on top of that, too complex for me to maintain / fix it by myself.
@@ -330,7 +333,7 @@ func translateVolume( | |||
libstorageAttachment := &types.VolumeAttachment{ | |||
VolumeID: attachment.VolumeID, | |||
InstanceID: &types.InstanceID{ID: attachment.ServerID, Driver: cinder.Name}, | |||
DeviceName: attachment.Device, | |||
DeviceName: resolveDeviceName(attachment.VolumeID, attachment.Device), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This instead needs to match the volume ID to those found in the LocalDevices map, which right now is empty, and pull the device name from that. This code may be running on a different node than where the volume is attached.
Each driver has to do this a bit differently, but here is an example from EBS and ScaleIO
Hi there @codenrhoden, To fix this the following is needed to be done (feel free to correct me if I'm wrong):
I could try to give this a go, but since my current workload is at an all-time high (at least it feels this way), it probably will take at least a month (needless to say that I'm not the most proficient go programmer out there). |
As highlighted in #1183, Cinder suggests a device name for a volume, which is not always used by the hypervisor. This issue is reliably reproducible with force detach:
Doing this leads to Cinder always offering the same device name, while the hypervisor will pick something else (possibly due to abruptly losing said device).
This patch aims to resolve the issue by resolving the device names by matching the volume IDs to the
virtio-XXXXXXXX-XXXX-XXXX-X
-symlinks created under /dev/disk/by-id (adapted from ederst@0f57fc7)