add cgroup_v2 support
This commit is contained in:
parent
b302a14214
commit
be80d1ca5b
125
nohang
125
nohang
@ -59,11 +59,24 @@ stat_dict = dict()
|
|||||||
separate_log = False # will be overwritten after parse config
|
separate_log = False # will be overwritten after parse config
|
||||||
|
|
||||||
|
|
||||||
with open('/proc/self/cgroup') as f:
|
def find_cgroup_indexes():
|
||||||
# Find cgroup-line position in /proc/*/cgroup file.
|
""" Find cgroup-line positions in /proc/*/cgroup file.
|
||||||
for cgroup_index, line in enumerate(f):
|
"""
|
||||||
|
|
||||||
|
cgroup_v1_index = None
|
||||||
|
cgroup_v2_index = None
|
||||||
|
|
||||||
|
with open('/proc/self/cgroup') as f:
|
||||||
|
for index, line in enumerate(f):
|
||||||
if ':name=' in line:
|
if ':name=' in line:
|
||||||
break
|
cgroup_v1_index = index
|
||||||
|
if line.startswith('0::'):
|
||||||
|
cgroup_v2_index = index
|
||||||
|
|
||||||
|
return cgroup_v1_index, cgroup_v2_index
|
||||||
|
|
||||||
|
|
||||||
|
cgroup_v1_index, cgroup_v2_index = find_cgroup_indexes()
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@ -227,14 +240,30 @@ def test():
|
|||||||
##########################################################################
|
##########################################################################
|
||||||
|
|
||||||
|
|
||||||
def pid_to_cgroup(pid):
|
def pid_to_cgroup_v1(pid):
|
||||||
"""
|
"""
|
||||||
"""
|
"""
|
||||||
|
cgroup_v1 = ''
|
||||||
try:
|
try:
|
||||||
with open('/proc/' + pid + '/cgroup') as f:
|
with open('/proc/' + pid + '/cgroup') as f:
|
||||||
for n, line in enumerate(f):
|
for index, line in enumerate(f):
|
||||||
if n == cgroup_index:
|
if index == cgroup_v1_index:
|
||||||
return '/' + line.partition('/')[2][:-1]
|
cgroup_v1 = '/' + line.partition('/')[2][:-1]
|
||||||
|
return cgroup_v1
|
||||||
|
except FileNotFoundError:
|
||||||
|
return ''
|
||||||
|
|
||||||
|
|
||||||
|
def pid_to_cgroup_v2(pid):
|
||||||
|
"""
|
||||||
|
"""
|
||||||
|
cgroup_v2 = ''
|
||||||
|
try:
|
||||||
|
with open('/proc/' + pid + '/cgroup') as f:
|
||||||
|
for index, line in enumerate(f):
|
||||||
|
if index == cgroup_v2_index:
|
||||||
|
cgroup_v2 = line[3:-1]
|
||||||
|
return cgroup_v2
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
@ -394,10 +423,16 @@ def pid_to_badness(pid):
|
|||||||
if search(re_tup[1], name) is not None:
|
if search(re_tup[1], name) is not None:
|
||||||
badness += int(re_tup[0])
|
badness += int(re_tup[0])
|
||||||
|
|
||||||
if re_match_cgroup:
|
if re_match_cgroup_v1:
|
||||||
cgroup = pid_to_cgroup(pid)
|
cgroup_v1 = pid_to_cgroup_v1(pid)
|
||||||
for re_tup in cgroup_re_list:
|
for re_tup in cgroup_v1_re_list:
|
||||||
if search(re_tup[1], cgroup) is not None:
|
if search(re_tup[1], cgroup_v1) is not None:
|
||||||
|
badness += int(re_tup[0])
|
||||||
|
|
||||||
|
if re_match_cgroup_v2:
|
||||||
|
cgroup_v2 = pid_to_cgroup_v2(pid)
|
||||||
|
for re_tup in cgroup_v2_re_list:
|
||||||
|
if search(re_tup[1], cgroup_v2) is not None:
|
||||||
badness += int(re_tup[0])
|
badness += int(re_tup[0])
|
||||||
|
|
||||||
if re_match_realpath:
|
if re_match_realpath:
|
||||||
@ -1017,8 +1052,11 @@ def find_victim(_print_proc_table):
|
|||||||
if extra_table_info == 'None':
|
if extra_table_info == 'None':
|
||||||
extra_table_title = ''
|
extra_table_title = ''
|
||||||
|
|
||||||
elif extra_table_info == 'cgroup':
|
elif extra_table_info == 'cgroup_v1':
|
||||||
extra_table_title = 'CGroup'
|
extra_table_title = 'CGroup_v1'
|
||||||
|
|
||||||
|
elif extra_table_info == 'cgroup_v2':
|
||||||
|
extra_table_title = 'CGroup_v2'
|
||||||
|
|
||||||
elif extra_table_info == 'cmdline':
|
elif extra_table_info == 'cmdline':
|
||||||
extra_table_title = 'cmdline'
|
extra_table_title = 'cmdline'
|
||||||
@ -1059,14 +1097,17 @@ def find_victim(_print_proc_table):
|
|||||||
if pid_to_status(pid) is None:
|
if pid_to_status(pid) is None:
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
name, state, ppid, uid, vm_size, vm_rss, vm_swap = pid_to_status(
|
(name, state, ppid, uid, vm_size, vm_rss,
|
||||||
pid)
|
vm_swap) = pid_to_status(pid)
|
||||||
|
|
||||||
if extra_table_info == 'None':
|
if extra_table_info == 'None':
|
||||||
extra_table_line = ''
|
extra_table_line = ''
|
||||||
|
|
||||||
elif extra_table_info == 'cgroup':
|
elif extra_table_info == 'cgroup_v1':
|
||||||
extra_table_line = pid_to_cgroup(pid)
|
extra_table_line = pid_to_cgroup_v1(pid)
|
||||||
|
|
||||||
|
elif extra_table_info == 'cgroup_v2':
|
||||||
|
extra_table_line = pid_to_cgroup_v2(pid)
|
||||||
|
|
||||||
elif extra_table_info == 'cmdline':
|
elif extra_table_info == 'cmdline':
|
||||||
extra_table_line = pid_to_cmdline(pid)
|
extra_table_line = pid_to_cmdline(pid)
|
||||||
@ -1187,7 +1228,6 @@ def find_victim_info(pid, victim_badness, name):
|
|||||||
break
|
break
|
||||||
|
|
||||||
cmdline = pid_to_cmdline(pid)
|
cmdline = pid_to_cmdline(pid)
|
||||||
environ = pid_to_environ(pid)
|
|
||||||
oom_score = rline1('/proc/' + pid + '/oom_score')
|
oom_score = rline1('/proc/' + pid + '/oom_score')
|
||||||
oom_score_adj = rline1('/proc/' + pid + '/oom_score_adj')
|
oom_score_adj = rline1('/proc/' + pid + '/oom_score_adj')
|
||||||
|
|
||||||
@ -1274,7 +1314,9 @@ def find_victim_info(pid, victim_badness, name):
|
|||||||
try:
|
try:
|
||||||
realpath = os.path.realpath('/proc/' + pid + '/exe')
|
realpath = os.path.realpath('/proc/' + pid + '/exe')
|
||||||
victim_lifetime = format_time(uptime() - pid_to_starttime(pid))
|
victim_lifetime = format_time(uptime() - pid_to_starttime(pid))
|
||||||
victim_cgroup = pid_to_cgroup(pid)
|
victim_cgroup_v1 = pid_to_cgroup_v1(pid)
|
||||||
|
victim_cgroup_v2 = pid_to_cgroup_v2(pid)
|
||||||
|
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
print('The victim died in the search process: FileNotFoundError')
|
print('The victim died in the search process: FileNotFoundError')
|
||||||
update_stat_dict_and_print(
|
update_stat_dict_and_print(
|
||||||
@ -1308,10 +1350,10 @@ def find_victim_info(pid, victim_badness, name):
|
|||||||
'\n VmSize: {} MiB' \
|
'\n VmSize: {} MiB' \
|
||||||
'\n VmRSS: {} MiB {}' \
|
'\n VmRSS: {} MiB {}' \
|
||||||
'\n VmSwap: {} MiB' \
|
'\n VmSwap: {} MiB' \
|
||||||
'\n CGroup: {}' \
|
'\n CGroup_v1: {}' \
|
||||||
|
'\n CGroup_v2: {}' \
|
||||||
'\n Realpath: {}' \
|
'\n Realpath: {}' \
|
||||||
'\n Cmdline: {}' \
|
'\n Cmdline: {}' \
|
||||||
'\n Environ: {}' \
|
|
||||||
'\n Lifetime: {}'.format(
|
'\n Lifetime: {}'.format(
|
||||||
round((time() - status0) * 1000),
|
round((time() - status0) * 1000),
|
||||||
name,
|
name,
|
||||||
@ -1326,10 +1368,10 @@ def find_victim_info(pid, victim_badness, name):
|
|||||||
str(vm_rss).rjust(len_vm),
|
str(vm_rss).rjust(len_vm),
|
||||||
detailed_rss_info,
|
detailed_rss_info,
|
||||||
str(vm_swap).rjust(len_vm),
|
str(vm_swap).rjust(len_vm),
|
||||||
victim_cgroup,
|
victim_cgroup_v1,
|
||||||
|
victim_cgroup_v2,
|
||||||
realpath,
|
realpath,
|
||||||
cmdline,
|
cmdline,
|
||||||
environ,
|
|
||||||
victim_lifetime)
|
victim_lifetime)
|
||||||
|
|
||||||
return victim_info
|
return victim_info
|
||||||
@ -1754,12 +1796,11 @@ config_dict = dict()
|
|||||||
processname_re_list = []
|
processname_re_list = []
|
||||||
cmdline_re_list = []
|
cmdline_re_list = []
|
||||||
environ_re_list = []
|
environ_re_list = []
|
||||||
|
|
||||||
uid_re_list = []
|
uid_re_list = []
|
||||||
cgroup_re_list = []
|
cgroup_v1_re_list = []
|
||||||
|
cgroup_v2_re_list = []
|
||||||
realpath_re_list = []
|
realpath_re_list = []
|
||||||
|
|
||||||
|
|
||||||
# dictionary with names and commands for the parameter
|
# dictionary with names and commands for the parameter
|
||||||
# execute_the_command
|
# execute_the_command
|
||||||
# тут тоже список нужен, а не словарь
|
# тут тоже список нужен, а не словарь
|
||||||
@ -1824,13 +1865,21 @@ try:
|
|||||||
valid_re(reg_exp)
|
valid_re(reg_exp)
|
||||||
uid_re_list.append((badness_adj, reg_exp))
|
uid_re_list.append((badness_adj, reg_exp))
|
||||||
|
|
||||||
if line.startswith('@CGROUP_RE'):
|
if line.startswith('@CGROUP_V1_RE'):
|
||||||
a = line.partition(
|
a = line.partition(
|
||||||
'@CGROUP_RE')[2].strip(' \n').partition('///')
|
'@CGROUP_V1_RE')[2].strip(' \n').partition('///')
|
||||||
badness_adj = a[0].strip(' ')
|
badness_adj = a[0].strip(' ')
|
||||||
reg_exp = a[2].strip(' ')
|
reg_exp = a[2].strip(' ')
|
||||||
valid_re(reg_exp)
|
valid_re(reg_exp)
|
||||||
cgroup_re_list.append((badness_adj, reg_exp))
|
cgroup_v1_re_list.append((badness_adj, reg_exp))
|
||||||
|
|
||||||
|
if line.startswith('@CGROUP_V2_RE'):
|
||||||
|
a = line.partition(
|
||||||
|
'@CGROUP_V2_RE')[2].strip(' \n').partition('///')
|
||||||
|
badness_adj = a[0].strip(' ')
|
||||||
|
reg_exp = a[2].strip(' ')
|
||||||
|
valid_re(reg_exp)
|
||||||
|
cgroup_v2_re_list.append((badness_adj, reg_exp))
|
||||||
|
|
||||||
if line.startswith('@REALPATH_RE'):
|
if line.startswith('@REALPATH_RE'):
|
||||||
a = line.partition(
|
a = line.partition(
|
||||||
@ -1871,6 +1920,8 @@ except FileNotFoundError:
|
|||||||
# print(uid_re_list)
|
# print(uid_re_list)
|
||||||
# print(environ_re_list)
|
# print(environ_re_list)
|
||||||
# print(realpath_re_list)
|
# print(realpath_re_list)
|
||||||
|
# print(cgroup_v1_re_list)
|
||||||
|
# print(cgroup_v2_re_list)
|
||||||
|
|
||||||
|
|
||||||
##########################################################################
|
##########################################################################
|
||||||
@ -1895,7 +1946,8 @@ ignore_psi = conf_parse_bool('ignore_psi')
|
|||||||
regex_matching = conf_parse_bool('regex_matching')
|
regex_matching = conf_parse_bool('regex_matching')
|
||||||
re_match_cmdline = conf_parse_bool('re_match_cmdline')
|
re_match_cmdline = conf_parse_bool('re_match_cmdline')
|
||||||
re_match_uid = conf_parse_bool('re_match_uid')
|
re_match_uid = conf_parse_bool('re_match_uid')
|
||||||
re_match_cgroup = conf_parse_bool('re_match_cgroup')
|
re_match_cgroup_v1 = conf_parse_bool('re_match_cgroup_v1')
|
||||||
|
re_match_cgroup_v2 = conf_parse_bool('re_match_cgroup_v2')
|
||||||
re_match_realpath = conf_parse_bool('re_match_realpath')
|
re_match_realpath = conf_parse_bool('re_match_realpath')
|
||||||
re_match_environ = conf_parse_bool('re_match_environ')
|
re_match_environ = conf_parse_bool('re_match_environ')
|
||||||
|
|
||||||
@ -2160,9 +2212,14 @@ else:
|
|||||||
|
|
||||||
if 'extra_table_info' in config_dict:
|
if 'extra_table_info' in config_dict:
|
||||||
extra_table_info = config_dict['extra_table_info']
|
extra_table_info = config_dict['extra_table_info']
|
||||||
if (extra_table_info != 'None' and extra_table_info != 'cgroup' and
|
if (extra_table_info != 'None' and
|
||||||
extra_table_info != 'cmdline' and extra_table_info != 'environ' and
|
extra_table_info != 'cgroup_v1' and
|
||||||
extra_table_info != 'realpath' and extra_table_info != 'All'):
|
extra_table_info != 'cgroup_v2' and
|
||||||
|
extra_table_info != 'cmdline' and
|
||||||
|
extra_table_info != 'environ' and
|
||||||
|
extra_table_info != 'realpath' and
|
||||||
|
extra_table_info != 'All'):
|
||||||
|
|
||||||
errprint('Invalid config: invalid extra_table_info value\nExit')
|
errprint('Invalid config: invalid extra_table_info value\nExit')
|
||||||
exit(1)
|
exit(1)
|
||||||
else:
|
else:
|
||||||
|
32
nohang.conf
32
nohang.conf
@ -188,51 +188,58 @@ regex_matching = False
|
|||||||
|
|
||||||
Example:
|
Example:
|
||||||
|
|
||||||
@PROCESSNAME_RE -100 /// ^Xorg$
|
@PROCESSNAME_RE -100 /// ^Xorg$
|
||||||
|
|
||||||
@PROCESSNAME_RE -500 /// ^sshd$
|
@PROCESSNAME_RE -500 /// ^sshd$
|
||||||
|
|
||||||
|
|
||||||
5.2 Matching cmdlines with RE patterns
|
5.2 Matching cmdlines with RE patterns
|
||||||
|
|
||||||
A good option that allows fine adjustment.
|
A good option that allows fine adjustment.
|
||||||
|
|
||||||
re_match_cmdline = False
|
re_match_cmdline = False
|
||||||
|
|
||||||
@CMDLINE_RE 300 /// -childID|--type=renderer
|
@CMDLINE_RE 300 /// -childID|--type=renderer
|
||||||
|
|
||||||
@CMDLINE_RE -200 /// ^/usr/lib/virtualbox
|
@CMDLINE_RE -200 /// ^/usr/lib/virtualbox
|
||||||
|
|
||||||
|
|
||||||
5.3 Matching UIDs with RE patterns
|
5.3 Matching UIDs with RE patterns
|
||||||
|
|
||||||
The most slow option
|
The most slow option
|
||||||
|
|
||||||
re_match_uid = False
|
re_match_uid = False
|
||||||
|
|
||||||
@UID_RE -100 /// ^0$
|
@UID_RE -100 /// ^0$
|
||||||
|
|
||||||
|
|
||||||
5.4 Matching CGroup-line with RE patterns
|
5.4 Matching CGroup-line with RE patterns
|
||||||
|
|
||||||
re_match_cgroup = False
|
re_match_cgroup_v1 = False
|
||||||
|
|
||||||
@CGROUP_RE -50 /// system.slice
|
@CGROUP_V1_RE -50 /// ^/system.slice
|
||||||
|
|
||||||
@CGROUP_RE 50 /// foo.service
|
@CGROUP_V1_RE 50 /// foo.service
|
||||||
|
|
||||||
|
@CGROUP_V1_RE -50 /// ^/user.slice
|
||||||
|
|
||||||
|
re_match_cgroup_v2 = False
|
||||||
|
|
||||||
|
@CGROUP_V2_RE 100 /// ^/workload
|
||||||
|
|
||||||
@CGROUP_RE -50 /// user.slice
|
|
||||||
|
|
||||||
5.5 Matching realpath with RE patterns
|
5.5 Matching realpath with RE patterns
|
||||||
|
|
||||||
re_match_realpath = False
|
re_match_realpath = False
|
||||||
|
|
||||||
@REALPATH_RE 20 /// ^/usr/bin/foo
|
@REALPATH_RE 20 /// ^/usr/bin/foo
|
||||||
|
|
||||||
|
|
||||||
5.6 Matching environ with RE patterns
|
5.6 Matching environ with RE patterns
|
||||||
|
|
||||||
re_match_environ = False
|
re_match_environ = False
|
||||||
|
|
||||||
@ENVIRON_RE 100 /// USER=user
|
@ENVIRON_RE 100 /// USER=user
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Note that you can control badness also via systemd units via OOMScoreAdjust, see
|
Note that you can control badness also via systemd units via OOMScoreAdjust, see
|
||||||
@ -352,13 +359,14 @@ print_proc_table = True
|
|||||||
|
|
||||||
Valid values:
|
Valid values:
|
||||||
None
|
None
|
||||||
cgroup
|
cgroup_v1
|
||||||
|
cgroup_v2
|
||||||
cmdline
|
cmdline
|
||||||
environ
|
environ
|
||||||
realpath
|
realpath
|
||||||
All
|
All
|
||||||
|
|
||||||
extra_table_info = cgroup
|
extra_table_info = cgroup_v1
|
||||||
|
|
||||||
print_victim_info = True
|
print_victim_info = True
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user