synchronization problem in libvirt's remotefs volume drivers
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
OpenStack Compute (nova) |
Confirmed
|
Undecided
|
Unassigned |
Bug Description
Remotefs drivers have to mount a filesystem while connecting a new volume and unmount it eventually. They do it with code like:
connect_volume:
if not is_mounted():
do_mount()
disconnect_volume:
try:
umount()
except:
if error is not 'fs is busy':
raise
There is a race here - someone can umount fs between "if not is_mounted():" and "do_mount()".
I think there should be sort of reference counting, so that disconnect_volume will not unmount fs, is some instances use it.
The simple testcase:
1. Configure cinder to use nfs driver
2. Create 2 volume from an image
cinder create --image <image_id> 4
cinder create --image <image_id> 4
3. boot 2 instances from these volumes
nova boot inst1 --flavor m1.vz --block-device id=<vol1 id>,source=
nova boot inst2 --flavor m1.vz --block-device id=<vol2 id>,source=
4. Suspend first instance
nova suspend inst1
5. delete second instance
nova delete inst2
6. resume first instance
nova resume inst1
The error should appear
] Setting instance vm_state to ERROR
] Traceback (most recent call last):
] File "/opt/stack/
] yield
] File "/opt/stack/
] block_device_info)
] File "/opt/stack/
] vifs_already_
] File "/opt/stack/
] xml, pause=pause, power_on=power_on)
] File "/opt/stack/
] guest.launch(
] File "/opt/stack/
] self._encoded_xml, errors='ignore')
] File "/usr/lib/
] six.reraise(
] File "/opt/stack/
] return self._domain.
] File "/usr/lib/
] result = proxy_call(
] File "/usr/lib/
] rv = execute(f, *args, **kwargs)
] File "/usr/lib/
] six.reraise(c, e, tb)
] File "/usr/lib/
] rv = meth(*args, **kwargs)
] File "/usr/lib64/
] if ret == -1: raise libvirtError ('virDomainCrea
] libvirtError: Cannot access storage file '/opt/stack/
tags: | added: libvirt |
tags: | added: volumes |
Changed in nova: | |
status: | New → Confirmed |