Ejemplo n.º 1
0
    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)
Ejemplo n.º 2
0
    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()
Ejemplo n.º 3
0
Archivo: xlease.py Proyecto: nirs/vdsm
    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)
Ejemplo n.º 4
0
 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)])
Ejemplo n.º 5
0
 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)])
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
0
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()
Ejemplo n.º 8
0
    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)
Ejemplo n.º 9
0
    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)
Ejemplo n.º 10
0
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()
Ejemplo n.º 11
0
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))
Ejemplo n.º 12
0
    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)
Ejemplo n.º 13
0
    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)
Ejemplo n.º 14
0
Archivo: xlease.py Proyecto: nirs/vdsm
    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)
Ejemplo n.º 15
0
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)