Bukkit control script

This post is a work in progress I’m sure I’m forgetting things.

This is a heavily modified version of this startup script. If you don’t know what you are doing please find someone who does. Some of the stuff I do here can break your server. This script is provided as is and will probably be updated ever once in a while to fix problems.  So check back for updates or send me your changes. Also remember if you have a very large map this can add several minutes to your servers boot time as the files are copied from disk to the ramdisk at boot.

Things I have modified

  1. Changed script to work with bukkit instead of vanilla Minecraft.
  2. Replaced cp and rm commands with simpler and faster rsync.
  3. Added MAX_RAM setting for startup
  4. Changed options for startup. I’m sure some options are debatable.
  5. Added sndmsg command so that simple messages can be sent to the server console.
  6. Removed update command. I just don’t want it for bukkit.
  7. Added 60 second sleep on shutdown to give users time to logout after server says it is going down.

Just a warning about using this script. It is not fully tested. You really should understand what is going on in the script before using it. This version has been sanitized a bit and is not fully tested.

You will need to install some version of linux or similar OS to run this script.  I personally use CentOS.  See here for how I setup CentOS for Minecraft.

This startup script assumes you are running Bukkit from a ramdisk. The ramdisk is simple to setup. Figure out where you want to mount the ramdisk. I use /minecraft1 for the mount point. mkdir /minecraft1 to create the mount point. Now edit /etc/fstab and add

tmpfs /minecraft1 tmpfs defaults,size=6144m 0 0

That line will create a 6GB ramdisk at boot. You should change the size option to match the amount of ram you want for the bukkit map files and plugins. I store everything in the ramdisk. It can be broken up if you don’t want to store all the plugin data on the ramdisk.  Remember you need enough ram in your system for MAX_RAM and the ramdisk.  In my case I need over 12GB of ram to run bukkit and basic system services.

Next you will need to add the code below to the startup script.  I place mine in /etc/init.d/minecraft.  Once the script is added run chkconfig –add minecraft to add the script to the normal startup of the server.  chkconfig –list will list all running services.  You should see something like this for minecraft:
minecraft 0:off 1:off 2:on 3:on 4:on 5:on 6:off
If all the run levels are off do chkconfig --levels 2345 minecraft on. You should be able to test your server startup now by running /etc/init.d/minecraft start.


#!/bin/bash
# /etc/init.d/minecraft
# original version of script http://www.minecraftwiki.net/wiki/Tutorials/Ramdisk_enabled_server
# Heavily modified by drewmtb
# version 0.6 2012-02-17
# changes made drewmtb
# removed the world2 stuff mv and rm -r
# changed cp -R to rsync its faster
# added MAX_RAM variable
# innvocation has been modified. Your mileage may vary
# added sndmsg option for sending messages to server
# added 60 second sleep to mc_stop before stop is run to give users time to logout
# update removed we don't want to do that for bukkit

### BEGIN INIT INFO
# Provides: minecraft
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Minecraft server
# Description: Starts the minecraft server
### END INIT INFO

#Settings
# jar file for startup
SERVICE='craftbukkit.jar'
# username to startup as
USERNAME="minecraft"
# location of minecraft source files for ramdisk
MCSTORE='/home/minecraft/bukkit'
# location of minecraft ramdisk
MCPATH='/home/minecraft/bukkit_ramdisk'
# number of CPUs to use for startup
CPU_COUNT=4
# amount of ram to give bukkit
MAX_RAM=6144M
# These settings are up for debate
INVOCATION="java -native -server -Xmx$MAX_RAM -Xms$MAX_RAM -Xmn1024M -XX:NewRatio=3 -XX:+UseThreadPriorities -XX:+U
seConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+CMSIncrementalPacing -oss4M -ss4M -XX:+UseFastAccessorMethods
-Xnoclassgc -XX:+AggressiveOpts -jar $SERVICE nogui"
# path to backup files to
BACKUPPATH='/backup1/minecraft/daily'
# used by sndmsg to post messages to the server
SRVMSG=$2

