From ebd4da08f28a646ca7609841e54dedeb7f18e303 Mon Sep 17 00:00:00 2001 From: Gui Chen Date: Thu, 8 Aug 2013 23:58:40 -0400 Subject: [PATCH] add lockfile support for mic/chroot.py module a simple lockfile implementation is added, and it is supposed to provide an exclusive locking in the chroot dir Signed-off-by: Gui Chen --- mic/chroot.py | 16 +++++++++++----- mic/utils/lock.py | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 5 deletions(-) create mode 100644 mic/utils/lock.py diff --git a/mic/chroot.py b/mic/chroot.py index 20ae215..8792cad 100644 --- a/mic/chroot.py +++ b/mic/chroot.py @@ -23,15 +23,14 @@ import subprocess from mic import msger from mic.conf import configmgr -from mic.utils import misc, errors, runner, fs_related +from mic.utils import misc, errors, runner, fs_related, lock ##################################################################### ### GLOBAL CONSTANTS ##################################################################### chroot_bindmounts = None -chroot_lockfd = -1 -chroot_lock = "" +chroot_lock = None BIND_MOUNTS = ( "/proc", "/proc/sys/fs/binfmt_misc", @@ -142,6 +141,13 @@ def setup_mtab(chrootdir): shutil.copyfile(mtab, dstmtab) def setup_chrootenv(chrootdir, bindmounts = None): + global chroot_lock + + # acquire the lock + if not chroot_lock: + lockpath = os.path.join(chrootdir, '.chroot.lock') + chroot_lock = lock.SimpleLockfile(lockpath) + chroot_lock.acquire() # bind mounting bind_mount(get_bindmounts(chrootdir, bindmounts)) # setup resolv.conf @@ -207,8 +213,6 @@ def cleanup_mounts(chrootdir): msger.warning("%s is not directory or is not empty" % point) def cleanup_chrootenv(chrootdir, bindmounts=None, globalmounts=()): - # unlock - chroot_lockfd.close() # kill processes kill_proc_inchroot(chrootdir) # clean mtab @@ -219,6 +223,8 @@ def cleanup_chrootenv(chrootdir, bindmounts=None, globalmounts=()): bind_unmount(get_bindmounts(chrootdir, bindmounts)) # clean up mounts cleanup_mounts(chrootdir) + # release the lock + chroot_lock.release() return None diff --git a/mic/utils/lock.py b/mic/utils/lock.py new file mode 100644 index 0000000..0bd14d8 --- /dev/null +++ b/mic/utils/lock.py @@ -0,0 +1,50 @@ +# Copyright (c) 2011 Intel, 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 any later version. + +import os +import errno + +class LockfileError(Exception): + """ Lockfile Exception""" + pass + +class SimpleLockfile(object): + """ Simple implementation of lockfile """ + def __init__(self, fpath): + self.fpath = fpath + self.lockf = None + + def acquire(self): + """ acquire the lock """ + try: + self.lockf = os.open(self.fpath, + os.O_CREAT | os.O_EXCL | os.O_WRONLY) + except OSError as err: + if err.errno == errno.EEXIST: + raise LockfileError("File %s is locked already" % self.fpath) + raise + + def release(self): + """ release the lock """ + try: + # FIXME: open file and close it immediately + os.close(self.lockf) + except IOError as err: + if err.errno != errno.EBADF: + raise LockfileError("Failed to release file: %s" % self.fpath) + try: + os.remove(self.fpath) + except OSError as err: + if err.errno != errno.ENOENT: + raise LockfileError("Failed to release file: %s" % self.fpath) + + def __enter__(self): + self.acquire() + return self + + def __exit__(self, *args): + self.release() + -- 2.7.4