mirror of
https://github.com/ansible-collections/community.general.git
synced 2026-02-04 07:51:50 +00:00
filesystem: xfs resize: minimal required increment (#11033)
Internally XFS uses allocation groups. Allocation groups have a maximum
size of 1 TiB - 1 block. For devices >= 4 TiB XFS uses max size
allocation groups. If a filesystem is extended and the last allocation
group is already at max size, a new allocation group is added. An
allocation group seems to require at least 64 4 KiB blocks.
For devices with integer TiB size (>4), this creates a filesystem that
has initially has 1 unused block per TiB size. The `resize` option
detects this unused space, and tries to resize the filesystem. The
xfs_growfs call is successful (exit 0), but does not increase the file
system size. This is detected as repeated change in the task.
Test case:
```
- hosts: localhost
tasks:
- ansible.builtin.command:
cmd: truncate -s 4T /media/xfs.img
creates: /media/xfs.img
notify: loopdev xfs
- ansible.builtin.meta: flush_handlers
- name: pickup xfs.img resize
ansible.builtin.command:
cmd: losetup -c /dev/loop0
changed_when: false
- community.general.filesystem:
dev: "/dev/loop0"
fstype: "xfs"
- ansible.posix.mount:
src: "/dev/loop0"
fstype: "xfs"
path: "/media/xfs"
state: "mounted"
# always shows a diff even for newly created filesystems
- community.general.filesystem:
dev: "/dev/loop0"
fstype: "xfs"
resizefs: true
handlers:
- name: loopdev xfs
ansible.builtin.command:
cmd: losetup /dev/loop0 /media/xfs.img
```
NB: If the last allocation group is not yet at max size, the filesystem
can be resized. Detecting this requires considering the XFS topology.
Other filesystems (at least ext4) also seem to require a minimum
increment after the initial device size, but seem to use the entire
device after initial creation.
Fun observation: creating a 64(+) TiB filesystem leaves a 64(+) block
gap at the end, that is allocated in a subsequent xfs_growfs call.
Co-authored-by: Johannes Naab <johannes.naab@hetzner-cloud.de>
This commit is contained in:
parent
c984b89667
commit
f5943201b9
2 changed files with 8 additions and 1 deletions
2
changelogs/fragments/filesystem-xfs-resize-slack.yml
Normal file
2
changelogs/fragments/filesystem-xfs-resize-slack.yml
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
bugfixes:
|
||||
- filesystem - avoid false positive change detection on XFS resize due to unusable slack space (https://github.com/ansible-collections/community.general/pull/11033).
|
||||
|
|
@ -207,6 +207,7 @@ class Filesystem:
|
|||
MKFS_SET_UUID_EXTRA_OPTIONS: list[str] | None = []
|
||||
INFO: str | None = None
|
||||
GROW: str | None = None
|
||||
GROW_SLACK: int = 0
|
||||
GROW_MAX_SPACE_FLAGS: list[str] | None = []
|
||||
GROW_MOUNTPOINT_ONLY = False
|
||||
CHANGE_UUID: str | None = None
|
||||
|
|
@ -275,7 +276,7 @@ class Filesystem:
|
|||
self.module.warn(f"unable to process {self.INFO} output '{err}'")
|
||||
self.module.fail_json(msg=f"unable to process {self.INFO} output for {dev}")
|
||||
|
||||
if not fssize_in_bytes < devsize_in_bytes:
|
||||
if fssize_in_bytes + self.GROW_SLACK >= devsize_in_bytes:
|
||||
self.module.exit_json(changed=False, msg=f"{self.fstype} filesystem is using the whole device {dev}")
|
||||
elif self.module.check_mode:
|
||||
self.module.exit_json(changed=True, msg=f"resizing filesystem {self.fstype} on device {dev}")
|
||||
|
|
@ -355,6 +356,10 @@ class XFS(Filesystem):
|
|||
MKFS_FORCE_FLAGS = ["-f"]
|
||||
INFO = "xfs_info"
|
||||
GROW = "xfs_growfs"
|
||||
# XFS (defaults with 4KiB blocksize) requires at least 64 block of free
|
||||
# space to add a new allocation group, avoid resizing (noop, but shown as
|
||||
# diff) if the difference between the filesystem and the device is less
|
||||
GROW_SLACK = 64 * 4096 - 1
|
||||
GROW_MOUNTPOINT_ONLY = True
|
||||
CHANGE_UUID = "xfs_admin"
|
||||
CHANGE_UUID_OPTION = "-U"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue