7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

FreeBSDAdvent Calendar 2020

Day 10

TigerVNC-1.11.0にてvncserver/vncsessionまわりのエラーを調査した話

Last updated at Posted at 2020-12-11

FreeBSD Advent Calendar 2020 10日目の記事です。
今日はTigerVNCパッケージの更新でハマった話を書こうと思います。

背景

1日目の記事でFreeBSD+Jailによるコンテナ環境を気軽に作成・破棄できるようになりました。さらにVNCと組み合わせることで、GUI環境も構築できます。
FreeBSDではTigerVNCパッケージが提供されており、ことを用いることで簡単にVNCサーバを立ち上げることができます。

ところが、いつものようにTigerVNCをインストールして動かそうとしたところ、これまでの手順では動かせなくなっており、あれこれ調べて対応したというのが今日のお話になります。

設定手順の一連の流れ

今日の話はデバッグのための試行錯誤が長々と続くため、最初に一連の設定手順を載せておきます。
(なのでこの部分だけ見ればOKという話でもあります...)

$ # 必要なパッケージのインストール。
$ sudo pkg install -y \
    tigervnc-server tigervnc-viewer \
    perl5 xauth xterm xrdb xsetroot \
    ja-uim-mozc uim-gtk ja-font-sazanami \
    leafpad open-motif
$ # VNCの設定ファイル用ディレクトリを作成。
$ mkdir .vnc
$ vncpasswd .vnc/passwd
$
$ # Xvncを起動したときに実行させるスクリプト。
$ cat <<_EOF > .vnc/xstartup
#!/bin/sh

export GTK_IM_MODULE=uim
export QT_IM_MODULE=uim
export XMODIFIERS=@im=uim
export XIM=uim

mozc_process=`ps ax | grep mozc | grep -v grep | wc -l`
[ $mozc_process -eq 0 ] && /usr/local/bin/mozc start &

uim_xim_process=`ps ax | grep uim-xim | grep -v grep | wc -l`
[ $uim_xim_process -eq 0 ] && uim-xim &

xsetroot -solid midnightblue

exec mwm
_EOF
$
$ # Xvncコマンドを直接実行し、xterm経由でxstartupを実行する。
$ Xvnc -PasswordFile ~/.vnc/passwd -verbose 2 & \
    sleep 2 \
    && xterm -iconic -display :0 /home/fbsd/.vnc/xstartup &

vncserverコマンドでのエラー

FreeBSDでTigerVNCを用いたGUI環境を構築する場合には、以下のようなパッケージをインストールします。

$ sudo pkg install -y \
    tigervnc-server tigervnc-viewer \
    perl5 xauth xterm xrdb xsetroot \
    ja-uim-mozc uim-gtk ja-font-sazanami \
    leafpad open-motif

これまでは必要なパッケージをインストールしたのち、 vncserver :0 でVNCサーバを起動していたのですが、パッケージをアップデートしたタイミングでコマンドが見つけられなくなってしまいました。

$ vncserver :0
-bash: vncserver: command not found

どのバージョンから変更が入っている?

VNCが利用できている既存の環境と比較すると、TigerVNCのバージョンが 1.10.1_1 から 1.11.0 に上がっていました。

  • vncserver でVNCが起動できる環境。
$ pkg info tigervnc-server | head -n4
tigervnc-server-1.10.1_1
Name           : tigervnc-server
Version        : 1.10.1_1
Installed on   : Tue May 19 01:20:05 2020 JST
  • パッケージアップデート後の環境。
$ pkg info tigervnc-server | head -n4
tigervnc-server-1.11.0
Name           : tigervnc-server
Version        : 1.11.0
Installed on   : Sun Oct 11 02:10:00 2020 JST

インストールされるファイルの差分確認

インストールされるファイルの差分をみると、いくつか差異があります。

$ diff -u tigervnc-server-1.10.1_1.txt tigervnc-server-1.11.0.txt
--- tigervnc-server-1.10.1_1.txt        2020-10-11 02:29:50.500981000 +0900
+++ tigervnc-server-1.11.0.txt  2020-10-11 02:30:02.870729000 +0900
@@ -1,16 +1,22 @@
 /usr/local/bin/vncconfig
 /usr/local/bin/vncpasswd
-/usr/local/bin/vncserver
 /usr/local/bin/x0vncserver
 /usr/local/bin/Xvnc
