VirtualBox / VMware Player のシリアルコンソールを使う

## 仮想マシンのコンソールが欲しい
久々に VirtualBox を触ったのでメモ。ついでに VMware Player もまとめておく。
KVM コンソールのような大げさな画面はいらないし headless で VM を起動したいけど、いざって時のためにコンソールを触れるようにしておきたい。

ゲストOS 側の設定も必要だが、ここはやはりシリアルコンソールで。

## VirtualBox でシリアル出力設定する

Linux なら unix domain socket を置くディレクトリを用意しておき、
VirtualBox を起動して下記のように設定する

![vbox_setting.png](https://qiita-image-store.s3.amazonaws.com/0/44206/872adc49-0f6e-5819-156b-d89057ec2ce9.png)


socket は Create Pipe にチェックを入れておけば VM 起動時に自動的に作成される。

ホストOS が Windows なら ```\\.\pipe\mypipename``` のようにする。

## VMware Player でシリアル出力設定する

VMware Player を起動し、設定は下記のようにする。

![vmware_setting.png](https://qiita-image-store.s3.amazonaws.com/0/44206/141b5502-7624-5949-3c24-4f647cd51727.png)

手元に Linux + VMware が無かったが、その場合でも同じように socket の名前を指定すればよいだけのはず。

## ゲスト OS の headless 起動

VMware Player を headless で動かすには VIX が必要なため、適切なバージョンの VIX をインストールしておく。
コマンドのパスは Windows / Linux で違うが、実行方法は同じ。

* VirtualBox

```
VBoxManage startvm Name_of_VM --type headless
```

* VMware

```
vmrun -T player start "Path_to_Guest.vmx" nogui
```


## ゲスト OS を設定する
以下は CentOS 6 のシリアル設定の例。
必要な手順はディストリビューションによって異なるだろう。

```/boot/grub/grub.conf
default=0
timeout=5
serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=10 serial console
#splashimage=(hd0,1)/boot/grub/splash.xpm.gz
hiddenmenu
title CentOS (2.6.32-358.el6.x86_64)
        root (hd0,1)
        kernel /boot/vmlinuz-2.6.32-358.el6.x86_64 ro root=UUID=874f153e-fc34-4821-9f13-e070c0c63190 rd_NO_LUKS LANG=en_US.UTF-8 rd_NO_MD SYSFONT=latarcyrheb-sun16 crashkernel=auto  KEYBOARDTYPE=pc KEYTABLE=jp106 rd_NO_LVM rd_NO_DM console=tty0 console=ttyS0,115200n8r
        initrd /boot/initramfs-2.6.32-358.el6.x86_64.img

```

agetty の起動はデフォルトの /etc/init/serial.conf のままで良かった。

```console
# egrep -v '\s*#|^$' /etc/init/serial.conf
start on fedora.serial-console-available DEV=* and stopped rc RUNLEVEL=[2345]
stop on runlevel [S016]
instance $DEV
respawn
pre-start exec /sbin/securetty $DEV
exec /sbin/agetty /dev/$DEV $SPEED vt100-nav
post-stop exec /sbin/initctl emit --no-wait fedora.serial-console-available DEV=$DEV SPEED=$SPEED
usage 'DEV=ttySX SPEED=Y  - where X is console id and Y is baud rate'
```

設定が完了したらゲストを再起動する。


## シリアルコンソールを使う

接続相手が unix domain socket なので、ググると socat の例が良く出てくるが、socat 単体だと以下のような点から不足だと思う。

 * Ctrl-c による SIGINT を送れない（うっかり押すと socat が終了して抜けてしまう）
 * エコーバックを忘れてうっかりパスワードが画面に見えてしまう。

socat で pty を作成して、操作は screen を使うと個人的にいい感じだった。

```console
$# -d -d をつけると起動中に pty をどこに作ったか表示するので
$# screen では表示された pty を指定する
$ socat -d -d unix-connect:/var/run/vbox/test.sock pty,raw,echo=0 &
[1] 13548
2014/06/12 22:12:54 socat[13548] N opening connection to AF=1 "/var/run/vbox/test.sock"
2014/06/12 22:12:54 socat[13548] N successfully connected from local address AF=1 "\0\0\0\0\0\0\0\0\0\x02\0\0\0\0[\0\0\0|\0\0\0w"
2014/06/12 22:12:54 socat[13548] N PTY is /dev/pts/8
2014/06/12 22:12:54 socat[13548] N starting data transfer loop with FDs [3,3] and [4,4]

$ screen /dev/pts/8

## Enter たたく ##

CentOS release 6.5 (Final)
Kernel 2.6.32-431.el6.x86_64 on an x86_64

test.local login:　root
Password:
Last login: Thu Jun 12 22:14:01 on ttyS0
[root@test ~]#
## パスワードのエコーバックもないし、Ctrl-c では終了しない ##

```


Windows なら TeraTerm (4.74 以降?) でパイプに接続できる。
新しい接続から TCP/IP を選択し、
ホストに作成したパイプの名前 ```\\.\pipe\control-node.sock``` を入れる。

![teraterm_serial.png](https://qiita-image-store.s3.amazonaws.com/0/44206/1be2e5ee-205d-e888-8771-2310ee8a5a45.png)