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.
This commit is contained in:
Will Woods 2012-06-13 18:33:39 -04:00
parent 2aae30e691
commit 1c2c8ec4a8

View File

@ -26,6 +26,7 @@ from pylorax.sysutils import cpfile
from subprocess import * from subprocess import *
import sys import sys
import traceback import traceback
from time import sleep
######## Functions for making container images (cpio, squashfs) ########## ######## Functions for making container images (cpio, squashfs) ##########
@ -119,13 +120,31 @@ def mount(dev, opts="", mnt=None):
check_call(mount) check_call(mount)
return mnt return mnt
def umount(mnt): def umount(mnt, lazy=False, maxretry=3, retrysleep=1.0):
'''Unmount the given mountpoint. If the mount was a temporary dir created '''Unmount the given mountpoint. If lazy is True, do a lazy umount (-l).
by mount, it will be deleted. Returns false if the unmount fails.''' If the mount was a temporary dir created by mount, it will be deleted.
raises CalledProcessError if umount fails.'''
umount = ["umount"] umount = ["umount"]
if lazy: umount += ["-l"]
umount += [mnt] umount += [mnt]
logger.debug(" ".join(umount)) 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: if 'lorax.imgutils' in mnt:
os.rmdir(mnt) os.rmdir(mnt)
logger.debug("remove tmp mountdir %s", mnt) logger.debug("remove tmp mountdir %s", mnt)