Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce the checkmptctl actor #1141

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions repos/system_upgrade/el7toel8/actors/checkmptctl/actor.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
from leapp.actors import Actor
from leapp.libraries.actor.checkmptctl import check_mptctl
from leapp.models import ActiveKernelModulesFacts
from leapp.reporting import Report
from leapp.tags import ChecksPhaseTag, IPUWorkflowTag


class CheckMptctl(Actor):
"""
Check if a process uses the mptctl kernel module that will be removed.
It could prevent the unloading of this module which does not handle HW.
"""
name = "check_mptctl"
consumes = (ActiveKernelModulesFacts,)
produces = (Report,)
tags = (ChecksPhaseTag, IPUWorkflowTag,)

def process(self):
check_mptctl()
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
#!/usr/libexec/platform-python

from os import listdir, readlink
from os.path import islink
from leapp import reporting
from leapp.libraries.stdlib import api
from leapp.models import ActiveKernelModulesFacts

iodevs = ['/dev/mptctl', '/dev/mpt2ctl', '/dev/mpt3ctl']


def get_open_files():
"""
Mimics fuser to get the filenames corresponding to
open file descriptors for running processes
"""
open_files = {}
for pid in listdir('/proc'):
if not pid.isdigit():
continue
open_list = []
for fd in listdir('/proc/%s/fd' % pid):
fd_path = '/proc/%s/fd/%s' % (pid, fd)
if islink(fd_path):
open_list.append(readlink(fd_path))
if len(open_list):
open_files[pid] = open_list
return open_files


def get_process_info(pid):
""" Return the PID alongside the command line in use """
try:
with open('/proc/%s/cmdline' % pid, 'r') as f:
cmdline = f.read().split('\0')
return "%s: %s" % (pid, " ".join(cmdline))
except IOError: # in case the process is already dead
return


def get_mptctl_locks(open_files):
"""
Get the list of processes that prevent the unloading of the mptctl module
Note: monitoring tools from Dell and HP are known to use it.
"""
locks = []
for pid in open_files.keys():
if any(f in iodevs for f in open_files[pid]):
locks.append(pid)
return locks


def is_module_loaded(module):
"""
Determines if the given kernel module has been reported in the ActiveKernelModuleFacts as loaded.
:return: True if the module has been found in the ActiveKernelModuleFacts.
:rtype: bool
"""
for fact in api.consume(ActiveKernelModulesFacts):
for active_module in fact.kernel_modules:
if active_module.filename == module:
return True
return False


def check_mptctl():
""" Main actor process """
if not is_module_loaded("mptctl"):
return

mptctl_locks = get_mptctl_locks(get_open_files())

if not mptctl_locks:
return

processes = '\n'.join([get_process_info(pid) for pid in mptctl_locks])

summary = (
'Leapp detected that the following processes are using the mptctl '
'kernel module which will be removed in RHEL 8:\n{0}'
)

hint = (
'Stop this application or the service that runs this process.'
)

reporting.create_report([
reporting.Title(
'Detected processes that are using mptctl.'
),
reporting.Summary(summary.format(processes)),
reporting.Remediation(hint=hint.format(processes)),
reporting.Severity(reporting.Severity.HIGH),
reporting.Groups([reporting.Groups.KERNEL, reporting.Groups.DRIVERS]),
reporting.Groups([reporting.Groups.INHIBITOR]),
])

Loading