The Puppet Labs Issue Tracker has Moved: https://tickets.puppetlabs.com

Kernel Modules

Problem: managing Linux kernel modules

There is no resource to handle loading/unloading Linux kernel modules and also ensuring they are loaded automatically at boot.

Solution

I’ve taken part of Recipes/Simple Text for managing putting the module line in and out of /etc/modules and added exec statements load/unload module based on ensure.


define kern_module ($ensure) {
    $modulesfile = $operatingsystem ? { debian => "/etc/modules", redhat => "/etc/rc.modules" }
    case $operatingsystem {
        redhat: { file { "/etc/rc.modules": ensure => file, mode => 755 } }
    }
    case $ensure {
        present: {
            exec { "insert_module_${name}":
                command => $operatingsystem ? {
                    debian => "/bin/echo '${name}' >> '${modulesfile}'",
                    redhat => "/bin/echo '/sbin/modprobe ${name}' >> '${modulesfile}' "
                },
                unless => "/bin/grep -qFx '${name}' '${modulesfile}'"
            }
            exec { "/sbin/modprobe ${name}": unless => "/bin/grep -q '^${name} ' '/proc/modules'" }
        }
        absent: {
            exec { "/sbin/modprobe -r ${name}": onlyif => "/bin/grep -q '^${name} ' '/proc/modules'" }
            exec { "remove_module_${name}":
                command => $operatingsystem ? {
                    debian => "/usr/bin/perl -ni -e 'print unless /^\\Q${name}\\E\$/' '${modulesfile}'",
                    redhat => "/usr/bin/perl -ni -e 'print unless /^\\Q/sbin/modprobe ${name}\\E\$/' '${modulesfile}'"
                },
                onlyif => $operatingsystem ? {
                    debian => "/bin/grep -qFx '${name}' '${modulesfile}'",
                    redhat => "/bin/grep -q '^/sbin/modprobe ${name}' '${modulesfile}'"
                }
            }
        }
        default: { err ( "unknown ensure value ${ensure}" ) }
    }
}

Usage example: load ‘dummy’ module

kern_module { "dummy": ensure => present }

Usage example: unload ‘dummy’ module

kern_module { "dummy": ensure => absent }

Caveats

The only one I have noticed at this point is if you are removing a module and its still being used by another module, the exec statement will fail. If you are also controlling the the child module it will clean itself up in the next configuration run.

Discussion

Why not use /etc/modprobe.d as a more portable way to manage this, and then individual files can be used instead of trying to play line-editing? Also, what is /etc/modules, we have /etc/modprobe.conf on RHEL and CentOS. Is /etc/modules a Debian thing?

MrProper: /etc/modprobe.d is for setting module options and aliases not to trigger the module being loaded. redhat uses /etc/rc.modules as a script which gets executed before rc.local if present. i have updated the manifest to reflect this

Revised 21 May 2009

I’ve tweaked the script slightly to work on CentOS

define kern_module ($ensure) {
    $modulesfile = $operatingsystem ? { debian => "/etc/modules", redhat => "/etc/rc.modules", centos=>"/etc/rc.modules" }
    case $operatingsystem {
        redhat: { file { "/etc/rc.modules": ensure => file, mode => 755 } }
        centos: { file { "/etc/rc.modules": ensure => file, mode => 755 } }
    }
    case $ensure {
        present: {
            exec { "insert_module_${name}":
                command => $operatingsystem ? {
                    debian => "/bin/echo '${name}' >> '${modulesfile}'",
                    redhat => "/bin/echo '/sbin/modprobe ${name}' >> '${modulesfile}' ",
                    centos => "/bin/echo '/sbin/modprobe ${name}' >> '${modulesfile}' "
                },
                unless => $operatingsystem ? {
                    debian => "/bin/grep -qFx '${name}' '${modulesfile}'",
                    redhat => "/bin/grep -q '^/sbin/modprobe ${name}\$' '${modulesfile}'",
                    centos => "/bin/grep -q '^/sbin/modprobe ${name}\$' '${modulesfile}'",
                }
            }
            exec { "/sbin/modprobe ${name}": unless => "/bin/grep -q '^${name} ' '/proc/modules'" }
        }
        absent: {
            exec { "/sbin/modprobe -r ${name}": onlyif => "/bin/grep -q '^${name} ' '/proc/modules'" }
            exec { "remove_module_${name}":
                command => $operatingsystem ? {
                    debian => "/usr/bin/perl -ni -e 'print unless /^\\Q${name}\\E\$/' '${modulesfile}'",
                    redhat => "/usr/bin/perl -ni -e 'print unless /^\\Q/sbin/modprobe ${name}\\E\$/' '${modulesfile}'",
                    centos => "/usr/bin/perl -ni -e 'print unless /^\\Q/sbin/modprobe ${name}\\E\$/' '${modulesfile}'"
                },
                onlyif => $operatingsystem ? {
                    debian => "/bin/grep -qFx '${name}' '${modulesfile}'",
                    redhat => "/bin/grep -q '^/sbin/modprobe ${name}\$' '${modulesfile}'",
                    centos => "/bin/grep -q '^/sbin/modprobe ${name}\$' '${modulesfile}'"
                }
            }
        }
        default: { err ( "unknown ensure value ${ensure}" ) }
    }
}