protected override void Run() { // the network lock and the connection.expectDisruption will be cleared in clean() new_bonds = new List <NewBond>(); network = null; Connection.ExpectDisruption = true; int inc = 100 / (Connection.Cache.HostCount * 3 + 1); string network_ref = CreateNetwork(0, inc); try { network = Connection.WaitForCache(new XenRef <XenAPI.Network>(network_ref)); network.Locked = true; XenAPI.Network.remove_from_other_config(Session, network_ref, XenAPI.Network.CREATE_IN_PROGRESS); int lo = inc; foreach (Host host in GetHostsMasterLast()) { List <PIF> pifs = PIFs[host].FindAll(x => x.physical).ToList(); List <XenRef <PIF> > pif_refs = new List <XenRef <PIF> >(); foreach (PIF pif in pifs) { pif_refs.Add(new XenRef <PIF>(pif.opaque_ref)); } log.DebugFormat("Creating bond on {0} with {1} PIFs...", Helpers.GetName(host), pifs.Count); Dictionary <string, string> bondProperties = new Dictionary <string, string>(); if (bondMode == bond_mode.lacp) { bondProperties.Add("hashing_algorithm", Bond.HashingAlgoritmToString(hashingAlgoritm)); } RelatedTask = tampaOrGreater ? Bond.async_create(Session, network_ref, pif_refs, "", bondMode, bondProperties) : bostonOrGreater? Bond.async_create(Session, network_ref, pif_refs, "", bondMode) : Bond.async_create(Session, network_ref, pif_refs, ""); PollToCompletion(lo, lo + inc); lo += inc; log.DebugFormat("Creating bond on {0} done: bond is {1}.", Helpers.GetName(host), Result); Bond new_bond = Connection.WaitForCache(new XenRef <Bond>(Result)); if (new_bond == null) { throw new Failure(Failure.INTERNAL_ERROR, "Bond didn't appear in our cache!"); } PIF new_master = Connection.Resolve(new_bond.master); if (new_master == null) { throw new Failure(Failure.INTERNAL_ERROR, "Bond master didn't appear in our cache!"); } new_bonds.Add(new NewBond(new_bond, new_master, pifs)); new_bond.Locked = true; new_master.Locked = true; } foreach (NewBond new_bond in new_bonds) { lo += inc; ReconfigureManagementInterfaces(new_bond.slaves, new_bond.master, lo); } foreach (NewBond new_bond in new_bonds) { lo += inc; if (!bostonOrGreater) { NetworkingActionHelpers.Plug(this, new_bond.master, lo); } } } catch (Exception) { foreach (NewBond new_bond in new_bonds) { RevertManagementInterfaces(new_bond); DestroyBond(new_bond.bond); } DestroyNetwork(network_ref); throw; } Description = string.Format(Messages.ACTION_CREATE_BOND_DONE, name_label); }
protected override void Run() { Connection.ExpectDisruption = true; List <VIF> unplugged_vifs = new List <VIF>(); string old_network_name = Network == null ? "" : Network.Name; Exception e = null; if (!bostonOrGreater) { if (Network != null && NewNetworkName != null) { // Unplug all active VIFs, because we can't fiddle with the PIFs on the network while the // VIFs are active (xapi won't let us). foreach (VIF vif in Connection.ResolveAll(Network.VIFs)) { if (vif.currently_attached) { log.DebugFormat("Unplugging VIF {0} from network {1}...", vif.uuid, old_network_name); VIF.unplug(Session, vif.opaque_ref); unplugged_vifs.Add(vif); log.DebugFormat("VIF {0} unplugged from network {1}.", vif.uuid, old_network_name); } } } } BestEffort(ref e, ReconfigureManagementInterfaces); if (e != null) { throw e; } PercentComplete = 50; int inc = 40 / (Bonds.Count + Masters.Count + Slaves.Count); int lo = PercentComplete; foreach (Bond bond in Bonds) { Bond bond1 = bond; int lo1 = lo; BestEffort(ref e, delegate() { RelatedTask = Bond.async_destroy(Session, bond1.opaque_ref); }); PollToCompletion(lo1, lo1 + inc); lo += inc; } foreach (PIF master in Secondaries) { if (!bostonOrGreater) { ReconfigureSecondaryManagement(master, PercentComplete + inc); } PercentComplete += inc; } if (!bostonOrGreater) { foreach (PIF pif in Slaves) { NetworkingActionHelpers.Plug(this, pif, PercentComplete + inc); } } if (Network != null) { if (NewNetworkName == null) { // We can delete the whole network. log.DebugFormat("Destroying network {0} ({1})...", old_network_name, Network.uuid); BestEffort(ref e, delegate() { XenAPI.Network.destroy(Session, Network.opaque_ref); log.DebugFormat("Network {0} ({1}) destroyed.", old_network_name, Network.uuid); }); } else { // Rename the network, so that the VIFs still have somewhere to live. log.DebugFormat("Renaming network {0} ({1}) to {2}...", old_network_name, Network.uuid, NewNetworkName); XenAPI.Network n = (XenAPI.Network)Network.Clone(); n.name_label = NewNetworkName; BestEffort(ref e, delegate() { n.SaveChanges(Session); log.DebugFormat("Renaming network {0} ({1}) done.", NewNetworkName, n.uuid); }); // Replug all the VIFs that we unplugged before. if (!bostonOrGreater) { foreach (VIF vif in unplugged_vifs) { log.DebugFormat("Replugging VIF {0} into network {1}...", vif.opaque_ref, NewNetworkName); BestEffort(ref e, delegate() { VIF.plug(Session, vif.opaque_ref); log.DebugFormat("Replugging VIF {0} into network {1} done.", vif.opaque_ref, NewNetworkName); }); } } } } if (e != null) { throw e; } Description = string.Format(Messages.ACTION_DESTROY_BOND_DONE, Name); }