tarを利用して特定のディレクトリを移動する
/export/home/bata64/Solaris
というディレクトリを、
/var/tmp/Solaris
としてコピーしたいとします。
このとき、
$ cp -rp /export/home/bata64/Solaris /var/tmp/Solaris
とか実行すると、ディレクトリ以下にシンボリックリンクが存在する場合実ファイルとしてコピーされてしまいます(参考:)。
なので、大量にデータが格納されているディレクトリ、例えば何からのソフトウェアがインストールされているディレクトリ等の場合、cpだとどうなっているのかわからないので危険です(古くからのSolaris使う人からは伝承のように「大事なディレクトリのデータコピーのときはcp使うな」と教わったものです)。
mvだと良さそうですが、コピー元がなくなってしまうので、なんらかのトラブルで処理中断した場合、移動したデータと移動しなかったデータに分かれてしまい復旧が大変になります。どうすればいいのか?
いまどきのLinuxとかだと色々対処方法がありますが、昔はtarを使うしかなかったようです。
すなわち、こうしていました。
$ cd /export/home/bata64/ $ tar cpf - Solaris |(cd /var/tmp/;tar xpfB -)
アーカイブデータを標準出力に渡し、パイプで受けて所定ディレクトリに移動してそれを展開する、というものです。
tarはその名が示すとおりテープにアーカイブするために作られたコマンドですが、アーカイブ時にパーミッションやディレクトリ以下のファイル構造を維持できるという特徴を活かし、いつしかアーカイブファイル作成用コマンドとして使われ、様々な技法が編み出されたようです。
これは便利なコマンドがインストールされていない、ネットもつながらないのでyum install出来ない、というような環境下でなんとかする時に非常に便利です。tarとbashの標準出力、標準入力のパイプ渡しはUNIXエンジニアの伝統技術みたいなものだと思いますので、これは覚えておきたいところです。
ではー。
ディレクトリを移動せずにtarアーカイブを作る
こちらのエントリに書いてある内容を調べている際に、定年が近いミスターSolarisおじさん(近年までオフィスでの執務PCがUltra60だった)が何気なくやってらして、「やべー知らんかった」とショックを受けたのでご紹介します。
何をしたいかというと、
/export/home/bata_dir
を、
/var/tmp
以下に、
bata_dir.tar
というファイル名でtarアーカイブしたい場合、
$ cd /export/home/
してから
$ tar cf /var/tmp/bata_dir.tar bata_dir
を実行していたわけです。
$ tar cf /var/tmp/bata_dir.tar /export/home/bata_dir
とかやると、展開時に絶対パス(/export/home)に展開されてしまいますから・・・。
が、このように-Cオプションをつけて実行すれば、cdでディレクトリ移動しなくて良いのでした。
$ tar cf /var/tmp/bata_dir.tar -C ./export/home bata_dir
一行ですむので大変便利です。
ではー。
特定ディレクトリを除外してtarアーカイブを作る
何をしたいかというと、
[bata64@Server ~]$ find pl pl pl/総合順位表.csv pl/ShinMasuzawa pl/ShinMasuzawa/config pl/ShinMasuzawa/config/config.pl pl/ShinMasuzawa/config/config.BAK pl/ShinMasuzawa/Build.PL ~中略~ pl/Masuzawa pl/Masuzawa/EXCEL_TEST pl/Masuzawa/EXCEL_TEST/新増沢方式審査用紙tmp.csv pl/Masuzawa/EXCEL_TEST/新増沢方式審査用紙.csv pl/Masuzawa/EXCEL_TEST/新増沢方式審査用紙.xlsx pl/Masuzawa/EXCEL_TEST/新増沢方式審査用紙tmp.xlsx pl/Masuzawa/EXCEL_TEST/Bata pl/Masuzawa/EXCEL_TEST/Bata/GetData.BAK pl/Masuzawa/EXCEL_TEST/Bata/GetData.pm pl/Masuzawa/EXCEL_TEST/Bata/CSV.BAK ~略~
[bata64@Server ~]$ tar cf /var/tmp/pl.tar pl
とすれば良いですが、当然plディレクトリ以下の全てのディレクトリ、ファイルを含めたアーカイブファイルである「pl.tar」が出来上がります。
このとき、「pl/Masuzawa」以下のディレクトリとファイル以外をtarアーカイブしたい場合は以下のようにします。
除外ディレクトリを書いたテキストファイル(除外ディレクトリ記載ファイル)を用意する
[bata64@Server ~]$ vi ~bata64/xfile
とかで編集し、
pl/Masuzawa
と記入します。複数ある場合は改行区切りで、
pl/Masuzawa pl/sirakaba/aozora/minamikaze pl/sen/masao
みたいに書いていけば良いです。
がポイントです。
除外ディレクトリ記載ファイルを指定してtarアーカイブ作成
/export/home/bata64/pl
である場合、
/export/home/bata64/
に移動する、という事です。
その上で、-Xオプションをつけて除外ディレクトリ記載ファイルを指定してtarアーカイブを作成します。
[bata64@Server ~]$ tar cfX /var/tmp/pl.tar ~bata64/xfile pl
これでOK。本当に除外されているかどうかを知りたければ-vオプションつけて
[bata64@Server ~]$ tar cfvX /var/tmp/pl.tar ~bata64/xfile pl
として標準出力を目視でがんばるか、出来上がったtarアーカイブを-tオプションで眺めればよいと思います。
[bata64@Server ~]$ tar tfv /var/tmp/pl.tar
注意点
私はSolarisだいすきっ子ですので以下の環境で試しました。
SPARC Solaris10 1/13 SPARC Solaris8 10/01
すると、
- Solaris10の場合/usr/sfw/bin/gtarでは成功
- Solaris8に別途インストールしたGNU tar(バージョン1.13)ではエラーが出ず成功したように見えるが除外されていない
- Solaris8のOSバンドル tarでは成功
という結果になりました。Solarisで試して上手く行かないなー、という方はtarのバージョンとかを疑ってみてはいかがでしょう。
なお、カーネル2.6台のLinuxとかSolaris11にバンドルされているGNU tarの場合は大体成功します(というかいまどきのOSであれば大体大丈夫でしょう)。
x86版Solaris10物理サーバをVirtualBoxへ移行(P2V)
2009年に買ったマザーボードで組んだPCにてx86 Solaris10を稼働、主にpukiwikiサーバとして活用しています。
ただ、半年に1回程度ハングするため*1に再起動が必要となる運用をしていたので少々煩わしさを感じていました。
そんな中、新たに「C2750D4I」というマザーボードを購入し、x86 Solaris11サーバとして稼働させました。
このマザーボードはメモリ、HDD共にたくさん積むことが出来るので仮想化環境の基盤的な使い方をするとよさそうだ、と考えたので、勉強もかねて物理Solaris10サーバを仮想化環境へ移行(いわゆるP2V)してみる事にしました。
仮想化ソフトウェアはSolaris11でも動くフリーのもの、という事でVirtualBoxを選びました。
*1:HW由来なのかOSなのか不明・・・
ZFSスナップショットを管理するPythonスクリプト
Pythonの勉強がてら作ってみました。
前提条件
該当Solaris11サーバは日次で全ZFSのスナップショットを取得しており、書式は
[ZFS名]@YYYYmmddHHMMSS
とする。
また、Pythonのバージョンは
3.5.1
とする。
使い方
Usage: ./rotate_zfs_snapshot.py [ZFS name] [age_date]
ZFS「bata64/data」の、30日経過したスナップショットを削除したい場合は
./rotate_zfs_snapshot.py bata64/data 30
とすればよい。
なお、スーパユーザ権限が必要です。
ソースコード
初めて作ったのでくどいほどコメントを入れてみました。
#!/usr/bin/env python import sys import datetime import subprocess import re ## プログラム実行時の引数を取得 param = sys.argv ## 引数の数を取得(コマンド名+引数の数値が取得される) check_params = len(param) ## 引数の数が2でない場合は使用例出して異常終了 if check_params != 3: print ("Usage: " + param[0] + " [ZFS name] [age_date]") sys.exit(1) ## 第一引数で渡された値を取得(ZFS名) snapshot_name = param[1] ## 第二引数で渡された値を取得(エージング期間) age_date = int ( param[2] ) ## datetimeモジュールで現時刻を取得 date_now = datetime.datetime.now() ## datetimeモジュールで今から○日前の日付を、しきい値として取得 date_threshold = date_now - datetime.timedelta( days = age_date ) ## zfs list -H -t snapshotを実行してスナップショット一覧を取得 cmd_zfs_list = subprocess.Popen([ 'zfs', 'list', '-H', '-t', 'snapshot' ], stdout=subprocess.PIPE) ### 実行結果がbyte型で渡されたので、文字型として扱うためにデコードして変数へ代入 out_zfs_list = cmd_zfs_list.communicate()[0].decode('utf-8') cmd_zfs_list.stdout.close() ## zfs list実行結果を1行ずつ(改行区切り)でリストに格納 list_zfs_list = out_zfs_list.split('\n') ## zfs list実行結果を解釈するための正規表現を定義。Perlだと /^(ZFS名@([0-9]{14}))\s/ という感じ text_re = r'^'+ r'(' + snapshot_name + r'@' + r'(' + r'[0-9]{14}' + r')' + r')' + r'\s' ## 正規表現パターンをコンパイル p = re.compile( text_re ) ## zfs list実行結果が入ったリストをfor文で1個ずつ処理 for line in list_zfs_list: ## zfs list実行結果を正規表現パターンで判定 matchOB = p.match( line ) ## 正規表現パターンにマッチしていたら処理実行 if matchOB: ## 正規表現グループ化によってスナップショット名の@より右側(取得日時)を取得 date_snapshot = matchOB.group( 2 ) ## 正規表現グループ化によってスナップショット名(取得日時)を取得 name_snapshot = matchOB.group( 1 ) ## スナップショット取得日時をdatetimeモジュールで日時データへ変換 date_snapshot_datetime = datetime.datetime.strptime(date_snapshot, '%Y%m%d%H%M%S') ## スナップショット取得日時がしきい値より古い場合処理実行 if date_snapshot_datetime <= date_threshold: ## zfs destroyコマンド実行 status_zfs_destroy = subprocess.call([ 'zfs', 'destroy', name_snapshot ], stdout=subprocess.PIPE) ## コマンド応答ステータスが0であれば成功した旨出力 if status_zfs_destroy == 0: print ( "destroy " + name_snapshot + " SUCCESS." ) ## コマンド応答ステータスが0以外であれば失敗した旨と応答ステータスを出力 else: print ( "destroy " + name_snapshot + " FAIL. CODE = " + str ( status_zfs_destroy ) )
では。
Solaris11.1にDBD::mysqlをインストール(追記あり)
Solaris11.1にHRForecastをインストール - 部屋を掃除したら漫画が沢山出てきたので書く日記で行った、DBD::mysqlのインストールについてです。これがかなりハマりました。
※2014年4月2日追記
cpanmを実行する前に
PATH=/opt/solarisstudio12.3/bin
というようにSolarisStudioをインストールした上でPATHに設定してやれば、下記で説明している作業をする事なくインストールに成功するようです。
事情があってSolarisStudio使えない方は以下の手順で頑張ってみてください。
Solaris11.1にHRForecastをインストール
はじめに
kazeburoさん作成のHRForecastというグラフ作成ツールを使おうと思いました。理由としては
- Perlで書かれている
- 過去日付のデータも登録できる(同じくkazeburoさん作成のGrowthForecastには無い機能)
だからです。
で、会社のマイSolaris 11.1サーバにインストールしようとしたら苦労したのと、ネットで検索したら私が困った事の解決方法そのものズバリが見つからなかったので書いてみます。
前提条件
OS: Oracle Solaris 11.1 X86 64bit版 Perl: v5.18.1 on plenv 2.1.1 mysql: Ver 14.14 Distrib 5.1.37, for pc-solaris2.11 (i386) using readline 5.1 HRForecast: 2013年11月8日現在の最新版(86a47c399b) CPANモジュールのインストールにはcpanmを使用する。 その他、gitとかcurlとかcpanmとか、登場するツールは全てインストール済みである事。