def initLock(self, lease): self.log.info( "Initializing sanlock for domain %s path=%s alignment=%s " "block_size=%s io_timeout=%s", self._sdUUID, self._idsPath, self._alignment, self._block_size, self._io_timeout) resource_name = lease.name.encode("utf-8") try: sanlock.write_lockspace( self._lockspace_name, self._idsPath, iotimeout=self._io_timeout, align=self._alignment, sector=self._block_size) sanlock.write_resource( self._lockspace_name, resource_name, [(lease.path, lease.offset)], align=self._alignment, sector=self._block_size) except sanlock.SanlockException: self.log.exception( "Cannot initialize lock for domain %s", self._sdUUID) raise se.ClusterLockInitError()
def test_write_resource( tmpdir, sanlock_daemon, filename, encoding, size, offset): path = util.generate_path(tmpdir, filename, encoding) util.create_file(path, size) disks = [(path, offset)] # Test read and write with default alignment and sector size values. sanlock.write_resource(b"ls_name", b"res_name", disks) res = sanlock.read_resource(path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } # Test read and write with explicit alignment and sector size values. sanlock.write_resource( b"ls_name", b"res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) res = sanlock.read_resource( path, offset=offset, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) 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 == [] magic = util.read_magic(path, offset) assert magic == constants.PAXOS_DISK_MAGIC util.check_guard(path, size)
def test_write_resource_4k_invalid_sector_size(sanlock_daemon, user_4k_path): disks = [(user_4k_path, 0)] with pytest.raises(sanlock.SanlockException) as e: sanlock.write_resource( b"ls_name", b"res_name", disks, sector=SECTOR_SIZE_512) assert e.value.errno == errno.EINVAL
def test_write_resource_4k(sanlock_daemon, user_4k_path, align): disks = [(user_4k_path, 0)] # Poison resource area, ensuring that previous tests will not break this # test, and sanlock does not write beyond the lockspace area. with io.open(user_4k_path, "rb+") as f: f.write(align * b"x") util.write_guard(user_4k_path, align) sanlock.write_resource( b"ls_name", b"res_name", disks, align=align, sector=SECTOR_SIZE_4K) res = sanlock.read_resource( user_4k_path, align=align, sector=SECTOR_SIZE_4K) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } owners = sanlock.read_resource_owners( b"ls_name", b"res_name", disks, align=align, sector=SECTOR_SIZE_4K) assert owners == [] # Verify that resource was written. magic = util.read_magic(user_4k_path) assert magic == constants.PAXOS_DISK_MAGIC # Check that sanlock did not write beyond the lockspace area. util.check_guard(user_4k_path, align)
def test_write_resource_4k_invalid_sector_size(sanlock_daemon, user_4k_path): disks = [(user_4k_path, 0)] with pytest.raises(sanlock.SanlockException) as e: sanlock.write_resource( "ls_name", "res_name", disks, sector=SECTOR_SIZE_512) assert e.value.errno == errno.EINVAL
def test_write_resource_4k(sanlock_daemon, user_4k_path, align): disks = [(user_4k_path, 0)] # Poison resource area, ensuring that previous tests will not break this # test, and sanlock does not write beyond the lockspace area. with io.open(user_4k_path, "rb+") as f: f.write(align * b"x") util.write_guard(user_4k_path, align) sanlock.write_resource( "ls_name", "res_name", disks, align=align, sector=SECTOR_SIZE_4K) res = sanlock.read_resource( user_4k_path, align=align, sector=SECTOR_SIZE_4K) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } owners = sanlock.read_resource_owners( "ls_name", "res_name", disks, align=align, sector=SECTOR_SIZE_4K) assert owners == [] # Verify that resource was written. with io.open(user_4k_path, "rb") as f: magic, = struct.unpack("< I", f.read(4)) assert magic == constants.PAXOS_DISK_MAGIC # Check that sanlock did not write beyond the lockspace area. util.check_guard(user_4k_path, align)
def remove(self, lease_id): """ Remove lease from index Raises: - NoSuchLease if lease was not found - OSError if I/O operation failed - sanlock.SanlockException if sanlock operation failed. """ # TODO: validate lease id is lower case uuid log.info("Removing lease %r in lockspace %r", lease_id, self._lockspace) recnum = self._index.find_record(lease_id) if recnum == -1: raise NoSuchLease(lease_id) record = Record(lease_id, RECORD_STALE) self._write_record(recnum, record) # TODO: remove the sanlock resource # There is no sanlock api for removing a resource. # This is a hack until we find a better way. # Need to discuss this with David Teigland. offset = self._lease_offset(recnum) sanlock.write_resource("", "", [(self._file.name, offset)]) record = Record(BLANK_UUID, RECORD_FREE) self._write_record(recnum, record)
def test_write_resource_path_length(no_sanlock_daemon): path = "x" * constants.SANLK_PATH_LEN with pytest.raises(ValueError): sanlock.write_resource(b"ls_name", b"res_name", [(path, 0)]) path = "x" * (constants.SANLK_PATH_LEN - 1) with raises_sanlock_errno(): sanlock.write_resource(b"ls_name", b"res_name", [(path, 0)])
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 test_clear_empty_storage(tmpdir, sanlock_daemon): path = util.generate_path(tmpdir, "clear_test") util.create_file(path, MiB) disks = [(path, 0)] # Clear area without any resource written - should succeed sanlock.write_resource(b"ls_name", b"inval_res_name", disks, clear=True) magic = util.read_magic(path) assert magic == constants.PAXOS_DISK_CLEAR
def test_write_resource_invalid_align_sector( tmpdir, sanlock_daemon, align, sector): path = str(tmpdir.join("resources")) util.create_file(path, MIN_RES_SIZE) disks = [(path, 0)] with pytest.raises(ValueError): sanlock.write_resource( "ls_name", "res_name", disks, align=align, sector=sector)
def test_write_resource_parse_args(no_sanlock_daemon, name, filename, encoding): path = util.generate_path("/tmp/", filename, encoding) disks = [(path, 0)] with raises_sanlock_errno(): sanlock.write_resource(name, b"res_name", disks) with raises_sanlock_errno(): sanlock.write_resource(b"ls_name", name, disks)
def test_write_resource_invalid_align_sector( tmpdir, sanlock_daemon, align, sector): path = str(tmpdir.join("resources")) util.create_file(path, MIN_RES_SIZE) disks = [(path, 0)] with pytest.raises(ValueError): sanlock.write_resource( b"ls_name", b"res_name", disks, align=align, sector=sector)
def _write_resource(path, offset, alignment, block_size, resource, lockspace): """ Helper for writing sanlock resources. """ log.info("Writing sanlock resource=%s lockspace=%s path=%s offset=%s", resource, lockspace, path, offset) sanlock.write_resource(lockspace.encode("utf-8"), resource.encode("utf-8"), [(path, offset)], align=alignment, sector=block_size)
def test_clear_empty_lockspace_resource(tmpdir, sanlock_daemon): path = util.generate_path(tmpdir, "clear_test") util.create_file(path, MiB) disks = [(path, 0)] sanlock.write_resource(b"ls_name", b"res_name", disks) # Clear with empty lockspace and resource - should succeed sanlock.write_resource(b"", b"", disks, clear=True) magic = util.read_magic(path) assert magic == constants.PAXOS_DISK_CLEAR
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 test_init_resource(tmpdir, sanlock_daemon): path = tmpdir.join("resources") size = 1024**2 util.create_file(str(path), size) sanlock.write_resource("ls_name", "res_name", [(str(path), 0)]) with io.open(str(path), "rb") as f: magic, = struct.unpack("< I", f.read(4)) assert magic == constants.PAXOS_DISK_MAGIC # TODO: check more stuff here... util.check_guard(str(path), size)
def test_read_resource_owners_4k_invalid_sector_size( sanlock_daemon, user_4k_path): disks = [(user_4k_path, 0)] sanlock.write_resource( "ls_name", "res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_4K) with pytest.raises(sanlock.SanlockException) as e: sanlock.read_resource_owners( "ls_name", "res_name", disks, sector=SECTOR_SIZE_512) assert e.value.errno == errno.EINVAL
def test_read_resource_owners_4k_invalid_sector_size( sanlock_daemon, user_4k_path): disks = [(user_4k_path, 0)] sanlock.write_resource( b"ls_name", b"res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_4K) with pytest.raises(sanlock.SanlockException) as e: sanlock.read_resource_owners( b"ls_name", b"res_name", disks, sector=SECTOR_SIZE_512) assert e.value.errno == errno.EINVAL
def newVolumeLease(cls, metaId, sdUUID, volUUID): cls.log.debug("Initializing volume lease volUUID=%s sdUUID=%s, " "metaId=%s", volUUID, sdUUID, metaId) volPath = metaId[0] leasePath = cls.leaseVolumePath(volPath) oop.getProcessPool(sdUUID).truncateFile(leasePath, LEASE_FILEOFFSET) cls.file_setrw(leasePath, rw=True) manifest = sdCache.produce_manifest(sdUUID) sanlock.write_resource( sdUUID.encode("utf-8"), volUUID.encode("utf-8"), [(leasePath, LEASE_FILEOFFSET)], align=manifest.alignment, sector=manifest.block_size)
def add(self, lease_id): """ Add lease to index, returning LeaseInfo. Raises: - LeaseExists if lease already stored for lease_id - InvalidRecord if corrupted lease record is found - NoSpace if all slots are allocated - OSError if I/O operation failed - sanlock.SanlockException if sanlock operation failed. """ log.info("Adding lease %r in lockspace %r", lease_id, self.lockspace) recnum = self._index.find_record(lease_id) if recnum != -1: record = self._index.read_record(recnum) if record.updating: # Record can have updating flag due to partial creation caused # by older vdsm versions log.warning( "Ignoring partially created lease in updating " "state recnum=%s resource=%s offset=%s", recnum, record.resource, record.offset) else: raise LeaseExists(lease_id) else: recnum = self._index.find_free_record() if recnum == -1: raise NoSpace(lease_id) offset = lease_offset(recnum, self._alignment) # We create a lease in 2 steps: # 1. create a sanlock resource in the slot associated with this # record. If this fails, the index will not change. # 2. write a new record, making the new resource available. If writing # a record fails, the index does not change and the new resource # will not be available. sanlock.write_resource(self.lockspace.encode("utf-8"), lease_id.encode("utf-8"), [(self._file.name, offset)], align=self._alignment, sector=self._block_size) record = Record(lease_id, offset) self._write_record(recnum, record) return LeaseInfo(self.lockspace, lease_id, self._file.name, offset)
def test_read_resource_owners_invalid_align_size(tmpdir, sanlock_daemon): path = str(tmpdir.join("path")) util.create_file(path, GiB) disks = [(path, 0)] sanlock.write_resource(b"ls_name", b"res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) with pytest.raises(sanlock.SanlockException) as e: sanlock.read_resource_owners(b"ls_name", b"res_name", disks, align=ALIGNMENT_2M, sector=SECTOR_SIZE_512) assert e.value.errno == errno.EINVAL
def test_write_resource(tmpdir, sanlock_daemon, size, offset): path = str(tmpdir.join("resources")) util.create_file(path, size) disks = [(path, offset)] # test read and write with default alignment and sector size values sanlock.write_resource("ls_name", "res_name", disks) res = sanlock.read_resource(path, offset=offset) assert res == { "lockspace": "ls_name", "resource": "res_name", "version": 0 } # test read and write with explicit alignment and sector size values sanlock.write_resource("ls_name", "res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) res = sanlock.read_resource(path, offset=offset, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) assert res == { "lockspace": "ls_name", "resource": "res_name", "version": 0 } owners = sanlock.read_resource_owners("ls_name", "res_name", disks) assert owners == [] with io.open(path, "rb") as f: f.seek(offset) magic, = struct.unpack("< I", f.read(4)) assert magic == constants.PAXOS_DISK_MAGIC # TODO: check more stuff here... util.check_guard(path, size)
def _repair(broken_leases): print("Repairing volume leases ...") total = 0 repaired = 0 for sd_uuid in broken_leases: for img_uuid in broken_leases[sd_uuid]: for vol_uuid in broken_leases[sd_uuid][img_uuid]: total += 1 vol_lease = broken_leases[sd_uuid][img_uuid][vol_uuid] try: sanlock.write_resource( sd_uuid, vol_uuid, [(vol_lease['path'], vol_lease['offset'])]) repaired += 1 except sanlock.SanlockException as e: print("Failed to repair lease of volume {}/{}. Error {}". format(vol_lease['image'], vol_lease['volume'], e)) print("Repaired ({}/{}) volume leases.".format(repaired, total))
def test_read_resource_owners_invalid_align_size(tmpdir, sanlock_daemon): path = str(tmpdir.join("path")) util.create_file(path, GiB) disks = [(path, 0)] sanlock.write_resource( "ls_name", "res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) with pytest.raises(sanlock.SanlockException) as e: sanlock.read_resource_owners( "ls_name", "res_name", disks, align=ALIGNMENT_2M, sector=SECTOR_SIZE_512) assert e.value.errno == errno.EINVAL
def test_write_resource(tmpdir, sanlock_daemon, filename, encoding, size, offset): path = util.generate_path(tmpdir, filename, encoding) util.create_file(path, size) disks = [(path, offset)] # Test read and write with default alignment and sector size values. sanlock.write_resource("ls_name", "res_name", disks) res = sanlock.read_resource(path, offset=offset) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } # Test read and write with explicit alignment and sector size values. sanlock.write_resource( "ls_name", "res_name", disks, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) res = sanlock.read_resource( path, offset=offset, align=ALIGNMENT_1M, sector=SECTOR_SIZE_512) assert res == { "lockspace": b"ls_name", "resource": b"res_name", "version": 0 } owners = sanlock.read_resource_owners("ls_name", "res_name", disks) assert owners == [] with io.open(path, "rb") as f: f.seek(offset) magic, = struct.unpack("< I", f.read(4)) assert magic == constants.PAXOS_DISK_MAGIC # TODO: check more stuff here... util.check_guard(path, size)
def remove(self, lease_id): """ Remove lease from index Raises: - NoSuchLease if lease was not found - OSError if I/O operation failed - sanlock.SanlockException if sanlock operation failed. """ log.info("Removing lease %r in lockspace %r", lease_id, self.lockspace) recnum = self._index.find_record(lease_id) if recnum == -1: raise se.NoSuchLease(lease_id) offset = lease_offset(recnum, self._alignment) # We remove a lease in 2 steps: # 1. write an empty record, making the resource unavailable. If writing # a record fails, the index does not change and the new resource # remains available # 2. write an empty sanlock resource in the slot associated with this # record. If this fails we log an error and don't fail the removal # as index is already updated and resource will not be available. self._write_record(recnum, EMPTY_RECORD) # There is no way to remove a resource, so we write an invalid resource # with empty resource and lockspace values. # TODO: Use SANLK_WRITE_CLEAR, expected in rhel 7.4. try: sanlock.write_resource(b"", b"", [(self._file.name, offset)], align=self._alignment, sector=self._block_size) except sanlock.SanlockException: log.warning( "Ignoring failure to clear sanlock resource file=%s " "offset=%s", self._file.name, offset)
def add(self, lease_id): """ Add lease to index, returning LeaseInfo. Raises: - LeaseExists if lease already stored for lease_id - InvalidRecord if corrupted lease record is found - NoSpace if all slots are allocated - OSError if I/O operation failed - sanlock.SanlockException if sanlock operation failed. """ # TODO: validate lease id is lower case uuid log.info("Adding lease %r in lockspace %r", lease_id, self._lockspace) recnum = self._index.find_record(lease_id) if recnum != -1: record = self._index.read_record(recnum) if record.state == RECORD_STALE: # TODO: rebuild this record instead of failing raise StaleLease(lease_id, record.modified) else: raise LeaseExists(lease_id, record.modified) recnum = self._index.find_record(BLANK_UUID) if recnum == -1: raise NoSpace(lease_id) record = Record(lease_id, RECORD_STALE) self._write_record(recnum, record) offset = self._lease_offset(recnum) sanlock.write_resource(self._lockspace, lease_id, [(self._file.name, offset)]) record = Record(lease_id, RECORD_USED) self._write_record(recnum, record) return LeaseInfo(self._lockspace, lease_id, self._file.name, offset, record.modified)
def test_clear_resource(tmpdir, sanlock_daemon): path = util.generate_path(tmpdir, "clear_test") util.create_file(path, MiB) disks = [(path, 0)] sanlock.write_resource(b"ls_name", b"res_name", disks) sanlock.write_resource(b"ls_name", b"res_name", disks, clear=True) with pytest.raises(sanlock.SanlockException) as e: sanlock.read_resource(path) assert e.value.errno == constants.SANLK_LEADER_MAGIC magic = util.read_magic(path) assert magic == constants.PAXOS_DISK_CLEAR util.check_guard(path, MiB) # run clear on already cleared resource sanlock.write_resource(b"ls_name", b"res_name", disks, clear=True) magic = util.read_magic(path) assert magic == constants.PAXOS_DISK_CLEAR
def _clear_resource(path, offset, alignment, block_size): log.info("Clearing sanlock resource file=%s offset=%s", path, offset) sanlock.write_resource(b"", b"", [(path, offset)], align=alignment, sector=block_size)
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 == []
def test_write_resource_invalid_disk(tmpdir, sanlock_daemon, disk): # Test parsing disks list with invalid content. disks = [disk] with pytest.raises(ValueError) as e: sanlock.write_resource(b"ls_name", b"res_name", disks) assert repr(disk) in str(e.value)
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 test_write_resource_invalid_disk(tmpdir, sanlock_daemon, disk): # Test parsing disks list with invalid content. disks = [disk] with pytest.raises(ValueError) as e: sanlock.write_resource("ls_name", "res_name", disks) assert repr(disk) in str(e.value)
def test_write_resource_parse_args(no_sanlock_daemon, name): with raises_sanlock_errno(): sanlock.write_resource(name, "res_name", [("disk_path",0)]) with raises_sanlock_errno(): sanlock.write_resource("ls_name", name, [("disk_path",0)])