예제 #1
0
        private bool IsNodePubliclyUp(AmNetworkMonitor.Node node)
        {
            IAmCluster cluster = this.GetCluster();

            if (cluster == null)
            {
                AmNetworkMonitor.Tracer.TraceError <AmServerName>(0L, "If cluster object is not valid, then assume node {0} is up", node.Name);
                return(true);
            }
            Exception   ex;
            AmNodeState nodeState = cluster.GetNodeState(node.Name, out ex);

            if (ex != null)
            {
                return(false);
            }
            if (!AmClusterNode.IsNodeUp(nodeState))
            {
                return(false);
            }
            AmClusterNodeNetworkStatus amClusterNodeNetworkStatus = AmClusterNodeStatusAccessor.Read(cluster, node.Name, out ex);

            return(amClusterNodeNetworkStatus == null || amClusterNodeNetworkStatus.HasADAccess);
        }
예제 #2
0
        private void CheckClusterStateForDagServerRemoval()
        {
            this.m_output.AppendLogMessage("CheckClusterStateForDagServerRemoval entered. m_removeNode={0}, m_destroyCluster={1}", new object[]
            {
                this.m_removeNode,
                this.m_destroyCluster
            });
            try
            {
                this.m_clusDag = AmCluster.OpenDagClus(this.m_dag);
            }
            catch (AmClusterException ex)
            {
                this.m_output.AppendLogMessage("Trying to open the cluster on the servers in the DAG '{0}' failed with exception {1}", new object[]
                {
                    this.m_dagName,
                    ex
                });
                this.m_output.WriteErrorSimple(new DagTaskRemoveDagServerMustHaveQuorumException(this.m_dagName));
            }
            using (DumpClusterTopology dumpClusterTopology = new DumpClusterTopology(this.m_clusDag, this.m_output))
            {
                dumpClusterTopology.Dump();
            }
            this.m_output.AppendLogMessage("Trying to open the node on the cluster.", new object[0]);
            IAmClusterNode amClusterNode = null;

            try
            {
                amClusterNode = this.m_clusDag.OpenNode(this.m_mailboxAmServerName);
            }
            catch (ClusterException ex2)
            {
                this.m_output.AppendLogMessage("OpenNode threw an exception. It's probably because the server is no longer clustered. Proceeding with -configurationonly.", new object[0]);
                this.m_output.AppendLogMessage("For the records, the exception was {0}.", new object[]
                {
                    ex2
                });
                this.m_configurationOnly   = true;
                this.m_mailboxServerIsDown = true;
                return;
            }
            using (amClusterNode)
            {
                AmNodeState state = amClusterNode.GetState(false);
                this.m_output.AppendLogMessage("Node.GetState( {0} ) reports that it is {1}.", new object[]
                {
                    this.m_mailboxAmServerName,
                    state
                });
                if (!AmClusterNode.IsNodeUp(state))
                {
                    this.m_mailboxServerIsDown = true;
                }
            }
            if (!this.m_skipDagValidation)
            {
                try
                {
                    DagTaskHelper.ValidateDagClusterMembership(this.m_output, this.m_dag, this.m_clusDag, this.m_mailboxAmServerName);
                }
                catch (ClusterException ex3)
                {
                    this.DagTrace("ValidateDagClusterMembership() for the mailbox server failed possibly with error {0}, ex = {1}. This is OK.", new object[]
                    {
                        LocalizedException.GenerateErrorCode(ex3.InnerException).ToString(),
                        ex3.Message
                    });
                }
            }
            int num = this.m_clusDag.EnumerateNodeNames().Count <AmServerName>();

            this.DagTrace(string.Format("There are {0} nodes in the cluster.", num), new object[0]);
            if (num == 1)
            {
                this.m_destroyCluster = true;
            }
            else
            {
                this.m_removeNode = true;
            }
            bool destroyCluster = this.m_destroyCluster;

            this.ReopenClusterIfNecessary();
            if ((this.m_removeNode || this.m_destroyCluster) && this.m_dag.DatacenterActivationMode != DatacenterActivationModeOption.Off)
            {
                DagTaskHelper.CheckDagCanBeActivatedInDatacenter(this.m_output, this.m_dag, (ADObjectId)this.m_mailboxServer.Identity, (ITopologyConfigurationSession)base.DataSession);
            }
            this.DagTrace("CheckClusterStateForDagServerRemoval left. m_removeNode={0}, m_destroyCluster={1}.", new object[]
            {
                this.m_removeNode,
                this.m_destroyCluster
            });
        }
        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();
        }
