def acquire(self, hostId, lease): with nested(self._lock, SANLock._sanlock_lock): self.log.info("Acquiring %s for host id %s", lease, hostId) while True: if SANLock._sanlock_fd is None: try: SANLock._sanlock_fd = sanlock.register() except sanlock.SanlockException as e: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot register to sanlock", str(e)) try: sanlock.acquire(self._sdUUID, lease.name, [(lease.path, lease.offset)], slkfd=SANLock._sanlock_fd) except sanlock.SanlockException as e: if e.errno != errno.EPIPE: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot acquire %s" % (lease,), str(e)) SANLock._sanlock_fd = None continue break self.log.debug("Successfully acquired %s for host id %s", lease, hostId)
def acquire(self, hostId): with nested(self._lock, SANLock._sanlock_lock): self.log.info("Acquiring cluster lock for domain %s (id: %s)", self._sdUUID, hostId) while True: if SANLock._sanlock_fd is None: try: SANLock._sanlock_fd = sanlock.register() except sanlock.SanlockException as e: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot register to sanlock", str(e)) try: sanlock.acquire(self._sdUUID, SDM_LEASE_NAME, self.getLockDisk(), slkfd=SANLock._sanlock_fd) except sanlock.SanlockException as e: if e.errno != os.errno.EPIPE: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot acquire cluster lock", str(e)) SANLock._sanlock_fd = None continue break self.log.debug( "Cluster lock for domain %s successfully acquired " "(id: %s)", self._sdUUID, hostId)
def acquire(self, hostID, lease): if lease != self._lease: raise MultipleLeasesNotSupported("acquire", lease) leaseTimeMs = self._leaseTimeSec * 1000 ioOpTimeoutMs = self._ioOpTimeoutSec * 1000 with self._lock: self.log.debug("Acquiring cluster lock for domain %s" % self._sdUUID) lockUtil = self.getLockUtilFullPath() acquireLockCommand = subprocess.list2cmdline([ lockUtil, "start", self._sdUUID, str(hostID), str(self._lockRenewalIntervalSec), str(lease.path), str(leaseTimeMs), str(ioOpTimeoutMs), str(self._leaseFailRetry), str(os.getpid()) ]) cmd = [constants.EXT_SU, misc.IOUSER, '-s', constants.EXT_SH, '-c', acquireLockCommand] (rc, out, err) = misc.execCmd(cmd, cwd=self.lockUtilPath, sudo=True, ioclass=utils.IOCLASS.REALTIME, ioclassdata=0, setsid=True) if rc != 0: raise se.AcquireLockFailure(self._sdUUID, rc, out, err) self.log.debug("Clustered lock acquired successfully")
def acquire(self, hostId, lease): self.log.info("Acquiring %s for host id %s", lease, hostId) # If host id was acquired by this thread, this will return immediately. # If host is id being acquired asynchronically by the domain monitor, # wait until the domain monitor find that host id was acquired. # # IMPORTANT: This must be done *before* entering the lock. Once we # enter the lock, the domain monitor cannot check if host id was # acquired, since hasHostId() is using the same lock. if not self._ready.wait(self.ACQUIRE_HOST_ID_TIMEOUT): raise se.AcquireHostIdFailure( "Timeout acquiring host id, cannot acquire %s (id=%s)" % (lease, hostId)) with self._lock, SANLock._sanlock_lock: while True: if SANLock._sanlock_fd is None: try: SANLock._sanlock_fd = sanlock.register() except sanlock.SanlockException as e: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot register to sanlock", str(e)) resource_name = lease.name.encode("utf-8") try: sanlock.acquire(self._lockspace_name, resource_name, [(lease.path, lease.offset)], slkfd=SANLock._sanlock_fd) except sanlock.SanlockException as e: if e.errno != errno.EPIPE: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot acquire %s" % (lease, ), str(e)) SANLock._sanlock_fd = None continue break self.log.info("Successfully acquired %s for host id %s", lease, hostId)
def acquire(self, hostId, lease): if lease != self._lease: raise MultipleLeasesNotSupported("acquire", lease) with self._globalLockMapSync: self.log.info("Acquiring local lock for domain %s (id: %s)", self._sdUUID, hostId) hostId, lockFile = self._getLease() if lockFile: try: osutils.uninterruptible(fcntl.fcntl, lockFile, fcntl.F_GETFD) except IOError as e: # We found a stale file descriptor, removing. del self._globalLockMap[self._sdUUID] # Raise any other unkown error. if e.errno != errno.EBADF: raise else: self.log.debug( "Local lock already acquired for domain " "%s (id: %s)", self._sdUUID, hostId) return # success, the lock was already acquired lockFile = osutils.uninterruptible(os.open, self._idsPath, os.O_RDONLY) try: osutils.uninterruptible(fcntl.flock, lockFile, fcntl.LOCK_EX | fcntl.LOCK_NB) except IOError as e: osutils.close_fd(lockFile) if e.errno in (errno.EACCES, errno.EAGAIN): raise se.AcquireLockFailure(self._sdUUID, e.errno, "Cannot acquire local lock", str(e)) raise else: self._globalLockMap[self._sdUUID] = (hostId, lockFile) self.log.debug( "Local lock for domain %s successfully acquired " "(id: %s)", self._sdUUID, hostId)
def acquire(self, hostId, lease, lvb=False): if lvb and not supports_lvb: raise se.UnsupportedOperation( "This sanlock version does not support LVB") self.log.info("Acquiring %s for host id %s, lvb=%s", lease, hostId, lvb) # If host id was acquired by this thread, this will return immediately. # If host is id being acquired asynchronically by the domain monitor, # wait until the domain monitor find that host id was acquired. # # IMPORTANT: This must be done *before* entering the lock. Once we # enter the lock, the domain monitor cannot check if host id was # acquired, since hasHostId() is using the same lock. if not self._ready.wait(self.ACQUIRE_HOST_ID_TIMEOUT): raise se.AcquireHostIdFailure( "Timeout acquiring host id, cannot acquire %s (id=%s)" % (lease, hostId)) with self._lock, SANLock._process_lock: while True: if SANLock._process_fd is None: try: SANLock._process_fd = sanlock.register() except sanlock.SanlockException as e: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot register to sanlock", str(e)) self.log.info("Using sanlock process fd %d", SANLock._process_fd) # TODO: remove once sanlock 3.8.3 is available on centos. extra_args = {"lvb": lvb} if supports_lvb else {} try: sanlock.acquire( self._lockspace_name, lease.name.encode("utf-8"), [(lease.path, lease.offset)], slkfd=SANLock._process_fd, **extra_args) except sanlock.SanlockException as e: if e.errno != errno.EPIPE: raise se.AcquireLockFailure( self._sdUUID, e.errno, "Cannot acquire %s" % (lease,), str(e)) # If we hold leases, we just lost them, since sanlock is # releasing all process leases when the process fd is # closed. The only way to recover is to panic; child # processes run by vdsm will be killed, and vdsm will lose # the SPM role. if SANLock._lease_count > 0: panic("Sanlock process fd was closed while " "holding {} leases: {}" .format(SANLock._lease_count, e)) self.log.warning("Sanlock process fd was closed: %s", e) SANLock._process_fd = None continue SANLock._lease_count += 1 break self.log.info("Successfully acquired %s for host id %s", lease, hostId)
def error(*args): raise se.AcquireLockFailure('id', 'rc', 'out', 'err')