contact
----------------------------

Blog <-

gCountDown v1.0: Systray countdown timer for Linux

I've released v1.0 of the gCountDown program.

gCountDown is a very simple alarm countdown timer. It sits in your system tray where you can click it to set an alarm. Once the time runs out, you will be alerted.

This release adds the ability to play a sound when an alarm goes off pops up a menu on right-clicking the icon so you can quit the application and has some minor bugfixes. A Debian/Ubuntu package is now also available.

Stop Pingback/Trackback Spam on WordPress

I guess the spammers finally found my blog, cause I've been getting a lot of pignback/trackback spam. I tried some anti-spam plugins, but none really worked, so I disabled pingbacks altogether. Here's how:

First, log into wordpress as an admin. Go to Settings → Discussion, and uncheck the Allow link notifications from other blogs (pingbacks and trackbacks.) box.

That's not all though, cause that just works for new articles. Old ones will still allow ping/trackbacks. As far as I could tell, WordPress doesn't have a feature to disable those for older posts, so we'll have to fiddle around in the database directly.

Connect to your MySQL server using the WordPress username and password. If you no longer remember those, you can find them in the wp-config.php file.

$ mysql -u USERNAME -p -h localhost
Password: PASSWORD
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1684228
Server version: 5.0.51a-24+lenny5 (Debian)

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql>

At the MySQL prompt, we must now switch to our WordPress database. Again, if you don't remember the name, you can find it in the wp-config.php file. In my case, it is em_wordpress

mysql> USE em_wordpress;
Database changed

Finally, we update all posts and disable ping backs on them:

mysql> UPDATE wp_posts SET ping_status = 'closed';
Query OK, 1084 rows affected (0.10 sec)
Rows matched: 1084  Changed: 1084  Warnings: 0

There we go. No more ping- and trackback spam on old posts.

Creating simple Debian packages

Here's a quick way to create your own Debian package. This is merely a simple package which will not be included in the official Debian repositories, so we can ignore most of the Debian packaging guidelines.

First off, we need to create a directory which shall hold the contents of the package. In this case, a simple Python script called 'myscript'.

mkdir myscript

Next, we need to create the control file. This file contains some meta-data for the Debian package such as the name, description, etc. It lives in a special directory called 'DEBIAN' in the root of the package.

mkdir myscript/DEBIAN
vi myscript/DEBIAN/control

We put the following contents in the control file

Package: myscript
Version: 0.1
Section: utils
Priority: optional
Architecture: all
Essential: no
Depends: python
Maintainer: Your Name 
Description: The short description of the script
 A longer description of the descript, possible
 spanning multiple lines.

Most of these fields are rather self-explanatory. You can find a list of valid Sections on the "List of Sections" page. Make sure to use the last part of the URL, not the actual title of the section. For scripts, the Architecture will almost always be 'all'. The Depends field tells the package installation software which other packages should be installed for this package to work correctly. Multiple packages can be specified by separating them with commas. See Chapter 7 of the Debian Policy Manual for details. The Description field is a single line containing a simple description of the package. The extended description can be placed under it, and may span multiple lines. Prefix each line with a single space.

Now we add the actual contents of the package to the myscript directory. We shall be installing the script in /usr/bin, so we create that directory and place our script in it.

mkdir -p myscript/usr/bin
cp ~/dev/myscript myscript/usr/bin/

Here's the final directory layout of the myscript directory:

myscript
myscript/usr
myscript/usr/bin
myscript/usr/bin/myscript
myscript/DEBIAN
myscript/DEBIAN/control

The final step: actually creating the package!

fakeroot dpkg-deb --build myscript

fakeroot is a special tool that runs another program (in this case dpkg-deb) and fakes all filesystem ownerships as being 'root:root'. This is needed because the files in this Debian package need to be owned by root. The dpkg-deb --build command takes care of creating the package.

The myscript.deb Debian package can now be installed on your system using dpkg:

dpkg -i ./myscript.deb

Users of a GUI can usually right-click .deb files in their file managers and choose to install them from there. There are no special things to consider for de-installation of the package, unless the binary in your package creates files in non-temporary storage or users' homedirs.

Please note again that this is not an official Debian package, and is missing many things required in well-made Debian packages ready for inclusion in the official Debian repositories.

Update::

If you want to include configuration files in the package, just add a etc/ directory in your package:

myscript
myscript/etc
myscript/etc/myscript
myscript/etc/myscript/myscript.conf

Normally when upgrading a package that contains a configuration file, Debian asks:

