ラベル Red Hat の投稿を表示しています。 すべての投稿を表示
ラベル Red Hat の投稿を表示しています。 すべての投稿を表示

2017/06/06

JP1/AJS3環境でRHEL7/CentOS7ファイアウォールを設定する

はじめに

JP1/Automatic Job Management System 3 (JP1/AJS3)環境において、firewalldを設定する方法を紹介する。

参考: 『JP1/AJS3環境でWindowsファイアウォールを設定する

JP1/Automatic Job Management System 3 (JP1/AJS3)は、業務を自動化する製品。
詳細は、マニュアルを参照。

JP1/AJS3 を構成する主な要素には、マネージャホスト・エージェントホストがある。
マネージャホストは、エージェントホストを制御し、ジョブを実行させる。
マネージャホストは、エージェントホストの機能を含む。
このため、マネージャホスト自身にジョブを実行させることもできる。

JP1/AJS3 は、企業内ネットワーク内部で使用されることが多い。
このため、各構成要素のパーソナルファイアウォールが無効化されていても、一概に安全でないとは言えない。
しかし、無効化しない方がセキュリティ上より安全である。

RHEL 7/CentOS 7では、firewalld がパーソナルファイアウォール機能を提供する。

JP1/AJS3 環境でのファイアウォール設定要件については、以下を参考にした。


ファイアウォールの設定方針

RHEL 7/CentOS 7では、パーソナルファイアウォールとして、firewalld と iptables が利用できる。この iptables は、TCP/UDP ポートを一つづつ追加していくか、連続した TCP/UDP ポートを追加するかのいずれかの方法でルールを定義する。
一方、firewalld は、iptables と同様の方法に加えて、複数の TCP/UDP ポートをひとまとめにして扱うことができる。
ひとまとめにした TCP/UDP ポートは、サービスと呼ばれ、名前を付けて扱うことが出来る。

マネージャホストおよびエージェントホストの両方で同じサービスを定義し、必要に応じてサービス単位で通信を許可する。


Firewalldサービスの定義

Firewalld のサービスは、/etc/firewalld/services以下に XML ファイルを作成することで定義する。

Firewalldサービスの定義/設定前状態の確認

マネージャホストおよびエージェントホストで以下の通り実行する。
定義したサービスの一覧をfirewall-cmd --get-servicesで得ることができる。

[root@agent ~]# cd /etc/firewalld/services
[root@agent services]# ls *JP1*
ls: cannot access *JP1*: No such file or directory
[root@agent services]# for SERVICE in $(firewall-cmd --get-services); do [[ $SERVICE = *JP1* ]] && echo $SERVICE; done
[root@agent services]#

何も定義されていないことが解る。

Firewalldサービスの定義/設定


マネージャホストおよびエージェントホストで以下の通り実行する。

[root@agent services]# cat <<'EOF' > JP1Base-to-JP1Base.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1Base-to-JP1Base</short>
>   <description>JP1/Base to JP1/Base</description>
>   <port protocol="tcp" port="20098"/>
>   <port protocol="tcp" port="20306"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-to-JP1Base.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-to-JP1Base</short>
>   <description>JP1/AJS3 (both Manager and Agent) to JP1/Base</description>
>   <port protocol="tcp" port="20240"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-View-to-Manager.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-View-to-Manager</short>
>   <description>JP1/AJS3 View to JP1/AJS3 Manaer</description>
>   <port protocol="tcp" port="20244"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-Agent-to-Manager.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-Agent-to-Manager</short>
>   <description>JP1/AJS3 Agent to JP1/AJS3 Manaer</description>
>   <port protocol="tcp" port="20241"/>
>   <port protocol="tcp" port="20243"/>
>   <port protocol="tcp" port="20246"/>
>   <port protocol="tcp" port="20301"/>
>   <port protocol="tcp" port="22251"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-Manager-to-Agent.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-Manager-to-Agent</short>
>   <description>JP1/AJS3 Manager to JP1/AJS3 Aent</description>
>   <port protocol="tcp" port="20242"/>
>   <port protocol="tcp" port="20247"/>
>   <port protocol="tcp" port="20300"/>
>   <port protocol="tcp" port="22251"/>
>   <port protocol="tcp" port="23139"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-Manager-to-Manager.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-Manager-to-Manager</short>
>   <description>JP1/AJS3 Manager to JP1/AJS3 Manager</description>
>   <port protocol="tcp" port="20241"/>
>   <port protocol="tcp" port="20244"/>
>   <port protocol="tcp" port="20245"/>
>   <port protocol="tcp" port="23160"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-SDK-to-Manager.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-SDK-to-Manager</short>
>   <description>JP1/AJS3 SDK to JP1/AJS3 Manager</description>
>   <port protocol="tcp" port="22250"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-Agent-to-Agent.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-Agent-to-Agent</short>
>   <description>JP1/AJS3 Agent to JP1/AJS3 Agent</description>
>   <port protocol="tcp" port="22251"/>
>   <port protocol="udp" port="22251"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > JP1AJS3-Web-Console-to-Manager.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>JP1AJS3-Web-Console-to-Manager</short>
>   <description>JP1/AJS3 Web Console to JP1/AJS3 Manager</description>
>   <port protocol="tcp" port="22250"/>
> </service>
> EOF
[root@agent services]# cat <<'EOF' > Web-Browser-to-JP1AJS3-Web-Console.xml
> <?xml version="1.0" encoding="utf-8"?>
> <service>
>   <short>Web-Browser-to-JP1AJS3-Web-Console</short>
>   <description>Web Browser to JP1/AJS3 Web Console</description>
>   <port protocol="tcp" port="22252"/>
>   <port protocol="tcp" port="22253"/>
> </service>
> EOF
[root@agent services]#


Firewalld サービスの定義/設定後状態の確認

マネージャホストおよびエージェントホストで以下の通り実行する。
定義されたサービスは、定義をfirewall-cmd --reloadでリロードすることによって反映される。

[root@agent services]# ls *JP1*
JP1AJS3-Agent-to-Agent.xml      JP1AJS3-SDK-to-Manager.xml          JP1Base-to-JP1Base.xml
JP1AJS3-Agent-to-Manager.xml    JP1AJS3-View-to-Manager.xml         Web-Browser-to-JP1AJS3-Web-Console.xml
JP1AJS3-Manager-to-Agent.xml    JP1AJS3-Web-Console-to-Manager.xml
JP1AJS3-Manager-to-Manager.xml  JP1AJS3-to-JP1Base.xml
[root@agent services]# firewall-cmd --reload
success
[root@agent services]# for SERVICE in $(firewall-cmd --get-services); do [[ $SERVICE = *JP1* ]] && echo $SERVICE; done
JP1AJS3-Agent-to-Agent
JP1AJS3-Agent-to-Manager
JP1AJS3-Manager-to-Agent
JP1AJS3-Manager-to-Manager
JP1AJS3-SDK-to-Manager
JP1AJS3-View-to-Manager
JP1AJS3-Web-Console-to-Manager
JP1AJS3-to-JP1Base
JP1Base-to-JP1Base
Web-Browser-to-JP1AJS3-Web-Console
[root@agent services]# for SERVICE in $(firewall-cmd --get-services); do if [[ $SERVICE = *JP1* ]]; then echo "### $SERVICE"; firewall-cmd --info-service=$SERVICE; fi; done
### JP1AJS3-Agent-to-Agent
JP1AJS3-Agent-to-Agent
  ports: 22251/tcp 22251/udp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-Agent-to-Manager
JP1AJS3-Agent-to-Manager
  ports: 20241/tcp 20243/tcp 20246/tcp 20301/tcp 22251/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-Manager-to-Agent
JP1AJS3-Manager-to-Agent
  ports: 20242/tcp 20247/tcp 20300/tcp 22251/tcp 23139/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-Manager-to-Manager
JP1AJS3-Manager-to-Manager
  ports: 20241/tcp 20244/tcp 20245/tcp 23160/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-SDK-to-Manager
JP1AJS3-SDK-to-Manager
  ports: 22250/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-View-to-Manager
JP1AJS3-View-to-Manager
  ports: 20244/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-Web-Console-to-Manager
JP1AJS3-Web-Console-to-Manager
  ports: 22250/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1AJS3-to-JP1Base
JP1AJS3-to-JP1Base
  ports: 20240/tcp
  protocols:
  source-ports:
  modules:
  destination:
### JP1Base-to-JP1Base
JP1Base-to-JP1Base
  ports: 20098/tcp 20306/tcp
  protocols:
  source-ports:
  modules:
  destination:
### Web-Browser-to-JP1AJS3-Web-Console
Web-Browser-to-JP1AJS3-Web-Console
  ports: 22252/tcp 22253/tcp
  protocols:
  source-ports:
  modules:
  destination:
[root@agent services]#


Firewalld ルールの定義

Firewalld ルールの定義/設定前状態の確認

マネージャホストおよびエージェントホストで以下の通り実行する。

[root@agent services]# firewall-cmd --get-default-zone
public
[root@agent services]# firewall-cmd --info-zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources:
  services: dhcpv6-client http https ntp smtp ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  sourceports:
  icmp-blocks:
  rich rules:

[root@agent services]#

Firewalld ルールの定義/設定

エージェントホストで以下の通り実行する。

[root@agent services]# firewall-cmd --permanent --zone=public --add-service=JP1Base-to-JP1Base --add-service=JP1AJS3-to-JP1Base
success
[root@agent services]# firewall-cmd --permanent --zone=public --add-service=JP1AJS3-Manager-to-Agent --add-service=JP1AJS3-Agent-to-Agent
success
[root@agent services]#

マネージャホストでは、これらのサービスの他に、JP1AJS3-Agent-to-Manager、JP1AJS3-Manager-to-Manager、JP1AJS3-SDK-to-Manager、JP1AJS3-View-to-ManagerおよびJP1AJS3-Web-Console-to-Managerを追加する。

Firewalld ルールの定義/設定後状態の確認