예제 #4
0
        // Token: 0x060008AC RID: 2220 RVA: 0x00029304 File Offset: 0x00027504
        internal static void CreateFileShareWitnessQuorum(ITaskOutputHelper output, IAmCluster cluster, string fswShare)
        {
            output = (output ?? NullTaskOutputHelper.GetNullLogger());
            IAmClusterGroup amClusterGroup = cluster.FindCoreClusterGroup();

            if (amClusterGroup == null)
            {
                Thread.Sleep(10000);
                amClusterGroup = cluster.FindCoreClusterGroup();
                if (amClusterGroup == null)
                {
                    throw new FailedToGetClusterCoreGroupException();
                }
            }
            using (amClusterGroup)
            {
                IEnumerable <AmClusterResource> source = amClusterGroup.EnumerateResourcesOfType("File Share Witness");
                IAmClusterResource amClusterResource   = source.ElementAtOrDefault(0);
                try
                {
                    bool flag = false;
                    if (amClusterResource == null)
                    {
                        output.AppendLogMessage("CreateFileShareWitnessQuorum: Could not find an existing FSW resource. A new one will be created.", new object[0]);
                        flag = true;
                    }
                    else if (amClusterResource.GetState() == AmResourceState.Failed)
                    {
                        output.AppendLogMessage("CreateFileShareWitnessQuorum: The existing FSW resource is in a Failed state. It should be deleted and recreated.", new object[0]);
                        flag = true;
                    }
                    else
                    {
                        string privateProperty = amClusterResource.GetPrivateProperty <string>("SharePath");
                        if (!SharedHelper.StringIEquals(privateProperty, fswShare))
                        {
                            output.AppendLogMessage("CreateFileShareWitnessQuorum: There is already a FSW, but the current share path ({0}) is not what's desired ({1}). Will try to fix it.", new object[]
                            {
                                privateProperty,
                                fswShare
                            });
                            List <string> list = new List <string>(4);
                            foreach (IAmClusterNode amClusterNode in cluster.EnumerateNodes())
                            {
                                using (amClusterNode)
                                {
                                    if (!AmClusterNode.IsNodeUp(amClusterNode.State))
                                    {
                                        list.Add(amClusterNode.Name.NetbiosName);
                                    }
                                }
                            }
                            if (list.Count > 0)
                            {
                                output.WriteErrorSimple(new DagTaskSetDagNeedsAllNodesUpToChangeQuorumException(string.Join(",", list.ToArray())));
                            }
                            DagHelper.SetFswSharePath(output, cluster, amClusterResource, fswShare);
                        }
                    }
                    AmResourceState state;
                    if (!flag && amClusterResource != null)
                    {
                        try
                        {
                            state = amClusterResource.GetState();
                            if (state != AmResourceState.Online)
                            {
                                output.AppendLogMessage("The FSW is not online (it is {0}). Attempting to bring online.", new object[]
                                {
                                    state
                                });
                                amClusterResource.OnlineResource();
                            }
                            state = amClusterResource.GetState();
                            output.AppendLogMessage("The fsw resource is now in state {0}.", new object[]
                            {
                                state
                            });
                            if (state != AmResourceState.Online)
                            {
                                flag = true;
                            }
                        }
                        catch (ClusterException ex)
                        {
                            output.AppendLogMessage("Bringing the FSW resource online failed, so it will be deleted and recreated. For the record, the error was {0}", new object[]
                            {
                                ex
                            });
                            flag = true;
                        }
                    }
                    if (flag)
                    {
                        if (amClusterResource != null)
                        {
                            amClusterResource.Dispose();
                            amClusterResource = null;
                        }
                        output.AppendLogMessage("CreateFileShareWitnessQuorum: Calling RevertToMnsQuorum to clean everything up first.", new object[0]);
                        DagHelper.RevertToMnsQuorum(output, cluster);
                        string text = string.Format("File Share Witness ({0})", fswShare);
                        output.AppendLogMessage("Creating a new file share witness resource named '{0}'.", new object[]
                        {
                            text
                        });
                        amClusterResource = amClusterGroup.CreateResource(text, "File Share Witness");
                        DagHelper.SetFswSharePath(output, cluster, amClusterResource, fswShare);
                    }
                    output.AppendLogMessage("The FSW resource is now in state {0}.", new object[]
                    {
                        amClusterResource.GetState()
                    });
                    string text2;
                    uint   maxLogSize;
                    string quorumResourceInformation = cluster.GetQuorumResourceInformation(out text2, out maxLogSize);
                    output.AppendLogMessage("The current quorum resource is '{0}'. About to set it to the FSW.", new object[]
                    {
                        quorumResourceInformation
                    });
                    state = amClusterResource.GetState();
                    if (state != AmResourceState.Online)
                    {
                        output.WriteErrorSimple(new DagTaskFileShareWitnessResourceIsStillNotOnlineException(fswShare, state.ToString()));
                    }
                    cluster.SetQuorumResource(amClusterResource, null, maxLogSize);
                    quorumResourceInformation = cluster.GetQuorumResourceInformation(out text2, out maxLogSize);
                    output.AppendLogMessage("The quorum resource is now '{0}'.", new object[]
                    {
                        quorumResourceInformation
                    });
                    output.AppendLogMessage("Bringing the quorum resource online...", new object[0]);
                    amClusterResource.OnlineResource();
                }
                finally
                {
                    if (amClusterResource != null)
                    {
                        amClusterResource.Dispose();
                        amClusterResource = null;
                    }
                }
            }
        }
