2013年6月14日金曜日

VMware: vSphere ESXi 4.1 ゲストOSが起動できなくなる

 VMWareゲストOSを稼働させていると、突然動作が不安定になって起動出来なくなることがあります。
 以前vSphere ESXi上でゲストOS(RHELinux)を複数稼働させていたのですが、そのうち2つが同じ症状でクラッシュし、調査したところ原因はOSごとに割り当てあてたHDD容量が稼働時間の経過とともに不足してしまうことにありました。

■症状
 LinuxゲストOS使用中に動作が不安定になり、その後起動出来なくなる。
 OSを起動しても、途中でメンテナンスモードが立ち上がってしまう。

■エラー詳細
1. 起動時のエラー
 /dev/VolGroup00/LogVol00 contains a file system with errors. check forced.



 
2. メンテナンスモードが立ち上がる
 *** An error occurred during the file system check
 *** Dropping you to a shell; the system will reboot
 *** when you leave the shell.
 Give root password for maintenance

■原因
 OSを稼働させているうちにデータがHDに蓄積し、OSに割り当てた物理メモリが不足してしまう。
 メンテナンスモードにログインし、
 # df -k
 でハードディスクの容量をチェックして、使用率(Use%)が95%以上まで達していたら確実です。


■対応
 ゲストOSの物理メモリサイズを拡張する
 拡張したメモリをVMWareが動いているパーティションに割り当てる

■手順
1. ゲストOSのシャットダウン
 メンテナンスモードが表示された場合、一旦物理メモリサイズの拡張のため、ゲストOSをシャットダウンします。
 # shutdown -h now
 シャットダウンコマンドがきかない場合はクライアントツールで該当ゲストOSを右クリックし、電源→パワーオフを選択して「はい」をクリックし、強制的にパワーオフします。

2. 物理メモリの増量
 該当ゲストOSを右クリック
 →設定の編集
 →ハードディスク1
 →ディスクプロビジョニングから物理ボリュームを増やしたい分増やします。
【重要】あとで物理メモリ拡張の際に、手動で入力するため、何G増やしたのか覚えておいてください。

3. メンテナンスモードにログイン
 もう一度VMをパワーオンして起動し、ふたたびメンテナンスモードで「Give root password for maintenance」とログインを求められたら、rootのパスワードを入力してログイン。
 # パスワード

4. 現在のディスク容量チェック
 # /sbin/fdisk -l
 # df -k
 でハードディスクの容量をチェックして、使用率(Use%)が95%以上まで達していたら確実です。
 だいたい使用率80%超えから発生するようです。(1台めは80%でクラッシュしましたが、2台めは95%になるまで耐えました)

5. 増量した物理メモリをOSに認識させる
 ここから増やした物理メモリをOSに認識させ、ゲストOSが動いているパーティションに統合するための操作をします。
 以下のサイトの手順にしたがって、デバイスに増やした物理メモリを認識させて下さい。
 
 参考サイト:
 VMware仮想ディスクの拡張
 http://blog.as-is.net/2006/11/vmware.html
 (大変助かりました。ありがとうございました)

 ※上記エントリーのvmware-vdiskmanager.exeの実行は既にクライアントから実行済みなので必要ありません。
 fdiskでパーティションを切るところからはじめます。

【重要】
 ※このまま手順を進めた場合、物理ボリュームを作る部分でエラーとなる場合がありますが、その対応は後述します。
 まずはエラーがでる部分まで進めてください。

【重要】
 hda, sdaなどのデバイス名や、増やす容量は、設定に合わせて適宜読み替えてください。
 資料はデバイスがhda、増設は2Gですが、私の場合のゲストOSのデバイスはsdaで、増設は16Gでした。

【重要】
 OSが通常稼働している時に拡張する場合には割りとすんなりと実行出来ますが、今回のようなディスクエラーを起こしている状態で実行すると、物理メモリを作ってデバイスを拡張するところでエラーが発生します。
 # /usr/sbin/pvcreate /dev/sda3
 →file based locking initialisation failed エラーで止まる。

 容量がなくディスクが壊れた風になってしまっています。
 このエラーが出たら、一旦ここでfsckを実行し、Vol00を修復します。
 # fsck
 ※オプションなしで大丈夫です。自動でVol00を修復してくれます。
 実行途中で色々と聞かれますが、ひたすら「y」を打ち続けます。


 (終了後)# reboot
 
 そうするとOSが通常起動するので、すぐにターミナルを起動し、可及的速やかにpvcreateの続きから物理メモリを認識させてください。
 vgextendで/dev/hdc: open failed: メディアが見つかりません と表示されても次行にsuccessfullyとあれば問題ありません(たぶん)
 ※lvextendでInsufficient free space: 188 extents needed, but only 156 available 等のエラーになった場合、物理ボリュームサイズが何らかの要因で確保出来ていないので、減らして再トライしてください。succeccfullyと出るまでです。

6. 現在のディスク容量チェック
 無事に最後まで到達できたら、再びハードディスクの容量チェック。メモリ量が反映され、Use%が無事に下がっていれば完了です。
 # /sbin/fdisk -l
 # df -k


お疲れ様でした。

【参考】
VMware仮想ディスクの拡張
http://blog.as-is.net/2006/11/vmware.html

ディスク追加してリブートしたら、"Locking type 1 initialisation failed." というエラー
http://kenyo.tdiary.net/?date=200711