マネージャホストおよびエージェントホストで以下の通り実行する。

[root@agent services]# firewall-cmd --reload
success
[root@agent services]# firewall-cmd --info-zone=public
public (active)
  target: default
  icmp-block-inversion: no
  interfaces: ens160
  sources:
  services: JP1AJS3-Agent-to-Agent JP1AJS3-Manager-to-Agent JP1AJS3-to-JP1Base JP1Base-to-JP1Base dhcpv6-client http https ntp smtp ssh
  ports:
  protocols:
  masquerade: no
  forward-ports:
  sourceports:
  icmp-blocks:
  rich rules:

[root@agent services]#

2017/02/27

システム起動時のfsck

現状の確認

インストール直後の既定値を確認する。

/etc/fstab

[root@centos01 ~]# cat /etc/fstab | grep /dev/mapper/vg_centos01-lv_root
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1
[root@centos01 ~]#
第6フィールドが「1」となっている。
この設定では、起動の際にfsck実施条件をチェックし、適宜fsckを実施する。

ボリュームのパラメータ

CentOS 6/RHEL 6の場合、既定ではext4のボリュームは、fsckを実施しない様設定されている。
# ちなみに、CentOS 7/RHEL 7では、既定でxfsのため、起動にfsckは実行されない。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              4
Maximum mount count:      -1
Last checked:             Thu Feb 23 06:06:05 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

現在は、以下の通り設定されていることが判る。
  • マウントされた回数(Mount count)が4、
  • マウント回数によるfsck実行(Maximum mount count)は無し、
  • 最後にfsckが実行されたの(Last checked)が2017.2.23(木) 06:06:05、
  • 経過時間によるfsck実行(Check interval)は無し
結果、既定状態では起動時のfsckは、実行されないことが判る。

マウント回数による条件の検証

Maximum mount countの設定

前に確認した通り、現在のマウント回数は4回なので、Maximum mount countを5に設定する。
[root@centos01 ~]# tune2fs -c 5 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 5
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              3
Maximum mount count:      5
Last checked:             Thu Feb 23 06:06:05 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認1: fsckされない場合

再度再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数5回だが、Maximum mount countの設定値5を超えていないため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              5
Maximum mount count:      5
Last checked:             Thu Feb 23 06:06:05 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認2: fsckされる場合

再度再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数6回に達し、Maximum mount countの設定値5を超えるため、fsckされる。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      5
Last checked:             Sat Feb 25 13:42:42 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復旧

設定を元に戻す。
[root@centos01 ~]# tune2fs -c -1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to -1
[root@centos01 ~]#

/fastbootの検証

ファイル/fastbootを作成すると、次回起動時にfsckされなくなることを確認する。

設定

[root@centos01 ~]# tune2fs -c 1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 1
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 13:42:42 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認1: fsckされない場合

/fastbootを作成し、再起動する。
[root@centos01 ~]# touch /fastboot
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数2回で、Maximum mount countの設定値2を超えているが、/fastbootが作成されていたため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              2
Maximum mount count:      1
Last checked:             Sat Feb 25 13:42:42 2017
Check interval:           0 (<none>)
[root@centos01 ~]#
再起動前に作成した/fastbootは削除されている。
[root@centos01 ~]# ls /fastboot
ls: cannot access /fastboot: そのようなファイルやディレクトリはありません
[root@centos01 ~]#

確認2: fsckされる場合

/fastbootが設定されていない状態で再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数3回に達し、Maximum mount countの設定値1を超えるため、fsckされる。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 14:35:52 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復旧

設定を戻す。
[root@centos01 ~]# tune2fs -c -1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to -1
[root@centos01 ~]#

/forcefsckの検証

ファイル/forcefsckを作成すると、強制的にfsckを実行させることができる。
これを確認する。

現在状態の確認

現在の状態を確認する。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      -1
Last checked:             Sat Feb 25 14:35:52 2017
Check interval:           0 (<none>)
[root@centos01 ~]#
マウント回数、経過時間共にfsckされる条件を満たしていないことが判る。

確認

/forcefsckを作成し、再起動する。
[root@centos01 ~]# touch /forcefsck
[root@centos01 ~]# shutdown -r now
強制的にfsckが実行される。
起動後、確認する。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      -1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

/etc/fstabの第6フィールドの検証

/etc/fstabの第6フィールドを0に設定すると、fsckが抑制される。

設定

/etc/fstabの第6フィールドを0に設定する。
[root@centos01 ~]# cp -p /etc/fstab /etc/fstab.orig
[root@centos01 ~]# grep lv_root /etc/fstab
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1
[root@centos01 ~]# sed -i '/lv_root/s/1$/0/' /etc/fstab
[root@centos01 ~]# grep lv_root /etc/fstab
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 0
[root@centos01 ~]#

Maximum mount countを1に設定する。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      -1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]# tune2fs -c 1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to 1
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認1: fsckされない

再起動する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数2回に達し、Maximum mount countの設定値1を超えるが、/etc/fstabでfsckを抑制しているため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              2
Maximum mount count:      1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

確認2: /etc/fstabの第6フィールド VS /forcefsck

/etc/fstabの第6フィールドを0にした状態で/forcefsckを作成した場合どうなるか検証する。

/forcefsckを作成し、再起動する。
[root@centos01 ~]# touch /forcefsck
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数3回に達し、Maximum mount countの設定値1を超え、さらに/etc/forcefsckが作成されているが、/etc/fstabでfsckを抑制しているため、fsckされない。
最後にfsckした時刻(Last checked)が変わっていないことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              3
Maximum mount count:      1
Last checked:             Sat Feb 25 14:48:14 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復元1: /etc/fstabのみ

/etc/fsckの第6フィールドのみ設定を戻す。
[root@centos01 ~]# mv -f /etc/fstab.orig /etc/fstab
[root@centos01 ~]# grep lv_root /etc/fstab
/dev/mapper/vg_centos01-lv_root /                       ext4    defaults        1 1
[root@centos01 ~]#

確認3: fsckされる

/etc/fsckの第6フィールドの設定を戻すと、fsckされることを確認する。
[root@centos01 ~]# shutdown -r now
起動後、確認する。
この時点でマウント回数4回に達し、Maximum mount countの設定値1を超えるので、fsckされる。
最後にfsckした時刻(Last checked)が変わったことで確認できる。
[root@centos01 ~]# tune2fs -l /dev/mapper/vg_centos01-lv_root | egrep -i 'mount count|check'
Mount count:              1
Maximum mount count:      1
Last checked:             Sat Feb 25 15:21:03 2017
Check interval:           0 (<none>)
[root@centos01 ~]#

復元2: Maximum mount count

Maximum mount countの設定を戻す。
[root@centos01 ~]# tune2fs -c -1 /dev/mapper/vg_centos01-lv_root
tune2fs 1.41.12 (17-May-2010)
Setting maximal mount count to -1
[root@centos01 ~]#

2014/09/09

CentOS 7でmozcを使う・その8・デスクトップの設定

デスクトップ右上の「ja」をクリックする。

「地域と言語の設定」を選択する。
「地域と言語」の「設定」画面が表示される。

CentOS 7でmozcを使う・その7・Emacsの設定

Emacsでmozcを利用できるよう設定する。
[alice@centos02 SPECS]$ cd
[alice@centos02 ~]$ cat >> .emacs <<'EOL'

;; for mozc
(require 'mozc)
(setq default-input-method "japanese-mozc")
[alice@centos02 ~]$ emacs -nw
EOL
[alice@centos02 ~]$ 

その0・Fedora 19レポジトリの準備
その1・mozcのビルド#1/2
その2・protobufのビルドとインストール
その3・zinniaおよびtomoeのビルドとインストール
その4・gypのビルド・インストール
その5・mozcのビルド#2/2とインストール
その6・Emacsの設定
その7・デスクトップの設定

CentOS 7でmozcを使う・その6・mozcのビルド#2/2とインストール

mozcのビルドに必要なパッケージはすべて準備出来た。

mozcのビルドを試みる。
[alice@centos02 SPECS]$ rpmbuild -ba mozc.spec
実行中(%prep): /bin/sh -e /var/tmp/rpm-tmp.hQQUlx
+ umask 022
+ cd /home/alice/rpmbuild/BUILD
+ cd /home/alice/rpmbuild/BUILD
<<略>>
  g++ '-DOS_LINUX' '-DMOZC_BUILD' '-DCHANNEL_DEV' '-DENABLE_GTK_RENDERER' '-DMOZC_ENABLE_UNITTEST' '-DNDEBUG' '-DQT_NO_DEBUG' '-DNO_LOGGING' '-DIGNORE_HELP_FLAG' '-DIGNORE_INVALID_FLAG' -I. -Iout_linux/Release/obj/gen  -Wall -Wno-char-subscripts -Wno-sign-compare -Wno-deprecated-declarations -Wwrite-strings -fPIC -fno-exceptions -fmessage-length=0 -fno-strict-aliasing -funsigned-char -include base/namespace.h -pipe -pthread -fno-omit-frame-pointer -fstack-protector --param=ssp-buffer-size=4 -O2 -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -Wno-deprecated -std=gnu++0x -O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong --param=ssp-buffer-size=4 -grecord-gcc-switches   -m64 -mtune=generic -MMD -MF out_linux/Release/.deps/out_linux/Release/obj.target/http_client/net/proxy_manager.o.d.raw  -c -o out_linux/Release/obj.target/http_client/net/proxy_manager.o net/proxy_manager.cc
net/http_client.cc:587:9: note: #pragma message: HTTPClient is disabled.
 MOZC_COMPILE_MESSAGE("HTTPClient is disabled.");
         ^
  LD_LIBRARY_PATH=/home/alice/rpmbuild/BUILD/mozc-1.15.1814.102/out_linux/Release/lib.host:/home/alice/rpmbuild/BUILD/mozc-1.15.1814.102/out_linux/Release/lib.target:$LD_LIBRARY_PATH; export LD_LIBRARY_PATH; cd gui; mkdir -p /home/alice/rpmbuild/BUILD/mozc-1.15.1814.102/out_linux/Release/obj/gen/gui/tool; /usr/lib64/qt-3.3/bin/rcc -o "/home/alice/rpmbuild/BUILD/mozc-1.15.1814.102/out_linux/Release/obj/gen/gui/tool/qrc_mozc_tool.cc" -name qrc_mozc_tool tool/mozc_tool.qrc
/bin/sh: /usr/lib64/qt-3.3/bin/rcc: No such file or directory
make: *** [out_linux/Release/obj/gen/gui/tool/qrc_mozc_tool.cc] Error 127
make: *** Waiting for unfinished jobs....
Traceback (most recent call last):
  File "build_mozc.py", line 1467, in 
    main()
  File "build_mozc.py", line 1463, in main
    procedure[1](cmd_opts, cmd_args, original_directory_name)
  File "build_mozc.py", line 1086, in BuildMain
    BuildOnLinux(options, targets, original_directory_name)
  File "build_mozc.py", line 1042, in BuildOnLinux
    RunOrDie([make_command] + build_args + target_names)
  File "/home/alice/rpmbuild/BUILD/mozc-1.15.1814.102/build_tools/util.py", line 97, in RunOrDie
    '==========']))
