nova/nova/tests/unit/virt/libvirt/volume
Matthew Booth 4aa39c44a4 libvirt: Fix races with nfs volume mount/umount
A single nfs export typically contains multiple volumes. We were
handling this in the libvirt driver by:

1. On mount, we 'ensure' the mount is available, so we don't fail if
   another instance already has it mounted.

2. On umount, we trap and ignore 'device is busy' so we don't fail if
   another instance is already using it.

Unfortunately, while this works for serial mounts and unmounts, there
are multiple failure cases when volumes from the same export are
mounted and unmounted simultaneously. It causes an error if an
instance is stopped: as the qemu process is not actively using the
mountpoint it will not prevent an unmount for another volume on the
same mountpoint from succeeding. It will not be possible to restart
the instance, because its mountpoint will not be mounted.

To fix this, we create a singleton manager object, which tracks mounts
and umount requests per export, and calls the real mount/umount only
when required. It uses per-export locks to allow concurrency while
avoiding races. Because we now expect to know the state of the host at
all times, we no longer need to execute speculative mount/umount
commands.

As we track attachments (a mapping from volume to instance) rather
than volumes, we also gracefully support multi-attach.

This change implements this for nfs, but the solution is intended to
be extended to all LibvirtBaseFileSystemVolumeDrivers.

Closes-Bug: #1421550
Change-Id: I3155984d76df06371a6c45f633aa448168a96d64
2017-05-08 15:33:23 +00:00
..
__init__.py libvirt: move volume/remotefs/quobyte modules under volume subdir 2015-07-28 17:46:05 -07:00
test_aoe.py libvirt: Pass Host instead of Driver to volume drivers 2016-11-01 16:41:08 +00:00
test_disco.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_fibrechannel.py objects: Move 'arch' to 'fields.Architecture' 2016-11-25 16:19:41 +00:00
test_fs.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_glusterfs.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_gpfs.py libvirt: Pass Host instead of Driver to volume drivers 2016-11-01 16:41:08 +00:00
test_hgst.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_iscsi.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_iser.py libvirt: Pass Host instead of Driver to volume drivers 2016-11-01 16:41:08 +00:00
test_mount.py libvirt: Fix races with nfs volume mount/umount 2017-05-08 15:33:23 +00:00
test_net.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_nfs.py libvirt: Fix races with nfs volume mount/umount 2017-05-08 15:33:23 +00:00
test_quobyte.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_remotefs.py Properly quote IPv6 address in RsyncDriver 2016-08-01 14:56:37 +03:00
test_scaleio.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_scality.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_smbfs.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00
test_volume.py libvirt: drop MIN_QEMU_DISCARD_VERSION 2017-02-11 20:30:31 -05:00
test_vzstorage.py libvirt: Pass instance to connect_volume and disconnect_volume 2017-05-08 11:31:11 -04:00