[PATCH] Fix unloading modules in driver-updates (#1085099)
Will Woods
wwoods at redhat.com
Mon Apr 21 14:31:31 UTC 2014
An unintended consequence of commit de2d663 is that driver-updates won't
unload *any* modules at all: /tmp/dd_modules (the list of "early"
modules that shouldn't be removed) is now created *after* we load all
modules.)
This patch makes driver-updates attempt to remove any driver that's in
the update disk(s) it loads.
First we make dd_extract() return a list of the firmware/module files
that were in the driver disk it extracted.
Next process_dd() builds a list of those for each extracted driver and
passes that to reload_modules().
reload_modules() maps those filenames to module names, and adds them to
the list of modules to be unloaded.
NOTE: Probably the correct behavior (and the way it worked in RHEL6)
would be to revert the change to /tmp/dd_modules and fix that bug in a
different way (e.g. by tracking driver disks by UUID instead of device
name, so they don't get loaded twice if the device name changes).
That requires a bunch of refactoring work; this is a stopgap solution.
---
dracut/driver-updates | 25 +++++++++++++++++++++----
1 file changed, 21 insertions(+), 4 deletions(-)
diff --git a/dracut/driver-updates b/dracut/driver-updates
index 5eb4cdc..373884f 100755
--- a/dracut/driver-updates
+++ b/dracut/driver-updates
@@ -252,8 +252,10 @@ def get_module_set(fname):
modules.update([mod_args[0]])
return modules
+def to_modname(modfile):
+ return os.path.basename(modfile)[:-3].replace('-','_')
-def reload_modules():
+def reload_modules(newfiles):
""" Reload new module versions from /lib/modules/<kernel>/updates/
"""
try:
@@ -267,6 +269,12 @@ def reload_modules():
new_modules = current_modules.difference(startup_modules)
log.debug("new_modules = %s", " ".join(new_modules))
+ # And a list of modules contained in the disk we just extracted
+ dd_modules = set(to_modname(f) for f in newfiles if f.endswith(".ko"))
+ # TODO: what modules do we unload when there's new firmware?
+ log.debug("dd_modules = %s", " ".join(dd_modules))
+ new_modules.update(dd_modules)
+
# I think we can just iterate once using modprobe -r to remove unused deps
for module in new_modules:
try:
@@ -369,7 +377,7 @@ def dd_extract(driver, dest_path="/updates/", kernel_ver=None):
:type driver: Driver object
:param dest_path: Top directory of the destination path
:type dest_path: string
- :returns: None
+ :returns: list of paths to extracted firmware and modules
This extracts the driver's files into 'dest_path' (which defaults
to /updates/ so that the normal live updates handling will overlay
@@ -402,12 +410,15 @@ def dd_extract(driver, dest_path="/updates/", kernel_ver=None):
if not os.path.exists(d):
os.makedirs(d)
+ filelist = []
+
# Copy *.ko files over to /updates/lib/modules/<kernel>/updates/
for root, _dirs, files in os.walk(dest_path+"/lib/modules/"):
if root.endswith("/updates") and os.path.isdir(root):
continue
for f in (f for f in files if f.endswith(".ko")):
src = root+"/"+f
+ filelist.append(src)
copy_file(src, ko_updates)
move_file(src, initrd_updates)
@@ -417,9 +428,13 @@ def dd_extract(driver, dest_path="/updates/", kernel_ver=None):
continue
for f in (f for f in files):
src = root+"/"+f
+ filelist.append(src)
copy_file(src, firmware_updates)
move_file(src, initrd_firmware)
+ # Tell our caller about the newly-extracted stuff
+ return filelist
+
# an arbitrary value to signal refreshing the menu contents
DoRefresh = True
@@ -542,15 +557,17 @@ def process_dd(dd_path):
# Copy the repository for Anaconda to use during install
copy_repo(dd_path, "/updates/run/install/DD-")
+ extracted = []
+
for driver in filter(lambda d: d.selected, drivers):
- dd_extract(driver, "/updates/")
+ extracted += dd_extract(driver, "/updates/")
# Write the package names for all modules and firmware for Anaconda
if "modules" in driver.flags or "firmwares" in driver.flags:
with open("/run/install/dd_packages", "a") as f:
f.write("%s\n" % driver.name)
- reload_modules()
+ reload_modules(extracted)
def select_dd(device):
--
1.9.0
More information about the anaconda-patches
mailing list