---
# System prepended metadata

title: 作業系統概論作業三
tags: [OS]

---

# 作業系統概論作業三
###### 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。