+/usr/local/etc/pam.d/tigervnc
+/usr/local/etc/tigervnc/vncserver-config-defaults
+/usr/local/etc/tigervnc/vncserver-config-mandatory
+/usr/local/etc/tigervnc/vncserver.users
 /usr/local/lib/xorg/modules/extensions/libvnc.so
+/usr/local/libexec/vncserver
 /usr/local/man/man1/vncconfig.1.gz
 /usr/local/man/man1/vncpasswd.1.gz
-/usr/local/man/man1/vncserver.1.gz
 /usr/local/man/man1/x0vncserver.1.gz
 /usr/local/man/man1/Xvnc.1.gz
+/usr/local/man/man8/vncserver.8.gz
+/usr/local/man/man8/vncsession.8.gz
+/usr/local/sbin/vncsession
 /usr/local/share/doc/tigervnc/tigervnc-server-LICENCE.TXT
 /usr/local/share/doc/tigervnc/tigervnc-server-README.rst
-/usr/local/share/licenses/tigervnc-server-1.10.1_1/catalog.mk
-/usr/local/share/licenses/tigervnc-server-1.10.1_1/GPLv2+
-/usr/local/share/licenses/tigervnc-server-1.10.1_1/LICENSE
+/usr/local/share/licenses/tigervnc-server-1.11.0/catalog.mk
+/usr/local/share/licenses/tigervnc-server-1.11.0/GPLv2+
+/usr/local/share/licenses/tigervnc-server-1.11.0/LICENSE

vncserverをフルパス指定で実行すれば解決?

vncserver コマンドは /usr/local/libexec 以下に移動されていました。

バージョン1.10.1_1  /usr/local/bin/vncserver
バージョン1.11.0    /usr/local/libexec/vncserver

フルパス指定で /usr/local/libexec/vncserver を実行すれば解決するかと思ったのですが、別のエラーが出てしまいました。

$ /usr/local/libexec/vncserver :0 ; echo $?
vncserver: Couldn't find suitable Xsession.
2

そしてここから長いデバッグの旅が始まったのです...。

頑張ってデバッグする

Xsessionファイルの作成

以下に同様のエラーが報告されていた。Xsession ファイルが存在しないことが原因のようです。

手動で Xsession ファイルを作成します。

手動で Xsession ファイルを作成する。

$ ls /etc/X11/Xsession
ls: /etc/X11/Xsession: そのようなファイルまたはディレクトリはありません
$ echo '#!/bin/sh' | sudo tee /etc/X11/Xsession
$ sudo chmod +x /etc/X11/Xsession

パスワードファイルの作成

Xsession 関連のエラーは解消しましたが、今度はVNC用のパスワードファイルが無いというエラーに遭遇しました。

$ /usr/local/libexec/vncserver :0
VNC authentication enabled, but no password file created.

対応方法は自明で、 ~/.vnc/passwd ファイルを作成することで対応します。

$ mkdir .vnc
$ vncpasswd .vnc/passwd
Password:
Verify:
Would you like to enter a view-only password (y/n)? n

デスクトップセッションファイルの作成

今度はデスクトップセッション周りのエラーに遭遇しました。

$ /usr/local/libexec/vncserver :0 ; echo $?
Could not find a desktop session to run
255

ソースコードを参照してみると、エラーメッセージは以下の場所で出力されているようです。

