After working half of the day on this issue on my local installation, if all you want to do is to detach a root volume, two updates in mysql are sufficient:
use cinder;
update volume_attachment set mountpoint='/dev/vdb' where volume_id = 'oldVolumeId' and deleted = 0;
use nova;
update block_device_mapping set device_name = '/dev/vdb', boot_index=1 where volume_id = 'oldVolumeId' and deleted = 0;
basically the mountpoint/device name must not be /dev/vda and boot_index must not be 0. If this is true, you can successfully remove the volume using
nova volume-detach <instanceId> <volumeId>.
To attach another volume, do the same thing in reverse after having used nova volume-attach. That is, set the name back to /dev/vda and set the boot_index to 0 for the new volume. Basically below:
use cinder;
update volume_attachment set mountpoint='/dev/vda' where volume_id = 'shinyNewVolumeId' and deleted = 0;
use nova;
update block_device_mapping set device_name = '/dev/vda', boot_index=0 where volume_id = 'shinyNewVolumeId' and deleted = 0;
Then again use the magic incantation:
nova reboot --hard <instanceId>
to force a fresh and correct libvirt config for the instance being created.
After working half of the day on this issue on my local installation, if all you want to do is to detach a root volume, two updates in mysql are sufficient:
use cinder; '/dev/vdb' where volume_id = 'oldVolumeId' and deleted = 0; mapping set device_name = '/dev/vdb', boot_index=1 where volume_id = 'oldVolumeId' and deleted = 0;
update volume_attachment set mountpoint=
use nova;
update block_device_
basically the mountpoint/device name must not be /dev/vda and boot_index must not be 0. If this is true, you can successfully remove the volume using
nova volume-detach <instanceId> <volumeId>.
To attach another volume, do the same thing in reverse after having used nova volume-attach. That is, set the name back to /dev/vda and set the boot_index to 0 for the new volume. Basically below:
use cinder; '/dev/vda' where volume_id = 'shinyNewVolumeId' and deleted = 0; mapping set device_name = '/dev/vda', boot_index=0 where volume_id = 'shinyNewVolumeId' and deleted = 0;
update volume_attachment set mountpoint=
use nova;
update block_device_
Then again use the magic incantation:
nova reboot --hard <instanceId>
to force a fresh and correct libvirt config for the instance being created.