ChromebookでSDカードのテスト(性能、セクタ検証)

ChromebookでSDカードのテストをしてみた。

  • ASUS Chromebook C101P
  • Samsung MicroSDXC 128GB EVO Plus (Read 100MB/s、Write 90MBs) Amazon並行輸入品(Amazon配送) (fdiskによると119.2GB)

  • ファイルシステム性能1(ExFAT) Nintendo Switchで使った上、フォーマットせずに、スロットに挿して自動認識させる。 fuse-exfatでマウントと表示される。 ユーザ空間プロセス経由でのI/Oだと思われる。 ddで書き込みテスト(1MB単位、オールゼロデータ(/dev/zero)) →約15MB/s。

  • ファイルシステム性能2(ExFAT、Crostini) 上記のマウントされた状態で、Linuxオプション(Crostini)からアクセス。 9pでマウントと表示される。 仮想ホスト・ゲスト間の9pプロトコル通信によるアクセスと思われる。 ddで書き込みテスト(1MB単位、オールゼロデータ(/dev/zero)) →約5Mb/s。

  • ブロックセクタ検証性能 (CrostiniゲストLinuxオプションでなくホストで)アンマウントしてbadblocksでテスト(デフォルト操作。読み込みのみ、1KB単位。) →約25MB/s。

  • ブロック読み取り性能 (ホストから、かつ、ファイルシステムは経由せず)ブロックデバイスを直接リード。 ddコマンドで1MB単位×1000回。 →約70MB/s。

カードスロット+ドライバ経由の性能だと、メモリカードの公式性能100MB/sの7割ぐらいの性能。

Chromebook 標準以外の仮想マシン作成

Chromebook仮想マシンを制御するコマンド「vmc」に「create」サブコマンドが追加された。devチャンネルで使用できる。(ChromeOS v77)

引数にインストールメディア(ISOイメージ)に加え、リムーバブルメディアも指定できる。 引数を指定しない場合、標準の仮想マシンである「termina」が(もうひとつ)インストールされた。 rootイメージ(2GB)は共有するようだが、追加のファイルシステムは個別に作成される模様。 termina以外のVMを作るのは「plugin VM作成」という処理らしいが現状は未サポートのようだ。

localhost # vmc 
USAGE: vmc
   [ start [--enable-gpu] <name> |
     stop <name> |
     create [-p] <name> [<source media> [<removable storage name>]] [-- additional parameters]
     destroy <name> |
     disk-op-status <command UUID> |
     export <vm name> <file name> [<removable storage name>] |
     import [-p] <vm name> <file name> [<removable storage name>] |
     list |
     share <vm name> <path> |
     unshare <vm name> <path> |
     container <vm name> <container name> [ <image server> <image alias> ]  |
     usb-attach <vm name> <bus>:<device> |
     usb-detach <vm name> <port> |
     usb-list <vm name> |
     help ]


localhost# vmc  create -p newvm aaa bbb
Error: routine at frontends/vmc.rs:193 `vm_create(vm_name,user_id_hash,plugin_vm,file_name,removable_media,params)` failed: Plugin VMs are currently disabled

localhost# vmc create newvm aaa bbb
Error: routine at frontends/vmc.rs:193 `vm_create(vm_name,user_id_hash,plugin_vm,file_name,removable_media,params)` failed: source media path does not exist

localhost ~ # vmc create termina2

localhost ~ # vmc list
termina (7002292224 bytes)
termina2 (5286006784 bytes)
Total Size (bytes): 12288299008

localhost# cd /home/root/*/crosvm

localhost# ls -lh *.img
-rw-------. 1 crosvm crosvm 6.6G Jul 16 14:50 'dGVybWluYQ==.img'
-rw-------. 1 crosvm crosvm 5.0G Jul 26 19:36 'dGVybWluYTI=.img'

localhost# du -sh *.img
1.5G    dGVybWluYQ==.img
4.0K    dGVybWluYTI=.img

Chromebook LinuxからSDカードやUSBメモリを使う方法

今のところ、9p共有ファイルシステム経由でしか使えない模様。 ためしに、100MBのファイルをddで作ってみたところ、4MB/s。遅い。。。

  • 標準VMのterminaは決め打ちでディスク一個しか使わない。
  • terminaの中ではrootで動けず、loopデバイスもなく、コンテナのストレージ設定でごまかす手段がない。(見つからない)
  • ついでにpenguinコンテナではrootになれるが、なんちゃってrootでありtermina的には一般ユーザでしかない。
  • vmcコマンドの最新ソースによるとcreateサブコマンドがあり、ディスクイメージファイルだけでなくリムーバブルメディア指定も可能のようだ。が、まだChromeOSのDEVチャネルにも来ていない。これが本命かな。
  • linuxからのUSB直接アクセスサポートはまだちゃんと動かない。権限エラーとなる。

なお、vmcコマンドにcreateサブコマンドが追加(コミット)されたのはついこないだの7/3。

vm_tools: crostini_client: implement "create" command

