add CLI options using sys.argv
This commit is contained in:
parent
5f211d765b
commit
c0cffa7e7a
20
README.md
20
README.md
@ -107,6 +107,19 @@ $ sudo systemctl start nohang
|
|||||||
$ sudo systemctl enable nohang
|
$ sudo systemctl enable nohang
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Command line options
|
||||||
|
|
||||||
|
```
|
||||||
|
./nohang -h
|
||||||
|
usage: nohang [-h] [-c CONFIG]
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-c CONFIG, --config CONFIG
|
||||||
|
path to the config file, default values:
|
||||||
|
./nohang.conf, /etc/nohang/nohang.conf
|
||||||
|
```
|
||||||
|
|
||||||
## How to configure nohang
|
## How to configure nohang
|
||||||
|
|
||||||
The program can be configured by editing the [config file](https://github.com/hakavlad/nohang/blob/master/nohang.conf). The configuration includes the following sections:
|
The program can be configured by editing the [config file](https://github.com/hakavlad/nohang/blob/master/nohang.conf). The configuration includes the following sections:
|
||||||
@ -205,13 +218,13 @@ Please create [issues](https://github.com/hakavlad/nohang/issues). Use cases, fe
|
|||||||
- [x] Handle all timeouts when notify-send starts
|
- [x] Handle all timeouts when notify-send starts
|
||||||
- [x] Fix conf parsing: use of `line.partition('=')` instead of `line.split('=')`
|
- [x] Fix conf parsing: use of `line.partition('=')` instead of `line.split('=')`
|
||||||
- [x] Add `oom-sort`
|
- [x] Add `oom-sort`
|
||||||
- [x] Reduce memory usage (remove `import argparse`)
|
- [x] Reduce memory usage and startup time (using `sys.argv` instead of `argparse`)
|
||||||
- [x] Remove CLI options (need to add it again via `sys.argv`)
|
- [x] Remove CLI options (need to add it again via `sys.argv`)
|
||||||
- [x] Remove self-defense options from config, use systemd unit scheduling instead
|
- [x] Remove self-defense options from config, use systemd unit scheduling instead
|
||||||
- [x] Add the ability to send any signal instead of SIGTERM for processes with certain names
|
- [x] Add the ability to send any signal instead of SIGTERM for processes with certain names
|
||||||
- [x] Handle `UnicodeDecodeError` if victim name consists of many unicode characters
|
- [x] Handle `UnicodeDecodeError` if victim name consists of many unicode characters
|
||||||
- [x] Fix `mlockall()` using `MCL_ONFAULT` and lock all memory by default
|
- [x] Fix `mlockall()` using `MCL_ONFAULT` and lock all memory by default
|
||||||
- [ ] Add `PSI` support (using `/proc/pressure/memory`, need Linux 4.20+)
|
- [x] Add initial support for `PSI` (using `/proc/pressure/memory`, need Linux 4.20+)
|
||||||
- [ ] Redesign of the config
|
- [ ] Redesign of the config
|
||||||
- [ ] Decrease CPU usage: ignore `zram` by default
|
- [ ] Decrease CPU usage: ignore `zram` by default
|
||||||
- [ ] Improve user input validation
|
- [ ] Improve user input validation
|
||||||
@ -221,5 +234,4 @@ Please create [issues](https://github.com/hakavlad/nohang/issues). Use cases, fe
|
|||||||
- [x] Fix: replace `re.fullmatch()` by `re.search()`
|
- [x] Fix: replace `re.fullmatch()` by `re.search()`
|
||||||
- [ ] Validation RE patterns at startup
|
- [ ] Validation RE patterns at startup
|
||||||
|
|
||||||
- [v0.1](https://github.com/hakavlad/nohang/releases/tag/v0.1), 2018-11-23
|
- [v0.1](https://github.com/hakavlad/nohang/releases/tag/v0.1), 2018-11-23: Initial release
|
||||||
- 1st release
|
|
||||||
|
211
nohang
211
nohang
@ -4,9 +4,48 @@ import os
|
|||||||
from ctypes import CDLL
|
from ctypes import CDLL
|
||||||
from time import sleep, time
|
from time import sleep, time
|
||||||
from operator import itemgetter
|
from operator import itemgetter
|
||||||
from sys import stdout
|
from sys import stdout, stderr, argv, exit
|
||||||
from signal import SIGKILL, SIGTERM
|
from signal import SIGKILL, SIGTERM
|
||||||
|
|
||||||
|
|
||||||
|
help_mess = """usage: nohang [-h] [-c CONFIG]
|
||||||
|
|
||||||
|
optional arguments:
|
||||||
|
-h, --help show this help message and exit
|
||||||
|
-c CONFIG, --config CONFIG
|
||||||
|
path to the config file, default values:
|
||||||
|
./nohang.conf, /etc/nohang/nohang.conf"""
|
||||||
|
|
||||||
|
|
||||||
|
if len(argv) == 1:
|
||||||
|
if os.path.exists('./nohang.conf'):
|
||||||
|
config = cd = os.getcwd() + '/nohang.conf'
|
||||||
|
else:
|
||||||
|
config = '/etc/nohang/nohang.conf'
|
||||||
|
|
||||||
|
elif len(argv) == 2:
|
||||||
|
if argv[1] == '--help' or argv[1] == '-h':
|
||||||
|
print(help_mess)
|
||||||
|
exit(1)
|
||||||
|
else:
|
||||||
|
print('Invalid CLI input')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
elif len(argv) > 3:
|
||||||
|
print('Invalid CLI input')
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
else:
|
||||||
|
if argv[1] == '--config' or argv[1] == '-c':
|
||||||
|
config = argv[2]
|
||||||
|
else:
|
||||||
|
print('Invalid option: {}'.format(argv[1]))
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
conf_err_mess = 'Invalid config. Exit.'
|
||||||
|
|
||||||
|
|
||||||
start_time = time()
|
start_time = time()
|
||||||
|
|
||||||
sig_dict = {SIGKILL: 'SIGKILL',
|
sig_dict = {SIGKILL: 'SIGKILL',
|
||||||
@ -40,6 +79,7 @@ HR = '~' * 79
|
|||||||
# todo: make config option
|
# todo: make config option
|
||||||
print_total_stat = True
|
print_total_stat = True
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
# define functions
|
# define functions
|
||||||
@ -194,7 +234,7 @@ def conf_parse_string(param):
|
|||||||
else:
|
else:
|
||||||
print('All the necessary parameters must be in the config')
|
print('All the necessary parameters must be in the config')
|
||||||
print('There is no "{}" parameter in the config'.format(param))
|
print('There is no "{}" parameter in the config'.format(param))
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def conf_parse_bool(param):
|
def conf_parse_bool(param):
|
||||||
@ -211,14 +251,14 @@ def conf_parse_bool(param):
|
|||||||
elif param_str == 'False':
|
elif param_str == 'False':
|
||||||
return False
|
return False
|
||||||
else:
|
else:
|
||||||
print('Invalid value of the "{}" parameter.'.format(param_str))
|
print('Invalid value of the "{}" parameter.'.format(param))
|
||||||
print('Valid values are True and False.')
|
print('Valid values are True and False.')
|
||||||
print('Exit')
|
print('Exit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('All the necessary parameters must be in the config')
|
print('All the necessary parameters must be in the config')
|
||||||
print('There is no "{}" parameter in the config'.format(param_str))
|
print('There is no "{}" parameter in the config'.format(param))
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def rline1(path):
|
def rline1(path):
|
||||||
@ -325,6 +365,9 @@ def pid_to_uid(pid):
|
|||||||
return f_list[uid_index].split('\t')[2]
|
return f_list[uid_index].split('\t')[2]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def notify_send_wait(title, body):
|
def notify_send_wait(title, body):
|
||||||
'''GUI notifications with UID != 0'''
|
'''GUI notifications with UID != 0'''
|
||||||
with Popen(['notify-send', '--icon=dialog-warning', title, body]) as proc:
|
with Popen(['notify-send', '--icon=dialog-warning', title, body]) as proc:
|
||||||
@ -338,8 +381,6 @@ def notify_send_wait(title, body):
|
|||||||
def notify_helper(title, body):
|
def notify_helper(title, body):
|
||||||
'''GUI notification with UID = 0'''
|
'''GUI notification with UID = 0'''
|
||||||
|
|
||||||
# os.system(notify_helper_path + ' foo bar &')
|
|
||||||
|
|
||||||
with Popen([notify_helper_path, title, body]) as proc:
|
with Popen([notify_helper_path, title, body]) as proc:
|
||||||
try:
|
try:
|
||||||
proc.wait(timeout=wait_time)
|
proc.wait(timeout=wait_time)
|
||||||
@ -350,12 +391,16 @@ def notify_helper(title, body):
|
|||||||
title, body))
|
title, body))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def send_notify_warn():
|
def send_notify_warn():
|
||||||
"""
|
"""
|
||||||
Look for process with maximum 'badness' and warn user with notification.
|
Look for process with maximum 'badness' and warn user with notification.
|
||||||
(implement Low memory warnings)
|
(implement Low memory warnings)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
'''
|
||||||
# find process with max badness
|
# find process with max badness
|
||||||
fat_tuple = fattest()
|
fat_tuple = fattest()
|
||||||
pid = fat_tuple[0]
|
pid = fat_tuple[0]
|
||||||
@ -376,7 +421,14 @@ def send_notify_warn():
|
|||||||
|
|
||||||
# title = 'Low memory: {}'.format(low_mem_percent)
|
# title = 'Low memory: {}'.format(low_mem_percent)
|
||||||
title = 'Low memory'
|
title = 'Low memory'
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
body = 'Next victim: {}[{}]'.format(
|
body = 'Next victim: {}[{}]'.format(
|
||||||
name.replace(
|
name.replace(
|
||||||
# symbol '&' can break notifications in some themes,
|
# symbol '&' can break notifications in some themes,
|
||||||
@ -384,6 +436,13 @@ def send_notify_warn():
|
|||||||
'&', '*'),
|
'&', '*'),
|
||||||
pid
|
pid
|
||||||
)
|
)
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
'''
|
||||||
|
body = 'MemAvail: {}%\nSwapFree: {}%'.format(
|
||||||
|
round(mem_available / mem_total * 100),
|
||||||
|
round(swap_free / (swap_total + 0.1) * 100))
|
||||||
|
|
||||||
if root: # If nohang was started by root
|
if root: # If nohang was started by root
|
||||||
# send notification to all active users with special script
|
# send notification to all active users with special script
|
||||||
@ -391,6 +450,22 @@ def send_notify_warn():
|
|||||||
else: # Or by regular user
|
else: # Or by regular user
|
||||||
# send notification to user that runs this nohang
|
# send notification to user that runs this nohang
|
||||||
notify_send_wait(title, body)
|
notify_send_wait(title, body)
|
||||||
|
'''
|
||||||
|
|
||||||
|
|
||||||
|
b = """{} 'Low memory' 'MemAvail: {}%\nSwapFree: {}%' &""".format(
|
||||||
|
notify_helper_path,
|
||||||
|
round(mem_available / mem_total * 100),
|
||||||
|
round(swap_free / (swap_total + 0.1) * 100)
|
||||||
|
)
|
||||||
|
|
||||||
|
t0 = time()
|
||||||
|
os.system(b)
|
||||||
|
t1 = time()
|
||||||
|
print('t:', t1 - t0)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def send_notify(signal, name, pid):
|
def send_notify(signal, name, pid):
|
||||||
@ -402,13 +477,14 @@ def send_notify(signal, name, pid):
|
|||||||
pid: str process pid
|
pid: str process pid
|
||||||
"""
|
"""
|
||||||
title = 'Freeze prevention'
|
title = 'Freeze prevention'
|
||||||
body = '{} {}[{}]'.format(
|
body = '<b>{}</b> [{}] <b>{}</b>'.format(
|
||||||
notify_sig_dict[signal],
|
notify_sig_dict[signal],
|
||||||
|
pid,
|
||||||
name.replace(
|
name.replace(
|
||||||
# symbol '&' can break notifications in some themes,
|
# symbol '&' can break notifications in some themes,
|
||||||
# therefore it is replaced by '*'
|
# therefore it is replaced by '*'
|
||||||
'&', '*'),
|
'&', '*'
|
||||||
pid
|
)
|
||||||
)
|
)
|
||||||
if root:
|
if root:
|
||||||
# send notification to all active users with notify-send
|
# send notification to all active users with notify-send
|
||||||
@ -899,7 +975,7 @@ def sleep_after_check_mem():
|
|||||||
stdout.flush()
|
stdout.flush()
|
||||||
sleep(t)
|
sleep(t)
|
||||||
except KeyboardInterrupt:
|
except KeyboardInterrupt:
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
def calculate_percent(arg_key):
|
def calculate_percent(arg_key):
|
||||||
@ -922,12 +998,12 @@ def calculate_percent(arg_key):
|
|||||||
mem_min_percent = string_to_float_convert_test(mem_min_percent)
|
mem_min_percent = string_to_float_convert_test(mem_min_percent)
|
||||||
if mem_min_percent is None:
|
if mem_min_percent is None:
|
||||||
print('Invalid {} value, not float\nExit'.format(arg_key))
|
print('Invalid {} value, not float\nExit'.format(arg_key))
|
||||||
exit()
|
exit(1)
|
||||||
# Final validations...
|
# Final validations...
|
||||||
if mem_min_percent < 0 or mem_min_percent > 100:
|
if mem_min_percent < 0 or mem_min_percent > 100:
|
||||||
print(
|
print(
|
||||||
'{}, as percents value, out of range [0; 100]\nExit'.format(arg_key))
|
'{}, as percents value, out of range [0; 100]\nExit'.format(arg_key))
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
# mem_min_sigterm_percent is clean and valid float percentage. Can
|
# mem_min_sigterm_percent is clean and valid float percentage. Can
|
||||||
# translate into Kb
|
# translate into Kb
|
||||||
@ -938,14 +1014,14 @@ def calculate_percent(arg_key):
|
|||||||
mem_min_mb = string_to_float_convert_test(mem_min[:-1].strip())
|
mem_min_mb = string_to_float_convert_test(mem_min[:-1].strip())
|
||||||
if mem_min_mb is None:
|
if mem_min_mb is None:
|
||||||
print('Invalid {} value, not float\nExit'.format(arg_key))
|
print('Invalid {} value, not float\nExit'.format(arg_key))
|
||||||
exit()
|
exit(1)
|
||||||
mem_min_kb = mem_min_mb * 1024
|
mem_min_kb = mem_min_mb * 1024
|
||||||
if mem_min_kb > mem_total:
|
if mem_min_kb > mem_total:
|
||||||
print(
|
print(
|
||||||
'{} value can not be greater then MemTotal ({} MiB)\nExit'.format(
|
'{} value can not be greater then MemTotal ({} MiB)\nExit'.format(
|
||||||
arg_key, round(
|
arg_key, round(
|
||||||
mem_total / 1024)))
|
mem_total / 1024)))
|
||||||
exit()
|
exit(1)
|
||||||
mem_min_percent = mem_min_kb / mem_total * 100
|
mem_min_percent = mem_min_kb / mem_total * 100
|
||||||
|
|
||||||
else:
|
else:
|
||||||
@ -982,7 +1058,7 @@ for s in mem_list:
|
|||||||
|
|
||||||
if mem_list_names[2] != 'MemAvailable':
|
if mem_list_names[2] != 'MemAvailable':
|
||||||
print('Your Linux kernel is too old, Linux 3.14+ requied\nExit')
|
print('Your Linux kernel is too old, Linux 3.14+ requied\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
swap_total_index = mem_list_names.index('SwapTotal')
|
swap_total_index = mem_list_names.index('SwapTotal')
|
||||||
swap_free_index = swap_total_index + 1
|
swap_free_index = swap_total_index + 1
|
||||||
@ -1003,6 +1079,8 @@ vm_size_index = status_names.index('VmSize')
|
|||||||
vm_rss_index = status_names.index('VmRSS')
|
vm_rss_index = status_names.index('VmRSS')
|
||||||
vm_swap_index = status_names.index('VmSwap')
|
vm_swap_index = status_names.index('VmSwap')
|
||||||
uid_index = status_names.index('Uid')
|
uid_index = status_names.index('Uid')
|
||||||
|
state_index = status_names.index('State')
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
anon_index = status_names.index('RssAnon')
|
anon_index = status_names.index('RssAnon')
|
||||||
@ -1023,7 +1101,7 @@ cd = os.getcwd()
|
|||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
config = '/etc/nohang/nohang.conf'
|
#config = '/etc/nohang/nohang.conf'
|
||||||
|
|
||||||
# config = 'nohang.conf'
|
# config = 'nohang.conf'
|
||||||
|
|
||||||
@ -1075,7 +1153,7 @@ try:
|
|||||||
if len(etc_name) > 15:
|
if len(etc_name) > 15:
|
||||||
print('Invalid config, the length of the process '
|
print('Invalid config, the length of the process '
|
||||||
'name must not exceed 15 characters\nExit')
|
'name must not exceed 15 characters\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
etc_dict[etc_name] = etc_command
|
etc_dict[etc_name] = etc_command
|
||||||
|
|
||||||
# NEED VALIDATION!
|
# NEED VALIDATION!
|
||||||
@ -1095,16 +1173,21 @@ try:
|
|||||||
|
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
print('PermissionError', conf_err_mess)
|
print('PermissionError', conf_err_mess)
|
||||||
exit()
|
exit(1)
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
print('UnicodeDecodeError', conf_err_mess)
|
print('UnicodeDecodeError', conf_err_mess)
|
||||||
exit()
|
exit(1)
|
||||||
except IsADirectoryError:
|
except IsADirectoryError:
|
||||||
print('IsADirectoryError', conf_err_mess)
|
print('IsADirectoryError', conf_err_mess)
|
||||||
exit()
|
exit(1)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
print('IndexError', conf_err_mess)
|
print('IndexError', conf_err_mess)
|
||||||
exit()
|
exit(1)
|
||||||
|
except FileNotFoundError:
|
||||||
|
print('FileNotFoundError', conf_err_mess)
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# print(processname_re_list)
|
# print(processname_re_list)
|
||||||
# print(cmdline_re_list)
|
# print(cmdline_re_list)
|
||||||
@ -1158,53 +1241,53 @@ if 'rate_mem' in config_dict:
|
|||||||
rate_mem = string_to_float_convert_test(config_dict['rate_mem'])
|
rate_mem = string_to_float_convert_test(config_dict['rate_mem'])
|
||||||
if rate_mem is None:
|
if rate_mem is None:
|
||||||
print('Invalid rate_mem value, not float\nExit')
|
print('Invalid rate_mem value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if rate_mem <= 0:
|
if rate_mem <= 0:
|
||||||
print('rate_mem MUST be > 0\nExit')
|
print('rate_mem MUST be > 0\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('rate_mem not in config\nExit')
|
print('rate_mem not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'rate_swap' in config_dict:
|
if 'rate_swap' in config_dict:
|
||||||
rate_swap = string_to_float_convert_test(config_dict['rate_swap'])
|
rate_swap = string_to_float_convert_test(config_dict['rate_swap'])
|
||||||
if rate_swap is None:
|
if rate_swap is None:
|
||||||
print('Invalid rate_swap value, not float\nExit')
|
print('Invalid rate_swap value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if rate_swap <= 0:
|
if rate_swap <= 0:
|
||||||
print('rate_swap MUST be > 0\nExit')
|
print('rate_swap MUST be > 0\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('rate_swap not in config\nExit')
|
print('rate_swap not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'rate_zram' in config_dict:
|
if 'rate_zram' in config_dict:
|
||||||
rate_zram = string_to_float_convert_test(config_dict['rate_zram'])
|
rate_zram = string_to_float_convert_test(config_dict['rate_zram'])
|
||||||
if rate_zram is None:
|
if rate_zram is None:
|
||||||
print('Invalid rate_zram value, not float\nExit')
|
print('Invalid rate_zram value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if rate_zram <= 0:
|
if rate_zram <= 0:
|
||||||
print('rate_zram MUST be > 0\nExit')
|
print('rate_zram MUST be > 0\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('rate_zram not in config\nExit')
|
print('rate_zram not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'swap_min_sigterm' in config_dict:
|
if 'swap_min_sigterm' in config_dict:
|
||||||
swap_min_sigterm = config_dict['swap_min_sigterm']
|
swap_min_sigterm = config_dict['swap_min_sigterm']
|
||||||
else:
|
else:
|
||||||
print('swap_min_sigterm not in config\nExit')
|
print('swap_min_sigterm not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'swap_min_sigkill' in config_dict:
|
if 'swap_min_sigkill' in config_dict:
|
||||||
swap_min_sigkill = config_dict['swap_min_sigkill']
|
swap_min_sigkill = config_dict['swap_min_sigkill']
|
||||||
else:
|
else:
|
||||||
print('swap_min_sigkill not in config\nExit')
|
print('swap_min_sigkill not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'min_delay_after_sigterm' in config_dict:
|
if 'min_delay_after_sigterm' in config_dict:
|
||||||
@ -1212,13 +1295,13 @@ if 'min_delay_after_sigterm' in config_dict:
|
|||||||
config_dict['min_delay_after_sigterm'])
|
config_dict['min_delay_after_sigterm'])
|
||||||
if min_delay_after_sigterm is None:
|
if min_delay_after_sigterm is None:
|
||||||
print('Invalid min_delay_after_sigterm value, not float\nExit')
|
print('Invalid min_delay_after_sigterm value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if min_delay_after_sigterm < 0:
|
if min_delay_after_sigterm < 0:
|
||||||
print('min_delay_after_sigterm must be positiv\nExit')
|
print('min_delay_after_sigterm must be positiv\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('min_delay_after_sigterm not in config\nExit')
|
print('min_delay_after_sigterm not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'min_delay_after_sigkill' in config_dict:
|
if 'min_delay_after_sigkill' in config_dict:
|
||||||
@ -1226,13 +1309,13 @@ if 'min_delay_after_sigkill' in config_dict:
|
|||||||
config_dict['min_delay_after_sigkill'])
|
config_dict['min_delay_after_sigkill'])
|
||||||
if min_delay_after_sigkill is None:
|
if min_delay_after_sigkill is None:
|
||||||
print('Invalid min_delay_after_sigkill value, not float\nExit')
|
print('Invalid min_delay_after_sigkill value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if min_delay_after_sigkill < 0:
|
if min_delay_after_sigkill < 0:
|
||||||
print('min_delay_after_sigkill must be positive\nExit')
|
print('min_delay_after_sigkill must be positive\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('min_delay_after_sigkill not in config\nExit')
|
print('min_delay_after_sigkill not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'psi_avg10_sleep_time' in config_dict:
|
if 'psi_avg10_sleep_time' in config_dict:
|
||||||
@ -1240,13 +1323,13 @@ if 'psi_avg10_sleep_time' in config_dict:
|
|||||||
config_dict['psi_avg10_sleep_time'])
|
config_dict['psi_avg10_sleep_time'])
|
||||||
if psi_avg10_sleep_time is None:
|
if psi_avg10_sleep_time is None:
|
||||||
print('Invalid psi_avg10_sleep_time value, not float\nExit')
|
print('Invalid psi_avg10_sleep_time value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if psi_avg10_sleep_time < 0:
|
if psi_avg10_sleep_time < 0:
|
||||||
print('psi_avg10_sleep_time must be positive\nExit')
|
print('psi_avg10_sleep_time must be positive\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('psi_avg10_sleep_time not in config\nExit')
|
print('psi_avg10_sleep_time not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'sigkill_psi_avg10' in config_dict:
|
if 'sigkill_psi_avg10' in config_dict:
|
||||||
@ -1254,13 +1337,13 @@ if 'sigkill_psi_avg10' in config_dict:
|
|||||||
config_dict['sigkill_psi_avg10'])
|
config_dict['sigkill_psi_avg10'])
|
||||||
if sigkill_psi_avg10 is None:
|
if sigkill_psi_avg10 is None:
|
||||||
print('Invalid sigkill_psi_avg10 value, not float\nExit')
|
print('Invalid sigkill_psi_avg10 value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if sigkill_psi_avg10 < 0 or sigkill_psi_avg10 > 100:
|
if sigkill_psi_avg10 < 0 or sigkill_psi_avg10 > 100:
|
||||||
print('sigkill_psi_avg10 must be in the range [0; 100]\nExit')
|
print('sigkill_psi_avg10 must be in the range [0; 100]\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('sigkill_psi_avg10 not in config\nExit')
|
print('sigkill_psi_avg10 not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'sigterm_psi_avg10' in config_dict:
|
if 'sigterm_psi_avg10' in config_dict:
|
||||||
@ -1268,13 +1351,13 @@ if 'sigterm_psi_avg10' in config_dict:
|
|||||||
config_dict['sigterm_psi_avg10'])
|
config_dict['sigterm_psi_avg10'])
|
||||||
if sigterm_psi_avg10 is None:
|
if sigterm_psi_avg10 is None:
|
||||||
print('Invalid sigterm_psi_avg10 value, not float\nExit')
|
print('Invalid sigterm_psi_avg10 value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if sigterm_psi_avg10 < 0 or sigterm_psi_avg10 > 100:
|
if sigterm_psi_avg10 < 0 or sigterm_psi_avg10 > 100:
|
||||||
print('sigterm_psi_avg10 must be in the range [0; 100]\nExit')
|
print('sigterm_psi_avg10 must be in the range [0; 100]\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('sigterm_psi_avg10 not in config\nExit')
|
print('sigterm_psi_avg10 not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'min_badness' in config_dict:
|
if 'min_badness' in config_dict:
|
||||||
@ -1282,13 +1365,13 @@ if 'min_badness' in config_dict:
|
|||||||
config_dict['min_badness'])
|
config_dict['min_badness'])
|
||||||
if min_badness is None:
|
if min_badness is None:
|
||||||
print('Invalid min_badness value, not integer\nExit')
|
print('Invalid min_badness value, not integer\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if min_badness < 0 or min_badness > 1000:
|
if min_badness < 0 or min_badness > 1000:
|
||||||
print('Invalud min_badness value\nExit')
|
print('Invalud min_badness value\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('min_badness not in config\nExit')
|
print('min_badness not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'oom_score_adj_max' in config_dict:
|
if 'oom_score_adj_max' in config_dict:
|
||||||
@ -1296,13 +1379,13 @@ if 'oom_score_adj_max' in config_dict:
|
|||||||
config_dict['oom_score_adj_max'])
|
config_dict['oom_score_adj_max'])
|
||||||
if oom_score_adj_max is None:
|
if oom_score_adj_max is None:
|
||||||
print('Invalid oom_score_adj_max value, not integer\nExit')
|
print('Invalid oom_score_adj_max value, not integer\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if oom_score_adj_max < 0 or oom_score_adj_max > 1000:
|
if oom_score_adj_max < 0 or oom_score_adj_max > 1000:
|
||||||
print('Invalid oom_score_adj_max value\nExit')
|
print('Invalid oom_score_adj_max value\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('oom_score_adj_max not in config\nExit')
|
print('oom_score_adj_max not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'min_time_between_warnings' in config_dict:
|
if 'min_time_between_warnings' in config_dict:
|
||||||
@ -1310,20 +1393,20 @@ if 'min_time_between_warnings' in config_dict:
|
|||||||
config_dict['min_time_between_warnings'])
|
config_dict['min_time_between_warnings'])
|
||||||
if min_time_between_warnings is None:
|
if min_time_between_warnings is None:
|
||||||
print('Invalid min_time_between_warnings value, not float\nExit')
|
print('Invalid min_time_between_warnings value, not float\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
if min_time_between_warnings < 1 or min_time_between_warnings > 300:
|
if min_time_between_warnings < 1 or min_time_between_warnings > 300:
|
||||||
print('min_time_between_warnings value out of range [1; 300]\nExit')
|
print('min_time_between_warnings value out of range [1; 300]\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
else:
|
else:
|
||||||
print('min_time_between_warnings not in config\nExit')
|
print('min_time_between_warnings not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
if 'swap_min_warnings' in config_dict:
|
if 'swap_min_warnings' in config_dict:
|
||||||
swap_min_warnings = config_dict['swap_min_warnings']
|
swap_min_warnings = config_dict['swap_min_warnings']
|
||||||
else:
|
else:
|
||||||
print('swap_min_warnings not in config\nExit')
|
print('swap_min_warnings not in config\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@ -1344,12 +1427,12 @@ def get_swap_threshold_tuple(string):
|
|||||||
valid = string_to_float_convert_test(string[:-1])
|
valid = string_to_float_convert_test(string[:-1])
|
||||||
if valid is None:
|
if valid is None:
|
||||||
print('somewhere swap unit is not float_%')
|
print('somewhere swap unit is not float_%')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
value = float(string[:-1].strip())
|
value = float(string[:-1].strip())
|
||||||
if value < 0 or value > 100:
|
if value < 0 or value > 100:
|
||||||
print('invalid value, must be from the range[0; 100] %')
|
print('invalid value, must be from the range[0; 100] %')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
return value, True
|
return value, True
|
||||||
|
|
||||||
@ -1357,18 +1440,18 @@ def get_swap_threshold_tuple(string):
|
|||||||
valid = string_to_float_convert_test(string[:-1])
|
valid = string_to_float_convert_test(string[:-1])
|
||||||
if valid is None:
|
if valid is None:
|
||||||
print('somewhere swap unit is not float_M')
|
print('somewhere swap unit is not float_M')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
value = float(string[:-1].strip()) * 1024
|
value = float(string[:-1].strip()) * 1024
|
||||||
if value < 0:
|
if value < 0:
|
||||||
print('invalid unit in config (negative value)')
|
print('invalid unit in config (negative value)')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
return value, False
|
return value, False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print('Invalid config file. There are invalid units somewhere\nExit')
|
print('Invalid config file. There are invalid units somewhere\nExit')
|
||||||
exit()
|
exit(1)
|
||||||
|
|
||||||
|
|
||||||
swap_min_sigterm_tuple = get_swap_threshold_tuple(swap_min_sigterm)
|
swap_min_sigterm_tuple = get_swap_threshold_tuple(swap_min_sigterm)
|
||||||
|
@ -4,7 +4,7 @@ After=sysinit.target
|
|||||||
Documentation=man:nohang(1) https://github.com/hakavlad/nohang
|
Documentation=man:nohang(1) https://github.com/hakavlad/nohang
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
ExecStart=/usr/sbin/nohang
|
ExecStart=/usr/sbin/nohang --config /etc/nohang/nohang.conf
|
||||||
Slice=nohang.slice
|
Slice=nohang.slice
|
||||||
Restart=always
|
Restart=always
|
||||||
ProtectSystem=strict
|
ProtectSystem=strict
|
||||||
|
Loading…
Reference in New Issue
Block a user