Mount a windows share folder #3

CIFS で Windows の共有ディレクトリをマウントすると Linux 側が不安定になる件。結局 nfs サーバは試していない。いや一応 WinNFSd だけ試してみたのだが、ファイル名のエンコーディングを指定できずに化けてしまうのにがっくりしてそこから追ってない。

Linux 側の現象を見てみるに、どうも一旦スリープして、復帰するとマウントの状態がおかしくなっている気がする。一旦おかしくなると Thunar は固まるし、端末からマウントしたディレクトリを覗いただけで固まって困る。

ということはスリープ時に一旦アンマウントして、復帰したらマウントしなおせばいいのか?

と思ってググってみたらそのものズバリのケースがあった。これもまた割と既知の現象だった。/etc/pm/sleep.d/ に以下のようなシェルスクリプトを置いておく:

#!/bin/sh
# Unmount CIFS share on hibernate/suspend and remount it on resume

case "$1" in
hibernate|suspend)
umount /media/windows/music
umount /media/windows/pictures
;;
thaw|resume)
mount /media/windows/music
mount /media/windows/pictures
;;
*) exit $NA
;;
esac

なるほどねえ。

ちなみにおかしくなったマウントの状態は [cci]umount -l /media/windows/music[/cci] などと -l オプションをつければ一応解消できるのだが。このオプションは、つまりアンマウントのための様々なクリーンアップは後回しにして、とりあえずファイルシステムの階層からの切り離しを優先するとのことだ。後回しにしただけなので、もしかしたらマウントがおかしくなった状態を完全に解消する方法とは言えないのかもしれない。

Promise and Generator #5

ex の executor はかなり書き換えたわけだが、一方で vi コマンドの executor というのも一応ある。これは ex ほど大規模ではなくて、単に vi コマンドの文字列をキー入力キューに挿入するだけだ。この機能は [cci].[/cci] コマンド及び [cci]@[/cci] コマンドが利用している。つまりいわゆるマクロ機能に相当する。

今回コマンドの実行が非同期になったことで難しくなったのは、マクロの実行が完了したタイミングが取れないということで


executeViCommand('2w');
doSomethingAfterExecute();

ということができない。そこで、キー入力の最後に特別な擬似キー [cci]*macro-end*[/cci] を付加するようにした。なぜマクロ完了のタイミングが重要なのかといえば、カウントというものがあるからだ。[cci].[/cci] の場合は実行する vi コマンド列がカウントを内包しているのであんまり関係ないのだが、[cci]@[/cci] の場合はそうではない。

そういうわけでこのマクロ実行完了を表す擬似キーを使う。対応するコマンドハンドラ内でカウントを見て、必要なら再度コマンド列をキー入力キューに充填したりすればいい。ところでそのハンドラは normal モードにしか存在しないので、マクロ実行完了時のモードもまた normal モードじゃいけない。つまり他のモードの場合は [cci]escape[/cci] キーを再充填するなどの処置も必要。

それから、[cci]@[/cci] コマンドというのは指定したレジスタの内容を vi コマンドとして実行する機能なのだが。そうすると今回施した修正の元、たとえば [cci]@a[/cci] という文字列がレジスタ [cci]a[/cci] に格納されている状態で [cci]@a[/cci] を実行すると実質的な再帰が起こってしまう。ちなみに vim 7.4 (2013 Aug 10, compiled Nov 24 2016 16:44:48) で試したところ、固まってしまった(固まらない時もある。よくわからない)。

というわけで、[cci]@[/cci] コマンドのもとで vi コマンドを実行している際は同じレジスタを使った [cci]@[/cci] コマンドを入れ子で使えないようにした。入れ子でなければいいので、@a が @b を呼び、それが @c を呼び…ということはできる。

Promise and Generator #4

ぼちぼち Selenium でテストし始める。

ところで Selenium でテストする際、ブラウザの console 出力を得たい時がある。…のだけど、いまいちそのへんのドキュメントが整備されていない気がする。javascript バインディングの API はドキュメントがあるが、これはあくまでリファレンスであってハウツー的なものはほとんど書いてない。

いろいろ調べてみたところ、

const webdriver = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
:
:
var loggingPrefs = new webdriver.logging.Preferences()
loggingPrefs.setLevel(
webdriver.logging.Type.BROWSER,
webdriver.logging.Level.ALL);

var options = new chrome.Options();
options.setLoggingPrefs(loggingPrefs);

var driver = new webdriver.Builder()
.withCapabilities(webdriver.Capabilities.chrome())
.setChromeOptions(options)
.build()
:
:
driver.manage().logs().get(webdriver.logging.Type.BROWSER).then(log => {
// log は Entry インスタンスの配列で、
// 各要素の message プロパティに console 出力の各行が格納されている
});

という感じでいいようだ。message プロパティは前後にソースファイル名や行番号などが付加されていたりするので、そういうものを削ぎ落とす加工は必要。

Early arousal syndrome

Windows10マシンが、いつのまにかスリープさせると数秒後に勝手に復帰し、さらに数秒後にまたスリープし、そして再び数秒後に勝手に復帰…というのを繰り返すようになった。おもしろいので1時間くらい放っておいたが1時間くらい繰り返している。

イベントビューアからカスタムビューを生成して Power-Troubleshooter を抽出し、復帰の理由を見てみたところ、犯人は VBoxSVC.exe のようだった。つまり VirtualBox だ。お前かよ。お前かよ。

わりと既知の問題のようだ。

とりあえず VirtualBox のバージョンを最新にしたら今のところ収まったように見えるが、また再発するかもしれない。ちなみに復帰の理由はコマンドプロンプトから [cci]powercfg -lastwake[/cci] でも確認できる。

npm 5

npm の CEO である Isaac Schlueter 氏から直々にメールが来て(と言っても単に npm ユーザ全員に送ってるだけだが)、npm が version 5 になったよ! パフォーマンスとか可用性とか色々良くなったから使ってみてね! ということであった。

へー、と [cci]npm install npm@latest -g[/cci] と打ち込んでバージョンが上がったのを確認し、そのまま [cci]npm outdated -g[/cci] としたところ、出て来るべきものが何も出てこない。[cci]npm update -g[/cci] としても何も起こらない。

なんか、バグみたいだ。うーん。テストとかしないのかな。

* * *

件の issue に書かれているワークアラウンドを試してみたところ、さらになんかおかしい。

各モジュール自身のディレクトリがある。例えば [cci]~/.nvm/versions/node/v7.2.1/lib/node_modules/chromedriver[/cci] とか。これに対して [cci]npm install -g chromedriver[/cci] とする。すると、モジュール自身のディレクトリは消え失せ、その代わりに自分自身を指す間違ったシンボリックで置き換えられた。もちろんこれには全く意味はなく、当然モジュールも動作しない。

あらかじめ各モジュールのディレクトリを削除した上で再インストールすればいいようだ。うーんなんか…なんか…。

Promise and Generator #3

長い時間をかけてちくちくいじっていたものが終結しつつある。キーボード入力から vi コマンド / ex コマンドの実行、その実行の完了を保証するシーケンスポイントまでの一連の関数呼び出しが Promise の連鎖によって行われるように修正した。とても疲れた。

これにより、従来あんまり綺麗な形で実装していなかった非同期処理を、それを必要とする関数内に局所的に閉じ込める形にできて見通しが良くなった。例えばクラウドに対する読み書きの場合は、それを担当するのは ex コマンドのハンドラなのだが。応答が複数回来るので、一旦途中で ex 仮想マシンの実行を中断し、wasavi 側のグローバルなメッセージハンドラで受けて、適宜再開する…のようなことをしていた。バックエンドに対するメッセージは基本的に送信と応答の 1 回のやり取りで完結するので複数のやり取りに対応できないからだ。とても不自然。

これを、ex コマンドハンドラ内で Promise を生成し、新規に開いたメッセージポートを通して複数回のやり取りをし、すべてが完了したら resolve() するようになった。とても見通しがいい。

