nova.virt.block_device.DriverBlockDevice cannot save to DB if bdm passed in was not already an object

Bug #1524035 reported by Matt Riedemann
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Compute (nova)
Fix Released
Medium
Matt Riedemann

Bug Description

This code doesn't work:

https://github.com/openstack/nova/blob/master/nova/virt/block_device.py#L128-L131

That will create a BlockDeviceMapping object to be wrapped in the DriverBlockDevice object (if a BDM object was not passed in). The problem is on self._bdm_obj.save() will fail with something like this:

Captured traceback:
~~~~~~~~~~~~~~~~~~~
    Traceback (most recent call last):
      File "nova/tests/unit/virt/test_block_device.py", line 909, in test_blank_attach_volume_cinder_cross_az_attach_false
        self.virt_driver)
      File "nova/virt/block_device.py", line 456, in attach
        self.save()
      File "nova/virt/block_device.py", line 363, in save
        super(DriverVolumeBlockDevice, self).save()
      File "nova/virt/block_device.py", line 176, in save
        self._bdm_obj.save()
      File "/home/mriedem/git/nova/.tox/py27/local/lib/python2.7/site-packages/oslo_versionedobjects/base.py", line 203, in wrapper
        objtype=self.obj_name())
    oslo_versionedobjects.exception.OrphanedObjectError: Cannot call save on orphaned BlockDeviceMapping object

That's because the BDM object that was created doesn't have a context set on it.

And we can't pass context to self._bdm_obj.save() because we removed that here: https://review.openstack.org/#/c/164268/

We've apparently never had a problem with this in runtime because we must always be constructing the DriverBlockDevice with a real BDM object in the compute code, we just weren't doing it properly in the tests - and the tests mock out nova.objects.BlockDeviceMapping.save() so we never knew it was a problem.

Matt Riedemann (mriedem)
Changed in nova:
status: New → Triaged
importance: Undecided → Medium
assignee: nobody → Matt Riedemann (mriedem)
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to nova (master)

Fix proposed to branch: master
Review: https://review.openstack.org/260685

Changed in nova:
status: Triaged → In Progress
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to nova (master)

Reviewed: https://review.openstack.org/260685
Committed: https://git.openstack.org/cgit/openstack/nova/commit/?id=215f403ad3b7705a28075217b97a0f6f6e658204
Submitter: Jenkins
Branch: master

commit 215f403ad3b7705a28075217b97a0f6f6e658204
Author: Matt Riedemann <email address hidden>
Date: Mon Dec 21 13:48:36 2015 -0800

    DriverBlockDevice must receive a BDM object, not a dict

    Commit 7a54543a81cbb8d20e6df29e7f4468a436dae212
    made it such that a BlockDeviceMapping object has to be
    constructed with a request context in order to call the
    remotable save() method on it.

    We must be already passing BDM objects when constructing
    DriverBlockDevices otherwise calling self._bdm_obj.save()
    would fail with an OrphanedObjectError. So the only places
    that were still using bdm dicts were unit tests, and those
    worked because objects.BlockDeviceMapping.save() is being
    mocked out.

    This removes the false sense of ability to construct a
    DriverBlocKDevice without a BDM object and cleans up the
    unit tests to reflect that reality.

    Closes-Bug: #1524035

    Change-Id: Ie745fc4d36ceb3e0aae1b14d5d56b2b83bbb192c

Changed in nova:
status: In Progress → Fix Released
Revision history for this message
Thierry Carrez (ttx) wrote : Fix included in openstack/nova 13.0.0.0b2

This issue was fixed in the openstack/nova 13.0.0.0b2 development milestone.

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.