Add PowerShell Windows launch scripts

patch by Joshua McKenzie; tested by Philip Thompson for CASSANDRA-7001
This commit is contained in:
Jonathan Ellis 2014-05-14 09:09:51 -07:00
parent 4ee372106f
commit 1927d5ec72
7 changed files with 914 additions and 3 deletions

View File

@ -1,4 +1,5 @@
2.1.0-rc1
* Add PowerShell Windows launch scripts (CASSANDRA-7001)
* Make commitlog archive+restore more robust (CASSANDRA-6974)
* Fix marking commitlogsegments clean (CASSANDRA-6959)
* Add snapshot "manifest" describing files included (CASSANDRA-6326)

View File

@ -18,6 +18,7 @@
if "%OS%" == "Windows_NT" setlocal
set ARG=%1
if /i "%ARG%" == "LEGACY" goto runLegacy
set INSTALL="INSTALL"
set UNINSTALL="UNINSTALL"
@ -25,14 +26,36 @@ pushd %~dp0..
if NOT DEFINED CASSANDRA_HOME set CASSANDRA_HOME=%CD%
popd
REM -----------------------------------------------------------------------------
REM See if we have access to run unsigned powershell scripts
for /F "delims=" %%i in ('powershell Get-ExecutionPolicy') do set PERMISSION=%%i
if "%PERMISSION%" == "Unrestricted" goto runPowerShell
goto runLegacy
REM -----------------------------------------------------------------------------
:runPowerShell
echo Detected powershell execution permissions. Running with enhanced startup scripts.
echo starting ps1: %CASSANDRA_HOME%/bin/cassandra.ps1
powershell /file %CASSANDRA_HOME%/bin/cassandra.ps1 %*
goto finally
REM -----------------------------------------------------------------------------
:runLegacy
echo WARNING! Powershell script execution unavailable.
echo Please use 'powershell Set-ExecutionPolicy Unrestricted'
echo on this user-account to run cassandra with fully featured
echo functionality on this platform.
echo Starting with legacy startup options
if NOT DEFINED CASSANDRA_MAIN set CASSANDRA_MAIN=org.apache.cassandra.service.CassandraDaemon
if NOT DEFINED JAVA_HOME goto :err
REM ***** JAVA options *****
set JAVA_OPTS=-ea^
-javaagent:"%CASSANDRA_HOME%\lib\jamm-0.2.6.jar"^
-Xms1G^
-Xmx1G^
-Xms2G^
-Xmx2G^
-XX:+HeapDumpOnOutOfMemoryError^
-XX:+UseParNewGC^
-XX:+UseConcMarkSweepGC^
@ -102,7 +125,7 @@ rem set PR_CLASSPATH=%CASSANDRA_CLASSPATH%
--StopMode=jvm --StopClass=%CASSANDRA_MAIN% --StopMethod=stop ^
++JvmOptions=%JAVA_OPTS_DELM% ++JvmOptions=-DCassandra ^
--PidFile pid.txt
echo Installation of %SERVICE_JVM% is complete
goto finally

281
bin/cassandra.ps1 Normal file
View File

