cron: add scrub and trim jobs for btrfs/zfs

No longer depend on `rootfs` variable.
This commit is contained in:
Hoang Nguyen 2023-06-20 00:00:00 +07:00
parent 386fdb9280
commit 62f28a2c92
Signed by: folliehiyuki
GPG Key ID: B0567C20730E9B11
8 changed files with 68 additions and 42 deletions

View File

@ -7,7 +7,7 @@ Stuff that are planned to be added/changed.
- [ ] /etc/security/access.conf
- [ ] Filesystem snapshot:
- [ ] sanoid / zrepl (rootfs=zfs)
- [ ] How should we figure out the underlying fstype if rootfs=tmpfs??
- [ ] Root on tmpfs
- [ ] Filesystem backup (I don't have spare hard drives -_- so not supported for now):
- [ ] Local incremental backups (to spare disk)
- [ ] Remote backups

View File

@ -4,9 +4,11 @@ initramfs_generator:
- dracut
- booster
snapshot_tool: '{{ ["sanoid", "zrepl"] if rootfs == "zfs"
else ["snapper", "btrbk"] if rootfs == "btrfs"
else ["none"] }}'
snapshot_tool:
- btrbk
- sanoid
- snapper
- zrepl
# NOTE: Keep this in sync with `shell_mappings` in roles/user/defaults/main.yml
usershell:

View File

@ -1,5 +0,0 @@
#!/bin/sh
# Use flock to ensure the cron job won't start a 2nd time
# Ref: https://wiki.archlinux.org/title/Cron#Ensuring_exclusivity
/usr/bin/flock -nx /tmp/btrfs_scrub.lock /sbin/btrfs scrub start /

View File

@ -1,5 +1,8 @@
#!/bin/sh
# This needs fstrim
# For busybox's fstrim, using multiple 'fstrim /mount_point' is more feasible
/sbin/fstrim -a
# NOTE: we only trim things inside /etc/fstab to avoid ZFS mount paths
# (they will be handled by `zpool trim` cron job)
# This needs fstrim from util-linux package.
# For busybox's fstrim, use multiple 'fstrim /mount_point'.
exec /sbin/fstrim -A

View File

@ -1,12 +1,4 @@
---
- name: cron | Create fstrim daily job
copy:
src: fstrim
dest: /etc/periodic/daily/fstrim
owner: root
group: root
mode: '755'
# It is recomended to preserve /var/tmp across reboots
- name: cron | Create empty /var/tmp/ weekly job
copy:
@ -16,14 +8,11 @@
group: root
mode: '755'
- name: cron | Create btrfs-scrub monthly job
copy:
src: btrfs-scrub
dest: /etc/periodic/monthly/btrfs-scrub
owner: root
group: root
mode: '755'
when: rootfs == 'btrfs'
- name: cron | Create trimming cron jobs
import_tasks: trim.yml
- name: cron | Create scrubbing cron jobs for zfs/btrfs
import_tasks: scrub.yml
- name: cron | Install logrotate and cpulimit
community.general.apk:

View File

@ -0,0 +1,23 @@
---
- name: cron | Create BTRFS scrub monthly job
copy:
content: |
#!/bin/sh
exec /sbin/btrfs scrub start -B {{ item }}
dest: /etc/periodic/monthly/scrub-btrfs-{{ item | regex_replace('/', '@') }}
owner: root
group: root
mode: '755'
# PERF: a shorter version but requires `py3-jmespath`: '{{ ansible_mounts | json_query("[?fstype == `btrfs`].mount") }}'
loop: '{{ ansible_mounts | selectattr("fstype", "equalto", "btrfs") | map(attribute="mount") | list }}'
- name: cron | Create ZFS pool scrub monthly job
copy:
content: |
#!/bin/sh
exec /usr/sbin/zpool scrub -w {{ item }}
dest: /etc/periodic/monthly/scrub-zfs-{{ item }}
mode: '755'
owner: root
group: root
loop: '{{ ansible_zfs_pools | map(attribute="name") | list }}'

25
roles/cron/tasks/trim.yml Normal file
View File

@ -0,0 +1,25 @@
---
# NOTE: dmcrypt discourages using `discard` mount option (as in BTRFS on LUKS),
# so running trim manually in a cron job
- name: cron | Create fstrim weekly job
copy:
src: fstrim
dest: /etc/periodic/weekly/fstrim
owner: root
group: root
mode: '755'
- name: cron | Create ZFS pool trim weekly job
copy:
content: |
#!/bin/sh
if /usr/sbin/zpool status {{ item }} | grep -qF "trimming"; then
exec /usr/sbin/zpool wait -t trim {{ item }}
else
exec /usr/sbin/zpool trim -w {{ item }}
fi
dest: /etc/periodic/weekly/trim-zfs-{{ item }}
mode: '755'
owner: root
group: root
loop: '{{ ansible_zfs_pools | map(attribute="name") | list }}'

View File

@ -2,20 +2,7 @@
- name: Setup the system
hosts: all
gather_facts: true
# vars:
# # Determine the fstype of root filesystem
# # PERF: a shorter version but requires `py3-jmespath`: '{{ ansible_mounts | json_query("[?mount == `/`].fstype") | first }}'
# rootfs: '{{ ansible_mounts | selectattr("mount", "equalto", "/") | map(attribute="fstype") | first }}'
pre_tasks:
# FIXME: ansible_mounts doesn't recognise ZFS dataset (yet???)
# Ref: https://github.com/ansible/ansible/issues/24644
- name: Guess fstype of the root filesystem
shell:
cmd: /bin/findmnt -M / -o FSTYPE -f | tail -n 1
register: findmnt_result
- name: Set rootfs variable
set_fact:
rootfs: findmnt_result.stdout
- name: Sanity checks
tags: always
block:
@ -32,6 +19,9 @@
msg: 'Variable `{{ item }}` needs to be 1 of {{ accepted_values[item] }}'
when: not vars[item] in accepted_values[item]
loop: '{{ accepted_values | flatten }}'
- name: Get ZFS pool facts
community.general.zpool_facts:
tags: always
roles:
- role: essential
tags: essential
@ -67,7 +57,6 @@
tags: zram
- role: snapshot
tags: snapshot
when: snapshot_tool != 'none'
- role: earlyoom
tags: earlyoom
- role: user