ラベル サーバ構築 の投稿を表示しています。 すべての投稿を表示
ラベル サーバ構築 の投稿を表示しています。 すべての投稿を表示

2014年4月22日火曜日

bash か sh か、それが問題だ

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月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がインストールできたら変換を行います。下記のようにコマンドを打ちます。
$ /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 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のプロキシ向けに丸投げする設定を以下のように書きました。

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@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ではシステムの起動時に自動的に起動するデーモンを登録する仕組みが用意されている。自動起動するデーモンの登録及び解除は、
  • 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 に関する設定を色々指定できるみたいだ。該当部分はこんな記述になっている。

-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 で出力されるログには、アプリケーションが指定したファシリティとプライオリティが付いている。
ファシリティには次のようなものがある。

ファシリティ 対象のログ
auth(security) 認証サービスのメッセージ(現在はauthprivが推奨されている)
authpriv 認証サービス(カテゴリはauthと同じ。authとは出力結果が異なる)
cron cronのメッセージ
daemon デーモンのメッセージ
kern カーネルのメッセージ
lpr プリンタサービスのメッセージ
mail メールサービスのメッセージ
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オプションをつけて現在の状態を確認。

[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が新たに追加したハードディスク。

[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を逆にすればいい。

※この記事について指摘・意見・提案・感想などありましたら下のコメント欄にどうそ。