build_tools.util.RunOrDieError:
==========
 ERROR: make -j2 MAKE_JOBS=2 BUILDTYPE=Release builddir_name=out_linux V=1 ibus_mozc mozc_emacs_helper mozc_server mozc_tool mozc_renderer
==========
エラー: /var/tmp/rpm-tmp.nwszNW の不正な終了ステータス (%build)


RPM ビルドのエラー:
    /var/tmp/rpm-tmp.nwszNW の不正な終了ステータス (%build)
[alice@centos02 SPECS]$
ビルドが失敗する。
原因は、/usr/lib64/qt-3.3/bin/rccが存在しないため。

CentOS 7でmozcを使う・その5・gypのビルド・インストール

gypをビルドする。

展開する。
[alice@centos02 SPECS]$ cd
[alice@centos02 ~]$ rpm -ivh gyp-0.1-0.10.1617svn.fc19.src.rpm
警告: gyp-0.1-0.10.1617svn.fc19.src.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID fb4b18e6: NOKEY
更新中 / インストール中...
   1:gyp-0.1-0.10.1617svn.fc19        ################################# [100%]
警告: ユーザー mockbuild は存在しません - root を使用します
警告: グループ mockbuild は存在しません - root を使用します
警告: ユーザー mockbuild は存在しません - root を使用します
<<略>>
警告: グループ mockbuild は存在しません - root を使用します
[alice@centos02 ~]$ 

CentOS 7でmozcを使う・その4・zinniaおよびtomoeのビルドとインストール

続いて、zinniaのビルドを試みる。
[alice@centos02 SPECS]$ cd
[alice@centos02 ~]$ rpm -ivh zinnia-0.06-16.fc19.src.rpm
警告: zinnia-0.06-16.fc19.src.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID fb4b18e6: NOKEY
更新中 / インストール中...
   1:zinnia-0.06-16.fc19              ################################# [100%]
警告: ユーザー mockbuild は存在しません - root を使用します
警告: グループ mockbuild は存在しません - root を使用します
警告: ユーザー mockbuild は存在しません - root を使用します
<<略>>
警告: グループ mockbuild は存在しません - root を使用します
[alice@centos02 ~]$ cd rpmbuild/SPECS/
[alice@centos02 SPECS]$ rpmbuild -ba zinnia.spec
警告: %changelog に偽の日付: Fri Mar 04 2010 Liang Suilong  - 0.05-3
警告: %changelog に偽の日付: Wed Mar 02 2010 Liang Suilong  - 0.05-2
エラー: ビルド依存性の失敗:
        tomoe は zinnia-0.06-16.el7.centos.x86_64 に必要とされています
[alice@centos02 SPECS]$
パッケージtomoeが不足していることが判る。

tomoeは、CentOS 7用レポジトリに存在していない。
[alice@centos02 SPECS]$ cd
[alice@centos02 ~]$ yum info tomoe
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
エラー: 表示するパッケージはありません
[alice@centos02 ~]$

CentOS 7でmozcを使う・その3・protobufのビルドとインストール

まず、protobufのビルドを試みる。
基本的な手順は、mozcと同じ。
[alice@centos02 ~]$ rpm -ivh protobuf-2.5.0-4.fc19.src.rpm
警告: protobuf-2.5.0-4.fc19.src.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID fb4b18e6: NOKEY
更新中 / インストール中...
   1:protobuf-2.5.0-4.fc19            ################################# [100%]
警告: ユーザー mockbuild は存在しません - root を使用します
警告: グループ mockbuild は存在しません - root を使用します
<<略>>
警告: グループ mockbuild は存在しません - root を使用します
[alice@centos02 ~]$ cd rpmbuild/SPECS/
[alice@centos02 SPECS]$ rpmbuild -ba protobuf.spec
Package emacs was not found in the pkg-config search path.
Perhaps you should add the directory containing `emacs.pc'
to the PKG_CONFIG_PATH environment variable
No package 'emacs' found
エラー: ビルド依存性の失敗:
        emacs-el >= 24.1 は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされてい ます
        python-devel は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされています
        java-devel >= 1.6 は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされています
        maven-local は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされています
        maven-compiler-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされています
        maven-install-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされ ています
        maven-jar-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされてい ます
        maven-javadoc-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされ ています
        maven-resources-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とさ れています
        maven-surefire-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされています
        maven-antrun-plugin は protobuf-2.5.0-4.el7.centos.x86_64 に必要とされています
[alice@centos02 SPECS]$
不足しているパッケージについて、CentOS 7用レポジトリからインストールを試みる。

CentOS 7でmozcを使う・その2・mozcのビルド#1/2

mozcのSRPMをダウンロードし、ビルド(コンパイル)を試みる。
[alice@centos02 ~]$ yumdownloader --source --enablerepo=fedora,fedora-updates mozc
読み込んだプラグイン:fastestmirror, langpacks
Enabling base-source repository
Enabling updates-source repository
<<略>>
警告: /home/alice/mozc-1.15.1814.102-1.fc19.src.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID fb4b18e6: NOKEY
mozc-1.15.1814.102-1.fc19.src.rpm の公開鍵がインストールされていません
mozc-1.15.1814.102-1.fc19.src.rpm                          |  35 MB   02:40
[alice@centos02 ~]$

rpm -ivh」で展開する。
~/rpmbuildに展開される。
[alice@centos02 ~]$ rpm -ivh mozc-1.15.1814.102-1.fc19.src.rpm
警告: mozc-1.15.1814.102-1.fc19.src.rpm: ヘッダー V3 RSA/SHA256 Signature、鍵 ID fb4b18e6: NOKEY
更新中 / インストール中...
   1:mozc-1.15.1814.102-1.fc19        ################################# [100%]
警告: ユーザー mockbuild は存在しません - root を使用します
警告: グループ mockbuild は存在しません - root を使用します
<<略>>
警告: グループ mockbuild は存在しません - root を使用します
[alice@centos02 ~]$

CentOS 7でmozcを使う・その1・Fedora 19レポジトリの準備

Fedora 19用yumレポジトリを利用できるようにする。

RPMファイルを展開するために、rpmdevtoolsを導入する。
[root@centos02 ~]# yum install -y rpmdevtools
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile
依存性の解決をしています
<<略>>
インストール:
  rpmdevtools.noarch 0:8.3-5.el7

完了しました!
[root@centos02 ~]#

RPMパッケージをダウンロードする。
[alice@centos02 ~]$ wget 'http://ftp.jaist.ac.jp/pub/Linux/Fedora/releases/19/Fedora/x86_64/os/Packages/f/fedora-release-19-2.noarch.rpm'
--2014-09-08 21:54:53--  http://ftp.jaist.ac.jp/pub/Linux/Fedora/releases/19/Fedora/x86_64/os/Packages/f/fedora-release-19-2.noarch.rpm
ftp.jaist.ac.jp (ftp.jaist.ac.jp) をDNSに問いあわせています... 150.65.7.130, 2001:df0:2ed:feed::feed
ftp.jaist.ac.jp (ftp.jaist.ac.jp)|150.65.7.130|:80 に接続しています... 接続しま した。
<<略>>
2014-09-08 21:54:54 (77.5 KB/s) - `fedora-release-19-2.noarch.rpm' へ保存完了 [32472/32472]

[alice@centos02 ~]$

CentOS 7でmozcを使う・その0・概要

RHEL 7 (Red Hat Enterprise Linux 7)やCentOS 7などの互換OSでは、標準で日本語入力にkkcを利用できる。
しかし、このkkcは、非常に使いづらい。
この代替として、mozcを導入する方法を紹介する。

Mozcは、Google 日本語入力の流れを汲む、日本語IME(Input Method Editor)。
複数のUNIX系OSをはじめ、Windowsにも対応している。

2014/09/07

CentOS 7とvmware-tools

RHEL 7 (Red Hat Enterprise Linux 7)互換のCentOS 7をVMware ESXi上のゲストOSとして動かす場合、vmware-toolsを別途インストールする必要が無い。

CentOS 7には、標準パッケージにvmware-tools相等のものが入っている。
それを利用すれば、OS起動後にVMwareが提供するvmware-toolsを別途インストールする必要が無い。
パッケージグループとしては、guest-agentsおよびguest-desktop-agentsをインストールすればよい。
$ yum --disablerepo=epel groups info guest-agents guest-desktop-agents
読み込んだプラグイン:fastestmirror, langpacks
Loading mirror speeds from cached hostfile

グループ: ゲストエージェント
 グループ ID: guest-agents
 説明: ハイパーバイザー配下で稼働する場合に使用するエージェントです。
 強制的なパッケージ:
   =hyperv-daemons
   =open-vm-tools
   =qemu-guest-agent

