CDM(Console Display Manager) 導入の罠

# 背景

Arch Linux で3 年ほどDM として、xdm を使っていたのだが、 xdm に飽きてきたのとブラックボックス感があって中身をあまり知らなかったので、 よりシンプルなCDM を使ってみた。しかし、このCDM の導入は意外と 苦労したのでメモをするのと、DM がWM を開くまでの流れについて 考えてみた。

# 環境

-   Linux 4.20.6 (arch Linux)

# インストール

パッケージマネージャからインストールした。私はarch を使っているので `pacman` でインストール。

```shell-script
# pacman -S cdm-git
```

# 設定

[CDM - ArchWiki](https://wiki.archlinux.jp/index.php/CDM) に書いてある通りに設定すれば大丈夫だろ、と思っていたが、 結果X がうまく起動せず、[AUR (en) - cdm-git](https://aur.archlinux.org/packages/cdm-git/) のコメント、および [cdm のgithub ページ](https://github.com/evertiro/cdm/pull/33/files) を参照し、設定を行った。

## `~/.cdmrc` の作成・編集

cdm の設定ファイルは、 `/etc/cdmrc` （グローバル）、 `~/.cdmrc` （ユーザ個別） があるが、私は `~/.cdmrc` をデフォルトの `/etc/cdmrc` からコピーし、編集した。

コメントが書いてあるので、コメント読んでいけば設定できるはず。 1つだけ注意すべきは、

```shell-script:~/.cdmrc
xtty=keep
```

とすること。[cdm のgithub ページ](https://github.com/evertiro/cdm/pull/33/files) によるとtty を変更するとX が立ち上がらない ようだ。

## `/etc/X11/Xwrapper.config` の作成・編集

このファイルに関しては、[AUR (en) - cdm-git](https://aur.archlinux.org/packages/cdm-git/) のコメントを参照した。

```conf:/etc/X11/Xwrapper.config
# for CDM
needs_root_rights = yes
```

これがないと、VT が切り替えられない趣旨のエラーが起こり、X が起動しない。 VT を切り替えるにはルート権限が必要なようだ。

## `/usr/bin/cdm-xlaunch` の編集

[cdm のgithub ページ](https://github.com/evertiro/cdm/pull/33/files) の変更を `/usr/bin/cdm-xlaunch` に適用する。 arch linux の場合のみ？では、これをしないとX が立ち上がらない。 大分前から知られていたようだが、まだこの変更はなぜかマージされていない ようだ…

# ログインからWM が立ち上がるまでの動き

ログインからWM(stumpwm を使用) が起動するまでの動きを `ps` にて調査した。 セッションID でフィルタを掛けている。

```shell-script
ps -s "573 597 617" -j f                                                                                                                                                                                           [~]
PID  PGID   SID TTY      STAT   TIME COMMAND
573   573   573 ?        Ss     0:00 login -- kiso
597   597   597 tty1     Ss+    0:00  \_ /bin/bash /usr/bin/cdm
614   597   597 tty1     S+     0:00      \_ /bin/bash /usr/bin/cdm-xlaunch --startxlog /dev/null -- -- :0 -nolisten tcp vt1
617   617   617 ?        Ss     0:00          \_ /bin/sh /usr/bin/startx -- :0 -nolisten tcp vt1
644   617   617 ?        S      0:00              \_ xinit /home/kisoNas/.xinitrc -- /usr/bin/X :0 -nolisten tcp vt1 -auth /tmp/serverauth.zy0uczwWYy
645   645   617 ?        Sl     0:18                  \_ /usr/lib/Xorg :0 -nolisten tcp vt1 -auth /tmp/serverauth.zy0uczwWYy
649   649   617 ?        S      0:01                  \_ /usr/bin/stumpwm
︙
```

コマンドの結果から、ログインからWM が立ち上がるまでは下記のような流れになっているようだ。

1.  コンソールにてログイン
2.  `zsh --login` (デフォルトシェルはzsh にしている)
3.  `/etc/zprofile` を実行
    
    ```shell-script:/etc/zprofile
    # load cdm
    
    # To avoid potential situation where cdm(1) crashes on every TTY, here we
    # default to execute cdm(1) on tty1 only, and leave other TTYs untouched.
    if [[ "$(tty)" == '/dev/tty1' ]]; then
        [[ -n "$CDM_SPAWN" ]] && return
        # Avoid executing cdm(1) when X11 has already been started.
        [[ -z "$DISPLAY$SSH_TTY$(pgrep xinit)" ]] && exec cdm
    fi
    ```
4.  `exec cdm` により2 で実行した `zsh --login` のプロセスに代わり、 `/bin/bash /usr/bin/cdm` のプロセスを実行する。
5.  `/usr/bin/cdm-xlaunch` 内で
    
    ```shell-script:/usr/bin/cdm-xlaunch
    setsid startx "$@" > "$startxlog"
    ```
    
    により、新しいセッションID で
    
    ```shell-script
    /bin/sh /usr/bin/startx -- :0 -nolisten tcp vt1
    ```
    
    が実行される。
6.  X が5 で起動されたため、 `~/.xinitrc` が読み込まれ、
    
    ```shell-script:~/.xinitrc
    exec /usr/bin/stumpwm
    ```
    
    で `/usr/bin/stumpwm` でstumpwm のWM が実行される。

文章にすると長くなってしまうが、動きとしてはシンプルだ。CDM だと `systemd` が絡まないのがよい。

# まとめ

CDM を導入するだけで大分ハマってしまったが、結果的にソースのgithub のページ で同じような不具合が起こっていないかを探すのがよかったようだ。 また、CDM に変えてよかったのは、bash で書かれているし、動き自体がシンプルで分かりやすかった ことだ。それと、CDM のメニュー画面で"シャットダウン"、"再起動"の機能を追加できたのもよい （xdm のときは、これら機能はなかった）。