# 作業系統概論作業三
###### tags: `OS`
## #1 Soft Link and Hard Link
以下為實驗開始前的前置指令。
```
$ touch file1.txt
$ ln file1.txt file2.txt
$ ln -s file1.txt file3.txt
```
### What are the inode values of each file?
觀察 inode:
```
$ ls -li
62757 -rw-rw-r-- 2 vagrant vagrant 0 Jan 10 08:42 file1.txt
62757 -rw-rw-r-- 2 vagrant vagrant 0 Jan 10 08:42 file2.txt
62758 lrwxrwxrwx 1 vagrant vagrant 9 Jan 10 08:42 file3.txt -> file1.txt
```
故 inode 資訊如下。
| file1.txt | file2.txt | file3.txt |
| -------- | -------- | -------- |
| 62757 | 62757 | 62758 |
### Do they have the same content?
#### 實驗一
最一開始三個檔案甫建立之時,對任一檔案內容的變動,皆會連帶更新其他兩個檔案,使三者內容保持一致。這是因為三者皆透過 link 直接或間接的指向 62757 。
#### 實驗二
現在我試著重建 file3.txt 。
```
$ rm file3.txt
$ ln -s file1.txt file3.txt
```
發現 file3.txt 仍與其它二者一致。這是因為 file3.txt 仍指向 file1.txt ,故間接指向 62757 。
#### 實驗三
現在我試著重建 file2.txt 。
```
$ rm file2.txt
$ ln file1.txt file2.txt
```
發現 file2.txt 仍與其他二者一致。這是因為 file2.txt 仍指向 62757 。
#### 實驗四
現在我試著刪除 file1.txt 。
```
$ rm file1.txt
$ ls -li
62757 -rw-rw-r-- 1 vagrant vagrant 12 Jan 10 08:47 file2.txt
62758 lrwxrwxrwx 1 vagrant vagrant 9 Jan 10 08:42 file3.txt -> !file1.txt
```
此時 file2.txt 之內容仍然保持不變,但 file3.txt 已毀損。這是因為 file2.txt 依然指向 62757 。但 file3.txt 指向已不存在的 file1.txt ,導致毀損而無法閱讀。
現在試著重建 file1.txt 。
```
$ touch file1.txt
$ ls -li
62759 -rw-rw-r-- 1 vagrant vagrant 0 Jan 10 08:59 file1.txt
62757 -rw-rw-r-- 1 vagrant vagrant 12 Jan 10 08:47 file2.txt
62758 lrwxrwxrwx 1 vagrant vagrant 9 Jan 10 08:42 file3.txt -> file1.txt
```
此時即使更改 file1.txt , file2.txt 也不會再發生改變,這是因為該兩檔案指向不同的 index node 所致。此時無論變更 file1.txt 或 file3.txt 的內容,該兩檔案都會保持一致,這是因為該兩檔案接直接或間接指向 62759 的緣故。
## #2 Creating and mounting file system
準備好一個 500MiB 的硬碟 /dev/sdb ,格式化後掛載。
```
$ mkdir -p /mnt/oshw
$ mount -t ext4 /dev/sdb /mnt/oshw
$ mkfs -t ext4 -N 800 -b 4096 /dev/sdb 1>/dev/null 2>&1
```
檢查格式化後的硬碟狀態。
```
$ fdisk -l /dev/sdb
Disk /dev/sdb: 500 MiB, 524288000 bytes, 1024000 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
$ df -iTh | egrep 'Filesystem|/dev/sdb'
Filesystem Type Inodes IUsed IFree IUse% Mounted on
/dev/sdb ext4 896 10 886 2% /mnt/oshw
$ blockdev --getbsz /dev/sdb
4096
$ mount | grep /dev/sdb
/dev/sdb on /mnt/oshw type ext4 (rw,relatime,data=ordered)
```
得知 /dev/sdb 格式化後的資訊如下:
- 格式為 ext4
- 空間為 500 MiB
- inode 數量為 896,並非剛好 800
- block size 為 4096 byte
- 掛載在 /mnt/oshw
## #3 Inode and block
### Try to create directories in this file system as many as you can. How many directories can be created in this file system? Why?
我寫了以下的 script 來大量建立目錄。
```bash
#!/bin/bash
set -e
i=0
while true; do
mkdir /mnt/oshw/$i
i=$((i+1))
done
```
然後執行此 script 。
```
$ ./script.sh
mkdir: cannot create directory ‘/mnt/oshw/886’: No space left on device
```
由此可知最多可以建立 886 個目錄。這是因為 /dev/sdb 能夠使用的 free inode 只有 886 個。
### Try to create 1-byte files in this file system as many as you can. How many 1-byte files can be created in this file system? Can it completely use all space in this file system?
實驗前使用空間僅 768 KiB 。
```
$ df
root@vagrant:~# df
Filesystem 1K-blocks Used Available Use% Mounted on
udev 472436 0 472436 0% /dev
tmpfs 100860 5388 95472 6% /run
/dev/mapper/vagrant--vg-root 64800356 1471420 60007492 3% /
tmpfs 504300 0 504300 0% /dev/shm
tmpfs 5120 0 5120 0% /run/lock
tmpfs 504300 0 504300 0% /sys/fs/cgroup
tmpfs 100860 0 100860 0% /run/user/1000
/dev/sdb 495448 768 458840 1% /mnt/oshw
```
我寫了以下的 script 來大量建立 1-byte 檔案。
```bash
#!/bin/bash
set -e
i=0
while true; do
echo -n x > /mnt/oshw/$i
i=$((i+1))
done
```
```
$ ./script.sh
./script.sh: line 6: /mnt/oshw/886: No space left on device
$ df
Filesystem 1K-blocks Used Available Use% Mounted on
udev 472436 0 472436 0% /dev
tmpfs 100860 5388 95472 6% /run
/dev/mapper/vagrant--vg-root 64800356 1471420 60007492 3% /
tmpfs 504300 0 504300 0% /dev/shm
tmpfs 5120 0 5120 0% /run/lock
tmpfs 504300 0 504300 0% /sys/fs/cgroup
tmpfs 100860 0 100860 0% /run/user/1000
/dev/sdb 495448 4312 455296 1% /mnt/oshw
```
由此可知只能建立 886 個檔案,總計 886 bytes ,並未用滿 500MiB 。這是因為 free inode 只有 886 個。此外,此操作額外佔用了 3544KiB ,這個數字剛好是 886 個 block size 。
### Try to create a file which size as large as you can. What is the maximum file size? Can it completely use all space in this file system?
實驗前,先調查環境資訊。可以得知整個 disk 有 128000 個 block ,總空間為 524288000 byte ,但可使用的 free block 只有 123670 個。
```
$ tune2fs -l /dev/sdb | egrep 'Block count|Free blocks'
Block count: 128000
Free blocks: 123670
```
使用以下指令創造一個容量極大的檔案並查看其大小。
```
$ dd if=/dev/urandom bs=4096 count=9999999999 of=file
dd: error writing 'file': No space left on device
121110+0 records in
121109+0 records out
496062464 bytes (496 MB, 473 MiB) copied, 2.66737 s, 186 MB/s
$ ls -l
total 484440
-rw-r--r-- 1 root root 496062464 Jan 10 11:46 file
```
可知單一檔案其容量極大值為 496062464 byte ,相當於 121109 個 block,並未用完整個硬碟的 524288000 byte。此時調查剩餘的 free blocks :
```
$ dumpe2fs /dev/sdb
# omit some contents for simplicity
Group 0: (Blocks 0-32767) csum 0xf414 [ITABLE_ZEROED]
Primary superblock at 0, Group descriptors at 1-1
Reserved GDT blocks at 2-63
Block bitmap at 64 (+64), csum 0xf379cdeb
Inode bitmap at 68 (+68), csum 0xab90ebcc
Inode table at 72-78 (+72)
0 free blocks, 213 free inodes, 1 directories
Free blocks:
Free inodes: 12-224
Group 1: (Blocks 32768-65535) csum 0x3e45 [ITABLE_ZEROED]
Backup superblock at 32768, Group descriptors at 32769-32769
Reserved GDT blocks at 32770-32831
Block bitmap at 65 (bg #0 + 65), csum 0xb17db9a7
Inode bitmap at 69 (bg #0 + 69), csum 0x60dc68d1
Inode table at 79-85 (bg #0 + 79)
2560 free blocks, 224 free inodes, 0 directories
Free blocks: 35435-35668, 35818-36863, 63488-64767
Free inodes: 225-448
Group 2: (Blocks 65536-98303) csum 0x7bbc [ITABLE_ZEROED]
Block bitmap at 66 (bg #0 + 66), csum 0xf379cdeb
Inode bitmap at 70 (bg #0 + 70), csum 0x60dc68d1
Inode table at 86-92 (bg #0 + 86)
0 free blocks, 224 free inodes, 0 directories
Free blocks:
Free inodes: 449-672
Group 3: (Blocks 98304-127999) csum 0x3023 [ITABLE_ZEROED]
Backup superblock at 98304, Group descriptors at 98305-98305
Reserved GDT blocks at 98306-98367
Block bitmap at 67 (bg #0 + 67), csum 0xf379cdeb
Inode bitmap at 71 (bg #0 + 71), csum 0x60dc68d1
Inode table at 93-99 (bg #0 + 93)
0 free blocks, 224 free inodes, 0 directories
Free blocks:
Free inodes: 673-896
```
發現剩餘 2560 個 free block ,這些空間可能有額外的保留用途。實際上整個硬碟已被使用的空間為 (byte): $$(123670 - 2560) \times 4096 = 496066560$$
剛剛建立的大檔案其實只占用 496062464 byte ,距離 496066560 byte 剛好差一個 block 的空間。事實上此 block 是被掛載點 /mnt/oshw 這個目錄拿去用了, `Group 0` 區塊所顯示的 `1 directories` 即是指 /mnt/oshw。