Configuration file `/etc/myscript/myscript.conf'
 ==> Modified (by you or by a script) since installation.
 ==> Package distributor has shipped an updated version.
   What would you like to do about it ?  Your options are:
    Y or I  : install the package maintainer's version
    N or O  : keep your currently-installed version
      D     : show the differences between the versions
      Z     : start a shell to examine the situation
 The default action is to keep your current version.
*** tvtgrab.conf (Y/I/N/O/D/Z) [default=N] ? 

To get the same thing for your package, you'll have to let dpkg know which files are configuration files. You can do so by including a conffiles in the DEBIAN directory:

cat myscript/DEBIAN/conffiles
/etc/myscript/myscript.conf

Debian will now recognize your configuration files.

gCountDown: Systray countdown timer for Linux

I needed an easy way to set timers on my desktop PC. All I really want is to set a countdown in hours, minutes and seconds, and have it alert me when that time has elapsed. I couldn't find anything simple with some exceptions that wouldn't compile (anymore) due to missing libs (which weren't available in Xubuntu). So I whipped up my own.

You can download it from its home page, and here's a screenshot of the thing:

Additionally, I was quite amazed at how easy it is to write GUI applications using just GTK in combination with Glade. Writing this tool took me only about an hour, with no previous knowledge. All it really required was creating a GTK Status Icon with an active signal handler. The handler pops up an interface put together in Glade by loading the gcountdown.glade file using gtk.glade.XML(). Connecting signals to the widgets is also super easy with signal_autoconnect().

Take a look at the source code. It's only a measly 136 lines.

Redirect stdout and stderr to a logger in Python

I'm writing a daemon and needed a method of redirecting anything that gets sent to the standard out and standard error file descriptors (stdout and stderr) to a logging facility. I googled around a bit, but couldn't find a satisfactory solution, so I came up with this.

import logging
import sys
 
class StreamToLogger(object):
   """
   Fake file-like stream object that redirects writes to a logger instance.
   """
   def __init__(self, logger, log_level=logging.INFO):
      self.logger = logger
      self.log_level = log_level
      self.linebuf = ''
 
   def write(self, buf):
      for line in buf.rstrip().splitlines():
         self.logger.log(self.log_level, line.rstrip())
 
logging.basicConfig(
   level=logging.DEBUG,
   format='%(asctime)s:%(levelname)s:%(name)s:%(message)s',
   filename="out.log",
   filemode='a'
)
 
stdout_logger = logging.getLogger('STDOUT')
sl = StreamToLogger(stdout_logger, logging.INFO)
sys.stdout = sl
 
stderr_logger = logging.getLogger('STDERR')
sl = StreamToLogger(stderr_logger, logging.ERROR)
sys.stderr = sl
 
print "Test to standard out"
raise Exception('Test to standard error')

We define a custom file-like object called StreamToLogger object which sends anything written to it to a logger instead. We then create two instances of that object and replace sys.stdout and sys.stderr with our fake file-like instances.

The output logfile looks like this:

2011-08-14 14:46:20,573:INFO:STDOUT:Test to standard out
2011-08-14 14:46:20,573:ERROR:STDERR:Traceback (most recent call last):
2011-08-14 14:46:20,574:ERROR:STDERR:  File "redirect.py", line 33, in 
2011-08-14 14:46:20,574:ERROR:STDERR:raise Exception('Test to standard error')
2011-08-14 14:46:20,574:ERROR:STDERR:Exception
2011-08-14 14:46:20,574:ERROR:STDERR::
2011-08-14 14:46:20,574:ERROR:STDERR:Test to standard error

(Finite-) State Machines in practice

(The lastest version of this article is always available in from this location).

1. Introduction

A (Finite-) State Machine is a method of determining output by reading input and switching the state of the machine (computer program). Depending on the type of State Machine (more on this later), the state of the machine is changed by looking at the current state, sometimes in combination with looking at the input.

Read the rest of this entry »

ePub versions of Writings now available

I've generated ePub versions (for reading in ebook readers) of most of the Writings to the page.

Netfilter (iptables) performance tests

Here's a nice study on the performance of Linux's network firewalling/packet mangling layer:

Netfilter Performance Testing

Conclusions (mine, based on the study):

  • Netfilter/iptables is up to par with other filter solutions when it comes to plain routing.
  • Netfilter/iptables is not up to par with other filter solutions when it comes to connection tracking (basically just getting all the traffic through netfilter and keeping track of it) and filtering
  • When a chain has many rules, netfilter/iptables filtering performance drops significantly. Chain modifications (adding rules) performance also degrades significantly. This starts at 256 rules, so don't use more.

The problems seem to stem from the way Netfilter stores and processes the rules:

It is well known that netfilter/iptables does not scale well if one wants to use large number of rules in a single chain. The reason of the problem lies in the fact that the rules are processed in netfilter/iptables one after another, linearly.

Minecraft Server optimization

The Minecraft server was running very slowly and gobbling up a significant amount of memory. Game-play was laggy, chunk loading stuttery and I saw a LOT of the following message in the server.log:

[WARNING] Can't keep up! Did the system time change, or is the server overloaded?

I decided to unleash my google-fu, dug through the Java manuals and found some optimizations that:

  • Significantly reduced the CPU load.
  • Reduced the memory usage of Minecraft from about 80% to 20 to 30% (of 1Gb). That means you can run Minecraft server on as little as 200Mb.
  • Got rid of the "Can't keep up!" messages.
  • Reduced lag on the server to almost nothing.
  • Reduced chunk loading stuttering.

It does seem there has been a slight increase in chunks not loading properly, but that might be my imagination.

So what did I do? It's really simple:

  • Run the Minecraft server and world from a RAM disk. This will greatly enhance performance of loading chunks and at the same time reduce CPU load. Memory usage in total will go up (because the entire world is now in RAM), but since the new Minecraft McRegion storage format (introduced in Minecraft v1.3 Beta) uses a lot less disk space, it's no big deal.
  • Provide the -Xincgc option to Java. This enabled the concurrent incremental garbage collector, which basically means that Java won't pause for a couple of seconds to clean up old unused stuff (unloaded chunks). This reduces lag and choppiness in the loading of chunks/movement of mobs and destruction/placement of blocks.

I'll discuss here how to set up a RAM disk and how to make persistent copies of your live Minecraft map (or you'd lose everything on reboot).

Setting up a RAM disk

This section assumes that you're running under GNU/Linux, you've got Minecraft in a directory /home/minecraft/minecraft/minecraft_server/ (the directory where the minecraft_server.jar lives). Commands are prefixed by either a '$' or a '#' prompt, meaning you should either run the command as the minecraft user (or whichever user has read/write access to the minecraft server) or the root user.

Let's get started! First, check how much space you will need for your minecraft world:

$ du -hs /home/minecraft/minecraft/minecraft_server
50M	/home/minecraft/minecraft/minecraft_server

The minecraft directory is currently using 50mb. It's already a fairly large world, so we'll give it double that: 100Mb.

Now, move the minecraft_server directory to a different name, because we need to create an empty RAM disk in its place:

$ mv /home/minecraft/minecraft/minecraft_server /home/minecraft/minecraft/minecraft_server.persistent
$ mkdir /home/minecraft/minecraft/minecraft_server

Next, add an entry for the RAM disk to /etc/fstab. This will make sure it is automatically remounted when your system restarts

$ sudo echo "tmpfs    /home/minecraft/minecraft/minecraft_server     tmpfs    rw,size=100M    0    0" >> /etc/fstab

Mount it:

# mount /home/minecraft/minecraft/minecraft_server

Copy the contents off the backup minecraft_server directory over to the RAM disk:

$ cp -ar /home/minecraft/minecraft/minecraft_server.persistent/* /home/minecraft/minecraft/minecraft_server/

You can now start Minecraft with the following command:

$ tmux new -d -n "minecraft" "minecraft" "java -Xincgc -Xmx1G -jar minecraft_server.jar nogui"

Making persistent copies

It is imperative that you regularly create a persistent copy of the RAM disk! If the power on your server ever fails (or if you reboot it manually), your world is LOST! If you're running the Minecraft server in a `tmux` session (and you've started tmux with: 'tmux -n minecraft -s minecraft'), you can create a shellscript and call it from a CRON job say every hour. You can also get my Minecraft Server run script, which can also do backups and start/stop the Minecraft server without having to attach to the console. But for those who just want the persistent-copy script, here you go:

PATH_MC="/home/minecraft/minecraft/minecraft_server"

# Temporary turn off MC saving so we don't get a corrupt backup
tmux send -t "minecraft" "save-off" C-m
tmux send -t "minecraft" "save-all" C-m
# Wait until the MC server log indicates the save is complete
while true; do
    sleep 0.2
    TMP=`grep "Save complete." $PATH_MC/server.log | wc -l`
    if [ $TMP -gt $SAVE_COMPLETE ]; then
        break
    fi
done
# Create persistent copy from RAM to disk
rm -rf "$PATH_MC.persistent"
cp -ar "$PATH_MC" "$PATH_MC.persistent"
# Turn world saving back on
tmux send -t "minecraft" "save-on" C-m

Save it as a file called /home/minecraft/mc_persistent.sh and make it executable:

chmod 750 /home/minecraft/mc_persistent.sh

Create a now cronjob and call it every hour:

0 * * * * /home/minecraft/mc_persistent.sh

That's it! Happy lag-free mining.

MCPlayerEdit v0.19 released

I've released a new version of my Minecraft Player/World Editor MCPlayerEdit v0.19. This release features the following modifications and additions:

  • Added a `health` command which lets you set the player health (also a god-mode)
  • Fixed a bug where only supplying an item ID to give/remove would not give the maximum stack size but would give a stack equal in size to the item ID specified.
  • Fixed a bug where adding non-safe items to the inventory would give a stack size of 0.

You can get the new version Here.