linuxでRyzenの温度センサーを動くようにする

Ryzenには温度監視機能があるのですが、本記事執筆現在、linuxのいわゆるupstream kernel(最新版は4.13)ではドライバが無いのでこの機能が使えません。温度監視をしたければWindowsFreeBSDを使うしかないという悲しい状況です。sensorsコマンドを実行しても次の通り、温度に関する情報は得られません。

$ sensors
asus-isa-0000
Adapter: ISA adapter
cpu_fan:        0 RPM

$ 

しかし、まだupstreamにマージされていないパッチを適用すれば、この機能を使えます。

AMD Zen Temperature Monitoring On Linux Is Working With Hwmon-Next - Phoronix

今使っているカーネルに関連パッチをcherry-pickしてきてもいいのですが、とりあえず試してみるだけなので、手間を省いて次のように関連パッチが入ったbranch, hwmon-nextをそのままビルドします。

$ cd ~/src/linux
$ git remote add staging git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging.git
$ git fetch staging
...
$ git checkout staging/hwmon-next
...
$ cp /boot/config-$(uname -r) .config
$ make olddefconfig
...
$ make menuconfig                    # SENSORS_K10TEMP(Device Drivers -> Hardware Monitoring support -> AMD Family 10h+ temperature sensor)を選択
...
$ make -j$(grep -c processor /proc/cpuinfo)
...
$ 

できたカーネル上でsensorsコマンドを実行してみましょう(インストールとリブートの手順は省いています)。

$ sensors
k10temp-pci-00c3
Adapter: PCI adapter
temp1:        +31.0°C  (high = +70.0°C)                  # 温度情報が出力されている

asus-isa-0000
Adapter: ISA adapter
cpu_fan:        0 RPM

$ 

うまく動いているようです。よかったよかった。後はupstream kernelにパッチがマージされるまで待ちです。残念ながら4.14のマージウィンドウは逃しているので4.15以降です。

ちなみに関連パッチは次の3つです。4.13に以下3つのパッチをcherry-pickした状態で温度情報が採取できていることを確認済です。

  • 398f86f hwmon: (k10temp) Add support for temperature offsets
  • 3b7317cc hwmon: (k10temp) Add support for family 17h
  • 12dbb1a hwmon: (k10temp) Move chip specific code into probe function

iOS用のmosh/ssh環境作成

iPad Pro+smartkeyboardを手に入れました。リモートのlinuxマシン上でちょっとした作業をしたいけれども、いちいちPCを起動するのが面倒なときのために、早速mosh/sshクライアントアプリをインストールすることにしました。結論から言うと、しばらくはBlinkというアプリを使う予定です。

App Storeにおいて"mosh ssh"で検索したところ、該当するのはTermiusとBlinkの二つのみでした。前者は評価版を無償で使えるようなので、とりあえず前者を試してみました。こちらはsshは期待通り動くのですが、moshの挙動が怪しいのが難点でした。なにより辛いのが、emacs上でC-spcによる範囲選択が動作しないことでした。このため候補から外しました。

次に試したのがBlinkです。ろくに情報もレビューも無いのに2400円もするのが不安でしたが、悩んでる時間が勿体無いので買ってみました。起動してみると、そろそろ2020年になろうとするこの時代のiOSアプリとしては信じられないほど不親切な出来栄えであり、最初はいきなり謎のコマンドプロンプトが表示されて放置でした。Windowsユーザだったころにlinuxを最初に触ったときの絶望感を思い出しました。

最初はハズレを掴まされたかなと思ったのですが、一旦触ってみるとTermiusとは異なり、前述のmoshの問題も無いため、しばらくはこれを使ってみることにしました。C-mが効かないという別の問題があるのですが、致命的ではないこと、かつ、次のように、すでにgithub上にissueも発行されていることより、しばらく我慢することにしました。

github.com

最後に、どちらのクライアントも私の持っているJISキーボードでは"\"が入力できずに"¥"になってしまうことが大きな問題でした。プログラミングで頻繁に使用するエスケープシーケンスを挿入するためには必須のキーなので、これは辛いです。本来は"option + ¥"によって"\"を入力できるのですが、optionキーでescをエミュレーションしているせいか、この手は使えませんでした。結局のところ.emacsへの次の行を追加によって解決しました。

(define-key global-map (kbd "¥") "\\")

wi2 300を契約&解約しました

最近外出先で仕事をすることが多くなってきたせいか、スマホに入れているSIMの通信容量制限に達しかける、あるいは達してしまって通信容量追加チケットを買う羽目になることが多くなってきました。最も単純な対処はSIMの契約プランを変更することですが、公衆無線wifi、とくにwi2 300がどんなものなのかに何となく興味があったこと、および月額料金が400円程度なので調査に時間を消費するより実際に使用感を確かめるほうがローコストだと判断して、契約してみました。

