Mac OS X Yosemite からの NFS 経由でのNASへの書き込みが激遅なのを何とかする
Solarisとのファイル共有も考えてNFSが喋れるNAS(NETGEAR ReadyNAS)を買ったのだけど、Mac からの NFS の書き込みが激遅なのでなんとかしてみた。
改善前の状態
Mac ⇔ NAS 間ギガビットでつながっているにも関わらず、スループットが数Kbps程度で、以下のエラーが延々と繰り返す。
nfs server readynas:/data/Documents: not responding nfs server readynas:/data/Documents: is alive again
ついカッとなって Wireshark でパケットを調べた所、Mac からの NFS の COMMIT リクエストに対する NAS側からのリプライに時間がかかっている(30秒超!!)ことがわかった。
対策
NFS マウント時に async オプションを追加し、データの WRITE 後に COMMIT リクエストを出さないようにする。
1) /etc/nfs.conf に以下の行を追記し async オプションの使用を許可する
nfs.client.allow_async = 1
2) /etc/fstab を作成し NFS マウントのエントリを追加する。その際マウントオプションとして async を指定
readnas:/data/Documents /data nfs async
※ 念のため、/data はマウントポイントで予め mkdir(1) コマンドでディレクトリを作っておく必要があります。また、readnas は 私の環境での NFS のサーバ(NAS)のホスト名です。/data/Documents はNFSサーバ(NAS)上で共有されているディレクトリです。
3) root ユーザで automount(1) コマンドを使って fstab ファイルの内容をロードする
$ sudo /usr/sbin/automount -vc
対策2
起動時に自動マウントする必要はない場合は、手動でマウントするだけであれば以下のコマンドでも async オプションをつけてマウントできます
$ sudo mount_nfs -o async,nosync readynas:/data/Documents /data
もちろん不要になったらアンマウントもできます。
$ sudo diskutil umount /data
結果
スループットが 400Mbps 程度に改善!
Visual Studio 2013 で emacs キーバインドを使う
Visual Studio 2010 ではEmacsEmulationsという拡張機能が提供されていてEmacsキーバインドが使えたんだけど、Visual Studio 2013 ではこの機能拡張が通常は使えないので、これを使えるようにしようという話です。
元ネタはこちらの stackoverflow のQA
Emacs Keybindings in Visual Studio 2012 or 2013 - Stack Overflow
ぶっちゃけ一番の解答とコメントの補足を合わせたて日本語化しただけですのでこのQA直接見るだけでもOKです。
環境
私が確認した環境は以下のとおり
Windows | Windows 7 Professional SP1 + IE 11 |
Visual Studio | Visual Studio 2013 Premium Edition |
手順
1. EmacsEmulations をダウンロード
2. ダウンロードした EmacsEmulations.vsix ファイルの名前を EmacsEmulations.zip に変更して zip ファイルとして解凍する。
3. 解凍したフォルダに含まれるextensions.vsixmanifestファイルをテキストエディタ等で開き タグの値を「10.0」から「12.0」に変更する。
<VisualStudio Version="12.0"> <Edition>Pro</Edition> </VisualStudio>
※Visual Studio 2012の場合、値は「11.0」だそうです。私は未確認です。
4. 解凍したフォルダに含まれるEmacs.vskを「C:\Program Files\Microsoft Visual Studio 12.0\Common7\IDE」フォルダにコピーする。(※ 64ビットWindows の場合は「C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE」フォルダにコピー)
5. extensions.vsixmanifest を含む解凍したフォルダに含まれるファイルを再度 zip 圧縮する。
この際、解凍した EmacsEmulations フォルダを圧縮するのではなく、EmacsEmulationsフォルダに含まれる全てのファイル、フォルダを選んで zip ファイルを作るのが大事。
6. EmacsEmulations.zipの拡張子を再びEmacsEmulations.vsixに変更
7. 管理者として実行したコマンドプロンプからEmacsEmulations.vsixを実行
C:\>start EmacsEmulations.vsix
もし「このVSIXパッケージは、ルートファイルextension.vsixmanifestが含まれていないため無効です。VSIXファイルが破損している可能性があります」というエラーが出た場合には手順5.のフォルダごと圧縮してしまったことが原因と思われます。解凍した中身のファイルとフォルダを全て選択してZip圧縮してみてください。
GlassFish 付属の JavaDB(Derby) 10.9.1.0 を Java7u51 で起動する
Java7u51の Socket Permission の変更によって49152未満のポート番号でソケットを Listen する場合には明示的にパーミッションを与えることが必要になったようです。
参考: Java™ SE Development Kit 7 Update 51 Release Notes
このため、デフォルトでTCP ポート1527でリッスンする JavaDB も以下のようなエラーを吐いて起動できなくなりました。
C:\glassfish4\glassfish\bin>asadmin start-database Starting database in Network Server mode on host 0.0.0.0 and port 1527. Unable to start database. Please check log in C:\glassfish4\glassfish\databases\derby.log. Command start-database failed.
実際のログファイルの中はこんな感じ
Sun Feb 02 06:29:10 UTC 2014: Booting Derby version The Apache Software Foundation - Apache Derby - 10.9.1.0 - (1344872): instance a816c00e-0143-f149-323a-00000c6e8579 on database directory C:\glassfish4\glassfish\databases\dnd_db with class loader sun.misc.Launcher$AppClassLoader@1860045 Loaded from file:/C:/glassfish4/javadb/lib/derby.jar java.vendor=Oracle Corporation java.runtime.version=1.7.0_51-b13 user.dir=C:\glassfish4\javadb\bin derby.system.home=C:\glassfish4\glassfish\databases Database Class Loader started - derby.database.classpath='' Sun Feb 02 07:34:10 UTC 2014 : Security manager installed using the Basic server security policy. Sun Feb 02 07:34:11 UTC 2014 : access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") Sun Feb 02 07:34:11 UTC 2014 : access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372) at java.security.AccessController.checkPermission(AccessController.java:559) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkListen(SecurityManager.java:1134) at java.net.ServerSocket.bind(ServerSocket.java:375) at java.net.ServerSocket.<init>(ServerSocket.java:237) at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:231) at org.apache.derby.impl.drda.NetworkServerControlImpl.createServerSocket(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.access$000(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at org.apache.derby.impl.drda.NetworkServerControlImpl.blockingStart(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.executeWork(Unknown Source) at org.apache.derby.drda.NetworkServerControl.main(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.sun.enterprise.admin.cli.optional.DerbyControl.invokeNetworkServerControl(DerbyControl.java:158) at com.sun.enterprise.admin.cli.optional.DerbyControl.main(DerbyControl.java:245) java.security.AccessControlException: access denied ("java.net.SocketPermission" "localhost:1527" "listen,resolve") at java.security.AccessControlContext.checkPermission(AccessControlContext.java:372) at java.security.AccessController.checkPermission(AccessController.java:559) at java.lang.SecurityManager.checkPermission(SecurityManager.java:549) at java.lang.SecurityManager.checkListen(SecurityManager.java:1134) at java.net.ServerSocket.bind(ServerSocket.java:375) at java.net.ServerSocket.<init>(ServerSocket.java:237) at javax.net.DefaultServerSocketFactory.createServerSocket(ServerSocketFactory.java:231) at org.apache.derby.impl.drda.NetworkServerControlImpl.createServerSocket(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.access$000(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl$1.run(Unknown Source) at java.security.AccessController.doPrivileged(Native Method) at org.apache.derby.impl.drda.NetworkServerControlImpl.blockingStart(Unknown Source) at org.apache.derby.impl.drda.NetworkServerControlImpl.executeWork(Unknown Source) at org.apache.derby.drda.NetworkServerControl.main(Unknown Source) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at com.sun.enterprise.admin.cli.optional.DerbyControl.invokeNetworkServerControl(DerbyControl.java:158) at com.sun.enterprise.admin.cli.optional.DerbyControl.main(DerbyControl.java:245)
今後 JavaDB 側でも対応してくるとは思いますが「なんでもいいからとりあえず起動したい」という方のために私の行った対策を方法を書いておきます。
なお、以下の手順では以下のフォルダに GlassFish がインストールされていると想定しています。これはデフォルトのフォルダですが、もし変えている場合には逐次読み替えてください。
- C:\glassfish4
※ ちなみに、私の環境は Windows Azuer 上の Windows Server 2012 Datacenter ですがこちらはあまり影響していないと思います。
1. セキュリティポリシーファイルの作成
C:\glassfish4\javadb\bin\security.policy
grant { permission java.net.SocketPermission "localhost:1527", "listen"; permission java.security.AllPermission; };
2. JavaDB のJava起動オプションの追加
C:\glassfish4\javadb\bin\NetworkServerControl.bat (Linux の場合には NetworkServerControl)に以下のJava起動オプションを追記します。
セキュリティ・マネージャを有効にする
-Djava.security.manager |
Databaseが置いてあるフォルダのパスの指定
-Dderby.system.home=C:\glassfish4\glassfish\databases |
※ ここではデフォルトの Dabase の場所を指定しています。Dabaseファイルを別の場所に置かれている場合にはそちらを指定してください
ファイルの実際の行は以下のようになります。
NetworkServerControl.bat
... :runNoClasspath "%_JAVACMD%" %DERBY_OPTS% -Dderby.system.home=C:\glassfish4\glassfish\databases -Djava.security.manager -Djava.security.policy=security.policy -classpath "%LOCALCLASSPATH%" org.apache.derby.drda.NetworkServerControl %DERBY_ARGS% %DERBY_CMD_LINE_ARGS% goto end ...
4. JavaDB の起動
先ほど編集したNetworkServerControlでJavaDBを起動します
C:\glassfish4\javadb\bin>NetworkServerControl start Sun Feb 02 08:14:45 UTC 2014 : Apache Derby Network Server - 10.9.1.0 - (1344872) started and ready to accept connection s on port 1527
これで無事ポート1527 を Listen して起動できました!
Solaris 用 Twitter ファイルシステム
Twitter をファイルシステムとしてマウントする擬似ファイルシステムです。
任意の場所にマウントすると 「home」, 「mention」 といったタイムライン名を持つファイルが現れて cat(1M) や tail(1M) などのコマンドでタイムラインを表示することができます。また vi(1M)、emacs(1M)、もしくはリダイレクトを使って「post」ファイルに書き込めば通常のファイル操作だけでツイートすることもできます。
English Here.
カーネルモードの擬似ファイルシステムがありユーザモードデーモンと協調して動作することで実現しています。簡単に言うと FUSE みたいなものです。
前提条件
1. IUMFS ファイルシステムモジュール
カーネルモードのファイルシステムモジュールが必要になります。
以下のリンクからダウンロードしてビルド、インストールしてください。
kaizawa-iumfs.tar.gz
IUMFS について詳しくはこちらをご覧ください。
2. JRE7/JDK7 以降。
3. Twitter アカウント
ソースコード
ソースコードは Github で管理していますのでこちらから参照できます。
https://github.com/kaizawa/iumfs-twitterfs
コンパイルとインストール
ユーザモードデーモンプログラム
ユーザモードデーモンプログラムはJavaで書かれています。
上にリンクの圧縮ファイルの中にはコンパイル済みの jar ファイルが含まれていますので基本的には Java のコードを再コンパイルする必要はありません。ただ、もし必要であれば以下のように ant コマンドでコンパイルすることもできます。
sol11:/var/tmp/iumfs-twitterfs $ ant Buildfile: build.xml jar: init: compile: [javac] Compiling 107 source files to /var/tmp/iumfs-twitterfs/cmd/build/classes jar: [jar] Building jar: /var/tmp/iumfs-twitterfs/cmd/twitterfsd.jar BUILD SUCCESSFUL Total time: 2 seconds sol11:/var/tmp/iumfs-twitterfs $
使い方
マウント方法
方法1) Twitterファイルシステムをオートマウントを利用してマウントする(推奨)
オートマウントを利用して自動的にマウントさせることができます。この方法なら管理者権限で mount(1M)コマンドをマニュアルで実行する必要はありません。
mount(1M) コマンドでのマウントと違い、一般ユーザは管理者の介入なしで自分の Twitter アカウントをセットアップすることができます。
圧縮ファイルの中に含まれる setup_automount というシェルスクリプトを管理者権限で実行してください。オートマウントの設定が自動的に行われます。
# ./setup_automount
何をしているか気になる方はこのスクリプトを見て自分で各コマンドを実行してください。
簡単に言うと automounter マップファイルを作成してマウントポイントが置かれる /twitter ディレクトリを作成し autofs サービスをリスタートしています。
方法2) mount(1M)コマンドを使ってマウントする
オートマウントを利用せずに直接 mount(1M) コマンドを使ってマウントすることもできます。
マウントする際はファイルシステムタイプとして「iumfs」を指定してください。
IUMFS ファイルシステムモジュールをインストールしていれば iumfs 専用の mount コマンドもインストールされており、ファイルシステムタイプをしていすることでこちらが自動的に使われます。
(注) オートマンとを利用するう場合と違い、複数の twitter アカウントを使ってタイムラインを見たい場合には毎回 mount(1M) を実行する必要があります。
使い方
mount -F iumfs -o user=user_name twitters_url mount_point
- user_name は twitter アカウントです。
- twitter_url は twitter filesystem を表す文字列です
- mount_point は /mnt 等のファイルシステムがマウントするパスです。
例)
# /usr/sbin/mount -F iumfs -o user=kaizawa2test twitterfs://twitter.com /mnt
実は上記の「twitterfs」と「twitter.com」に意味は無く実際には何か文字が入っていれば大丈夫です。(でも省略はできません)
-o オプションで twitter アカウントをしていするのを忘れないようにしてください。これは必須オプションです。
Twitterファイルシステムユーザモードデーモンの起動
圧縮ファイルを展開するとその中に twitterfsd.jar デーモンプログラム が含まれています。このデーモンプログラムは twitter4j ライブラリを利用して twitter.com にアクセスします。
デーモン起動用に start-twitterfsd というシェルスクリプトを用意してありますのでこちらを使って起動してください。
$ ./start-twitterfsd
もしインターネットに接続するためにプロキシサーバを経由必要がある場合には以下のようにしてプロキシサーバを指定してください。
$ ./start-twitterfsd -Dhttp.proxyHost=192.168.1.1 -Dhttp.proxyPort=8080
タイムラインの表示
オートマウントを使用している場合には /twitter/<あなたのアカウント> に移動してください。<あなたのアカウント>はあなたの Twitter アカウントになります。このディレクトリが予め存在する必要はありません。あなたがこのディレクトリに cd コマンドでアクセスした際に automount デーモンが自動的にディレクトリを作成します。
$ cd /twitter/kaizawa2test
もしこれが始めてのアクセスであれば「setup」というファイルが見つかるはずです。
$ cd /twitter/kaizawa2test $ ls ./ ../ setup*
これは Twitter のアクセストークンを取得するための初期設定プログラムです。
このプログラムを実行すると以下の様なメッセージが現れます。
$./setup Open the following URL and grant access to your account: http://api.twitter.com/oauth/authorize?oauth_token=9zhKalThfMKB5R20C2pGjdBnc0ydWIODzeDmFS3fsNI Enter the PIN(if aviailable) or just hit enter.[PIN]:
これは twitterfsd デーモンがあなたのタイムラインを取得したりツイートしたりするのに必要な手順になります。
setup プログラムの出力記載されたURLにアクセスしてください。以下のようなページが現れます。
もしこのアプリを承認する場合には「連携アプリを承認」を押してください。
表示された PID をコピーし、先ほどの setup プログラムのプロンプトに入力します。
$ ./setup Open the following URL and grant access to your account: http://api.twitter.com/oauth/authorize?oauth_token=9zhKalThfMKB5R20C2pGjdBnc0ydWIODzeDmFS3fsNI Enter the PIN(if aviailable) or just hit enter.[PIN]:9194085 <= ここにPIN番号を入力します Twitter access token setup successfully
これで twitterfsd デーモンは twitter サーバと通信可能な状態になりました。
もしここでエラーになった場合にはあなたの環境ではプロキシサーバが必要である可能性があります。
以下のようにプロキシサーバをしていして setup プログラムをやり直してみてください。
$ ./setup -Dhttp.proxyHost=192.168.1.1 -Dhttp.proxyPort=8080
setup プログラムが終了した後改めてアカウントのフォルダを見ると以下のようにみえるはずです。
「post」以外のそれぞれのファイルはタイムラインを表しています。
また、followers ディレクトリはフォロワーのタイムラインのファイルを持っており、friends ディレクトリはフォローしている各アカウントのタイムラインのファイルを持っています。*1
home | ホームタイムライン |
user | 自分の投稿のタイムライン |
followers/<アカウント> | フォロワーのタイムライン |
friends/<アカウント> | フォローしているアカウントのタイムライン |
retweet_of_me | リツイートされた自分の投稿のタイムライン |
これらのタイムラインファイルを UNIX コマンドで開くことができます。
各ファイルはバックグラウンドで自動的に更新されていきます。
例) ホームタイムラインを tail(1M) コマンドでチェックする
home タイムラインはストリームAPIを使っているためリアルタイムに近い更新が行われます。
ただし他のタイムラインについてはTwitter API の取得回数制限回避のため遅めです。*2
タイムライファイルはテキストファイルのように見せていますので cat(1M) や vi(1M) といったテキストコマンドで操作できます。
もちろん、ファイルをコピーしてもコピー先のファイルは更新されませんのであしからず。
ツイートを投稿する
通常の投稿
「post」ファイルがツイート投稿用のファイルです。ファイルの中身は常に空でサイズも0です。
このファイルに UTF-8 で文字列を書き込むことによって Twitter のツイートとして投稿できます。
Twitter 側でこのファイル書き込みが実際に投稿されていることを確認できます。
もしファイルに対して140時以上を書き込んだ場合には、メッセージは自動的に140文字づつに分割され投稿されます。
2番目以降の投稿には「(contd)」という接頭辞が着きます。
リプライとしての投稿
replies フォルダにリプライを投稿したいアカウントのファイルを作成しそのファイルにメッセージを書き込んで下さい。
例) ichgia2test というアカウントに「着いたよ」というリプライを送る。
上記のように予めファイルがある必要はありません。echo のリダイレクト先としてアカウント名をするだけでOKです。
すると、以下のように @ichgia2test という接頭辞が付いて投稿されます。
通常のメッセージに @ichgia2test と自分で付けて投稿しても同じことですが、この方法の場合投稿の前にアカウントの存在確認を行います。もし投稿先のアカウントが存在しない場合には ENOENT が返ります。
Tips
フォローしているアカウントへのリプライを非表示
デフォルトではホームタイムラインにはあなたがフォローしていないアカウントからフォローしているアカウントへのリプライが全て表示されます。これを止めるためには -Dtwitter4j.stream.user.repliesAll=false オプションを使って twitterfsd を起動します。
$ ./start-twitterfsd -Dtwitter4j.stream.user.repliesAll=false
FAQ
friends、followers フォルダが空なんだけど?
デフォルトでは空です。ls コマンド等で初めてのアクセス後、バックグラウンドで friends, follower のチェックが行われて徐々に追加されていきます。Twitter APIの制限のため1分間に20アカウントづつ増えます。
friends、followers 以下のアカウントのタイムラインが全然更新されないんだけど?
Twitter API の更新回数制限のため5秒に1アカウント分のタイムラインしか更新することができません。このため、friends、follower 数の合計が多い場合には各アカウントの更新頻度は長くなります。
例) 計1,000 の follower/friends が居る場合
更新間隔 = 5 x 1,000 = 5,000 秒 = 83分 = 1時間23分
replies フォルダ空なんだけど?
デフォルトは空です。エディタやリダイレクトなどを使ってリプライを送りたいTwitterアカウント名のファイル名として指定してを作成します。
ただし、実際に存在しないアカウント名を使っても ENOENT エラーとなりファイルは作成されません。
オートマウントディレクトリに知らない名前のがあるんだけど?
オートマウントディレクトリ(例では /twitter) 以下のフォルダは automountd によって自動的に作成されます。
ご自身で明示的にアクセスしなくてもシェルなどのアプリがファイルの存在を確認するためにアクセスしようとするとその名前のフォルダが作成されてしまいます。不要だと思われる場合には管理者権限で umount(1M) してください。
sol11:/twitter $ ls ./ ../ .paths/ kaizawa2test/ sol11:/twitter $ sudo umount /twitter/.paths sol11:/twitter $ ls ./ ../ kaizawa2test/
既知の問題
- タイムラインファイルのアクセス制限が行われていません。なのでシステムにログイン可能なユーザはすべてのタイムラインが読めてしまいます。
License
Twitter Filesystem is provided under Apache License 2.0.
This program is an open source software and free of charge.
You can use this program freely for any commercial and non-commercial use.
This program uses twitter4j.
Twitter4J
Copyright (c) 2007, Yusuke Yamamoto All rights reserved.
http://twitter4j.org
ESXiMonitor: ESXi モニターツール
ESXiMonitor とは?
ESXiMonitor はリモート VMware ESXi サーバ上のゲストOSの電源の状況を監視し、パワーオン、パワーオフ、リセット、シャットダウンなどの電源操作を行う行うツールです。
English page is here
※ このツールは Java で書かれており UI は JavaFX を使っています。
また、ESXi サーバの操作には VMware VI (vSphere) Java API を利用しています。
前提条件
ESXi サーバのサポートモードの有効化
ESXi サーバに対して電源操作を行うためには root ユーザでの SSH ログイン(通称サポートモード)を有効にする必要があります。以下のドキュメントを参考にしてください。
ダウンロードとインストール
以下のリンクをクリックするだけでこのツールを起動することができます。(*1)(*2)
Java プログラムとライブラリが自動的にダウンロードされシステムにインストールされます。
最新のソースコードをダウンロードしたい場合には以下のリンクからダウンロードできます。
コードは Github にあげているので Github 上でコードを見ていただくこともできます。
https://github.com/kaizawa/esximonitor
(*1) Mac OS の場合には esximonitor.jnlp というファイルがダウンロードされるだけで直接起動できないようです。起動するためには Finder からダンロードフォルダを開き esximonitor.jnlp ファイルを右クリックして「このアプリケーションで開く -> Java Web Start.app(デフォルト)」で起動してください。
(だれかブラウザから直接起動できる方法ご存知の方教えてください!!)
(*2) jar ファイルを自著署名しているので起動時に以下のような警告がでます。
もし問題無いと判断されましたら「リスクを受け入れて、このアプリケーションを実行します」にチェックをいれて「実行」ボタンを押してください。
将来的にはこの方法でも起動ができなくなるようなのでコード証明書の取得も検討中です。(高い…)
コンパイル方法
上記のソースコードをダウンロードしてきた場合には圧縮ファイルを展開したディレクトリで ant コマンドを実行することでコンパイルすることができます。
$ ant Buildfile: /Users/ka78231/NetBeansProjects/esximonitor/build.xml : default: BUILD SUCCESSFUL Total time: 7 seconds $
使い方
ESXiMonitor の起動
ESXi サーバの指定
初回起動時以下のような画面が現れ ESXi サーバの情報が求められます。
ホスト名(もしくはIP)、ユーザ名、パスワードを入力し最後に「Add」ボタンを押してください。
正常にログインできれば ESXi サーバ上の VM のリストが現れるはずです。
複数の ESXi サーバの監視
もし複数台の ESXi サーバの監視を行いたい場合には、メニューから Edit -> ESXi Servers をたどってください。
するとサーバの一覧画面が現れるはずです。「New」ボタンを押すと初回起動時と同様に ESXi サーバの情報を入力する画面が表示されます。
なお、ESXiMonitor ツールはこれらの情報を覚えていますので、次回起動時に再度サーバ情報を入力する必要はありません。
その後、監視したい方のサーバをコンボボックスから選択肢ます。
※ コンボボックスの右横の「Show All Servers」にチェックをいれると全てのサーバを一度に監視できます。
License
ESXiMonitor is provided under BSD License.
This program is an open source software and free of charge.
You can use this program freely for any commercial and non-commercial use.
This tool is utilizing following libraries and icons.
VMware VI (vSphere) Java API
http://vijava.sourceforge.net
Ganymed SSH-2 for Java
http://www.ganymed.ethz.ch/ssh2/
FAMFAMFAM - Silk Icons.
http://www.famfamfam.com/lab/icons/silk/
Mac OS X 環境で NetBeans 7.4 + JDK7u45 が頻繁にハングする
タイトルの通り、以下の環境にて NetBeans がハングし頻繁に操作不能に陥っていました。
調べたところどうやら以下の Mac OS X 向けの Java の Bug に該当するようです。
JDK-8025588 : macosx Frozen AppKit thread in 7u40
事象の確認方法としては jstat コマンドなどでハングしたときの Netbeans のスレッドダンプを確認すると以下の様なダンプが見られるとのことです。
$ /usr/bin/jstack -F 69760 ... Thread 1287: (state = IN_NATIVE) - sun.lwawt.macosx.LWCToolkit.doAWTRunLoop(long, boolean) @bci=0 (Interpreted frame) - sun.lwawt.macosx.LWCToolkit.invokeAndWait(java.lang.Runnable, java.awt.Component) @bci=67, line=549 (Interpreted frame) - sun.lwawt.macosx.LWCToolkit.invokeAndWait(java.util.concurrent.Callable, java.awt.Component) @bci=11, line=489 (Interpreted frame) - sun.lwawt.macosx.CAccessibility.invokeAndWait(java.util.concurrent.Callable, java.awt.Component) @bci=2, line=75 (Interpreted frame) - sun.lwawt.macosx.CAccessibility.getFocusOwner(java.awt.Component) @bci=8, line=521 (Interpreted frame) ...
(* 69760 は NetBeans のPIDです.)
この Bug レポートによると現時点 (JDK7u45) では以下の回避策があるようです。
- JDK7u25 を使う
- JDK8 Early Access を使う
以下、念のためそれぞれの実施方法です。
回避策1: JDK7u25 を使う
現在JDK7u45(もしくはu40)を使っているという前提です。
JDK7u45をアンインストール
/Library/Java/JavaVirtualMachines ディレクトリに移動し JDK7u45(もしくはu40)を削除
$ cd /Library/Java/JavaVirtualMachines $ rm -rf jdk1.7.0_45.jdk
JDK7u25のダウンロード
回避策2: JDK8 Early Access を使う
追記
JDK7u25を使う対策についてですが、MacBook Pro の Retina ディスプレイを使っている場合、JDK7u25ではRetinaに対応していないので表示がぼんやりとしてと悲しい状態になります。
JDK7u45の場合
JDK7u25の場合
heapstat: C-heap の利用状況確認
heapstat コマンドとは?
heapstat コマンドは動作中のプロセスや core ファイルから、アプリケーションの C-heap 領域の利用状況を表示するコマンドです。
アプリケーションが malloc(3C) を使ってメモリを確保した場合アプリの必要に応じて C-heap 領域が拡張します。しかしながら、free(3C)を呼び出しても実際にはこのメモリブロックはシステムに返却されません。フリーされたメモリブロックはフリーリストの置かれ、その後のアプリからの確保要求のために保持されます。
このコマンドは C-heap 内の空きメモリサイズを表示するツールになります。
使い方
heapstat [-v] { pid | core } [interval]
プロセスID(PID)を引数に与えることで heapstat コマンドは動作中のプロセスの C-heap 領域の利用状況を表示します。
$ heapstat 14641 free tree next free small free bottom size heap size free size free% size(kb) size(kb) size(kb) (kd) (kb) (kb) (%) 16 0 17 3 6656 36 0
もし引数としてインターバルも指定した場合、heapstat コマンドは指定した間隔(秒)毎に利用状況を出力します。
$ heapstat 14680 2 free tree next free small free bottom size heap size free size free% size(kb) size(kb) size(kb) (kd) (kb) (kb) (%) 327 0 67 0 8192 395 4 327 0 67 0 8192 395 4 327 0 66 227 8192 621 7 327 0 66 227 8192 621 7 327 0 66 227 8192 621 7 327 0 66 227 8192 621 7
もし PID の代わりに core ファイルのファイル名を指定した場合は core ファイルに含まれる C-heap 領域の使用状況を出力します。
$ heapstat /var/tmp/core.974 free tree next free small free bottom size heap size free size free% size(kb) size(kb) size(kb) (kd) (kb) (kb) (%) 0 1 51199 52851 129856 104051 80
出力項目
free tree size
Solaris の malloc は Self-Adjusting Binary Search Trees を使ってフリーされたメモリブロックを管理しています。
この列はこのバイナリツリー配下のフリーサイズの合計値を報告します。
next free size
free(3C)が呼ばれたタイミングではフリーされたブロックはフリーリストには追加されません。それらは「Last Freed」といフラグがつけられ、次回の malloc(3C)呼び出しまで保持されます。もし次回の malloc(3C) での要求サイズがこの保持したブロックのサイズに合致するなら、それがそのままアプリに返却されますが、もし要求に合わない場合にはフリーリストに追加されます。
この列は最後にフリーされ保持されているメモリブロックのサイズを表示します。
small free size
もし malloc(3C) が 64バイト以下のサイズのメモリを要求された場合、malloc(3C) は小さなサイズで C-heap を拡張する事無く、連続した小さなブロックを一度に確保し、後でリクエストされるまで保持します。(128個)
この列はこの未仕様の小さなブロックの合計サイズを表示します。
bottom size
この列はC-heap領域のの最後のフリーな塊のサイズを表示します。
heap size
この列は現在のアプリケーションのC-heap領域のサイズを表示します。
free size
この列はC-heap 領域内の空きサイズを表示します。
= free tree size + next free size + small free size + bottom size
free%
この列はC-heap領域内のの空きサイズの比率を表示します。
コンパイル方法
./configure、make にてコンパイルします。
インストールする際には root 権限のあるアカウントで make install を実行します。
$ ./configure checking for gcc... gcc checking whether the C compiler works... yes checking for C compiler default output file name... a.out checking for suffix of executables... checking whether we are cross compiling... no checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ISO C89... none needed checking for g++... g++ checking whether we are using the GNU C++ compiler... yes checking whether g++ accepts -g... yes checking for a BSD-compatible install... /usr/bin/ginstall -c checking for isainfo... yes configure: creating ./config.status config.status: creating Makefile config.status: creating heapstat-test/Makefile $ make gcc -g -I. -lproc -DPACKAGE_NAME=\"heapstat\" -DPACKAGE_TARNAME=\"heapstat\" -DPACKAGE_VERSION=\"0.1.0\" -DPACKAGE_STRING=\"heapstat\ 0.1.0\" -DPACKAGE_BUGREPORT=\"admin2@whiteboard.ne.jp\" -DPACKAGE_URL=\"\" -W -Wall -Wno-unknown-pragmas -Iinc -m64 -o heapstat heapstat_main.c gcc -g -I. -lproc -DPACKAGE_NAME=\"heapstat\" -DPACKAGE_TARNAME=\"heapstat\" -DPACKAGE_VERSION=\"0.1.0\" -DPACKAGE_STRING=\"heapstat\ 0.1.0\" -DPACKAGE_BUGREPORT=\"admin2@whiteboard.ne.jp\" -DPACKAGE_URL=\"\" -W -Wall -Wno-unknown-pragmas -Iinc -m32 -o heapstat32 heapstat.c gcc -g -I. -lproc -DPACKAGE_NAME=\"heapstat\" -DPACKAGE_TARNAME=\"heapstat\" -DPACKAGE_VERSION=\"0.1.0\" -DPACKAGE_STRING=\"heapstat\ 0.1.0\" -DPACKAGE_BUGREPORT=\"admin2@whiteboard.ne.jp\" -DPACKAGE_URL=\"\" -W -Wall -Wno-unknown-pragmas -Iinc -m64 -o heapstat64 heapstat.c $ sudo make install /usr/bin/ginstall -c -d -m 0755 -o root -g bin /usr/local/bin /usr/bin/ginstall -c -m 0755 -o root -g bin heapstat /usr/local/bin /usr/bin/ginstall -c -m 0755 -o root -g bin heapstat32 /usr/local/bin /usr/bin/ginstall -c -m 0755 -o root -g bin heapstat64 /usr/local/bin
テストした Solaris バージョン
- OpenIndiana 151.1.7
- Solaris 11.1
このコマンドは Illumos(OpenSolairs)の libc malloc(3C) のコードを元に書いています。
現在のところ Oracle Solaris 11.1 でも動作することは確認できていますが、今後 Solaris の malloc(3C)の実装が変わった場合には、このコマンドが正しく動作しなくなる可能性があります。
License
This program is provided under CDDL License.