CISS-150 Project 6 (10 points)
(Updated November 18, 2023)
Overview
The Ubuntu VM provided to you has no swap/paging space. Examination through the use of free
and top
will reveal this.
Ubuntu 17.04 and later allows the use of a file in the standard filesystem to provide the storage needed for paging space. You will go through a series of steps to create the paging space, confirm the system will use it, make it permanent, and confirm that it survives reboots.
Learning outcomes
- Planning and design.
- Modifying OS memory management resources.
- Understanding swap/paging space.
- Understanding
/etc/fstab
.
Before you proceed, it is STRONGLY recommended that you gracefully shut down the Ubuntu VM and take a snapshot.
Remember that the snapshot will allow you to revert to a known good state. These are complex and detailed steps. If you make a mistake, you will want a way to recover and start fresh.
TAKE A SNAPSHOT NOW!
Getting Started
Swap space (also called paging space since physical memory pages are written to disk) is an extension of physical memory. However, for a program to run, it must be in physical memory. Swap space does not mean you have more memory to run programs; it means you have a place to put running program data and code to get it out of the way so other work can be done.
Your Ubuntu system is intentionally lacking swap space. The first step is to confirm there is no swap space.
student@student-vm:~$ sudo -i
[sudo] password for student:
root@student-vm:~# swapon --show
root@student-vm:~# free
total used free shared buff/cache available
Mem: 3036072 737268 1675676 7600 623128 2121536
Swap: 0 0 0
root@student-vm:~#
Note that we became the root user, so all the commands are run as root.
Now we will create a 2GB dis file in the root directory for use as swap space
root@student-vm:~# fallocate -l 2G /swapfile
root@student-vm:~# ll /swapfile
-rw-r--r-- 1 root root 2147483648 Dec 29 15:11 /swapfile
root@student-vm:~#
Configuring Swap Space
Now that we have the file in place, there are a few tweaks that are necessary to use it as a swap space. The first is to set the permissions correctly, then we need to format the file for use as swap space.
First the file permissions must be set such that only the root user can write to it.
root@student-vm:~# chmod 600 /swapfile
Now we format the space as a swap file.
root@student-vm:~# mkswap /swapfile
Setting up swapspace version 1, size = 2 GiB (2147479552 bytes)
no label, UUID=fd567bb2-abe0-4093-8b96-9b3be2d4ce0e
At this point, we can try turning on the swap space.
root@student-vm:~# swapon /swapfile
root@student-vm:~# swapon --show
NAME TYPE SIZE USED PRIO
/swapfile file 2G 0B -2
Recall that earlier, we saw no swap space available when we used free to report all available memory. Running it again after the swap space has been activated will reveal that it has changed.
root@student-vm:~# free
total used free shared buff/cache available
Mem: 3036072 1079940 1059240 58336 896892 1725384
Swap: 2097148 0 2097148
root@student-vm:~#
Adding Persistence
The /etc/fstab
file is the text file that defines all available filesystems within the OS. It will look something like the following:
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
#
/dev/mapper/vgubuntu-root / ext4 errors=remount-ro 0 1
# /boot/efi was on /dev/sda1 during installation
UUID=B587-A388 /boot/efi vfat umask=0077 0 1
There are six fields separated by whitespace. For more information on the fields themselves, you can run
root@student-vm:~# man fstab
This file maintains information about storage that needs to be available at boot time. Part of the boot process is to mount known filesystems so that the files and directories they contain will be available to the rest of the OS, software packages, and users of the system.
Before we go any further, we will make a backup copy of the /etc/fstab
file:
root@student-vm:~# cp /etc/fstab /etc/fstab.orig
root@student-vm:~# ll /etc/fstab*
-rw-rw-r-- 1 root root 543 Dec 29 15:45 /etc/fstab
-rw-r--r-- 1 root root 543 Dec 29 15:50 /etc/fstab.orig
root@student-vm:~#
This way if we mess up when we do the confirmation later, we can go back without losing all of your work.
Using your editor of choice (nano
, gedit
, vi
, etc.) add the line at the bottom of the file /etc/fstab
.
/swapfile none swap sw 0 0
All is not lost, however. You have already made a snapshot, so you have a rollback point. You also have a copy of the fstab
file in its original form. You also can contact your instructor for additional help before you revert the snapshot and lose all the work you have done.
You can also run something like the following:
root@student-vm:~# echo "/swapfile none swap sw 0 0" | tee -a /etc/fstab
root@student-vm:~# cat /etc/fstab
The file will now look like the following:
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
#
/dev/mapper/vgubuntu-root / ext4 errors=remount-ro 0 1
# /boot/efi was on /dev/sda1 during installation
UUID=B587-A388 /boot/efi vfat umask=0077 0 1
/swapfile none swap sw 0 0
If your file looks drastically different, DO NOT REBOOT! Perform the recovery procedure below and try again.
If all looks good, then go ahead and reboot. When the system is back up, log in and check the swap status and free memory to confirm the swap is persistent across boots.
Recovery
If your resultant file does not look like the original plus the new line, you can recover the file with the following:
root@student-vm:~# cp /etc/fstab.orig /etc/fstab
If all copies of the /etc/fstab
file are wrong, contact your instructor before reverting the snapshot. They will advise you on the next steps.
Further Study
You have been assigned readings regarding swap and paging space. Be sure to review those for a deeper understanding of the purposes and limitations of swap space.
There is also an excellent guide in the Ubuntu SwapFaq.
In addition read the complete virtual memory details of OSTEP-Chapter 23.
Open a second terminal window, run top
, and place the window conspicuously so you can watch the data change. Make a note of the amount of memory used
, free
, and buff/cache
. Also, make a note of the amount of swap space used.
Experiment with the following code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
// 1 GB
#define SIZE 1024*1024*1024
int main(int argc, char **argv) {
void *ptr;
char s[5];
ptr = calloc(SIZE, sizeof(char));
if ( ptr ) {
memset(ptr, 'A', SIZE);
printf("1GB allocated (%p). Press ENTER to release.\n", ptr);
} else
printf("An error occurred (%d). Press ENTER.\n", errno);
fgets(s, 4, stdin);
}
Save it as mem.c
and perform the following:
root@student-vm:~# gcc -o mem mem.c
Now, before you run the program, consider this: The use of calloc()
forces the initialization of the memory block to zero. However, modern Linuxes already zero the pages, so the pages do not get mapped and perform this allocation in a lazy way similar to malloc()
. As a result, we have to use memset()
to force the pages to be mapped.
top
running in the other terminal window.root@student-vm:~# ./mem
2GB allocated. Press ENTER to release.
root@student-vm:~#
It will be obvious that memory values change in top
. Since we are using calloc()
and memset()
, the memory pages must be touched in order to set them to zero.
Two things to note about Linux is
- It is a demand-paging system.
- Memory allocation defaults to lazy allocation.
Regarding #1, demand-paging is basically only mapping pages to a process’ page table when they are actually touched. See TLDP’s documentation memory management. Specifically 3.1, 3.1.1, 3.1.2, 3.2, 3.4, 3.6, 3.8.
Regarding #2, since malloc()
explicitly states it does not initialize the memory, then it simply hands back a pointer to memory that is in use from the heap’s perspective, but not allocated by the kernel since the pages have not yet been touched.
Now, this means that the system is allowed to overcommit memory resources. This allows the system to maintain a high level of multiprogramming since it is playing the odds that not all of the programs will actually use all of the memory they have requested. This is a logical approach to resource management and has been applied to many areas of computing, especially networking (i.e., a switch with 48-1Gb port and a 10Gb uplink. This is overcommitted 4.8 to 1.)
There are a couple of values in the Linux system that manage memory overcommit. There are noted here.
root@student-vm:~# cat /proc/sys/vm/overcommit_memory
0
root@student-vm:~# cat /proc/sys/vm/overcommit_ratio
50
root@student-vm:~#
Details of how the three different values of vm.overcommit_memory
are defined at the Kernel website.