Resource icon

How to relocate swap to the boot drive

FreeNAS by default will allocate 2GiB on each pool HD and use this as swap. Unfortunately, if a disk fails, your system may crash.

If your boot devices is more reliable than a USB, and you have the space, it may be beneficial to relocate swap to a swap file on your boot device. An alternative is to use a dedicated swap device, or partition, and that approach is documented here

Note: putting swap on a USB flash drive is not a good idea.

At the same time it is beneficial to leave the default pool swap where it is because it allows you the ability to replace a failed HD with a similar HD which may be slightly smaller.

The tricky part is that FreeNAS rebuilds the swap config every time you reboot.

There is a simple solution :)

Firstly, you need to create a swap file on your boot drive.


Creating the swap file

The following procedure is documented in the FreeBSD handbook

Execute the following commands in a shell:

dd if=/dev/zero of=/usr/swap0 bs=1m count=4096
chmod 0600 /usr/swap0

This will create a swap file of 4096MiB, ie 4GiB, at /usr/swap0 and assign it the correct permissions. If you would like to use a larger swap file, simply multiply the number of GiB you would like to use by 1024 and use that for the count= field.

If you want to verify the swap file creation, you can use the following command
ls -al /usr/swap0

and when executed the output should look something like this

Code:
root@freenas:~# ls -al /usr/swap0
-rw-------  1 root  wheel  4294967296 Aug 24 21:42 /usr/swap0


Adding a Post-Init command to relocate swap from the pool disks to the boot disk.

The next step is to add a Post-Init command to relocate the swap every time your system reboots.

In the GUI, click on Tasks -> Init/Shutdown Scripts, Add Init/Shutdown Script:

Then add a "Command" where the command is the following
Code:
swapoff -a ; grep -v -E 'none[[:blank:]]+swap[[:blank:]]' /etc/fstab > /etc/fstab.new && echo "md99 none swap sw,file=/usr/swap0,late 0 0" >> /etc/fstab.new && mv /etc/fstab.new /etc/fstab ; swapon -aL


And set it to "Post Init" for "When"

Screen Shot 2017-08-25 at 2.48.14 PM.png


When finished it should look like this.

Screen Shot 2017-08-25 at 2.48.35 PM.png


Now restart.

To verify that the new swap is being used and the old swap system has been disabled you can run swapinfo

And you'll see something like this:
Code:
root@freenas:~ # swapinfo
Device		  1K-blocks	 Used	Avail Capacity
/dev/md99		 4194304		0  4194304	 0%


And you can check the /etc/fstab too
cat /etc/fstab

And it will look something like this:
Code:
root@freenas:~# cat /etc/fstab
freenas-boot/grub	/boot/grub	zfs	rw,noatime	1	0
fdescfs	/dev/fd	fdescfs rw	0 0
md99 none swap sw,file=/usr/swap0,late 0 0


And that's it.


Why do it this way, and not another?


This method of disabling/re-enabling swap does not require you to remove swap partitions from your pool drives, it makes no permanent changes to your installation, other than the creation of a /usr/swap0 file, which can be removed at any time, and it will not fail and accidentally use a precious data disk as a swap device.

It will also not affect the normal FreeBSD swapon/swapoff functionality, which means it will also work with my page-in-swap script.


What do I do if I want to increase my swap size?

Replace 4096 with the new size you would prefer, and run the below commands in a shell.

swapoff -a
dd if=/dev/zero of=/usr/swap0 bs=1m count=4096
swapon -aL


What do I do if I want to go back to using the pool swap?

Remove the post-init command, then disable swap
swapoff -a

then remove the swap file,
rm /usr/swap0

Then reboot.


But what is this doing?

Code:
swapoff -a ; grep -v -E 'none[[:blank:]]+swap[[:blank:]]' /etc/fstab > /etc/fstab.new && echo "md99 none swap sw,file=/usr/swap0,late 0 0
" >> /etc/fstab.new && mv /etc/fstab.new /etc/fstab ; swapon -aL


first we disable all current swap devices
swapoff -a

then we create a new fstab without any swap devices
grep -v -E 'none[[:blank:]]+swap[[:blank:]]' /etc/fstab > /etc/fstab.new

then if that worked we add our swap file as memory device 99 for late swap usage.
echo "md99 none swap sw,file=/usr/swap0,late 0 0" >> /etc/fstab.new

then if that worked, we replace the original fstab with the new fstab
mv /etc/fstab.new /etc/fstab

And finally, even if we failed to update the fstab, we re-enable swap, include late swap devices.
swapon -aL


How do you know this works?

When FreeNAS boots, the /conf/base/etc/ix.rc.d/ix-fstab script is run to regenerate the /etc/fstab file. The script replaces /etc/fstab with /conf/base/etc/fstab, which contains the default boot mount information, then it adds various mount options that are required according to the config and imported disks, and then finally it iterates over all imported pools and finds their swap partitions and adds an encrypted swap entry for each swap partition found.

This Post-Init command removes those swap entries safely, and then adds the swap file according to the FreeBSD handbooks instructions.


Caveats

If you detach or import a pool via the GUI, FreeNAS will regenerate the /etc/fstab. This will mean that swapoff -a will no longer work to temporarily disable your swap partition. This is not a big deal.

Additionally, when you import a pool, FreeNAS will re-enable that pool's swap partitions.

Both of these issues can be resolved by re-running the Post-Init command, and will be resolved at next reboot.
Author
Stux
Views
10,187
First release
Last update
Rating
5.00 star(s) 5 ratings

More resources from Stux

Latest reviews

Still works on FreeNAS 11.1-U5. Does what it says on the wrapper.
Freenas 9.3, not much swap, but want to test pulling drives anyways :) thanks!
Works great, thanks!
Fanominal. Works great in v11-U4
Works. Swap now on zfs volume where one disk failure cannot damage it. Neat.
Top