def test_add_rem_lockspace_async(tmpdir, sanlock_daemon): path = str(tmpdir.join("ls_name")) util.create_file(path, MiB) sanlock.write_lockspace("ls_name", path, iotimeout=1) acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=False) assert acquired is False # This will take 3 seconds. sanlock.add_lockspace("ls_name", 1, path, iotimeout=1, **{"async": True}) # While the lockspace is being aquired, we expect to get None. time.sleep(1) acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=False) assert acquired is None # Once the lockspace is acquired, we exepect to get True. acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=True) assert acquired is True # This will take about 3 seconds. sanlock.rem_lockspace("ls_name", 1, path, **{"async": True}) # Wait until the lockspace change state from True to None. while sanlock.inq_lockspace("ls_name", 1, path, wait=False): time.sleep(1) # While the lockspace is being released, we expect to get None. acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=False) assert acquired is None # Once the lockspace was released, we expect to get False. acquired = sanlock.inq_lockspace("ls_name", 1, path, wait=True) assert acquired is False
def main(): print "Creating the sanlock disk" fd, disk = tempfile.mkstemp() os.close(fd) offset = sanlock.get_alignment(disk) SNLK_DISKS = [(disk, offset)] print "Registering to sanlock" fd = sanlock.register() print "Initializing '%s'" % (LOCKSPACE_NAME, ) sanlock.init_lockspace(LOCKSPACE_NAME, disk) print "Initializing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.init_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) print "Releasing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.release(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) 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_add_rem_lockspace(tmpdir, sanlock_daemon, size, offset): path = str(tmpdir.join("ls_name")) util.create_file(path, size) sanlock.write_lockspace("ls_name", path, offset=offset, iotimeout=1) # Since the lockspace is not acquired, we exepect to get False. acquired = sanlock.inq_lockspace("ls_name", 1, path, offset=offset, wait=False) assert acquired is False sanlock.add_lockspace("ls_name", 1, path, offset=offset, iotimeout=1) # Once the lockspace is acquired, we exepect to get True. acquired = sanlock.inq_lockspace("ls_name", 1, path, offset=offset, wait=False) assert acquired is True sanlock.rem_lockspace("ls_name", 1, path, offset=offset) # Once the lockspace is released, we exepect to get False. acquired = sanlock.inq_lockspace("ls_name", 1, path, offset=offset, wait=False) assert acquired is False
def test_add_rem_lockspace_async(tmpdir, sanlock_daemon): path = str(tmpdir.join("ls_name")) util.create_file(path, MiB) sanlock.write_lockspace(b"ls_name", path, iotimeout=1) acquired = sanlock.inq_lockspace(b"ls_name", 1, path, wait=False) assert acquired is False # This will take 3 seconds. sanlock.add_lockspace(b"ls_name", 1, path, iotimeout=1, wait=False) # While the lockspace is being aquired, we expect to get None. time.sleep(1) acquired = sanlock.inq_lockspace(b"ls_name", 1, path, wait=False) assert acquired is None # Once the lockspace is acquired, we exepect to get True. acquired = sanlock.inq_lockspace(b"ls_name", 1, path, wait=True) assert acquired is True # This will take about 3 seconds. sanlock.rem_lockspace(b"ls_name", 1, path, wait=False) # Wait until the lockspace change state from True to None. while sanlock.inq_lockspace(b"ls_name", 1, path, wait=False): time.sleep(1) # While the lockspace is being released, we expect to get None. acquired = sanlock.inq_lockspace(b"ls_name", 1, path, wait=False) assert acquired is None # Once the lockspace was released, we expect to get False. acquired = sanlock.inq_lockspace(b"ls_name", 1, path, wait=True) assert acquired is False
def _initialize_sanlock(self): self._cond_start_service('sanlock') lease_file = self._broker.get_service_path( constants.SERVICE_TYPE + constants.LOCKSPACE_EXTENSION) if not self._sanlock_initialized: lvl = logging.INFO else: lvl = logging.DEBUG self._log.log(lvl, "Ensuring lease for lockspace %s, host id %d" " is acquired (file: %s)", constants.LOCKSPACE_NAME, self.host_id, lease_file) for attempt in range(constants.WAIT_FOR_STORAGE_RETRY): try: sanlock.add_lockspace(constants.LOCKSPACE_NAME, self.host_id, lease_file) except sanlock.SanlockException as e: if hasattr(e, 'errno'): if e.errno == errno.EEXIST: self._log.debug("Host already holds lock") break elif e.errno == errno.EINVAL: self._log.error( "cannot get lock on host id {0}: " "host already holds lock on a different" " host id" .format(self.host_id)) raise # this shouldn't happen, so throw the exception elif e.errno == errno.EINTR: self._log.warn("cannot get lock on host id {0}:" " sanlock operation interrupted" " (will retry)" .format(self.host_id)) elif e.errno == errno.EINPROGRESS: self._log.warn("cannot get lock on host id {0}:" " sanlock operation in progress" "(will retry)" .format(self.host_id)) elif e.errno == errno.ENOENT: self._log.warn("cannot get lock on host id {0}:" " the lock file '{1}' is missing" "(will retry)" .format(self.host_id, lease_file)) else: # no exception, we acquired the lock self._log.info("Acquired lock on host id %d", self.host_id) break # some temporary problem has occurred (usually waiting for # the storage), so wait a while and try again self._log.info("Failed to acquire the lock. Waiting '{0}'s before" " the next attempt". format(constants.WAIT_FOR_STORAGE_DELAY)) time.sleep(constants.WAIT_FOR_STORAGE_DELAY) else: # happens only if all attempts are exhausted raise ex.SanlockInitializationError( "Failed to initialize sanlock, the number of errors has" " exceeded the limit") # we get here only if the the lock is acquired self._sanlock_initialized = True
def main(): print "Creating the sanlock disk" fd, disk = tempfile.mkstemp() os.close(fd) offset = sanlock.get_alignment(disk) SNLK_DISKS = [(disk, offset)] print "Registering to sanlock" fd = sanlock.register() print "Initializing '%s'" % (LOCKSPACE_NAME,) sanlock.init_lockspace(LOCKSPACE_NAME, disk) print "Initializing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.init_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) print "Releasing '%s' on '%s'" % (RESOURCE_NAME, LOCKSPACE_NAME) sanlock.release(LOCKSPACE_NAME, RESOURCE_NAME, SNLK_DISKS, slkfd=fd) 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 _acquire_whiteboard_lock(self): self._log.log(logging.DEBUG, "Ensuring lease for lockspace %s, host id %d " "is acquired (file: %s)", broker_constants.LOCKSPACE_NAME, self.host_id, self._lease_file) for attempt in range(broker_constants.WAIT_FOR_STORAGE_RETRY): try: sanlock.add_lockspace( broker_constants.LOCKSPACE_NAME.encode(), self.host_id, self._lease_file ) except sanlock.SanlockException as e: if hasattr(e, 'errno'): if e.errno == errno.EEXIST: self._log.debug("Host already holds lock") break elif e.errno == errno.EINVAL: self._log.error( "cannot get lock on host id {0}: " "host already holds lock on a different" " host id" .format(self.host_id)) raise # this shouldn't happen, so throw the exception elif e.errno == errno.EINTR: self._log.warn("cannot get lock on host id {0}:" " sanlock operation interrupted" " (will retry)" .format(self.host_id)) elif e.errno == errno.EINPROGRESS: self._log.warn("cannot get lock on host id {0}:" " sanlock operation in progress" "(will retry)" .format(self.host_id)) elif e.errno == errno.ENOENT: self._log.warn("cannot get lock on host id {0}:" " the lock file '{1}' is missing" "(will retry)" .format(self.host_id, self._lease_file)) else: # no exception, we acquired the lock self._log.info("Acquired lock on host id %d", self.host_id) break # some temporary problem has occurred (usually waiting for # the storage), so wait a while and try again self._log.info("Failed to acquire the lock. Waiting '{0}'s before" " the next attempt". format(broker_constants.WAIT_FOR_STORAGE_DELAY)) time.sleep(broker_constants.WAIT_FOR_STORAGE_DELAY) else: # happens only if all attempts are exhausted raise ex.SanlockInitializationError( "Failed to initialize sanlock, the number of errors has" " exceeded the limit") # we get here only if the the lock is acquired return True
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 sanlock_acquire(hostId, lockspacePath, leasePath): sfd = sanlock.register() if not sanlock.inq_lockspace(LOCKSPACE_NAME, hostId, lockspacePath): msg = "Try to acquire host id %s:%s:%s:0" % (LOCKSPACE_NAME, hostId, lockspacePath) print(msg) sanlock.add_lockspace(LOCKSPACE_NAME, hostId, lockspacePath) msg = "Try to acquire leader lease:%s" % str(leasePath) print(msg) sanlock.acquire(LOCKSPACE_NAME, RESOURCE_NAME, [(leasePath, 0)], sfd)
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 acquireHostId(self, hostId, async): with self._lock: self.log.info("Acquiring host id for domain %s (id: %s)", self._sdUUID, hostId) try: sanlock.add_lockspace(self._sdUUID, hostId, self._idsPath, async=async) except sanlock.SanlockException as e: if e.errno == errno.EINPROGRESS: # if the request is not asynchronous wait for the ongoing # lockspace operation to complete if not async and not sanlock.inq_lockspace(self._sdUUID, hostId, self._idsPath, wait=True): raise se.AcquireHostIdFailure(self._sdUUID, e) # else silently continue, the host id has been acquired # or it's in the process of being acquired (async) elif e.errno != errno.EEXIST: raise se.AcquireHostIdFailure(self._sdUUID, e)
def test_add_rem_lockspace(tmpdir, sanlock_daemon, size, offset): path = str(tmpdir.join("ls_name")) util.create_file(path, size) sanlock.write_lockspace(b"ls_name", path, offset=offset, iotimeout=1) # Since the lockspace is not acquired, we exepect to get False. acquired = sanlock.inq_lockspace(b"ls_name", 1, path, offset=offset, wait=False) assert acquired is False sanlock.add_lockspace(b"ls_name", 1, path, offset=offset, iotimeout=1) # Once the lockspace is acquired, we exepect to get True. acquired = sanlock.inq_lockspace(b"ls_name", 1, path, offset=offset, wait=False) assert acquired is True lockspaces = sanlock.get_lockspaces() assert lockspaces == [{ 'flags': 0, 'host_id': 1, 'lockspace': b'ls_name', 'offset': offset, 'path': path }] sanlock.rem_lockspace(b"ls_name", 1, path, offset=offset) # Once the lockspace is released, we exepect to get False. acquired = sanlock.inq_lockspace(b"ls_name", 1, path, offset=offset, wait=False) assert acquired is False lockspaces = sanlock.get_lockspaces() assert lockspaces == []
def acquireHostId(self, hostId, wait): self.log.info("Acquiring host id for domain %s (id=%s, wait=%s)", self._sdUUID, hostId, wait) # Ensure that future calls to acquire() will wait until host id is # acquired. self._ready.valid = True with self._lock: self._start_add_lockspace() try: sanlock.add_lockspace( self._lockspace_name, hostId, self._idsPath, iotimeout=self._io_timeout, wait=wait) except sanlock.SanlockException as e: if e.errno == errno.EINPROGRESS: # if the request is not asynchronous wait for the ongoing # lockspace operation to complete else silently continue, # the host id has been acquired or it's in the process of # being acquired (async). if wait: if not sanlock.inq_lockspace( self._lockspace_name, hostId, self._idsPath, wait=True): raise se.AcquireHostIdFailure(self._sdUUID, e) self._end_add_lockspace(hostId) self._ready.set() elif e.errno == errno.EEXIST: self.log.info("Host id %s for domain %s already acquired", hostId, self._sdUUID) self._cancel_add_lockspace() self._ready.set() else: self._cancel_add_lockspace() raise se.AcquireHostIdFailure(self._sdUUID, e) else: if wait: self._end_add_lockspace(hostId) self._ready.set()
def acquireHostId(self, hostId): with self._lock: if self._hostId is not None: raise se.AcquireHostIdFailure(self._sdUUID, "Host id already acquired") self.log.info("Acquiring host id for domain %s (id: %s)", self._sdUUID, hostId) try: sanlock.add_lockspace(self._sdUUID, hostId, self._idsPath) except sanlock.SanlockException, e: if e.errno != errno.EEXIST: raise se.AcquireHostIdFailure(self._sdUUID, e) self._hostId = hostId self.log.debug("Host id for domain %s successfully acquired " "(id: %s)", self._sdUUID, self._hostId)
def test_add_rem_lockspace(tmpdir, sanlock_daemon, size, offset): path = str(tmpdir.join("ls_name")) util.create_file(path, size) sanlock.write_lockspace("ls_name", path, offset=offset, iotimeout=1) # Since the lockspace is not acquired, we exepect to get False. acquired = sanlock.inq_lockspace( "ls_name", 1, path, offset=offset, wait=False) assert acquired is False sanlock.add_lockspace("ls_name", 1, path, offset=offset, iotimeout=1) # Once the lockspace is acquired, we exepect to get True. acquired = sanlock.inq_lockspace( "ls_name", 1, path, offset=offset, wait=False) assert acquired is True lockspaces = sanlock.get_lockspaces() assert lockspaces == [{ 'flags': 0, 'host_id': 1, 'lockspace': b'ls_name', 'offset': offset, 'path': path }] sanlock.rem_lockspace("ls_name", 1, path, offset=offset) # Once the lockspace is released, we exepect to get False. acquired = sanlock.inq_lockspace( "ls_name", 1, path, offset=offset, wait=False) assert acquired is False lockspaces = sanlock.get_lockspaces() assert lockspaces == []
def test_add_lockspace_parse_args(no_sanlock_daemon, name, filename, encoding): path = util.generate_path("/tmp/", filename, encoding) with raises_sanlock_errno(): sanlock.add_lockspace(name, 1, path, 0, wait=False)
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_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_add_lockspace_parse_args(no_sanlock_daemon, name): with raises_sanlock_errno(): sanlock.add_lockspace(name, 1, "ls_path", 0)