グループ: ゲストデスクトップエージェント
 グループ ID: guest-desktop-agents
 説明: 仮想化したデスクトップとして稼働する場合に使用するエージェントです。
 強制的なパッケージ:
   =open-vm-tools-desktop
    qemu-guest-agent
   =spice-vdagent
$
なお、上の実行例では、yumコマンドで非標準レポジトリであるepelを無効化するために、disablerepoオプションを使用している。

2012/09/28

SSL/TLSポートの試験にopenssl s_client・gnutls-cliを使う


通常のTCPポート試験には、nc(1)コマンドを使う(以前はtelnet(1)コマンドがよく使われていた)。例えば、POP(110/tcp)は、以下の様に試験できる。
[user01@rhel01 ~]$ nc localhost 110
+OK Dovecot ready.
USER user01
+OK
PASS password
+OK Logged in.
LIST
+OK 1 messages:
1 448
.
QUIT
+OK Logging out.
[user01@rhel01 ~]$

では、SSL/TLSで暗号化されたTCPポートのテストはどうすればよいか?
まず、openssl(1)コマンドを用いる方法がある。このopensslコマンドのサブコマンドs_clientに、接続先を指定するオプション「-connect host:port」を与えて試験すればよい。例えば、POP3S(995/tcp)は、以下の様に試験できる。
[user01@rhel01 ~]$ openssl s_client -connect localhost:pop3s
CONNECTED(00000003)
depth=0 /OU=IMAP server/CN=imap.example.com/emailAddress=postmaster@example.com
verify error:num=18:self signed certificate
verify return:1
depth=0 /OU=IMAP server/CN=imap.example.com/emailAddress=postmaster@example.com
verify return:1
---
Certificate chain
 0 s:/OU=IMAP server/CN=imap.example.com/emailAddress=postmaster@example.com
   i:/OU=IMAP server/CN=imap.example.com/emailAddress=postmaster@example.com
---
Server certificate
-----BEGIN CERTIFICATE-----
MIICQzCCAaygAwIBAgIJALDUM09AsGlJMA0GCSqGSIb3DQEBBQUAMFgxFDASBgNV
<<略>>
Mk2FmzapbpeX11HSqprCX984Ofn00Ou8/AS2d9yEeJ/fsbB6UO9L8DZb0gL9nrkL
L7oDAsrwYg==
-----END CERTIFICATE-----
subject=/OU=IMAP server/CN=imap.example.com/emailAddress=postmaster@example.com
issuer=/OU=IMAP server/CN=imap.example.com/emailAddress=postmaster@example.com
---
No client certificate CA names sent
---
SSL handshake has read 1154 bytes and written 319 bytes
---
New, TLSv1/SSLv3, Cipher is DHE-RSA-AES256-SHA
Server public key is 1024 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
    Protocol  : TLSv1
    Cipher    : DHE-RSA-AES256-SHA
    Session-ID: 69F38BFB461D7E2CA1ED16CD1F7CA61B0CEEE69E9EB6AB64A45FDEC3BC4EE710
    Session-ID-ctx:
    Master-Key: 77544FE452E4FE2E1D735F023CD36BB5C8F6BD91BB62FB7A12C105144FB85A6F6FD2D2442B97F8DA96E753C21E7FB78A
    Key-Arg   : None
    Krb5 Principal: None
    Start Time: 1348815266
    Timeout   : 300 (sec)
    Verify return code: 18 (self signed certificate)
---
+OK Dovecot ready.
USER user01
+OK
PASS password
+OK Logged in.
LIST
+OK 1 messages:
1 448
.
QUIT
DONE
[user01@rhel01 ~]$

別法として、gnutls-cli(1)コマンドを使う方法もある。
[user01@rhel01 ~]$ gnutls-cli --port pop3s localhostResolving 'localhost'...
Connecting to '127.0.0.1:995'...
- Certificate type: X.509
 - Got a certificate list of 1 certificates.

 - Certificate[0] info:
 # The hostname in the certificate does NOT match 'localhost'.
 # valid since: Fri Sep 28 14:51:09 JST 2012
 # expires at: Sat Sep 28 14:51:09 JST 2013
 # fingerprint: E4:CB:D0:E4:F7:78:E8:59:20:45:0F:33:D4:4C:DB:01
 # Subject's DN: OU=IMAP server,CN=imap.example.com,EMAIL=postmaster@example.com
 # Issuer's DN: OU=IMAP server,CN=imap.example.com,EMAIL=postmaster@example.com


- Peer's certificate issuer is unknown
- Peer's certificate is NOT trusted
- Version: TLS 1.0
- Key Exchange: DHE RSA
- Cipher: AES 256 CBC
- MAC: SHA
- Compression: DEFLATE
- Handshake was completed

- Simple Client Mode:

+OK Dovecot ready.
USER user01
+OK
PASS password
+OK Logged in.
LIST
+OK 1 messages:
1 448
.
QUIT
+OK Logging out.
*** Fatal error: A TLS packet with unexpected length was received.
*** Server has terminated the connection abnormally.
[user01@rhel01 ~]$

なお、Red Hat系であれば、openssl(1)・gnutls-cli(1)両コマンドはそれぞれ、openssl・gnutls-utilsの両パッケージに含まれる。
[user01@rhel01 ~]$ rpm -qf $(which openssl)
openssl-0.9.8e-20.el5
openssl-0.9.8e-20.el5
[user01@rhel01 ~]$ rpm -qf $(which gnutls-cli)
gnutls-utils-1.4.1-3.el5_4.8
[user01@rhel01 ~]$

2012/01/28

Red Hat 6系でLLDPを使う・その2

前回の補足。 「lldptool set-tlv」 コマンドの「-V」オプションで指定できる項目にはどう言うものがあるだろう?調べてみよう。
[root@sl01 ~]# lldptool -h
Usage:
  lldptool  [options] [arg]   general command line usage format
  lldptool                             go into interactive mode
            [options] [arg]   general interactive command format

Options:
  -i [ifname]                          network interface
  -V [tlvid]                           TLV identifier
                                       may be numeric or keyword (see below)
  -n                                   "neighbor" option for command
  -a                                   "add" option for command
  -d                                   "remove" option for command
  -r                                   show raw message
  -R                                   show only raw messages

Commands:
  license                              show license information
  -h|help                              show command usage information
  -v|version                           show version
  -q|quit                              exit lldptool (interactive mode)
  -S|stats                             get LLDP statistics for ifname
  -t|get-tlv                           get TLVs from ifname
  -T|set-tlv                           set arg for tlvid to value
  -l|get-lldp                          get the LLDP parameters for ifname
  -L|set-lldp                          set the LLDP parameter for ifname

TLV identifiers:
   chassisID    : Chassis ID TLV
   portID       : Port ID TLV
   TTL          : Time to Live TLV
   portDesc     : Port Description TLV
   sysName      : System Name TLV
   sysDesc      : System Description TLV
   sysCap       : System Capabilities TLV
   mngAddr      : Management Address TLV
   macPhyCfg    : MAC/PHY Configuration Status TLV
   powerMdi     : Power via MDI TLV
   linkAgg      : Link Aggregation TLV
   MTU          : Maximum Frame Size TLV
   LLDP-MED     : LLDP-MED Settings
   medCap       : LLDP-MED Capabilities TLV
   medPolicy    : LLDP-MED Network Policy TLV
   medLoc       : LLDP-MED Location TLV
   medPower     : LLDP-MED Extended Power-via-MDI TLV
   medHwRev     : LLDP-MED Hardware Revision TLV
   medFwRev     : LLDP-MED Firmware Revision TLV
   medSwRev     : LLDP-MED Software Revision TLV
   medSerNum    : LLDP-MED Serial Number TLV
   medManuf     : LLDP-MED Manufacturer Name TLV
   medModel     : LLDP-MED Model Name TLV
   medAssetID   : LLDP-MED Asset ID TLV
   DCBXv1       : PRE-CEE DCBX TLV
   DCBX         : CEE DCBX TLV
   evbCfg       : EVB Configuration TLV
   vdp          : VDP protocol configuration
[root@sl01 ~]# 
サービスlldpadの設定ファイルは、/var/lib/lldpad/lldpad.conf。この設定ファイルは、lldpadデーモン起動時に存在していなければ、デーモンが自動的に作成する。
[root@sl01 ~]# service lldpad stop
Shutting down lldpad: [done]                               [  OK  ]
[root@sl01 ~]# rm /var/lib/lldpad/lldpad.conf
rm: remove 通常ファイル `/var/lib/lldpad/lldpad.conf'? y
[root@sl01 ~]# ls -l /var/lib/lldpad/lldpad.conf
ls: cannot access /var/lib/lldpad/lldpad.conf: そのようなファイルやディレクトリ はありません
[root@sl01 ~]# service lldpad start
Starting lldpad: [done]                                    [  OK  ]
[root@sl01 ~]# ls -l /var/lib/lldpad/lldpad.conf
-rw-------. 1 root root 213  1月 28 11:02 2012 /var/lib/lldpad/lldpad.conf
[root@sl01 ~]#
中身はテキストファイルだ。
[root@sl01 ~]# cat /var/lib/lldpad/lldpad.conf
dcbx :
{
  version = "1.0";
  dcbx_version = 2;
};
lldp :
{
  em1 :
  {
    tlvid00000001 :
    {
      info = "04D4AE52724ADD";
    };
    tlvid00000002 :
    {
      info = "03D4AE52724ADD";
    };
  };
};
[root@sl01 ~]#
デーモン起動時にリンクアップしているインターフェースに関する定義が自動的に追加されている。 この設定ファイルは、前回までに見たとおり、lldptool(8)コマンドを使い間接的に編集するが、手で編集できないわけでもない。
[root@sl01 ~]# service lldpad stop
Shutting down lldpad: [done]                               [  OK  ]
[root@sl01 ~]# rm /var/lib/lldpad/lldpad.conf
rm: remove 通常ファイル `/var/lib/lldpad/lldpad.conf'? y
[root@sl01 ~]# cp lldpad.conf /var/lib/lldpad/
[root@sl01 ~]# cat /var/lib/lldpad/lldpad.conf
dcbx :
{
  version = "1.0";
  dcbx_version = 2;
};
lldp :
{
  common :
  {
    adminStatus = 3;
    tlvid00000005 :
    {
      enableTx = true;
    };
    tlvid00000006 :
    {
      enableTx = true;
    };
    tlvid00000004 :
    {
      enableTx = true;
    };
    tlvid00000007 :
    {
      enableTx = true;
    };
    tlvid00120f01 :
    {
      enableTx = true;
    };
    tlvid00120f03 :
    {
      enableTx = true;
    };
    tlvid00120f04 :
    {
      enableTx = true;
    };
    tlvid00000008 :
    {
      enableTx = true;
    };
  };
};
[root@sl01 ~]#
この状態でデーモンを起動すると、期待通りLLDPの送受信が有効となっている。
[root@sl01 ~]# service lldpad start
Starting lldpad: [done]                                    [  OK  ]
[root@sl01 ~]# lldptool get-tlv -i em1
Chassis ID TLV
        MAC: d4:ae:52:72:4a:dd