This allows creating new Plugin VM instances and attaching an
installation media to them:

    vmc create -p VmName install.iso -- more args

Chromebook vmcコマンドを普通のshellから使う

Chromebookの開発者モードだと、croshではなく普通のシェルが使える。(croshからshellコマンドを実行) この、通常シェル(開発者シェルというべきか)からは、croshではでなきない通常のlinuxコマンド実行などが行えるが、vmcコマンドはエラーになる。

localhost / # vmc list
Error: expected CROS_USER_ID_HASH environment variable

Chromebook仮想マシンを制御するvmcコマンドは、croshという制限つきシェルから使うのが普通らしい。 ただし,以下をやれば通常シェルでも可能だった。

localhost / # export CROS_USER_ID_HASH=`echo /home/user/*|sed 's@^.*/@@'` 

localhost / # vmc list
termina (7002292224 bytes)
Total Size (bytes): 7002292224

ChromebookのLinux仮想マシンの起動方法を探す

ChromebookLinux仮想マシン(crostini)からMicroSDカードの内容が使いづらいので模索。

Linux仮想マシンからはChromeOSホストの内容にアクセスできるように、ネットワークファイル共有(9p)が設定されている。 ここ経由でMicroSDカードもアクセスできるけど、9pに制約があるし、Linuxパッケージの格納先にはできないので、使いづらい。 できれば、MicroSDカードにディスクイメージファイルをおいて、それをLinux仮想マシンからマウントして自由に使いたい。 ということで調べてみた。

Linux仮想マシン(termina)を起動するのは、crosvmコマンド。 引数として、仮想ディスクイメージファイルを指定する。 また、ユーザが使うLinux環境は、terminaではなく、temrinaの中に更に作られるLinuxコンテナ(Penguin)である。 Penguinが起動すると、もう一つ仮想ディスクイメージファイルが作成される。 ここにもう一つMicroSDカード上のディスクイメージファイルを指定できると嬉しい。

わからない点は2点。

(1) corsvmコマンドに仮想ディスクイメージファイルを渡すところがわからない。 ChromeOS上でpsコマンドを見ると、crosvmコマンドに--rwdiskオプションでコンテナ用ディスクイメージファイルを指定していることはわかるので、ここをいじりたいが、ChromeOSのどこでcrosvmコマンドを起動しているのかがわからない。 vmc start terminaの延長かな、とは思うけど。 vmcのソースをたどればよいのかな?

(2) terminaの中で、コンテナ用のストレージをどのように管理しているかがわからない。 temrinaでのコンテナ管理ツールlxdは使えるが、terminaではrootになれず、ストレージの設定がよくわからない。 lxdを駆使したら調べられるのかな。

まずは(1)を調べてみた。

vmcコマンドはcrostini_clientへのシンボリックリンクになっており、crostini_clientのソースを見ると、自分では実際の処理はせずに、vmconcierge(VMコンシェルジュ?)という別のプログラムにRPC要求を発行するだけのようだった。 vm_tools/conciergeのソースをみてみた。

termina_vm.ccからcrosvmを起動している模様。 (類似ソースファイルにarc_vm..ccというのがある。AndroidVM用らしい。) 指定されたディスクについてはそれぞれcrosvmに--rwdisk(または--disk)オプションで指定している。 このディスク指定をどこからとってくるのかがよくわからない。

ちょっと角度を変えて。 crostini_clientのvmcコマンドを見てみると、

490 const USAGE: &str = r#"
491    [ start [--enable-gpu] <name> |
492      stop <name> |
493      create [-p] <name> [<source media> [<removable storage name>]] [-- additional parameters]
494      destroy <name> |
495      disk-op-status <command UUID> |
496      export <vm name> <file name> [<removable storage name>] |
497      import [-p] <vm name> <file name> [<removable storage name>] |
498      list |
499      share <vm name> <path> |
500      unshare <vm name> <path> |
501      container <vm name> <container name> [ <image server> <image alias> ]  |
502      usb-attach <vm name> <bus>:<device> |
503      usb-detach <vm name> <port> |
504      usb-list <vm name> |
505      help ]
506 "#;

新しいvmcコマンドには「create」サブコマンドがあり、引数にリムーバブルディスクを指定できるようだ。 devチャンネルでも使ってみる。

localhost / # vmc 
USAGE: vmc
   [ start [--enable-gpu] <name> |
     stop <name> |
     destroy <name> |
     export <vm name> <file name> [removable storage name] |
     list |
     share <vm name> <path> |
     container <vm name> <container name> [ <image server> <image alias> ]  |
     usb-attach <vm name> <bus>:<device> |
     usb-detach <vm name> <port> |
     usb-list <vm name> |
     help ]

残念。createコマンドはChromeOS 76でもまだ入っていない。 ただし、usb-attachコマンドが増えたので試した。 仮想マシンから直接USBデバイスをアクセスする手段らしい。

