systemdでXvfbをデーモンとして起動させる

Selenium WebdriverをCUIで動かすために、Xvfbをデーモンとして起動させるようにします。
環境はCentOS 7です。

# serviceファイルを作成する

まずはデーモンを動作させるためのファイルを作成します。

```bash
$ vi /usr/lib/systemd/system/Xvfb.service
```

ファイルの内容は以下の様にしました。

```bash:Xvfb.service
[Unit]
Description=Virtual Framebuffer X server for X Version 11

[Service]
Type=simple
EnvironmentFile=-/etc/sysconfig/Xvfb
ExecStart=/usr/bin/Xvfb ${OPTION}
ExecReload=/bin/kill -HUP ${MAINPID}

[Install]
WantedBy=multi-user.target
```

SysVinitの時は、サービスをデフォルトのデーモンとして起動させたい場合、わざわざスクリプトとして書く必要がありましたが、systemdになってから書式が変わり、直感的に設定できるようになりました。

<br />

|パラメータ|説明|
|:-:|:-:|
|Description|デーモンの説明書き。 systemctl コマンド実行時に説明として表示される。|
|Type|デーモン起動の判定方法を指定する。|
|EnvironmentFile|環境変数の設定ファイル。ファイル名の先頭に"-"(ダッシュ)を付けていた場合、ファイルが存在しない場合でも正常に動作する。|
|ExecStart|デーモンを起動させるコマンド列。|
|ExecReload|デーモンを再読み込みさせるコマンド列。|
|WantedBy|自動起動を有効にした場合に指定されるランレベル|

デーモンファイルを確認すると、作成したXvfb.serviceファイルが確認できると思います。

```bash:デーモンファイル確認
$ systemctl list-unit-files | grep Xvfb.service
Xvfb.service                                disabled
```

# デーモン操作

systemdの通常のデーモンと同様の操作が可能です。

## デーモン状態確認

```bash:デーモン状態確認
$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled)
   Active: inactive (dead)
```

## デーモン起動

```bash:デーモン起動
$ systemctl start Xvfb.service

$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled)
   Active: active (running) since 土 2015-12-12 01:00:38 JST; 1s ago
 Main PID: 12089 (Xvfb)
   CGroup: /system.slice/Xvfb.service
           └-12089 /usr/bin/Xvfb

12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension MIT-SCREEN-SAVER
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension DOUBLE-BUFFER
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension RECORD
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension DPMS
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension Present
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension X-Resource
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension XVideo
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension XVideo-MotionCompensation
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension SELinux
12月 12 01:00:38 srv.example.com Xvfb[12089]: Initializing built-in extension GLX
Hint: Some lines were ellipsized, use -l to show in full.
```

## デーモン再読み込み

PIDが変わりません。

```bash:デーモン再読み込み
$ systemctl reload Xvfb.service

$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled)
   Active: active (running) since 土 2015-12-12 01:00:38 JST; 1min 54s ago
  Process: 12131 ExecReload=/bin/kill -HUP ${MAINPID} (code=exited, status=0/SUCCESS)
 Main PID: 12089 (Xvfb) # ← PIDが12089のまま
   CGroup: /system.slice/Xvfb.service
           └-12089 /usr/bin/Xvfb

12月 12 01:02:31 srv.example.com Xvfb[12089]: 4 GCs still allocated at reset
12月 12 01:02:31 srv.example.com Xvfb[12089]: GC: 4 objects of 16 bytes = 64 total bytes 0 privat...ocs
12月 12 01:02:31 srv.example.com Xvfb[12089]: CURSOR: 1 objects of 8 bytes = 8 total bytes 0 priv...ocs
12月 12 01:02:31 srv.example.com Xvfb[12089]: TOTAL: 5 objects, 72 bytes, 0 allocs
12月 12 01:02:31 srv.example.com Xvfb[12089]: 1 CURSORs still allocated at reset
12月 12 01:02:31 srv.example.com Xvfb[12089]: CURSOR: 1 objects of 8 bytes = 8 total bytes 0 priv...ocs
12月 12 01:02:31 srv.example.com Xvfb[12089]: TOTAL: 1 objects, 8 bytes, 0 allocs
12月 12 01:02:31 srv.example.com Xvfb[12089]: 1 CURSOR_BITSs still allocated at reset
12月 12 01:02:31 srv.example.com Xvfb[12089]: TOTAL: 0 objects, 0 bytes, 0 allocs
12月 12 01:02:31 srv.example.com systemd[1]: Reloaded Virtual Framebuffer X server for X Version 11.
Hint: Some lines were ellipsized, use -l to show in full.
```

## デーモン再起動

```bash:デーモン再起動
$ systemctl restart Xvfb.service
$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled)
   Active: active (running) since 土 2015-12-12 01:03:04 JST; 1s ago
  Process: 12131 ExecReload=/bin/kill -HUP ${MAINPID} (code=exited, status=0/SUCCESS)
 Main PID: 12142 (Xvfb) # ← 停止起動をしているためPIDが変わる
   CGroup: /system.slice/Xvfb.service
           └-12142 /usr/bin/Xvfb

12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension MIT-SCREEN-SAVER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DOUBLE-BUFFER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension RECORD
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DPMS
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension Present
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension X-Resource
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo-MotionCompensation
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension SELinux
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension GLX
Hint: Some lines were ellipsized, use -l to show in full.
```

