Asustor NASでVNCサーバーを本体起動時に自動起動するようにする

Windows PC上で走らせたTightVNC Viewerからアクセスした、Kodiを実行中のAS3102Tの画面

Windows PC上で走らせたTightVNC Viewerからアクセスした、Kodiを実行中のAS3102Tの画面

このほど購入したAsustor社製NAS AS3102TVNCサーバVNCサーバーを走らせることができた。次はNAS本体起動時にVNCサーバーが自動起動するようにしたいと考えた。

まずはx11vnc: a VNC server for real X displaysに関する参考資料を再掲:

その自動起動させる方法がわからない。ふる~いUnixでは/etc/rc.localを使うんだったように思うが、記憶は怪しいし最近のLinuxの流儀には全く疎い。”command line – How do I run a script at start up? – Ask Ubuntu“を参照したが、/etc/init/ディレクトリは存在せずUpstartがサポートされている風ではない(最近のメジャーなLinuxディストリビューションではsystemdへの移行が進行していると言うが)。/etc/rc.localも見当たらない(作成すれば実行される、ということなのかもしれないが)。/etc/init.d/ディレクトリ下にスクリプト作成してみたが、これが再起動をまたがって保存されない。困った。

たまたま”ASUSTOR NASのOptwareで入れたパッケージが自動起動しないので何とかした | nashiko.net“を読んで、既にインストールしているアプリのEntware-ngの初期化の一環としてVNCサーバーの起動を行うことを思いついた。

Entware-ngはAsustor NAS用OS ADMにインストールされたアプリであるので、それの管理システムのコンベンションにより(参考:”App Central: Developer’s Guide for Apkg 2.0“)、NAS起動時に以下のスクリプトがstartオプションを伴って実行される。

/volume1/.@plugins/AppCentral/entware-ng/CONTROL/start-stop

これがEntware-ngのパッケージの初期化を行うわけだが、そのためにそれが以下を実行する。

/opt/etc/init.d/rc.unslung start

/opt/etc/init.d/rc.unslungでは以下が核心部:

for i in $(/opt/bin/find /opt/etc/init.d/ -perm '-u+x' -name 'S*' | sort $ORDER ) ;                                                         
do                                                                                                                                          
    case "$i" in                                                                                                                            
        S* | *.sh )                                                                                                                         
            # Source shell script for speed.                                                                                                
            trap "" INT QUIT TSTP EXIT                                                                                                      
            #set $1                                                                                                                         
            #echo "trying $i" >> /tmp/rc.log                                                                                                
            . $i $ACTION $CALLER                                                                                                            
            ;;                                                                                                                              
        *)
            # No sh extension, so fork subprocess.                                                                                          
            $i $ACTION $CALLER                                                                                                              
            ;;                                                                                                                              
    esac                                                                                                                                    
done

シェルスクリプトなのであれば、/opt/etc/init.d/以下に”S”で始まるかファイル拡張子を”.sh”としたファイル名で、オーナをrootとし適切なファイル・パーミッションを設定した上で置いておけばよさそうだ。このスクリプトは、start, stop, restartのいずれかを引数として起動される、ということを前提にしていなければならない。Entware-ngのstart-stopスクリプト自身と同様。

最終的に落ち着いたスクリプトはこの記事の末尾に掲載するが、以下の点でひっかかった。もっとも大きかったのはタイミングの問題。

x11vncは、NASシステムが既に立ち上がっている状態であれば “Asustor NASでVNCサーバーを走らせる” にあるコマンドオプションを付けて起動すれば普通に動作する。しかし、NAS起動時においては、自作x11vncの初期化スクリプトは、どうやらX.orgアプリの初期化スクリプトの前に実行されるようで、それを考慮した形にしなければならなかった。なぜならXサーバーが立ち上がってない状態でx11vncを起動しようとすると単にエラーを吐いて終了してしまうから。この初期化の順序は、x11vncのそれがEntware-ngアプリの初期化の一環として行われることを考えると、アルファベット順で後に来るX.orgアプリの初期化より先に行われるのは当然なのかもしれない。

Autostart Plex on 202TE — Plex Forums” を参考にsleep文をx11vncを起動する前に追加してみたがこれはうまくいかない。考えてみればこれは当たり前で、上の/opt/etc/init.d/rc.unslungを見ればわかるように初期化スクリプトは並列に呼ばれるのではなく、逐次的に呼ばれる。単純にsleep文を追加したところで全体の初期化がその分遅れるだけで、x11vncがXサーバーが立ち上がってない状態で起動されるということは変わらず、エラーで終了、という結果に変わりはない。 “Autostart Plex on 202TE” でPlexの場合はそれでうまくいくというのは、それが必要とするWebサーバーがアプリとは違う仕組みで起動されるかなのではないだろうか。

