[ADMIN] Linux Init Script for Bukkit

Discussion in 'Bukkit Tools' started by Toasty, Jan 4, 2012.

Thread Status:
Not open for further replies.
  1. Offline

    Toasty

    Some admins from my server and I have been working on a shell script for Bukkit (it also works with vanilla) so that we could run it as a service on our Linux server (starts on system startup, stops properly on system shutdown/restart etc.).

    It's been in development since last November and while development's been slow, I think it's safe to say that we have a product that we're fairly satisfied with.

    For all intents and purposes, this script is a stable, usable product. We haven't slapped 1.0 on it yet as there's still some features we'd like to add to it (automatic creation of directory tree [easy], automatic backups [easy], etc.), but it gets done what we need it to get done.

    The main purpose of writing this script was so that we could put our worlds in a ramdisk with little worry that we'd lose too much data due to power failure or a system crash (neither of which we have problems with anymore anyway). We currently accomplish this with our script by setting up a cron job to run the backup command implemented in this script.


    So, without further adieu, I present to you our Linux Init Script for Bukkit:

    Wiki
    Readme
    Github

    Feel free to fork it, submit pull requests, bug reports, etc.
    This script is designed to work with both Debian based and enterprise Linux distributions, though it's only been tested on CentOS and Ubuntu.

    Requirements:

    The only requirement is that you have Screen installed on your system.

    Releases:

    v0.4.3 - Patch for lockfile error and ramdisk unmounting issues
    v0.4.2 - Hotfix for broken backup functionality
    v0.4.1 - Hotfix for issue #1
    v0.4
    v0.3

    Change Log:

    v0.4.3
    • Fixed lockfile error on Ubuntu
    • Temporary fix for failure to unmount the ramdisk in some situations
    • Slight modification to command line parsing ('worldbackup' and 'rdbackup' now become 'backup worlds' and 'backup ramdisk' respectively)
    v0.4.2
    • Fixed deprecated variables in backup function
    v0.4.1
    • Fixed syntax error on line 559
    v0.4
    • Finalized support for starting service in a ramdisk
    • Modified backup functionality to incorporate making snapshots of the whole ramdisk
    v0.3
    • Added preliminary support for starting service in a ramdisk
     
    JWhy likes this.
  2. Offline

    Toasty

    Sorry about all the hotfixes (So much for being a "Stable, useable product" : P ). I made the mistake of assuming that a few small changes to the backup functions wouldn't break the script, so I didn't test that feature a second time before finalizing v0.4. We double checked the script though, and we didn't find any more errors in it.

    If anyone does find any errors in v0.4.2 though, be sure to let us know in our issue tracker on Github!

    Also, on a side note, I re-uploaded versions 0.3, 0.4, and 0.4.1 a few days ago. I accidentally included the git repository in those downloads, which made them unnecessarily large (190+ kb vs. 14-15kb).
     
  3. Offline

    MStef94

    I'm noob in things like that... but it works ;)
    This cript makes bacups and restarts automaticl or I should use cron?

    Edit:
    I have one bug :(
    Code:
    Mounting ramdisk at /root/ramdisk
    Ramdisk mounted at /root/ramdisk
    Loading ramdisk...
     is not in /root/worlds !
    Could not start craftbukkit.jar.
    
    I create links:
    Code:
    ln -s /root/worlds/world world
    and when i do it, i'm in my minecraft-server folder...


    AND if I run without ramdisk:
    Code:
    Could not start craftbukkit.jar.
    touch: cannot touch `/var/lock/subsys/minecraft': No such file or directory
    
     
  4. Offline

    Toasty

    When the script first runs, it looks in the "$ROOT_PATH/$SERVER_DIR/$BUILD" folder for your "server.properties" file. It then reads that file and takes note of the value in the "level-name=" option. It uses that later in the script when copying your worlds into the ramdisk to make sure that the world referenced in the "server.properties" file gets loaded into the ramdisk.

    From the looks of it, either that option in your server.properties file is blank, or [more likely] you haven't yet run bukkit which generates that file the first time it's run.

    Go ahead and run bukkit once without the script and it should generate that file for you. After that, make sure your server.properties file is set up properly and go ahead and start your server with the script.


    In the event that doesn't fix the problem, make absolutely sure you're in the "$ROOT_PATH/$SERVER_DIR/$BUILD" directory when making those links to your world folders.


    As for the last error regarding the lock file, that's a problem on our end with the script. Ubuntu handles service scripts differently then CentOS or RHEL, and we're trying to work out a clean solution that works for both OS's .

    We're also working on a separate [interactive] script to make it easier for end-users to install and use this service script.

    Though of course it won't be necessary, so for those of you out there who are well-versed in Linux-based OS's, you'll still be able to install it manually without any added effort.
     
  5. Offline

    MStef94

    Bukkit starts every time, if I use this script, but I don't have this folder:
    Code:
    lockfile="/var/lock/subsys/minecraft"
    Everything wits server.properties and others is fine
     
  6. Offline

    Toasty

    Change that path to "/var/lock/minecraft" and see if the error goes away. I believe Ubuntu should have a symbolic link that points to the "/var/lock" folder.
     
  7. Offline

    MStef94

    Thanks, It works, but I have another error:
    Code:
    Could not start craftbukkit.jar
    (or something like that)

    But if I use screen -r <name> ---> bukkit is already started :/
     
  8. Offline

    Toasty

    Hmm. Put your configuration on pastebin and post a link here.

    Also, I'm assuming you're using Ubuntu, but what version are you using exactly?
     
  9. Offline

    MStef94

  10. Offline

    Toasty

    The problem is that you're referencing " craftbukkit-1.0.1-R1_r1.jar" in your invocation, but in the service variable you only have "craftbukkit.jar". After the service starts, it looks for the craftbukkit jar file in the list of running processes, but it can't find it because you told the script it was named "craftbukkit.jar" when it's really named " craftbukkit-1.0.1-R1_r1.jar".

    If you want to keep track of what version you're running, make a folder in your "mc" directory labeled "1.0.1-R1", put your server files in there, and enter that label into the $BUILD variable in the settings section. Then rename your jar file to "craftbukkit.jar".

    If you don't care then either rename the value in the $SERVICE variable or rename your craftbukkit.jar file to match what's in the $SERVICE variable.
     
  11. Offline

    wachnlurn

    Im getting this when i try to start the service
    Code:
    root@216:/etc/init.d# service minecraft start
    Starting craftbukkit-1.1-R2.jar
    Loading Ramdisk
    Mounting ramdisk at /home/minecraft/ramdisk
    Ramdisk mounted at /home/minecraft/ramdisk
    Loading ramdisk...
    Could not start craftbukkit-1.1-R2.jar.
    Unloading Ramdisk.
    Saving ramdisk to disk.
    Renaming world to world-2012-01-27-11.29
    world being copied to disk
    Renaming world_nether to world_nether-2012-01-27-11.29
    world_nether being copied to disk
    Renaming world_the_end to world_the_end-2012-01-27-11.29
    world_the_end being copied to disk
    Ramdisk mounted at /home/minecraft/ramdisk.... unmounting
    Ramdisk unmounted
    root@216:/etc/init.d# service minecraft stop
    craftbukkit-1.1-R2.jar was not running.
    craftbukkit-1.1-R2.jar is shut down.
    Nothing to save, ramdisk not mounted at /home/minecraft/ramdisk
    Ramdisk was not mounted at /home/minecraft/ramdisk
    root@216:/etc/init.d# service minecraft start
    Starting craftbukkit-1.1-R2.jar
    Loading Ramdisk
    Mounting ramdisk at /home/minecraft/ramdisk
    Ramdisk mounted at /home/minecraft/ramdisk
    Loading ramdisk...
    Could not start craftbukkit-1.1-R2.jar.
    Unloading Ramdisk.
    Saving ramdisk to disk.
    Renaming world to world-2012-01-27-11.33
    world being copied to disk
    Renaming world_nether to world_nether-2012-01-27-11.33
    world_nether being copied to disk
    Renaming world_the_end to world_the_end-2012-01-27-11.33
    world_the_end being copied to disk
    Ramdisk mounted at /home/minecraft/ramdisk.... unmounting
    Ramdisk unmounted
    root@216:/etc/init.d#
    i tried it from within /home/minecraft as well same result
     
  12. Offline

    Toasty

    Could you put a copy of your configuration on pastebin? It would also be useful to know how your directory tree is set up. Is it set up the same way as described in the guide?

    On a side note, assuming you ran through the setup process properly and either ran chkconfig or update-rc.d, you should be able to type "service minecraft start/stop/etc." from any directory on your machine, since it's set up as a service. Also, if the service fails to start, the script will properly unload the ramdisk (if the feature is enabled) and shut down the service, so you needn't run the stop command if it fails to start.


    As a note to everyone in general: I've been busy the past couple weeks on another more time-sensitive project which should be finished today. Once that's done, development on the script will pick up again.
     
  13. Offline

    wachnlurn

    I am pretty sure the problem is i was trying to run the server with too much ram. My server has 6GB. I was able to get it to run like this:
    Code:
    java -Xms2048M -Xmx2048M -jar craftbukkit.jar
    anything over that it gives java heapspace error. So i have confirmed it has nothing to do with the script or my configuration of it. I was trying to start the service with 4096M but when i was just executing the startup command i was using the default of 512M and 1024M. I assume that i am running 32 bit java and that is the problem and im currently *trying* to figure out how to install 64 bit java and make sure minecraft runs on it.
    Although come to think of it i thought 32 bit could go up to 4GB of ram?

    EDIT:
    yes I believe the directory is set up the same way, i verified for about an hour before realising the ram made a difference. I reread the wiki, notes etc. everything seems to be correct
    Code:
    #!/bin/bash
    # /etc/init.d/minecraft
    # version 0.4.1 2012-01-06 (YYYY-MM-DD)
     
    ### 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
     
    # chkconfig 2345 99 01
     
    # Codecraft-init-script: Linux init script for starting minecraft as a service
    # Copyright (C) 2011-2012  Daniel Hodgson, William Haggerty, Codeprogrammers
    #
    # This program is free software; you can redistribute it and/or
    # modify it under the terms of the GNU General Public License
    # as published by the Free Software Foundation; either version 2
    # of the License, or (at your option) any later version.
    #
    # This program is distributed in the hope that it will be useful,
    # but WITHOUT ANY WARRANTY; without even the implied warranty of
    # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    # GNU General Public License for more details.
    #
    # You should have received a copy of the GNU General Public License
    # along with this program; if not, write to the Free Software
    # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
     
    #Settings
    USERNAME="root"
    GROUPNAME="root"
    SCREEN_NAME="myminecraftvps"
    BUILD="craftbukkit"
    SERVICE="craftbukkit.jar"
    INVOCATION="java -d64 -Xms2048M -Xmx2048M -jar craftbukkit.jar"
    RAMDISK="true"
    RD_SIZE="512m"
     
    #File Paths/Names
    ROOT_PATH="/home/minecraft"
    WORLD_DIR="worlds"
    SERVER_DIR="minecraft_server"
    RD_DIR="ramdisk"
    ROOT_BUPATH="$ROOT_PATH/mc_backups"
     
    #Messages (sent to minecraft server console with "say" command)
    SAVE_OFF_MSG="Server going readonly..."
    SAVE_ON_MSG="Server going read-write..."
    BACKUP_START_MSG="SERVER BACKUP STARTING"
    BACKUP_RD_START_MSG="RAMDISK BACKUP STARTING"
    BACKUP_DONE_MSG="SERVER BACKUP COMPLETE"
    BACKUP_FAIL_MSG="SERVER BACKUP FAILED"
    STOP_MSG="SERVER SHUTTING DOWN IN 15 SECONDS"
    RESTART_MSG="SERVER GOING FOR RESTART"
     
  14. Offline

    Toasty

    Run "uname -r" in a terminal and it should tell you whether or not your OS is 64-bit capable, if you're not already sure. If it is a 64-bit OS, and you're running either Ubuntu, Debian, RHEL, or CentOS, it should grab the 64-bit version of Java automatically.

    I would suggest un-installing Java and instead install OpenJDK. Notch/Mojang claims that minecraft doesn't work well with OpenJDK, but I've been using it for over a year with no issues.

    You might want to throw in the "-server" flag too, as Java only automatically runs in server mode on a system with at least 2CPU's and 2GB of RAM (except for 32-bit windows systems where it will only ever run in client mode).

    Also, for reference my startup command looks something like this:
    Code:
     java -Xmn512M -Xms1024M -Xmx5120M -XX:+UseConcMarkSweepGC -XX:+UseParNewGC -XX:ParallelGCThreads=1 -XX:+CMSParallelRemarkEnabled -XX:+DisableExplicitGC -XX:MaxGCPauseMillis=500 -XX:SurvivorRatio=8 -XX:TargetSurvivorRatio=90 -jar craftbukkit.jar 
    There's a lot of JVM optimization flags in there, but the stuff most relevant to you is the first three flags.

    -Xmn512M says to set the heap size for the young generation to 512MB
    -Xms1024M says to set the initial Java heap size to 1GB
    -Xmx5120M says to set the maximum Java heap size to 5GB

    Setting a smaller initial heap size than the maximum size allows the JVM to be more efficient with it's usage of memory. Too low though, and performance will be slow until it allocates enough RAM. Our server is pretty low-key right now, so we don't have to worry about having too many people on at once. Therefore, we can set our initial heap size to a smaller amount.

    Having a larger young generation heap can improve performance as it can accomodate more short-lived objects, preventing them from being pushed into the old generation where garbage collection is slower and more costly (the server has to come to a complete stop while garbage collection is performed, which is what usually happens when you try to break a block and it doesn't work, or when blocks you just broke spontaneously re-appear).

    I should probably bump the size of my young generation come to think of it....
     
  15. Offline

    wachnlurn

    Thanks for responding i plan on tweaking the startup command but i wanted to make sure i have things correct first, and ive been stuck on this issue for a while now. Ive confirmed it is 32 bit java as -d64 does not even work in the startup command, but i do not know if my OS is 64 bit. I have many options available if i have to reinstall the OS.

    uname -r gives
    Code:
    Linux 216 2.6.32-38-generic-pae #83-Ubuntu SMP Wed Jan 4 12:11:13 UTC 2012 i686 GNU/Linux
    and the java version is
    Code:
    root@216:/usr/java# java -version
    java version "1.6.0_20"
    OpenJDK Runtime Environment (IcedTea6 1.9.10) (6b20-1.9.10-0ubuntu1~10.04.3)
    OpenJDK Server VM (build 19.0-b09, mixed mode)
     
  16. Offline

    Toasty

    "i686" means you're running a 32-bit OS, so yes, you may want to consider re-installing the OS. I would personally suggest CentOS 6 since it's basically RedHat Enterprise Linux without the branding (i.e. it's designed for server environments), but it's probably best to stick with what you're most familiar with.

    Also, it seems you are in fact using OpenJDK, which is the standard for Linux distros anyway, so you're fine there.
     
  17. Offline

    wachnlurn

  18. Offline

    Toasty

    Ah, yes. I forgot to mention the Java Tuning White Paper in my previous post. I read up on that and created my list of startup flags based on the information provided, keeping in mind that bukkit/minecraft is a real-time application where long periods of garbage collection can be more harmful than more frequent, albeit shorter, periods of garbage collection.

    It's a bit of a complicated read, but well worth it imo. I do believe that most of the flags carry over into OpenJDK, despite it being different software.

    I did some testing of my own with these flags and posted them in a thread which discussed GC some time early last year. I found the garbage collection to be more frequent, but all of the collections took less than one second, and the overall time spent collecting garbage was less.

    Though EvilSeph has a point. Every configuration is different, so your mileage may vary. However, the fact that bukkit is a real-time application doesn't change. Though in most cases, it's best to simply let the JVM handle the settings unless you've got a wealth of knowledge of both how garbage collection works in Java, and how the application you're running handles memory.

    I should probably do some more testing with those flags though. The last time I ever did any kind of benchmark with them was late last year. Minecraft (and consequently Bukkit) has changed quite a bit since then.

    EDIT: After doing a little googling, it seems that -XX:UseConcMarkSweepGC also enables the parallel garbage collector for the new generation, so the flag in my command which explicitly declares the latter is unnecessary. Didn't notice that before.

    EDIT by Moderator: merged posts, please use the edit button instead of double posting.
     
    Last edited by a moderator: May 22, 2016
  19. Offline

    Aetherspawn

    +1

    Used it once, its pretty good.
     
  20. Offline

    wachnlurn

    Thanks for your help. I reinstalled the OS set everything up again and it works great. The chunks load slowly on first login. and reading your earlier post im confused now is Xmn the garbage collection? and Xms the initial ram that the server runs on while Xmx is the "max" it can get too? im fearful that i set a very high garbage collection and max which i would imagine would cause a crash once it got to the max.
    Im going to do some reading on these flags and test them out as well.
     
  21. Offline

    Toasty

    Taken from the whitepaper. Basically, the young generation is a subset of the overall Java heap. If you have 6GB of RAM, and you plan on using a 512MB ramdisk, then 4GB is a safe maximum size for your Java heap (i.e. -Xmx4G or -Xmx4096M). -Xms only declares the initial size of the Java heap, so it must be less than or equal to -Xmx. It defines the initial size of the Java heap on startup. If you set it to less than the value given to -Xmx, then the JVM will start with less RAM and use up more over time, until it reaches the maximum value given by the -Xmx flag.

    Since the -Xmn flag declares the size of the young generation, which is a subset of the Java heap, then it also must be smaller than the maximum size. Honestly I'm not entirely sure, but I think it needs to be less than the minimum size as well (or quite possibly, setting a minimum size below that declared in -Xmn makes using -Xms redundant as the JVM will merely allocate enough ram to cover the young generation and then some, but this is just speculation. I'm not an expert. : P ).

    Either way, garbage collection takes less time for objects in the young generation, so ideally you'll want to make that larger. Since the white paper gives an example with a young generation of 2GB and a max heap of 3800MB, it's safe to assume that your young generation can be larger than half the total heap size.

    Also, to reiterate, the JVM will not use up any more RAM than the amount declared in the -Xmx flag. So if you use "-Xmx4G", then the JVM will use no more than 4GB of RAM.

    You might also want to look into JConsole for monitoring the JVM's performance.
    http://docs.oracle.com/javase/6/docs/technotes/guides/management/jconsole.html
     
  22. Offline

    wachnlurn

    any idea why i keep getting symlinks of world.old world_nether.old in my craftbukkit directory?
     
  23. Offline

    Toasty

    Yes. When the script starts up with the ramdisk feature enabled, it copies the worlds from your world folder into the ramdisk. Then it renames the symlinks in your server's working directory that point to the worlds directory as [worldname].old to differentiate them from the symlinks that the script makes which point to the worlds that are now in the ramdisk. It's a bit cleaner to implement in code than deleting and recreating symlinks to both the ramdisk and the worlds folder every time.

    They should disappear when the service is stopped, and they shouldn't appear if you don't use the ramdisk feature.

    I may change how symlinks are handled in the future to make it a little more fool-proof though, and that may result in the disappearance of symlinks ending with ".old".
     
  24. Offline

    wachnlurn

    if i use the cron job example in your wiki
    Code:
    /etc/init.d/minecraft worldbackup
    will that job fail if the service is not running or will it continue to run and wipe the world?
     
  25. Offline

    Toasty

    Backups are fail-safe, so you can't lose data by running a backup. Though the command has changed. It's now "backup [worlds | ramdisk]". The only difference between running a backup while the service is running and doing a backup while it's not running is that a message isn't sent to the bukkit/minecraft console to give players a heads up.

    In the future we plan to handle management of the cron job within the script so unnecessary backups aren't created.
     
  26. Offline

    Reko

    i get this when stopping server

    Can't unload ramdisk, cb.jar is still running!
    Ramdisk mounted at /root/minecraft/mcram.... unmounting
    umount: /root/minecraft/mcram: device is busy.
    (In some cases useful info about processes that use
    the device is found by lsof(8) or fuser(1))
    umount: /root/minecraft/mcram: device is busy.
     
  27. Offline

    Pierrick584

    Most commands works (well, status does) but start does not, here's the result

    root@server:~# service minecraft start
    created link for data
    created link for players
    created link for region
    links checked
    Still not running, waiting a while longer...
    Failed to start, aborting.
     
  28. Offline

    Reko

    ok i got everything running.... do i need to cron it for backups and if so do i backup worlds or ramdisk.... and where does it place the backups? and how do i find my most recent one?
     
  29. Offline

    Toasty

    Pierrick584 : Are you using the version in the download link in the parent post? The latest stable version doesn't output any messages to the command line like what you've listed (i.e. "created link for [item]" and "links checked").

    Reko : Yes you need to set up a cron job for automatic backups. Planning on implementing automatic backups in the future, but I've been too busy to work on this script for the past few weeks. That should change soon.
     
  30. Offline

    tom

    Toasty Hey, my world mounts perfectly fine, althought nothing that players have built gets transfered?

    Keep in mind that i transfered my world from another server right onto the new one where i started fresh with ram disk. The same terrain gets transfered, just no buildings. Whats up ?

    In the world file i have all the region files, player files etc.
     
Thread Status:
Not open for further replies.

Share This Page