Repository: ansible-collections/community.general

Issue:
lvol: extending to ' +100%FREE' calculating wrong size
### Summary

When I try to extend lv to max free available disk space, it calculates the wrong size after upgrading from 2.5.1 to current release (3.0.0)

Error:
--------
```
fatal: [vm-001]: FAILED! => {"changed": false, "msg": "Logical Volume root could not be extended. Not enough free space left (5120.0m required / 5116.0m available)"}
```


Possibly related to:
-------------------------
https://github.com/ansible-collections/community.general/issues/1988
https://github.com/ansible-collections/community.general/pull/2267

### Issue Type

Bug Report

### Component Name

lvol

### Ansible Version

```console (paste below)
ansible 2.10.8
  config file = /home/dominik.kaminski/ansible/ansible.cfg
  configured module search path = ['/home/dominik.kaminski/ansible/library']
  ansible python module location = /home/dominik.kaminski/.local/lib/python3.6/site-packages/ansible
  executable location = /home/dominik.kaminski/.local/bin/ansible
  python version = 3.6.8 (default, Aug 24 2020, 17:57:11) [GCC 8.3.1 20191121 (Red Hat 8.3.1-5)]

```


### Configuration

```console (paste below)
$ ansible-config dump --only-changed

```


### OS / Environment

UCS

### Steps to Reproduce

<!--- Paste example playbooks or commands between quotes below -->
```yaml (paste below)
- name: "Extend logical volume to available space"
  community.general.lvol:
    vg: "{{ extend_root_lvm_volume_lvm_vg_name }}"
    lv: "{{ extend_root_lvm_volume_lvm_data_volume }}"
    resizefs: "yes"
    size: "+100%FREE"
  tags:
    - extend_root_lvm_volume_resize
```


### Expected Results

Volumes should be extended to available free space or calculating free available size correct.

### Actual Results

```console (paste below)
fatal: [vm-001]: FAILED! => {"changed": false, "msg": "Logical Volume root could not be extended. Not enough free space left (5120.0m required / 5116.0m available)"}
```


### Code of Conduct

- [X] I agree to follow the Ansible Code of Conduct


Discussion:

Resolving patch:
diff --git a/plugins/modules/system/lvol.py b/plugins/modules/system/lvol.py
--- a/plugins/modules/system/lvol.py
+++ b/plugins/modules/system/lvol.py
@@ -389,7 +389,7 @@ def main():
     # Get information on volume group requested
     vgs_cmd = module.get_bin_path("vgs", required=True)
     rc, current_vgs, err = module.run_command(
-        "%s --noheadings --nosuffix -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s" % (vgs_cmd, unit, vg))
+        "%s --noheadings --nosuffix -o vg_name,size,free,vg_extent_size --units %s --separator ';' %s" % (vgs_cmd, unit.lower(), vg))
 
     if rc != 0:
         if state == 'absent':
@@ -403,7 +403,7 @@ def main():
     # Get information on logical volume requested
     lvs_cmd = module.get_bin_path("lvs", required=True)
     rc, current_lvs, err = module.run_command(
-        "%s -a --noheadings --nosuffix -o lv_name,size,lv_attr --units %s --separator ';' %s" % (lvs_cmd, unit, vg))
+        "%s -a --noheadings --nosuffix -o lv_name,size,lv_attr --units %s --separator ';' %s" % (lvs_cmd, unit.lower(), vg))
 
     if rc != 0:
         if state == 'absent':
@@ -505,16 +505,13 @@ def main():
             else:  # size_whole == 'FREE':
                 size_requested = size_percent * this_vg['free'] / 100
 
-            # from LVEXTEND(8) - The resulting value is rounded upward.
-            # from LVREDUCE(8) - The resulting value for the substraction is rounded downward, for the absolute size it is rounded upward.
             if size_operator == '+':
                 size_requested += this_lv['size']
-                size_requested += this_vg['ext_size'] - (size_requested % this_vg['ext_size'])
             elif size_operator == '-':
                 size_requested = this_lv['size'] - size_requested
-                size_requested -= (size_requested % this_vg['ext_size'])
-            else:
-                size_requested += this_vg['ext_size'] - (size_requested % this_vg['ext_size'])
+
+            # According to latest documentation (LVM2-2.03.11) all tools round down
+            size_requested -= (size_requested % this_vg['ext_size'])
 
             if this_lv['size'] < size_requested:
                 if (size_free > 0) and (size_free >= (size_requested - this_lv['size'])):


Test patch: