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) record = Record(lease_id, offset, updating=True) self._write_record(recnum, 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. sanlock.write_resource( "", "", [(self._file.name, offset)], align=self._alignment, sector=self._block_size) self._write_record(recnum, EMPTY_RECORD)
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 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 NoSuchLease(lease_id) offset = lease_offset(recnum) record = Record(lease_id, offset, updating=True) self._write_record(recnum, 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. sanlock.write_resource("", "", [(self._file.name, offset)]) self._write_record(recnum, EMPTY_RECORD)
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) sanlock.write_resource(sdUUID, volUUID, [(leasePath, LEASE_FILEOFFSET)])
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) sanlock.write_resource(sdUUID, volUUID, [(leasePath, LEASE_FILEOFFSET)])
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 initSANLock(sdUUID, idsPath, lease): initSANLockLog.debug("Initializing SANLock for domain %s", sdUUID) try: sanlock.write_lockspace(sdUUID, idsPath) sanlock.write_resource( sdUUID, lease.name, [(lease.path, lease.offset)]) except sanlock.SanlockException: initSANLockLog.error("Cannot initialize SANLock for domain %s", sdUUID, exc_info=True) raise se.ClusterLockInitError()
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, volUUID, [(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 initSANLock( sdUUID, idsPath, lease, alignment=sc.ALIGNMENT_1M, block_size=sc.BLOCK_SIZE_512): initSANLockLog.debug("Initializing SANLock for domain %s", sdUUID) try: sanlock.write_lockspace( sdUUID, idsPath, align=alignment, sector=block_size) sanlock.write_resource( sdUUID, lease.name, [(lease.path, lease.offset)], align=alignment, sector=block_size) except sanlock.SanlockException: initSANLockLog.error("Cannot initialize SANLock for domain %s", sdUUID, exc_info=True) raise se.ClusterLockInitError()
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 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: # TODO: rebuild this record instead of failing raise LeaseUpdating(lease_id) else: raise LeaseExists(lease_id) recnum = self._index.find_free_record() if recnum == -1: raise NoSpace(lease_id) offset = lease_offset(recnum) record = Record(lease_id, offset, updating=True) self._write_record(recnum, record) sanlock.write_resource( self.lockspace, lease_id, [(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 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. """ 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: # TODO: rebuild this record instead of failing raise LeaseUpdating(lease_id) else: raise LeaseExists(lease_id) recnum = self._index.find_free_record() if recnum == -1: raise NoSpace(lease_id) offset = lease_offset(recnum) record = Record(lease_id, offset, updating=True) self._write_record(recnum, record) sanlock.write_resource(self.lockspace, lease_id, [(self._file.name, offset)]) record = Record(lease_id, offset) self._write_record(recnum, record) return LeaseInfo(self.lockspace, lease_id, self._file.name, offset)
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)