diff --git a/lib/ansible/module_utils/yumdnf.py b/lib/ansible/module_utils/yumdnf.py index 0b3de6519ae..b3ed22bd24a 100644 --- a/lib/ansible/module_utils/yumdnf.py +++ b/lib/ansible/module_utils/yumdnf.py @@ -126,8 +126,9 @@ class YumDnf(with_metaclass(ABCMeta, object)): # default isn't a bad idea self.lockfile = '/var/run/yum.pid' + @abstractmethod def is_lockfile_pid_valid(self): - raise NotImplementedError + return def _is_lockfile_present(self): return (os.path.isfile(self.lockfile) or glob.glob(self.lockfile)) and self.is_lockfile_pid_valid() diff --git a/lib/ansible/modules/packaging/os/yum.py b/lib/ansible/modules/packaging/os/yum.py index 282934c0acc..c1333ea8c6f 100644 --- a/lib/ansible/modules/packaging/os/yum.py +++ b/lib/ansible/modules/packaging/os/yum.py @@ -413,38 +413,42 @@ class YumModule(YumDnf): def is_lockfile_pid_valid(self): try: - with open(self.lockfile, 'r') as f: - oldpid = int(f.readline()) - except ValueError: - # invalid data - os.unlink(self.lockfile) - return False - except (IOError, OSError) as e: - self.module.fail_json(msg="Failure opening %s: %s" % (self.lockfile, to_native(e))) - - if oldpid == os.getpid(): - # that's us? - os.unlink(self.lockfile) - return False - - try: - with open("/proc/%d/stat" % oldpid, 'r') as f: - stat = f.readline() + try: + with open(self.lockfile, 'r') as f: + oldpid = int(f.readline()) + except ValueError: + # invalid data + os.unlink(self.lockfile) + return False - if stat.split()[2] == 'Z': - # Zombie + if oldpid == os.getpid(): + # that's us? os.unlink(self.lockfile) return False - except IOError: + try: - os.kill(oldpid, 0) - except OSError as e: - if e.errno == errno.ESRCH: - # No such process + with open("/proc/%d/stat" % oldpid, 'r') as f: + stat = f.readline() + + if stat.split()[2] == 'Z': + # Zombie os.unlink(self.lockfile) return False - - self.module.fail_json(msg="Unable to check PID %s in %s: %s" % (oldpid, self.lockfile, to_native(e))) + except IOError: + # either /proc is not mounted or the process is already dead + try: + # check the state of the process + os.kill(oldpid, 0) + except OSError as e: + if e.errno == errno.ESRCH: + # No such process + os.unlink(self.lockfile) + return False + + self.module.fail_json(msg="Unable to check PID %s in %s: %s" % (oldpid, self.lockfile, to_native(e))) + except (IOError, OSError) as e: + # lockfile disappeared? + return False # another copy seems to be running return True