@ -0,0 +1,281 @@
#
# 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 (
[switch]$install,
[switch]$uninstall,
[switch]$help,
[switch]$verbose,
[switch]$f,
[string]$p,
[string]$H,
[string]$E
)
$pidfile = "pid.txt"
#-----------------------------------------------------------------------------
Function ValidateArguments
{
if ($install -and $uninstall)
{
exit
}
if ($help)
{
PrintUsage
}
}
#-----------------------------------------------------------------------------
Function PrintUsage
{
echo @"
usage: cassandra.ps1 [-f] [-h] [-p pidfile] [-H dumpfile] [-E errorfile] [-install | -uninstall] [-help]
-f Run cassandra in foreground
-install install cassandra as a service
-uninstall remove cassandra service
-p pidfile tracked by server and removed on close
-H change JVM HeapDumpPath
-E change JVM ErrorFile
-help print this message
-verbose Show detailed command-line parameters for cassandra run
NOTE: installing cassandra as a service requires Commons Daemon Service Runner
available at http://commons.apache.org/proper/commons-daemon/"
"@
exit
}
#-----------------------------------------------------------------------------
# Note: throughout these scripts we're replacing \ with /. This allows clean
# operation on both command-prompt and cygwin-based environments.
Function Main
{
ValidateArguments
. "$env:CASSANDRA_HOME/bin/source-conf.ps1"
$conf = Find-Conf
if ($verbose)
{
echo "Sourcing cassandra config file: $conf"
}
. $conf
SetCassandraEnvironment
$pidfile = "$env:CASSANDRA_HOME/$pidfile"
# Other command line params
if ($H)
{
$env:JVM_OPTS = $env:JVM_OPTS + " -XX:HeapDumpPath=$H"
}
if ($E)
{
$env:JVM_OPTS = $env:JVM_OPTS + " -XX:ErrorFile=$E"
}
if ($p)
{
$pidfile = "$p"
$env:CASSANDRA_PARAMS = $env:CASSANDRA_PARAMS + " -Dcassandra-pidfile=$pidfile"
}
if ($install -or $uninstall)
{
HandleInstallation
}
else
{
CleanOldRun
RunCassandra($f)
}
}
#-----------------------------------------------------------------------------
Function HandleInstallation
{
$SERVICE_JVM = "cassandra"
$PATH_PRUNSRV = "$env:CASSANDRA_HOME/bin/daemon/"
$PR_LOGPATH = $serverPath
if (!$env:PRUNSRV)
{
$env:PRUNSRV="$PATH_PRUNSRV/prunsrv"
}
echo "Attempting to delete existing $SERVICE_JVM service..."
Start-Sleep -s 2
$proc = Start-Process -FilePath "$env:PRUNSRV" -ArgumentList "//DS//$SERVICE_JVM" -PassThru -WindowStyle Hidden
# Quit out if this is uninstall only
if ($uninstall)
{
return
}
echo "Installing [$SERVICE_JVM]. If you get registry warnings, re-run as an Administrator"
Start-Sleep -s 2
$proc = Start-Process -FilePath "$env:PRUNSRV" -ArgumentList "//IS//$SERVICE_JVM" -PassThru -WindowStyle Hidden
echo "Setting the parameters for [$SERVICE_JVM]"
Start-Sleep -s 2
# Broken multi-line for convenience - glued back together in a bit
$args = @"
//US//$SERVICE_JVM
--Jvm=auto --StdOutput auto --StdError auto
--Classpath=$env:CLASSPATH
--StartMode=jvm --StartClass=$env:CASSANDRA_MAIN --StartMethod=main
--StopMode=jvm --StopClass=$env:CASSANDRA_MAIN --StopMethod=stop
++JvmOptions=$env:JVM_OPTS ++JvmOptions=-DCassandra
--PidFile $pidfile
"@
$args = $args -replace [Environment]::NewLine, ""
$proc = Start-Process -FilePath "$env:PRUNSRV" -ArgumentList $args -PassThru -WindowStyle Hidden
echo "Installation of [$SERVICE_JVM] is complete"
}
#-----------------------------------------------------------------------------
Function CleanOldRun
{
# see if we already have an instance of cassandra running from this folder
if (Test-Path $pidfile)
{
$a = Get-Content $pidfile
# file is there but empty
if ($a -eq $null)
{
Remove-Item $pidfile
return
}
$proc = Get-Process -Id $a -ErrorAction SilentlyContinue
if ($proc)
{
echo "ERROR! There is already an instance of cassandra running from this folder with pid: $a. Please use stop-server.bat to stop this instance before starting cassandra."
exit
}
else
{
Remove-Item $pidfile
}
}
}
#-----------------------------------------------------------------------------
Function RunCassandra([string]$foreground)
{
echo "Starting cassandra server"
$cmd = @"
$env:JAVA_BIN
"@
$arg1 = $env:JVM_OPTS
$arg2 = $env:CASSANDRA_PARAMS
$arg3 = "-cp $env:CLASSPATH"
$arg4 = @"
"$env:CASSANDRA_MAIN"
"@
$proc = $null
if ($verbose)
{
echo "Running cassandra with: [$cmd $arg1 $arg2 $arg3 $arg4]"
}
if ($foreground -ne "False")
{
$cygwin = $false
try
{
$uname = uname -o
$cygwin = $true
}
catch
{
# Failed at uname call, not in cygwin
}
if ($cygwin)
{
# if running on cygwin, we cannot capture ctrl+c signals as mintty traps them and then
# SIGKILLs processes, so we'll need to record our $pidfile file for future
# stop-server usage
if (!$p)
{
$arg2 = $arg2 + " -Dcassandra-pidfile=$pidfile"
}
echo @"
*********************************************************************
*********************************************************************
Warning! Running cassandra.bat -f on cygwin usually breaks control+c
functionality. You'll need to use:
stop-server.bat -p $pidfile
to stop your server or kill the java.exe instance.
*********************************************************************
*********************************************************************"
"@
# Note: we can't pause here and force user confirmation for a similar reason as there's a
# layer of indirection between powershell and stdin.
}
$arg2 = $arg2 + " -Dcassandra-foreground=yes"
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "$env:JAVA_BIN"
$pinfo.RedirectStandardInput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = $arg1,$arg2,$arg3,$arg4
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
echo $p.Id > $pidfile
$p.WaitForExit()
}
else
{
$proc = Start-Process -FilePath "$cmd" -ArgumentList $arg1,$arg2,$arg3,$arg4 -PassThru -WindowStyle Hidden
# Always store the pid, even if we're not registering it with the server
# The startup script uses this pid file as a protection against duplicate startup from the same folder
try
{
echo $proc.Id > $pidfile
}
catch
{
echo @"
WARNING! Failed to write pidfile to $pidfile. stop-server.bat and
startup protection will not be available.
"@
}
$cassPid = $proc.Id
if (-Not ($proc) -or $cassPid -eq "")
{
echo "Error starting cassandra."
echo "Run with -verbose for more information about runtime environment"
}
elseif ($foreground -eq "False")
{
echo "Started cassandra successfully with pid: $cassPid"
}
}
}
#-----------------------------------------------------------------------------
Main