結論から言いますと、このサービスは私にはまったく合っておらず、残念ながら一週間程度で解約することになりました。理由は次の通りです。

  • 普段行く場所が追加料金無しで利用できるベーシックエリアに入っておらず、一時間100円の追加料金が必要なオプションエリアになっていることが多い。わざわざこの料金を払うくらいならSIMのプラン変更したほうがマシなので、あまり意味がない
  • ベーシックエリアになっている場所であっても、店舗自身が独自無償wifiを提供しており、わざわざwi2 300を利用する意味が無いことがよくある(スタバとかタリーズとか)
  • wifiスポットに自動接続する設定にしていると、移動中に滅茶苦茶電波の弱いスポットを掴んだ挙句に全然通信できないという事態が頻繁に発生する。かたや自動接続にしていないと、いちいち自分でスポットを探して接続する必要があるので、ちょっとめんどくさい(その上、探して出てくるのが高頻度でオプションエリアのスポット)。

通信速度に関しては、普段それほど速度が必要な作業をしないせいもあってか、とくに不満はありませんでした。追加課金無しで利用できる場所が十分に多ければ、たとえば今のオプションエリアが全て追加課金無しで利用できるのであれば、十分に使い物になっていたでしょう。

なお、このサービスの良し悪しは「普段外出時にどこに行くか」に強く依存するので、その場所がベーシックエリアにあるのなら、SIMのプラン変更よりも割安になるケースが多いので、一度使ってみてもよいのではないでしょうか。

Open Source Summit Japan 2017に参加してきました

Open Source Summit Japan 2017というオープンソースソフトウェアに関する様々なセッションを聞くというイベントに昨日まで三日間参加してきました。内容を覚えてるうちにメモしておこうと思います。

Open Source Summit Japan 2017 | Open Source Summit Japan 2017 | Linux Conferences and Linux Events | The Linux Foundation

このイベントについて全然知らない人のために補足しておくと、世界中から様々な人が集まってくる全編英語の国際イベントです。参加人数はぱっと見、千人前後でしょうか。今年はとくにたくさんの人が参加したようです。かつてはLinux Con Japanという名前でlinuxカーネルを中心としたlinuxの話が主だったのですが、最近は他のOSSのセッションが増えてきてlinux色が薄まってきたからなのか、今年から改名したようです。

セッションそのもの以外でも、ここ数年は学生さんが多く参加しており*1、別の学生達や職業エンジニアの知り合いを作ったりという、同好の士を繋ぐハブとしての役割も果たしているように見えます。私も今年10人程度の学生さんを含むエンジニアと新たに知り合い、かつ、SNS上でしか知らなかった方々と初対面を果たせました。

ここからは今回とくに印象に残った二つのセッションについて紹介します。主にわたしが個人的に気になった部分の簡単な紹介や、それについて私がどう思ったか、どういう質疑があったのかということを書きます。詳しい内容は既にアップロードされている(かつこのエントリにリンクを張っている)セッションのスライドに書いているので、そちらを見ていただければと思います。

Noah: Hypervisor-Based Darwin Subsystem for Linux - Takaya Saeki & Yuichi Nishiwaki, The University of Tokyo

sched.co

スライドはこちら

LinuxのバイナリをmacOSの上で動かすという話です。「*BSDにもWindowsにもLinuxバイナリを動かす方法があるのにmacOSには無い、作っちゃえ!」という面白い動機によって開発されたようです。ネタがネタだけに会場には馴染みのあるカーネル野郎達がウジャウジャいました。類は友を呼ぶというやつでしょうか。

実現方法はおおよそ次の通りです。

  1. 1つのlinuxバイナリを動かすごとに1つのVMを立ち上げてそこにバイナリをロードする。および、後述のNoahプロセスというプロセスを立ち上げる
  2. linuxバイナリから作ったプロセスが発行するシステムコールはハイパーバイザがすべてトラップする
  3. システムコールの依頼内容をハイパーバイザがNoahプロセスに転送
  4. Noahプロセスがシステムコールをエミュレーションして結果をLinuxバイナリから作ったプロセスに返す(ちょうど普通のハイパーバイザがguestのかわりにハード処理をするようなイメージ)

Noahプロセス自身は単なるユーザプロセスなので、エミューレーション用コードにバグがあっても*BSDWIndowsによる他の実現方法のようにカーネルパニックが発生しないという特長があります。他にもmacOSのプロセスとLinuxバイナリから作られたプロセスがパイプやシグナルで通信できるという特長もあるようです。すごい。

