diff --git a/installsystems/tools.py b/installsystems/tools.py
index 7e5ebdd57294fa1c5ea34bddcf8ab32a4daaffa1..6bd512d48c6875ac8df74cab9c3eac185d2fc1bb 100644
--- a/installsystems/tools.py
+++ b/installsystems/tools.py
@@ -333,18 +333,21 @@ def human_size(num):
         num /= 1024.0
     return "%3.1f%s" % (num, x)
 
-def chroot(path, shell="/bin/bash", mount=True):
+def guess_distro(path):
     '''
-    Chroot inside a directory and call shell
-    if mount is true, mount /{proc,dev,sys} inside the chroot
+    Try to detect which distro is inside a directory
     '''
-    # try to guest distro
     if os.path.exists(os.path.join(path, "etc/debian_version")):
-        distro="debian"
+        return "debian"
     elif os.path.exists(os.path.join(path, "etc/arch-release")):
-        distro="archlinux"
-    else:
-        distro=None
+        return "archlinux"
+    return None
+
+def prepare_chroot(path, mount=True):
+    '''
+    Preate a chroot environment by mouting /{proc,sys,dev,dev/pts}
+    and try to guess dest os to avoid daemon lauching
+    '''
     # try to mount /proc /sys /dev
     if mount:
         mps = ("proc", "sys", "dev", "dev/pts")
@@ -358,6 +361,8 @@ def chroot(path, shell="/bin/bash", mount=True):
                     check_call(["mount",  "--bind", origin, target], close_fds=True)
                 except CalledProcessError as e:
                     warn("Mount failed: %s.\n" % e)
+    # try to guest distro
+    distro = guess_distro(path)
     # in case of debian disable policy
     if distro == "debian":
         arrow("Creating debian chroot housekeepers")
@@ -365,11 +370,16 @@ def chroot(path, shell="/bin/bash", mount=True):
         try: open(os.path.join(path, "etc/debian_chroot"), "w").write("CHROOT")
         except: pass
         # fake policy-d
-        try: open(os.path.join(path, "usr/sbin/policy-rc.d"), "w").write("#!/bin/bash\nexit 42\n")
+        policy_path = os.path.join(path, "usr/sbin/policy-rc.d")
+        try: open(policy_path, "w").write("#!/bin/bash\nexit 42\n")
         except: pass
-    # chrooting
-    arrow("Chrooting inside %s and running %s" % (path, shell))
-    call(["chroot", path, shell], close_fds=True)
+
+def unprepare_chroot(path, mount=True):
+    '''
+    Rollback preparation of a chroot environment inside a directory
+    '''
+    # try to guest distro
+    distro = guess_distro(path)
     # cleaning debian stuff
     if distro == "debian":
         arrow("Removing debian chroot housekeepers")
@@ -378,9 +388,23 @@ def chroot(path, shell="/bin/bash", mount=True):
             except: pass
     # unmounting
     if mount:
+        mps = ("proc", "sys", "dev", "dev/pts")
         arrow("Unmouting filesystems")
         for mp in reversed(mps):
             target = os.path.join(path, mp)
             if os.path.ismount(target):
                 arrow(target, 1)
                 call(["umount", target], close_fds=True)
+
+def chroot(path, shell="/bin/bash", mount=True):
+    '''
+    Chroot inside a directory and call shell
+    if mount is true, mount /{proc,dev,sys} inside the chroot
+    '''
+    # prepare to chroot
+    prepare_chroot(path, mount)
+    # chrooting
+    arrow("Chrooting inside %s and running %s" % (path, shell))
+    call(["chroot", path, shell], close_fds=True)
+    # revert preparation of chroot
+    unprepare_chroot(path, mount)