fsck
http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230781/

--------------------------------
だらしない更新ペースのblogですが、本エントリーで100記事目でした。
100記事目は、私のようなハードウェアリテラシーの低い人間が扱うにはハードルが高すぎたVMWareから、思い出の2台クラッシュ事件を。
今思い出しても寒気が・・・。
いつも様々な技術blog様に助けていただいています。
このblogが、少しでも皆様のお役に立つことが出来れば幸いです。

2013年6月13日木曜日

CakePHP:エラーメッセージをモデルに設定しているのに「1」と表示される

誰もこんなことしないのかもしれませんが、心底悔しかったのでメモしておきます。

inputのフォームコントロールに「'error' => false」を記述することで、inputタグのバリデーションメッセージを無効にできます。
(※バリデーションが実行されなくなるわけではないです)
これは主にデザイン上、エラーメッセージの表示場所を変更したい際などに設定します。

この値を「true」にしていると、すべからくエラーメッセージが「1」になります。

フォームをコピペしたりして色々やっているうちにこんな指定をしてしまったんだと思いますが、なんせ「1」としか表示されないので何が悪いのか全く判らずはまりました。
この記述を削除することでエラーメッセージが正常に表示されるようになりました。

※CakePHP 1.3で確認

PHP:window.openで文字化け 

window.openでページを開いたとき、何故か文字コードがutf-8ではなくShift-JISに自動的に変換される場合があります。
HTML,PHP共に文字コードはutf-8で作成しています。

→HTMLを呼び出すPHPプログラムの先頭に
<?php header("Content-type: text/html; charset=utf-8") ?>
を追加し、強制的にutf-8に変換するようにしました。

CakePHP:リファラーを取得する

リファラを取得するのには

$this->referer();

で取得できます。

たとえばCakePHPってページが/root/controller/action/202などURLのラストに引数を含んでいるパターンも多いんですが、もちろんこれもまとめて取得できます。

※CakePHP 1.3で確認

2013年6月10日月曜日

Flex:コンテキストメニュー(右クリックメニュー)が表示されない

Flexでコンテキストメニューを作ると、表示されない場合があります。
Flexのコンテキストメニュー数の制限は15個ですが、それ以下でも表示されないという謎現象。
それは使おうとする単語が、Flexの予約語の場合です。

少なくとも以下はアウトです。
「開く(Open)」
「コピー(Copy)」
「削除(Delete)」
「デバッガー(Debugger)」

このときは単語の後ろに全角スペースを押し込んで対処しました。
半角スペースは効きませんでしたが、&nbsp;は効きます。
こちらの方がいいかも?
空欄で出てくるとかでなく、メニューごと出てこなくなるので、かなり混乱しました。

予約語一覧
  • Save
  • Zoom In
  • Zoom Out
  • 100%
  • Show All
  • Quality
  • Play
  • Loop
  • Rewind
  • Forward
  • Back
  • Movie not loaded
  • About
  • Print
  • Show Redraw Regions
  • Debugger
  • Undo
  • Cut
  • Copy
  • Paste
  • Delete
  • Select All
  • Open
  • Open in new window
  • Copy link
  • Copy Link Location
  • Del
【参照】
http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/ui/ContextMenuItem.html
日本語ソースを見つけられませんでした。
時間があるときリスト化したいです。


2013年6月6日木曜日

VB:HTMLDocument InnerHTML, OuterHTMLでパス(hrefやsrc)がローカルのパスに変換されてしまう

VB (.NET Framework 2.0) のHTMLDocument (HTMLElement)のメソッドのInnerHTML, OuterHTMLでhref(aタグのhrefやimgタグのsrcなど)を出力すると、パスが自動的にローカルのパスに変換されてしまいます。
散々探したものの、変換されないようにすることは出来ないようで。
サーバ上で実行すればいいのかもしれませんが、ローカルで確認出来ないもの困ります。
そもそも相対パスがローカルからの絶対パスになってしまうわけで、サーバ上でもうまくいくのかどうか。
なかなかこれだという情報がなく。
今時VBでHTML解析するのも流行らないのでしょうか。。

似たようなお悩みの人は見つけました
avoid innerHTML parsing
http://bytes.com/topic/javascript/answers/91167-avoid-innerhtml-parsing

私はinnerHTMLで取得したものを処理する必要があったので、一度パスをすべて保管してから変換後に再設定することにしました。
泥臭いと思いつつ、URLにある解決策の方法で、いちいちタグを生成して変換後のHTMLの元の場所にappendChildして行くのが出来なかったのです。

こんな感じでまず最初に配列で取得しておいて(*_divはHtmlElement。bodyタグの中身)
Dim _as As HtmlElementCollection = _div.GetElementsByTagName("a")
Dim a_href() As String = Nothing
Dim href_count As Integer = 0
For Each _a As HtmlElement In _as
    ReDim Preserve a_href(href_count)
    a_href(href_count) = _a.GetAttribute("href")
    href_count = href_count + 1
Next
変換が終わったらこれで元に戻す。
href_count = 0 '初期化
For Each _a As HtmlElement In _as
    If (a_href(href_count) <> "") Then
        _a.SetAttribute("href", a_href(href_count))
    End If
    href_count = href_count + 1
Next
途中でurlやimgをappendしてしまった場合、配列の参照エラーになりますのでお気をつけください。

にしても、勝手に変換しないように出来るのが一番いいんですけれども。