internal static void TryStartClussvcOnNode(AmServerName serverName, HaTaskOutputHelper output) { using (ServiceController serviceController = new ServiceController("clussvc", serverName.Fqdn)) { try { if (DatabaseAvailabilityGroupAction.GetServiceControllerStatus(serviceController, serverName.NetbiosName, output) == ServiceControllerStatus.StopPending) { output.AppendLogMessage("Service is in stop pending, wait for it to be stopped", new object[0]); serviceController.WaitForStatus(ServiceControllerStatus.Stopped, DatabaseAvailabilityGroupAction.ServiceTimeout); } if (DatabaseAvailabilityGroupAction.GetServiceControllerStatus(serviceController, serverName.NetbiosName, output) == ServiceControllerStatus.Stopped) { serviceController.Start(); output.WriteProgressSimple(Strings.WaitingForClusterServiceToStart(serverName.NetbiosName)); serviceController.WaitForStatus(ServiceControllerStatus.Running, DatabaseAvailabilityGroupAction.ServiceTimeout); } } catch (System.ServiceProcess.TimeoutException) { output.WriteErrorSimple(new FailedToStartClusSvcException(serverName.NetbiosName, DatabaseAvailabilityGroupAction.GetServiceControllerStatus(serviceController, serverName.NetbiosName, output).ToString())); } } }
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); }
private bool ForceQuorumIfNecessary() { bool flag = true; bool result = false; foreach (Server server in this.m_startedServers.Values) { this.m_output.AppendLogMessage("ForceQuorumIfNecessary: 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); if (serviceControllerStatus == ServiceControllerStatus.Stopped) { this.m_output.AppendLogMessage("ForceQuorum: clussvc is stopped on node {0}. Starting it.", new object[] { server.Name }); try { if (flag) { this.m_output.AppendLogMessage("Starting cluster service with /fq (force quorum).", new object[0]); serviceController.Start(new string[] { "/fq" }); flag = false; } else { this.m_output.AppendLogMessage("Starting cluster service in normal mode.", new object[0]); serviceController.Start(); } try { this.m_output.AppendLogMessage("Waiting up to {0} for clussvc to be in the Running state.", new object[] { RestoreDatabaseAvailabilityGroup.ServiceTimeOut }); serviceController.WaitForStatus(ServiceControllerStatus.Running, RestoreDatabaseAvailabilityGroup.ServiceTimeOut); result = true; } catch (System.ServiceProcess.TimeoutException) { this.m_output.WriteErrorSimple(new FailedToStartClusSvcException(server.Name, serviceControllerStatus.ToString())); } continue; } catch (Win32Exception ex) { this.m_output.AppendLogMessage("ForceQuorum: cluster service on {0}Failed to start with fq {1}", new object[] { server.Name, ex.Message }); this.m_output.WriteErrorSimple(new FailedToStartClusSvcException(server.Name, serviceControllerStatus.ToString())); continue; } catch (InvalidOperationException ex2) { this.m_output.AppendLogMessage("ForceQuorum: cluster service on {0}Failed to start with fq {1}", new object[] { server.Name, ex2.Message }); this.m_output.WriteErrorSimple(new FailedToStartClusSvcException(server.Name, serviceControllerStatus.ToString())); continue; } } this.m_output.AppendLogMessage("ForceQuorum: cluster service on {0} is in state {1}, we will try another node (if there is one) for forcing quorum.", new object[] { server.Name, serviceControllerStatus }); flag = false; } } return(result); }