Linuxのサービス制御シェルスクリプトを書いていて思ったことなんですけどね。そのプロジェクトの先人たちが書いたコードを拝見すると、一行目のシェバング行に sh と bash が混じっていたんですよ。つまり、「#!/bin/sh」と「#!/bin/bash」の両方のパターンがあったわけです。まあDebian系なので、shは正確にはashなんですがね。
それで、どういうふうに使い分けるんだろうか、と気になったわけです。shとbashではbashが拡張した独自文法がある、ということは知ってましたが、じゃあ具体的にはなんなのかと。色々調べてみたり、bashのmanページを見たりしましたが、違いをまとめたものがなかなか見つかりません。
だったら、機能が多いbashに統一すればいいのか、というとそうでもありません。bashのmanページの最後、バグの項は次の一文で始まります。
「bash は大きすぎるし、遅すぎます。」
おいおい(笑)公式でそう言っちゃうんかい。しかもmanページのバグの項目で。まあともかく、重いってことですね。まあ、起動スクリプトは軽いに越したことはありませんから、むやみやたらにbashに統一というのはあまり良くはないでしょう。
でまあ、どうしたかというと、どうしても sh では実現できない、あるいはbashを使わないと著しく大変な時だけbashを使い、それ以外の時はshで済ますことにしました。
ちなみに今までに書いたスクリプトの中にもシェバング行が「#!/bin/bash」のやつもあったので、そいつらは「#!/bin/sh」に書き換えてしまって不具合が出ない限りはそれでいく方針に。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
2014年4月22日火曜日
2014年4月18日金曜日
VMWare Fusionの仮想マシンをOVA形式で出力する
普段仕事はMacでやっていて、開発に使う仮想マシンもVMware Fusionで扱っているわけですけれども、仮想マシンを作成してちょっと他の人に共有したいなんてことがありましてね。そういう時には、OVA形式で出力できたら便利だなと思うわけですけれども、実はVMware Fusionには直接その機能がありません。なんてことだ!
というわけで、OVA形式へ出力するためには、VMwareが公式で提供しているツールである「VMware OVF Tool」が必要です。まずはこれをインストールします。
まず、VMware OVF Tool for Mac OSXをダウンロードします。下記URL参照。
https://my.vmware.com/jp/group/vmware/details?downloadGroup=OVFTOOL350&productId=352
つぎに、インストールを行います。dmgをマウントしたら”VMware OVF Tool.pkg”を実行。インストーラの指示に従えばいいです。
インストール先は、
"/Applications/VMware OVF Tool"
です。Finderからは「アプリケーション」で参照できますね。
OVF Toolがインストールできたら変換を行います。下記のようにコマンドを打ちます。
これで変換できます。それにしても、公式でツールを提供してくれるんだったら、VMware Fusionにも機能をつけておいてほしいものですな。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
というわけで、OVA形式へ出力するためには、VMwareが公式で提供しているツールである「VMware OVF Tool」が必要です。まずはこれをインストールします。
まず、VMware OVF Tool for Mac OSXをダウンロードします。下記URL参照。
https://my.vmware.com/jp/group/vmware/details?downloadGroup=OVFTOOL350&productId=352
つぎに、インストールを行います。dmgをマウントしたら”VMware OVF Tool.pkg”を実行。インストーラの指示に従えばいいです。
インストール先は、
"/Applications/VMware OVF Tool"
です。Finderからは「アプリケーション」で参照できますね。
OVF Toolがインストールできたら変換を行います。下記のようにコマンドを打ちます。
$ /Applications/VMware\ OVF\ Tool/ovftool --acceptAllEulas path/to/vm/VM01.vmwarevm/VM01.vmx path/to/output/VM01.ova
これで変換できます。それにしても、公式でツールを提供してくれるんだったら、VMware Fusionにも機能をつけておいてほしいものですな。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
2014年4月7日月曜日
シェルスクリプトでnginx master processのpidを取得する
シェルスクリプトからnginxの起動・終了を制御したいことがあって、master process のPIDを取得するにはどうしたらいいのか調べた経緯を少々書いてみます。
nginx は master process というプロセスの小プロセスとして worker process を複数持ち、実際の処理はworker processが担当し、全体の起動・終了などのworker process の管理はmaster processが担当しています。
(参考→http://d.hatena.ne.jp/kiwanami/20111205/1323105070)
ということで、シェルスクリプトから終了させる場合には、master processにシグナルを送るのが正しい作法でしょう。pkillでnginx全体にシグナル送ってもいいかもしれませんが、せっかくmaster processがあるのに少々乱暴っぽいですし。
普通に起動・終了を制御するのであればngixの設定でpidfileを作成していると思うのでpidfileに記録されてるpidを見ればmaster processのpidを特定できますけれども、pidfileが何らかの理由で消えたか見つからないか読み取れない場合の処理を書いておきたいと思ったので、pidfile以外でmaster processのpidを見つける方法をとります。
ということで、以下のコマンドで取得できます。
ps の a オプションは端末のある全てのプロセスの表示、xオプションは端末のないプロセスの表示なので、"ps ax"で全てのプロセスを表示します。opid,ppid,cmdはそれそれ、自身のpid、親プロセスのpid、コマンド名を出力するという意味です。その中からgrep で "nginx" を含む行だけを抽出します。ここまでの途中で出力してみるとこんな感じですね。
デーモンとして動くプロセスは、親プロセスのpidは1(init)になります。nginxでは、worker process は master processを親に持つため、pidが1なのはmaster processのみです。あと grep コマンド自身も実行中のシェルを親に持つため、pidが1のものを抜き出せば、それがmaster processになります。
とうことで、2列目に出力された親プロセスが1の行について、1列目のpidの値を出力するようawkで指定すればOKです。
参考になれば幸いです。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
nginx は master process というプロセスの小プロセスとして worker process を複数持ち、実際の処理はworker processが担当し、全体の起動・終了などのworker process の管理はmaster processが担当しています。
(参考→http://d.hatena.ne.jp/kiwanami/20111205/1323105070)
ということで、シェルスクリプトから終了させる場合には、master processにシグナルを送るのが正しい作法でしょう。pkillでnginx全体にシグナル送ってもいいかもしれませんが、せっかくmaster processがあるのに少々乱暴っぽいですし。
普通に起動・終了を制御するのであればngixの設定でpidfileを作成していると思うのでpidfileに記録されてるpidを見ればmaster processのpidを特定できますけれども、pidfileが何らかの理由で消えたか見つからないか読み取れない場合の処理を書いておきたいと思ったので、pidfile以外でmaster processのpidを見つける方法をとります。
ということで、以下のコマンドで取得できます。
ps ax opid,ppid,cmd | grep nginx | awk '$2 == "1" { print $1 }'
ps の a オプションは端末のある全てのプロセスの表示、xオプションは端末のないプロセスの表示なので、"ps ax"で全てのプロセスを表示します。opid,ppid,cmdはそれそれ、自身のpid、親プロセスのpid、コマンド名を出力するという意味です。その中からgrep で "nginx" を含む行だけを抽出します。ここまでの途中で出力してみるとこんな感じですね。
[root@host]# ps ax opid,ppid,cmd | grep nginx 5057 19498 grep nginx 6812 1 nginx: master process /usr/sbin/nginx 6813 6812 nginx: worker process 6814 6812 nginx: worker process 6815 6812 nginx: worker process 6816 6812 nginx: worker process
デーモンとして動くプロセスは、親プロセスのpidは1(init)になります。nginxでは、worker process は master processを親に持つため、pidが1なのはmaster processのみです。あと grep コマンド自身も実行中のシェルを親に持つため、pidが1のものを抜き出せば、それがmaster processになります。
とうことで、2列目に出力された親プロセスが1の行について、1列目のpidの値を出力するようawkで指定すればOKです。
[root@host]# ps ax opid,ppid,cmd | grep nginx | awk '$2 == "1" { print $1 }'
6812
参考になれば幸いです。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
2014年4月3日木曜日
nginxの設定でif文中のincludeがエラーになるので別の方法で設定する
nginx の設定で if文の中で include しようとするとエラーが起こります。具体的には、ドキュメントルート以下に存在しないファイルは別のURLのプロキシ向けに丸投げする設定を以下のように書きました。
上記設定を含んだ状態で起動しようとすると下記エラーが発生します。
調べてみると、if 文の中ではincludeはできないようです。さらに、nginx において if は可能な限り避けろという話が見つかりました。予測できない動きをすることがあり、場合によってはクラッシュの危険もあるとか。
http://forum.nginx.org/read.php?2,123451,123462#msg-123462
http://wiki.nginx.org/IfIsEvil
ということで、別の方法を模索します。今回の目的なら代わりに try_files が使えます。
http://heartbeats.jp/hbblog/2012/04/nginx05.html
上記URLを参考に書いてみましょう。
location が "/" と完全一致の時の設定に注意してください。try_files に $uri/ が指定してあると、directory index を試みて 403 エラーになってしまいます。そのため "/" との完全一致で $uri/ を抜いた try_files を指定しておきます。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
location / {
if (!-f $request_filename) {
proxy_pass http://some-url;
include /etc/nginx/proxy_params;
break;
}
}
上記設定を含んだ状態で起動しようとすると下記エラーが発生します。
[root@host]# service nginx start Restarting nginx: nginx: [emerg] "include" directive is not allowed here in /etc/nginx/sites-enabled/foo:21 nginx: configuration file /etc/nginx/nginx.conf test failed
調べてみると、if 文の中ではincludeはできないようです。さらに、nginx において if は可能な限り避けろという話が見つかりました。予測できない動きをすることがあり、場合によってはクラッシュの危険もあるとか。
http://forum.nginx.org/read.php?2,123451,123462#msg-123462
http://wiki.nginx.org/IfIsEvil
ということで、別の方法を模索します。今回の目的なら代わりに try_files が使えます。
http://heartbeats.jp/hbblog/2012/04/nginx05.html
上記URLを参考に書いてみましょう。
location / {
try_files $uri $uri/ @proxy;
}
location = / {
try_files $uri @proxy;
}
location @proxy {
proxy_pass http://some-url;
include /etc/nginx/proxy_params;
}
location が "/" と完全一致の時の設定に注意してください。try_files に $uri/ が指定してあると、directory index を試みて 403 エラーになってしまいます。そのため "/" との完全一致で $uri/ を抜いた try_files を指定しておきます。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうぞ。
2014年2月28日金曜日
VMWare上のDebianでHDD外してGRUBメニュー修正
VMWare Fusionで仮想マシンにDebian入れて使ってるんだけれども、少し前から/usr/local以下のファイルが消えたり復活したりして気持ち悪い挙動をしていた。再起動のタイミングで起きてるようで、どうもブート時にマウントするハードディスクが勝手に変わっているようだ。
とりあえず、起動時にブートローダであるGRUBのメニューを見てみると選択できるメニューのうちHDD選択に係る記述が root (hd0,msdos1) と root (/dev/sdb,msdos1) の2通りあり、それぞれ選択してみると、案の定/usr/local以下(というかファイルシステム)の内容が変化するのが確認できた。root (/dev/sdb,msdos1) の方がデフォルトになっていた。
原因を調べているうち、hd0で指定されるHDD(これは/dev/sdaでもある)と/dev/sdbのUUIDが同じであることを見つけた。そもそも、この/dev/sdbはバックアップ用に仮想マシンに追加したもので、以前に、dd使ってバックアップした時、UUIDが記録されたセクタもコピーしてしまったことが原因と思われる。で、/etc/fstabでルート( / )にマウントするディスクがUUIDで指定されているので、どちらのHDDか不定だったと推測される。
一時的なバックアップ用途にHDD追加してただけなので、今後の混乱を避けるためHDD自体を削除することにした。まず、 root (hd0,msdos1) の方のメニューで起動して
を実行。デフォルトメニューのほうに含まれる記述が root (/dev/sdb,msdos1) から root (hd0,msdos1) に変化したのを確認。
一旦電源をOFFにし、VMWare Fusion の設定から /dev/sdb に相当するHDDを削除。
再び起動。ログインして再度先ほどと同じコマンドでgrub.cfgを生成する。
を実行。grub.cfg の中身を覗くと、root (/dev/sdb,msdos1)の方のメニューは消えていた。もう一度再起動し、ブートローダのメニューが変更されてメニューが減ったのを確認。これでもう大丈夫なはず。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
とりあえず、起動時にブートローダであるGRUBのメニューを見てみると選択できるメニューのうちHDD選択に係る記述が root (hd0,msdos1) と root (/dev/sdb,msdos1) の2通りあり、それぞれ選択してみると、案の定/usr/local以下(というかファイルシステム)の内容が変化するのが確認できた。root (/dev/sdb,msdos1) の方がデフォルトになっていた。
原因を調べているうち、hd0で指定されるHDD(これは/dev/sdaでもある)と/dev/sdbのUUIDが同じであることを見つけた。そもそも、この/dev/sdbはバックアップ用に仮想マシンに追加したもので、以前に、dd使ってバックアップした時、UUIDが記録されたセクタもコピーしてしまったことが原因と思われる。で、/etc/fstabでルート( / )にマウントするディスクがUUIDで指定されているので、どちらのHDDか不定だったと推測される。
一時的なバックアップ用途にHDD追加してただけなので、今後の混乱を避けるためHDD自体を削除することにした。まず、 root (hd0,msdos1) の方のメニューで起動して
[root@localhost]# grub-mkconfig -o /boot/grub/grub.cfg
を実行。デフォルトメニューのほうに含まれる記述が root (/dev/sdb,msdos1) から root (hd0,msdos1) に変化したのを確認。
一旦電源をOFFにし、VMWare Fusion の設定から /dev/sdb に相当するHDDを削除。
再び起動。ログインして再度先ほどと同じコマンドでgrub.cfgを生成する。
[root@localhost]# grub-mkconfig -o /boot/grub/grub.cfg
を実行。grub.cfg の中身を覗くと、root (/dev/sdb,msdos1)の方のメニューは消えていた。もう一度再起動し、ブートローダのメニューが変更されてメニューが減ったのを確認。これでもう大丈夫なはず。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
2014年2月22日土曜日
Linuxでデーモン自動起動の順番はどう決まるのか
Linuxではシステムの起動時に自動的に起動するデーモンを登録する仕組みが用意されている。自動起動するデーモンの登録及び解除は、
で、上記コマンドの使い方は省略するが、どちらも行っていることは共通している。まず、デーモンの起動・終了などを制御するスクリプトは
/etc/init.d/{デーモン名}
という名前で用意されている。例えばSSHデーモンは /etc/init.d/ssh だ。これらのスクリプトには引数で start, stop, restart, status などを与えることができ、起動・終了・再起動・状態の取得などを行うことができる。
で、自動起動するデーモンについては、
/etc/rc{ランレベル番号}.d
にデーモン制御スクリプトへのシンボリックリンクを作成する。すると、システムの起動時に実行される /etc/init.c/rc スクリプトに参照され、実行される。例えばランレベル5でシステム起動時に自動起動されるスクリプトへのシンボリックリンクは、/etc/rc5.d 内に存在する。
その際の起動順序はシンボリックリンクの名前で決まる。具体的には
S{起動番号}{デーモン名}
である。この起動番号の小さい方から大きい方に向かって起動していく。例えば Apache2デーモンは S17apache2 、SSHデーモンは S18ssh という名前なので、Apache2 は SSH より先に起動することが分かる。
と、ここまでは前から知ってたんだけれども、じゃあ、この起動順序の番号はどこで決まってるのかについては特に調べもせず知らなかった。でもちょっと必要になったので調べてみた。どうやらRedhat系とDebian系で違うようだ。
Redhat系では、起動スクリプトである /etc/init.d/{デーモン名} の「コメント文」に特定の書式で書いてあり、chkconfig はそのコメントを見に行く。コメントの書式は
# chkconfig: - {起動番号} {終了番号}
となっていて、この起動番号が chkconfig を実行した際にシンボリックリンクの名前に使われる。
一方Debian系では、update-rc.d の場合、作成するシンボリックリンクの起動番号は自動的に決定されるらしい。ちょっと調べただけでは分からなかった。(知っている人いたらぜひコメントください。)
Debian系では別のコマンド sysv-rc-conf もあり(使うには sysv-rc-conf パッケージをインストールする必要がある)、こちらは
/var/lib/sysv-rc-conf/services
に記述された起動順序にそってシンボリックリンクを作成する。こちらの sysv-rc-conf は chkconfig にコマンドの書式が似ていることもあり、使いやすいと思う。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
- Redhat系では chkconfig
- Debian系では update-rc.d, sysv-rc-conf など
で、上記コマンドの使い方は省略するが、どちらも行っていることは共通している。まず、デーモンの起動・終了などを制御するスクリプトは
/etc/init.d/{デーモン名}
という名前で用意されている。例えばSSHデーモンは /etc/init.d/ssh だ。これらのスクリプトには引数で start, stop, restart, status などを与えることができ、起動・終了・再起動・状態の取得などを行うことができる。
で、自動起動するデーモンについては、
/etc/rc{ランレベル番号}.d
にデーモン制御スクリプトへのシンボリックリンクを作成する。すると、システムの起動時に実行される /etc/init.c/rc スクリプトに参照され、実行される。例えばランレベル5でシステム起動時に自動起動されるスクリプトへのシンボリックリンクは、/etc/rc5.d 内に存在する。
その際の起動順序はシンボリックリンクの名前で決まる。具体的には
S{起動番号}{デーモン名}
である。この起動番号の小さい方から大きい方に向かって起動していく。例えば Apache2デーモンは S17apache2 、SSHデーモンは S18ssh という名前なので、Apache2 は SSH より先に起動することが分かる。
と、ここまでは前から知ってたんだけれども、じゃあ、この起動順序の番号はどこで決まってるのかについては特に調べもせず知らなかった。でもちょっと必要になったので調べてみた。どうやらRedhat系とDebian系で違うようだ。
Redhat系では、起動スクリプトである /etc/init.d/{デーモン名} の「コメント文」に特定の書式で書いてあり、chkconfig はそのコメントを見に行く。コメントの書式は
# chkconfig: - {起動番号} {終了番号}
となっていて、この起動番号が chkconfig を実行した際にシンボリックリンクの名前に使われる。
一方Debian系では、update-rc.d の場合、作成するシンボリックリンクの起動番号は自動的に決定されるらしい。ちょっと調べただけでは分からなかった。(知っている人いたらぜひコメントください。)
Debian系では別のコマンド sysv-rc-conf もあり(使うには sysv-rc-conf パッケージをインストールする必要がある)、こちらは
/var/lib/sysv-rc-conf/services
に記述された起動順序にそってシンボリックリンクを作成する。こちらの sysv-rc-conf は chkconfig にコマンドの書式が似ていることもあり、使いやすいと思う。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
2014年1月31日金曜日
slapadd のログを syslogd でとる設定 ※slapd でも none を忘れずに
昨日に引き続き OpenLDAP ネタ。slapadd を実行するシェルスクリプトを書いていて、ログ出力がどうもうまくいかないので調べていた。
slapadd の man ページを参照すると -o オプションで syslogd に関する設定を色々指定できるみたいだ。該当部分はこんな記述になっている。
今回 syslogd 側 では daemon ファシリティでプライオリティが info 以上のログを出力するよう設定していたので、まずは
みたいな感じにやってみたけどログが出ない。いろいろ試行錯誤する中で、試しにそれまで付けていた -F オプションを外してみるとエラーがログに出た。どうやら -F オプションを指定するとデフォルトの slapd から出すログレベルの設定が消えて、何も syslog に出なくなるようだ。
そこで -o "syslog=<subsystems>" で改めて指定する。<subsystems> に指定できるログレベルについては昨日の記事を参照。
これでログ出力できた。
なお、ログレベルについて一点気をつけたほうがいいことがある。それは none だ。各種サイトで調べてみても none ってなんか一見不要そうな雰囲気だから最初は付けてなかった。けれど、これは指定しておくことを強くおすすめする。
たとえば、slapd をシェルからコマンドラインで打つとシェルには出るエラーメッセージが syslogd に記録されないんでおかしいと思ってたら、none を含めたら記録されるようになった。読んで意味がわかるメッセージがログに記録されるのは重要。こんな有用なログをなぜ none って名前のログレベルにしたんだよ・・・。
ちなみに余談だけれど、上に引用した slapadd の man ページの -o オプションの部分には、syslogd へ出力するログのプライオリティを変更するための slapd の -S オプションについて言及があるのに、slapd の man ページの方には -S オプションについての説明がない(笑)。それでも -S オプションは slapd の方でもきちんと機能する。単に man ページヘの書き忘れかもしれないから、syslogd への出力プライオリティを変更するオプションとして覚えておくと便利だろう。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
slapadd の man ページを参照すると -o オプションで syslogd に関する設定を色々指定できるみたいだ。該当部分はこんな記述になっている。
-o option[=value]
Specify an option with a(n optional) value. Possible generic
options/values are:
syslog=<subsystems> (see `-s' in slapd(8))
syslog-level=<level> (see `-S' in slapd(8))
syslog-user=<user> (see `-l' in slapd(8))
schema-check={yes|no}
value-check={yes|no}
The schema-check option toggles schema checking (default on);
the value-check option toggles value checking (default off).
The latter is incompatible with -q.
今回 syslogd 側 では daemon ファシリティでプライオリティが info 以上のログを出力するよう設定していたので、まずは
slapadd -o "syslog-level=INFO" -o "syslog-user=DAEMON" ・・・(以下略)
みたいな感じにやってみたけどログが出ない。いろいろ試行錯誤する中で、試しにそれまで付けていた -F オプションを外してみるとエラーがログに出た。どうやら -F オプションを指定するとデフォルトの slapd から出すログレベルの設定が消えて、何も syslog に出なくなるようだ。
そこで -o "syslog=<subsystems>" で改めて指定する。<subsystems> に指定できるログレベルについては昨日の記事を参照。
slapadd -o "syslog=stats,stats2,shell,parse,sync,none" -o "syslog-level=INFO" -o "syslog-user=DAEMON" ・・・(以下略)
これでログ出力できた。
なお、ログレベルについて一点気をつけたほうがいいことがある。それは none だ。各種サイトで調べてみても none ってなんか一見不要そうな雰囲気だから最初は付けてなかった。けれど、これは指定しておくことを強くおすすめする。
たとえば、slapd をシェルからコマンドラインで打つとシェルには出るエラーメッセージが syslogd に記録されないんでおかしいと思ってたら、none を含めたら記録されるようになった。読んで意味がわかるメッセージがログに記録されるのは重要。こんな有用なログをなぜ none って名前のログレベルにしたんだよ・・・。
ちなみに余談だけれど、上に引用した slapadd の man ページの -o オプションの部分には、syslogd へ出力するログのプライオリティを変更するための slapd の -S オプションについて言及があるのに、slapd の man ページの方には -S オプションについての説明がない(笑)。それでも -S オプションは slapd の方でもきちんと機能する。単に man ページヘの書き忘れかもしれないから、syslogd への出力プライオリティを変更するオプションとして覚えておくと便利だろう。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
2014年1月30日木曜日
slapd の syslogd 向けログ出力とデバッグレベル
OpenLDAPでLDAPサーバを構築している途中で、slapdがうまく起動しないことがあった。その際、slapdがログを吐かないことに気づいた。
そもそも、OpenLDAPの場合、デフォルト設定のままではログが出力されない設定になっているらしい。変更すべき設定は syslogd のファシリティとデバッグレベル。
・syslogd のファシリティ
ファシリティとは、ログの分類のこと。syslogd で出力されるログには、アプリケーションが指定したファシリティとプライオリティが付いている。
ファシリティには次のようなものがある。
プライオリティは、ログの重要度を表す。次のようなものがある。
どのファシリティのどのプライオリティのログを出力するかについては、/etc/syslog.conf ファイルに設定する。なお最近の Linux では syslogd ではなくその改良版である rsyslog が使われているかもしれないので、その場合 /etc/rsyslog.conf が設定ファイルになる。
設定は
のように書く。例えばメールに関する全てのログを /var/log/maillog に出力する設定は
という感じになる。
で、話をOpenLDAPに戻すと、実はOpenLDAPのデフォルトのファシリティは local4 になっている。この local4 に対するログ出力設定がデフォルトでは存在しないため、デフォルト設定のままではログが出力されないのだ。
これに対処するには、syslogd側の設定を変更するlogd側の設定を変更する場合、ファシリティlocal4 に対する設定を追加すればいい。次のような感じになる。
これを /etc/syslog.conf (または /etc/rsyslog.conf)に追加し、syslogデーモンを再起動すればよい。
なお、slapd側がsyslogdへログを出力する際のファシリティを変更することもできる。これは slapd 起動時の -l オプションで指定できる。LOCAL0〜LOCAL7, USER, DAEMON が指定可能。
もう一つ注意すべき点は、slapd が syslog へ出力する際のプライオリティは DEBUG になる点だ。このプライオリティを変更する方法は色々調べたが見つからなかった。(僕の環境では -S INFO を指定することでプライオリティを INFO に変更できたが、誰か正式な方法知ってたら教えてください。)
slapd が出力するログのレベルは、Configuration Backend を使っている場合 cn=config エントリの olcLogLevel に格納する。ログレベルは、次のようなものがある。
出力したいログレベルの数値の合計、またはログレベルの文字列をカンマ区切りで列挙する。デフォルトは 256 (stats) 。設定例としては
こんな感じ。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
参考ページ:
OpenLDAP ソフトウェア 2.3 管理者ガイド: slapd の実行
OpenLDAPによるディレクトリサーバ運用(3):ものいわぬOpenLDAPサーバのログ管理 (1/3) - @IT
Linux管理者への道(3):システム管理の基礎 syslogdの設定をマスターしよう (1/3) - @IT
そもそも、OpenLDAPの場合、デフォルト設定のままではログが出力されない設定になっているらしい。変更すべき設定は syslogd のファシリティとデバッグレベル。
・syslogd のファシリティ
ファシリティとは、ログの分類のこと。syslogd で出力されるログには、アプリケーションが指定したファシリティとプライオリティが付いている。
ファシリティには次のようなものがある。
| ファシリティ | 対象のログ |
|---|---|
| auth(security) | 認証サービスのメッセージ(現在はauthprivが推奨されている) |
| authpriv | 認証サービス(カテゴリはauthと同じ。authとは出力結果が異なる) |
| cron | cronのメッセージ |
| daemon | デーモンのメッセージ |
| kern | カーネルのメッセージ |
| lpr | プリンタサービスのメッセージ |
| メールサービスのメッセージ | |
| news | ニュースサービスのメッセージ |
| syslog | syslogのメッセージ |
| user | ユーザープロセスのメッセージ |
| uucp | uucp転送を行うプログラムのメッセージ |
| local0~7 | アプリケーションに依存する |
プライオリティは、ログの重要度を表す。次のようなものがある。
| プライオリティ | 説明 |
|---|---|
| emerg | 認証サービスのメッセージ(現在はauthprivが推奨されている) |
| alert | 認証サービス(カテゴリはauthと同じ。authとは出力結果が異なる) |
| crit | cronのメッセージ |
| err | デーモンのメッセージ |
| warning | カーネルのメッセージ |
| notice | プリンタサービスのメッセージ |
| info | メールサービスのメッセージ |
| debug | ニュースサービスのメッセージ |
どのファシリティのどのプライオリティのログを出力するかについては、/etc/syslog.conf ファイルに設定する。なお最近の Linux では syslogd ではなくその改良版である rsyslog が使われているかもしれないので、その場合 /etc/rsyslog.conf が設定ファイルになる。
設定は
ファシリティ.プライオリティ ログ出力先
のように書く。例えばメールに関する全てのログを /var/log/maillog に出力する設定は
mail.* /var/log/maillog
という感じになる。
で、話をOpenLDAPに戻すと、実はOpenLDAPのデフォルトのファシリティは local4 になっている。この local4 に対するログ出力設定がデフォルトでは存在しないため、デフォルト設定のままではログが出力されないのだ。
これに対処するには、syslogd側の設定を変更するlogd側の設定を変更する場合、ファシリティlocal4 に対する設定を追加すればいい。次のような感じになる。
local4.* /var/log/ldap.log
これを /etc/syslog.conf (または /etc/rsyslog.conf)に追加し、syslogデーモンを再起動すればよい。
なお、slapd側がsyslogdへログを出力する際のファシリティを変更することもできる。これは slapd 起動時の -l オプションで指定できる。LOCAL0〜LOCAL7, USER, DAEMON が指定可能。
もう一つ注意すべき点は、slapd が syslog へ出力する際のプライオリティは DEBUG になる点だ。このプライオリティを変更する方法は色々調べたが見つからなかった。(僕の環境では -S INFO を指定することでプライオリティを INFO に変更できたが、誰か正式な方法知ってたら教えてください。)
slapd が出力するログのレベルは、Configuration Backend を使っている場合 cn=config エントリの olcLogLevel に格納する。ログレベルは、次のようなものがある。
| ログレベル (10進数) |
ログレベル (16進数) |
ログレベル (文字列) |
ログ出力内容 |
|---|---|---|---|
| -1 | - | any | すべてのログを出力 |
| 0 | - | - | まったくログを出力しない |
| 1 | 0x1 | trace | 内部の関数呼び出し |
| 2 | 0x2 | packets | パケット操作 |
| 4 | 0x4 | args | 処理の詳細なトレース |
| 8 | 0x8 | cons | コネクション管理 |
| 16 | 0x10 | BER | パケット送受信 |
| 32 | 0x20 | filter | 検索フィルタ処理 |
| 64 | 0x40 | config | 設定ファイルの処理 |
| 128 | 0x80 | ACL | アクセス制御リストの処理 |
| 256 | 0x100 | stats | ステータスログ(デフォルト) |
| 512 | 0x200 | stats2 | ステータスログ2 |
| 1024 | 0x400 | shell | シェルバックエンドとの通信 |
| 2048 | 0x800 | parse | エントリの解析 |
| 16384 | 0x4000 | sync | syncrepl コンシューマ処理 |
| 32768 | 0x8000 | none | 設定に依存しない最低限の出力のみ |
出力したいログレベルの数値の合計、またはログレベルの文字列をカンマ区切りで列挙する。デフォルトは 256 (stats) 。設定例としては
dn: cn=config objectClass: olcGlobal cn: config olcLogLevel: trace,ACL
こんな感じ。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
参考ページ:
OpenLDAP ソフトウェア 2.3 管理者ガイド: slapd の実行
OpenLDAPによるディレクトリサーバ運用(3):ものいわぬOpenLDAPサーバのログ管理 (1/3) - @IT
Linux管理者への道(3):システム管理の基礎 syslogdの設定をマスターしよう (1/3) - @IT
2014年1月22日水曜日
仮想マシン上のLinuxでディスク容量を拡張してLVMとして追加する
VMWare Fusion に Debian7 を入れて使っているんだけど、最初の見立てが甘かったため、ディスク容量が一杯になってしまった。
そこで、ハードディスクの容量を増やして空き領域に新たなパーティションを作成し、LVMとして追加することにした。LVMなら再度容量を追加したりするとき便利だし。
まあ仮想マシンだから新たにディスクを増やしてもいいんだけれど、そこはせっかくなので仮想マシンならではの方法をやってみよう、ということでディスクの容量追加にした。
ただ容量増加前の状態だと20GBの容量ほぼ全部を1つのパーティションとして使っていて(かつLVMにしていない)、ここにルート(/)以下をまるごと突っ込んでしまっているので、このパーティション自体の容量を増やそうとすると色々と面倒だ。
そこで最も容量を圧迫している /home 以下に、新たに作成したLVMパーティションを割り当てることにした(参考にしたのはここ)。
まず、VMWare の設定画面からハードディスクの容量を変更する(20GB -> 50GB)。スナップショットがあると変更できないので、必要なデータは事前にバックアップしたうえでスナップショットは消しておく。
そしてルート権限で fdisk コマンドを実行する。-lオプションをつけて現在の状態を確認。
/dev/sdaは53.7GBと認識されてる。もちろん容量を増やしたから、現在のパーティションを全部合わせても空き領域がある。この空き領域に新しくパーティションを作成して/home用に使うことにする。その際、パーティションの開始セクタを空き領域の先頭に設定する。
そこで fdisk で続けて次の操作を行う。
・nコマンドを入力(パーティションを新規作成)
・パーティションタイプはデフォルト(プライマリ)でよいのでそのままEnter
・パーティション番号もデフォルト(この場合は3)でよいのでそのままEnter
・開始セクタは空き領域の先頭(この場合は41940992)を入力
・終了セクタは自動的に最終セクタがデフォルトになるのでそのままEnter
パーティションができたかpコマンドで確認。
/dev/sda3としてできている。
パーティションのタイプをtコマンドでLVMに変更する。
fdiskでの操作は
・コマンドは t を入力
・パーティション番号は先ほど作成した番号(3)を入力
・ヘックスコードはLVMを表す 8e を入力
pコマンドで結果を確認する。
確認できたら、w コマンドでパーティションテーブルに書き込む。
古いパーティションを使用中なので警告が出る。パーティションテーブルを有効化するために再起動する。
再起動後、PVを作成しようと思ったらコマンドがなかったので lvm2 をインストール。
コマンドを認識させるためログアウト&ログインしておく。そしてあらためてPVを作成。
VG作成、今回はPVを1つだけ使うことにする。
LV作成、VG空き容量の全部を使うことにする。
ext4としてフォーマット
/homeの中身を引っ越すため、一時的にマウントポイントを作成して新しく作成したパーティションをマウントし、コピーする。
/etc/fstabを編集する。
最終行に以下を追加して保存
最後に、コピー済みの/homeの中身を消して再起動
再起動後、dfで確認してみる。
/homeの容量が増えました。めでたしめでたし。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
そこで、ハードディスクの容量を増やして空き領域に新たなパーティションを作成し、LVMとして追加することにした。LVMなら再度容量を追加したりするとき便利だし。
まあ仮想マシンだから新たにディスクを増やしてもいいんだけれど、そこはせっかくなので仮想マシンならではの方法をやってみよう、ということでディスクの容量追加にした。
ただ容量増加前の状態だと20GBの容量ほぼ全部を1つのパーティションとして使っていて(かつLVMにしていない)、ここにルート(/)以下をまるごと突っ込んでしまっているので、このパーティション自体の容量を増やそうとすると色々と面倒だ。
そこで最も容量を圧迫している /home 以下に、新たに作成したLVMパーティションを割り当てることにした(参考にしたのはここ)。
まず、VMWare の設定画面からハードディスクの容量を変更する(20GB -> 50GB)。スナップショットがあると変更できないので、必要なデータは事前にバックアップしたうえでスナップショットは消しておく。
そしてルート権限で fdisk コマンドを実行する。-lオプションをつけて現在の状態を確認。
[root@localhost]~# fdisk -l Disk /dev/sda: 53.7 GB, 53687091200 bytes 255 heads, 63 sectors/track, 6527 cylinders, total 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000325f8 Device Boot Start End Blocks Id System /dev/sda1 * 2048 40136703 20067328 83 Linux /dev/sda2 40138750 41940991 901121 5 Extended /dev/sda5 40138752 41940991 901120 82 Linux swap / Solaris
/dev/sdaは53.7GBと認識されてる。もちろん容量を増やしたから、現在のパーティションを全部合わせても空き領域がある。この空き領域に新しくパーティションを作成して/home用に使うことにする。その際、パーティションの開始セクタを空き領域の先頭に設定する。
そこで fdisk で続けて次の操作を行う。
・nコマンドを入力(パーティションを新規作成)
・パーティションタイプはデフォルト(プライマリ)でよいのでそのままEnter
・パーティション番号もデフォルト(この場合は3)でよいのでそのままEnter
・開始セクタは空き領域の先頭(この場合は41940992)を入力
・終了セクタは自動的に最終セクタがデフォルトになるのでそのままEnter
Command (m for help): n
Partition type:
p primary (1 primary, 1 extended, 2 free)
l logical (numbered from 5)
Select (default p):
Using default response p
Partition number (1-4, default 3):
Using default value 3
First sector (40136704-104857599, default 40136704): 41940992
Last sector, +sectors or +size{K,M,G} (41940992-104857599, default 104857599):
Using default value 104857599
パーティションができたかpコマンドで確認。
Command (m for help): p Disk /dev/sda: 53.7 GB, 53687091200 bytes 255 heads, 63 sectors/track, 6527 cylinders, total 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000325f8 Device Boot Start End Blocks Id System /dev/sda1 * 2048 40136703 20067328 83 Linux /dev/sda2 40138750 41940991 901121 5 Extended /dev/sda3 41940992 104857599 31458304 83 Linux /dev/sda5 40138752 41940991 901120 82 Linux swap / Solaris
/dev/sda3としてできている。
パーティションのタイプをtコマンドでLVMに変更する。
fdiskでの操作は
・コマンドは t を入力
・パーティション番号は先ほど作成した番号(3)を入力
・ヘックスコードはLVMを表す 8e を入力
[root@localhost]~# fdisk /dev/sda Command (m for help): t Partition number (1-5): 3 Hex code (type L to list codes): 8e Changed system type of partition 3 to 8e (Linux LVM)
pコマンドで結果を確認する。
Command (m for help): p Disk /dev/sda: 53.7 GB, 53687091200 bytes 255 heads, 63 sectors/track, 6527 cylinders, total 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000325f8 Device Boot Start End Blocks Id System /dev/sda1 * 2048 40136703 20067328 83 Linux /dev/sda2 40138750 41940991 901121 5 Extended /dev/sda3 41940992 104857599 31458304 8e Linux LVM /dev/sda5 40138752 41940991 901120 82 Linux swap / Solaris
確認できたら、w コマンドでパーティションテーブルに書き込む。
Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: Re-reading the partition table failed with error 16: デバイスもしくはリソースがビジー状態です. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) Syncing disks.
古いパーティションを使用中なので警告が出る。パーティションテーブルを有効化するために再起動する。
[root@localhost]~# reboot
再起動後、PVを作成しようと思ったらコマンドがなかったので lvm2 をインストール。
[root@localhost]~# apt-get install lvm2
コマンドを認識させるためログアウト&ログインしておく。そしてあらためてPVを作成。
[root@localhost]~# pvcreate /dev/sda3 Writing physical volume data to disk "/dev/sda3" Physical volume "/dev/sda3" successfully created
VG作成、今回はPVを1つだけ使うことにする。
[root@localhost]~# vgcreate home1 /dev/sda3 Volume group "home1" successfully created
LV作成、VG空き容量の全部を使うことにする。
[root@localhost]~# lvcreate -n home1-1 -l 100\%FREE home1 Logical volume "home1-1" created
ext4としてフォーマット
[root@localhost]~# mkfs.ext4 /dev/home1/home1-1 mke2fs 1.42.5 (29-Jul-2012) Filesystem label= OS type: Linux Block size=4096 (log=2) Fragment size=4096 (log=2) Stride=0 blocks, Stripe width=0 blocks 1966080 inodes, 7864320 blocks 393216 blocks (5.00%) reserved for the super user First data block=0 Maximum filesystem blocks=4294967296 240 block groups 32768 blocks per group, 32768 fragments per group 8192 inodes per group Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done
/homeの中身を引っ越すため、一時的にマウントポイントを作成して新しく作成したパーティションをマウントし、コピーする。
[root@localhost]~# mkdir /mnt/home1-1 [root@localhost]~# mount /dev/home1/home1-1 /mnt/home1-1 [root@localhost]~# cp -rp /home/* /mnt/home1-1
/etc/fstabを編集する。
[root@localhost]~# vim /etc/fstab
最終行に以下を追加して保存
/dev/home1/home1-1 /home ext4 defaults 1 2
最後に、コピー済みの/homeの中身を消して再起動
[root@localhost]~# rm -rf /home/* [root@localhost]~# reboot
再起動後、dfで確認してみる。
[root@localhost]~# df -h ファイルシス サイズ 使用 残り 使用% マウント位置 rootfs 19G 6.6G 12G 37% / udev 10M 0 10M 0% /dev tmpfs 397M 688K 396M 1% /run /dev/disk/by-uuid/a1211e97-cb86-4aa7-8829-0700c8e26c1a 19G 6.6G 12G 37% / tmpfs 5.0M 0 5.0M 0% /run/lock tmpfs 969M 220K 969M 1% /run/shm /dev/mapper/home1-home1--1 30G 8.1G 20G 29% /home
/homeの容量が増えました。めでたしめでたし。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
2014年1月21日火曜日
仮想マシン上のLinuxでファイルシステムをまるごとバックアップ
VMWare FusionにDebian7をインストールして使っているんだけれど、
ちょっとバックアップをとりたくなったのでやってみた。
まず仮想マシンの設定で、十分な容量のハードディスクを新規に作成して追加しておく。(今回は20GB)
そしたらルート権限で fdisk コマンドを実行。-lオプションをつけて現在の状態を確認。/dev/sdbが新たに追加したハードディスク。
次に新しく追加したディスクをfdiskのオプションで渡して実行。
コマンド入力を求められるが、まずコマンド一覧を確認。
nコマンドで新規パーティションを作成する。いくつか質問されるが、
・パーティションタイプはプライマリ(p)
・パーティション番号は最初のパーティションなので1
・開始セクタはデフォルト(2048)
・終了セクタはバックアップ対象と同じセクタで作成する(40136703)
できたか確認。
確認したらwコマンドで書き込む。
シングルユーザモードに移行する。リードオンリーモードで / をリマウントする。
dd でバックアップ。
終わったらリードオンリーから通常のマウントに戻す。
これで完了。
バックアップから復元する時はddコマンドのifとofを逆にすればいい。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
ちょっとバックアップをとりたくなったのでやってみた。
まず仮想マシンの設定で、十分な容量のハードディスクを新規に作成して追加しておく。(今回は20GB)
そしたらルート権限で fdisk コマンドを実行。-lオプションをつけて現在の状態を確認。/dev/sdbが新たに追加したハードディスク。
[root@localhost]~# fdisk -l Disk /dev/sda: 53.7 GB, 53687091200 bytes 255 heads, 63 sectors/track, 6527 cylinders, total 104857600 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000325f8 Device Boot Start End Blocks Id System /dev/sda1 * 2048 40136703 20067328 83 Linux /dev/sda2 40138750 41940991 901121 5 Extended /dev/sda5 40138752 41940991 901120 82 Linux swap / Solaris Disk /dev/sdb: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x00000000 Disk /dev/sdb doesn't contain a valid partition table
次に新しく追加したディスクをfdiskのオプションで渡して実行。
コマンド入力を求められるが、まずコマンド一覧を確認。
[root@localhost]~# fdisk /dev/sdb Device contains neither a valid DOS partition table, nor Sun, SGI or OSF disklabel Building a new DOS disklabel with disk identifier 0x2fce4abf. Changes will remain in memory only, until you decide to write them. After that, of course, the previous content won't be recoverable. Warning: invalid flag 0x0000 of partition table 4 will be corrected by w(rite) Command (m for help): m Command action a toggle a bootable flag b edit bsd disklabel c toggle the dos compatibility flag d delete a partition l list known partition types m print this menu n add a new partition o create a new empty DOS partition table p print the partition table q quit without saving changes s create a new empty Sun disklabel t change a partition's system id u change display/entry units v verify the partition table w write table to disk and exit x extra functionality (experts only)
nコマンドで新規パーティションを作成する。いくつか質問されるが、
・パーティションタイプはプライマリ(p)
・パーティション番号は最初のパーティションなので1
・開始セクタはデフォルト(2048)
・終了セクタはバックアップ対象と同じセクタで作成する(40136703)
Command (m for help): n
Partition type:
p primary (0 primary, 0 extended, 4 free)
e extended
Select (default p): p
Partition number (1-4, default 1): 1
First sector (2048-41943039, default 2048): 2048
Last sector, +sectors or +size{K,M,G} (2048-41943039, default 41943039): 40136703
できたか確認。
Command (m for help): p Disk /dev/sdb: 21.5 GB, 21474836480 bytes 255 heads, 63 sectors/track, 2610 cylinders, total 41943040 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0xc3d14735 Device Boot Start End Blocks Id System /dev/sdb1 2048 40136703 20067328 83 Linux
確認したらwコマンドで書き込む。
Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. Syncing disks. [root@localhost]~#
シングルユーザモードに移行する。リードオンリーモードで / をリマウントする。
# telinit 1 [root@localhost]~# mount -r -n -o remount /
dd でバックアップ。
[root@localhost]~# dd if=/dev/sda1 of=/dev/sdb1
終わったらリードオンリーから通常のマウントに戻す。
[root@localhost]~# mount -w -n -o remount /
これで完了。
バックアップから復元する時はddコマンドのifとofを逆にすればいい。
※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。
登録:
投稿 (Atom)