Skip to content

Commit

Permalink
CA-383483: Rewrote the migration logic to fix regression (#3241)
Browse files Browse the repository at this point in the history
* Simplified the class name by renaming CrossPoolMigrateCanMigrateFilter to CrossPoolMigrateFilter.
* CA-383483: Rewrote (again) the migration logic because the fix to CA-294370 regressed migration from local to local storage.
Also, minor refactoring to some methods for more efficient calculations.

Signed-off-by: Konstantina Chremmou <[email protected]>
  • Loading branch information
kc284 authored Nov 14, 2023
1 parent f92e988 commit 3b773c7
Show file tree
Hide file tree
Showing 5 changed files with 159 additions and 132 deletions.
14 changes: 8 additions & 6 deletions XenAdmin/Commands/CrossPoolMigrateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,16 @@ public static bool CanRun(VM vm, Host preselectedHost, out string failureReason,
return false;
}

var vms = new List<VM> {vm};
if (preselectedHost != null)
{
var vms = new List<VM> {vm};

if (preselectedHost != null && new ResidentHostIsSameAsSelectionFilter(preselectedHost, vms).FailureFound(out failureReason))
return false;
if (new ResidentHostIsSameAsSelectionFilter(preselectedHost, vms).FailureFound(out failureReason))
return false;

if (preselectedHost != null && new CrossPoolMigrateCanMigrateFilter(preselectedHost, new List<VM> {vm},
WizardMode.Migrate, cache).FailureFound(out failureReason))
return false;
if (new CrossPoolMigrateFilter(preselectedHost, vms, WizardMode.Migrate, cache).FailureFound(out failureReason))
return false;
}

failureReason = string.Empty;
return true;
Expand Down
62 changes: 39 additions & 23 deletions XenAdmin/Commands/VMOperationHostCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ internal class VMOperationHostCommand : VMOperationCommand
{
public delegate Host GetHostForVM(VM vm);

private readonly static log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private static readonly log4net.ILog log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
private readonly Dictionary<VM, string> _cantBootReasons = new Dictionary<VM, string>();
private readonly bool _noneCanBoot = true;
private readonly string _text;
Expand All @@ -65,9 +65,7 @@ public VMOperationHostCommand(IMainWindow mainWindow, IEnumerable<SelectedItem>
{
VM vm = (VM)item.XenObject;

string reason = GetVmCannotBootOnHostReason(vm, GetHost(vm), session, operation);

if (reason == null)
if (VmCanBootOnHost(vm, GetHost(vm), session, operation, out var reason))
_noneCanBoot = false;
else
_cantBootReasons[vm] = reason;
Expand Down Expand Up @@ -107,26 +105,38 @@ protected override bool CanRun(VM vm)
return vm != null && !_cantBootReasons.ContainsKey(vm);
}

internal static string GetVmCannotBootOnHostReason(VM vm, Host host, Session session, vm_operations operation)
internal static bool VmCanBootOnHost(VM vm, Host host, Session session, vm_operations operation, out string cannotBootReason)
{
Host residentHost = vm.Connection.Resolve(vm.resident_on);

if (host == null)
return Messages.NO_HOME_SERVER;
{
cannotBootReason = Messages.NO_HOME_SERVER;
return false;
}

if (vm.power_state == vm_power_state.Running && residentHost != null
&& Helpers.ProductVersionCompare(Helpers.HostProductVersion(host), Helpers.HostProductVersion(residentHost)) < 0)
if (vm.power_state == vm_power_state.Running)
{
// This will be a migrate menu if powerstate if running
return Messages.OLDER_THAN_CURRENT_SERVER;
var residentHost = vm.Connection.Resolve(vm.resident_on);

if (residentHost != null)
{
if (host.opaque_ref == residentHost.opaque_ref)
{
cannotBootReason = Messages.HOST_MENU_CURRENT_SERVER;
return false;
}

if (Helpers.ProductVersionCompare(Helpers.HostProductVersion(host), Helpers.HostProductVersion(residentHost)) < 0)
{
cannotBootReason = Messages.OLDER_THAN_CURRENT_SERVER;
return false;
}
}
}

if (vm.power_state == vm_power_state.Running && residentHost != null && host.opaque_ref == residentHost.opaque_ref)
return Messages.HOST_MENU_CURRENT_SERVER;

if ((operation == vm_operations.pool_migrate || operation == vm_operations.resume_on) && VmCpuIncompatibleWithHost(host, vm))
{
return FriendlyErrorNames.VM_INCOMPATIBLE_WITH_THIS_HOST;
cannotBootReason = FriendlyErrorNames.VM_INCOMPATIBLE_WITH_THIS_HOST;
return false;
}

try
Expand All @@ -137,20 +147,27 @@ internal static string GetVmCannotBootOnHostReason(VM vm, Host host, Session ses
{
if (f.ErrorDescription.Count > 2 && f.ErrorDescription[0] == Failure.VM_REQUIRES_SR)
{
SR sr = host.Connection.Resolve((new XenRef<SR>(f.ErrorDescription[2])));
SR sr = host.Connection.Resolve(new XenRef<SR>(f.ErrorDescription[2]));

if (sr != null && sr.content_type == SR.Content_Type_ISO)
return Messages.MIGRATE_PLEASE_EJECT_YOUR_CD;
{
cannotBootReason = Messages.MIGRATE_PLEASE_EJECT_YOUR_CD;
return false;
}
}
return f.ShortMessage;

cannotBootReason = f.ShortMessage;
return false;
}
catch (Exception e)
{
log.ErrorFormat("There was an error calling assert_can_boot_here on host {0}: {1}", host.Name(), e.Message);
return Messages.HOST_MENU_UNKNOWN_ERROR;
cannotBootReason = Messages.HOST_MENU_UNKNOWN_ERROR;
return false;
}

return null;
cannotBootReason = null;
return true;
}

protected override CommandErrorDialog GetErrorDialogCore(IDictionary<IXenObject, string> cantRunReasons)
Expand All @@ -160,8 +177,7 @@ protected override CommandErrorDialog GetErrorDialogCore(IDictionary<IXenObject,

protected override string GetCantRunReasonCore(IXenObject item)
{
VM vm = item as VM;
if (vm != null && _cantBootReasons.ContainsKey(vm))
if (item is VM vm && _cantBootReasons.ContainsKey(vm))
return _cantBootReasons[vm];

return base.GetCantRunReasonCore(item);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ protected override DelayLoadingOptionComboBoxItem CreateDelayLoadingOptionComboB
var filters = new List<ReasoningFilter>
{
new ResidentHostIsSameAsSelectionFilter(xenItem, selectedVMs),
new CrossPoolMigrateCanMigrateFilter(xenItem, selectedVMs, wizardMode, migrateFilterCache)
new CrossPoolMigrateFilter(xenItem, selectedVMs, wizardMode, migrateFilterCache)
};
return new DelayLoadingOptionComboBoxItem(xenItem, filters);
}
Expand All @@ -139,7 +139,7 @@ protected override List<ReasoningFilter> CreateTargetServerFilterList(IXenObject
vmList.Add(selectedVMs.Find(vm => vm.opaque_ref == opaqueRef));

filters.Add(new ResidentHostIsSameAsSelectionFilter(xenObject, vmList));
filters.Add(new CrossPoolMigrateCanMigrateFilter(xenObject, vmList, wizardMode, migrateFilterCache));
filters.Add(new CrossPoolMigrateFilter(xenObject, vmList, wizardMode, migrateFilterCache));
}

return filters;
Expand Down
Loading

0 comments on commit 3b773c7

Please sign in to comment.