Making a Filesystem Inside a File
Goal
Create a real ext4 filesystem on an ordinary file, then read and adjust the superblock and look at the contents. At the end, write the fstab line that mounts that filesystem, using the UUID.
Why it matters
mkfs does not distinguish whether the target is a block device or an ordinary file. It just writes the defined structure. Thanks to this property, you can learn the internals of a filesystem without privileges, and in practice it is common to create and inspect image files. In particular, the fact that the number of inodes is fixed at format time and cannot be increased later, and how wasteful the default 5% reserved blocks are on a large disk, only sink in when you see the numbers.
This environment has no mount permission, so you do not actually attach it. Instead, what is graded is writing the fstab accurately — in the field, too, incidents come not from the mount command but from one fstab line.
Steps
- Create the
/root/diskdirectory and create/root/disk/lab.imgas a 256MiB sparse file. Then write the logical size and the actual occupied size, one per line, in/root/disk/sparse.txt(in bytes, logical size first). - Format that file as ext4 with the label
LABHUB. - Write only the filesystem UUID, on one line, in
/root/disk/uuid.txt. - Extract the three values block size / inode count / reserved block count from the superblock and write them in
/root/disk/super.txtin the following format.BLOCK_SIZE=<값>/INODE_COUNT=<값>/RESERVED_BLOCKS=<값>(each placeholder stands for the value you read from the superblock) - Lower the reserved block ratio to 1%, and write the reserved block count after the change, as a single number on one line, in
/root/disk/reserved-after.txt. It must be smaller than the value from step 4. - With
debugfs, create adatadirectory at the image root and save the root listing to/root/disk/rootls.txt. Bothlost+foundanddatamust be in the listing. - In
/root/disk/fstab.line, write one line of fstab that mounts this filesystem at/mnt/labdata. The device must useUUID=notation, the type must beext4, the options must include all ofdefaults,noatime, andnofail, dump must be0, and pass must be2. - Create
/root/disk/report.txtwith the following 5 lines.LABEL=LABHUB/UUID=<3번 값>/BLOCK_SIZE=<4번 값>/INODE_COUNT=<4번 값>/MOUNTPOINT=/mnt/labdata(the placeholders are the values from step 3 and step 4)
Notes
- The order is
truncate -s 256M <파일>,mkfs.ext4 -F -L LABHUB <파일>,blkid <파일>,dumpe2fs -h <파일>,tune2fs -m 1 <파일>(replace each placeholder with the image file path). - The actual occupied size comes from
du -B1 <파일>, and the logical size fromdu -B1 --apparent-size <파일>orstat -c %s. - Use
debugfs -w -R 'mkdir /data' <파일>for write operations anddebugfs -R 'ls -l /' <파일>for listing. - Common mistake 1: not being able to get past the "not a block special device" prompt of
mkfs.ext4without-F. - Common mistake 2: putting quotation marks around the UUID value in step 7. Do not use quotation marks in fstab.
Create a sparse image file
Create the /root/disk directory and create /root/disk/lab.img as a 256MiB sparse file. Then write the logical size and the actual occupied size, one per line, in /root/disk/sparse.txt (in bytes, logical size first).
truncate only specifies the size without allocating actual blocks. Compare the two kinds of size that du reports.
Format as ext4
Format that file as ext4 with the label LABHUB.
If you get a warning that it is not a block device, you need the force option. Use the option that specifies the label as well.
Extract the UUID
Write only the filesystem UUID, on one line, in /root/disk/uuid.txt.
blkid works on files too. To extract only the UUID value from the output, use a format option or string processing.
Read the superblock
Extract the three values block size / inode count / reserved block count from the superblock and write them in /root/disk/super.txt in the following format.
BLOCK_SIZE=<값> / INODE_COUNT=<값> / RESERVED_BLOCKS=<값> (each placeholder stands for the value you read from the superblock)
The -h of dumpe2fs prints only the superblock information. Think about what each of the three values means.
Change the reserved block ratio
Lower the reserved block ratio to 1%, and write the reserved block count after the change, as a single number on one line, in /root/disk/reserved-after.txt. It must be smaller than the value from step 4.
The -m of tune2fs is specified in percent. After the change, check again with dumpe2fs.
Look inside the image
With debugfs, create a data directory at the image root and save the root listing to /root/disk/rootls.txt. Both lost+found and data must be in the listing.
debugfs runs one command with -R. Write operations need a separate option.
Write the fstab line
In /root/disk/fstab.line, write one line of fstab that mounts this filesystem at /mnt/labdata. The device must use UUID= notation, the type must be ext4, the options must include all of defaults, noatime, and nofail, dump must be 0, and pass must be 2.
Separate the six fields with whitespace. Write the device in UUID= notation, and three options must be in the options field.
Image summary report
Create /root/disk/report.txt with the following 5 lines.
LABEL=LABHUB / UUID=<3번 값> / BLOCK_SIZE=<4번 값> / INODE_COUNT=<4번 값> / MOUNTPOINT=/mnt/labdata (the placeholders are the values from step 3 and step 4)
Just gather the values you extracted in the earlier steps as key=value. Write numbers without units.