wiki:TechnicalDetails

Technical details

Code

Swapspace is not meant to be portable. It runs on GNU systems with Linux kernel 2.4 or 2.6, and probably the old development series 2.5 as well. By far the most expansive testing has taken place on Linux 2.6.

The program is written in C99, the current ISO standard for the C language. The Makefile assumes gcc as a compiler, which currently defaults to the older C89 standard, but adds options to use C99 instead. The first thing you'll probably notice about the dialect is that "" is used to introduce end-of-line comments, as in C++. This was not permitted in standard C89 but is a valid part of C99.

One extension out of POSIX is used for signal handling. This is why extensions to the pure C99 language are enabled. Otherwise, everything should compile as pure standard C99.

Installation

The installation procedure creates a directory /var/lib/swapspace, which must be accessible to the system's superuser (root) only; granting any kind of access for this directory to an untrusted user is likely to constitute a serious security hole.

According to the Filesystem Hierarchy Standard, other appropriate places for this kind of file might be /var/tmp or /var/run. The former was not deemed appropriate because it is accessible to all users, and the latter because most system administrators would probably expect it to occupy very little space and may confine it to a partition that isn't large enough to hold useful swap space.

Also, files in /var/lib survive reboots whereas those in /var/tmp and /var/run need not. Obviously any data in swap files can be safely erased on reboot (it's even tempting to think that that would be safer, though I don't think it really is). But consider a system consistently short on physical memory: during boot, swapspace will see the swapfiles left by the previous session, and reinstate them immediately at very little cost, ready for use when they are needed. If they had been erased during reboot, swapspace would have to allocate new ones on disk when it recognized the need for more virtual memory, which takes much more time and resources.

Algorithm

Choices of allocation and deallocation are driven by a "finite state machine" consisting of four states: steady, hungry, overfed, and diet. The program will alternate through these states as circumstances dictate, applying different policies depending on current state. This was done to achieve a good tradeoff between willingness to free up unused swap space on the one hand, and avoidance of "thrashing" between deallocation and re-allocation of swapfiles on the other.

http://pqxx.org/dev-graphics/swapspace/fsm.png

For those interested, here is a quick description of these states and their associated policies:

Steady normal operation; no additional swap space is needed, nor do we have more than is needed. However, the program can go into the hungry or overfed states at the drop of a hat.
Hungry more swap space was recently allocated. The program is willing to allocate even more if needed, but it will not consider dropping unneeded swap files. After a certain timeout period, the program reverts to the steady state.
Overfed significantly more virtual memory is available than is needed. If this situation persists for a certain timeout period, a swapfile is deallocated and the program returns to the steady state.
Diet a recent allocation attempt has run into resource limits, e.g. because the filesystem used for swap files was full. No more swapspace can be allocated but excess files can be freed up very rapidly. Afer timeout, reverts to steady.

State information can be queried by sending the program the SIGUSR1 signal (see "man 7 signal" to get the number for your architecture) which will cause it to log debug information to the system's daemon log and/or standard output, as appropriate. The program can also be made to log state transitions by starting it with the -v or --verbose option.

Last modified 9 years ago Last modified on Apr 19, 2008, 4:47:41 AM