Exemple #1
0
        internal static void FixIPAddress(AmServerName nodeName, DatabaseAvailabilityGroup dag, IEnumerable <AmServerName> startedMailboxServers, ITaskOutputHelper output)
        {
            output.WriteProgressSimple(Strings.DagTaskFixingUpIpResources);
            MultiValuedProperty <IPAddress> databaseAvailabilityGroupIpv4Addresses = dag.DatabaseAvailabilityGroupIpv4Addresses;

            IPAddress[] array = new IPAddress[0];
            if (databaseAvailabilityGroupIpv4Addresses.Count > 0)
            {
                array = databaseAvailabilityGroupIpv4Addresses.ToArray();
            }
            string[] value = (from addr in array
                              select addr.ToString()).ToArray <string>();
            output.AppendLogMessage("Got the following IP addresses for the DAG (blank means DHCP):{0}", new object[]
            {
                string.Join(",", value)
            });
            using (AmCluster amCluster = AmCluster.OpenByNames(startedMailboxServers))
            {
                if (amCluster.CnoName != string.Empty)
                {
                    using (IAmClusterGroup amClusterGroup = amCluster.FindCoreClusterGroup())
                    {
                        using (IAmClusterResource amClusterResource = amClusterGroup.FindResourceByTypeName("Network Name"))
                        {
                            LocalizedString value2 = AmClusterResourceHelper.FixUpIpAddressesForNetName(output, amCluster, (AmClusterGroup)amClusterGroup, (AmClusterResource)amClusterResource, array);
                            output.WriteProgressSimple(Strings.DagTaskFixedUpIpResources(value2));
                            DagTaskHelper.LogCnoState(output, dag.Name, amClusterResource);
                        }
                    }
                }
            }
        }
Exemple #2
0
 internal static bool IsClusterUp(DatabaseAvailabilityGroup dag, HaTaskOutputHelper output)
 {
     try
     {
         using (AmCluster amCluster = AmCluster.OpenDagClus(dag))
         {
             using (IAmClusterGroup amClusterGroup = amCluster.FindCoreClusterGroup())
             {
                 IEnumerable <AmServerName> source = amCluster.EnumerateNodeNames();
                 output.AppendLogMessage("Cluster is up, there are {0} nodes in the cluster, group owner:{1}", new object[]
                 {
                     source.Count <AmServerName>(),
                     amClusterGroup.OwnerNode.NetbiosName
                 });
             }
         }
     }
     catch (AmCoreGroupRegNotFound amCoreGroupRegNotFound)
     {
         output.AppendLogMessage("Cluster is down, got AmCoreGroupRegNotFound:{0} when trying to open the cluster", new object[]
         {
             amCoreGroupRegNotFound.ToString()
         });
         return(false);
     }
     return(true);
 }
