diff --git a/.gitignore b/.gitignore
index 8631a91e4e8d1019182ff3b11108d2068bb13630..70b94621add4e12de3cb8a4ace39b3d1e3368fd9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,6 @@
 *.o
 *.hi
 *.hp
-.dir
 
 # /
 /Makefile
@@ -30,6 +29,7 @@
 /epydoc.conf
 /ganeti
 /stamp-srclinks
+/stamp-directories
 /vcs-version
 /*.patch
 /*.tar.bz2
diff --git a/Makefile.am b/Makefile.am
index 1ca30d0cda041175a39ef91885b03d24bd21da6b..3c95893f3ed8298d67a1616cb870d78a4c88ce88 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -115,8 +115,6 @@ DIRCHECK_EXCLUDE = \
 	ganeti-[0-9]*.[0-9]*.[0-9]* \
 	doc/html/_*
 
-all_dirfiles = $(addsuffix /.dir,$(DIRS) $(BUILDTIME_DIR_AUTOCREATE))
-
 # some helper vars
 COVERAGE_DIR = doc/coverage
 COVERAGE_PY_DIR = $(COVERAGE_DIR)/py
@@ -140,7 +138,6 @@ CLEANFILES = \
 	$(addsuffix /*.py[co],$(DIRS)) \
 	$(addsuffix /*.hi,$(HTOOLS_DIRS)) \
 	$(addsuffix /*.o,$(HTOOLS_DIRS)) \
-	$(all_dirfiles) \
 	$(PYTHON_BOOTSTRAP) \
 	epydoc.conf \
 	$(REPLACE_VARS_SED) \
@@ -153,6 +150,7 @@ CLEANFILES = \
 	$(man_MANS) \
 	$(manhtml) \
 	tools/kvm-ifup \
+	stamp-directories \
 	stamp-srclinks \
 	$(nodist_pkgpython_PYTHON) \
 	$(HS_ALL_PROGS) $(HS_BUILT_SRCS) \
@@ -169,8 +167,8 @@ BUILT_SOURCES = \
 
 built_base_sources = \
 	ganeti \
-	stamp-srclinks \
-	$(all_dirfiles)
+	stamp-directories \
+	stamp-srclinks
 
 built_python_base_sources = \
 	lib/_autoconf.py \
@@ -422,7 +420,7 @@ HS_LIB_SRCS = \
 HS_BUILT_SRCS = htools/Ganeti/HTools/Version.hs htools/Ganeti/Constants.hs
 HS_BUILT_SRCS_IN = $(patsubst %,%.in,$(HS_BUILT_SRCS))
 
-$(RUN_IN_TEMPDIR): | $(all_dirfiles)
+$(RUN_IN_TEMPDIR): | stamp-directories
 
 # Note: we use here an order-only prerequisite, as the contents of
 # _autoconf.py are not actually influencing the html build output: it
@@ -1082,7 +1080,7 @@ htools/Ganeti/Constants.hs: htools/Ganeti/Constants.hs.in \
 	set -e; \
 	{ cat $< ; PYTHONPATH=. $(CONVERT_CONSTANTS); } > $@
 
-lib/_autoconf.py: Makefile | lib/.dir
+lib/_autoconf.py: Makefile | stamp-directories
 	set -e; \
 	{ echo '# This file is automatically generated, do not edit!'; \
 	  echo '#'; \
@@ -1154,7 +1152,7 @@ lib/_autoconf.py: Makefile | lib/.dir
 	  echo "XEN_CMD = '$(XEN_CMD)'"; \
 	} > $@
 
-lib/_vcsversion.py: Makefile vcs-version | lib/.dir
+lib/_vcsversion.py: Makefile vcs-version | stamp-directories
 	set -e; \
 	VCSVER=`cat $(abs_top_srcdir)/vcs-version`; \
 	{ echo '# This file is automatically generated, do not edit!'; \
@@ -1213,7 +1211,7 @@ scripts/%: MODULE = ganeti.client.$(subst -,_,$(notdir $@))
 tools/ensure-dirs: MODULE = ganeti.tools.ensure_dirs
 $(HS_BUILT_TEST_HELPERS): TESTROLE = $(patsubst test/%,%,$@)
 
-$(PYTHON_BOOTSTRAP): Makefile | $(all_dirfiles)
+$(PYTHON_BOOTSTRAP): Makefile | stamp-directories
 	test -n "$(MODULE)" || { echo Missing module; exit 1; }
 	set -e; \
 	{ echo '#!/usr/bin/python'; \
@@ -1251,9 +1249,13 @@ $(HS_BUILT_TEST_HELPERS): Makefile
 	} > $@
 	chmod u+x $@
 
+stamp-directories: Makefile
+	@mkdir_p@ $(DIRS) $(BUILDTIME_DIR_AUTOCREATE)
+	touch $@
+
 # We need to create symlinks because "make distcheck" will not install Python
 # files when building.
-stamp-srclinks: Makefile | $(all_dirfiles)
+stamp-srclinks: Makefile | stamp-directories
 	set -e; \
 	for i in $(srclink_files); do \
 		if test ! -f $$i -a -f $(abs_top_srcdir)/$$i; then \
@@ -1417,11 +1419,6 @@ install-exec-local:
 	  "$(DESTDIR)${localstatedir}/log/ganeti" \
 	  "$(DESTDIR)${localstatedir}/run/ganeti"
 
-# To avoid conflicts between directory names and other targets, a file inside
-# the directory is used to ensure its existence.
-%.dir:
-	@mkdir_p@ $* && touch $@
-
 .PHONY: apidoc
 if WANT_HTOOLSAPIDOC
 apidoc: py-apidoc hs-apidoc