Port ID TLV
        MAC: d4:ae:52:72:4a:dd
Time to Live TLV
        120
Port Description TLV
        Interface   4 as em1
System Name TLV
        sl01.mynetwork.local
System Description TLV
        Linux sl01.mynetwork.local 2.6.32-220.2.1.el6.x86_64 #1 SMP Thu Dec 22 11:15:52 CST 2011 x86_64
System Capabilities TLV
        System capabilities:  Station Only
        Enabled capabilities: Station Only
Management Address TLV
        IPv6: f246:4000::
        Ifindex: 4
MAC/PHY Configuration Status TLV
        Auto-negotiation supported and enabled
        PMD auto-negotiation capabilities: 0x8037
        MAU type: 1000 BaseTFD
Link Aggregation TLV
        Aggregation not capable
        Currently not aggregated
        Aggregated Port ID: 0
Maximum Frame Size TLV
        1522
End of LLDPDU TLV
[root@sl01 ~]#
ただし、デーモン起動時にリンクアップしていたインターフェースの設定が自動的に追加されている。
[root@sl01 ~]# diff lldpad.conf /var/lib/lldpad/lldpad.conf
43a44,58
>   em1 :
>   {
>     tlvid00000001 :
>     {
>       info = "04D4AE52724ADD";
>     };
>     tlvid00000002 :
>     {
>       info = "03D4AE52724ADD";
>     };
>     tlvid00000008 :
>     {
>       ipv6 = "f246:4000::";
>     };
>   };
[root@sl01 ~]#
Red Hat 6系でLLDPを使う・その1
Red Hat 6系でLLDPを使う・その2

Red Hat 6系でLLDPを使う・その1

Red Hat Enterprise Linux 6 (RHEL6)およびその互換ディストリビューションでは、LLDPがサポートされている。今回の記事では、これを使ってみる。

LLDP (Link Layer Discovery Protocol)は、ネットワークインターフェースに直接接続されている対向機器が何かを知ることができる仕組み。Cisco製品を使ったことがあれば、CDPのオープン規格版だと思えば理解しやすいだろう。例えば、次のように使う。
[root@sl01 ~]# lldptool get-tlv -i em1 -n
Chassis ID TLV
        MAC: 08:2e:5f:85:7f:eb
Port ID TLV
        Local: 3
Time to Live TLV
        120
Port Description TLV
        3
System Name TLV
        ProCurve Switch 2510G-48
System Description TLV
        ProCurve J9280A Switch 2510G-48, revision Y.11.12, ROM N.10.02 (/sw/code/build/cod(cod11))
System Capabilities TLV
        System capabilities:  Bridge
        Enabled capabilities: Bridge
Management Address TLV
        IPv4: 172.18.0.245
        Ifindex: 0
End of LLDPDU TLV
[root@sl01 ~]#
出力結果を見ると、自身sl01のインターフェースem1の対向機器は、ProCurve Switch 2510G-48であって、そのポート3と接続されていることがわかる。その他、様々な情報を得ることができる。ただし、CDPとは違い、LLDPは、ネットワーク機器側、サーバ側双方ともデフォルトでは有効ではない。従って、有効にするための設定が必要。

まずは、サーバ側の設定を見てみよう。ネットワーク機器側は既に設定されているものとする。以下は、RHEL6.1と互換のScientific Linux 6.1で検証した。
RHEL系でLLDP機能を担うのは、lldpadというパッケージ。まず、これをインストールする。
[root@sl01 ~]# yum install -y lldpad
Loaded plugins: refresh-packagekit
sl                                                       | 1.9 kB     00:00
sl-security                                              | 1.9 kB     00:00
Setting up Install Process
Resolving Dependencies
<<略>> 

Running Transaction
Warning: RPMDB altered outside of yum.
  Installing : libconfig-1.3.2-1.1.el6.x86_64                               1/2
  Installing : lldpad-0.9.41-4.el6.x86_64                                   2/2

Installed:
  lldpad.x86_64 0:0.9.41-4.el6

Dependency Installed:
  libconfig.x86_64 0:1.3.2-1.1.el6

Complete!
[root@sl01 ~]#
インストールすると、lldpadというサービスが追加される。サービスが起動していない状態では、設定できない。インストール直後は、サービスが起動されていないため、起動する。
[root@sl01 ~]# chkconfig --list lldpad
lldpad          0:off   1:off   2:on    3:on    4:on    5:on    6:off
[root@sl01 ~]# service lldpad start
Starting lldpad: [done]                                    [  OK  ]
[root@sl01 ~]#
LLDPフレームを送受信するよう設定する。設定後、サービスを再起動しないと反映されないので注意する。
[root@sl01 ~]# lldptool set-lldp adminStatus=rxtx
[root@sl01 ~]# service lldpad restart
Checking for service lldpad: running
Shutting down lldpad: [done]                               [  OK  ]
Starting lldpad: [done]                                    [  OK  ]
[root@sl01 ~]#
タイミングによるが、まず最初にLLDPフレームをいくつか送信した後、ネットワーク機器側からのLLDPフレームが届く。これは、以下の様に確認することができる。
[root@sl01 ~]# lldptool stats -i em1
Total Frames Transmitted        = 5
Total Discarded Frames Received = 0
Total Error Frames Received     = 0
Total Frames Received           = 0
Total Discarded TLVs            = 0
Total Unrecognized TLVs         = 0
Total Ageouts                   = 0
[root@sl01 ~]# lldptool stats -i em1
Total Frames Transmitted        = 5
Total Discarded Frames Received = 0
Total Error Frames Received     = 0
Total Frames Received           = 2
Total Discarded TLVs            = 0
Total Unrecognized TLVs         = 0
Total Ageouts                   = 0
[root@sl01 ~]#
一回目の実行では、送信済フレームが5、受信済フレームが0だが、二回目は、受信フレームが2になっていることが解る。この状態になると、対向機器の情報を得ることができる。
[root@sl01 ~]# lldptool get-tlv -i em1 -n
Chassis ID TLV
        MAC: 08:2e:5f:85:7f:eb
Port ID TLV
        Local: 3
Time to Live TLV
        120
Port Description TLV
        3
System Name TLV
        ProCurve Switch 2510G-48
System Description TLV
        ProCurve J9280A Switch 2510G-48, revision Y.11.12, ROM N.10.02 (/sw/code/build/cod(cod11))
System Capabilities TLV
        System capabilities:  Bridge
        Enabled capabilities: Bridge
Management Address TLV
        IPv4: 172.18.0.245
        Ifindex: 0
End of LLDPDU TLV
[root@sl01 ~]#
一方、この状態ではサーバ側からはどう言う情報が送信されているのだろう。サーバ側から確認する。
[root@sl01 ~]# lldptool get-tlv -i em1
Chassis ID TLV
        MAC: d4:ae:52:72:4a:dd
Port ID TLV
        MAC: d4:ae:52:72:4a:dd
Time to Live TLV
        120
End of LLDPDU TLV
[root@sl01 ~]#
シャーシID(Chassis ID)およびポートID(Port ID)としてMACアドレスが、TTLとして120[秒]が送信される設定になっている。
ネットワーク機器側で確認する。
ProCurve Switch 2510G-48# show lldp info remote-device 3

 LLDP Remote Device Information Detail

  Local Port   : 3
  ChassisType  : mac-address
  ChassisId    : d4 ae 52 72 4a dd
  PortType     : mac-address
  PortId       : d4 ae 52 72 4a dd
  SysName      :
  System Descr :
  PortDescr    :

  System Capabilities Supported  :
  System Capabilities Enabled    :

  Remote Management Address


ProCurve Switch 2510G-48#
それらの情報がネットワーク機器側に認識されていることが判る。

さらに、ホスト名が送信される様設定してみよう。設定後は再起動が必要。
[root@sl01 ~]# lldptool set-tlv -V sysName enableTx=yes
[root@sl01 ~]# service lldpad restart
Checking for service lldpad: running
Shutting down lldpad: [done]                               [  OK  ]
Starting lldpad: [done]                                    [  OK  ]
[root@sl01 ~]#
ネットワーク機器側で確認する。
ProCurve Switch 2510G-48# show lldp info remote-device 3

 LLDP Remote Device Information Detail

  Local Port   : 3
  ChassisType  : mac-address
  ChassisId    : d4 ae 52 72 4a dd
  PortType     : mac-address
  PortId       : d4 ae 52 72 4a dd
  SysName      : sl01.mynetwork.local
  System Descr :
  PortDescr    :

  System Capabilities Supported  :
  System Capabilities Enabled    :

  Remote Management Address