## デーモン停止

```bash:デーモン停止
$ systemctl stop Xvfb.service
$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled)
   Active: inactive (dead)

12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension MIT-SCREEN-SAVER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DOUBLE-BUFFER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension RECORD
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DPMS
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension Present
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension X-Resource
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo-MotionCompensation
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension SELinux
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension GLX
12月 12 01:04:46 srv.example.com systemd[1]: Stopping Virtual Framebuffer X server for X Version 11...
12月 12 01:04:46 srv.example.com systemd[1]: Stopped Virtual Framebuffer X server for X Version 11.
Hint: Some lines were ellipsized, use -l to show in full.
```

## デーモン自動起動有効化

```bash:デーモン自動起動有効化
$ systemctl enable Xvfb.service
ln -s '/usr/lib/systemd/system/Xvfb.service' '/etc/systemd/system/multi-user.target.wants/Xvfb.service'
$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; enabled) # ← enabledとなる
   Active: inactive (dead)

12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension MIT-SCREEN-SAVER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DOUBLE-BUFFER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension RECORD
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DPMS
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension Present
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension X-Resource
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo-MotionCompensation
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension SELinux
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension GLX
12月 12 01:04:46 srv.example.com systemd[1]: Stopping Virtual Framebuffer X server for X Version 11...
12月 12 01:04:46 srv.example.com systemd[1]: Stopped Virtual Framebuffer X server for X Version 11.
Hint: Some lines were ellipsized, use -l to show in full.
```

## デーモン自動起動無効化

```bash:デーモン自動起動無効化
$ systemctl disable Xvfb.service
rm '/etc/systemd/system/multi-user.target.wants/Xvfb.service'
$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled) # ← disabledとなる
   Active: inactive (dead)

12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension MIT-SCREEN-SAVER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DOUBLE-BUFFER
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension RECORD
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension DPMS
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension Present
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension X-Resource
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension XVideo-MotionCompensation
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension SELinux
12月 12 01:03:04 srv.example.com Xvfb[12142]: Initializing built-in extension GLX
12月 12 01:04:46 srv.example.com systemd[1]: Stopping Virtual Framebuffer X server for X Version 11...
12月 12 01:04:46 srv.example.com systemd[1]: Stopped Virtual Framebuffer X server for X Version 11.
Hint: Some lines were ellipsized, use -l to show in full.
```

# 環境変数設定ファイル

環境変数を設定するファイルを作成してみます。

作成した Xvfb.service の、以下で定義されているファイルの事です。

```bash:Xvfb.service(抜粋)
EnvironmentFile=-/etc/sysconfig/Xvfb
```


`/etc/sysconfig/Xvfb` ファイルを実際に作成してみます。

```bash:環境設定ファイル作成
vi /etc/sysconfig/Xvfb
```

中身は以下のような設定をします。

```bash:/etc/sysconfig/Xvfb
# Xvfb Enviroment File
OPTION=":1 -screen 0 1600x1200x32"
```

ここで設定した変数 `OPTION` は、Xvfb.service の起動時に使われます。


```bash:Xvfb.service(抜粋)
ExecStart=/usr/bin/Xvfb ${OPTION}
```

上記で指定している `${OPTION}` に、`/etc/sysconfig/Xvfb` で設定した `OPTION` 変数の内容が反映されます。

上記の設定をした後、Xvfb.service を起動してみましょう。

```bash:デーモン起動(環境変数設定ファイル有り)
$ systemctl start Xvfb.service
$ systemctl status Xvfb.service
Xvfb.service - Virtual Framebuffer X server for X Version 11
   Loaded: loaded (/usr/lib/systemd/system/Xvfb.service; disabled)
   Active: active (running) since 土 2015-12-12 02:00:24 JST; 1s ago
 Main PID: 12835 (Xvfb)
   CGroup: /system.slice/Xvfb.service
           └-12835 /usr/bin/Xvfb :1 -screen 0 1600x1200x32 # ← オプションが付与されている

12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension MIT-SCREEN-SAVER
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension DOUBLE-BUFFER
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension RECORD
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension DPMS
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension Present
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension X-Resource
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension XVideo
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension XVideo-MotionCompensation
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension SELinux
12月 12 02:00:24 srv.example.com Xvfb[12835]: Initializing built-in extension GLX
Hint: Some lines were ellipsized, use -l to show in full.
```

上記のようにすれば外部ファイルでオプションを指定する事が可能です。
因みに、指定する変数は中括弧`{}`で括らないとエラーになるようです。

参考URL:
[「Systemd」を理解する ーシステム起動編ー](http://equj65.net/tech/systemd-boot/)
[man systemd.unitの訳](https://sites.google.com/site/kandamotohiro/systemd/man-systemd-unit-no-yi)
[Systemd入門(1) - Unitの概念を理解する](http://enakai00.hatenablog.com/entry/20130914/1379146157)