ME=`whoami`
as_user() {
if [ "$ME" == "$USERNAME" ] ; then
bash -c "$1"
else
su - $USERNAME -c "$1"
fi
}

mc_start() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "Tried to start but $SERVICE was already running!"
else
echo "$SERVICE was not running... starting."
cd $MCPATH
if [ ! -f "$MCPATH/$SERVICE" ]
then
echo "Ram drive empty... prepping."
as_user "rsync --archive --update --quiet $MCSTORE/ $MCPATH/"
fi
as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
sleep 7
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is now running."
else
echo "Could not start $SERVICE."
fi
fi
}

mc_saveoff() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... suspending saves"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP STARTING. Server going readonl
y...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sync
sleep 10
else
echo "$SERVICE was not running. Not suspending saves."
fi
}

mc_saveon() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... re-enabling saves"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER BACKUP ENDED. Server going read-write
...\"\015'"
else
echo "$SERVICE was not running. Not resuming saves."
fi
}

mc_sndmsg() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say $SRVMSG\"\015'"
else
echo "$SERVICE was not running. Not resuming saves."
fi
}

mc_stop() {
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running... stopping."
as_user "screen -p 0 -S minecraft -X eval 'stuff \"say SERVER SHUTTING DOWN IN 60 SECONDS. Saving m
ap...\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
sleep 60
as_user "screen -p 0 -S minecraft -X eval 'stuff \"stop\"\015'"
sleep 5
else
echo "$SERVICE was not running."
fi
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE could not be shut down... still running."
else
echo "$SERVICE is shut down."
fi
}

mc_backup() {
echo "Backing up minecraft files"
if [ -f $BACKUPPATH/MCBKUP_`date "+%Y.%m.%d"`-0.tar.gz ]
then
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
do
if [ -f $BACKUPPATH/MCBKUP_`date "+%Y.%m.%d"`-$i.tar.gz ]
then
continue
else
as_user "cd $MCSTORE && tar czf $BACKUPPATH/MCBKUP_`date "+%Y.%m.%d"`-$i.tar.gz ."
break
fi
done
else
as_user "cd $MCSTORE && tar czf $BACKUPPATH/MCBKUP_`date "+%Y.%m.%d"`-0.tar.gz ."
fi
echo "Backup complete"
}

mc_disksaverun() {

if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "Saving ramdrive to disk."
if [ ! -f $MCPATH/$SERVICE ]
then
echo "Error.. Minecraft not in ram"
else
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-off\"\015'"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-all\"\015'"
as_user "rsync --archive --update --quiet $MCPATH/ $MCSTORE/"
as_user "screen -p 0 -S minecraft -X eval 'stuff \"save-on\"\015'"
fi
else
echo "Service is not running"
fi

}

mc_disksavehalt() {
echo "Saving ramdrive to disk."
if [ ! -f $MCPATH/$SERVICE ]
then
echo "Error.. Minecraft not in ram"
else
echo "Saving, screen session closed"
as_user "rsync --archive --update --quiet $MCPATH/* $MCSTORE/"
fi

}

#Start-Stop here
case "$1" in
start)
mc_start
;;
stop)
mc_stop
mc_disksavehalt
;;
restart)
mc_stop
mc_disksavehalt
mc_start
;;
backup)
mc_disksaverun
mc_saveoff
mc_backup
mc_saveon
;;
sndmsg)
mc_sndmsg
;;
disksavehalt)
mc_disksavehalt
;;
disksaverun)
mc_disksaverun
;;
status)
if ps ax | grep -v grep | grep -v -i SCREEN | grep $SERVICE > /dev/null
then
echo "$SERVICE is running."
else
echo "$SERVICE is not running."
fi
;;

*)
echo "Usage: /etc/init.d/minecraft {start|stop|update|backup|status|restart|disksaverun}"
exit 1
;;
esac

exit 0