ProCurve Switch 2510G-48#
ホスト名が認識されている。
他の情報も有効にしてみよう。
[root@sl01 ~]# lldptool set-tlv -V sysDesc enableTx=yes
[root@sl01 ~]# lldptool set-tlv -V portDesc enableTx=yes
Checking for service lldpad: running
Shutting down lldpad: [done]                               [  OK  ]
Starting lldpad: [done]                                    [  OK  ]
[root@sl01 ~]#
確認。
ProCurve Switch 2510G-48# show lldp info remote-device 3

 LLDP Remote Device Information Detail

  Local Port   : 3
  ChassisType  : mac-address
  ChassisId    : d4 ae 52 72 4a dd
  PortType     : mac-address
  PortId       : d4 ae 52 72 4a dd
  SysName      : sl01.mynetwork.local
  System Descr : Linux sl01.mynetwork.local 2.6.32-220.2.1.el6.x86_64 #1 S...
  PortDescr    : Interface   4 as em1

  System Capabilities Supported  :
  System Capabilities Enabled    :

  Remote Management Address


ProCurve Switch 2510G-48#
システム詳細(System Descr)にカーネルのバージョンが表示されている。セキュリティ的には表示しない方がいいかもしれない。

Red Hat 6系でLLDPを使う・その1
Red Hat 6系でLLDPを使う・その2

2011/11/04

Logrotateはいつログを圧縮するか、あるいは、postrotateはいつ実行されるか

日々刻々、サーバにログはたまり続け、ディスク容量を圧迫する場合がある。これを回避するため、ログファイルをrename (mv)、圧縮(gzip)し、保存期間を過ぎたものを削除する、ローテートと呼ばれる操作を行う必要がある。RHELやCentOSでは、logrotateというコマンドでこれを行う。

