]>
Commit | Line | Data |
---|---|---|
9f95a23c TL |
1 | from mgr_util import get_most_recent_rate |
2 | ||
11fdf7f2 | 3 | from dashboard.services.ceph_service import CephService |
f67539c2 | 4 | |
11fdf7f2 TL |
5 | from .. import mgr |
6 | ||
9f95a23c TL |
7 | try: |
8 | from typing import Dict | |
9 | except ImportError: | |
10 | pass # Just for type checking | |
11 | ||
12 | ||
11fdf7f2 TL |
13 | SERVICE_TYPE = 'tcmu-runner' |
14 | ||
15 | ||
16 | class TcmuService(object): | |
17 | # pylint: disable=too-many-nested-blocks | |
f67539c2 | 18 | # pylint: disable=too-many-branches |
11fdf7f2 TL |
19 | @staticmethod |
20 | def get_iscsi_info(): | |
9f95a23c TL |
21 | daemons = {} # type: Dict[str, dict] |
22 | images = {} # type: Dict[str, dict] | |
39ae355f | 23 | daemon = None |
11fdf7f2 TL |
24 | for service in CephService.get_service_list(SERVICE_TYPE): |
25 | metadata = service['metadata'] | |
92f5a8d4 TL |
26 | if metadata is None: |
27 | continue | |
11fdf7f2 TL |
28 | status = service['status'] |
29 | hostname = service['hostname'] | |
30 | ||
31 | daemon = daemons.get(hostname, None) | |
32 | if daemon is None: | |
33 | daemon = { | |
34 | 'server_hostname': hostname, | |
35 | 'version': metadata['ceph_version'], | |
36 | 'optimized_paths': 0, | |
37 | 'non_optimized_paths': 0 | |
38 | } | |
39 | daemons[hostname] = daemon | |
40 | ||
41 | service_id = service['id'] | |
42 | device_id = service_id.split(':')[-1] | |
43 | image = images.get(device_id) | |
44 | if image is None: | |
45 | image = { | |
46 | 'device_id': device_id, | |
47 | 'pool_name': metadata['pool_name'], | |
48 | 'name': metadata['image_name'], | |
49 | 'id': metadata.get('image_id', None), | |
50 | 'optimized_paths': [], | |
51 | 'non_optimized_paths': [] | |
52 | } | |
53 | images[device_id] = image | |
54 | ||
55 | if status.get('lock_owner', 'false') == 'true': | |
56 | daemon['optimized_paths'] += 1 | |
57 | image['optimized_paths'].append(hostname) | |
58 | ||
59 | perf_key_prefix = "librbd-{id}-{pool}-{name}.".format( | |
60 | id=metadata.get('image_id', ''), | |
61 | pool=metadata['pool_name'], | |
62 | name=metadata['image_name']) | |
63 | perf_key = "{}lock_acquired_time".format(perf_key_prefix) | |
f67539c2 TL |
64 | perf_value = mgr.get_counter('tcmu-runner', |
65 | service_id, | |
66 | perf_key)[perf_key] | |
67 | if perf_value: | |
68 | lock_acquired_time = perf_value[-1][1] / 1000000000 | |
69 | else: | |
70 | lock_acquired_time = 0 | |
11fdf7f2 TL |
71 | if lock_acquired_time > image.get('optimized_since', 0): |
72 | image['optimized_daemon'] = hostname | |
73 | image['optimized_since'] = lock_acquired_time | |
74 | image['stats'] = {} | |
75 | image['stats_history'] = {} | |
76 | for s in ['rd', 'wr', 'rd_bytes', 'wr_bytes']: | |
77 | perf_key = "{}{}".format(perf_key_prefix, s) | |
9f95a23c TL |
78 | rates = CephService.get_rates('tcmu-runner', service_id, perf_key) |
79 | image['stats'][s] = get_most_recent_rate(rates) | |
80 | image['stats_history'][s] = rates | |
11fdf7f2 TL |
81 | else: |
82 | daemon['non_optimized_paths'] += 1 | |
83 | image['non_optimized_paths'].append(hostname) | |
84 | ||
85 | # clear up races w/ tcmu-runner clients that haven't detected | |
86 | # loss of optimized path | |
87 | for image in images.values(): | |
88 | optimized_daemon = image.get('optimized_daemon', None) | |
89 | if optimized_daemon: | |
90 | for daemon_name in image['optimized_paths']: | |
91 | if daemon_name != optimized_daemon: | |
92 | daemon = daemons[daemon_name] | |
93 | daemon['optimized_paths'] -= 1 | |
94 | daemon['non_optimized_paths'] += 1 | |
95 | image['non_optimized_paths'].append(daemon_name) | |
96 | image['optimized_paths'] = [optimized_daemon] | |
97 | ||
98 | return { | |
99 | 'daemons': sorted(daemons.values(), | |
100 | key=lambda d: d['server_hostname']), | |
101 | 'images': sorted(images.values(), key=lambda i: ['id']), | |
102 | } | |
103 | ||
104 | @staticmethod | |
105 | def get_image_info(pool_name, image_name, get_iscsi_info): | |
106 | for image in get_iscsi_info['images']: | |
107 | if image['pool_name'] == pool_name and image['name'] == image_name: | |
108 | return image | |
109 | return None |