我一直在处理稀疏文件,以便在Windows samba上复制Linux fs权限,从这里挂载一个想法: https : //www.thanassis.space/backup.html 。
虽然testing稀疏文件,但我发现了一个有趣的问题,其中“完整的”主驱动器不报告为应用程序的写入失败。 相反,当主机驱动器填满时,即使驱动器已满,写入仍会继续并成功完成。
为了testing这个我有以下的设置。
[root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 944M 7.1G 12% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 49M 1.7G 3% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 33M 4.0G 1% /mnt tmpfs 354M 0 354M 0% /run/user/0
我在/mnt上挂载了一个4G分区,我将在其上创build一个10G稀疏文件。
[root@ip-172-31-61-147 ~]# dd of=/mnt/file bs=1G count=0 seek=10 0+0 records in 0+0 records out 0 bytes (0 B) copied, 3.0097e-05 s, 0.0 kB/s
该文件创build正确,并不占用实际的分区空间,但似乎是一个10G文件。
[root@ip-172-31-61-147 ~]# ls -lh /mnt/ total 0 -rw-r--r--. 1 root root 10G Aug 28 21:10 file [root@ip-172-31-61-147 ~]# du -h /mnt/ 0 /mnt/
我在空间中分配一个文件系统并挂载它(通过losetupvalidation)。
[root@ip-172-31-61-147 ~]# mkfs.xfs /mnt/file meta-data=/mnt/file isize=512 agcount=4, agsize=655360 blks = sectsz=512 attr=2, projid32bit=1 = crc=1 finobt=0, sparse=0 data = bsize=4096 blocks=2621440, imaxpct=25 = sunit=0 swidth=0 blks naming =version 2 bsize=4096 ascii-ci=0 ftype=1 log =internal log bsize=4096 blocks=2560, version=2 = sectsz=512 sunit=0 blks, lazy-count=1 realtime =none extsz=4096 blocks=0, rtextents=0 [root@ip-172-31-61-147 ~]# mount /mnt/file /srv/ [root@ip-172-31-61-147 ~]# losetup -j /mnt/file /dev/loop0: [51729]:67 (/mnt/file) [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 945M 7.1G 12% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 49M 1.7G 3% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 43M 4.0G 2% /mnt tmpfs 354M 0 354M 0% /run/user/0 /dev/loop0 10G 33M 10G 1% /srv [root@ip-172-31-61-147 ~]#
在这个挂载点上,我可以正常写入文件,表明它正常工作。
[root@ip-172-31-61-147 ~]# dd if=/dev/zero of=/srv/init_file bs=1GiB count=1 1+0 records in 1+0 records out 1073741824 bytes (1.1 GB) copied, 8.22444 s, 131 MB/s [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 945M 7.1G 12% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 49M 1.7G 3% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 1.1G 3.0G 27% /mnt tmpfs 354M 0 354M 0% /run/user/0 /dev/loop0 10G 1.1G 9.0G 11% /srv [root@ip-172-31-61-147 ~]# ls -lh /srv/ total 1.0G -rw-r--r--. 1 root root 1.0G Aug 28 21:19 init_file [root@ip-172-31-61-147 ~]# [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 945M 7.1G 12% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 49M 1.7G 3% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 1.1G 3.0G 27% /mnt tmpfs 354M 0 354M 0% /run/user/0 /dev/loop0 10G 1.1G 9.0G 11% /srv
现在,当我尝试创build一个应该超出主机驱动器的文件时,它也将正确写入并且不报告错误。
[root@ip-172-31-61-147 ~]# dd if=/dev/zero of=/srv/too_large_a_file bs=1GiB count=4 4+0 records in 4+0 records out 4294967296 bytes (4.3 GB) copied, 49.9905 s, 85.9 MB/s [root@ip-172-31-61-147 ~]# echo $? 0
相关数据:
[root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 949M 7.1G 12% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 49M 1.7G 3% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 4.0G 20K 100% /mnt tmpfs 354M 0 354M 0% /run/user/0 /dev/loop0 10G 5.1G 5.0G 51% /srv [root@ip-172-31-61-147 ~]# du -h /srv/ 5.0G /srv/ [root@ip-172-31-61-147 ~]# du -h /srv/* 1.0G /srv/init_file 4.0G /srv/too_large_a_file [root@ip-172-31-61-147 ~]# ls -lh /srv/ total 5.0G -rw-r--r--. 1 root root 1.0G Aug 28 21:19 init_file -rw-r--r--. 1 root root 4.0G Aug 28 21:24 too_large_a_file [root@ip-172-31-61-147 ~]#
我试图使用其他实用程序(如rsync和cp来复制此行为。 也不报告错误,而是默默地失败。
使用cp:
[root@ip-172-31-61-147 ~]# cp -v too_large_a_file /srv/ 'too_large_a_file' -> '/srv/too_large_a_file' [root@ip-172-31-61-147 ~]# echo $? 0 [root@ip-172-31-61-147 ~]# ls -lhtr /srv/ total 5.0G -rw-r--r--. 1 root root 5.0G Aug 28 21:31 too_large_a_file [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 6.0G 2.1G 75% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 57M 1.7G 4% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 4.0G 20K 100% /mnt tmpfs 354M 0 354M 0% /run/user/0 /dev/loop0 10G 5.1G 5.0G 51% /srv
使用rsync:
[root@ip-172-31-61-147 ~]# rsync -vvv too_large_a_file /srv/ [sender] make_file(too_large_a_file,*,0) send_file_list done send_files starting server_recv(2) starting pid=16569 received 1 names recv_file_list done get_local_name count=1 /srv/ generator starting pid=16569 delta-transmission disabled for local transfer or --whole-file recv_generator(too_large_a_file,0) send_files(0, too_large_a_file) send_files mapped too_large_a_file of size 5368709120 calling match_sums too_large_a_file too_large_a_file sending file_sum false_alarms=0 hash_hits=0 matches=0 sender finished too_large_a_file send_files phase=1 recv_files(1) starting generate_files phase=1 recv_files(too_large_a_file) got file_sum renaming .too_large_a_file.CwVApY to too_large_a_file recv_files phase=1 generate_files phase=2 send_files phase=2 send files finished total: matches=0 hash_hits=0 false_alarms=0 data=5368709120 recv_files phase=2 generate_files phase=3 recv_files finished generate_files finished sent 5369364558 bytes received 31 bytes 57426359.24 bytes/sec total size is 5368709120 speedup is 1.00 [sender] _exit_cleanup(code=0, file=main.c, line=1052): about to call exit(0) [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 6.0G 2.1G 75% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 73M 1.7G 5% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 4.0G 20K 100% /mnt tmpfs 354M 0 354M 0% /run/user/0 /dev/loop0 10G 5.1G 5.0G 51% /srv
在运行md5sum我更加困惑:
[root@ip-172-31-61-147 ~]# md5sum /root/too_large_a_file ec4bcc8776ea04479b786e063a9ace45 /root/too_large_a_file [root@ip-172-31-61-147 ~]# md5sum /srv/too_large_a_file ec4bcc8776ea04479b786e063a9ace45 /srv/too_large_a_file
看来完整的文件被保存了,虽然怎么样,我不知道。
在研究这个时,我发现这个问题,有人在做相同的事情,但使用encryption的设置,他们确定了同样的问题,但无法解决它(事实上,他们build议打开一个新的问题!): 创build一个使用LUKS按需增长的encryption卷 。
任何帮助将是伟大的。
编辑 :根据请求的内核和系统信息
[root@ip-172-31-61-147 ~]# uname -a Linux ip-172-31-61-147 3.10.0-514.16.1.el7.x86_64 #1 SMP Wed Apr 12 15:04:24 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux [root@ip-172-31-61-147 ~]# cat /etc/redhat-release CentOS Linux release 7.3.1611 (Core)
根据提供的答案,我创build了新文件来testing/dev/zero理论。 我创build了一个所有的文件,并试图复制我的发现,发现它仍然是成功的。
[root@ip-172-31-61-147 ~]# tr '\0' '\377' < /dev/zero | dd bs=1 count=5G of=~/too_large_a_file [root@ip-172-31-61-147 ~]# du -h too_large_a_file 982M too_large_a_file
然后我把这个文件的多个副本放在稀疏文件装载(例如, cp too_large_a_file /srv/too_large_a_file_1 )
我能够将这些文件中的六个复制到外部而没有任何复制失败。
[root@ip-172-31-61-147 ~]# ls -lh /srv/ total 4.8G -rw-r--r--. 1 root root 982M Aug 29 00:14 too_large_a_file -rw-r--r--. 1 root root 982M Aug 29 00:26 too_large_a_file_2 -rw-r--r--. 1 root root 982M Aug 29 02:34 too_large_a_file_3 -rw-r--r--. 1 root root 982M Aug 29 02:34 too_large_a_file_4 -rw-r--r--. 1 root root 982M Aug 29 02:35 too_large_a_file_5
这里的驱动器显然是最大的。
Filesystem 1K-blocks Used Available Use% Mounted on /dev/xvda1 8377344 1975040 6402304 24% / devtmpfs 1920720 0 1920720 0% /dev tmpfs 1809256 0 1809256 0% /dev/shm tmpfs 1809256 82192 1727064 5% /run tmpfs 1809256 0 1809256 0% /sys/fs/cgroup /dev/xvdb1 4183040 4183020 20 100% /mnt tmpfs 361852 0 361852 0% /run/user/1000 /dev/loop0 10475520 5055864 5419656 49% /srv
所有的文件和原来的md5sums如下所示。
[root@ip-172-31-61-147 ~]# md5sum too_large_a_file e8154ef97a3eb2bd13aea04b823a4570 too_large_a_file [root@ip-172-31-61-147 ~]# md5sum /srv/* e8154ef97a3eb2bd13aea04b823a4570 /srv/too_large_a_file e8154ef97a3eb2bd13aea04b823a4570 /srv/too_large_a_file_2 e8154ef97a3eb2bd13aea04b823a4570 /srv/too_large_a_file_3 e8154ef97a3eb2bd13aea04b823a4570 /srv/too_large_a_file_4 154248d2eeaf5791dfc8199e51daadbc /srv/too_large_a_file_5
我将添加这是显然影响系统的东西,因为添加第六个文件崩溃了。 注意:复制完成后,系统再次响应。
编辑2:添加du信息。
[root@ip-172-31-61-147 ~]# du -h /srv/* 982M /srv/too_large_a_file 982M /srv/too_large_a_file_2 982M /srv/too_large_a_file_3 982M /srv/too_large_a_file_4 982M /srv/too_large_a_file_5
编辑3:内存信息我testing了这个,通过删除“重写”缓冲区的文件,然后复制一个回去,并删除caching,看看发生了什么。
[root@ip-172-31-61-147 ~]# rm /srv/too_large_a_file_5 rm: remove regular file '/srv/too_large_a_file_5'? y [root@ip-172-31-61-147 ~]# cp too_large_a_file /srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 2.2G 5.9G 28% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 97M 1.7G 6% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup /dev/xvdb1 4.0G 4.0G 20K 100% /mnt tmpfs 354M 0 354M 0% /run/user/1000 /dev/loop0 10G 4.9G 5.2G 49% /srv [root@ip-172-31-61-147 ~]# free -m && sync && echo 3 > /proc/sys/vm/drop_caches && free -m total used free shared buff/cache available Mem: 3533 93 1210 104 2229 3091 Swap: 0 0 0 total used free shared buff/cache available Mem: 3533 94 3281 104 157 3183 Swap: 0 0 0 [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 2.2G 5.9G 28% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 105M 1.7G 6% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup /dev/xvdb1 4.0G 4.0G 20K 100% /mnt tmpfs 354M 0 354M 0% /run/user/1000 /dev/loop0 10G 4.9G 5.2G 49% /srv [root@ip-172-31-61-147 ~]# md5sum /srv/too_large_a_file_5 154248d2eeaf5791dfc8199e51daadbc /srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# du -ah /srv/ 982M /srv/too_large_a_file 982M /srv/too_large_a_file_2 982M /srv/too_large_a_file_3 982M /srv/too_large_a_file_4 982M /srv/too_large_a_file_5 4.8G /srv/ [root@ip-172-31-61-147 ~]# ls -lh /srv/ total 4.8G -rw-r--r--. 1 root root 982M Aug 29 00:14 too_large_a_file -rw-r--r--. 1 root root 982M Aug 29 00:26 too_large_a_file_2 -rw-r--r--. 1 root root 982M Aug 29 02:34 too_large_a_file_3 -rw-r--r--. 1 root root 982M Aug 29 12:16 too_large_a_file_4 -rw-r--r--. 1 root root 982M Aug 29 12:27 too_large_a_file_5 [root@ip-172-31-61-147 ~]#
编辑4:内存信息继续我怀疑我的发现,我做了一个更多的testing,似乎有点启发。 在转储caching后,文件似乎发生了变化, md5sum输出也会更新。
[root@ip-172-31-61-147 ~]# rm /srv/too_large_a_file_5 rm: remove regular file '/srv/too_large_a_file_5'? y [root@ip-172-31-61-147 ~]# cp too_large_a_file /srv/too_large_a_file_5 (reverse-i-search)`m': r^C/srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# md5sum /srv/too_large_a_file_5 e8154ef97a3eb2bd13aea04b823a4570 /srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# [root@ip-172-31-61-147 ~]# [root@ip-172-31-61-147 ~]# md5sum /srv/too_large_a_file_5 e8154ef97a3eb2bd13aea04b823a4570 /srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# free -m && sync && echo 3 > /proc/sys/vm/drop_caches && free -m total used free shared buff/cache available Mem: 3533 93 298 104 3141 3091 Swap: 0 0 0 total used free shared buff/cache available Mem: 3533 93 3274 112 166 3175 Swap: 0 0 0 [root@ip-172-31-61-147 ~]# md5sum /srv/too_large_a_file_5 154248d2eeaf5791dfc8199e51daadbc /srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 2.2G 5.9G 28% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 113M 1.7G 7% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup /dev/xvdb1 4.0G 4.0G 20K 100% /mnt tmpfs 354M 0 354M 0% /run/user/1000 /dev/loop0 10G 4.9G 5.2G 49% /srv
重新启动后
[root@ip-172-31-61-147 ~]# mount /mnt/file /srv/ [root@ip-172-31-61-147 ~]# df -h Filesystem Size Used Avail Use% Mounted on /dev/xvda1 8.0G 2.2G 5.9G 28% / devtmpfs 1.9G 0 1.9G 0% /dev tmpfs 1.8G 0 1.8G 0% /dev/shm tmpfs 1.8G 17M 1.8G 1% /run tmpfs 1.8G 0 1.8G 0% /sys/fs/cgroup tmpfs 354M 0 354M 0% /run/user/1000 /dev/xvdb1 4.0G 4.0G 20K 100% /mnt /dev/loop0 10G 4.9G 5.2G 49% /srv [root@ip-172-31-61-147 ~]#
编辑5:同步信息
看来,以同步方式安装文件会产生错误。
[root@ip-172-31-61-147 ~]# mount -odefaults,sync /mnt/file /srv/ [root@ip-172-31-61-147 ~]# mount sysfs on /sys type sysfs (rw,nosuid,nodev,noexec,relatime,seclabel) ..snip.. /dev/xvdb1 on /mnt type xfs (rw,relatime,seclabel,attr2,inode64,noquota) /mnt/file on /srv type xfs (rw,relatime,sync,seclabel,wsync,attr2,inode64,noquota) [root@ip-172-31-61-147 ~]# cp too_large_a_file /srv/too_large_a_file_5 [root@ip-172-31-61-147 ~]# cp too_large_a_file /srv/too_large_a_file_5 cp: error writing '/srv/too_large_a_file_5': Input/output error cp: failed to extend '/srv/too_large_a_file_5': Input/output error [root@ip-172-31-61-147 ~]# ls /srv/ too_large_a_file too_large_a_file_2 too_large_a_file_3 too_large_a_file_4 too_large_a_file_5
你有足够的内存,使文件内容可以完全caching吗? 无论如何,我认为这是在内核/文件系统实现中没有考虑到的一个小问题。 毕竟这里有很多层次的工作。
“现在,当我尝试创build一个应该超出主驱动器的文件时,它也将正确写入,而不报告错误。
[root@ip-172-31-61-147 ~]# dd if=/dev/zero of=/srv/too_large_a_file
是的,它会正确写入,因为你写的零是稀疏文件,除非它被覆盖到别的东西,因此你在这里做了什么,什么都不写入稀疏文件。 如果你写的东西不是零,写入就会失败。
cp和rsync可能会根据操作系统和内核版本保持稀疏。