Exemple #3
0
        internal static void EvictStoppedNodes(DatabaseAvailabilityGroup dag, IEnumerable <Server> stoppedServers, HaTaskOutputHelper output)
        {
            if (dag == null)
            {
                throw new ArgumentNullException("dag");
            }
            if (stoppedServers == null)
            {
                throw new ArgumentNullException("stoppedServers");
            }
            if (output == null)
            {
                throw new ArgumentNullException("output");
            }
            string        error      = null;
            List <string> list       = new List <string>(1);
            string        verboseLog = null;

            using (AmCluster amCluster = AmCluster.OpenDagClus(dag))
            {
                using (IAmClusterGroup amClusterGroup = amCluster.FindCoreClusterGroup())
                {
                    output.AppendLogMessage("EvictStoppedNodes has been called. Dumping current cluster state.", new object[0]);
                    try
                    {
                        using (DumpClusterTopology dumpClusterTopology = new DumpClusterTopology(amCluster, output))
                        {
                            dumpClusterTopology.Dump();
                        }
                    }
                    catch (ClusterException ex)
                    {
                        output.AppendLogMessage("DumpClusterTopology( {0} ) failed with exception = {1}. This is OK.", new object[]
                        {
                            dag.Name,
                            ex.Message
                        });
                        output.AppendLogMessage("Ignoring previous error, as it is acceptable if the cluster does not exist yet.", new object[0]);
                    }
                    IEnumerable <AmServerName> source = amCluster.EnumerateNodeNames();
                    AmServerName ownerNode            = amClusterGroup.OwnerNode;
                    int          num = stoppedServers.Count <Server>();
                    foreach (Server server in stoppedServers)
                    {
                        AmServerName amServerName = new AmServerName(server);
                        if (source.Contains(amServerName))
                        {
                            output.AppendLogMessage("Server '{0}' is still a node in the cluster, and will have to be evicted.", new object[]
                            {
                                amServerName.NetbiosName
                            });
                            try
                            {
                                try
                                {
                                    output.WriteProgressIncrementalSimple(Strings.ProgressForceCleanupNode(server.Name), 20 / num);
                                    output.AppendLogMessage("Running the eviction operation by issuing an RPC to the replay service on '{0}'...", new object[]
                                    {
                                        ownerNode.Fqdn
                                    });
                                    ReplayRpcClientWrapper.RunEvictNodeFromCluster(ownerNode, amServerName, out verboseLog);
                                }
                                finally
                                {
                                    DagTaskHelper.LogRemoteVerboseLog(output, ownerNode.Fqdn, verboseLog);
                                }
                            }
                            catch (DagTaskOperationFailedException ex2)
                            {
                                output.AppendLogMessage("An exception was thrown! ex={0}", new object[]
                                {
                                    ex2.Message
                                });
                                Exception ex3;
                                if (ex2.TryGetInnerExceptionOfType(out ex3))
                                {
                                    output.AppendLogMessage("Ignore it. It was AmClusterEvictWithoutCleanupException, which is acceptable. It could be completed with cluster node /forcecleanp, but that isn't necessary.", new object[0]);
                                }
                                else if (ex2.TryGetInnerExceptionOfType(out ex3))
                                {
                                    output.AppendLogMessage("That exception is fine. It means that the server has already been evicted from the cluster.", new object[0]);
                                }
                                else
                                {
                                    error = ex2.Message;
                                    output.WriteWarning(Strings.FailedToEvictNode(server.Name, dag.Name, error));
                                    list.Add(server.Name);
                                }
                            }
                            catch (LocalizedException ex4)
                            {
                                error = ex4.Message;
                                output.WriteWarning(Strings.FailedToEvictNode(server.Name, dag.Name, error));
                                list.Add(server.Name);
                            }
                        }
                        else
                        {
                            output.AppendLogMessage("Server '{0}' is not in the cluster anymore. It must have already been evicted.", new object[]
                            {
                                amServerName.NetbiosName
                            });
                        }
                    }
                }
            }
            if (list.Count != 0)
            {
                output.WriteErrorSimple(new FailedToEvictNodeException(string.Join(",", list.ToArray <string>()), dag.Name, error));
            }
        }
        protected override void WriteResult(IConfigurable dataObject)
        {
            TaskLogger.LogEnter(new object[]
            {
                dataObject.Identity,
                dataObject
            });
            DatabaseAvailabilityGroup databaseAvailabilityGroup = (DatabaseAvailabilityGroup)dataObject;

            if (this.Status && !databaseAvailabilityGroup.IsDagEmpty())
            {
                List <ADObjectId> list      = new List <ADObjectId>(8);
                List <ADObjectId> list2     = new List <ADObjectId>(8);
                AmCluster         amCluster = null;
                try
                {
                    amCluster = AmCluster.OpenDagClus(databaseAvailabilityGroup);
                }
                catch (ClusterException exception)
                {
                    base.WriteError(exception, ErrorCategory.InvalidArgument, null);
                }
                if (amCluster != null)
                {
                    using (amCluster)
                    {
                        foreach (IAmClusterNode amClusterNode in amCluster.EnumerateNodes())
                        {
                            using (amClusterNode)
                            {
                                AmNodeState state = amClusterNode.GetState(false);
                                if (AmClusterNode.IsNodeUp(state))
                                {
                                    ADObjectId adobjectId = DagTaskHelper.FindServerAdObjectIdInDag(databaseAvailabilityGroup, amClusterNode.Name);
                                    if (adobjectId != null)
                                    {
                                        list.Add(adobjectId);
                                        if (state == AmNodeState.Paused)
                                        {
                                            list2.Add(adobjectId);
                                        }
                                    }
                                    else
                                    {
                                        this.WriteWarning(Strings.WarningClusterNodeNotFoundInDag(amClusterNode.Name.Fqdn, databaseAvailabilityGroup.Name));
                                    }
                                }
                            }
                        }
                        databaseAvailabilityGroup.OperationalServers   = list.ToArray();
                        databaseAvailabilityGroup.ServersInMaintenance = list2.ToArray();
                        DagNetworkConfiguration dagNetworkConfig = DagNetworkRpc.GetDagNetworkConfig(databaseAvailabilityGroup);
                        databaseAvailabilityGroup.ReplicationPort = dagNetworkConfig.ReplicationPort;
                        foreach (DatabaseAvailabilityGroupNetwork databaseAvailabilityGroupNetwork in dagNetworkConfig.Networks)
                        {
                            databaseAvailabilityGroup.NetworkNames.Add(databaseAvailabilityGroupNetwork.Name);
                        }
                        if (DagHelper.IsQuorumTypeFileShareWitness(amCluster))
                        {
                            IAmClusterGroup amClusterGroup = amCluster.FindCoreClusterGroup();
                            if (amClusterGroup == null)
                            {
                                databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.InvalidConfiguration);
                                this.WriteWarning(Strings.WarningClusterGroupNotFormed(databaseAvailabilityGroup.Name));
                                goto IL_306;
                            }
                            using (amClusterGroup)
                            {
                                IEnumerable <AmClusterResource> enumerable = null;
                                try
                                {
                                    enumerable = amClusterGroup.EnumerateResourcesOfType("File Share Witness");
                                    AmClusterResource amClusterResource = enumerable.ElementAtOrDefault(0);
                                    if (amClusterResource == null)
                                    {
                                        databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.InvalidConfiguration);
                                        this.WriteWarning(Strings.WarningFswNotFound(databaseAvailabilityGroup.Name));
                                    }
                                    else if (amClusterResource.GetState() == AmResourceState.Failed)
                                    {
                                        databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.InvalidConfiguration);
                                        this.WriteWarning(Strings.WarningFswFailed(databaseAvailabilityGroup.Name));
                                    }
                                    else
                                    {
                                        string           privateProperty = amClusterResource.GetPrivateProperty <string>("SharePath");
                                        UncFileSharePath a;
                                        if (UncFileSharePath.TryParse(privateProperty, out a))
                                        {
                                            if (a == databaseAvailabilityGroup.FileShareWitness)
                                            {
                                                databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.Primary);
                                            }
                                            else if (a == databaseAvailabilityGroup.AlternateFileShareWitness)
                                            {
                                                databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.Alternate);
                                            }
                                            else
                                            {
                                                databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.InvalidConfiguration);
                                                this.WriteWarning(Strings.WarningFswNotPrimaryOrAlternate(databaseAvailabilityGroup.Name));
                                            }
                                        }
                                        else
                                        {
                                            databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.InvalidConfiguration);
                                            this.WriteWarning(Strings.WarningFswNotValidPath(databaseAvailabilityGroup.Name, privateProperty));
                                        }
                                    }
                                }
                                finally
                                {
                                    if (enumerable != null)
                                    {
                                        foreach (AmClusterResource amClusterResource2 in enumerable)
                                        {
                                            using (amClusterResource2)
                                            {
                                            }
                                        }
                                    }
                                }
                                goto IL_306;
                            }
                        }
                        databaseAvailabilityGroup.WitnessShareInUse = new WitnessShareUsage?(WitnessShareUsage.None);
                        IL_306:;
                    }
                    this.UpdatePam(databaseAvailabilityGroup);
                    try
                    {
                        DeferredFailoverEntry[] serversInDeferredRecovery = DagTaskHelper.GetServersInDeferredRecovery(databaseAvailabilityGroup);
                        databaseAvailabilityGroup.ServersInDeferredRecovery = serversInDeferredRecovery;
                    }
                    catch (AmServerException ex)
                    {
                        this.WriteWarning(Strings.PAMOtherError(ex.Message));
                    }
                }
            }
            base.WriteResult(databaseAvailabilityGroup);
            TaskLogger.LogExit();
        }
        protected override void InternalProcessRecord()
        {
            TaskLogger.LogEnter();
            bool flag = false;

            if ((base.Fields["ReplicationPort"] != null || base.Fields["NetworkCompression"] != null || base.Fields["NetworkEncryption"] != null || base.Fields["ManualDagNetworkConfiguration"] != null || base.Fields["DiscoverNetworks"] != null) && !this.m_dag.IsDagEmpty())
            {
                flag = true;
                this.m_IsObjectChanged = true;
            }
            if (this.DataObject.AllowCrossSiteRpcClientAccess != this.AllowCrossSiteRpcClientAccess)
            {
                if (base.Fields["AllowCrossSiteRpcClientAccess"] != null)
                {
                    this.DataObject.AllowCrossSiteRpcClientAccess = this.AllowCrossSiteRpcClientAccess;
                    this.m_IsObjectChanged = true;
                }
                else
                {
                    this.AllowCrossSiteRpcClientAccess = this.DataObject.AllowCrossSiteRpcClientAccess;
                }
            }
            if (this.m_fsw != null)
            {
                this.m_dag.SetWitnessServer(this.m_fsw.FileShareWitnessShare, this.m_fsw.WitnessDirectory);
                this.m_IsObjectChanged = true;
            }
            if (this.m_afsw != null)
            {
                this.m_dag.SetAlternateWitnessServer(this.m_afsw.FileShareWitnessShare, this.m_afsw.WitnessDirectory);
                this.m_IsObjectChanged = true;
            }
            else if (this.AlternateWitnessServer == null && this.m_alternateWitnessServerParameterSpecified)
            {
                this.m_dag.SetAlternateWitnessServer(null, null);
            }
            base.InternalProcessRecord();
            if (flag && !this.m_dag.IsDagEmpty())
            {
                SetDagNetworkConfigRequest setDagNetworkConfigRequest = new SetDagNetworkConfigRequest();
                if (base.Fields["ReplicationPort"] != null)
                {
                    setDagNetworkConfigRequest.ReplicationPort = this.ReplicationPort;
                }
                setDagNetworkConfigRequest.NetworkCompression            = this.m_dag.NetworkCompression;
                setDagNetworkConfigRequest.NetworkEncryption             = this.m_dag.NetworkEncryption;
                setDagNetworkConfigRequest.ManualDagNetworkConfiguration = this.m_dag.ManualDagNetworkConfiguration;
                if (base.Fields["DiscoverNetworks"] != null)
                {
                    setDagNetworkConfigRequest.DiscoverNetworks = true;
                }
                DagNetworkRpc.SetDagNetworkConfig(this.m_dag, setDagNetworkConfigRequest);
            }
            if (!this.m_dag.IsDagEmpty())
            {
                using (AmCluster amCluster = AmCluster.OpenDagClus(this.m_dag))
                {
                    if (amCluster.CnoName != string.Empty)
                    {
                        using (IAmClusterGroup amClusterGroup = amCluster.FindCoreClusterGroup())
                        {
                            using (IAmClusterResource amClusterResource = amClusterGroup.FindResourceByTypeName("Network Name"))
                            {
                                IPAddress[] dagIpAddressesFromAd = this.GetDagIpAddressesFromAd(this.m_output, this.m_dag);
                                AmClusterResourceHelper.FixUpIpAddressesForNetName(this.m_output, amCluster, (AmClusterGroup)amClusterGroup, (AmClusterResource)amClusterResource, dagIpAddressesFromAd);
                                DagTaskHelper.LogCnoState(this.m_output, this.m_dag.Name, amClusterResource);
                            }
                        }
                    }
                }
                this.UpdateFileShareWitness();
                DagTaskHelper.NotifyServersOfConfigChange(this.m_allServers.Keys);
            }
            TaskLogger.LogExit();
        }