localhost / # lsusb
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 003: ID 0781:5583 SanDisk Corp. 
Bus 003 Device 004: ID 1286:204e Marvell Semiconductor, Inc. 
Bus 003 Device 002: ID 05e3:0610 Genesys Logic, Inc. 4-port hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 001 Device 004: ID 13d3:5696 IMC Networks 
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub

localhost / # vmc usb-attach termina 3:3
Error: routine at frontends/vmc.rs:308 `usb_attach(vm_name,user_id_hash,bus,device)` failed: failed permission_broker OpenPath: Rejected send message, 1 matched rules; type="method_call", sender=":1.121" (uid=0 pid=8282 comm="vmc usb-attach termina 3:3 ") interface="org.chromium.PermissionBroker" member="OpenPath" error name="(unset)" requested_reply="0" destination="org.chromium.PermissionBroker" (uid=230 pid=1919    comm="/usr/bin/permission_broker ")

だめだ。まだ動かないらしい。

Chromebook Linux VMモニタ(termina)をハック→失敗

Chromebooklinuxオプション機能(crostini)はtermina VM+penguinコンテナから構成されているが、terminaのrootになる方法がわからない。temrinaのrootディスクをいじってみる。

  1. Chormebookを開発者モードで起動してChromeOSのrootになる
  2. terminaのディスクイメージをマウントして中を書き換える。(まずは/usr/bin/sudoコマンドをChromOSから移植した)
  3. Chomebookを再起動

、、、結果、見事失敗。terminaのディスクを改ざんしたら起動に失敗する模様。暗号化とかはしていないのでいけるかと思ったが、ハッシュ値などがあるようだ。Googleからダウンロードしたディスクイメージしか使えなさそうだ。

localhost /mnt/stateful_partition/encrypted/chronos/cros-components/cros-termina/11895.50.0 # ls -lh
total 178M
-rw-r--r--. 1 chronos chronos 178M Jul  7 18:01 image.ext4
-rw-r--r--. 1 chronos chronos  256 Jul  7 18:01 imageloader.json
-rw-r--r--. 1 chronos chronos   70 Jul  7 18:01 imageloader.sig.1
-rw-r--r--. 1 chronos chronos   66 Jul  7 18:01 manifest.fingerprint
-rw-r--r--. 1 chronos chronos  242 Jul  7 18:01 manifest.json
 drwx------. 2 chronos chronos 4.0K Jul  7 18:01 _metadata
-rw-r--r--. 1 chronos chronos  229 Jul  7 18:01 table

Chromebook linux(crostini)からSDカード、Googleドライブを見る

chromebooklinuxオプション機能(crostini)は、SDカード(microSDカード)やGoogleドライブを見ることができる。 「ファイル」アプリでちょっと変更するだけ。(「設定」アプリではない。なお、ChromeOS GUIの右クリックは「Alt」キーを押しながらクリックだ)

linuxコンテナ(penguin)の前に、まず親のChromeOSでどう見えるかというと、SDカードは/media/removableの下にマウントされる。

localhost ~ # df /dev/mmcblk1
Filesystem     1K-blocks  Used Available Use% Mounted on
/dev/mmcblk1     3858432  1024   3857408   1% /media/removable/SD4G

Google Driveは/media/fuseだ。

localhost ~ # df -h /media/fuse/drivefs-*/
Filesystem      Size  Used Avail Use% Mounted on
drivefs          11G  3.0G  7.4G  29% /media/fuse/drivefs-33427e8bxxxxxxxxxxxx0d3dacd7f

ChromeOSから起動されるtermina VM(linuxコンテナの管理サーバにあたる)では、以下のようになっている。

(termina) chronos@localhost ~ $ df -h /mnt/shared/
Filesystem      Size  Used Avail Use% Mounted on
9p              1.9G  572K  1.9G   1% /mnt/shared

(termina) chronos@localhost ~ $ ls -l /mnt/shared/
total 0
drwxr-xr-x 3 root root 60 Jul  7 12:12 GoogleDrive
drwxr-xr-x 3 root root 60 Jul  7 12:12 removable

「9p」というのは、NFS/CIFSの親戚?で「9protocol」というらしい。今はGoogleにいる、unixの開発者が作ったOS「plan9」(B級SF映画のタイトルからつけられた)の技術の一つ。Crostini(イタリア料理の一種からつけられた)を構成するパーツにつけられた、コンシェルジュとかソムリエ(フランス語のホテル・レストラン関係の職種からつけられた?)とかのネーミングはおそらくこの人たちの仕業と思われる。親であるChromeOS上で「9p」をしゃべるサーバプログラムの名前は「9s」(9 server)らしい。

linuxの容量が足りない場合、removableの下にマウントしたSDカード(removable)か、インターネット越しのGoogle Driveを利用するしかない。/usr/を増やすことはできないので、アプリを増やす用途だと難しい。ビルド作業用など/home、/work的な用途のみ。

termina VMのrootがとれないのと、penguinコンテナのrootはエセrootなので、loopマウントなどの回避策が使えない。 セキュアなんだろうが不便だ。 コンテナをSDカードの中に作れるオプションがほしい。