2019年7月26日 星期五

Androidx migration build fail

markdown 把一個專案從 support library 升級到 androidx 的時候 build fail,Android Studio 給出的 error message 就是
Program type already present: android.support.v4.os.ResultReceiver$1
Google 找到的好像都是說 dependency 沒有轉換乾淨,例如可能有第三方 library 還在依賴 support library,但是我的專案沒有用到第三方 library 而且確定所有依賴都是 androidx。 最後想到會不會是 build tool 版本太低導致,於是把 com.android.tools.build:gradle 從 3.1.3 升級到 3.2.1,gradle version 從 4.4 升級到 4.6,build 就成功了。 搞不懂 build tool 版本問題為什麼會跑出這個錯誤訊息,不過也不想去深究,反正 android build 總是很容易遇到奇奇怪怪的問題,只是要注意要開始導入新東西時,build tool 最好要用新一點的版本。

2019年7月1日 星期一

Block Size 與 Direct IO

markdown 在使用 direct IO 的時候,讀取/寫入的大小、buffer 的起始位置與檔案操作的 offset 需要是某個數值的整數倍,在 linux 2.4 之前,這個數值是 filesystem 的 logical block size,通常是 4K,在 linux 2.6 之後,這個數值是 device physical block size (device sector size),通常是 512 bytes。 block 在不同的語境可能會有不同的意思,容易造成混淆,在這邊解釋一下這兩個名詞的意思。 ### physical block 表示 device 本身一次能夠操作的最小單位,也有可能叫 device sector 或是 physical sector。 ### logical block 這個概念存在 linux filesystem 中,是 linux 一次 device 操作的最小單元,有時候叫 filesystem block、data block 或是直接就叫 block,logical block size 必須是 physical block size 的整數倍。 ### Advanced Format 原本 physical block size 幾乎都是 512 bytes,然而為了日漸增加的大檔需求,有些製造商推出了 4K physical block size 的儲存裝置。但不是所有 OS 與軟體都支援 4K physical block size,所以儲存裝置內的 firmware 支援一種功能,就是可以 export 出 512 bytes 的 "logical sector size" 給 linux (稱為 512e 格式),然後 firmware 內部將非 4K 對齊的 IO 操作轉換為 4K IO 操作。 若是 firmware 不使用模擬 512 bytes 模式而使用原生 4K,則稱為 4K native device,不過這要作業系統跟系統上軟體也支援才行,否則可能會遇到奇奇怪怪的問題。而 512e 與 4K native 這些新的格式與概念就是 [Advanced Format](http://idema.org/?page_id=2153) 在 512e 格式下出現的 logical sector size 與先前提到的 logical block 很容易造成混淆,在這裡我認為這兩個講的不是同一件事,一個是存在 linux filesystem 的概念,一個是存在儲存裝置內的概念,對於 512e 格式的儲存裝置,從 linux 系統的角度來看,裝置的 physical block size 是 512 bytes 的,雖然它實際上是 4K。 那對新式 4K physical block size 的儲存裝置,direct IO 要怎麼對齊?在 512e 格式的系統上,需對齊 512 bytes,但在 native 4K 的系統上,則需對齊 4K。要對齊哪個數字,可以經由查詢系統上的 logical sector size (不是 filesystem 的 logical block size) 得到,例如用 [ioctl](http://man7.org/linux/man-pages/man2/ioctl.2.html) 傳參數 BLKSSZGET。 當然查詢 physical block size 然後對齊它我覺得也是可以的,不過網路上的範例似乎都是查詢 logical block size 來作對齊,可能是因為這樣在 512e 裝置上可以對齊 512 bytes,對於對齊來說數字越小是越容易做到的。 *** Reference: * [Logical Block Size](https://docs.oracle.com/cd/E19455-01/805-7228/fsfilesysappx-9/index.html) * [I/O Limits: block sizes, alignment and I/O hints](https://people.redhat.com/msnitzer/docs/io-limits.txt) * [Support statement for 512e and 4K Native drives for VMware vSphere and vSAN](https://kb.vmware.com/s/article/2091600) * [Linux and 4K disk sectors](https://lwn.net/Articles/322777/) * [4K-sector drives and Linux](https://lwn.net/Articles/377895/) * [Linux on 4KB-sector disks: Practical advice](https://developer.ibm.com/tutorials/l-4kb-sector-disks/)