From 1c2c8ec4a86f08395b3fe2146153fc3625613c27 Mon Sep 17 00:00:00 2001 From: Will Woods Date: Wed, 13 Jun 2012 18:33:39 -0400 Subject: [PATCH] pylorax.imgutils: add retry loop and "lazy" to umount() There's something strange going on where unmounting a hfsplus volume immediately after mounting it will fail with EBUSY. This makes the umount fail, which makes the rmdir fail, which causes a traceback, which breaks mkefiboot --apple. It works fine if you wait a second and retry.. so do that. Also, add the "lazy" argument so you can do lazy unmounts if you like. --- src/pylorax/imgutils.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/pylorax/imgutils.py b/src/pylorax/imgutils.py index 164c5546..5ec6e8af 100644 --- a/src/pylorax/imgutils.py +++ b/src/pylorax/imgutils.py @@ -26,6 +26,7 @@ from pylorax.sysutils import cpfile from subprocess import * import sys import traceback +from time import sleep ######## Functions for making container images (cpio, squashfs) ########## @@ -119,13 +120,31 @@ def mount(dev, opts="", mnt=None): check_call(mount) return mnt -def umount(mnt): - '''Unmount the given mountpoint. If the mount was a temporary dir created - by mount, it will be deleted. Returns false if the unmount fails.''' +def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0): + '''Unmount the given mountpoint. If lazy is True, do a lazy umount (-l). + If the mount was a temporary dir created by mount, it will be deleted. + raises CalledProcessError if umount fails.''' umount = ["umount"] + if lazy: umount += ["-l"] umount += [mnt] logger.debug(" ".join(umount)) - rv = call(umount) + count = 0 + while maxretry > 0: + try: + rv = check_call(umount) + except CalledProcessError: + count += 1 + if count == maxretry: + raise + logger.warn("failed to unmount %s. retrying (%d/%d)...", + mnt, count, maxretry) + if logger.getEffectiveLevel() <= logging.DEBUG: + fuser = check_output(["fuser", "-vm", mnt], + stderr=STDOUT) + logger.debug("fuser -vm:\n%s\n", fuser) + sleep(retrysleep) + else: + break if 'lorax.imgutils' in mnt: os.rmdir(mnt) logger.debug("remove tmp mountdir %s", mnt)