]> git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/cephadm/tuned_profiles.py
3f617956846ba62471702526db38c710a150c27d
[ceph.git] / ceph / src / pybind / mgr / cephadm / tuned_profiles.py
1 import logging
2 from typing import Dict, List, TYPE_CHECKING
3 from ceph.utils import datetime_now
4 from .schedule import HostAssignment
5 from ceph.deployment.service_spec import ServiceSpec, TunedProfileSpec
6
7 if TYPE_CHECKING:
8 from cephadm.module import CephadmOrchestrator
9
10 logger = logging.getLogger(__name__)
11
12 SYSCTL_DIR = '/etc/sysctl.d'
13
14
15 class TunedProfileUtils():
16 def __init__(self, mgr: "CephadmOrchestrator") -> None:
17 self.mgr = mgr
18
19 def _profile_to_str(self, p: TunedProfileSpec) -> str:
20 p_str = f'# created by cephadm\n# tuned profile "{p.profile_name}"\n\n'
21 for k, v in p.settings.items():
22 p_str += f'{k} = {v}\n'
23 return p_str
24
25 def _write_all_tuned_profiles(self) -> None:
26 host_profile_mapping: Dict[str, List[Dict[str, str]]] = {}
27 for host in self.mgr.cache.get_hosts():
28 host_profile_mapping[host] = []
29
30 for profile in self.mgr.tuned_profiles.list_profiles():
31 p_str = self._profile_to_str(profile)
32 ha = HostAssignment(
33 spec=ServiceSpec(
34 'crash', placement=profile.placement),
35 hosts=self.mgr.cache.get_schedulable_hosts(),
36 unreachable_hosts=self.mgr.cache.get_unreachable_hosts(),
37 draining_hosts=self.mgr.cache.get_draining_hosts(),
38 daemons=[],
39 networks=self.mgr.cache.networks,
40 )
41 all_slots, _, _ = ha.place()
42 for host in {s.hostname for s in all_slots}:
43 host_profile_mapping[host].append({profile.profile_name: p_str})
44
45 for host, profiles in host_profile_mapping.items():
46 self._remove_stray_tuned_profiles(host, profiles)
47 self._write_tuned_profiles(host, profiles)
48
49 def _remove_stray_tuned_profiles(self, host: str, profiles: List[Dict[str, str]]) -> None:
50 if host in self.mgr.offline_hosts:
51 return
52 cmd = ['ls', SYSCTL_DIR]
53 found_files = self.mgr.ssh.check_execute_command(host, cmd).split('\n')
54 found_files = [s.strip() for s in found_files]
55 updated = False
56 for file in found_files:
57 if '-cephadm-tuned-profile.conf' not in file:
58 continue
59 if not any(file.split('-')[0] in p.keys() for p in profiles):
60 logger.info(f'Removing stray tuned profile file {file}')
61 cmd = ['rm', '-f', f'{SYSCTL_DIR}/{file}']
62 self.mgr.ssh.check_execute_command(host, cmd)
63 updated = True
64 if updated:
65 self.mgr.ssh.check_execute_command(host, ['sysctl', '--system'])
66
67 def _write_tuned_profiles(self, host: str, profiles: List[Dict[str, str]]) -> None:
68 if host in self.mgr.offline_hosts:
69 return
70 updated = False
71 for p in profiles:
72 for profile_name, content in p.items():
73 if self.mgr.cache.host_needs_tuned_profile_update(host, profile_name):
74 logger.info(f'Writing tuned profile {profile_name} to host {host}')
75 profile_filename: str = f'{SYSCTL_DIR}/{profile_name}-cephadm-tuned-profile.conf'
76 self.mgr.ssh.write_remote_file(host, profile_filename, content.encode('utf-8'))
77 updated = True
78 if updated:
79 self.mgr.ssh.check_execute_command(host, ['sysctl', '--system'])
80 self.mgr.cache.last_tuned_profile_update[host] = datetime_now()