예제 #5
0
        private bool CheckClussvcRunningOnStartedServers()
        {
            bool result = false;
            List <AmServerName> list  = new List <AmServerName>(16);
            List <AmServerName> list2 = new List <AmServerName>(16);

            new List <AmServerName>(16);
            List <string> list3 = new List <string>(16);

            foreach (Server server in this.m_startedServers.Values)
            {
                this.m_output.AppendLogMessage("Checking if clussvc is running on {0}...", new object[]
                {
                    server.Name
                });
                using (ServiceController serviceController = new ServiceController("clussvc", server.Name))
                {
                    ServiceControllerStatus serviceControllerStatus = DatabaseAvailabilityGroupAction.GetServiceControllerStatus(serviceController, server.Name, this.m_output);
                    this.m_output.AppendLogMessage("Clussvc is {0} on {1}.", new object[]
                    {
                        serviceControllerStatus,
                        server.Name
                    });
                    if (serviceControllerStatus == ServiceControllerStatus.Running)
                    {
                        list.Add(new AmServerName(server));
                    }
                    else
                    {
                        list2.Add(new AmServerName(server));
                    }
                }
            }
            if (list2.Count == this.m_startedServers.Values.Count)
            {
                this.m_output.AppendLogMessage("None of the {0} servers in the started list had clussvc running, so it is safe to continue with restore-dag, but forcequorum will be necessary.", new object[]
                {
                    list2.Count
                });
            }
            else
            {
                int num = 0;
                List <AmServerName> list4 = new List <AmServerName>(1);
                try
                {
                    using (AmCluster amCluster = AmCluster.OpenByNames(list))
                    {
                        IEnumerable <IAmClusterNode> enumerable = amCluster.EnumerateNodes();
                        foreach (IAmClusterNode amClusterNode in enumerable)
                        {
                            AmNodeState state = amClusterNode.State;
                            this.m_output.AppendLogMessage("The node {0} has cluster state = {1}.", new object[]
                            {
                                amClusterNode.Name,
                                state
                            });
                            if (state == AmNodeState.Joining)
                            {
                                this.m_output.AppendLogMessage("  Node {0} is joining! That means there is some difficulty establishing quorum.", new object[]
                                {
                                    amClusterNode.Name
                                });
                                list3.Add(amClusterNode.Name.NetbiosName);
                            }
                            else if (AmClusterNode.IsNodeUp(state))
                            {
                                num++;
                            }
                            if (state == AmNodeState.Paused)
                            {
                                list4.Add(amClusterNode.Name);
                            }
                        }
                        foreach (IAmClusterNode amClusterNode2 in enumerable)
                        {
                            amClusterNode2.Dispose();
                        }
                    }
                }
                catch (ClusterException)
                {
                    this.m_output.WriteErrorSimple(new DagTaskRestoreDagCouldNotOpenClusterException());
                }
                this.m_output.AppendLogMessage("There were {0} total (Stopped&Started) servers that were Up, out of {1} servers in the Started list that had clussvc running.", new object[]
                {
                    num,
                    list.Count
                });
                if (num == list.Count)
                {
                    this.m_output.AppendLogMessage("Because the two values are the same, that means quorum is healthy (even if not all of the servers are Up), so it is safe to continue with restore-dag.", new object[0]);
                    result = true;
                }
                else if (num > list.Count)
                {
                    this.m_output.AppendLogMessage("Because there are more servers that are up than there are in the Started list, it is safe to continue with restore-dag.", new object[0]);
                    result = true;
                }
                else
                {
                    this.m_output.AppendLogMessage("Because the two values are different, that means quorum is contested/in flux, so it is NOT safe to continue with restore-dag.", new object[0]);
                    this.m_output.WriteErrorSimple(new RestoreFailedDagUpException(string.Join(",", list3.ToArray())));
                }
            }
            return(result);
        }