Swap HOWTO

Swap HOWTO

V.0.2

	If there are any questions or comments, please direct them to
walt@erudition.net. The newest copy of this HowTo can always be retrieved
from www.freebsd-howto.com. All rights for the reproduction of this
document are reserved.

	Summary

	This HowTo deals with the installation of additional swap space
for 2.2.x, 3.x and 4.x FreeBSD systems. It covers two approaches: using
the /stand/sysinstall administration utility and an additional method
using the vn(4) system, following a general overview of what swap is and
how it is used in Operating Systems in general.  It quickly covers how to
mount additional swap partitions and virtual swap disks during bootup.

1.	Background

	1.1.	What is Swap?
	1.2.	Swap Efficiency

2.	Installation

	2.1.	Determining Swap Parition Size
        2.2.    Installing Swap with The Label Editor
	        2.2.1.  Using Spare/Unallocated Space
	        2.2.2. Adding Hard Disks for Additional Swap Space
		        2.2.2.1. Adding /etc/fstab Entry for Additional
				 Swap Partitions
			2.2.2.2. swapinfo(8)

        2.3.    Using vn(4) System for Additional Swap Space
	        2.3.1.  Enabling vn(4) in Kernel
	        2.3.2.  Using MAKEDEV(8) to Add vn(4) Device Entries in /dev
	        2.3.3.  Creating Swap Image File
	        2.3.4.  Configuring vn(4) Swap Disk with vnconfig(8)
	        2.3.5.  Using rc.conf to Mount Swap Image Files on Bootup
	        2.3.6.	Having Multiple Virtual Swap Disks Mount on Bootup

3.	Appendix














	1.1. What is Swap?

	An important part of many virtual memory systems is the swap
space. It is an area of storage, usually situated on a hard disk, that
acts as a temporary extention of the system's memory. Swapping is vital
for many systems where sufficient memory either can not be afforded or can
not be enabled in the system. It, along with demand-paging, allows a
system's processes not to be limited by the size of physical memory.

	To understand the role that swap space plays in a system, memory
pages (evenly sized chunks of memory) can be broken into two categories:
file-backed and anonymous. File-backed memory, as the name implies, is
memory whose contents originated from a filesystem and has a corresponding
copy of itself saved on a disk somewhere, such as a source file, binary,
shell script, database, etc. Likewise, anonymous memory does not have a
corresponding version sitting on a disk somewhere and so once it exits
physical memory, it is lost.

	Typical anonymous memory consists of memory chunks garnered
through the malloc() family of system calls and/or any data that is
initialized during runtime, such as arrays, temporary variables, linked
lists, and so on. As the various memory buckets (active, inactive, cache,
free, etc) are being balanced for the particular system load, and memory
pages are moving among these buckets, if at some point a memory page with
anonymous memory must be moved out of physicasl memory for higher priority
processes, they can not simply be discarded. Indeed, data would be lost
and the process(es) that require it would be unable to continue. As such,
swap space comes into play. The memory pages with anonymous memory are
swapped out onto into the swap space to temporarily hold them until enough
physical memory has been freed to continue their use.

	1.2. Swap Efficiency

	Such swap usage as outlined in the previous section allows a
system greater flexibility in managing multiple, large processes at the
same time. In addition, various characteristics of the FreeBSD swap
management allow for its efficient and effective use. One such
characteristic is that memory pages swapped out, once called back and not
rendered dirty again (not changed), do not lose their allocated area on
the swap space so that they can be quickly swapped out again if necessary.
The allocated swap is reserved until the memory page is no longer
necessary (that is, until all disk I/O necessary has been made, allowing
the discarding of the anonymous memory page) or the page has been rendered
dirty (changed). Another performance boost is yielded by not preallocating
swap space for every process in memory, such as many System V-based
systems do. Also, swap partitions are not encumbered by the overheard of
maintaining a filesystem on top of them. Memory pages can be more quickly
allocated, deallocated, written, and read.
	
	To further increase swap performance, it is suggested to spread
swap activity across multiple disks if possible. For instance, if one has
/ and /var on one disk, and /home, /usr, and /tmp on another, it is
recommended to split the total swap size in half and place each half on a
separate disk, such that the brunt of swap activity does not fall on one
disk, doubling the I/O speed for swap. FreeBSD automatically cycles usage
among multiple swap partitions in a round robin fashion.

	2.1. Determining Swap Partition Size

	When determining the amount of swap space to allow your system
