protected override void Run()
        {
            Description     = string.Format(Messages.ACTION_MOVING_VDI, Helpers.GetName(vdi));
            PercentComplete = 10;
            log.DebugFormat("Moving VDI '{0}'", Helpers.GetName(vdi));
            RelatedTask = VDI.async_copy(Session, vdi.opaque_ref, SR.opaque_ref);
            PollToCompletion(PercentComplete, 60);

            VDI newVdi = Connection.WaitForCache(new XenRef <VDI>(Result));

            // if the original is a suspend VDI, link the suspended VM to the new VDI
            if (vdi.type == vdi_type.suspend)
            {
                var suspendedVm = (from vm in Connection.Cache.VMs
                                   let suspendVdi = Connection.Resolve(vm.suspend_VDI)
                                                    where suspendVdi != null && suspendVdi.uuid == vdi.uuid
                                                    select vm).FirstOrDefault();
                if (suspendedVm != null)
                {
                    VM.set_suspend_VDI(Session, suspendedVm.opaque_ref, newVdi.opaque_ref);
                }
            }
            PercentComplete = 60;

            var newVbds = new List <VBD>();

            foreach (var vbdRef in vdi.VBDs)
            {
                var oldVbd = Connection.Resolve(vbdRef);
                if (oldVbd == null)
                {
                    continue;
                }

                var newVbd = new VBD
                {
                    userdevice   = oldVbd.userdevice,
                    bootable     = oldVbd.bootable,
                    mode         = oldVbd.mode,
                    type         = oldVbd.type,
                    unpluggable  = oldVbd.unpluggable,
                    other_config = oldVbd.other_config,
                    VDI          = new XenRef <VDI>(newVdi.opaque_ref),
                    VM           = new XenRef <VM>(oldVbd.VM)
                };
                newVbd.SetIsOwner(oldVbd.GetIsOwner());
                newVbds.Add(newVbd);

                try
                {
                    if (oldVbd.currently_attached && oldVbd.allowed_operations.Contains(vbd_operations.unplug))
                    {
                        VBD.unplug(Session, vbdRef);
                    }
                }
                finally
                {
                    if (!oldVbd.currently_attached)
                    {
                        VBD.destroy(Session, vbdRef);
                    }
                }
            }

            PercentComplete = 80;

            VDI.destroy(Session, vdi.opaque_ref);

            foreach (var newVbd in newVbds)
            {
                Connection.WaitForCache(VBD.create(Session, newVbd));
            }

            PercentComplete = 100;
            Description     = Messages.MOVED;
            log.DebugFormat("Moved VDI '{0}'", Helpers.GetName(vdi));
        }
Пример #2
0
        protected override void Run()
        {
            Description = Messages.ACTION_PREPARING;

            // move the progress bar above 0, it's more reassuring to see than a blank bar as we copy the first disk
            PercentComplete += 10;
            int halfstep = 90 / (VM.VBDs.Count * 2);

            var exceptions = new List <Exception>();

            foreach (var vbdRef in VM.VBDs)
            {
                if (Cancelling)
                {
                    throw new CancelledException();
                }

                var oldVBD = Connection.Resolve(vbdRef);

                if (oldVBD == null || !oldVBD.GetIsOwner())
                {
                    continue;
                }

                if (_storageMapping == null ||
                    !_storageMapping.TryGetValue(oldVBD.VDI.opaque_ref, out SR sr) || sr == null)
                {
                    continue;
                }

                var curVdi = Connection.Resolve(oldVBD.VDI);
                if (curVdi == null)
                {
                    continue;
                }

                if (curVdi.SR.opaque_ref == sr.opaque_ref)
                {
                    continue;
                }

                Description = string.Format(Messages.ACTION_MOVING_VDI_TO_SR,
                                            Helpers.GetName(curVdi), Helpers.GetName(sr));

                RelatedTask = VDI.async_copy(Session, oldVBD.VDI.opaque_ref, sr.opaque_ref);
                PollToCompletion(PercentComplete, PercentComplete + halfstep);
                var newVDI = Connection.WaitForCache(new XenRef <VDI>(Result));

                var newVBD = new VBD
                {
                    userdevice   = oldVBD.userdevice,
                    bootable     = oldVBD.bootable,
                    mode         = oldVBD.mode,
                    type         = oldVBD.type,
                    unpluggable  = oldVBD.unpluggable,
                    other_config = oldVBD.other_config,
                    VDI          = new XenRef <VDI>(newVDI.opaque_ref),
                    VM           = new XenRef <VM>(VM.opaque_ref)
                };
                newVBD.SetIsOwner(oldVBD.GetIsOwner());

                try
                {
                    VDI.destroy(Session, oldVBD.VDI.opaque_ref);
                }
                catch (Exception e)
                {
                    log.ErrorFormat("Failed to destroy old VDI {0}", oldVBD.VDI.opaque_ref);
                    exceptions.Add(e);
                }

                Connection.WaitForCache(VBD.create(Session, newVBD));

                PercentComplete += halfstep;
            }

            if (SR != null)
            {
                VM.set_suspend_SR(Session, VM.opaque_ref, SR.opaque_ref);
            }

            if (exceptions.Count > 0)
            {
                throw new Exception(Messages.ACTION_VM_MOVING_VDI_DESTROY_FAILURE);
            }

            Description = Messages.MOVED;
        }