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._leasesPath, SDM_LEASE_OFFSET)], 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): 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 main(): print "Creating the sanlock disk" fd, disk = tempfile.mkstemp() os.close(fd) offset = sanlock.get_alignment(disk) SNLK_DISKS = [(disk, offset)] print "Registering to sanlock" fd = sanlock.register() print "Initializing '%s'" % (LOCKSPACE_NAME, ) sanlock.init_lockspace(LOCKSPACE_NAME, disk) print "Initializing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.init_resource(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS) print "Acquiring the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.add_lockspace(LOCKSPACE_NAME, HOST_ID, disk) try: print "Acquiring '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.acquire(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) print "Releasing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.release(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) finally: print "Releasing the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.rem_lockspace(LOCKSPACE_NAME, HOST_ID, disk) print "Removing the sanlock disk" os.remove(disk)
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, e: raise se.AcquireLockFailure(self._sdUUID, e.errno, "Cannot register to sanlock", str(e)) try: sanlock.acquire(self._sdUUID, LEASE_NAME, [self._leasesPath], slkfd=SANLock._sanlock_fd) except sanlock.SanlockException, e: if e.errno != errno.EPIPE: raise se.AcquireLockFailure(self._sdUUID, e.errno, "Cannot acquire cluster lock", str(e)) SANLock._sanlock_fd = None continue break
def main(): print "Creating the sanlock disk" fd, disk = tempfile.mkstemp() os.close(fd) offset = sanlock.get_alignment(disk) SNLK_DISKS = [(disk, offset)] print "Registering to sanlock" fd = sanlock.register() print "Initializing '%s'" % (LOCKSPACE_NAME,) sanlock.init_lockspace(LOCKSPACE_NAME, disk) print "Initializing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.init_resource(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS) print "Acquiring the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.add_lockspace(LOCKSPACE_NAME, HOST_ID, disk) try: print "Acquiring '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.acquire(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) print "Releasing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.release(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) finally: print "Releasing the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.rem_lockspace(LOCKSPACE_NAME, HOST_ID, disk) print "Removing the sanlock disk" os.remove(disk)
def test_acquire_path_length(no_sanlock_daemon): path = "x" * constants.SANLK_PATH_LEN with pytest.raises(ValueError): sanlock.acquire(b"ls_name", b"res_name", [(path, 0)], pid=os.getpid()) path = "x" * (constants.SANLK_PATH_LEN - 1) with raises_sanlock_errno(): sanlock.acquire(b"ls_name", b"res_name", [(path, 0)], pid=os.getpid())
def test_acquire_parse_args(no_sanlock_daemon, name, filename, encoding): path = util.generate_path("/tmp/", filename, encoding) disks = [(path, 0)] with raises_sanlock_errno(): sanlock.acquire(b"ls_name", name, disks, pid=os.getpid()) with raises_sanlock_errno(): sanlock.acquire(name, b"res_name", disks, pid=os.getpid())
def main(): signal.signal(signal.SIGTERM, sigTermHandler) print "Creating the sanlock disk" fd, disk = tempfile.mkstemp() os.close(fd) os.chown(disk, pwd.getpwnam("sanlock").pw_uid, grp.getgrnam("sanlock").gr_gid) offset = sanlock.get_alignment(disk) SNLK_DISKS = [(disk, offset)] print "Registering to sanlock" fd = sanlock.register() print "Initializing '%s'" % (LOCKSPACE_NAME, ) sanlock.write_lockspace(LOCKSPACE_NAME, disk) print "Initializing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.write_resource(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS) print "Acquiring the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.add_lockspace(LOCKSPACE_NAME, HOST_ID, disk) try: print "Acquiring '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.acquire(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd, version=0) while True: print "Trying to get lockspace '%s' hosts" % LOCKSPACE_NAME try: hosts_list = sanlock.get_hosts(LOCKSPACE_NAME) except sanlock.SanlockException as e: if e.errno != os.errno.EAGAIN: raise else: print "Lockspace '%s' hosts: " % LOCKSPACE_NAME, hosts_list break time.sleep(5) print "Resource '%s' owners: " % RESOURCE_NAME, \ sanlock.read_resource_owners( LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS) print "Releasing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.release(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) except Exception as e: print "Exception: ", e finally: print "Releasing the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.rem_lockspace(LOCKSPACE_NAME, HOST_ID, disk) print "Removing the sanlock disk" os.remove(disk)
def sanlock_acquire(hostId, lockspacePath, leasePath): sfd = sanlock.register() if not sanlock.inq_lockspace(LOCKSPACE_NAME, hostId, lockspacePath): msg = "Try to acquire host id %s:%s:%s:0" % (LOCKSPACE_NAME, hostId, lockspacePath) print(msg) sanlock.add_lockspace(LOCKSPACE_NAME, hostId, lockspacePath) msg = "Try to acquire leader lease:%s" % str(leasePath) print(msg) sanlock.acquire(LOCKSPACE_NAME, RESOURCE_NAME, [(leasePath, 0)], sfd)
def main(): signal.signal(signal.SIGTERM, sigTermHandler) print "Creating the sanlock disk" fd, disk = tempfile.mkstemp() os.close(fd) os.chown(disk, pwd.getpwnam("sanlock").pw_uid, grp.getgrnam("sanlock").gr_gid) offset = sanlock.get_alignment(disk) SNLK_DISKS = [(disk, offset)] print "Registering to sanlock" fd = sanlock.register() print "Initializing '%s'" % (LOCKSPACE_NAME,) sanlock.write_lockspace(LOCKSPACE_NAME, disk, max_hosts=0, iotimeout=0, align=1048576, sector=512) print "Initializing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.write_resource(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, align=1048576, sector=512) print "Acquiring the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.add_lockspace(LOCKSPACE_NAME, HOST_ID, disk) try: print "Acquiring '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.acquire(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd, version=0) while True: print "Trying to get lockspace '%s' hosts" % LOCKSPACE_NAME try: hosts_list = sanlock.get_hosts(LOCKSPACE_NAME) except sanlock.SanlockException as e: if e.errno != os.errno.EAGAIN: raise else: print "Lockspace '%s' hosts: " % LOCKSPACE_NAME, hosts_list break time.sleep(5) print "Resource '%s' owners: " % RESOURCE_NAME, \ sanlock.read_resource_owners( LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, align=1048576, sector=512) print "Releasing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.release(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) except Exception as e: print "Exception: ", e finally: print "Releasing the id '%i' on '%s'" % (HOST_ID, LOCKSPACE_NAME) sanlock.rem_lockspace(LOCKSPACE_NAME, HOST_ID, disk) print "Removing the sanlock disk" os.remove(disk)
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 test_acquire_release_resource(tmpdir, sanlock_daemon, size, offset): ls_path = str(tmpdir.join("ls_name")) util.create_file(ls_path, size) res_path = str(tmpdir.join("res_name")) util.create_file(res_path, size) sanlock.write_lockspace(b"ls_name", ls_path, offset=offset, iotimeout=1) sanlock.add_lockspace(b"ls_name", 1, ls_path, offset=offset, iotimeout=1) # Host status is not available until the first renewal. with pytest.raises(sanlock.SanlockException) as e: sanlock.get_hosts(b"ls_name", 1) assert e.value.errno == errno.EAGAIN time.sleep(1) host = sanlock.get_hosts(b"ls_name", 1)[0] assert host["flags"] == sanlock.HOST_LIVE disks = [(res_path, offset)] sanlock.write_resource(b"ls_name", b"res_name", disks) res = sanlock.read_resource(res_path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } owners = sanlock.read_resource_owners(b"ls_name", b"res_name", disks) assert owners == [] fd = sanlock.register() sanlock.acquire(b"ls_name", b"res_name", disks, slkfd=fd) res = sanlock.read_resource(res_path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 1 } owner = sanlock.read_resource_owners(b"ls_name", b"res_name", disks)[0] assert owner["host_id"] == 1 assert owner["flags"] == 0 assert owner["generation"] == 1 assert owner["io_timeout"] == 0 # Why 0? # TODO: check timestamp. host = sanlock.get_hosts(b"ls_name", 1)[0] assert host["flags"] == sanlock.HOST_LIVE assert host["generation"] == owner["generation"] sanlock.release(b"ls_name", b"res_name", disks, slkfd=fd) res = sanlock.read_resource(res_path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 1 } owners = sanlock.read_resource_owners(b"ls_name", b"res_name", disks) assert owners == []
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 test_acquire_release_resource(tmpdir, sanlock_daemon, size, offset): ls_path = str(tmpdir.join("ls_name")) util.create_file(ls_path, size) res_path = str(tmpdir.join("res_name")) util.create_file(res_path, size) sanlock.write_lockspace("ls_name", ls_path, offset=offset, iotimeout=1) sanlock.add_lockspace("ls_name", 1, ls_path, offset=offset, iotimeout=1) # Host status is not available until the first renewal. with pytest.raises(sanlock.SanlockException) as e: sanlock.get_hosts("ls_name", 1) assert e.value.errno == errno.EAGAIN time.sleep(1) host = sanlock.get_hosts("ls_name", 1)[0] assert host["flags"] == sanlock.HOST_LIVE disks = [(res_path, offset)] sanlock.write_resource("ls_name", "res_name", disks) res = sanlock.read_resource(res_path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } owners = sanlock.read_resource_owners("ls_name", "res_name", disks) assert owners == [] fd = sanlock.register() sanlock.acquire("ls_name", "res_name", disks, slkfd=fd) res = sanlock.read_resource(res_path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 1 } owner = sanlock.read_resource_owners("ls_name", "res_name", disks)[0] assert owner["host_id"] == 1 assert owner["flags"] == 0 assert owner["generation"] == 1 assert owner["io_timeout"] == 0 # Why 0? # TODO: check timestamp. host = sanlock.get_hosts("ls_name", 1)[0] assert host["flags"] == sanlock.HOST_LIVE assert host["generation"] == owner["generation"] sanlock.release("ls_name", "res_name", disks, slkfd=fd) res = sanlock.read_resource(res_path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 1 } owners = sanlock.read_resource_owners("ls_name", "res_name", disks) assert owners == []