57
bin/source-conf.ps1 Normal file
View File

@ -0,0 +1,57 @@
#
# 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.
Function Find-Conf
{
$file = "";
# Order of preference on grabbing environment settings:
# 1: %CASSANDRA_INCLUDE%
# 2a: %USERPROFILE%/cassandra-env.ps1 (cmd-prompt)
# 2b: $HOME/cassandra-env.ps1 (cygwin)
# 3: %CASSANDRA_HOME%/conf/cassandra-env.ps1
# 4: Relative to current working directory (../conf)
if (Test-Path Env:\CASSANDRA_INCLUDE)
{
$file = "$env:CASSANDRA_INCLUDE"
}
elseif (Test-Path "$env:USERPROFILE/cassandra-env.ps1")
{
$file = "$env:USERPROFILE/cassandra-env.ps1"
}
elseif (Test-Path "$env:HOME/cassandra-env.ps1")
{
$file = "$env:HOME/cassandra-env.ps1"
}
elseif (Test-Path Env:\CASSANDRA_HOME)
{
$file = "$env:CASSANDRA_HOME/conf/cassandra-env.ps1"
}
else
{
$file = [System.IO.Directory]::GetCurrentDirectory() + "/../conf/cassandra-env.ps1"
}
$file = $file -replace "\\", "/"
if (Test-Path $file)
{
return $file
}
else
{
echo "Error with environment file resolution. Path: [$file] not found."
exit
}
}