Exemple #6
0
        private List <string> JoinStartedNodes(IEnumerable <Server> serversToStart)
        {
            if (serversToStart == null)
            {
                throw new ArgumentNullException("serversToStart");
            }
            List <string> list = new List <string>(1);

            using (AmCluster amCluster = AmCluster.OpenDagClus(this.m_dag))
            {
                using (IAmClusterGroup amClusterGroup = amCluster.FindCoreClusterGroup())
                {
                    try
                    {
                        using (DumpClusterTopology dumpClusterTopology = new DumpClusterTopology(amCluster, this.m_output))
                        {
                            dumpClusterTopology.Dump();
                        }
                    }
                    catch (ClusterException ex)
                    {
                        this.m_output.AppendLogMessage("DumpClusterTopology( {0} ) failed with exception = {1}. This is OK.", new object[]
                        {
                            this.m_dag.Name,
                            ex.Message
                        });
                        this.m_output.AppendLogMessage("Ignoring previous error, as it is acceptable if the cluster does not exist yet.", new object[0]);
                    }
                    AmServerName ownerNode = amClusterGroup.OwnerNode;
                    DatabaseTasksHelper.CheckReplayServiceRunningOnNode(ownerNode, new Task.TaskErrorLoggingDelegate(base.WriteError));
                    if (amCluster.CnoName != string.Empty)
                    {
                        using (IAmClusterResource amClusterResource = amClusterGroup.FindResourceByTypeName("Network Name"))
                        {
                            DagTaskHelper.LogCnoState(this.m_output, this.m_dag.Name, amClusterResource);
                        }
                    }
                    foreach (Server server in serversToStart)
                    {
                        bool         flag         = false;
                        AmServerName amServerName = new AmServerName(server);
                        try
                        {
                            if (amCluster.IsEvictedBasedOnMemberShip(amServerName))
                            {
                                this.m_output.WriteProgressSimple(Strings.ProgressJoinNode(amServerName.NetbiosName));
                                this.m_output.AppendLogMessage("ForceCleanup the Node {0}", new object[]
                                {
                                    server.Name
                                });
                                DatabaseAvailabilityGroupAction.ForceCleanupOneNodeLocally(this.m_dag.Name, server, TimeSpan.FromSeconds(15.0), this.m_output);
                                this.m_output.AppendLogMessage("Join the node {0} to the cluster", new object[]
                                {
                                    server.Name
                                });
                                DatabaseAvailabilityGroupAction.JoinOneNode(ownerNode, amServerName, this.m_output);
                                flag = true;
                            }
                            else
                            {
                                this.m_output.AppendLogMessage("{0} is not evicted", new object[]
                                {
                                    amServerName
                                });
                            }
                            if (!AmCluster.IsRunning(amServerName))
                            {
                                try
                                {
                                    this.m_output.AppendLogMessage("{0} cluster service is not running, try to start the service", new object[]
                                    {
                                        server.Name
                                    });
                                    this.m_output.WriteProgressSimple(Strings.ProgressStartClussvc(amServerName.NetbiosName));
                                    DatabaseAvailabilityGroupAction.TryStartClussvcOnNode(amServerName, this.m_output);
                                }
                                catch (InvalidOperationException)
                                {
                                    this.m_output.AppendLogMessage("Got an invalidOperationException, most likely the node {0} is force cleanedup", new object[]
                                    {
                                        amServerName
                                    });
                                    if (flag)
                                    {
                                        this.m_output.AppendLogMessage("STRANGE! we joined {0} but cannot start the service!", new object[]
                                        {
                                            amServerName
                                        });
                                        throw;
                                    }
                                    this.m_output.WriteProgressSimple(Strings.ProgressJoinNode(amServerName.NetbiosName));
                                    DatabaseAvailabilityGroupAction.JoinForceCleanupNode(ownerNode, amServerName, this.m_output);
                                    flag = true;
                                }
                            }
                            if (flag)
                            {
                                ICollection <AmServerName> startedMailboxServers = from server1 in this.m_dag.StartedMailboxServers
                                                                                   select new AmServerName(server1);
                                DatabaseAvailabilityGroupAction.FixIPAddress(new AmServerName(server.Fqdn), this.m_dag, startedMailboxServers, this.m_output);
                            }
                        }
                        catch (LocalizedException ex2)
                        {
                            this.m_output.WriteWarning(Strings.FailedToJoinNode(server.Name, this.m_dag.Name, ex2.Message));
                            list.Add(server.Name);
                        }
                        catch (InvalidOperationException ex3)
                        {
                            this.m_output.WriteWarning(Strings.FailedToJoinNode(server.Name, this.m_dag.Name, ex3.Message));
                            list.Add(server.Name);
                        }
                    }
                }
            }
            return(list);
        }