Reinstalling grub on an unbootable Debian system

Fixing an unbootable computer after a failed grub installation can be a bit tricky. Here's what I ended up doing.

First of all, boot the machine up and get access to the root partition:

  1. Get a Debian installation CD for the same architecture (i.e. don't use an i386 CD if your root partition is amd64). The distro version doesn't matter too much: a lenny CD will boot squeeze/sid just fine.
  2. Boot the install CD and select Rescue mode under Advanced options.
  3. Answer the language, keyboard and network questions any way you want and provide the decryption passphrases for any of the encrypted partitions you need to mount.
  4. When prompted, request a shell on the root partition.

If you need to upgrade the version of the grub package (for example if this problem was caused by a bug which is now fixed):

  1. Make sure that the network interface is up (ifup eth0).
  2. Make sure that /etc/resolv.conf has at least one nameserver line, otherwise add one.
  3. Install the latest version using apt-get or dpkg.

Now that you have the right grub version, run the following (with the right device name for your machine):

grub-mkdevicemap  
grub-install /dev/hda  
update-grub

Finally, reboot and cross your fingers :)

Stopping long-running Postgres queries

As part of troubleshooting performance problems in PostgreSQL, you may need to terminate a query which is taking a long time to run.

To do this, find the Postgres process which is currently executing the query:

SELECT procpid, current_query, query_start  
FROM pg_stat_activity;

The procpid column displays the Operating System's process ID that can then be used to send the INT signal which will cause Postgres to roll the query back and move on to the next one:

kill -INT procpid

If this happens regularly, you can also tell Postgres to kill any query which takes longer than a given number of milliseconds (say 1 hour) by using this setting:

statement_timeout = 3600000  

Writing the perfect patch

Other people have written and talked (in Lecture 3) about writing the perfect patch for a Free Software project. The goal there is to increase the likelihood that a patch will be accepted by the project developers.

Integrating and testing patches takes time and so reducing that burden is essential when interacting with busy maintainers. Especially if they're volunteers.

Here's what I try to keep in mind when preparing a patch.

Use the right options to diff

These two options should always be part of your call to the diff command:

  • -u: use the most common patch format, unidiff.
  • -p: include the name of the function that's being changed.

and this one can be useful if the output seems unnecessarily large:

  • -d: try hard to find a smaller set of changes.

Minimize the number of changes

You need to draw attention to the changes that you're proposing and remove all other potential distractions:

  • Follow the coding style of the original file. Your changes must fully blend in or they are likely to be rejected.
  • Do not re-indent existing code. This will make it look like you modified every line.
  • Pay attention to whitespace changes. In particular: end-of-line characters, trailing spaces and tab-versus-space differences. Use the dos2unix or unix2dos commands if you need to.
  • Gratuitous refactoring of existing code. Unless the refactoring makes your change smaller or easier to understand, keep it for another patch.

Of course all of the above would be acceptable patches on their own, just not combined with other types of changes.

Only one logical change at a time

Patches often need to be broken up into a series of logical changes to avoid these two extremes:

  • the gigantic patch which adds a number of features and fixes a couple of bugs but scares everybody
  • a series of interdependent patches which all relate to the same change and must all be applied together

It's a bit of a balancing act, but a good rule of thumb is:

  • to have one patch per feature or bug and
  • to try to find the smallest (yet meaningful) change which can be applied on its own.

It's not just about the patch

Your patch can be really good, but the email (or the bug tracker update) announcing it should also contain:

  • a good description of the problem it solves and how it solves it
  • the output of diffstat to give an idea of the size of the change