f.write('\n'.join(lines))
conf = Path(ctx.sysctl_dir).joinpath(f'90-ceph-{fsid}-{daemon_type}.conf')
- lines: Optional[List] = None
+ lines: List = []
if daemon_type == 'osd':
lines = OSD.get_sysctl_settings()
lines = HAproxy.get_sysctl_settings()
elif daemon_type == 'keepalived':
lines = Keepalived.get_sysctl_settings()
+ lines = filter_sysctl_settings(ctx, lines)
# apply the sysctl settings
if lines:
call_throws(ctx, ['sysctl', '--system'])
+def sysctl_get(ctx: CephadmContext, variable: str) -> Union[str, None]:
+ """
+ Read a sysctl setting by executing 'sysctl -b {variable}'
+ """
+ out, err, code = call(ctx, ['sysctl', '-b', variable])
+ return out or None
+
+
+def filter_sysctl_settings(ctx: CephadmContext, lines: List[str]) -> List[str]:
+ """
+ Given a list of sysctl settings, examine the system's current configuration
+ and return those which are not currently set as described.
+ """
+ def test_setting(desired_line: str) -> bool:
+ # Remove any comments
+ comment_start = desired_line.find('#')
+ if comment_start != -1:
+ desired_line = desired_line[:comment_start]
+ desired_line = desired_line.strip()
+ if not desired_line or desired_line.isspace():
+ return False
+ setting, desired_value = map(lambda s: s.strip(), desired_line.split('='))
+ if not setting or not desired_value:
+ return False
+ actual_value = sysctl_get(ctx, setting)
+ return desired_value != actual_value
+ return list(filter(test_setting, lines))
+
+
def migrate_sysctl_dir(ctx: CephadmContext, fsid: str) -> None:
"""
Cephadm once used '/usr/lib/sysctl.d' for storing sysctl configuration.
# invalid IPv6 and valid subnets list
with pytest.raises(Exception):
- rc = cd.ip_in_sublets('fe80:2030:31:24', 'fe80::/64')
\ No newline at end of file
+ rc = cd.ip_in_sublets('fe80:2030:31:24', 'fe80::/64')
+
+
+class TestSysctl:
+ @mock.patch('cephadm.sysctl_get')
+ def test_filter_sysctl_settings(self, sysctl_get):
+ ctx = cd.CephadmContext()
+ input = [
+ # comment-only lines should be ignored
+ "# just a comment",
+ # As should whitespace-only lines",
+ " \t ",
+ " = \t ",
+ # inline comments are stripped when querying
+ "something = value # inline comment",
+ "fs.aio-max-nr = 1048576",
+ "kernel.pid_max = 4194304",
+ "vm.lowmem_reserve_ratio = 256\t256\t32\t0\t0",
+ " vm.max_map_count = 65530 ",
+ " vm.max_map_count = 65530 ",
+ ]
+ sysctl_get.side_effect = [
+ "value",
+ "1",
+ "4194304",
+ "256\t256\t32\t0\t0",
+ "65530",
+ "something else",
+ ]
+ result = cd.filter_sysctl_settings(ctx, input)
+ assert len(sysctl_get.call_args_list) == 6
+ assert sysctl_get.call_args_list[0].args[1] == "something"
+ assert sysctl_get.call_args_list[1].args[1] == "fs.aio-max-nr"
+ assert sysctl_get.call_args_list[2].args[1] == "kernel.pid_max"
+ assert sysctl_get.call_args_list[3].args[1] == "vm.lowmem_reserve_ratio"
+ assert sysctl_get.call_args_list[4].args[1] == "vm.max_map_count"
+ assert sysctl_get.call_args_list[5].args[1] == "vm.max_map_count"
+ assert result == [
+ "fs.aio-max-nr = 1048576",
+ " vm.max_map_count = 65530 ",
+ ]