仮想マシンを一緒にバックアップする6つのLinux論理ボリュームがあります。 VMは現在シャットダウンされているため、一貫したイメージを簡単に取得できます。
6つの画像すべてをアーカイブにまとめたいのですが。簡単に言うと、次のようなことができます。
cp /dev/Zia/vm_lvraid_* /tmp/somedir
tar c /tmp/somedir | whatever
しかし、それはもちろん追加のコピーを作成します。余分なコピーを避けたいのですが。
明白なアプローチ:
tar c /dev/Zia/vm_lvraid_* | whatever
tarは特別なファイル(この場合はシンボリックリンク)を認識し、基本的にln -s
をアーカイブに保存するため、機能しません。または、--dereference
を使用するか、直接/dev/dm-X
を指定すると、それらを特殊(デバイスファイル)として認識し、基本的にmknod
をアーカイブに保存します。
この動作を無効にするtarのコマンドラインオプションを検索しましたが、見つかりませんでした。私もcpio
を試しましたが、同じ問題があり、それを上書きするオプションも見つかりませんでした。 7z
(同上)も試しました。 pax
と同じです。私もZip
を試しましたが、それ自体が混乱しました。
編集:GNU tarとGNU cpioのソースコードを見ると、どちらもこれを行うことができないように見えます。少なくとも、深刻な策略なしでは(デバイスファイルの特別な処理を無効にすることはできません。そのため、深刻な策略の提案や代替ユーティリティをいただければ幸いです。
TLDR:複数のディスクイメージを一緒にパックし(rawデバイスから取得)、追加のディスク上のコピーを作成せずにその出力をストリーミングするアーカイバーはありますか?私の好みはPOSIXやGNU tarなどの一般的な形式で出力されます。
だから最近私はtar
でこれをやりたかった。いくつかの 調査 は、私ができなかったのは少し無意味なだけではないことを示しました。私はこの奇妙な_split --filter="cat >file; tar -r ..."
_のことを思いつきましたが、まあ、それはひどく遅かったです。そして、私がtar
について読むほど、それは無意味であるように見えました。
ご覧のとおり、tar
はレコードの連結リストにすぎません。構成ファイルはいかなる方法でも変更されません-それらは全体がアーカイブ内にあります。しかし、それらは512バイトのblock境界でblockedオフであり、すべてのファイルの前にはがありますヘッダ。それでおしまい。ヘッダーの形式も非常にシンプルです。
それで、私は自分のtar
を書きました。私はそれを... shitar
と呼びます。
_z() (IFS=0; printf '%.s\\0' $(printf "%.$(($1-${#2}))d"))
chk() (IFS=${IFS#??}; set -f; set -- $(
printf "$(fmt)" "$n" "$@" '' "$un" "$gn"
); IFS=; a="$*"; printf %06o "$(($(
while printf %d+ "'${a:?}"; do a=${a#?}; done 2>/dev/null
)0))")
fmt() { printf '%s\\'"${1:-n}" %s "${1:+$(z 99 "$n")}%07d" \
%07o %07o %011o %011o "%-${1:-7}s" ' 0' "${1:+$(z 99)}ustar " %s \
"${1:+$(z 31 "$un")}%s"
}
_
肉とジャガイモです。ヘッダーを書き込み、chksumを計算します。これは、相対的に言えば、唯一の難しい部分です。これはustar
ヘッダー形式を実行します...maybe。少なくとも、それはGNU tar
がustar
ヘッダー形式であると考えているように思われるように見えますが、文句を言わないほどです。そして、それだけではありません。まだ凝固していないだけです。ここでは、以下を紹介します。
_for f in 1 2; do echo hey > file$f; done
{ tar -cf - file[123]; echo .; } | tr \\0 \\n | grep -b .
0:file1 #filename - first 100 bytes
100:0000644 #octal mode - next 8
108:0001750 #octal uid,
116:0001750 #gid - next 16
124:00000000004 #octal filesize - next 12
136:12401536267 #octal Epoch mod time - next 12
148:012235 #chksum - more on this
155: 0 #file type - gnu is weird here - so is shitar
257:ustar #magic string - header type
265:mikeserv #owner
297:mikeserv #group - link name... others shitar doesnt do
512:hey #512-bytes - start of file
1024:file2 #512 more - start of header 2
1124:0000644
1132:0001750
1140:0001750
1148:00000000004
1160:12401536267
1172:012236
1179: 0
1281:ustar
1289:mikeserv
1321:mikeserv
1536:hey
10240:. #default blocking factor 20 * 512
_
それはtar
です。すべてが_\0
_ nullsで埋め込まれているため、読みやすくするためにem
を_\n
_ ewlinesに変換します。そしてshitar
:
_#the rest, kind of, calls z(), fmt(), chk() + gets $mdata and blocks w/ dd
for n in file[123]
do d=$n; un=$USER; gn=$(id --group --name)
set -- $(stat --printf "%a\n%u\n%g\n%s\n%Y" "$n")
printf "$(fmt 0)" "$n" "$@" "$(chk "$@")" "$un" "$gn"
printf "$(z $((512-298)) "$gn")"; cat "$d"
printf "$(x=$(($4%512));z $(($4>512?($x>0?$x:512):512-$4)))"
done |
{ dd iflag=fullblock conv=sync bs=10240 2>/dev/null; echo .; } |
tr \\0 \\n | grep -b .
_
_0:file1 #it's the same. I shortened it.
100:0000644 #but the whole first file is here
108:0001750
116:0001750
124:00000000004
136:12401536267
148:012235 #including its checksum
155: 0
257:ustar
265:mikeserv
297:mikeserv
512:hey
1024:file2
...
1172:012236 #and file2s checksum
...
1536:hey
10240:.
_
私は一種と言いますが、それはshitar
の目的ではないためです。tar
はすでにそれを美しく実行しています。私はそれがどのように機能するかを示したかっただけです-つまり、chksum
に触れる必要があります。そうでなければ、私はdd
ファイルの先頭からtar
ingして、それで終わります。それは時々うまくいくかもしれませんが、アーカイブに複数のメンバーがいるとき、それは面倒になります。それでも、chksumは本当に簡単です。
まず、7つのスペースにします-(これは奇妙なgnuのことですが、仕様に8と記載されているように、ハッキングはハックです)。次に、ヘッダーのすべてのバイトの8進値を合計します。それがあなたのチェックサムです。したがって、ヘッダーを実行する前にファイルメタデータが必要です。または、chksumがありません。そして、それは主にustar
アーカイブです。
OK。さて、それが何をするつもりなのか:
_cd /tmp; mkdir -p mnt
for d in 1 2 3
do fallocate -l $((1024*1024*500)) disk$d
lp=$(Sudo losetup -f --show disk$d)
sync
Sudo mkfs.vfat -n disk$d "$lp"
Sudo mount "$lp" mnt
echo disk$d file$d | Sudo tee mnt/file$d
Sudo umount mnt
Sudo losetup -d "$lp"
done
_
これにより、3つの500Mディスクイメージが作成され、それぞれがフォーマットおよびマウントされ、それぞれにファイルが書き込まれます。
_for n in disk[123]
do d=$(Sudo losetup -f --show "$n")
un=$USER; gn=$(id --group --name)
set -- $(stat --printf "%a\n%u\n%g\n$(lsblk -bno SIZE "$d")\n%Y" "$n")
printf "$(fmt 0)" "$n" "$@" "$(chk "$@")" "$un" "$gn"
printf "$(z $((512-298)) "$gn")"
Sudo cat "$d"
Sudo losetup -d "$d"
done |
dd iflag=fullblock conv=sync bs=10240 2>/dev/null |
xz >disks.tar.xz
_
注-明らかにブロックデバイスは常に正しくブロックするだけです。かなり便利です。
そのtar
は、ディスクデバイスファイルのコンテンツをインストリームで出力し、出力をxz
にパイプします。
_ls -l disk*
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk1
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk2
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk3
-rw-r--r-- 1 mikeserv mikeserv 229796 Sep 3 01:05 disks.tar.xz
_
今、真実の瞬間...
_ xz -d <./disks.tar.xz| tar -tvf -
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk1
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk2
-rw-r--r-- mikeserv/mikeserv 524288000 2014-09-03 01:01 disk3
_
やったー!抽出...
_xz -d <./disks.tar.xz| tar -xf - --xform='s/[123]/1&/'
ls -l disk*
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk1
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk11
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk12
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk13
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk2
-rw-r--r-- 1 mikeserv mikeserv 524288000 Sep 3 01:01 disk3
-rw-r--r-- 1 mikeserv mikeserv 229796 Sep 3 01:05 disks.tar.xz
_
比較...
_cmp disk1 disk11 && echo yay || echo shite
yay
_
そしてマウント...
_Sudo mount disk13 mnt
cat mnt/*
disk3 file3
_
したがって、この場合、shitar
は大丈夫だと思います。私はそれがうまくいかないことのすべてには行きたくないです。しかし、私は言うでしょう-少なくともファイル名に改行をしないでください。
また、私が提供した代替案を考慮して、これをsquashfs
で行うこともできます。ストリームからビルドされた単一のアーカイブを取得するだけでなく、_mount
ableであり、カーネルのvfs
に組み込まれています。
_# Copy 10K from the device /dev/sda1 into the file input. Ordinarily
# Mksquashfs given a device, fifo, or named socket will place that special file
# within the Squashfs filesystem, this allows input from these special
# files to be captured and placed in the Squashfs filesystem.
input f 444 root root dd if=/dev/sda1 bs=1024 count=10
# Creating a block or character device examples
# Create a character device "chr_dev" with major:minor 100:1 and
# a block device "blk_dev" with major:minor 200:200, both with root
# uid/gid and a mode of rw-rw-rw.
chr_dev c 666 root root 100 1
blk_dev b 666 0 0 200 200
_
btrfs (send|receive)
を使用して、サブボリュームを任意のstdin
- capableコンプレッサーにストリーミングすることもできます。もちろん、このサブボリュームは、圧縮コンテナーとして使用する前に存在する必要はありません。
それでも、squashfs
について...
私はこの正義をやっているとは思わない。これは非常に簡単な例です:
_ cd /tmp; mkdir ./emptydir
mksquashfs ./emptydir /tmp/tmp.sfs -p \
'file f 644 mikeserv mikeserv echo "this is the contents of file"'
Parallel mksquashfs: Using 6 processors
Creating 4.0 filesystem on /tmp/tmp.sfs, block size 131072.
[==================================================================================|] 1/1 100%
Exportable Squashfs 4.0 filesystem, gzip compressed, data block size 131072
compressed data, compressed metadata, compressed fragments,...
###...
###AND SO ON
###...
echo '/tmp/tmp.sfs /tmp/imgmnt squashfs loop,defaults,user 0 0'|
Sudo tee -a /etc/fstab >/dev/null
mount ./tmp.sfs
cd ./imgmnt
ls
total 1
-rw-r--r-- 1 mikeserv mikeserv 29 Aug 20 11:34 file
cat file
this is the contents of file
cd ..
umount ./imgmnt
_
これは、mksquash
のインライン_-p
_引数のみです。 _-pf
_を使用して、必要な数のファイルを含むファイルを入手できます。形式は単純です。新しいアーカイブのファイルシステムでターゲットファイルの名前/パスを定義し、モードと所有者を指定して、どのプロセスを実行してstdoutを読み取るかを指示します。好きなだけ作成することができ、LZMA、GZIP、LZ4、XZを使用できます。そして、最終的な結果は、あなたがcd
であるアーカイブです。
ただし、フォーマットの詳細:
これはもちろん、単なるアーカイブではありません-圧縮された、マウント可能なLinuxファイルシステムイメージです。その形式はLinuxカーネルのものです。これはバニラカーネルでサポートされているファイルシステムです。このように、Vanilla Linuxカーネルと同じくらい一般的です。ですから、tar
プログラムがインストールされていないバニラLinuxシステムを実行していると言ったら、疑わしいと思いますが、おそらくあなたを信じているでしょう。しかし、あなたがsquashfs
ファイルシステムがサポートされていないバニラLinuxシステムを実行していると私に言ったとしたら、私はあなたを信じません。
問題はしばらくの間私を困惑させ、私はうまくいく解決策を見つけたと思います。
-si{NAME}
フラグを使用すると、7zで必要なことを達成できると思います。
あなたはあなたのニーズに適応することができます。
7z a test.7z -siSDA2.txt < /dev/sda1
7z a test.7z -siSDA2.txt < /dev/sda2
7z l test.7z
7-Zip [64] 9.20 Copyright (c) 1999-2010 Igor Pavlov 2010-11-18
p7Zip Version 9.20 (locale=en_US.UTF-8,Utf16=on,HugeFiles=on,8 CPUs)
Listing archive: test.7z
--
Path = test.7z
Type = 7z
Method = LZMA
Solid = -
Blocks = 2
Physical Size = 1770
Headers Size = 162
Date Time Attr Size Compressed Name
------------------- ----- ------------ ------------ ------------------------
2014-08-19 22:01:08 ..... 6314 804 SDA1.txt
2014-08-19 22:01:11 ..... 6314 804 SDA2.txt
------------------- ----- ------------ ------------ ------------------------
12628 1608 2 files, 0 folders
[〜#〜] edit [〜#〜]:猫の無用な使用を削除