during installation, a general rule of thumb is to allocate 1.5 - 2 times
as much swap space as you intend to eventually have physical memory.
Basing one's allocation size on the maximum, eventual, physical memory
size attempts to save one from having to resize partitions or add virtual
swap disks later with the vn(4) system. The 1.5 - 2 factor is a good rule
of thumb that works for moderate physical memory sizes: 16M - 64M of RAM.
If one has more physical memory, such as 128M, or 256M, sufficient swap
space may well be less of an issue. In such situations, if one is
confident that one will not be regularly bumping one's memory limits, a
1:1 or even 2:1 RAM to swap ratio may be reasonable.

	2.2.	Installing Swap with The Label Editor

	2.2.1.	Using Spare/Unallocated Space

	When installing a new system, it is with the disk label editor
with which one allocates swap space. It is also with the disklabel editor
with which one may resize swap partitions. Some individuals make it a
habit to always leave unallocated space on their hard disks such that it
could be used later as necessary for emergency purposes, such as extending
the swap partition. If you are one such individual, then the current swap
partition, if not in use, can be safely deleted whilst in single user
mode, and re-added, larger, utilizing the backup additional space.

	To do this, it is recommended to first reboot. Because a swap
partition can not be unmounted after mounted with swapon(8), it can not be
deactivated to be deleted and then re-added. As such, even if one drops to
single user mode with 'shutdown now' one would not be able to unmount the
swap partition.

	Following the reboot, and boot into single user mode, one should
mount the / partition as read-write along with the /usr and /tmp
partitions. This can be accomplished by issuing the following commands:

	mount -rw /
	mount -rw /usr
	mount -rw /tmp

	Once this is done, one must re-enter the visual disklabel editor.
This is done by running '/stand/sysinstall.' From there, select the Custom
installation type, and from the menu that appears afterwards, select
"Label." If one has multiple drives, one will be next prompted to select
the drive for which to edit the disk labels. Select the appropriate disk.
Once it has been selected, focus will be shifted to the visual disklabel
editor. It may look similar to the following example if one has 256M of
unallocated space on the disk (as indicated by the top line):


                         FreeBSD Disklabel Editor

Disk: wd1       Partition name: wd1s1   Free: 524288 blocks (256MB)

Part    Mount            Size Newfs   Part    Mount            Size Newfs
----    -----            ---- -----   ----    -----            ---- -----
wd1s1a  <none>          200MB *
wd1s1b  swap            256MB SWAP
wd1s1e  <none>          500MB *
wd1s1f  <none>         1000MB *
wd1s1g  <none>         1000MB *
wd1s1h  <none>         9460MB *





The following commands are valid here (upper or lower case):
C = Create      D = Delete         M = Mount pt. W = Write
N = Newfs Opts  T = Newfs Toggle   U = Undo      Q = Finish
A = Auto Defaults for all!

Use F1 or ? to get more help, arrow keys to select.


	To delete an already existing swap partition, maneuver down to it
and hit the 'd' key to delete. Following this - continuing with the above
example - one's display would show:



                         FreeBSD Disklabel Editor

Disk: wd1       Partition name: wd1s1   Free: 1048576 blocks (512MB)

Part    Mount            Size Newfs   Part    Mount            Size Newfs
----    -----            ---- -----   ----    -----            ---- -----
wd1s1a  <none>          200MB *
wd1s1e  <none>          500MB *
wd1s1f  <none>         1000MB *
wd1s1g  <none>         1000MB *
wd1s1h  <none>         9460MB *





The following commands are valid here (upper or lower case):
C = Create      D = Delete         M = Mount pt. W = Write
N = Newfs Opts  T = Newfs Toggle   U = Undo      Q = Finish
A = Auto Defaults for all!

Use F1 or ? to get more help, arrow keys to select.

	As we see in this example, there are 512M of space now left. To
allocate this total amount to swap space, one must maneuver up to the
"Disk:" line, hit the 'c' key to create a new partition, and respond to
the first query window by hitting enter (thus accepting the total amount
of space) and then answering the following query window by indicating that
it will be a swap partition. Once this is done, one must select 'w' to
commit the new adjustment, and back up out of the Label editor first, and
then the entire program.

	Finally, when back at the command prompt, simply issuing the