話を聞いていると確かに技術的に言ってることは理解できるのですが、そのアイデアを実装して形にしてしまう行動力、および、あまたあるシステムコールのエミュレーションコードを書いて実装を完成させて動くところまでもっていくという実装力に感心しきりでした。

他にも質疑が面白かったのも特徴的でした。この手のネタはエンジニアにとってはどれだけの種類のLinuxバイナリが動くのか、つまりどこまでの範囲Linuxをエミュレーションできているのかという興味が尽きないのですが、「コンテナは動かしたことあるか」「procfsはどうなっているのか」という質問に対して彼らはことごとく「Please send PR」というカウンターパンチを使って見事切り抜けていました。発表中にとっさにこういうウィットに富んだことが言えるのもポイントが高いです。

余談ですが、発表されたおふたりはNoahで未踏スーパークリエイター認定を受けた方々だそうです。すごい人もいるもんですね。

www.ipa.go.jp

WalB: Real-time and Incremental Backup System for Block Devices - Kota Uchida, Cybozu, Inc.

sched.co

スライドはこちら

サイボウズ社が運用しているシステムにおけるバックアップの課題と、それを解決したWalBというバックアップシステムの紹介です。サイボウズグループウェア日本最大手であり*2、この規模の会社が使っているシステムの内部を数値込みで見られることはなかなか無いので、貴重な機会でした。

サイボウズのシステムでは一日一回のインクリメンタルバックアップが要件になっているそうです。dm-snapやdm-thinなどを用いたバックアップシステムでは(既存システムはdm-snapを用いたもの)、一日ごとにスナップショットを採取して、最新のものから数えて2つのスナップショットをスキャンすることによってバックアップ用の差分をデータを作る必要があります。これらの方法ではこのスキャン処理にかかる時間が長いのがネックなのだとか。

その一方でWalBは、管理対象とするブロックデバイスに対する書き込みのログ(デバイス内のどこに何を書き込んだかという情報)をログデバイスと呼ばれるデバイスに別途書き込んでおいて、このログがほぼそのままインクリメンタルバックアップ用の差分データになるという仕組みだそうです。この方法だと書き込み処理ごとに定常的にログデバイスに対する書き込みが発生しますが、スナップショットベースのバックアップシステムのような、一日一回バックアップ時に発生する大きなI/O負荷(スキャン処理)は無くなります。うまく考えたものです。

今回はバックアップを採取する側の話が中心でしたが、今後はリストアを含めた運用全体に関する話がどこかで聞けたらいいなあと思いました。

このセッションについては、技術的な面白さだけではなく、ハードを売っているわけでないソフトウェア専業の会社がlinuxデバイスドライバ(WalBのブロックデバイスを実現する部分)を書いて、バックアップシステムを自作して、かつ、それを実運用していることにも感銘を受けました。最近ではFacebooklinuxカーネルチームを抱えているなど、海外企業ではそのような事例はいくつも聞いたことがありますが、日本でもこういうことをしている会社があるのは知らなかったです。

なお、このプレゼンは再演予定もあるそうなので、興味のある人は行ってみるといいかもしれません。

atnd.org

*1:まだ学生でなく生徒と呼ばれる年齢のかたもいらっしゃいます。すごい

*2:このエントリを読んでくれるようなエンジニアの人にとっては、最近話題になった、32GBメモリのマシンを全員に支給してくれる羨ましい会社としてのほうが有名かも

コーディング練習: holeを意識したコピー

昨日に引き続きプログラミングの練習。網羅性とサイズの大きさで有名な次の本の演習のひとつを扱いました。

作るのはファイルをコピーするだけのプログラムです。もとのファイルにholeがあれば、コピー先ファイルにもholeを作る必要があります(ヌルバイトの連続によってストレージ領域を消費してはいけない)。

web上には次のような回答例がありました。

github.com

目的のプログラムを作る場合には通常lseek()のwhence引数にSEEK_HOLEとSEEK_DATAを指定することによってholeのありかを検出します(ここには書きませんがioctl()でも同様のことができます)。しかし、上記プログラムの作者の環境はこれらが使えないカーネルバージョンだったらしく、この方法を使わない単純な実装になっていました。連続するヌル文字を見つけたら、それらをただ書き込むのではなく、lseek()によって飛ばしてしまおうというものです。これは一見うまくいきそうですが、次のような問題があります。

  • もともとわざとヌル文字で埋めていたブロックもholeになってしまう
  • hole部分をフルスキャンする必要があるため、コピー所要時間が長くなる
  • ファイル末尾に連続するNULL文字あるいはholeがあった場合は、その部分がコピーされない。それら領域をlseek()によって飛ばした後に0バイトwrite()する(つまり実質何もしない)だけでファイルサイズを正しいものに更新しないため、ファイルサイズがコピー元ファイルより短くなってしまう

