[entropy.client*] make Entropy resources pid lock handling atomic
This commit is contained in:
@@ -504,7 +504,10 @@ def database(options):
|
||||
if rc == "No":
|
||||
return 0
|
||||
|
||||
Equo.resources_create_lock()
|
||||
acquired = Equo.resources_create_lock()
|
||||
if not acquired:
|
||||
print_info(red(" %s." % (_("Entropy locked during lock acquire"),)))
|
||||
return 2
|
||||
|
||||
if toBeRemoved:
|
||||
mytxt = blue("%s. %s:") % (
|
||||
|
||||
@@ -13,6 +13,7 @@ from __future__ import with_statement
|
||||
import os
|
||||
import stat
|
||||
import fcntl
|
||||
import errno
|
||||
import sys
|
||||
import shutil
|
||||
import time
|
||||
@@ -950,6 +951,9 @@ class RepositoryMixin:
|
||||
|
||||
class MiscMixin:
|
||||
|
||||
# resources lock file object container
|
||||
RESOURCES_LOCK_F_REF = None
|
||||
|
||||
def reload_constants(self):
|
||||
initconfig_entropy_constants(etpSys['rootdir'])
|
||||
self.SystemSettings.clear()
|
||||
@@ -961,29 +965,22 @@ class MiscMixin:
|
||||
os.chown(filepath,-1,etpConst['entropygid'])
|
||||
|
||||
def resources_create_lock(self):
|
||||
self.create_pid_file_lock(etpConst['locks']['using_resources'])
|
||||
return self.create_pid_file_lock(etpConst['locks']['using_resources'])
|
||||
|
||||
def resources_remove_lock(self):
|
||||
if hasattr(self, "_resources_lock_fd"):
|
||||
f_obj = MiscMixin.RESOURCES_LOCK_F_REF
|
||||
if f_obj is not None:
|
||||
fcntl.flock(f_obj.fileno(), fcntl.LOCK_UN)
|
||||
|
||||
if self._resources_lock_fd is not None:
|
||||
try:
|
||||
fcntl.flock(self._resources_lock_fd, fcntl.LOCK_UN)
|
||||
except IOError, err:
|
||||
if err.errno == errno.EBADF:
|
||||
self._resources_lock_fd = None
|
||||
else:
|
||||
raise
|
||||
if self._resources_lock_fd is not None:
|
||||
os.close(self._resources_lock_fd)
|
||||
self._resources_lock_fd = None
|
||||
if f_obj is not None:
|
||||
f_obj.close()
|
||||
MiscMixin.RESOURCES_LOCK_F_REF = None
|
||||
|
||||
if os.access(etpConst['locks']['using_resources'], os.F_OK | os.W_OK):
|
||||
if os.access(etpConst['locks']['using_resources'], os.F_OK):
|
||||
os.remove(etpConst['locks']['using_resources'])
|
||||
|
||||
def resources_check_lock(self):
|
||||
rc = self.check_pid_file_lock(etpConst['locks']['using_resources'])
|
||||
return rc
|
||||
return self.check_pid_file_lock(etpConst['locks']['using_resources'])
|
||||
|
||||
def check_pid_file_lock(self, pidfile):
|
||||
if not os.path.isfile(pidfile):
|
||||
@@ -1004,6 +1001,11 @@ class MiscMixin:
|
||||
return False
|
||||
|
||||
def create_pid_file_lock(self, pidfile, mypid = None):
|
||||
|
||||
if MiscMixin.RESOURCES_LOCK_F_REF is not None:
|
||||
# already locked, reentrant lock
|
||||
return
|
||||
|
||||
lockdir = os.path.dirname(pidfile)
|
||||
if not os.path.isdir(lockdir):
|
||||
os.makedirs(lockdir,0775)
|
||||
@@ -1011,12 +1013,20 @@ class MiscMixin:
|
||||
if mypid == None:
|
||||
mypid = os.getpid()
|
||||
|
||||
f = open(pidfile, "w")
|
||||
fd = f.fileno()
|
||||
fcntl.flock(fd, fcntl.LOCK_EX)
|
||||
f.write(str(mypid))
|
||||
f.flush()
|
||||
self._resources_lock_fd = fd
|
||||
pid_f = open(pidfile, "w")
|
||||
try:
|
||||
fcntl.flock(pid_f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
|
||||
except IOError, err:
|
||||
if err.errno not in (errno.EACCES, errno.EAGAIN,):
|
||||
# ouch, wtf?
|
||||
raise
|
||||
pid_f.close()
|
||||
return False # lock already acquired
|
||||
|
||||
pid_f.write(str(mypid))
|
||||
pid_f.flush()
|
||||
MiscMixin.RESOURCES_LOCK_F_REF = pid_f
|
||||
return True
|
||||
|
||||
def application_lock_check(self, silent = False):
|
||||
# check if another instance is running
|
||||
|
||||
@@ -2067,7 +2067,9 @@ class Package:
|
||||
return 21
|
||||
|
||||
# lock
|
||||
self.Entropy.resources_create_lock()
|
||||
acquired = self.Entropy.resources_create_lock()
|
||||
if not acquired:
|
||||
return 4 # app locked during lock acquire
|
||||
try:
|
||||
rc = self.run_stepper(xterm_header)
|
||||
finally:
|
||||
|
||||
@@ -1928,7 +1928,9 @@ class Repository:
|
||||
return 4
|
||||
|
||||
# lock
|
||||
self.Entropy.resources_create_lock()
|
||||
acquired = self.Entropy.resources_create_lock()
|
||||
if not acquired:
|
||||
return 4 # app locked during lock acquire
|
||||
try:
|
||||
rc = self.run_sync()
|
||||
finally:
|
||||
|
||||
@@ -740,7 +740,9 @@ class SecurityInterface:
|
||||
return 4
|
||||
|
||||
# lock
|
||||
self.Entropy.resources_create_lock()
|
||||
acquired = self.Entropy.resources_create_lock()
|
||||
if not acquired:
|
||||
return 4 # app locked during lock acquire
|
||||
try:
|
||||
rc_lock = self.__run_fetch()
|
||||
except:
|
||||
|
||||
Reference in New Issue
Block a user