'exit' command will start the init scripts and mount all filesystems in
/etc/fstab, including the new swap partition.

	2.2.2. Adding Hard Disks for Additional Swap Space

	The previous approach to adding additional swap space is the best,
although, usually not the available approach, as few people leave unused
space on the disk for just such ocassions. A modified version of this
approach is to add an additional HD, and allocate swap on it via a similar
procedure. This option is even less practical as:

	1) One may not be able to afford a second HD.
	2) It is a production server and can not be shutdown to add a
second HD. Likewise, repartitioning one's swap space on a single HD
utilizing backup, unused, space suffers from the same problem, as one must
reboot.

	However, if an additional HD is handy and this approach can be
used, /stand/sysinstall must be re-entered. Selecting the appropriate
drive when prompted after the Label Editor is selected, one can add a swap
partition in the same exact procedure as in the previous example when the
swap partition was re-added after it had been deleted. In addition, unless
the entire HD is being used for swap, additional filesystems may be
desired so that the HD can be used for additional purposes, aside from
simple swapping.

	2.2.2.1 Adding /etc/fstab Entry for Additional Swap Partitions

	To ensure that the new swap partition is loaded by the system, an
entry for it should be added in /etc/fstab. Swap partition entries in
/etc/fstab are the same as they are for a conventional filesystems except
that in the "Options" column, the option is not 'rw' but 'sw'. One can
easily copy the /etc/fstab entry for the first swap partition and simply
change the "Device" entry to correspond with the new swap partition's
device node. A quick way to discover the device node for your swap
partition is to use swapinfo(8). swapinfo(8) is also useful to observe how
much of one's swap partition(s) are in use. 

	2.3.	Using vn(4) System for Additional Swap Space

	2.3.1.	Enabling vn(4) in Kernel  

	The final option, albeit does not offer the most efficient swap
facilities, allows the extention of swap space on a running system without
rebooting granted that the vn(4) system has been enabled in the kernel. It
is suggested that the prudent administrator running one or more systems
that he/she feels will make heavy use of swap and may push the limits of
the swap partition should enable vn(4), the virtual node disk driver, in
the kernel.

	It can be easily done by adding the following line to the kernel
configuration file and then recompiling (consult
http://www.freebsd.org/handbook/kernelconfig-building.html on how to build
a custom kernel):

	pseudo-device	vn	4	#Vnode driver

	With the above line, four vn(4) disk drivers will be enabled in
the kernel, which should suffice for the vast majority of situations. Any
scenario that warrants more vn(4) disk drivers should indicate to the
administrator that a more conventional solution via adding swap partitions
should be followed instead, unless, the drivers are also intended for
"virtual" filesystems. Making heavy use of several virtual disks would
incur a high I/O overhead on both IDE and SCSI drives and may well not be
the best solution for a heavy-load system.

	If you are running FreeBSD 4.0 or higher, you will be able to load
the vn(4) driver through a kernel loadable module, using kldload(8) with
the following simple command:

	(root@nu)~># kldload vn
	(root@nu)~># kldstat
	Id Refs Address    Size     Name
	 1    3 0xc0100000 215c20   kernel
	 5    1 0xc1128000 3000     vn.ko

	This functionality in FreeBSD 4.x systems allows for even greater
flexibility as a system troubled by low swap and an administrator lacking
forsight will still be able to enable virtual node swapping without losing
uptime. 

	Device nodes for the first (/dev/vn0*) virtual node disk driver
are usually setup in the basic system installation.

(lasker@nu)~>% ls /dev/{,r}vn*                
/dev/rvn0       /dev/rvn0f      /dev/rvn0s4     /dev/vn0d       /dev/vn0s2
/dev/rvn0a      /dev/rvn0g      /dev/rvn0s5     /dev/vn0e       /dev/vn0s3
/dev/rvn0b      /dev/rvn0h      /dev/vn0        /dev/vn0f       /dev/vn0s4
/dev/rvn0c      /dev/rvn0s1     /dev/vn0a       /dev/vn0g       /dev/vn0s5
/dev/rvn0d      /dev/rvn0s2     /dev/vn0b       /dev/vn0h
/dev/rvn0e      /dev/rvn0s3     /dev/vn0c       /dev/vn0s1
(lasker@nu)~>% 

	The /dev/rvn* device nodes are for raw access of the vn(4)