55
bin/stop-server.bat Normal file
View File

@ -0,0 +1,55 @@
@REM
@REM Licensed to the Apache Software Foundation (ASF) under one or more
@REM contributor license agreements. See the NOTICE file distributed with
@REM this work for additional information regarding copyright ownership.
@REM The ASF licenses this file to You under the Apache License, Version 2.0
@REM (the "License"); you may not use this file except in compliance with
@REM the License. You may obtain a copy of the License at
@REM
@REM http://www.apache.org/licenses/LICENSE-2.0
@REM
@REM Unless required by applicable law or agreed to in writing, software
@REM distributed under the License is distributed on an "AS IS" BASIS,
@REM WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@REM See the License for the specific language governing permissions and
@REM limitations under the License.
@echo off
if "%OS%" == "Windows_NT" setlocal
pushd %~dp0..
if NOT DEFINED CASSANDRA_HOME set CASSANDRA_HOME=%CD%
popd
REM -----------------------------------------------------------------------------
REM See if we have the capabilities of running the powershell scripts
for /F "delims=" %%i in ('powershell Get-ExecutionPolicy') do set PERMISSION=%%i
if "%PERMISSION%" == "Unrestricted" goto runPowerShell
goto runLegacy
REM -----------------------------------------------------------------------------
:runPowerShell
REM Need to generate a random title for this command-prompt to determine its pid.
REM We detach and re-attach the console in stop-server.ps1 to send ctrl+c to the
REM running cassandra process and need to re-attach here to print results.
set /A rand=%random% %% (100000 - 1 + 1) + 1
TITLE %rand%
FOR /F "tokens=2 delims= " %%A IN ('TASKLIST /FI ^"WINDOWTITLE eq %rand%^" /NH') DO set PID=%%A
REM Start with /B -> the control+c event we generate in stop-server.ps1 percolates
REM up and hits this external batch file if we call powershell directly.
start /B powershell /file %CASSANDRA_HOME%/bin/stop-server.ps1 -batchpid %PID% %*
goto finally
REM -----------------------------------------------------------------------------
:runLegacy
echo WARNING! Powershell script execution unavailable.
echo Please use 'powershell Set-ExecutionPolicy Unrestricted'
echo on this user-account to run cassandra with fully featured
echo functionality on this platform.
echo Cannot stop server without powershell access.
goto finally
:finally
ENDLOCAL

178
bin/stop-server.ps1 Normal file
View File

@ -0,0 +1,178 @@
#
# 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.
proc.WaitForExit(2000);
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)
System.Console.WriteLine("Successfully sent ctrl+c to process with id: " + pidToKill + ".");
}
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
$a = 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
}
[PowerStopper.Stopper]::StopProgram($a, $batchpid, $silent)
}
#-----------------------------------------------------------------------------
ValidateArguments
KillProcess

316
conf/cassandra-env.ps1 Normal file
View File

