linux2020
目的: 檢驗學員對 Linux 記憶體管理、POSIX shared memory, POSIX semaphore 和 split/epoll 系統呼叫的認知
1
考慮一個使用 POSIX shared memory 和 semaphore 開發的 key-value store 實作,測試程式碼:
參考執行輸出:
原始程式碼可見 kv.c。
這份實作應該能在 multi-process 和 multi-thread 環境運作。
請補完上述 kv.c
程式碼。
作答區
AAA = ?
(a)
open
(b)
shm_open
BBB = ?
(a)
store->clients
(b)
store->clients++
(c)
++store->clients
(d)
store->clients--
(e)
--store->clients
CCC = ?
(a)
0(b)
cache_idx
(c)
cache_idx++
(d)
cache_idx--
DDD = ?
(a)
0(b)
cache_idx
(c)
cache_idx++
(d)
cache_idx--
延伸問題:
2
以下程式碼嘗試透過 epoll 和 splice 系統呼叫,實作出具體而微的 Port forwarding。考慮一個情境:我們對外有一台防火牆,在 DNS 設定方面,我們設定 ftp.mydomain.com
及 www.mydomain.com
都指向這台防火牆。但我們希望所有 HTTP 連線都重新導向到內部的 192.168.0.2
這台機器上,而所有 FTP 連線都交由 192.168.0.3
來處理。這時候我們就可以使用 port forwarding 的方式來達成。對應的 NAT (Network Address Translation) 的設定如下:
第一行的目的就是將 port 80 的 tcp 連線重新導向到 192.168.0.2
的 port 80,而第 2 和第 3 行是將 port 20 及 port 21 的連線交由 192.168.0.3
來處理。在 192.168.0.2
及 192.168.0.3
這二台機器上,我們只要設定它們的 gateway 為防火牆的 IP,例如 192.168.0.1
即可。
使用 splice 系統呼叫,我們有機會在網路介面控制器的支援下,達到 Zero-copy 資料傳輸。
原始程式碼可見 proxy.c,其 list.h
取自 list.h,改寫自 Linux 核心原始程式碼。
假設本地機器系統 port 80 已有網頁伺服器在等待連線。proxy
的測試方式為
等程式執行後,在另一個終端機畫面中輸入下列命令:
接著你就可以輸入 HTTP 請求字串,如 GET /index.html
。
此外,你還可以把 port 8082 轉向到 Google 首頁:
先找出 www.google.com
的 IP 地址:
得到以下輸出:
修改上述命令:
重複上述 telnet
命令,這時候就會看到 Google 首頁的字串。
請補完程式碼。
作答區
EEE = ?
(a)
num_events
(b)
num_events++
(c)
num_events--
(d)
++num_events
(e)
--num_events
FFF = ?
(a)
不需要加入程式碼(b)
buf->bytes += n
(c)
buf->bytes -= n
(d)
buf->bytes--
(e)
buf->bytes++
延伸問題: