1

What's the best way to disable swap entirely on a fleet of GNU/Linux hosts, using systemd and Ansible?

For whatever reason some of my virtual machines have a swap file configured in their /etc/fstab, which gets automatically picked up at boot by systemd-fstab-generator like this:

$ cat /run/systemd/generator/swapfile.swap
# Automatically generated by systemd-fstab-generator

[Unit]
SourcePath=/etc/fstab
Documentation=man:fstab(5) man:systemd-fstab-generator(8)

[Swap]
What=/swapfile

Some services running on those machines get terminally slow when using the swap file, for various reasons, so I need to prevent them from using it. My version of systemd doesn't yet include MemorySwapMax.

I'd like to avoid messing up with /etc/fstab and I don't mind having those swap files left in place.

For context, I'm using ansible-3.0.0, ansible-base-2.10.6; the machines are CentOS 7, with systemd 219.

3
  • Just delete the swap line from /etc/fstab if you don't want it. Also you realize that this means you will just run out of ram and the OOM-killer will kill some memory hogging processes?
    – psusi
    Feb 26, 2021 at 19:15
  • @psusi I don't want to change /etc/fstab with ansible. And yes, my goal is to get those processes killed as fast as possible by the kernel.
    – Nemo
    Feb 26, 2021 at 19:38
  • How convenient. Linus Torvalds just proclaimed that "swapfiles just aren't normal". lkml.org/lkml/2021/3/3/1332 I swear there was no coordination. ;)
    – Nemo
    Mar 5, 2021 at 23:38

1 Answer 1

1

You can let systemd do its thing by default and then just revert it with another systemd unit immediately afterwards.

If you check with systemd show swapfile.swap, you'll see all the unit does is to run swapon on that file. When you issue swapoff manually, the swap will reappear at the next boot.

Running swapoff immediately after swapon will only take a fraction of a second because there's nothing to move back from disk to memory. However you must make sure you run swapoff after swapon, and you can tell systemd to do so with After=local-fs.target.

Place your unit file as a j2 template named noswap.service.j2 in the templates/ directory for your playbook or role:

{{ ansible_managed|comment }}

[Unit]
Description=Disable swapfile
Documentation=man:swapon(8) man:systemd.swap(5)
After=local-fs.target

[Service]
Type=oneshot
User=root
ExecStart=/usr/sbin/swapoff -a

[Install]
WantedBy=default.target

Have something like this in your playbook or role:

---
- name: Your playbook

  tasks:
    - name: Write noswap systemd service config file
      template:
        src: noswap.service.j2
        dest: /etc/systemd/system/noswap.service
        owner: root
        group: root
        mode: 0644
      notify: Enable noswap service

  handlers:
    - name: Enable noswap service
      systemd:
        name: noswap
        state: started
        enabled: true
        daemon_reload: true

After the first time, the service will be started during boot, so the state: started should prevent it from being issued again every time you run ansible.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .