vagrant up 失敗の原因究明

  • 投稿日:
  • by
  • カテゴリ:

vagrant upがなぜか失敗するのでその原因究明をしたときの話です。

事象

PS E:\vagrant> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Box 'hashicorp/precise64' could not be found. Attempting to find and install...
    default: Box Provider: virtualbox
    default: Box Version: >= 0
==> default: Loading metadata for box 'hashicorp/precise64'
    default: URL: https://vagrantcloud.com/hashicorp/precise64
==> default: Adding box 'hashicorp/precise64' (v1.1.0) for provider: virtualbox
    default: Downloading: https://vagrantcloud.com/hashicorp/boxes/precise64/versions/1.1.0/providers/virtualbox.box
    default: Download redirected to host: vagrantcloud-files-production.s3.amazonaws.com
    default:
==> default: Successfully added box 'hashicorp/precise64' (v1.1.0) for 'virtualbox'!
==> default: Importing base box 'hashicorp/precise64'...
There was an error while executing `VBoxManage`, a CLI used by Vagrant
for controlling VirtualBox. The command and stderr is shown below.

Command: ["import", "\\\\?\\E:\\vagrant_home\\.vagrant.d\\boxes\\hashicorp-VAGRANTSLASH-precise64\\1.1.0\\virtualbox\\box.ovf", "--vsys", "0", "--vmname", "precise64_1571241203898_82313", "--vsys", "0", "--unit", "12", "--disk", "D:/VMimages/precise64_1571241203898_82313/box-disk1.vmdk"]

Stderr: 0%...10%...20%...30%...40%...50%...60%...70%...80%...90%...100%
Interpreting \\?\E:\vagrant_home\.vagrant.d\boxes\hashicorp-VAGRANTSLASH-precise64\1.1.0\virtualbox\box.ovf...
OK.
0%...
Progress state: E_INVALIDARG
VBoxManage.exe: error: Appliance import failed
VBoxManage.exe: error: Code E_INVALIDARG (0x80070057) - One or more arguments are invalid (extended info not available)
VBoxManage.exe: error: Context: "enum RTEXITCODE __cdecl handleImportAppliance(struct HandlerArg *)" at line 957 of file VBoxManageAppliance.cpp
PS E:\vagrant>

先に原因を書きますが、上記のように引数が悪いと言われますが、実際はディスクの空き容量が不足しているのが原因でした。

環境

Host: Windows 10 Guest: (何でも)

Vagrant: 2.2.5、2.2.6 Virtual Box: 6.0.12、6.0.14

原因究明

エラーメッセージでググってみると以下のissueに該当しているのを発見!

Invalid arguments to vboxmanage (potentially malformed path) #10832

ところが、未解決のままcloseしていました。 一日寝かしてみましたがやっぱり解決しないので新規オープンしようと思って 報告ルールに従って情報を集めていたらデバッグログの出し方があったのでこれを見てみました。 すると、VBoxManage.exeが失敗していたのだとわかりました。 VBoxManage.exeはvagrantではなく、Virtual Boxのコマンドです。

そこで、VBoxManage.exeの実行方法を調べて同じ引数で実行してみます。すると、再現します。

vagrantの呼び出し方が悪いのか、VBoxManage.exeが悪いかを切り分けます。 VBoxManage.exeの引数をいろいろと変えて試してみました。 すると、diskのファイル名(.vmdk)の指定を変えると成功する場合がありました。 指定の仕方によるのかも思いいくつかのパターンを試しましたが結論としては、ディスクの空き容量が足りていないと失敗することがわかりました。

つまり指定するドライブの問題です。ドライブを指定しているのは誰かというとVirtual Boxです。 Virtual Boxの「デフォルトの仮想マシンフォルダー」が使われています。 というわけで、この設定を変えることで解決できます。

問題の報告でも苦戦

Vagrantのissueに挙がっていたので同じ問題で悩む人もいるのだろうということで、関係各所に報告することにしました。 Virtual Boxのメッセージが分かりにくいのが良くないと思うのでメッセージの改善依頼を出してみることにしました。

Virtual BoxのForumがあるのでとりあえずそこで報告しようと思ってPosting Guidを見てみると、ユーザ登録が必要となっています。 registerのリンクをクリックするとNot Foundとなって登録できません。 loginのリンクは生きていたのでそちらを見てみるとOracleのログイン画面です。 アカウントを作成して無事にログインしてどう伝えるのが良いか考えてみましたが、モデレータへDMを送る機能があるようなのでそこに送ろうとしました。 しかし、URL入りのメッセージを送るにはユーザ作成後5日と5ポストの実績が必要だそうです。そんなにポストする予定はないので普通のTopicとしてポストすることにします。

Suggestionsという分類があるのでそちらでポストしようとしたら、今度はURL入りのポストはユーザ作成後1日と1ポストの実績が必要だそうです。 URL入りを送るのは難しそうなのでじゃあ、もうURL入れずに送ろうと思って送ろうと思ったら、ユーザ作成後1日経たないとURL無くてもポストできないそうです。 本題のメッセージの改善についても同じ理由でポストできませんでした。

もう疲れちゃいましたが、明日こそポストしてみます。

はじめてのWindows クラッシュダンプ解析

  • 投稿日:
  • by
  • カテゴリ:

Windows 10のマシンがブルースクリーンになってしまって、再発すると困るので見てみました。 ググってみるとちょっと見てみるところまでは簡単にできそうだったのでやってみました。

結果はDPCウォッチドッグに引っかかっているみたい。(以下は、!analyze -vの抜粋)

DPC_WATCHDOG_VIOLATION (133)
The DPC watchdog detected a prolonged run time at an IRQL of DISPATCH_LEVEL
or above.
Arguments:
Arg1: 0000000000000000, A single DPC or ISR exceeded its time allotment. The offending
    component can usually be identified with a stack trace.
Arg2: 0000000000000501, The DPC time count (in ticks).
Arg3: 0000000000000500, The DPC time allotment (in ticks).
Arg4: fffff8003376e350, cast to nt!DPC_WATCHDOG_GLOBAL_TRIAGE_BLOCK, which contains
    additional information regarding this single DPC timeout

そしてkの結果には以下の文字列が。

rt640x64!MpHandleRecvIntPriVLanJumbo+0xb41
rt640x64!MPHandleMessageInterrupt

ここを見ると、スタックとレースのちょっと下で読んでる関数が問題なんだろうとわかるので、Realtekのドライバかなと思って、RT640x64でググってみるとやっぱりRealtekのドライバでした。最新のドライバにしてみたら?とコメントもあるし、そういえばMicrosoftから提供されているドライバしか入れてないなと思ったのでインストールしてみました。 これで安定してくれると良いなぁ。。

なお、ドライバインストールをそのNICを使ってリモートデスクトップでログインしながらやったので、途中で通信止まってしまいましたが少ししたらまたつながって一安心というのをしました。 さらに、PriVLANという文字列があったので、「優先度およびVLAN」という設定を無効にしたら、またしても一瞬通信が途絶えて、「あっ」ってなってしまいました。ちなみにジャンボフレームは無効になっていました。

ドライバの場所

https://www.realtek.com/ja/component/zoo/advanced-search/80?Itemid=389

デバッグ方法、他

日本語ページのリンクにしてますが、読みにくいので英語版で読む方が良いような気がします。。

メモリダンプに !analyze -v するまで・前編 ~ ダンプの取り方~ WinDbg を使用してクラッシュダンプファイルを分析する Stop エラーまたはブルー スクリーン エラーに対する高度なトラブルシューティング ドライバーの検証ツール ドライバー検証ツール !analyze !analyze 拡張機能の使用 バグ チェック 0x133 DPCウォッチドッグ違反

ダウンロード用シンボルのURL設定 SRVc:\websymbolshttp://msdl.microsoft.com/download/symbols

合わせて読みたい

キーボード操作でメモリ ダンプ ファイルを作成できる Windows の機能 DriverObject と DriverEntry ダンプファイルに保存された ETW トレースログを表示する ダンプファイルに保存されたイベントログを取り出す

mtdataapi.vimの開発状況

  • 投稿日:
  • by
  • カテゴリ:

以前、このエントリで書いたプラグインがとりあえず使える感じになってきたので改めてここに書く。

このプラグインは、Movable TypeというCMSを利用する際の文字編集を簡単にするために開発しています。 Movable Type(以下、MT)は、エントリを編集するインタフェースとしてWeb UIを提供していますが、豊富なエディタの機能を利用することができないのが個人的な欠点でした。 Web UIのままでも、javascriptを書くことで様々な機能を追加することができますが、使い慣れたエディタを使える方が何かと便利です。 そこで、vimというエディタで編集したものがMTにすぐにアップロードできたり、MTのエントリをvimにダウンロードできたりすることを実現したいと思いました。

そこでmtdataapi.vimでは、MTのもつAPIであるData APIを使って、エントリ情報をやり取りすることでエントリ情報のアップロードやダウンロードを実現しました。 MtOpenコマンドの引数にエントリIDを与えると、MTから該当のエントリをダウンロードしてきてローカルファイルに保存します。そして、そのローカルファイルを開きます。 そのまま編集して:wで保存すると、MTにアップロードされて、エントリが更新されます。 ダウンロードしたエントリは、本文だけでなく公開、非公開(下書き)の状態やカテゴリ、タグなどの情報も含まれていて、それらも編集可能です。そのため、非公開のエントリを公開に変えて保存するだけで、エントリを公開状態にすることができます。

本文編集の際のフォーマットは、htmlだけでなくMarkdownも利用できます。 Markdownで表現できない部分(複雑なhtmlなど)は、htmlのままにしておいて、文章だけMarkdownで記載することも可能です。文章だけであればMarkdownで記載できれば十分なのですが、それができない場合はhtmlをMarkdownで扱おうとすると情報が失われてしまうケースがありました。そのため、両方を扱えるようにしています。 htmlの方が情報が多いので、基本的にはhtmlでローカルファイルには保存しておいてMTとやり取りします。文章を編集する際のみ、該当部分をMarkdownに変換する使い方を意図しています。

上記のhtmlとMarkdownを変換するために、MtHTMLtoMDとMtMDtoHTMLコマンドを用意しています。 ビジュアル選択した状態で上記コマンドを実行すると、選択部分が変換されます。 Markdownでの編集が終わったらhtmlに変換して、:wするという使い方を想定しています。 MtOpenした場合も、:wで保存した場合も、その後自動的にMTの情報でbufferが更新されます。このときはhtmlで更新されます。

MTでは画像のアップロード操作などもできます。 Web UIではマウスで簡単に画像の挿入ができますが、mtdataapi.vimではできません。そのため、Web UIでエントリを編集する場合もあると思います。 そうした場合、ローカルファイルの情報が古くなってしまいますが、MtOpenで開いた状態でを押すとMTから情報をダウンロードして最新の情報で更新されます。

自分でこのプラグインを作ってみて実際に使っていますが、文章を書くのが楽になってブログエントリを書くのも楽になりました。 ブログといえばWord Pressが有名でMovable Typeは利用者が少ないような気がしますが、利用者の方は使っていただけると嬉しいです。

mtdataapi.vim

vimのコマンドラインモードのマップ定義の仕方

  • 投稿日:
  • by
  • カテゴリ:

vimではマップという機能で様々なことが実現できます。 簡単に言うとショートカットキーを作ることができます。 また、vimにはモードが複数あり、モード毎にキーの意味が異なるのでモード毎に同じキーに別の意味を割り当てることができます。

モードの一つとして、コマンドラインモードがあります。コマンドラインモードは、vimを終了するときに使用できる:qでも利用しています。 :qとキー入力する場合、キー入力前の状態はノーマルモードです。そこから:を入力した時点でコマンドラインモードに移ります。 qはコマンドラインモードのコマンド(の省略形)です。そのあと、実際にはエンターキーを入力しますがこれによりqコマンドが実行されます。

そこでこのqコマンドに別の意味を持たせることがmapでできるのですが、設定の仕方を誤ってなかなか期待通りにならなかったので失敗した点を示します。 なお、実際に失敗したキーはqではなく、w(保存コマンド)でしたので、以下の例ではwコマンドで示します。

失敗 その1

mapコマンド(実際にはcnoremapコマンドを使用)のlhs側(新しく登録するキー)にエンターキーを記載しない

cnoremap w w<CR>q<CR>

mapコマンドの引数は大きく二つあり、新しく登録するキー列とそのキー列を入力した場合の意味を示すキー列等です。 その二つをlhs、rhsとそれぞれ表現します。Left Hand SideとRight Hand Sideの略と思われます。

以下のように書くと、エンターを押さなくてもrhs側のキー列が入力されたのと同じことが起こります。 そのため、:w filename と打とうとしていた場合でも:wと入力した時点でrhs側が入力されてしまいやりたかったことができません。 実現したいこと次第で対処法は変わりますが(つまり複数の選択肢がありますが)、今回は以下のように記載することで対処可能でした。

cnoremap w<CR> w<CR>q<CR>

失敗 その2

lhs、rhsに:を余計に記載する

cnoremap :w<CR> :q<CR>

cnoremapコマンドはコマンドラインモードでのキー入力に対して機能するので、lhsにもrhsにも:は不要です。 以下のようにすると:wしようとすると:qで終了するようになるはずです。

cnoremap w<CR> q<CR>

vim plugin の ftdetectの効かせ方

  • 投稿日:
  • by
  • カテゴリ:

vim plugin を作っていてなかなか解決できなかった課題のメモです。

vim ではファイルタイププラグインという種類のプラグインが作成できます。 ファイルタイププラグインはファイルタイプに合わせて挙動を変えることができるようにするためのプラグインです。 vim はファイルを開いた際に、そのファイルがどのファイルタイプか判別します。 ファイルタイプはC言語のようなプログラミング言語毎にあらかじめ定義されていますし、自分で作成することもできます。 自分で作成する場合には、ファイルタイプ名を決めて、そのファイルタイプの場合にどのような挙動にするかを定義したプラグインファイルを作成します。 例えば、ファイルタイプ毎に異なるマップを定義することができます。 その場合、プラグインファイルには定義したいマップコマンドを記述します。そうすることで、特定のファイルタイプの場合にのみそのマップコマンドが実行されるようになります。

ところで、ファイルを開くたびにそのファイルがどのファイルタイプかを判別する必要がありますが、自分で作成したファイルタイプのことはvimは知らないので、どのファイルが自作のファイルタイプに該当するかを定義する必要があります。 それには何らかの方法で以下のようにしてファイルタイプを指定する必要があります。これを実現する方法はいくつかありますが、その一つに ftdetect/*.vim というファイルを使う方法があります。

set filetype=aaaa

ftdetect/*.vim というファイルは、ファイルを開いた際(厳密にはバッファを開いた際)に自動的に読み込まれて実行されるファイルの一つです。 runtimepath配下にあるftdetect/*.vimを実行します。 このファイルは、以下の設定がされていないと読み込まれないようですが、これだけを設定していても読み込まれない場合がありました。

set runtimepath+=~/where/to/pluginpath/
filetype plugin on

読み込まれるようにするためには以下のように、runtimepathの設定の前に filetype offを設定する必要がありました。

filetype off
set runtimepath+=~/where/to/pluginpath/
filetype plugin on

WiMaxから固定回線に乗り換えた

  • 投稿日:
  • by

WiMAXから固定回線に乗り換えました。
引っ越ししたときにインターネット回線を解約して、次どうするかというときに、また引っ越す予定があったのでWiMAXにしました。
とりあえずはそれなりに速度も出て使えなくはないんだけど、Wi-Fiの電波が弱くて遅かったり、時々切れることもあった。
どこの回線が良いのかなぁとか悩んでいるうちに随分日が経ってしまったけれど、ようやく決めました。
月額料金も安いし(1200円)、速度も今のところ大丈夫そう。集合住宅のベストエフォートだから波があるかもしれないけれど。
Global IPも安いから準備できたら申し込もうかな。

blogの始め方その1

  • 投稿日:
  • by
  • カテゴリ:

どこに書くか

blogを書き始めようとするときに、まずはどこに書くかを決める必要があります。 世界中で人気のWord Pressというソフトウェアを使う手もありますが、ややニッチ(?)なMovable Typeというソフトウェアもあります。 Movable TypeはSix Apartという会社が開発しているソフトウェアで、商用ブログサービスとしてType Padというものもあります。 私はMovable Typeに書くことにしているのでMovable Typeを使います。

何で書くか

Movable TypeはWebインタフェースがあるので、ブラウザで書くのが通常ですがブラウザのテキストフォームに書くような形になるので使いづらいです。使いやすくするにはjavascriptを書いて機能拡張するなどの工夫が必要です。しかし、世の中には文章を書くためのツールとしてエディタがいくつもあり、それらを使う方が文書を書くには都合が良いのです。当たり前ですね。Movable TypeにはWebのGUIインタフェース以外にWeb APIも提供しています。このWeb APIはData APIという名前で定義されていて、これを使うと記事の新規作成や編集なども行えます。

そういうわけで、エディタで書いた文章をData APIを使ってMovable Typeに投稿する仕組みが実現できそうです。 これができればエディタで気持ちよく文章を書いて、そのままMovable Typeのblogエントリとして投稿できるはずです。 欠点があるとすれば、写真などの画像を入れようとすると難しくて、WebのGUIインタフェースの方が直感的に配置できたり、アップロードもできるので操作性は上です。 ですので、画像の取り扱いはWeb GUI、文字はエディタと使い分けることにします。

さて、エディタで書いた文章をData APIを使ってMovable Typeに投稿しようと思いますが、どのような操作性が良いでしょうか。 気軽に編集できるようにするには、エディタでテキストファイルを保存するような操作でData APIを使って投稿できる、修正できるというのが良いでしょうか。 ローカルに編集したり、Data APIを使って編集を反映したりと使い分けられるようにするのも手です。 とりあえずはローカルにあるファイルを編集し、上書き保存すると、Data APIを使ってMovable Typeの記事も編集(変更)されるという仕組みを目指します。

足りない機能

エディタでファイルを保存すると自動的にData APIにアクセスする仕組みを実現する必要が出てきました。 自動で行うというのがポイントですが、そのためには以下のような方法が考えられます。

  • ファイルの更新チェックをリアルタイムで行うようにカーネルフックモジュールを用意する
  • ファイルの更新チェックを行うデーモンを用意する
  • エディタの保存処理をフックする仕組みを用意する

カーネルフックモジュールで実装すると、色々と無駄で遅くなりそうです。 デーモンを用意するのも大げさな感じですし、無駄な感じです。 そこで今回はエディタの保存処理をフックする仕組みを用意することにします。

保存処理をフックできるようなエディタはいくつもありますが、筆者はvimが好きなのでvimを採用します。 vimはemacsと同じく拡張が用意で基本的になんでもできます。

vimの場合は、vim scriptという形で保存処理をフックする仕組みを記述すれば実現できます。 vim の設定ファイルはvimrcに記述しますが、この設定ファイルもvim script形式です。 そのため、vimrcに保存処理のフックすく仕組みを書けば解決できますが、その仕組みが巨大であったり、汎用的にできたり、公開したい場合にはプラグインとして作成することもできます。 今回はMovable Type利用者でかつ、vim利用者のためのプラグインを作成することにします。

足りない機能を補う

vim プラグインに必要な機能はData APIへのアクセスに関するものと、ローカルファイルの取り扱いに関するものに分けられます。 Data APIはHTTPアクセスなのでHTTPリクエストとレスポンスの取り扱いが必要です。 この部分はvital.vimを使います。 ローカルファイルの取り扱いは自分で用意します。

Data APIで取得したエントリはJSON形式で取得できますが、それをローカルファイルに保存する前にエディタで編集しやすい形に整形する必要があります。 また、その逆にローカルファイルの内容をData APIで投稿する際には逆の整形を行う必要があります。 こうした処理をちまちま書いていくといずれ出来上がります。 プラグインの処理の詳細は別の記事に書きますので、そちらを参照してください。

作成中の vim プラグイン vim-mtdataapi

記事を投稿する

プラグインが完成したら、ようやく記事を投稿できます。 長い道のりでした。

前回の記事に書いた件、以下のURLに知りたいことが書いてありました。 どうやらバグではなくて仕様ということらしいです。 help :todo を見ると、ドキュメントに書こうとしているようです。(以下に抜粋)

Space before comma in function definition not allowed: "function x(a , b)"
Give a more appropriate error message.  Add a remark to the docs.

参考URL

というわけで、 vim script の関数定義の際の引数リストのカンマの前にスペースは書けないということがわかりました。

vim scriptの関数定義時のE475発生条件

  • 投稿日:
  • by
  • カテゴリ:

vim scriptで関数定義しただけでE475という引数不正のエラーが出た。 以下のokfuncは問題無いが、ngfuncは定義時にエラーとなるようで、sourceコマンドで読み込むだけでエラーとなる。 つまり、カンマの前にスペースがあるとエラーとなる。

function! s:okfunc( arg1, arg2 ) abort
  echo "it's ok"
endfunction
function! s:ngfunc( arg1 , arg2 ) abort
  echo "it's ng"
endfunction

上記を適当なファイルに保存して、sourceで読み込むと以下のエラーとなった。

E475: 無効な引数です: arg1 , arg2 ) abort

確認した環境は8.1-1142

「チューリングの計算理論入門」を読んだ

「チューリングの計算理論入門」を読んだ。 チューリングマシンってどんなだっけ?と思って、手に取った本。 シャノンの情報理論入門の著者と同じで、本の位置付けも入門で同じ。 チューリングについて語る前に、その頃の時代背景の説明や関係しそうなしなさそうな人物の紹介などについて述べて、その後チューリングの話に入るという展開。 チューリングマシンというものは、そもそも物理的な機械でなくて、数学的な理論の実装機械というものであり、その説明のために時代背景やチューリングが達成したかった数学的課題を説明している。そして、チューリングマシンは数学的な基礎だけでなく、現代のコンピュータの基礎としての位置付けとなった。

チューリングマシンとは、無限長のテープ(記憶装置)と状態を持った機械であり、状態遷移とテープの読み書きのルールを定義することであらゆるアルゴリズムを実行できるものです。