summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--nova/tests/virt/xenapi/test_xenapi.py18
-rw-r--r--nova/virt/xenapi/vmops.py43
2 files changed, 38 insertions, 23 deletions
diff --git a/nova/tests/virt/xenapi/test_xenapi.py b/nova/tests/virt/xenapi/test_xenapi.py
index d99fdcb8e..5a0ccb8dd 100644
--- a/nova/tests/virt/xenapi/test_xenapi.py
+++ b/nova/tests/virt/xenapi/test_xenapi.py
@@ -3310,7 +3310,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
self.xenstore = dict(persist={}, ephem={})
def fake_get_vm_opaque_ref(inst, instance):
- self.assertEqual(instance, 'instance')
+ self.assertEqual(instance, {'uuid': 'fake'})
return 'vm_ref'
def fake_add_to_param_xenstore(inst, vm_ref, key, val):
@@ -3323,12 +3323,12 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
del self.xenstore['persist'][key]
def fake_write_to_xenstore(inst, instance, path, value, vm_ref=None):
- self.assertEqual(instance, 'instance')
+ self.assertEqual(instance, {'uuid': 'fake'})
self.assertEqual(vm_ref, 'vm_ref')
self.xenstore['ephem'][path] = jsonutils.dumps(value)
def fake_delete_from_xenstore(inst, instance, path, vm_ref=None):
- self.assertEqual(instance, 'instance')
+ self.assertEqual(instance, {'uuid': 'fake'})
self.assertEqual(vm_ref, 'vm_ref')
if path in self.xenstore['ephem']:
del self.xenstore['ephem'][path]
@@ -3357,7 +3357,8 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
# Check xenstore key sanitizing
system_metadata=[{'key': 'sys_a', 'value': 1},
{'key': 'sys_b', 'value': 2},
- {'key': 'sys_c', 'value': 3}])
+ {'key': 'sys_c', 'value': 3}],
+ uuid='fake')
self.conn._vmops.inject_instance_metadata(instance, 'vm_ref')
self.assertEqual(self.xenstore, {
@@ -3374,6 +3375,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
def test_change_instance_metadata_add(self):
# Test XenStore key sanitizing here, too.
diff = {'test.key': ['+', 4]}
+ instance = {'uuid': 'fake'}
self.xenstore = {
'persist': {
'vm-data/user-metadata/a': '1',
@@ -3387,7 +3389,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
},
}
- self.conn._vmops.change_instance_metadata('instance', diff)
+ self.conn._vmops.change_instance_metadata(instance, diff)
self.assertEqual(self.xenstore, {
'persist': {
@@ -3406,6 +3408,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
def test_change_instance_metadata_update(self):
diff = dict(b=['+', 4])
+ instance = {'uuid': 'fake'}
self.xenstore = {
'persist': {
'vm-data/user-metadata/a': '1',
@@ -3419,7 +3422,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
},
}
- self.conn._vmops.change_instance_metadata('instance', diff)
+ self.conn._vmops.change_instance_metadata(instance, diff)
self.assertEqual(self.xenstore, {
'persist': {
@@ -3436,6 +3439,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
def test_change_instance_metadata_delete(self):
diff = dict(b=['-'])
+ instance = {'uuid': 'fake'}
self.xenstore = {
'persist': {
'vm-data/user-metadata/a': '1',
@@ -3449,7 +3453,7 @@ class XenAPIInjectMetadataTestCase(stubs.XenAPITestBase):
},
}
- self.conn._vmops.change_instance_metadata('instance', diff)
+ self.conn._vmops.change_instance_metadata(instance, diff)
self.assertEqual(self.xenstore, {
'persist': {
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py
index bf8aa3e52..0a21c0b5c 100644
--- a/nova/virt/xenapi/vmops.py
+++ b/nova/virt/xenapi/vmops.py
@@ -1095,6 +1095,7 @@ class VMOps(object):
def inject_instance_metadata(self, instance, vm_ref):
"""Inject instance metadata into xenstore."""
+ @utils.synchronized('xenstore-' + instance['uuid'])
def store_meta(topdir, data_list):
for item in data_list:
key = self._sanitize_xenstore_key(item['key'])
@@ -1108,9 +1109,8 @@ class VMOps(object):
def change_instance_metadata(self, instance, diff):
"""Apply changes to instance metadata to xenstore."""
vm_ref = self._get_vm_opaque_ref(instance)
- for key, change in diff.items():
- key = self._sanitize_xenstore_key(key)
- location = 'vm-data/user-metadata/%s' % key
+
+ def process_change(location, change):
if change[0] == '-':
self._remove_from_param_xenstore(vm_ref, location)
try:
@@ -1129,6 +1129,14 @@ class VMOps(object):
# catch KeyError for domid if instance isn't running
pass
+ @utils.synchronized('xenstore-' + instance['uuid'])
+ def update_meta():
+ for key, change in diff.items():
+ key = self._sanitize_xenstore_key(key)
+ location = 'vm-data/user-metadata/%s' % key
+ process_change(location, change)
+ update_meta()
+
def _find_root_vdi_ref(self, vm_ref):
"""Find and return the root vdi ref for a VM."""
if not vm_ref:
@@ -1531,19 +1539,22 @@ class VMOps(object):
vm_ref = vm_ref or self._get_vm_opaque_ref(instance)
LOG.debug(_("Injecting network info to xenstore"), instance=instance)
- for vif in network_info:
- xs_data = self._vif_xenstore_data(vif)
- location = ('vm-data/networking/%s' %
- vif['address'].replace(':', ''))
- self._add_to_param_xenstore(vm_ref,
- location,
- jsonutils.dumps(xs_data))
- try:
- self._write_to_xenstore(instance, location, xs_data,
- vm_ref=vm_ref)
- except KeyError:
- # catch KeyError for domid if instance isn't running
- pass
+ @utils.synchronized('xenstore-' + instance['uuid'])
+ def update_nwinfo():
+ for vif in network_info:
+ xs_data = self._vif_xenstore_data(vif)
+ location = ('vm-data/networking/%s' %
+ vif['address'].replace(':', ''))
+ self._add_to_param_xenstore(vm_ref,
+ location,
+ jsonutils.dumps(xs_data))
+ try:
+ self._write_to_xenstore(instance, location, xs_data,
+ vm_ref=vm_ref)
+ except KeyError:
+ # catch KeyError for domid if instance isn't running
+ pass
+ update_nwinfo()
def _create_vifs(self, vm_ref, instance, network_info):
"""Creates vifs for an instance."""