drivers.

	2.3.2.	Using MAKEDEV(8) to Add vn(4) Device Entries in /dev

	If for one reason or another, device entries in /dev do not exist,
they can be easily added with the MAKEDEV(8) script in /dev. In addition,
via the same procedure, additional vn(4) device node entries (/dev/vn1*,
/dev/vn2*, etc) can be added. For instance, to add /dev/vn1* entries, the
following procedure would suffice:

(lasker@nu)~>% su
Password:
(root@nu)/home/lasker># cd /dev
(root@nu)/dev># ./MAKEDEV vn1
(root@nu)/dev># ls /dev/{,r}vn* 
/dev/rvn0       /dev/rvn0s3     /dev/rvn1h      /dev/vn0f       /dev/vn1c
/dev/rvn0a      /dev/rvn0s4     /dev/rvn1s1     /dev/vn0g       /dev/vn1d
/dev/rvn0b      /dev/rvn0s5     /dev/rvn1s2     /dev/vn0h       /dev/vn1e
/dev/rvn0c      /dev/rvn1       /dev/rvn1s3     /dev/vn0s1      /dev/vn1f
/dev/rvn0d      /dev/rvn1a      /dev/rvn1s4     /dev/vn0s2      /dev/vn1g
/dev/rvn0e      /dev/rvn1b      /dev/vn0        /dev/vn0s3      /dev/vn1h
/dev/rvn0f      /dev/rvn1c      /dev/vn0a       /dev/vn0s4      /dev/vn1s1
/dev/rvn0g      /dev/rvn1d      /dev/vn0b       /dev/vn0s5      /dev/vn1s2
/dev/rvn0h      /dev/rvn1e      /dev/vn0c       /dev/vn1        /dev/vn1s3
/dev/rvn0s1     /dev/rvn1f      /dev/vn0d       /dev/vn1a       /dev/vn1s4
/dev/rvn0s2     /dev/rvn1g      /dev/vn0e       /dev/vn1b
(root@nu)/dev># 

	Remember, device nodes can only be added by root.

	2.3.3.	Creating Swap Image File

	Once this has been accomplished the box is ready to configure any
vn(4) driver for swap or "virtual" filesystem use. This is easily
accomplished with the vnconfig(8) command. However, before one can use
vnconfig(8) to add swap, a swap image file must be created that will be
used in this capacity.

	The vn(4) system allows a file to be used as a virtual filesystem
or virtual swap partition - in short, a virtual disk. Because in both
cases virtual disks are present on top of an underlying filesytem, they
will not be as efficient as a regular filesystem or swap partition. This
is reminiscent of the swap implementation in Windows (3.11/95/98/NT)
systems. However, as mentioned earlier, it allows for a convenient
extensibility to your system without having to reboot, which is especially
practical on production servers.

	Therefore, we must first create a file that can be used by
vnconfig(8) to map to a vn(4) driver. Issuing the folowing command line
will create a 64M file in /var for vn(4) swap use:

(root@nu)/var># time dd if=/dev/zero of=/var/swap0 bs=1024 count=64000 
64000+0 records in
64000+0 records out
65536000 bytes transferred in 20.189202 secs (3246092 bytes/sec)
dd if=/dev/zero of=/var/swap0 bs=1024 count=64000  0.27s user 5.93s system
30% cpu 20.226 total
(root@nu)/var>#

	For a quick breakdown of the dd(1) usage above, the input file
("if") was /dev/zero so as to fill the swap file with zeros (having the
same effect as using the bzero() function), the output file ("of") was the
swap image itself ("/var/swap0"), the block size ("bs") was 1024 bytes,
and the number of such blocks ("count") that was copied was 64000. 64000 x
1024b = 64M. The swap image file needn't be called "swap0", but can be
named anything that the administrator desires, and it needn't be placed in
/var, either. 

(root@nu)/var># ls -l swap0
-rw-r--r--  1 root  wheel  65536000 Dec 20 09:24 swap0
(root@nu)/var># 

	The time(1) utility was used to convey the time for the file