このlogrotateの設定ファイルは、/etc/logrotate.confおよび、その中から読み出される/etc/logrotate.d/*である。詳しくは、logrotate(8)を参照のこと。

さて、このlogrotateを使って、複数のサーバのログを、NFSなどの共有ディスク(仮に/var/oldlogsとする)に集約する場合を考えてみる。まず、複数のサーバのログが同ファイル名のだと一箇所に集約したときに上書きされてしまう可能性があるので、例えば、/var/log/some/log-ホスト名の様にしなければならない。

設定ファイル中で、ディレクティブolddir directoryでその共有ディスクに移動させる方法を思いつくかもしれない。
/var/log/some/log-ホスト名 {
      olddir /var/oldlogs
}
しかし、これは上手くいかない。というのは、logrotateでは、ローテート後のファイルは、元ファイルと同じデバイス上にしか置けない、という制限があるからだ。
# cat /etc/logrotate.d/test
/var/log/some/log-ホスト名 {
        olddir /var/oldlog
}
# ls /var/log/some
log-ホスト名
# logrotate -f /etc/logrotate.d/test
error: /etc/logrotate.d/test:3 olddir /var/oldlog and log file /var/log/some/log-ホスト名 are on different devices
# 
これを回避するために、ローテート後に共有ディスクへのコピーを実行することを思いつくだろう。設定ファイル中でpostrotate/endscript ディレクティブを使えば実現できる。このディレクティブを用いると、mv直後にシェルスクリプトを実行させることができるためだ。
# cat /etc/logrotate.d/test
/var/log/some/log-ホスト名 {
        rotate 4
        postrotate
                cp -p /var/log/some/log-ホスト名.1 /var/oldlog
        endscript
}
# logrotate -f /etc/logrotate.d/test
# ls /var/log/some
log-ホスト名.1
# ls /var/oldlog
log-ホスト名.1  lost+found
#
しかし、これにもまだ問題が出る場合がある。ディレクティブcompressを使って、ログファイルを圧縮する場合だ。次の様にして上手くいくだろうか?
# cat /etc/logrotate.d/test
/var/log/some/log-ホスト名 {
        rotate 4
        compress
        postrotate
                cp -p /var/log/some/log-ホスト名.1.gz /var/oldlog
        endscript
}
#
これは上手くいかない。
# ls /var/log/some/log-ホスト名*
/var/log/some/log-ホスト名
# ls /var/oldlog/log-ホスト名*
ls: /var/oldlog/log-ホスト名*: No such file or directory
# logrotate -f /etc/logrotate.d/test
cp: cannot stat `/var/log/some/log-ホスト名.1.gz': No such file or directory
error: error running postrotate script for /var/log/some/log-ホスト名
# ls /var/log/some/log-ホスト名*
/var/log/some/log-ホスト名.1.gz
# ls /var/oldlog/log-ホスト名.*
ls: /var/oldlog/log-ホスト名*: No such file or directory
#
なぜか?それは、実行タイミングにある。logrotateは、まずmvし、postrotate/endscript ディレクティブのシェルスクリプトを実行した後、gzipで圧縮するため、シェルスクリプト実行時には、まだ*.1.gzというファイルは存在せず、圧縮前の*.1のままである。

これは、postrotate/endscript ディレクティブの代わりにlastaction/endscript ディレクティブを使えば解決できる。
# cat /etc/logrotate.d/test
/var/log/some/log-ホスト名 {
        rotate 4
        compress
        lastaction
                cp -p /var/log/some/log-ホスト名.1.gz /var/oldlog
        endscript
}
# ls /var/log/some/log-ホスト名*
/var/log/some/log-ホスト名
# ls /var/oldlog/log-ホスト名*
ls: /var/oldlog/log-ホスト名*: No such file or directory
# logrotate -f /etc/logrotate.d/test
# ls /var/log/some/log-ホスト名*
/var/log/some/log-ホスト名.1.gz
# ls /var/oldlog/log-ホスト名*
/var/oldlog/log-ホスト名.1.gz
#
このままでは、共有ディスクには一世代しか保存されない。また、一度コピーに失敗すると、復旧できない。これらを解決するには、dateextディレクティブとrsyncコマンドを用いる。
# cat /etc/logrotate.d/test
/var/log/some/log-ホスト名 {
        rotate 4
        compress
        dateext
        lastaction
                rsync -a /var/log/some/log-ホスト名-*.gz /var/oldlog
        endscript
}
# ls /var/log/some/log-ホスト名*
/var/log/some/log-ホスト名
# ls /var/oldlog/log-ホスト名*
ls: /var/oldlog/log-ホスト名*: No such file or directory
# logrotate -f /etc/logrotate.d/test
# ls /var/log/some/log-ホスト名*
/var/log/some/log-ホスト名-20111104.gz
# ls /var/oldlog/log-ホスト名*
/var/oldlog/log-ホスト名-20111104.gz
#

2011/04/13

Xen DomUでRedmine + Phusion Passenger + Ruby Enterprise Edition

二年ぶりのご無沙汰でした。

Xen DomUで、Redmineを運用する。物理マシンの場合の手順は、『Redmine 1.1をCentOS5.5にインストールする手順』に詳しいが、Xen DomUにこれと同じ手順を適用すると、コンソールや/var/log/messagesあたりに次のようなメッセージが表示されることがある
4gb seg fixup, process ruby (pid 1270), cs:ip 73:00867ba6
4gb seg fixup, process ruby (pid 1270), cs:ip 73:001c30f1
4gb seg fixup, process ruby (pid 1270), cs:ip 73:00867ba6
4gb seg fixup, process ruby (pid 1270), cs:ip 73:001c30f1
printk: 96 messages suppressed.
4gb seg fixup, process ruby (pid 1270), cs:ip 73:00867ba6
これは、『4gb seg fixup REE XEN』で報告されている問題と同じで、ここで挙げられている通り、環境変数を設定してからRuby Enterprise Edition(以下、REE)をインストールすればよい。以下作業ログ。
REEをダウンロードし、展開する。
[fujino@DomU Ruby]$ ls ruby-enterprise-1.8.7-2011.03.tar.gz
ruby-enterprise-1.8.7-2011.03.tar.gz
[fujino@DomU Ruby]$ tar xzf ruby-enterprise-1.8.7-2011.03.tar.gz
[fujino@DomU Ruby]$
以下、rootで作業する。まず、環境変数を設定する。
[root@DomU Ruby]# export CFLAGS="-mno-tls-direct-seg-refs"
[root@DomU Ruby]# export CXXFLAGS="-mno-tls-direct-seg-refs"
[root@DomU Ruby]#
REEをインストールする。このとき、REEに同梱されているgemや開発者用ドキュメントをインストールしないよう指定する。
[root@DomU Ruby]# ./ruby-enterprise-1.8.7-2011.03/installer --dont-install-useful-gems --no-dev-docs
Welcome to the Ruby Enterprise Edition installer
This installer will help you install Ruby Enterprise Edition 1.8.7-2011.03.
Don't worry, none of your system files will be touched if you don't want them
to, so there is no risk that things will screw up.

You can expect this from the installation process:

1. Ruby Enterprise Edition will be compiled and optimized for speed for this
system.
2. Ruby on Rails will be installed for Ruby Enterprise Edition.
3. You will learn how to tell Phusion Passenger to use Ruby Enterprise
Edition instead of regular Ruby.

Press Enter to continue, or Ctrl-C to abort.[Enter]を入力

Checking for required software...

* C compiler... found at /usr/bin/gcc
* C++ compiler... found at /usr/bin/g++
* The 'make' tool... found at /usr/bin/make
* The 'patch' tool... found at /usr/bin/patch
* Zlib development headers... found
* OpenSSL development headers... found
* GNU Readline development headers... found
--------------------------------------------
Target directory

Where would you like to install Ruby Enterprise Edition to?
(All Ruby Enterprise Edition files will be put inside that directory.)

[/opt/ruby-enterprise-1.8.7-2011.03] :[Enter]を入力
--------------------------------------------
Compiling and optimizing the memory allocator for Ruby Enterprise Edition
In the mean time, feel free to grab a cup of coffee.

./configure --prefix=/opt/ruby-enterprise-1.8.7-2011.03 --disable-dependency-tracking
checking build system type... i686-pc-linux-gnu
checking host system type... i686-pc-linux-gnu
<<略>>
--------------------------------------------
Ruby Enterprise Edition is successfully installed!
If want to use Phusion Passenger (http://www.modrails.com) in combination
with Ruby Enterprise Edition, then you must reinstall Phusion Passenger against
Ruby Enterprise Edition, as follows:

/opt/ruby-enterprise-1.8.7-2011.03/bin/passenger-install-apache2-module

Make sure you don't forget to paste the Apache configuration directives that
the installer gives you.


If you ever want to uninstall Ruby Enterprise Edition, simply remove this
directory:

/opt/ruby-enterprise-1.8.7-2011.03

If you have any questions, feel free to visit our website:

http://www.rubyenterpriseedition.com

Enjoy Ruby Enterprise Edition, a product of Phusion (www.phusion.nl) :-)
[root@DomU Ruby]#
Gemを1.4.2へダウングレードする。
[root@DomU Ruby]# /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby -S gem update --system 1.4.2
Updating rubygems-update
Fetching: rubygems-update-1.4.2.gem (100%)
Successfully installed rubygems-update-1.4.2
Installing RubyGems 1.4.2
RubyGems 1.4.2 installed
File not found: README
[root@DomU Ruby]# /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby -S gem --version
1.4.2
[root@DomU Ruby]#
Rack 1.0.1およびi18n 0.4.2をインストールする。開発者用ドキュメントは不要なのでインストールしない。
[root@DomU Ruby]# /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby -S gem install rack --version=1.0.1 --no-rdoc --no-ri
Fetching: rack-1.0.1.gem (100%)
Successfully installed rack-1.0.1
1 gem installed
[root@DomU Ruby]# /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby -S gem install i18n --version=0.4.2 --no-rdoc --no-ri
Fetching: i18n-0.4.2.gem (100%)
Successfully installed i18n-0.4.2
1 gem installed
[root@DomU Ruby]#
づつけて、MySQL gemをインストールする。やはり開発者用ドキュメントは不要なのでインストールしない。
[root@DomU Ruby]# /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby -S gem install mysql --no-rdoc --no-ri
Fetching: mysql-2.8.1.gem (100%)
Building native extensions. This could take a while...
Successfully installed mysql-2.8.1
1 gem installed
[root@DomU Ruby]#
Apache HTTP Server用モジュールをインストールする。
[root@DomU Ruby]# /opt/ruby-enterprise-1.8.7-2011.03/bin/passenger-install-apache2-module
Welcome to the Phusion Passenger Apache 2 module installer, v3.0.6.

This installer will guide you through the entire installation process. It
shouldn't take more than 3 minutes in total.

Here's what you can expect from the installation process:

1. The Apache 2 module will be installed for you.
2. You'll learn how to configure Apache.
3. You'll learn how to deploy a Ruby on Rails application.

Don't worry if anything goes wrong. This installer will advise you on how to
solve any problems.

Press Enter to continue, or Ctrl-C to abort.[Enter]を入力


--------------------------------------------

Checking for required software...

* GNU C++ compiler... found at /usr/bin/g++
* Curl development headers with SSL support... found
* OpenSSL development headers... found
<<略>>

--------------------------------------------
The Apache 2 module was successfully installed.

Please edit your Apache configuration file, and add these lines:

LoadModule passenger_module /opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.6/ext/apache2/mod_passenger.so
PassengerRoot /opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.6
PassengerRuby /opt/ruby-enterprise-1.8.7-2011.03/bin/ruby

After you restart Apache, you are ready to deploy any number of Ruby on Rails
applications on Apache, without any further Ruby on Rails-specific
configuration!

Press ENTER to continue.[Enter]を入力


--------------------------------------------
Deploying a Ruby on Rails application: an example

Suppose you have a Rails application in /somewhere. Add a virtual host to your
Apache configuration file and set its DocumentRoot to /somewhere/public:


ServerName www.yourhost.com
DocumentRoot /somewhere/public # <-- be sure to point to 'public'!

AllowOverride all # <-- relax Apache security settings
Options -MultiViews # <-- MultiViews must be turned off



And that's it! You may also want to check the Users Guide for security and
optimization tips, troubleshooting and other useful information:

/opt/ruby-enterprise-1.8.7-2011.03/lib/ruby/gems/1.8/gems/passenger-3.0.6/doc/Users guide Apache.html

Enjoy Phusion Passenger, a product of Phusion (www.phusion.nl) :-)
http://www.modrails.com/

Phusion Passenger is a trademark of Hongli Lai & Ninh Bui.
[root@DomU Ruby]#

2009/04/05

シェルスクリプト内でXMLから情報を取り出す

XML形式により情報をやり取りすることが多くなった昨今、シェルスクリプト(shell script)でXMLを扱うことも増えてきた。例えば、libvirtを使って
virsh dumpxml DomU名
として得た仮想マシンの設定情報などだ。Xen DomU dc1の設定ファイル/etc/xen/dc1が、
name = "dc1"
uuid = "4df3f764-00cb-42a6-8ff6-a98985cbda14"
maxmem = 256
memory = 64
vcpus = 1
bootloader = "/usr/bin/pygrub"
on_poweroff = "destroy"
on_reboot = "restart"
on_crash = "restart"
vfb = [ ]
disk = [ "phy:/dev/VolGroupXX/LogVolDc1,xvda,w" ]
vif = [ "mac=00:16:3e:ff:ab:01,bridge=br1000",
"mac=00:16:3e:ff:ab:02,bridge=br2000" ]
だったとしよう。このdc1の設定をXML形式で得ると、
# virsh dumpxml dc1
<domain type='xen' id='18'>
<name>dc1</name>
<uuid>094a82d5-7e6c-980d-49d3-9e8e68fb84e2</uuid>
<bootloader>/usr/bin/pygrub</bootloader>
<os>
<type>linux</type>
<kernel>/var/lib/xen/boot_kernel.rMNCqh</kernel>
<initrd>/var/lib/xen/boot_ramdisk.og2mn7</initrd>
<cmdline>ro root=/dev/VolGroup00/LogVol00 console=xvc0 acpi=off nopcmcia noapm nousb nofirewire nosound</cmdline>
</os>
<memory>262144</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<interface type='bridge'>
<source bridge='br4000'/>
<target dev='vif18.0'/>
<mac address='00:16:3e:1d:89:01'/>
<script path='vif-bridge'/>
</interface>
<interface type='bridge'>
<source bridge='br2002'/>
<target dev='vif18.1'/>
<mac address='00:16:3e:1d:92:01'/>
<script path='vif-bridge'/>
</interface>
<disk type='block' device='disk'>
<driver name='phy'/>
<source dev='/dev/VolGroupXX/LogVolDc1'/>
<target dev='xvda'/>
</disk>
<console tty='/dev/pts/1'/>
</devices>
</domain>

#
のようになる。このとき、ディスクに関する情報を取り出したいとしよう。
まず、XML形式をファイルに保存する。
# virsh dumpxml dc1 > dc1.xml
#
このファイルを引数として、xmllintコマンドを対話モードで起動する。
# xmllint --shell dc1.xml
/ >
プロンプトの「/」は、現在のXML文書上のパスを示している。
ここで「cat」と入力すると、現在のパス以下の内容すべてが表示される。つまり、XMLファイルの内容すべてが表示されることになる。
/ > cat
<?xml version="1.0"?>
<domain type="xen" id="18">
<name>dc1</name>
<uuid>094a82d5-7e6c-980d-49d3-9e8e68fb84e2</uuid>
<bootloader>/usr/bin/pygrub</bootloader>
<os>
<type>linux</type>
<kernel>/var/lib/xen/boot_kernel.rMNCqh</kernel>
<initrd>/var/lib/xen/boot_ramdisk.og2mn7</initrd>
<cmdline>ro root=/dev/VolGroup00/LogVol00 console=xvc0 acpi=off nopcmcia noapm nousb nofirewire nosound</cmdline>
</os>
<memory>262144</memory>
<currentMemory>65536</currentMemory>
<vcpu>1</vcpu>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>restart</on_crash>
<devices>
<interface type="bridge">
<source bridge="br4000"/>
<target dev="vif18.0"/>
<mac address="00:16:3e:1d:89:01"/>
<script path="vif-bridge"/>
</interface>
<interface type="bridge">
<source bridge="br2002"/>
<target dev="vif18.1"/>
<mac address="00:16:3e:1d:92:01"/>
<script path="vif-bridge"/>
</interface>
<disk type="block" device="disk">
<driver name="phy"/>
<source dev="/dev/VolGroupXX/LogVolDc1"/>
<target dev="xvda"/>
</disk>
<console tty="/dev/pts/1"/>
</devices>
</domain>

/ >
ただし、xmllintの出力は正規化されているため、先頭行が追加されている。
ディスクに関する設定は、XPath形式で表せば、「/domain/devices/disk」にあることが解る。これをcatで出力してみる。
/ > cat /domain/devices/disk
-------
<disk type="block" device="disk">
<driver name="phy"/>
<source dev="/dev/VolGroupXX/LogVolDc1"/>
<target dev="xvda"/>
</disk>
/ >
さらに、ソースデバイス名のみを抽出してみよう。
/ > cat /domain/devices/disk/source/@dev
-------
dev="/dev/VolGroupXX/LogVolDc1"
/ >
これを非対話的に実行するには、
# echo "cat /domain/devices/disk/source/@dev" | xmllint --shell dc1.xml
/ > -------
dev="/dev/VolGroupXX/LogVolDc1"
/ > #
とすればよい。
これと同様の操作をネットワークインターフェースに対して実行してみる。
# echo "cat /domain/devices/interface/source/@bridge" | xmllint --shell dc1.xml 
/ > -------
bridge="br4000"
-------
bridge="br2002"
/ > #
XPath /domain/devices/interfaceにマッチする要素は二つあるので、出力も二つだ。
これらのうち、二番目のものだけを出力するには、
# echo "cat /domain/devices/interface[2]/source/@bridge" | xmllint --shell dc1.xml
/ > -------
bridge="br2002"
/ > #
とする。

2009/04/03

A backup script for Xen DomUs, part 2

A backup script for Xen DomUs, part 1』で紹介したスクリプトxen-backup.shについて解説する。

このスクリプトの大まかな流れは以下の通り:
  1. バックアップ設定ファイルの読み込み: 182行目
  2. バックアップを実行するかどうかの検査: 183行目~215行目
  3. DomU設定の解析: 217行目~228行目
  4. ディスクイメージのマウント@ローカル: 230行目~254行目
  5. ディスクイメージのマウント@リモートDom0: 256行目~263行目
  6. Rsyncによるバックアップ: 265行目~266行目
  7. ディスクイメージのアンマウント@リモートDom0: 268行目~274行目
  8. ディスクイメージのアンマウント@ローカル: 277行目~280行目

バックアップを実行するかどうかの検査
DomUの状態を表示するコマンド
virsh domstate DomU名
を使って、以下の各項目を検査する。
  1. 対象DomUが、ローカルDom0でホストされいるか?
  2. 対象DomUが、ローカルDom0で正常に実行されているか?
  3. 自分自身がDOM0Sに含まれているか?
すべての検査に合格すれば、バックアップを実行する。

DomU設定の解析
コマンド
virsh dumpxml DomU名
で対象となるDomUの設定(XML形式)を得て、ディスクイメージ情報を抽出する。
このとき、関数get_value_from_configを呼び出す。
115: get_value_from_config()
116: {
117:     local xml=$1 num=$2 elem=$3 attr=$4
118:     echo "cat /domain/devices/disk[$num]/$elem/@$attr" | \
119:         xmllint --shell $xml | \
120:         awk -F\" '/^ +'$attr'/{print $2}'
121: }
この中ではxmllintコマンドを使用している。ディスクイメージに対する設定項目/domain/devices/diskは、複数指定される可能性があることに注意。

ディスクイメージのマウント@ローカル
各ディスクイメージをローカルにマウントする。
マウントする前に、ディスクイメージのスナップショットを撮っている(『XenとLVM・その3・スナップショットLVの利用』参照)
238:                 lvcreate --snapshot --name=$snapshot_name --size=$SNAPSHOT_SIZE ${disk_source[$i]}
239:                 add_close_command "lvremove -f /dev/$vgname/$snapshot_name"
240:                 analyze_disk /dev/$vgname/$snapshot_name
マウント時と反対の動作をバックアップ後に実施する必要があるため、add_close_command関数(34行目~38行目)を使って記録する。
実際の解析は、analyze_disk関数(124行目~175行目)を使っている。

analyze_disk関数
マウント時の動作は、リモート側でも実行する必要があるため、add_open_command関数(14行目~19行目)で実行および記録する。
与えられたデバイス$the_diskに対して、
131:     part_type=`parted -s $the_disk print | awk '/^Partition Table:/{print $3}'`
でパーティションの種類を得ている。これがDOSパーティションなら、パーティション毎に分割し、それぞれに対して処理する必要がある。
134:             add_open_command "kpartx -a -p $PSEP $the_disk"
135:             add_close_command "kpartx -d -p $PSEP $the_disk"
ここで、kpartxコマンドに対するオプション「-p 区切文字」を指定していることに注意。例えば、/dev/VolGroup00/LogVolDomUに対して、
kpartx -a /dev/VolGroup00/LogVolDomU1
を実行すると、パーティションごとに
/dev/mapper/LogVolDomU1
/dev/mapper/LogVolDomU1
等のデバイスが作成されるが、元のデバイス名の最後が数字の場合、例えば/dev/VolGroup00/LogVolDomU1の場合は、
/dev/mapper/LogVolDomU1p1
/dev/mapper/LogVolDomU1p1
の様に区切文字「p」が挿入される。オプション「-p 区切文字」を指定すれば、どちらの場合も区切文字が挿入されるので都合が良い。なお、「kpartx -a -p 区切文字」で作成したデバイスは、「-p」を指定して「kpartx -d -p 区切文字」としないと削除できない(この辺りの動作は、kpartxのmanpageにも触れられていない)
136:             while read device[$num] fs_type[$num] mount_point[$num]; do
137:                 ((num++))
138:             done <<EOF
139: $(parted -s $the_disk print | awk '/^ *[0-9]+ /{print $1" "$6" "$7}')
140: EOF
この部分は、一見
parted -s $the_disk print | awk '/^ *[0-9]+ /{print $1" "$6" "$7}' | while read device[$num] fs_type[$num] mount_point[$num]; do
((num++))
done
の様に書き直せそうだが、期待通りの動作とならない。なぜなら、readコマンドをパイプの後で使うと、readコマンドがサブシェルで実行され、サブシェルの変数には代入されるが、元のシェルの変数には反映されないため。
最終的に、mountコマンドでマウントされるデバイスにまで分割できたら、add_fs_table関数(52行目~57行目)で記録しておく。ディレクトリ階層の高い順にマウントする必要があるため、すべてのマウントポイントを解析し終えてからマウントする(252行目~254行目)。

ディスクイメージのマウント@リモートDom0
リモートDom0に対して、SSH経由でマウントを実行する。
258:         ssh -T $remote_dom0 <<EOF
259: ##### COMMANDS FOR TARGET TO OPEN
260: `exec_open_commands | sed 's/-'$$'//'`
261: mkdir -p $target_prefix
262: `mount_fs_all $target_prefix | sed 's/-'$$'//'`
263: EOF
入力がTTYでないことを明示するため、sshコマンドには、「-T」オプションを与えている。

Rsyncによるバックアップ
266:         rsync -avz --delete -e ssh $source_prefix/ $remote_dom0:$target_prefix
引数「$source_prefix/」の最後のスラッシュは必須。省略すると、期待通りに動作しない。


A backup script for Xen DomUs, part 1
A backup script for Xen DomUs, part 2

A backup script for Xen DomUs, part 1

XenのDomUを運用する際、複数のDom0(物理サーバ)を準備しておき、DomUのディスクイメージ(以下、単にイメージ)を共有しておけば、一台のDom0が故障しても、健全なDom0でサービスを継続することが可能だ。
Dom0間でDomUイメージを共有する方法には、iSCSIを使う方法や、DRBDを使う方法があるが、CentOSのiSCSIターゲット(ストレージ側)やDRBDには問題があり、今のところ安心して採用できない(iSCSIターゲットに専用機器を使えば問題無いが、金がかかる)

そこで紹介するのが、今回のバックアップスクリプトxen-backup.shだ。このスクリプトは、rsync(1)を使うため、単純にディスクイメージをネットワークコピーするより圧倒的に早い。また、Xen固有のコマンドを一切使わず、virshコマンドを使っている。このため、libvirtがサポートしている他の仮想環境、kvmなどでも使用できるかもしれない(未確認)。
前提条件は以下の通り:
  1. Dom0間で、rootによるSSHログインが可能であること。
  2. 論理ボリューム(logical volume, LV)上にイメージが保存されていること。
  3. 各DomUに対して、ディスクイメージLV名が一致すること。
  4. Dom0とDomUのボリュームグループ名(volume group, VG)が重複しないこと。
  5. 実行前に別途フルバックアップを実行すること。
  6. 無保証
前提条件1.は、rsyncを安全に使うため必要。完全に自動化したい場合は、このバックアップ用の公開鍵を作成し、秘密鍵のパスフレーズを外した状態で、各Dom0のrootに配布すればよい。
前提条件2.は、動作中のDomUに対してスナップショットを撮ってバックアップするための条件。スナップショットが必要ない場合は、ファイルや物理的なディスクパーティションに対して動作させられるよう改造するのはそう難しくないだろう。
前提条件3.は要するに、DomUの設定ファイルが(ディスクイメージに関して)完全に一致すれば良い、ということだ。これは単に私の手抜きの結果。LV名が異なる場合は、コピー元・コピー先それぞれのDom0上で設定ファイルを解析するよう改造が必要。
前提条件4.については、『パスワードを紛失したDomUをリカバリ』に書いた通りで、具体的には、DomoのVG名を、標準の「VolGroup00」から「VolGroupXX」に変更してインストールする(DomUのVG名を標準のままでよい)。『Red Hat Cluster: CentOS 5.1上でRHCSを使ってみる・その2・Dom0 fsXのインストール』を参照。
前提条件5.は、使用前に例えば、
[root@dom0a ~]# dd bs=16M if=/dev/VolGroupXX/LogVolDomU1 | ssh dom0b 'dd bs=16M of=/dev/VolGroupXX/LogVolDomU1'
を実行する必要がある。今回のスクリプトでは、パーティション情報やLVM情報はコピーされないためだ。

なお、今回のスクリプトでは、対象DomUが実際に動作しているDom0上から、他のDom0へコピーを行う。これは、誤って古いイメージから新しいイメージへ書き戻すのを防ぐため。

スクリプトを実行する前に、各DomUに対する設定ファイル/root/Works/Xen-Backup/xen-backup.d/*.confを準備する(通常は、DomU名.conf)。設定項目は次の二つのみ:
DOMU
DomU名
DOM0S
このDomUのイメージを保存するDom0。空白で区切って並べる。ネットワーク的に到達可能な名前でなければならない。
例えば、DomU domu1に対する設定ファイル/root/Works/Xen-Backup/xen-backup.d/domu1.confならば、
DOMU=domu1
DOM0S="dom0a dom0b"
となる。この場合、domu1は、dom0a dom0bでホストされている。

xen-backup.shをダウンロード

コードは以下のbase64形式を、xen-backup.sh.b64として保存しておき、以下のコマンド
cat xen-backup.sh.b64 | base64 -di | gunzip > xen-backup.sh
で復元して使用する。

2009/4/5(日)追記:
ログをSYSLOGで出力するように変更した。

2009/4/6(月)追記:
重複実行を排除した。

2009/4/7(火)追記:
エラーもログされるよう変更した。
Cronからでも正常に実行されるよう、PATHを設定するように変更した。

2012/11/30(金)追記:
ファイルをダウンロードできるようにした。

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


A backup script for Xen DomUs, part 1
A backup script for Xen DomUs, part 2