ソースコード中の前後の処理をみるど、どうやら /usr/share/xsessions/*.desktop でマッチするファイルが存在しないことが要因のようです。

if (!$sessionname) {
  foreach $file (glob("/usr/share/xsessions/*.desktop")) {
    ($name) = $file =~ /^.*\/(.*)[.]desktop$/;
    %session = LoadXSession($name);
    if (%session) {
      $sessionname = $name;
      last;
    }
  }
}

if (!$sessionname) {
  die "Could not find a desktop session to run\n";
}

なるほど、たしかに /usr/share/xsessions ディレクトリの中身は空っぽになっています。

$ ls /usr/share/xsessions/*.desktop | wc -l
       0

/usr/share/xsessions/mwm.desktop ファイルを作成して以下の内容を記載します。

[Desktop Entry]
Name=MWM
Exec=mwm
TryExec=/home/fbsd/.vnc/xstartup

xinitでエラー

これで大丈夫かなと思ったのですが、今度は xinit でエラーが出てしまいました...。

$ /usr/local/libexec/vncserver :0
...
xinit: connection to X server lost

waiting for X server to shut down

xinit とその中から実行されそうなスクリプトは以下の場所にあるようです。とはいえ、TigerVNCパッケージを更新する前は普通に動作していたため、 xinit 側が要因である可能性は低そうです。

$ find /usr/local/etc/ | grep -i xinit | xargs file
find: /usr/local/etc/cups/ssl: パーミッションが拒絶されました
/usr/local/etc/X11/xinit:         directory
/usr/local/etc/X11/xinit/xinitrc: POSIX shell script, ASCII text executable

そもそも /usr/local/libexec/vncserver コマンドは libexec ディレクトリに配置される形に変更されているので、このコマンドを直接実行するという事自体が推奨されない使い方になった、という話なのかもしれません。
どうやら /usr/local/sbin/vncsession が内部的に vncserver を実行しているようです。が、こちらも実行すると以下のようなエラーになってしまいます...。

$ sudo vncsession fbsd :0
Failure daemonizing

ソースコードと照らし合わせてみる

どうやらこれはTigerVNCのソースコードと照らし合わせながら調べないと原因特定ができなさそうです。
vncsession で発生しているエラーをソースコードから検索してみます。

$ find . -type f -name vncsession
./unix/vncserver/vncsession
$ sudo ./unix/vncserver/vncsession fbsd :0
Failure daemonizing
$ find . -type f | xargs grep 'Failure daemonizing'
./unix/vncserver/vncsession.c:            fprintf(stderr, "Failure daemonizing\n");

該当箇所の前後の処理を見てもイマイチエラーの原因が分かりません...。
vncsessionvncserver の順で呼び出していることまでは把握できているので、最終的に実行される xinit コマンドがどう実行されるかを調べるほうが早道かもしれません。

        /* Wait for child to finish startup */
        len = read(fds[0], buf, 1);
        if (len != 1) {
            fprintf(stderr, "Failure daemonizing\n");
            _exit(EX_OSERR);
        }

xinitコマンドはどう実行されている?

xinit は以下の個所から実行されるようです。 @cmd という配列にオプション等を追加していき、最終的に xinit コマンド文字列が作り出されています。

@cmd = ("xinit");

push(@cmd, $Xsession, $session{'Exec'});

push(@cmd, '--');

# We build up our Xvnc command with options
push(@cmd, "@CMAKE_INSTALL_FULL_BINDIR@/Xvnc", ":$displayNumber");

foreach my $k (sort keys %config) {
  push(@cmd, "-$k");
  push(@cmd, $config{$k}) if defined($config{$k});
  delete $default_opts{$k}; # file options take precedence
}

foreach my $k (sort keys %default_opts) {
  push(@cmd, "-$k");
  push(@cmd, $default_opts{$k}) if defined($default_opts{$k});
}

私の環境では以下のような xinit コマンドになっていました。

xinit -- /usr/local/bin/Xvnc :0 -auth /home/fbsd/.Xauthority -desktop tmp01.furandon.net:0

xinitのオプション

xinit(1)のマニュアルを見ると、 -- の後にserverと付随するオプションを指定するという形になっています。
ということは、TigerVNCでは、 xinit から Xvnc が実行されるという流れになっているという話ですね。

$ man 1 xinit
NAME
       xinit - X Window System initializer

SYNOPSIS
       xinit [ [ client ] options ... ] [ -- [ server ] [ display ] options
       ... ]

Xvncを直接実行する

これは Xvnc を直接実行すれば良さそうです。以下のようなコマンドを実行することで、無事にVNCが利用できる状態になりました。

$ Xvnc -PasswordFile ~/.vnc/passwd -verbose 2 & \
    sleep 2 \
    && xterm -iconic -display :0 /home/fbsd/.vnc/xstartup &

その他のハマりどころ

今回の調査を行っている際に ~/.ssh/known_hosts の内容と接続元PCの情報に齟齬が出ている状態だと、Xvncを直接実行する形であってもVNCに接続できないという点にハマりました。
仮想マシン等で環境を構築していると、接続元PCのIPアドレスを使いまわしたりするため、この現象に遭遇しやすいかもしれません。この場合は、 ~/.ssh/known_hosts の該当エントリを削除することで問題が解消します。

まとめ

TigerVNCパッケージの更新でハマった話を紹介しました。思っていたよりも深くまで調べないと解消方法が見つからないため苦労しました。
最終的には Xvnc コマンドを直接実行する方法で解消しましたが、 .xstartup コマンドの実行はちょっとトリッキーな方法で実行しているため、より良い方法を見つけたいところです。

7
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
7
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?