Verify that the named kernel module is not loaded

    name
        The name of the kernel module to verify is not loaded

    persist
        Remove module from ``/etc/modules``

    comment
        Comment out module in ``/etc/modules`` rather than remove it

    mods
        A list of modules to verify are unloaded.  If this argument is used,
        the ``name`` argument, although still required, is not used, and
        becomes a placeholder

        .. versionadded:: 2016.3.0

def absent(name, persist=False, comment=True, mods=None):
    '''
    Verify that the named kernel module is not loaded

    name
        The name of the kernel module to verify is not loaded

    persist
        Remove module from ``/etc/modules``

    comment
        Comment out module in ``/etc/modules`` rather than remove it

    mods
        A list of modules to verify are unloaded.  If this argument is used,
        the ``name`` argument, although still required, is not used, and
        becomes a placeholder

        .. versionadded:: 2016.3.0
    '''
    if not isinstance(mods, (list, tuple)):
        mods = [name]
    ret = {'name': name,
           'result': True,
           'changes': {},
           'comment': ''}

    loaded_mods = __salt__['kmod.mod_list']()
    if persist:
        persist_mods = __salt__['kmod.mod_list'](True)
        # Union of loaded modules and persistent modules
        loaded_mods = list(set(loaded_mods) | set(persist_mods))

    # Intersection of proposed modules and loaded modules
    to_unload = list(set(mods) & set(loaded_mods))
    if to_unload:
        if __opts__['test']:
            ret['result'] = None
            if len(to_unload) == 1:
                _append_comment(ret, 'Kernel module {0} is set to be removed'.format(to_unload[0]))
            elif len(to_unload) > 1:
                _append_comment(ret, 'Kernel modules {0} are set to be removed'.format(', '.join(to_unload)))
            return ret

        # Unload modules and collect results
        unloaded = {'yes': [], 'no': [], 'failed': []}
        for mod in to_unload:
            unload_result = __salt__['kmod.remove'](mod, persist, comment)
            if isinstance(unload_result, (list, tuple)):
                if unload_result:
                    for module in unload_result:
                        ret['changes'][module] = 'removed'
                    unloaded['yes'].append(mod)
                else:
                    ret['result'] = False
                    unloaded['no'].append(mod)
            else:
                ret['result'] = False
                unloaded['failed'].append([mod, unload_result])

        # Update comment with results
        if len(unloaded['yes']) == 1:
            _append_comment(ret, 'Removed kernel module {0}'.format(unloaded['yes'][0]))
        elif len(unloaded['yes']) > 1:
            _append_comment(ret, 'Removed kernel modules {0}'.format(', '.join(unloaded['yes'])))

        if len(unloaded['no']) == 1:
            _append_comment(ret, 'Failed to remove kernel module {0}'.format(unloaded['no'][0]))
        if len(unloaded['no']) > 1:
            _append_comment(ret, 'Failed to remove kernel modules {0}'.format(', '.join(unloaded['no'])))

        if unloaded['failed']:
            for mod, msg in unloaded['failed']:
                _append_comment(ret, 'Failed to remove kernel module {0}: {1}'.format(mod, msg))

        return ret

    else:
        if len(mods) == 1:
            ret['comment'] = 'Kernel module {0} is already removed'.format(mods[0])
        else:
            ret['comment'] = 'Kernel modules {0} are already removed'.format(', '.join(mods))

        return ret