creation. In the above example, it took a hair over 20 seconds (20.226
seconds). When using dd(1) to create the swap image file, you needn't use
time(1) unless you are curious.

	2.3.4.	Configuring vn(4) Swap Disk with vnconfig(8)

	This having been accomplished, we can now use vnconfig(8) to map
our new swap image file to a vn(4) driver:

	(root@nu)/var># vnconfig -e /dev/vn0c /var/swap0 swap

	To view the mounted swap partitions/images and their usage, the
swapinfo(8) command must be used:

(root@nu)/var># swapinfo                             
Device      1K-blocks     Used    Avail Capacity  Type
/dev/wd1s1b    262144        0   262016     0%    Interleaved
/dev/vn0c       64000        0    63872     0%    Interleaved
Total          325888        0   325888     0%
(root@nu)/var># 
 
	In the above example, neither the primary swap partition nor the
newly added swap image are in use at the moment. Glancing at the "Device"
column, we can observe the vn(4) driver that is being used for the swap
image file we configured and mounted. Under normal circumstances,
swapon(8) is used to manually add additional swap space. In the case of
configuring swap with vnconfig(8), if the -e option is used, and the
'swap' keyword is put at the end of the command line, then swapon(8) is
automatically called when the file -> vn(4) driver mapping is done by
vnconfig(8).

	2.3.5.	Using rc.conf to Mount Swap Image Files on Bootup

	Now, once that we are familiar with how to add swap image files
manually, if necessary, the easiest way to have the swap image file load
on every bootup is to use a convenient over-ride in /etc/rc.conf:

(root@nu)~># grep -B4 swap /etc/defaults/rc.conf 
##############################################################
### Important initial Boot-time options  #####################
##############################################################

swapfile="NO"           # Set to name of swapfile if aux swapfile desired.
(root@nu)~># 

	Above we see the default "swapfile" entry in
/etc/defaults/rc.conf. To have a swap image file load automatically during
bootup, simply, the following line must be added to /etc/rc.conf (using
the same example swap image file as we used previously):

swapfile="/var/swap0"	# Set to name of swapfile if aux swapfile desired.

	With this, the main FreeBSD init file, /etc/rc, will mount the
swap image file, /var/swap0. Following is a snippet from the /etc/rc
script that mounts an additional wap image file:

(root@nu)~># grep -A1 -B3 vnconfig /etc/rc 
# Add additional swapfile, if configured.
if [ "x$swapfile" != "xNO" -a -w "$swapfile" -a -b /dev/vn0b ]; then
        echo "Adding $swapfile as additional swap."
        vnconfig /dev/vn0b $swapfile && swapon /dev/vn0b
fi
(root@nu)~># 

	In the usage of vnconfig(8) in the /etc/rc script, swapon(8) is
called manually after a vanilla vnconfig(8) usage (that is, it was used
without the -e option, which implies the -c option. The -e option for
vnconfig(8) is for use when additional special options are used, such as
the keyword 'swap' for indicating the configured vn(4) image file should
be used as a virtual swap disk). With this, a user need not ever manually
run vnconfig(8) to configure a virtual swap disk, but simply specify the
file image to be used by vn(4) for swap in /etc/rc.conf. This is a quick,
simple, procedure that any novice administrator can do. The prime
disadvantage is that it only works for one additional swap image file. If
multiple additional swap image files are desired, they can be easily added
in a number of fashions such that they will be run on bootup.

	2.3.6.	Having Multiple Virtual Swap Disks Mount on Bootup

	After creating the necessary swap image files, the exact
vnconfig(8) lines needed to configure the vn(4) virtual swap disks, as
explained in section 2.3.4., may be added as-is into /etc/rc.local. That
way, they will be run during bootup and the desired virtual swap disks
will be configured and activated. Another method is to add them to a shell
script and then placing it into /usr/local/etc/rc.d. The syntax would be
the same, but as with any shell script, the file must have the user
execute bit set so that it can be run.

	3.	Apendix

	Swap / Virtual Memory Systems	

	http://www.backplane.com/FreeBSD/FreeBSDVM.txt
	"Operating System Concepts," Silberschatz & Galvin, Pages 245-249
	http://www.freebsd.org/handbook/internals-vm.html

	Recompiling the FreeBSD Kernel	

	http://www.freebsd.org/handbook/kernelconfig-building.html

Leave a Reply

Your email address will not be published. Required fields are marked *