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(); }
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); }