実際、次に示す簡単なテスト(ファイル内の色々な箇所にholeが空いているファイルをコピー)のほとんどに失敗しました。

github.com

その一方で、私の実装は次の通りです(上記プログラムは見ずに作ってます)。

github.com

このプログラムは、次のような特徴があります。

  • lseek()におけるSEEK_HOLEとSEEK_DATAを使っている。データ領域をコピーする処理と、その後に続くholeを飛ばす処理の繰り返しです。
  • エラー処理のためにgotoを用いている。gotoを見るのも嫌というかたがたもいると思いますが、こういうケースではgotoを使わないほうがむしろコードが見にくくなると私は考えています

こちらは前述のテストをすべてパスしました。ほかの観点でテストをしたらまだバグは潜んでいると思いますが、ひとまずは合格です。

コーディング練習: 人の書いたプログラムを自分の方法で書き直す

web上で、とある凄腕エンジニアのかたが実装した簡単なプログラミング言語の実装と、その様子を紹介したビデオを見つけました。

gist.github.com

www.youtube.com

思うところあって、プログラムの仕様をできるだけ変えないまま、自分なりに書き直す練習をしたかったので、ちょうどいい小さな規模のこのプログラムで実践してみました。

gist.github.com

仕様を変えないまま…とは言っても仕様が文書なりで明確化されていたわけではないので、ソースから著者の意図を推測しただけです。一から書き直すという方法もありますが、今回は既存のソースを改編するという方法をとりました。

変更点は次の通り。

  • 仕様っぽいもの(すごく柔らかい、お金を取るプロダクトの仕様書として出したら殴られるレベルのもの。ここではこれでいいんです)をソース冒頭に書いた
  • 関数名、変数名(とくにグローバル変数)は何をしているものなのかをわかりやすくした
  • エラーチェックの追加: 引数の数、バッファオーバーランなど
  • print機能(P()関数)による出力と、トップレベルの文を評価した際の出力を区別できるようにした
  • 雑多なバグ修正

もう少しこだわると、コードへのポインタはグローバル変数ではなく関数引数にしたかったんですが、無用にややこしくするだけになる恐れがあったので、やめました。

可読性においては初級者には見やすくなっていると思います。その一方で、上級者にとっては冗長に見えるかと思います。それらはオリジナルソースの作者と私の好みの違い、および、ソースをどれだけ気合を入れて書いたかの違いでしょう。「俺だったらここはこうするね」という意見も多々あろうかと思います。色々な人が同じことをした場合のソースを並べて見てみたいものです。

この試みはけっこう面白かったので、他のソースでもやってみようかと思います。オレオレプログラムを書く場合とは異なる脳の部位を使っている気がします。

ノートPCに仕込まれていたキーロガーを削除した

三日前にこんなニュースが飛び込んできました。

thehackernews.com

で、私が最近買ったPCはHP製品です。

satoru-takeuchi.hatenablog.com

該当PCの一覧にもありました。あーあ。

https://www.modzero.ch/advisories/MZ-17-01-Conexant-Keylogger.txt

こんなのを仕込まれていてはたまらないので、問題となる実行ファイルを削除しました。ログファイル(c:/Users/Public/MicTray.log)にパスワードを含む打鍵履歴が山盛り記録されていて肝を冷やしたかったのですが、残念ながら当該ファイルは空であり、かつ、変更日時はOSインストール時とおもわしきものでした。私のPCにインストールされているバージョンのドライバではロギングしていないのか、あるいはログファイルはスーパーハカーの手によって変更履歴が改竄されているのかは知らないです。

ただこの話は、迷惑かついい気分がしないのは確かなんですが、

  • ログを".log"というわかりやすい拡張子のファイルに保存している
  • ドライバ自身からはネットワーク転送していないらしい
  • 全ユーザにファイルが読める

という隠す気ゼロのしょっぱい作りなあたり、わざとでなく本当に「やっちゃった」だけなのでは?というのは感じます(後付けで何を言っても真意は作者にしかわかりませんが…)。

5/14に落ちてきたWindows Update “Conexant - MEDIA - 5/14/2017 12:00:00 AM - 9.0.134.1"によって、問題のログファイルは消され、かつそれを作っていると思わしき実行ファイルは更新されていたので、これが修正なのでしょう。こういうのは黙って直すだけではなく、HPからなんらかのアナウンスが欲しいところです。がっかり。