'tcmu-runner', service_id, perf_key)[perf_key] or
[[0, 0]])[-1][1] / 1000000000
if lock_acquired_time > image.get('optimized_since', 0):
+ image['optimized_daemon'] = hostname
image['optimized_since'] = lock_acquired_time
image['stats'] = {}
image['stats_history'] = {}
daemon['non_optimized_paths'] += 1
image['non_optimized_paths'].append(hostname)
+ # clear up races w/ tcmu-runner clients that haven't detected
+ # loss of optimized path
+ for image in images.values():
+ optimized_daemon = image.get('optimized_daemon', None)
+ if optimized_daemon:
+ for daemon_name in image['optimized_paths']:
+ if daemon_name != optimized_daemon:
+ daemon = daemons[daemon_name]
+ daemon['optimized_paths'] -= 1
+ daemon['non_optimized_paths'] += 1
+ image['non_optimized_paths'].append(daemon_name)
+ image['optimized_paths'] = [optimized_daemon]
+
return {
'daemons': sorted(daemons.values(), key=lambda d: d['server_hostname']),
'images': sorted(images.values(), key=lambda i: ['id']),
mocked_servers = [{
'ceph_version': 'ceph version 13.0.0-5083- () mimic (dev)',
- 'hostname': 'ceph-dev',
- 'services': [{'id': 'a:b', 'type': 'tcmu-runner'}]
+ 'hostname': 'ceph-dev1',
+ 'services': [{'id': 'ceph-dev1:pool1/image1', 'type': 'tcmu-runner'}]
+}, {
+ 'ceph_version': 'ceph version 13.0.0-5083- () mimic (dev)',
+ 'hostname': 'ceph-dev2',
+ 'services': [{'id': 'ceph-dev2:pool1/image1', 'type': 'tcmu-runner'}]
}]
-mocked_metadata = {
+mocked_metadata1 = {
'ceph_version': 'ceph version 13.0.0-5083- () mimic (dev)',
'pool_name': 'pool1',
'image_name': 'image1',
'image_id': '42',
- 'optimized_since': 100.0,
+ 'optimized_since': 1152121348,
+}
+
+mocked_metadata2 = {
+ 'ceph_version': 'ceph version 13.0.0-5083- () mimic (dev)',
+ 'pool_name': 'pool1',
+ 'image_name': 'image1',
+ 'image_id': '42',
+ 'optimized_since': 0,
}
mocked_get_daemon_status = {
'lock_owner': 'true',
}
-mocked_get_counter = {
- 'librbd-42-pool1-image1.lock_acquired_time': [[10000.0, 10000.0]],
+mocked_get_counter1 = {
+ 'librbd-42-pool1-image1.lock_acquired_time': [[1152121348 * 1000000000,
+ 1152121348 * 1000000000]],
'librbd-42-pool1-image1.rd': [[0, 0], [1, 43]],
'librbd-42-pool1-image1.wr': [[0, 0], [1, 44]],
'librbd-42-pool1-image1.rd_bytes': [[0, 0], [1, 45]],
'librbd-42-pool1-image1.wr_bytes': [[0, 0], [1, 46]],
}
+mocked_get_counter2 = {
+ 'librbd-42-pool1-image1.lock_acquired_time': [[0, 0]],
+ 'librbd-42-pool1-image1.rd': [],
+ 'librbd-42-pool1-image1.wr': [],
+ 'librbd-42-pool1-image1.rd_bytes': [],
+ 'librbd-42-pool1-image1.wr_bytes': [],
+}
+
+
+def _get_counter(_daemon_type, daemon_name, _stat):
+ if daemon_name == 'ceph-dev1:pool1/image1':
+ return mocked_get_counter1
+ elif daemon_name == 'ceph-dev2:pool1/image1':
+ return mocked_get_counter2
+ return Exception('invalid daemon name')
+
class TcmuIscsiControllerTest(ControllerTestCase):
@classmethod
def setup_server(cls):
mgr.list_servers.return_value = mocked_servers
- mgr.get_metadata.return_value = mocked_metadata
+ mgr.get_metadata.side_effect = [mocked_metadata1, mocked_metadata2]
mgr.get_daemon_status.return_value = mocked_get_daemon_status
- mgr.get_counter.return_value = mocked_get_counter
+ mgr.get_counter.side_effect = _get_counter
mgr.url_prefix = ''
TcmuIscsi._cp_config['tools.authenticate.on'] = False # pylint: disable=protected-access
self._get('/api/test/tcmu')
self.assertStatus(200)
self.assertJsonBody({
- 'daemons': [{
- 'server_hostname': 'ceph-dev',
- 'version': 'ceph version 13.0.0-5083- () mimic (dev)',
- 'optimized_paths': 1, 'non_optimized_paths': 0}],
+ 'daemons': [
+ {
+ 'server_hostname': 'ceph-dev1',
+ 'version': 'ceph version 13.0.0-5083- () mimic (dev)',
+ 'optimized_paths': 1, 'non_optimized_paths': 0},
+ {
+ 'server_hostname': 'ceph-dev2',
+ 'version': 'ceph version 13.0.0-5083- () mimic (dev)',
+ 'optimized_paths': 0, 'non_optimized_paths': 1}],
'images': [{
- 'device_id': 'b',
+ 'device_id': 'pool1/image1',
'pool_name': 'pool1',
'name': 'image1',
- 'id': '42', 'optimized_paths': ['ceph-dev'],
- 'non_optimized_paths': [],
- 'optimized_since': 1e-05,
+ 'id': '42',
+ 'optimized_paths': ['ceph-dev1'],
+ 'non_optimized_paths': ['ceph-dev2'],
+ 'optimized_daemon': 'ceph-dev1',
+ 'optimized_since': 1152121348,
'stats': {
'rd': 43.0,
'wr': 44.0,