では( sleep 300; x11vnc...) &のようにバックグラウンド・プロセスにして…とやってみたが、実はx11vnc自身がこういう事態を想定したコマンドライン・オプションを用意してくれていた。以下x11vnc(1) – Linux man pageより(斜体は作者による):

-display WAIT:…

A special usage mode for the normal -display option.
Useful with -unixpw, but can be used independently of it. If the display string begins with WAIT: then x11vnc waits until a VNC client connects before opening the X display (or -rawfb device).
This could be useful for delaying opening the display for certain usage modes (say if x11vnc is started at boot time and no X server is running or users logged in yet).

これとバックグラウンド起動を指定する-bgコマンドライン・オプションの組み合わせでこの問題は解決。

次の問題はユーザ認証。NASシステムが起動済みの状態であれば-usepwコマンドライン・オプションだけで済むのだが、どうも起動時のファイルシステムのマウントのタイミングと絡むのか、-rfbauth /root/.vnc/passwdの様に明示的にパスワードが保存されたファイルへのパスを指定しないといけなかった。

最後に、同時に複数のクライアントがアクセスできるため-sharedオプションが必要だった。

-httpdirオプションでJava VNCクライアントを提供できるのだが、これは動かなかった。が、これはJavaのブラウザプラグインが廃止される途上にあり、Chromeでは既に使えなくなっていたからのようだ。その他のブラウザではしかるべき設定をすれば動くはずだと思うのだが、そもそも重要なことではないので諦めた。

これで無事NAS起動時にx11vncが起動するようになったが、VNCクライアントから接続すると画面操作に対する反応が非常に遅い。そもそも画面が見えないと設定のできないKodiのために用意した道具立てで、一旦しかるべきディスプレイが用意された暁にはさほど利用しないと思うので、これ以上追求しない。リモートからアクセスできるのはそれはそれでこれからも有用だとは思うが。

以下に最終的なスクリプトを示す。

#!/bin/sh

xorg_root_dir=/volume1/.@plugins/AppCentral/xorg

export LD_LIBRARY_PATH="$xorg_root_dir"/usr/lib/:$LD_LIBRARY_PATH
export LC_CTYPE=C

tmp_dir=/tmp
vnc_pid_file="$tmp_dir/vncserver.pid"
vnc_log_file="$tmp_dir/vncserver.log"

test -f "$vnc_log_file" || /bin/touch "$vnc_log_file"

do_start() {
    echo "####`/bin/date`: About to start VNC server." >> "$vnc_log_file" 
    # Seems SSL was not enabled at x11vnc's compile-time, so no '-ssl', and
    #   thus no '-unixpw'.
    # Password file needs to be explicitly specified; otherwise x11vnc cannot
    #   find it when invoked at startup in this script. 
    # Java client applet does not seem to work.
    $xorg_root_dir/usr/bin/x11vnc \
	      -rfbauth /root/.vnc/passwd \
	      -display WAIT:0.0 -forever -shared -bg \
	      -solid -ncache 10 \
              -httpdir "$xorg_root_dir"/usr/share/x11vnc/classes \
    	      >> "$vnc_log_file" 2>&1 &
    pid="$!" 
    echo $pid > "$vnc_pid_file" 
    echo "####Script being run as `/usr/bin/whoami`." >> "$vnc_log_file"
    echo "####`/bin/date`: Started VNC server with PID $pid." >> "$vnc_log_file" 
    return 0
}
 
do_stop() {
    if [ -f "$vnc_pid_file" ]
    then
        kill `cat "$vnc_pid_file"`
	/bin/rm "$vnc_pid_file" 
    fi
    echo "####`/bin/date`: Stopping VNC server." >> "$vnc_log_file"
    return 0
}
 
case "$1" in
    start)
        do_start
	;;
    stop)
        do_stop
	;;
    restart)
        do_stop
        do_start
	;;
    *)
	echo "usage: $0 {start|stop|restart}"
	exit 1
	;;
esac
exit 0
広告

Asustor NASでVNCサーバーを本体起動時に自動起動するようにする」への3件のフィードバック

  1. ピンバック: Asustor NASでVNCサーバーを走らせる | あくまで暫定措置としてのブログ
  2. ピンバック: NASのVirtualBoxでAndroid-x86を動かす | あくまで暫定措置としてのブログ
  3. ピンバック: VNCクライアントが受け取った画像データをChromecastにキャストできないか | あくまで暫定措置としてのブログ

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中