我如何tarball proc文件系统?

时间:2010-09-02 20:28:53

标签: linux bash tar

我想拍摄整个proc文件系统的快照,并将其保存在tarball中(或者在最坏的情况下将所有文本文件连接到一个文本文件中)。

但是当我跑步时:

tar -c /proc

我遇到了段错误。

最好的方法是什么?我应该在每个文件中设置某种递归遍历吗?

我只有基本的* nix实用程序,例如bash,cat,ls,echo等。我没有像python或perl或java那样的任何东西。

3 个答案:

答案 0 :(得分:6)

linux / proc文件系统实际上是伪装成文件系统的内核变量。没有什么可以保存,因此无需备份。如果系统允许您,您可以rm -rf /proc并在下次重启时神奇地重新出现。

/ dev文件系统具有真正的i节点,可以备份它们。除了他们没有内容,只有一个主要和次要的号码,权限和名称。备份特殊设备文件的工具仅记录这些参数,从不尝试打开(2)设备。但是,由于设备的主要和次要数字仅对它们所构建的精确系统有意义,因此几乎没有理由对它们进行备份。

尝试tar / proc伪文件系统导致tar出现段错误的原因是因为/ proc具有有趣的文件行为:像只写伪文件这样的东西可能看起来具有读取权限,但是如果返回错误指示则返回错误指示程序试图打开(2)它进行备份。这肯定会让天真的焦油变得顽固。

添加以回复评论

tar对读取/ proc / kmsg有问题并不让我感到惊讶,因为它有一些有趣的属性:

# strace cat /proc/kmsg
execve("/bin/cat", ["cat", "kmsg"],
open("kmsg", O_RDONLY|O_LARGEFILE)      = 3
// ok, no problem opening the file for reading
fstat64(3, { st_mode=S_IFREG|0400,  st_size=0,
// looks like a normal file of zero length
// but cat does not pay attention to st_size so it just
// does a blocking read
read(3, "<4>[103128.156051] ata2.00: qc t"..., 32768) = 461
write(1, "<4>[103128.156051] ata2.00: qc t"..., 461) = 461
// ...forever...
read(3, "<6>[103158.228444] ata2.00: conf"..., 32768) = 48
write(1, "<6>[103158.228444] ata2.00: conf"..., 48) = 48
+++ killed by SIGINT +++

因为/ proc / kmsg是内核消息的运行列表,所以它永远不会返回0(EOF)它会一直持续到我感到无聊并按^ C。

有趣的是,我的tar与/ proc / kmsg没有问题:

$ tar --version
tar (GNU tar) 1.22
# tar cf /tmp/junk.tar /proc/kmsg
$ tar tvf /tmp/junk.tar
-r-------- root/root         0 2010-09-01 14:41 proc/kmsg

如果你查看strace输出,GNU tar 1.22看到st_length == 0并且甚至没有打开文件进行读取,因为那里没有任何东西。

我可以想象你的tar看到长度为0,使用malloc(3)分配了那么多(无)空间,它尽职地将指针传回零长度缓冲区。您的tar从/ proc / kmsg读取,读取的长度非零,并尝试将其存储在零长度缓冲区中并且违反了分段。

这只是一个在/ proc中等待焦油的老鼠洞。还有多少人?不知道。他们会表现得一样吗?可能不是。哪些〜1000左右的文件不是/proc/<pid>伪文件会有奇怪的语义?说不上。

但也许是最有说服力的问题:你对/ proc / sys / vm / lowmem_reserve_ratio有什么意义,下周会有什么不同,你能从这个差异中学到什么吗?

答案 1 :(得分:2)

虽然如果你想要做出类似这样的事情,那么接受的答案会很有意义,但是有一个答案可行。这是一个将完整/ proc文件系统复制到/ tmp / proc的脚本。然后可以对其进行tar和gzip压缩。在用新的文件服务器替换它之前,我用它来记住我可靠的旧文件服务器的设置和功能(内存,bogomips,默认进程等)。

cd /
mkdir /tmp/proc
find /proc -type f | while read F ; do
   D=/tmp/$(dirname $F)
   test -d $D || mkdir -p $D
   test -f /tmp/$F || sudo cat $F > /tmp/$F
done

备注: 由于我必须使用cat而不是cp,因此不会保留权限。 cp -a /proc /proccopy不起作用,因为它也会在“kcore”上崩溃。 mc(Midnight Commander)成功创建了/ proc的副本然后你可以tar和gzip,但是你必须解雇成千上万的“无法读取文件XYZ”错误,并且它在'kcore'上也会因总线错误而崩溃。

答案 2 :(得分:1)

一个简单的答案:

ls -Rd /proc/* > proc.lst 
foreach item (<proc.lst>)
  echo "proc_file:$item"
  if (-f $item) cat $item
end

提供网站咨询协议:

“但要避免......根据意见做出陈述......”

(恕我直言......基于相当多年的经验)在一个特定的时间点,想出一些很好的理由想要获得/ proc / *的所选元素的快照并不需要太多的想象力存储它,或将它发送到某个地方。因此,我会质疑“答案”的用处,例如:

linux / proc文件系统实际上是伪装成文件系统的内核变量。没有什么可以保存,因此无需备份。如果系统允许你,你可以rm -rf / proc,它会在下次重启时神奇地重新出现。

......理由是它没有回答问题,做出错误的断言,并包含与问题无关的无偿信息。