prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  modprobe: Call 'modprobe -r' instasd of 'rmmod' for absent?
  ##### ISSUE TYPE
  - Feature Idea
  ##### COMPONENT NAME
  
  modprobe
  ##### ANSIBLE VERSION
  
  ```
  ansible 2.0.1.0
    config file =
    configured module search path = Default w/o overrides
  ```
  ##### CONFIGURATION
  
  N/A
  ##### OS / ENVIRONMENT
  
  N/A (linux target)
  ##### SUMMARY
  
  Current implementation of modprobe module uses `rmmod` command to remove kernel module.
  https://github.com/ansible/ansible-modules-extras/blob/stable-2.1/system/modprobe.py#L114
  
  Why don't we use `modprobe -r` instead of `rmmod` here?
  
  `modprobe -r` would be better because; 
  1. It will also unload unused modules
  2. Straight forward from module name
  ##### STEPS TO REPRODUCE
  
  I was trying to unload sb_edac module from my server (since it conflict with some hardware monitoring of server), the module depends on edac_core and edac_core was loaded only for sb_edac.
  
  Before applying playbook, on the target server.
  
  ```
  server# lsmod | grep edac
  sb_edac                28672  0
  edac_core              53248  1 sb_edac
  ```
  
  playbook (snippet)
  
  ```
  - name: unload edac modules
    modprobe:
      name: sb_edac
      state: absent
  ```
  ##### EXPECTED RESULTS
  
  edac_core module unloaded, since it no longer be used.
  ##### ACTUAL RESULTS
  
  After applying playbook, on the target server.
  
  ```
  server# lsmod | grep edac
  edac_core              53248  0
  ```
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `system/modprobe.py`
  Content:
  ```
  1 #!/usr/bin/python
  2 #coding: utf-8 -*-
  3 
  4 # (c) 2013, David Stygstra <david.stygstra@gmail.com>
  5 #
  6 # This file is part of Ansible
  7 #
  8 # This module is free software: you can redistribute it and/or modify
  9 # it under the terms of the GNU General Public License as published by
  10 # the Free Software Foundation, either version 3 of the License, or
  11 # (at your option) any later version.
  12 #
  13 # This software is distributed in the hope that it will be useful,
  14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 # GNU General Public License for more details.
  17 #
  18 # You should have received a copy of the GNU General Public License
  19 # along with this software.  If not, see <http://www.gnu.org/licenses/>.
  20 
  21 
  22 DOCUMENTATION = '''
  23 ---
  24 module: modprobe
  25 short_description: Add or remove kernel modules
  26 requirements: []
  27 version_added: 1.4
  28 author:
  29     - "David Stygstra (@stygstra)" 
  30     - "Julien Dauphant"
  31     - "Matt Jeffery"
  32 description:
  33     - Add or remove kernel modules.
  34 options:
  35     name:
  36         required: true
  37         description:
  38             - Name of kernel module to manage.
  39     state:
  40         required: false
  41         default: "present"
  42         choices: [ present, absent ]
  43         description:
  44             - Whether the module should be present or absent.
  45     params:
  46         required: false
  47         default: ""
  48         version_added: "1.6"
  49         description:
  50             - Modules parameters.
  51 '''
  52 
  53 EXAMPLES = '''
  54 # Add the 802.1q module
  55 - modprobe: name=8021q state=present
  56 # Add the dummy module
  57 - modprobe: name=dummy state=present params="numdummies=2"
  58 '''
  59 
  60 from ansible.module_utils.basic import *
  61 from ansible.module_utils.pycompat24 import get_exception
  62 import shlex
  63 
  64 
  65 def main():
  66     module = AnsibleModule(
  67         argument_spec={
  68             'name': {'required': True},
  69             'state': {'default': 'present', 'choices': ['present', 'absent']},
  70             'params': {'default': ''},
  71         },
  72         supports_check_mode=True,
  73     )
  74     args = {
  75         'changed': False,
  76         'failed': False,
  77         'name': module.params['name'],
  78         'state': module.params['state'],
  79         'params': module.params['params'],
  80     }
  81 
  82     # Check if module is present
  83     try:
  84         modules = open('/proc/modules')
  85         present = False
  86         module_name = args['name'].replace('-', '_') + ' '
  87         for line in modules:
  88             if line.startswith(module_name):
  89                 present = True
  90                 break
  91         modules.close()
  92     except IOError:
  93         e = get_exception()
  94         module.fail_json(msg=str(e), **args)
  95 
  96     # Check only; don't modify
  97     if module.check_mode:
  98         if args['state'] == 'present' and not present:
  99             changed = True
  100         elif args['state'] == 'absent' and present:
  101             changed = True
  102         else:
  103             changed = False
  104         module.exit_json(changed=changed)
  105 
  106     # Add/remove module as needed
  107     if args['state'] == 'present':
  108         if not present:
  109             command = [module.get_bin_path('modprobe', True), args['name']]
  110             command.extend(shlex.split(args['params']))
  111             rc, _, err = module.run_command(command)
  112             if rc != 0:
  113                 module.fail_json(msg=err, **args)
  114             args['changed'] = True
  115     elif args['state'] == 'absent':
  116         if present:
  117             rc, _, err = module.run_command([module.get_bin_path('rmmod', True), args['name']])
  118             if rc != 0:
  119                 module.fail_json(msg=err, **args)
  120             args['changed'] = True
  121 
  122     module.exit_json(**args)
  123 
  124 main()
  125
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/system/modprobe.py b/system/modprobe.py
  --- a/system/modprobe.py
  +++ b/system/modprobe.py
  @@ -114,7 +114,7 @@
               args['changed'] = True
       elif args['state'] == 'absent':
           if present:
  -            rc, _, err = module.run_command([module.get_bin_path('rmmod', True), args['name']])
  +            rc, _, err = module.run_command([module.get_bin_path('modprobe', True), '-r', args['name']])
               if rc != 0:
                   module.fail_json(msg=err, **args)
               args['changed'] = True
  
verification_info: {"golden_diff": "diff --git a/system/modprobe.py b/system/modprobe.py\n--- a/system/modprobe.py\n+++ b/system/modprobe.py\n@@ -114,7 +114,7 @@\n             args['changed'] = True\n     elif args['state'] == 'absent':\n         if present:\n-            rc, _, err = module.run_command([module.get_bin_path('rmmod', True), args['name']])\n+            rc, _, err = module.run_command([module.get_bin_path('modprobe', True), '-r', args['name']])\n             if rc != 0:\n                 module.fail_json(msg=err, **args)\n             args['changed'] = True\n", "issue": "modprobe: Call 'modprobe -r' instasd of 'rmmod' for absent?\n##### ISSUE TYPE\n- Feature Idea\n##### COMPONENT NAME\n\nmodprobe\n##### ANSIBLE VERSION\n\n```\nansible 2.0.1.0\n  config file =\n  configured module search path = Default w/o overrides\n```\n##### CONFIGURATION\n\nN/A\n##### OS / ENVIRONMENT\n\nN/A (linux target)\n##### SUMMARY\n\nCurrent implementation of modprobe module uses `rmmod` command to remove kernel module.\nhttps://github.com/ansible/ansible-modules-extras/blob/stable-2.1/system/modprobe.py#L114\n\nWhy don't we use `modprobe -r` instead of `rmmod` here?\n\n`modprobe -r` would be better because; \n1. It will also unload unused modules\n2. Straight forward from module name\n##### STEPS TO REPRODUCE\n\nI was trying to unload sb_edac module from my server (since it conflict with some hardware monitoring of server), the module depends on edac_core and edac_core was loaded only for sb_edac.\n\nBefore applying playbook, on the target server.\n\n```\nserver# lsmod | grep edac\nsb_edac                28672  0\nedac_core              53248  1 sb_edac\n```\n\nplaybook (snippet)\n\n```\n- name: unload edac modules\n  modprobe:\n    name: sb_edac\n    state: absent\n```\n##### EXPECTED RESULTS\n\nedac_core module unloaded, since it no longer be used.\n##### ACTUAL RESULTS\n\nAfter applying playbook, on the target server.\n\n```\nserver# lsmod | grep edac\nedac_core              53248  0\n```\n\n", "before_files": [{"content": "#!/usr/bin/python\n#coding: utf-8 -*-\n\n# (c) 2013, David Stygstra <david.stygstra@gmail.com>\n#\n# This file is part of Ansible\n#\n# This module is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This software is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this software.  If not, see <http://www.gnu.org/licenses/>.\n\n\nDOCUMENTATION = '''\n---\nmodule: modprobe\nshort_description: Add or remove kernel modules\nrequirements: []\nversion_added: 1.4\nauthor:\n    - \"David Stygstra (@stygstra)\" \n    - \"Julien Dauphant\"\n    - \"Matt Jeffery\"\ndescription:\n    - Add or remove kernel modules.\noptions:\n    name:\n        required: true\n        description:\n            - Name of kernel module to manage.\n    state:\n        required: false\n        default: \"present\"\n        choices: [ present, absent ]\n        description:\n            - Whether the module should be present or absent.\n    params:\n        required: false\n        default: \"\"\n        version_added: \"1.6\"\n        description:\n            - Modules parameters.\n'''\n\nEXAMPLES = '''\n# Add the 802.1q module\n- modprobe: name=8021q state=present\n# Add the dummy module\n- modprobe: name=dummy state=present params=\"numdummies=2\"\n'''\n\nfrom ansible.module_utils.basic import *\nfrom ansible.module_utils.pycompat24 import get_exception\nimport shlex\n\n\ndef main():\n    module = AnsibleModule(\n        argument_spec={\n            'name': {'required': True},\n            'state': {'default': 'present', 'choices': ['present', 'absent']},\n            'params': {'default': ''},\n        },\n        supports_check_mode=True,\n    )\n    args = {\n        'changed': False,\n        'failed': False,\n        'name': module.params['name'],\n        'state': module.params['state'],\n        'params': module.params['params'],\n    }\n\n    # Check if module is present\n    try:\n        modules = open('/proc/modules')\n        present = False\n        module_name = args['name'].replace('-', '_') + ' '\n        for line in modules:\n            if line.startswith(module_name):\n                present = True\n                break\n        modules.close()\n    except IOError:\n        e = get_exception()\n        module.fail_json(msg=str(e), **args)\n\n    # Check only; don't modify\n    if module.check_mode:\n        if args['state'] == 'present' and not present:\n            changed = True\n        elif args['state'] == 'absent' and present:\n            changed = True\n        else:\n            changed = False\n        module.exit_json(changed=changed)\n\n    # Add/remove module as needed\n    if args['state'] == 'present':\n        if not present:\n            command = [module.get_bin_path('modprobe', True), args['name']]\n            command.extend(shlex.split(args['params']))\n            rc, _, err = module.run_command(command)\n            if rc != 0:\n                module.fail_json(msg=err, **args)\n            args['changed'] = True\n    elif args['state'] == 'absent':\n        if present:\n            rc, _, err = module.run_command([module.get_bin_path('rmmod', True), args['name']])\n            if rc != 0:\n                module.fail_json(msg=err, **args)\n            args['changed'] = True\n\n    module.exit_json(**args)\n\nmain()\n", "path": "system/modprobe.py"}], "after_files": [{"content": "#!/usr/bin/python\n#coding: utf-8 -*-\n\n# (c) 2013, David Stygstra <david.stygstra@gmail.com>\n#\n# This file is part of Ansible\n#\n# This module is free software: you can redistribute it and/or modify\n# it under the terms of the GNU General Public License as published by\n# the Free Software Foundation, either version 3 of the License, or\n# (at your option) any later version.\n#\n# This software is distributed in the hope that it will be useful,\n# but WITHOUT ANY WARRANTY; without even the implied warranty of\n# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n# GNU General Public License for more details.\n#\n# You should have received a copy of the GNU General Public License\n# along with this software.  If not, see <http://www.gnu.org/licenses/>.\n\n\nDOCUMENTATION = '''\n---\nmodule: modprobe\nshort_description: Add or remove kernel modules\nrequirements: []\nversion_added: 1.4\nauthor:\n    - \"David Stygstra (@stygstra)\" \n    - \"Julien Dauphant\"\n    - \"Matt Jeffery\"\ndescription:\n    - Add or remove kernel modules.\noptions:\n    name:\n        required: true\n        description:\n            - Name of kernel module to manage.\n    state:\n        required: false\n        default: \"present\"\n        choices: [ present, absent ]\n        description:\n            - Whether the module should be present or absent.\n    params:\n        required: false\n        default: \"\"\n        version_added: \"1.6\"\n        description:\n            - Modules parameters.\n'''\n\nEXAMPLES = '''\n# Add the 802.1q module\n- modprobe: name=8021q state=present\n# Add the dummy module\n- modprobe: name=dummy state=present params=\"numdummies=2\"\n'''\n\nfrom ansible.module_utils.basic import *\nfrom ansible.module_utils.pycompat24 import get_exception\nimport shlex\n\n\ndef main():\n    module = AnsibleModule(\n        argument_spec={\n            'name': {'required': True},\n            'state': {'default': 'present', 'choices': ['present', 'absent']},\n            'params': {'default': ''},\n        },\n        supports_check_mode=True,\n    )\n    args = {\n        'changed': False,\n        'failed': False,\n        'name': module.params['name'],\n        'state': module.params['state'],\n        'params': module.params['params'],\n    }\n\n    # Check if module is present\n    try:\n        modules = open('/proc/modules')\n        present = False\n        module_name = args['name'].replace('-', '_') + ' '\n        for line in modules:\n            if line.startswith(module_name):\n                present = True\n                break\n        modules.close()\n    except IOError:\n        e = get_exception()\n        module.fail_json(msg=str(e), **args)\n\n    # Check only; don't modify\n    if module.check_mode:\n        if args['state'] == 'present' and not present:\n            changed = True\n        elif args['state'] == 'absent' and present:\n            changed = True\n        else:\n            changed = False\n        module.exit_json(changed=changed)\n\n    # Add/remove module as needed\n    if args['state'] == 'present':\n        if not present:\n            command = [module.get_bin_path('modprobe', True), args['name']]\n            command.extend(shlex.split(args['params']))\n            rc, _, err = module.run_command(command)\n            if rc != 0:\n                module.fail_json(msg=err, **args)\n            args['changed'] = True\n    elif args['state'] == 'absent':\n        if present:\n            rc, _, err = module.run_command([module.get_bin_path('modprobe', True), '-r', args['name']])\n            if rc != 0:\n                module.fail_json(msg=err, **args)\n            args['changed'] = True\n\n    module.exit_json(**args)\n\nmain()\n", "path": "system/modprobe.py"}]}