diff options
| author | Chris Behrens <cbehrens@codestud.com> | 2012-10-08 23:33:17 +0000 |
|---|---|---|
| committer | Chris Behrens <cbehrens@codestud.com> | 2012-10-09 00:00:17 +0000 |
| commit | fb101685cc14ed9b0396ce966e571d3fb457c32f (patch) | |
| tree | adc4fe9352d1ea0a2cb9c52fd404a62f8a6908ce /nova/virt | |
| parent | df473799c212381c072a3d37c40feb6629eff890 (diff) | |
XenAPI should only snapshot root disk
Change ID I3e2973 broke XenAPI migrations (resizes) as it caused snapshots
of all disks (including swap and ephemeral disks, if enabled) to be sent
over to the destination host. The destination only expects vhds for the
root disk, named by sequence numbers. swap and ephemeral disks ended up
with sequence numbers, also, messing up the re-building of the chain on
the destination.
Fixes bug 1064083
Change ID I3e2973 also didn't change the stub of VM.snapshot to
VDI.snapshot, but tests still passed due to the new code ignoring all
exceptions while snapshotting. Potential issues in
snapshot_attached_here() would also be ignored due to excessive stubbing
in the xenapi migration testing. This is also addressed here.
Change-Id: I145030f92a75615d056a30cabcb6ca97e34a8b6c
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/xenapi/fake.py | 10 | ||||
| -rw-r--r-- | nova/virt/xenapi/vm_utils.py | 52 |
2 files changed, 19 insertions, 43 deletions
diff --git a/nova/virt/xenapi/fake.py b/nova/virt/xenapi/fake.py index 13be473b3..ac41669f2 100644 --- a/nova/virt/xenapi/fake.py +++ b/nova/virt/xenapi/fake.py @@ -172,7 +172,7 @@ def create_vdi(name_label, sr_ref, **kwargs): 'other_config': {}, 'location': '', 'xenstore_data': {}, - 'sm_config': {}, + 'sm_config': {'vhd-parent': None}, 'physical_utilisation': '123', 'managed': True, } @@ -564,12 +564,18 @@ class SessionBase(object): def _plugin_pickle_noop(self, method, args): return pickle.dumps(None) + def _plugin_migration_transfer_vhd(self, method, args): + kwargs = pickle.loads(args['params'])['kwargs'] + vdi_ref = self.xenapi_request('VDI.get_by_uuid', + (kwargs['vdi_uuid'], )) + assert vdi_ref + return pickle.dumps(None) + _plugin_glance_upload_vhd = _plugin_pickle_noop _plugin_kernel_copy_vdi = _plugin_noop _plugin_kernel_create_kernel_ramdisk = _plugin_noop _plugin_kernel_remove_kernel_ramdisk = _plugin_noop _plugin_migration_move_vhds_into_sr = _plugin_noop - _plugin_migration_transfer_vhd = _plugin_pickle_noop def _plugin_xenhost_host_data(self, method, args): return jsonutils.dumps({'host_memory': {'total': 10, diff --git a/nova/virt/xenapi/vm_utils.py b/nova/virt/xenapi/vm_utils.py index bc098678f..e1d3ab753 100644 --- a/nova/virt/xenapi/vm_utils.py +++ b/nova/virt/xenapi/vm_utils.py @@ -551,56 +551,26 @@ def get_vdi_for_vm_safely(session, vm_ref): @contextlib.contextmanager def snapshot_attached_here(session, instance, vm_ref, label): + """Snapshot the root disk only. Return a list of uuids for the vhds + in the chain. + """ LOG.debug(_("Starting snapshot for VM"), instance=instance) # Memorize the original_parent_uuid so we can poll for coalesce vm_vdi_ref, vm_vdi_rec = get_vdi_for_vm_safely(session, vm_ref) original_parent_uuid = _get_vhd_parent_uuid(session, vm_vdi_ref) + sr_ref = vm_vdi_rec["SR"] + snapshot_ref = session.call_xenapi("VDI.snapshot", vm_vdi_ref, {}) try: - vdi_snapshot_recs = _vdi_snapshot_vm_base(session, instance, vm_ref) - sr_ref = vm_vdi_rec["SR"] - parent_uuid, base_uuid = _wait_for_vhd_coalesce( - session, instance, sr_ref, vm_vdi_ref, original_parent_uuid) - - vdi_uuids = [] - for snapshot in vdi_snapshot_recs: - vdi_uuids += [vdi_rec['uuid'] for vdi_rec in - _walk_vdi_chain(session, snapshot['uuid'])] - + snapshot_rec = session.call_xenapi("VDI.get_record", snapshot_ref) + _wait_for_vhd_coalesce(session, instance, sr_ref, vm_vdi_ref, + original_parent_uuid) + vdi_uuids = [vdi_rec['uuid'] for vdi_rec in + _walk_vdi_chain(session, snapshot_rec['uuid'])] yield vdi_uuids finally: - _destroy_snapshots(session, instance, vdi_snapshot_recs) - - -def _vdi_snapshot_vm_base(session, instance, vm_ref): - """Make a snapshot of every non-cinder VDI and return a list - of the new vdi records. - """ - new_vdis = [] - try: - vbd_refs = session.call_xenapi("VM.get_VBDs", vm_ref) - for vbd_ref in vbd_refs: - oc = session.call_xenapi("VBD.get_other_config", vbd_ref) - if 'osvol' not in oc: - # This volume is not a nova/cinder volume - vdi_ref = session.call_xenapi("VBD.get_VDI", vbd_ref) - snapshot_ref = session.call_xenapi("VDI.snapshot", vdi_ref, - {}) - new_vdis.append(session.call_xenapi("VDI.get_record", - snapshot_ref)) - - except session.XenAPI.Failure: - LOG.exception(_("Failed to snapshot VDI"), instance=instance) - raise - finally: - return new_vdis - - -def _destroy_snapshots(session, instance, vdi_snapshot_recs): - vdi_refs = [session.call_xenapi("VDI.get_by_uuid", vdi_rec['uuid']) - for vdi_rec in vdi_snapshot_recs] - safe_destroy_vdis(session, vdi_refs) + safe_destroy_vdis(session, [snapshot_ref]) def get_sr_path(session): |
