diff --git a/.gitignore b/.gitignore
index 80bd7878d07d2cec254facb1ed7fc7fb52ad3820..cc6be7f79e5d6b9ea0e0180c15ddb3a9b5575486 100644
--- a/.gitignore
+++ b/.gitignore
@@ -102,6 +102,7 @@
 /htools/hscan
 /htools/hail
 /htools/hspace
+/htools/htools
 /htools/test
 /htools/*.prof*
 /htools/*.stat
diff --git a/Makefile.am b/Makefile.am
index 8efd02790163af1b18eaca30f808502260f0e94f..3e230322cd9c1bc7e29c644e4925e82c61c9d841 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -308,7 +308,8 @@ HS_PROGS = \
 	htools/hbal \
 	htools/hscan \
 	htools/hail \
-	htools/hspace
+	htools/hspace \
+	htools/htools
 
 HS_ALL_PROGS = $(HS_PROGS) htools/test
 HS_PROG_SRCS = $(patsubst %,%.hs,$(HS_ALL_PROGS))
@@ -580,7 +581,8 @@ man_MANS = \
 	man/hail.1 \
 	man/hbal.1 \
 	man/hscan.1 \
-	man/hspace.1
+	man/hspace.1 \
+	man/htools.1
 
 manrst = $(patsubst %.1,%.rst,$(patsubst %.7,%.rst,$(patsubst %.8,%.rst,$(man_MANS))))
 manhtml = $(patsubst %.rst,%.html,$(manrst))
diff --git a/htools/htools.hs b/htools/htools.hs
new file mode 100644
index 0000000000000000000000000000000000000000..bd3803d8765fe8cc563da21bc0881e694a956385
--- /dev/null
+++ b/htools/htools.hs
@@ -0,0 +1,54 @@
+{-| Main htools binary.
+
+-}
+
+{-
+
+Copyright (C) 2011 Google Inc.
+
+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.
+
+-}
+
+module Main (main) where
+
+import Data.Char (toLower)
+import System
+import System.IO
+
+import Ganeti.HTools.Utils
+
+-- | Supported binaries.
+personalities :: [(String, IO ())]
+personalities = []
+
+-- | Display usage and exit.
+usage :: String -> IO ()
+usage name = do
+  hPutStrLn stderr $ "Unrecognised personality '" ++ name ++ "'."
+  hPutStrLn stderr "This program must be installed under one of the following\
+                   \ names:"
+  mapM_ (hPutStrLn stderr . ("  - " ++) . fst) personalities
+  hPutStrLn stderr "Please either rename/symlink the program or set\n\
+                   \the environment variable HTOOLS to the desired role."
+  exitWith $ ExitFailure 1
+
+main :: IO ()
+main = do
+  binary <- getEnv "HTOOLS" `catch` (\_ -> getProgName)
+  let name = map toLower binary
+      boolnames = map (\(x, y) -> (x == name, y)) personalities
+  select (usage name) boolnames
diff --git a/man/footer.rst b/man/footer.rst
index 44d7f958d84e9155449fc91ff96508ffbfccf0e2..2ded5ba1978f28054e1c8c66a348b39360a39af3 100644
--- a/man/footer.rst
+++ b/man/footer.rst
@@ -23,9 +23,9 @@ Ganeti daemons: **ganeti-watcher**(8) (automatic instance restarter),
 daemon), **ganeti-masterd**(8) (master daemon), **ganeti-rapi**(8)
 (remote API daemon).
 
-Ganeti htools: **hbal**(1) (cluster balancer), **hspace**(1) (capacity
-calculation), **hail**(1) (IAllocator plugin), **hscan**(1) (data
-gatherer from remote clusters).
+Ganeti htools: **htools**(1) (generic binary), **hbal**(1) (cluster
+balancer), **hspace**(1) (capacity calculation), **hail**(1) (IAllocator
+plugin), **hscan**(1) (data gatherer from remote clusters).
 
 COPYRIGHT
 ---------
diff --git a/man/htools.rst b/man/htools.rst
new file mode 100644
index 0000000000000000000000000000000000000000..116309970c0f29b776016a212b1f9b224cf44fd0
--- /dev/null
+++ b/man/htools.rst
@@ -0,0 +1,93 @@
+HTOOLS(1) Ganeti | Version @GANETI_VERSION@
+===========================================
+
+NAME
+----
+
+htools - Cluster allocation and placement tools for Ganeti
+
+SYNOPSIS
+--------
+
+**hbal**
+  cluster balancer
+
+**hspace**
+  cluster capacity computation
+
+**hail**
+  IAllocator plugin
+
+**hscan**
+  saves cluster state for later reuse
+
+
+DESCRIPTION
+-----------
+
+
+``htools`` is a suite of tools designed to help with allocation/movement
+of instances and balancing of Ganeti clusters. ``htools`` is also the
+generic binary that must be symlinked or hardlinked under each tool's
+name in order to perform the different functions. Alternatively, the
+environment variable HTOOLS can be used to set the desired role.
+
+Installed as ``hbal``, it computes and optionally executes a suite of
+instance moves in order to balance the cluster.
+
+Installed as ``hspace``, it computes how many additional instances can
+be fit on a cluster, while maintaining N+1 status. It can run on models
+of existing clusters or of simulated clusters.
+
+Installed as ``hail``, it acts as an IAllocator plugin, i.e. it is used
+by Ganeti to compute new instance allocations and instance moves.
+
+Installed as ``hscan``, it scans the local or remote cluster state and
+saves it to files which can later be reused by the other roles.
+
+COMMON OPTIONS
+--------------
+
+Options behave the same in all program modes, but not all program modes
+support all options. Some common options are:
+
+-v, --verbose
+  Increase the output verbosity. Each usage of this option will
+  increase the verbosity (currently more than 2 doesn't make sense)
+  from the default of one.
+
+-q, --quiet
+  Decrease the output verbosity. Each usage of this option will
+  decrease the verbosity (less than zero doesn't make sense) from the
+  default of one.
+
+-V, --version
+  Just show the program version and exit.
+
+UNITS
+~~~~~
+
+Some options accept not simply numerical values, but numerical values
+together with a unit. By default, such unit-accepting options use
+mebibytes. Using the lower-case letters of *m*, *g* and *t* (or their
+longer equivalents of *mib*, *gib*, *tib*, for which case doesn't
+matter) explicit binary units can be selected. Units in the SI system
+can be selected using the upper-case letters of *M*, *G* and *T* (or
+their longer equivalents of *MB*, *GB*, *TB*, for which case doesn't
+matter).
+
+More details about the difference between the SI and binary systems can
+be read in the *units(7)* man page.
+
+ENVIRONMENT
+-----------
+
+The environment variable ``HTOOLS`` can be used instead of
+renaming/symlinking the programs; simply set it to the desired role and
+then the name of the program is no longer used.
+
+.. vim: set textwidth=72 :
+.. Local Variables:
+.. mode: rst
+.. fill-column: 72
+.. End: