Reading and Designing the Mount Tree
Goal
Read /proc/self/mountinfo yourself to understand the mount tree and propagation types, and write a bind mount and a tmpfs in two formats, fstab and a systemd unit.
Why it matters
The reason mounts have become hard in the container era is mount namespaces and propagation. A volume attached on the host being invisible in the container, or a mount remaining and holding the disk after you delete the container, all come from here. And that information is not in the output of the mount command; it is only in the optional fields of /proc/self/mountinfo. There is a big difference between being able to read this file and not.
This lab runs on an Ubuntu 24.04 VM. So you actually mount the .mount unit you wrote in step 7 with systemctl start — you learn that systemd rejects a unit whose name differs from the path by even one character, not by memorizing the rule but by being rejected. It used to run in a Pod, which had no mount permission, and reading and design were all you could do.
Steps
- Create the
/root/mntdirectory, extract the three values마운트지점 타입 옵션(mount point, type, and options, in that order) from each line of/proc/self/mountinfo, separate them with spaces, and save them as/root/mnt/parsed.txt. It must have at least 5 lines and must include/proc. - Print the current mounts with
findmntin the타깃,소스,타입format (target, source, type) and save them as/root/mnt/findmnt.txt. - Select only the mounts whose type is
tmpfsand save them as/root/mnt/tmpfs.txt. It must have at least 1 line. - Determine the propagation type of each mount and save it in
/root/mnt/propagation.txtin the format마운트지점 <shared|slave|private>(the mount point followed by its propagation type). It must have at least 5 lines. - In
/root/mnt/bind.fstab, write the following bind mount line as one line. The source is/srv/data, the target is/var/www/data, the type isnone, the options includebindandro, dump is0, and pass is0. - In
/root/mnt/tmpfs.fstab, write the following tmpfs line as one line. The mount point is/var/cache/app, the type istmpfs, the options include all ofsize=256M,mode=1777,noexec,nosuid, andnodev, dump is0, and pass is0. - Write the same content as in step 6 as a systemd unit as well. The file name must be the exact name obtained by escaping the mount point, and you put it under
/root/mnt/. It must have the three sections[Unit],[Mount], and[Install], and[Mount]must have the four keysWhat,Where,Type, andOptions. - Create
/root/mnt/design.txtwith the following 4 lines.MOUNTS=<1번 파일의 줄 수>/TMPFS=<3번 파일의 줄 수>/BIND_TARGET=/var/www/data/UNIT=<7번에서 만든 파일 이름(경로 제외)>(the placeholders are the line count of the file from step 1, the line count of the file from step 3, and the name, without the path, of the file you created in step 7)
Notes
- In mountinfo, the number of fields before and after the single hyphen (
-) boundary differs. The mount point is the 5th field, and the type is the first field after the hyphen. - You can extract only the columns you want in the form
findmnt -n -o TARGET,SOURCE,FSTYPE. - You can get the unit name with
systemd-escape --path --suffix=mount /var/cache/app. If the tool is not available, apply the rule yourself (remove the leading slash, turn the remaining slashes into hyphens). - Common mistake 1: in step 1, the number of optional fields varies from line to line, so awk's fixed column numbers go out of line. Find the hyphen position first.
- Common mistake 2: making up the unit name in step 7. systemd rejects the unit if the name differs from the path.
Parse mountinfo
Create the /root/mnt directory, extract the three values 마운트지점 타입 옵션 (mount point, type, and options, in that order) from each line of /proc/self/mountinfo, separate them with spaces, and save them as /root/mnt/parsed.txt. It must have at least 5 lines and must include /proc.
The field separator is whitespace, and in the middle there are optional fields whose number varies. A single hyphen is the boundary.
View with findmnt
Print the current mounts with findmnt in the 타깃,소스,타입 format (target, source, type) and save them as /root/mnt/findmnt.txt.
findmnt is a tool that reads /proc, so it works without privileges. There is an option that specifies the output format.
Pick out only the tmpfs mounts
Select only the mounts whose type is tmpfs and save them as /root/mnt/tmpfs.txt. It must have at least 1 line.
Filter for only those whose type is tmpfs. Notice which ones have a size option and which do not.
Build the propagation table
Determine the propagation type of each mount and save it in /root/mnt/propagation.txt in the format 마운트지점 <shared|slave|private> (the mount point followed by its propagation type). It must have at least 5 lines.
If the optional fields have shared: or master:, it is shared or slave, respectively. If there is nothing, it is private.
Bind mount fstab line
In /root/mnt/bind.fstab, write the following bind mount line as one line. The source is /srv/data, the target is /var/www/data, the type is none, the options include bind and ro, dump is 0, and pass is 0.
The type field of a bind mount is none, and bind goes in the options. You can specify read-only at the same time.
tmpfs fstab line
In /root/mnt/tmpfs.fstab, write the following tmpfs line as one line. The mount point is /var/cache/app, the type is tmpfs, the options include all of size=256M, mode=1777, noexec, nosuid, and nodev, dump is 0, and pass is 0.
Write tmpfs in the device position. Always specify the size, and include the three security options as well.
The .mount unit file
Write the same content as in step 6 as a systemd unit as well. The file name must be the exact name obtained by escaping the mount point, and you put it under /root/mnt/. It must have the three sections [Unit], [Mount], and [Install], and [Mount] must have the four keys What, Where, Type, and Options.
The unit name must be the mount point path, escaped. You can get the exact name with systemd-escape.
Mount design document
Create /root/mnt/design.txt with the following 4 lines.
MOUNTS=<1번 파일의 줄 수> / TMPFS=<3번 파일의 줄 수> / BIND_TARGET=/var/www/data / UNIT=<7번에서 만든 파일 이름(경로 제외)> (the placeholders are the line count of the file from step 1, the line count of the file from step 3, and the name, without the path, of the file you created in step 7)
Take the values from the files you created in the earlier steps. Counting lines is enough for the counts.