Пример #1
0
def read_resource(path,
                  offset,
                  alignment=sc.ALIGNMENT_1M,
                  block_size=sc.BLOCK_SIZE_512):
    """
    Helper for reading sanlock resoruces, supporting both non-existing and
    deleted resources.

    Returns: ResourceInfo
    Raises: NoSuchResource if there is no resource at this offset
    """
    try:
        res = sanlock.read_resource(path,
                                    offset,
                                    align=alignment,
                                    sector=block_size)
    except sanlock.SanlockException as e:
        if e.errno != SANLK_LEADER_MAGIC:
            raise
        raise NoSuchResource(path, offset)
    if res["resource"] == b"":
        # lease deleted with a version of sanlock not supporting
        # resource clearning.
        raise NoSuchResource(path, offset)
    return ResourceInfo(res["lockspace"].decode("utf-8"),
                        res["resource"].decode("utf-8"), res["version"])
Пример #2
0
    def inquire(self, lease):
        resource = sanlock.read_resource(lease.path, lease.offset)
        if resource["resource"] != lease.name:
            raise InvalidLeaseName(resource["resource"], lease)

        owners = sanlock.read_resource_owners(self._sdUUID, lease.name,
                                              [(lease.path, lease.offset)])

        if len(owners) > 1:
            self.log.error("Cluster lock is reported to have more than "
                           "one owner: %s", owners)
            raise RuntimeError("Multiple owners for %s" % (lease,))

        elif not owners:
            return None, None

        resource_owner = owners[0]
        resource_version = resource["version"]
        host_id = resource_owner["host_id"]
        try:
            host = sanlock.get_hosts(self._sdUUID, host_id)[0]
        except sanlock.SanlockException as e:
            if e.errno == errno.ENOENT:
                # add_lockspace has not been completed yet,
                # the inquiry has to be retried.
                raise TemporaryFailure("inquire", lease, str(e))
            elif e.errno == errno.EAGAIN:
                # The host status is not available yet.
                # Normally, we'd raise it to the caller, but this
                # breaks the "Remove DC" flow in engine, so we assume
                # the lease is currently held by the host
                # See: https://bugzilla.redhat.com/1613838
                self.log.debug("host %s status in not available yet, "
                               "it may hold the lease %s",
                               host_id, lease)
                return resource_version, host_id
            else:
                raise

        host_status = self.STATUS_NAME[host["flags"]]

        if resource_owner["generation"] != host["generation"]:
            # The lease is considered free by sanlock because
            # the host reconnected to the storage but it no
            # longer has the lease
            self.log.debug("host %r generation %r does not match resource "
                           "generation %r, lease %s is free", host_id,
                           host, resource_owner["generation"], lease)
            return resource_version, None

        if host_status in (HOST_STATUS_DEAD, HOST_STATUS_FREE):
            # These are the only states that mean the host cannot hold
            # this lease. Any other state means the host either holding the
            # lease or could be holding the lease.
            self.log.debug("host %s cannot hold %s is effectively free",
                           host, lease)
            return resource_version, None

        return resource_version, host_id
Пример #3
0
    def inquire(self, lease):
        resource = sanlock.read_resource(lease.path, lease.offset)
        if resource["resource"] != lease.name:
            raise InvalidLeaseName(resource["resource"], lease)

        owners = sanlock.read_resource_owners(self._sdUUID, lease.name,
                                              [(lease.path, lease.offset)])

        if len(owners) == 1:
            return resource.get("version"), owners[0].get("host_id")
        elif len(owners) > 1:
            self.log.error("Cluster lock is reported to have more than "
                           "one owner: %s", owners)
            raise RuntimeError("Multiple owners for %s" % (lease,))

        return None, None
Пример #4
0
    def inquire(self, lease):
        resource = sanlock.read_resource(lease.path, lease.offset)
        if resource["resource"] != lease.name:
            raise InvalidLeaseName(resource["resource"], lease)

        owners = sanlock.read_resource_owners(self._sdUUID, lease.name,
                                              [(lease.path, lease.offset)])

        if len(owners) == 1:
            return resource.get("version"), owners[0].get("host_id")
        elif len(owners) > 1:
            self.log.error(
                "Cluster lock is reported to have more than "
                "one owner: %s", owners)
            raise RuntimeError("Multiple owners for %s" % (lease, ))

        return None, None
Пример #5
0
def read_resource(path, offset):
    """
    Helper for reading sanlock resoruces, supporting both non-existing and
    deleted resources.

    Returns: ResourceInfo
    Raises: NoSuchResource if there is no resource at this offset
    """
    try:
        res = sanlock.read_resource(path, offset)
    except sanlock.SanlockException as e:
        if e.errno != SANLK_LEADER_MAGIC:
            raise
        raise NoSuchResource(path, offset)
    if res["resource"] == "":
        # lease deleted with a version of sanlock not supporting
        # resource clearning.
        raise NoSuchResource(path, offset)
    return ResourceInfo(res["lockspace"], res["resource"], res["version"])
Пример #6
0
def read_resource(path, offset):
    """
    Helper for reading sanlock resoruces, supporting both non-existing and
    deleted resources.

    Returns: ResourceInfo
    Raises: NoSuchResource if there is no resource at this offset
    """
    try:
        res = sanlock.read_resource(path, offset)
    except sanlock.SanlockException as e:
        if e.errno != SANLK_LEADER_MAGIC:
            raise
        raise NoSuchResource(path, offset)
    if res["resource"] == "":
        # lease deleted with a version of sanlock not supporting
        # resource clearning.
        raise NoSuchResource(path, offset)
    return ResourceInfo(res["lockspace"], res["resource"], res["version"])