@ -0,0 +1,316 @@
#
# 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.
# NOTE: All param tuning can be done in the SetCassandraEnvironment Function below
#-----------------------------------------------------------------------------
Function SetCassandraHome()
{
if (! $env:CASSANDRA_HOME)
{
$cwd = [System.IO.Directory]::GetCurrentDirectory()
$cwd = Split-Path $cwd -parent
$env:CASSANDRA_HOME = $cwd -replace "\\", "/"
}
}
#-----------------------------------------------------------------------------
Function SetCassandraMain()
{
if (! $env:CASSANDRA_MAIN)
{
$env:CASSANDRA_MAIN="org.apache.cassandra.service.CassandraDaemon"
}
}
#-----------------------------------------------------------------------------
Function BuildClassPath
{
$cp = "$env:CASSANDRA_HOME/conf"
foreach ($file in Get-ChildItem "$env:CASSANDRA_HOME/lib/*.jar")
{
$file = $file -replace "\\", "/"
$cp = $cp + ";" + "$file"
}
# Add build/classes/main so it works in development
$cp = $cp + ";" + "$env:CASSANDRA_HOME/build/classes/main;$env:CASSANDRA_HOME/build/classes/thrift"
$env:CLASSPATH=$cp
}
#-----------------------------------------------------------------------------
Function CalculateHeapSizes
{
# Validate that we need to run this function and that our config is good
if ($env:MAX_HEAP_SIZE -and $env:HEAP_NEWSIZE)
{
return
}
if (($env:MAX_HEAP_SIZE -and !$env:HEAP_NEWSIZE) -or (!$env:MAX_HEAP_SIZE -and $env:HEAP_NEWSIZE))
{
echo "please set or unset MAX_HEAP_SIZE and HEAP_NEWSIZE in pairs"
exit 1
}
$memObject = Get-WMIObject -class win32_physicalmemory
$memory = ($memObject | Measure-Object Capacity -Sum).sum
$memoryMB = $memory / (1024*1024)
$cpu = gwmi Win32_ComputerSystem | Select-Object NumberOfLogicalProcessors
$systemCores = $cpu.NumberOfLogicalProcessors
# set max heap size based on the following
# max(min(1/2 ram, 1024MB), min(1/4 ram, 8GB))
# calculate 1/2 ram and cap to 1024MB
# calculate 1/4 ram and cap to 8192MB
# pick the max
$halfMem = $memoryMB / 2
$quarterMem = $halfMem / 2
if ($halfMem -gt 1024)
{
$halfMem = 1024
}
if ($quarterMem -gt 8192)
{
$quarterMem = 8192
}
$maxHeapMB = ""
if ($halfMem -gt $quarterMem)
{
$maxHeapMB = $halfMem
}
else
{
$maxHeapMB = $quarterMem
}
$env:MAX_HEAP_SIZE = [System.Convert]::ToString($maxHeapMB) + "M"
# Young gen: min(max_sensible_per_modern_cpu_core * num_cores, 1/4
$maxYGPerCore = 100
$maxYGTotal = $maxYGPerCore * $systemCores
$desiredYG = $maxHeapMB / 4
if ($desiredYG -gt $maxYGTotal)
{
$env:HEAP_NEWSIZE = [System.Convert]::ToString($maxYGTotal) + "M"
}
else
{
$env:HEAP_NEWSIZE = [System.Convert]::ToString($desiredYG) + "M"
}
}
#-----------------------------------------------------------------------------
Function ParseJVMInfo
{
# grab info about the JVM
$pinfo = New-Object System.Diagnostics.ProcessStartInfo
$pinfo.FileName = "$env:JAVA_BIN"
$pinfo.RedirectStandardError = $true
$pinfo.RedirectStandardOutput = $true
$pinfo.UseShellExecute = $false
$pinfo.Arguments = "-version"
$p = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stderr = $p.StandardError.ReadToEnd()
$sa = $stderr.Split("""")
$env:JVM_VERSION = $sa[1]
if ($stderr.Contains("OpenJDK"))
{
$env:JVM_VENDOR = "OpenJDK"
}
elseif ($stderr.Contains("Java(TM)"))
{
$env:JVM_VENDOR = "Oracle"
}
else
{
$JVM_VENDOR = "other"
}
$pa = $sa[1].Split("_")
$env:JVM_PATCH_VERSION=$pa[1]
# get 64-bit vs. 32-bit
$pinfo.Arguments = "-d64 -version"
$pArch = New-Object System.Diagnostics.Process
$p.StartInfo = $pinfo
$p.Start() | Out-Null
$p.WaitForExit()
$stderr = $p.StandardError.ReadToEnd()
if ($stderr.Contains("Error"))
{
$env:JVM_ARCH = "32-bit"
}
else
{
$env:JVM_ARCH = "64-bit"
}
}
#-----------------------------------------------------------------------------
Function SetCassandraEnvironment
{
echo "Setting up Cassandra environment"
if (Test-Path Env:\JAVA_HOME)
{
$env:JAVA_BIN = "$env:JAVA_HOME/bin/java.exe"
}
elseif (Get-Command "java.exe")
{
$env:JAVA_BIN = "java.exe"
}
else
{
echo "ERROR! No JAVA_HOME set and could not find java.exe in the path."
exit
}
SetCassandraHome
$env:CASSANDRA_CONF = "$env:CASSANDRA_HOME/conf"
$env:CASSANDRA_PARAMS="-Dcassandra -Dlogback.configurationFile=logback.xml"
SetCassandraMain
BuildClassPath
# Override these to set the amount of memory to allocate to the JVM at
# start-up. For production use you may wish to adjust this for your
# environment. MAX_HEAP_SIZE is the total amount of memory dedicated
# to the Java heap; HEAP_NEWSIZE refers to the size of the young
# generation. Both MAX_HEAP_SIZE and HEAP_NEWSIZE should be either set
# or not (if you set one, set the other).
#
# The main trade-off for the young generation is that the larger it
# is, the longer GC pause times will be. The shorter it is, the more
# expensive GC will be (usually).
#
# The example HEAP_NEWSIZE assumes a modern 8-core+ machine for decent
# times. If in doubt, and if you do not particularly want to tweak, go
# 100 MB per physical CPU core.
#$env:MAX_HEAP_SIZE="4G"
#$env:HEAP_NEWSIZE="800M"
CalculateHeapSizes
ParseJVMInfo
# add the jamm javaagent
if (($env:JVM_VENDOR -ne "OpenJDK") -or ($env:JVM_VERSION.CompareTo("1.6.0") -eq 1) -or
(($env:JVM_VERSION -eq "1.6.0") -and ($env:JVM_PATCH_VERSION.CompareTo("22") -eq 1)))
{
$env:JVM_OPTS = "$env:JVM_OPTS -javaagent:$env:CASSANDRA_HOME/lib/jamm-0.2.6.jar"
}
# enable assertions. disabling this in production will give a modest
# performance benefit (around 5%).
$env:JVM_OPTS = "$env:JVM_OPTS -ea"
# Specifies the default port over which Cassandra will be available for
# JMX connections.
$JMX_PORT="7199"
$env:JVM_OPTS = "$env:JVM_OPTS -Dlog4j.defaultInitOverride=true"
# some JVMs will fill up their heap when accessed via JMX, see CASSANDRA-6541
$env:JVM_OPTS="$env:JVM_OPTS -XX:+CMSClassUnloadingEnabled"
# enable thread priorities, primarily so we can give periodic tasks
# a lower priority to avoid interfering with client workload
$env:JVM_OPTS="$env:JVM_OPTS -XX:+UseThreadPriorities"
# allows lowering thread priority without being root. see
# http://tech.stolsvik.com/2010/01/linux-java-thread-priorities-workar
$env:JVM_OPTS="$env:JVM_OPTS -XX:ThreadPriorityPolicy=42"
# min and max heap sizes should be set to the same value to avoid
# stop-the-world GC pauses during resize, and so that we can lock the
# heap in memory on startup to prevent any of it from being swapped
# out.
$env:JVM_OPTS="$env:JVM_OPTS -Xms$env:MAX_HEAP_SIZE"
$env:JVM_OPTS="$env:JVM_OPTS -Xmx$env:MAX_HEAP_SIZE"
$env:JVM_OPTS="$env:JVM_OPTS -Xmn$env:HEAP_NEWSIZE"
$env:JVM_OPTS="$env:JVM_OPTS -XX:+HeapDumpOnOutOfMemoryError"
# Per-thread stack size.
$env:JVM_OPTS="$env:JVM_OPTS -Xss256k"
# Larger interned string table, for gossip's benefit (CASSANDRA-6410)
$env:JVM_OPTS="$env:JVM_OPTS -XX:StringTableSize=1000003"
# GC tuning options
$env:JVM_OPTS="$env:JVM_OPTS -XX:+UseParNewGC"
$env:JVM_OPTS="$env:JVM_OPTS -XX:+UseConcMarkSweepGC"
$env:JVM_OPTS="$env:JVM_OPTS -XX:+CMSParallelRemarkEnabled"
$env:JVM_OPTS="$env:JVM_OPTS -XX:SurvivorRatio=8"
$env:JVM_OPTS="$env:JVM_OPTS -XX:MaxTenuringThreshold=1"
$env:JVM_OPTS="$env:JVM_OPTS -XX:CMSInitiatingOccupancyFraction=75"
$env:JVM_OPTS="$env:JVM_OPTS -XX:+UseCMSInitiatingOccupancyOnly"
$env:JVM_OPTS="$env:JVM_OPTS -XX:+UseTLAB"
if (($env:JVM_VERSION.CompareTo("1.7") -eq 1) -and ($env:JVM_ARCH -eq "64-Bit"))
{
$env:JVM_OPTS="$env:JVM_OPTS -XX:+UseCondCardMark"
}
# GC logging options -- uncomment to enable
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+PrintGCDetails"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+PrintGCDateStamps"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+PrintHeapAtGC"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+PrintTenuringDistribution"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+PrintGCApplicationStoppedTime"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+PrintPromotionFailure"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:PrintFLSStatistics=1"
# $env:JVM_OPTS="$env:JVM_OPTS -Xloggc:/var/log/cassandra/gc-`date +%s`.log"
# If you are using JDK 6u34 7u2 or later you can enable GC log rotation
# don't stick the date in the log name if rotation is on.
# $env:JVM_OPTS="$env:JVM_OPTS -Xloggc:/var/log/cassandra/gc.log"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:+UseGCLogFileRotation"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:NumberOfGCLogFiles=10"
# $env:JVM_OPTS="$env:JVM_OPTS -XX:GCLogFileSize=10M"
# Configure the following for JEMallocAllocator and if jemalloc is not available in the system
# library path (Example: /usr/local/lib/). Usually "make install" will do the right thing.
# set LD_LIBRARY_PATH=<JEMALLOC_HOME>/lib/
# $env:JVM_OPTS="$env:JVM_OPTS -Djava.library.path=<JEMALLOC_HOME>/lib/"
# uncomment to have Cassandra JVM listen for remote debuggers/profilers on port 1414
# $env:JVM_OPTS="$env:JVM_OPTS -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=1414"
# Prefer binding to IPv4 network intefaces (when net.ipv6.bindv6only=1). See
# http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6342561 (short version:
# comment out this entry to enable IPv6 support).
$env:JVM_OPTS="$env:JVM_OPTS -Djava.net.preferIPv4Stack=true"
# jmx: metrics and administration interface
#
# add this if you're having trouble connecting:
# $env:JVM_OPTS="$env:JVM_OPTS -Djava.rmi.server.hostname=<public name>"
#
# see
# https://blogs.oracle.com/jmxetc/entry/troubleshooting_connection_problems_in_jconsole
# for more on configuring JMX through firewalls, etc. (Short version:
# get it working with no firewall first.)
$env:JVM_OPTS="$env:JVM_OPTS -Dcom.sun.management.jmxremote.port=$JMX_PORT"
$env:JVM_OPTS="$env:JVM_OPTS -Dcom.sun.management.jmxremote.ssl=false"
$env:JVM_OPTS="$env:JVM_OPTS -Dcom.sun.management.jmxremote.authenticate=false"
#$env:JVM_OPTS="$env:JVM_OPTS -Dcom.sun.management.jmxremote.password.file=/etc/cassandra/jmxremote.password"
$env:JVM_OPTS="$env:JVM_OPTS $JVM_EXTRA_OPTS"
$env:JVM_OPTS = "$env:JVM_OPTS -Dlog4j.configuration=log4j-server.properties"
}