CA-216935: Fixed a bug that can occur when multiple pools are being updated with the same update and one of the prechecks happen before the other pool is finished applying the update

The PatchPrechecksOnMultipleHostsInAPoolPlanAction did not filter the patchmappings by masterhost, so with some probability, it could choose the wrong mapping (pool_patch object for the same update, but in different pool). This bug is being fixed in this commit, other changes only renamed (for more consistent naming) a class and removed an unused field.

Signed-off-by: Gabor Apati-Nagy <gabor.apati-nagy@citrix.com>
This commit is contained in:
Gabor Apati-Nagy 2016-08-02 14:30:20 +01:00
parent 893275fb2f
commit 48ef276c06
7 changed files with 18 additions and 19 deletions

View File

@ -155,9 +155,9 @@ namespace XenAdmin.Wizards.PatchingWizard
var hostsToApply = us.Where(u => u.Value.Contains(patch)).Select(u => u.Key).ToList();
hostsToApply.Sort();
planActions.Add(new DownloadPatchPlanAction(master.Connection, patch, patchMappings, AllDownloadedPatches));
planActions.Add(new DownloadPatchPlanAction(master.Connection, patch, AllDownloadedPatches));
planActions.Add(new UploadPatchToMasterPlanAction(master.Connection, patch, patchMappings, AllDownloadedPatches));
planActions.Add(new PatchPrechecksOnMultipleHostsPlanAction(master.Connection, patch, hostsToApply, patchMappings));
planActions.Add(new PatchPrechecksOnMultipleHostsInAPoolPlanAction(master.Connection, patch, hostsToApply, patchMappings));
foreach (var host in hostsToApply)
{

View File

@ -38,14 +38,14 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
public class ApplyXenServerPatchPlanAction : PlanActionWithSession
{
private readonly XenRef<Host> host;
private readonly Host host;
private readonly XenServerPatch xenServerPatch;
private readonly List<PoolPatchMapping> mappings;
public ApplyXenServerPatchPlanAction(Host host, XenServerPatch xenServerPatch, List<PoolPatchMapping> mappings)
: base(host.Connection, string.Format(Messages.UPDATES_WIZARD_APPLYING_UPDATE, xenServerPatch.Name, host.Name))
{
this.host = new XenRef<Host>(host);
this.host = host;
this.xenServerPatch = xenServerPatch;
this.mappings = mappings;
}
@ -53,7 +53,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
protected override void RunWithSession(ref Session session)
{
var mapping = mappings.Find(m => m.XenServerPatch.Uuid == xenServerPatch.Uuid);
var mapping = mappings.Find(m => m.XenServerPatch.Uuid == xenServerPatch.Uuid && m.MasterHost == Helpers.GetMaster(host.Connection));
if (mapping != null && mapping.Pool_patch != null)
{
var patchRef = mapping.Pool_patch;

View File

@ -43,15 +43,13 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
class DownloadPatchPlanAction : PlanActionWithSession
{
private readonly XenServerPatch patch;
private readonly List<PoolPatchMapping> mappings;
private Dictionary<XenServerPatch, string> AllDownloadedPatches = new Dictionary<XenServerPatch, string>();
private string tempFileName = null;
public DownloadPatchPlanAction(IXenConnection connection, XenServerPatch patch, List<PoolPatchMapping> mappings, Dictionary<XenServerPatch, string> allDownloadedPatches)
public DownloadPatchPlanAction(IXenConnection connection, XenServerPatch patch, Dictionary<XenServerPatch, string> allDownloadedPatches)
: base(connection, string.Format(Messages.PATCHINGWIZARD_DOWNLOADUPDATE_ACTION_TITLE_WAITING, patch.Name))
{
this.patch = patch;
this.mappings = mappings;
this.AllDownloadedPatches = allDownloadedPatches;
}

View File

@ -37,17 +37,18 @@ using XenAPI;
using System.Linq;
using System.IO;
using XenAdmin.Network;
using XenAdmin.Diagnostics.Checks;
using XenAdmin.Diagnostics.Checks;
using System.Diagnostics;
namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
class PatchPrechecksOnMultipleHostsPlanAction : PlanActionWithSession
class PatchPrechecksOnMultipleHostsInAPoolPlanAction : PlanActionWithSession
{
private readonly XenServerPatch patch;
private readonly List<PoolPatchMapping> mappings;
private List<Host> hosts = null;
public PatchPrechecksOnMultipleHostsPlanAction(IXenConnection connection, XenServerPatch patch, List<Host> hosts, List<PoolPatchMapping> mappings)
public PatchPrechecksOnMultipleHostsInAPoolPlanAction(IXenConnection connection, XenServerPatch patch, List<Host> hosts, List<PoolPatchMapping> mappings)
: base(connection, string.Format("Precheck for {0} in {1}...", patch.Name, connection.Name))
{
this.patch = patch;
@ -57,7 +58,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
protected override void RunWithSession(ref Session session)
{
var mapping = mappings.Find(m => m.XenServerPatch == patch);
var mapping = mappings.Find(m => m.XenServerPatch == patch && m.MasterHost == Helpers.GetMaster(Connection));
if (mapping != null && mapping.Pool_patch != null)
{
foreach (var host in hosts)

View File

@ -12,7 +12,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
public XenServerPatch XenServerPatch { get; set; }
public Pool_patch Pool_patch { get; set; }
public Host Host { get; set; }
public Host MasterHost { get; set; }
public override bool Equals(object obj)
{
@ -24,12 +24,12 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
return
this.XenServerPatch == that.XenServerPatch
&& this.Pool_patch == that.Pool_patch
&& this.Host == that.Host;
&& this.MasterHost == that.MasterHost;
}
public override int GetHashCode()
{
return XenServerPatch.GetHashCode() ^ Pool_patch.GetHashCode() ^ Host.GetHashCode();
return XenServerPatch.GetHashCode() ^ Pool_patch.GetHashCode() ^ MasterHost.GetHashCode();
}
}
}

View File

@ -57,7 +57,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
{
Pool_patch poolPatch = null;
var mapping = patchMappings.FirstOrDefault(pm => pm.Host == master && pm.XenServerPatch == patch);
var mapping = patchMappings.FirstOrDefault(pm => pm.MasterHost == master && pm.XenServerPatch == patch);
if (mapping != null || mapping.Pool_patch != null && mapping.Pool_patch.opaque_ref != null)
{

View File

@ -64,7 +64,7 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
var poolPatches = new List<Pool_patch>(session.Connection.Cache.Pool_patches);
var conn = session.Connection;
var existingMapping = mappings.Find(m => m.Host == Helpers.GetMaster(conn) && m.Pool_patch != null && m.XenServerPatch == patch);
var existingMapping = mappings.Find(m => m.MasterHost == Helpers.GetMaster(conn) && m.Pool_patch != null && m.XenServerPatch == patch);
if (existingMapping == null
|| !poolPatches.Any(p => string.Equals(p.uuid, existingMapping.Pool_patch.uuid, StringComparison.OrdinalIgnoreCase)))
{
@ -92,12 +92,12 @@ namespace XenAdmin.Wizards.PatchingWizard.PlanActions
var newMapping = new PoolPatchMapping()
{
Host = Helpers.GetMaster(session.Connection),
MasterHost = Helpers.GetMaster(session.Connection),
XenServerPatch = patch,
Pool_patch = poolPatch
};
if (!mappings.Any(m => m.Host == newMapping.Host && m.Pool_patch == newMapping.Pool_patch && m.XenServerPatch == patch))
if (!mappings.Any(m => m.MasterHost == newMapping.MasterHost && m.Pool_patch == newMapping.Pool_patch && m.XenServerPatch == patch))
mappings.Add(newMapping);
}
catch (Exception ex)