mirror of https://github.com/apache/cassandra
194 lines
6.5 KiB
PowerShell
194 lines
6.5 KiB
PowerShell
#
|
|
# Licensed to the Apache Software Foundation (ASF) under one or more
|
|
# contributor license agreements. See the NOTICE file distributed with
|
|
# this work for additional information regarding copyright ownership.
|
|
# The ASF licenses this file to You under the Apache License, Version 2.0
|
|
# (the "License"); you may not use this file except in compliance with
|
|
# the License. You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
param (
|
|
[string]$p,
|
|
[string]$batchpid,
|
|
[switch]$f,
|
|
[switch]$silent,
|
|
[switch]$help
|
|
)
|
|
|
|
#-----------------------------------------------------------------------------
|
|
Function ValidateArguments
|
|
{
|
|
if (!$p)
|
|
{
|
|
PrintUsage
|
|
}
|
|
if ($help)
|
|
{
|
|
PrintUsage
|
|
}
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
Function PrintUsage
|
|
{
|
|
echo @"
|
|
|
|
usage: stop-server.ps1 -p pidfile -f[-help]
|
|
-p pidfile tracked by server and removed on close.
|
|
-s Silent. Don't print success/failure data.
|
|
-f force kill.
|
|
"@
|
|
exit
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
Function KillProcess
|
|
{
|
|
if (-Not (Test-Path $p))
|
|
{
|
|
if (-Not ($silent))
|
|
{
|
|
echo "Error - pidfile not found. Aborting."
|
|
}
|
|
exit
|
|
}
|
|
|
|
$t = @"
|
|
using System;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Runtime.InteropServices;
|
|
using System.Threading;
|
|
|
|
namespace PowerStopper
|
|
{
|
|
public static class Stopper
|
|
{
|
|
delegate bool ConsoleCtrlDelegate(CtrlTypes CtrlType);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true)]
|
|
static extern bool AttachConsole(uint dwProcessId);
|
|
|
|
[DllImport("kernel32.dll", SetLastError = true, ExactSpelling = true)]
|
|
static extern bool FreeConsole();
|
|
|
|
enum CtrlTypes : uint
|
|
{
|
|
CTRL_C_EVENT = 0,
|
|
CTRL_BREAK_EVENT,
|
|
CTRL_CLOSE_EVENT,
|
|
CTRL_LOGOFF_EVENT = 5,
|
|
CTRL_SHUTDOWN_EVENT
|
|
}
|
|
|
|
[DllImport("kernel32.dll")]
|
|
[return: MarshalAs(UnmanagedType.Bool)]
|
|
private static extern bool GenerateConsoleCtrlEvent(CtrlTypes dwCtrlEvent, uint dwProcessGroupId);
|
|
|
|
[DllImport("kernel32.dll")]
|
|
static extern bool SetConsoleCtrlHandler(ConsoleCtrlDelegate HandlerRoutine, bool Add);
|
|
|
|
// Our output gets swallowed on ms-dos as we can't re-attach our console to the output of the cmd
|
|
// running the batch file.
|
|
public static void StopProgram(int pidToKill, int consolePid, bool silent)
|
|
{
|
|
Process proc = null;
|
|
try
|
|
{
|
|
proc = Process.GetProcessById(pidToKill);
|
|
}
|
|
catch (ArgumentException)
|
|
{
|
|
if (!silent)
|
|
System.Console.WriteLine("Process " + pidToKill + " not found. Aborting.");
|
|
return;
|
|
}
|
|
|
|
if (!FreeConsole())
|
|
{
|
|
if (!silent)
|
|
System.Console.WriteLine("Failed to FreeConsole to attach to running cassandra process. Aborting.");
|
|
return;
|
|
}
|
|
|
|
if (AttachConsole((uint)pidToKill))
|
|
{
|
|
//Disable Ctrl-C handling for our program
|
|
SetConsoleCtrlHandler(null, true);
|
|
GenerateConsoleCtrlEvent(CtrlTypes.CTRL_C_EVENT, 0);
|
|
|
|
// Must wait here. If we don't and re-enable Ctrl-C
|
|
// handling below too fast, we might terminate ourselves.
|
|
bool exited = proc.WaitForExit(30000);
|
|
if(!exited)
|
|
proc.Kill();
|
|
|
|
FreeConsole();
|
|
|
|
// Re-attach to current console to write output
|
|
if (consolePid >= 0)
|
|
AttachConsole((uint)consolePid);
|
|
|
|
// Re-enable Ctrl-C handling or any subsequently started
|
|
// programs will inherit the disabled state.
|
|
SetConsoleCtrlHandler(null, false);
|
|
|
|
if (!silent)
|
|
{
|
|
if(exited)
|
|
System.Console.WriteLine("Successfully sent ctrl+c to process with id: " + pidToKill + ".");
|
|
else
|
|
System.Console.WriteLine("Process with id: " + pidToKill + " did not exit after 30 seconds, killed.");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (!silent)
|
|
{
|
|
string errorMsg = new System.ComponentModel.Win32Exception(Marshal.GetLastWin32Error()).Message;
|
|
System.Console.WriteLine("Error attaching to pid: " + pidToKill + ": " + Marshal.GetLastWin32Error() + " - " + errorMsg);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
"@
|
|
# cygwin assumes environment variables are case sensitive which causes problems when
|
|
# the type dictionary references 'tmp' or 'temp' and throws a System.ArgumentException
|
|
$oldTmp = $env:TMP
|
|
$oldTemp = $env:Temp
|
|
$env:TMP=''
|
|
$env:TEMP=''
|
|
Add-Type -TypeDefinition $t
|
|
$env:TMP = $oldTmp
|
|
$env:TEMP = $oldTemp
|
|
|
|
$pidToKill = Get-Content $p
|
|
# If run in cygwin, we don't get the TITLE / pid combo in stop-server.bat but also don't need
|
|
# to worry about reattaching console output as it gets stderr/stdout even after the C#/C++
|
|
# FreeConsole calls.
|
|
if ($batchpid -eq "No")
|
|
{
|
|
$batchpid = -1
|
|
}
|
|
|
|
if ($f)
|
|
{
|
|
taskkill /f /pid $pidToKill
|
|
}
|
|
else
|
|
{
|
|
[PowerStopper.Stopper]::StopProgram($pidToKill, $batchpid, $silent)
|
|
}
|
|
}
|
|
|
|
#-----------------------------------------------------------------------------
|
|
ValidateArguments
|
|
KillProcess
|