ex コマンドのエグゼキュータも Promise ベースで動作するように書き直した。疲れた。

マップマネージャもまた Promise を使用するように完全に書き直した。これもまた疲れた。

疲れすぎてもう海に還りたい。

Using redshift

いま使っているマシンは Thinkcentre なんとかという、いわゆる一体型 PC なのだが。このマシンを仮に明るい時間にいじっている際は、ディスプレイの輝度はそれなりに上げてほしい。しかし逆に、夜更けにいじっている際は輝度は抑えてほしい。このあたりを賢く調節してくれないだろうか。

というわけで redshift を導入する。~/.config/redshift.conf を以下のような形で適当に書き(経度・緯度は伏せたが、そのとおりの数値を書く)
[redshift]
temp-day=5500K
temp-night=5000K
transition=1
gamma=1.0:0.9:0.9
location-provider=manual
brightness-day=1.0
brightness-night=0.5

[manual]
lat=*
lon=*

これをログイン時に常駐させると、時間帯によってディスプレイの色温度やガンマ値や輝度を適切なものに調整してくれる。すごい。

これを導入する際に、ディスプレイ側の設定が必要になるかもしれない。つまりディスプレイ側で色温度やガンマ値や輝度をハードウェア的に設定できる場合は、それらをデフォルト…というか「なんにも弄らないモード」に戻したり、輝度の場合は最大に設定したりしないといけない。この辺の、ディスプレイ設定のハードウェアとソフトウェアのシームレスかつ密な連携ってどうなっているんだろうか。

* * *

ソースを見てみたら、redshift は色温度・ガンマ値・輝度の3要素を制御できるわけだが、最終的にはすべての要素を掛けあわせたガンマ値にして設定しているようだ。つまりそれぞれ色温度テーブルから求めたガンマ値、R/G/Bに個別に指定できるガンマ値、R/G/B一律に指定するガンマ値という扱いになっている。

cVim

Chrome に cVim を入れて常用ブラウザとしている。そして、多少 cVimrc をいじって、その中に編集可能な要素内で [cci]Ctrl+H[/cci] が押されたら、[cci]deleteChar[/cci] 関数を呼び出すような設定にしている。

…のだが、最近になってこれが動かなくなってしまった。キャレットの左の 1 文字が選択されるのだが、削除されない。選択されたままになる。

デバッガで追ってみると、選択した後にその選択範囲を削除しようとする箇所で、selection オブジェクトの type が Range であれば削除する…となっている処理がある。しかしナウい Chrome では、編集可能な要素の selection.type は Caret が返されるようなのだ。なので、削除処理がスキップされる。

まあ、そのうち直るんでしょう。cVim のソースは現在でもそれなりにメンテされている。

Mount a windows share folder #2

以前、Windows10 マシンのけっこう余っているハードディスク容量を活用するため、ディレクトリを Xubuntu 側に公開したことがあったのだが、実はそれをやって以降、ファイルマネージャである Thunar の調子がとても良くない。よく固まるようになってしまった。

固まる原因が必ずしもこの共有だという明確な証拠はないのだが、試しに共有をオフにすると安定するので、まあそういうことなんだろう。

さてどうしよう。共有のプロトコルは CIFS である。これがダメなのか? もしかしたら NFS にすれば安定するだろうか。というわけで調べてみたのだが、Windows マシン上で NFS サーバを動かすというソリューションが意外に少ない。まあ、でも、そりゃそうですよね…。

探してみたところ、

などがある。github のやつは、もともとは別の方が SourceForge で公開されていたものの fork の fork みたいな感じ。

この他は、大昔の SFU にそういう機能があったりしたようだが昔のこと。Windows Server であれば標準で NFS サーバになれる、と思うがうちのは Server じゃない。cygwin か、あるいは今流行りの Windows Subsystem for Linux (WSL) にもありそうだが多分 Windows のネイティブなサービスとしては動かせない。

ということで上記の3つを試したいのだがそれでも面倒くさいなあ。前述の通り、できればサービスとして常駐する機能を持っているものがいいのだけど。