Package rhn :: Module rhnLockfile
[hide private]
[frames] | no frames]

Source Code for Module rhn.rhnLockfile

  1  # 
  2  # Copyright (c) 2008--2016 Red Hat, Inc. 
  3  # 
  4  # This software is licensed to you under the GNU General Public License, 
  5  # version 2 (GPLv2). There is NO WARRANTY for this software, express or 
  6  # implied, including the implied warranties of MERCHANTABILITY or FITNESS 
  7  # FOR A PARTICULAR PURPOSE. You should have received a copy of GPLv2 
  8  # along with this software; if not, see 
  9  # http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt. 
 10  # 
 11  # Red Hat trademarks are not licensed under GPLv2. No permission is 
 12  # granted to use or replicate Red Hat trademarks that are incorporated 
 13  # in this software or its documentation. 
 14  # 
 15   
 16  import os 
 17  import sys 
 18  import fcntl 
 19  from errno import EWOULDBLOCK, EEXIST 
 20  from rhn.i18n import bstr 
 21  import fcntl 
 22   
23 -class LockfileLockedException(Exception):
24 """thrown ONLY when pid file is locked.""" 25 pass
26
27 -class Lockfile:
28 29 """class that provides simple access to a PID-style lockfile. 30 31 methods: __init__(lockfile), acquire(), and release() 32 NOTE: currently acquires upon init 33 The *.pid file will be acquired, or an LockfileLockedException is raised. 34 """ 35
36 - def __init__(self, lockfile, pid=None):
37 """create (if need be), and acquire lock on lockfile 38 39 lockfile example: '/var/run/up2date.pid' 40 """ 41 42 # cleanup the path and assign it. 43 self.lockfile = os.path.abspath( 44 os.path.expanduser( 45 os.path.expandvars(lockfile))) 46 47 self.pid = pid 48 if not self.pid: 49 self.pid = os.getpid() 50 51 # create the directory structure 52 dirname = os.path.dirname(self.lockfile) 53 if not os.path.exists(dirname): 54 try: 55 os.makedirs(dirname) 56 except OSError: 57 e = sys.exc_info()[1] 58 if hasattr(e, 'errno') and e.errno == EEXIST: 59 # race condition... dirname exists now. 60 pass 61 else: 62 raise 63 64 # open the file -- non-destructive read-write, unless it needs 65 # to be created XXX: potential race condition upon create? 66 self.f = os.open(self.lockfile, os.O_RDWR|os.O_CREAT|os.O_SYNC) 67 self.acquire()
68
69 - def acquire(self):
70 """acquire the lock; else raise LockfileLockedException.""" 71 72 try: 73 fcntl.flock(self.f, fcntl.LOCK_EX|fcntl.LOCK_NB) 74 except IOError: 75 if sys.exc_info()[1].errno == EWOULDBLOCK: 76 raise LockfileLockedException( 77 "cannot acquire lock on %s." % self.lockfile, None, sys.exc_info()[2]) 78 else: 79 raise 80 # unlock upon exit 81 fcntl.fcntl(self.f, fcntl.F_SETFD, 1) 82 # truncate and write the pid 83 os.ftruncate(self.f, 0) 84 os.write(self.f, bstr(str(self.pid) + '\n'))
85
86 - def release(self):
87 # Remove the lock file 88 os.unlink(self.lockfile) 89 fcntl.flock(self.f, fcntl.LOCK_UN) 90 os.close(self.f)
91 92
93 -def main():
94 """test code""" 95 96 try: 97 L = Lockfile('./test.pid') 98 except LockfileLockedException: 99 sys.stderr.write("%s\n" % sys.exc_info()[1]) 100 sys.exit(-1) 101 else: 102 print("lock acquired ") 103 print("...sleeping for 10 seconds") 104 import time 105 time.sleep(10) 106 L.release() 107 print("lock released ")
108 109 if __name__ == '__main__': 110 # test code 111 sys.exit(main() or 0) 112