Ejemplo n.º 1
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.º 2
0
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)
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
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)
Ejemplo n.º 5
0
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
Ejemplo n.º 6
0
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)
Ejemplo n.º 7
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.
        """
        # 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)
Ejemplo n.º 8
0
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)])
Ejemplo n.º 9
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)
Ejemplo n.º 10
0
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
Ejemplo n.º 11
0
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)
Ejemplo n.º 12
0
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)
Ejemplo n.º 13
0
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)
Ejemplo n.º 14
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.º 15
0
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
Ejemplo n.º 16
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, 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)
Ejemplo n.º 17
0
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)
Ejemplo n.º 18
0
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
Ejemplo n.º 19
0
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
Ejemplo n.º 20
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.encode("utf-8"),
            volUUID.encode("utf-8"),
            [(leasePath, LEASE_FILEOFFSET)],
            align=manifest.alignment,
            sector=manifest.block_size)
Ejemplo n.º 21
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.º 22
0
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
Ejemplo n.º 23
0
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)
Ejemplo n.º 24
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.º 25
0
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
Ejemplo n.º 26
0
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)
Ejemplo n.º 27
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.º 28
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.
        """
        # 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)
Ejemplo n.º 29
0
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
Ejemplo n.º 30
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)
Ejemplo n.º 31
0
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 == []
Ejemplo n.º 32
0
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)
Ejemplo n.º 33
0
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 == []
Ejemplo n.º 34
0
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)
Ejemplo n.º 35
0
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)])