【Linux恶作剧系列】1 如何写满磁盘而难以被发现
相信各位搞系统运维的同学,都收到过机器磁盘满了的报警短信,通常这时候心里一定想着,这是哪个不着调的把系统服务配错了或者把代码写飞了,没有log rotate,没有控制写入数据大小,没有限制core的行为...
本文...本文打算写点别的方法,教你如何写满磁盘却又比较难被查到,嗯...也就是说,你查不出谁写满磁盘的时候,请重新复习这篇文章看看。
0 背景知识
系统命令 | 作用 |
---|---|
ls | list, 列出当前目录下的目录和文件 |
lsof | 列出打开的文件 |
df | 报告文件系统磁盘空间使用率 |
du | disk usage,统计当前目录或文件使用了多大的磁盘 |
1 小儿科的隐藏文件
linux下以"."开头的文件为隐藏文件,直接使用ls命令查看不到,这可能导致一些新手同学发现目录够大,而目录下面空空如也。
root@icymoon_dev> du -hs ./testdir/
89M ./testdir/
root@icymoon_dev> ls ./testdir/
root@icymoon_dev>
这个不难,ls 加“-a”参数就可以展示这些文件了。
root@icymoon_dev> ls -a ./testdir/
. .. .file
root@icymoon_dev> ls -al ./testdir/
total 91100
drwxr-xr-x 2 root root 4096 Sep 5 11:34 .
drwxr-xr-x. 3 root root 4096 Sep 5 11:35 ..
-rw-r--r-- 1 root root 93275613 Sep 5 11:34 .file
root@icymoon_dev>
2 进阶版,删除正在被写入的文件
咱们先看个实验哈,以/boot分区为例;
假设/boot分区开始是这样子:
root@icymoon_dev> df | head -n 1 ; df | grep boot
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 499656 406256 56704 88% /boot
root@icymoon_dev> du -hs /boot/
396M /boot/
root@icymoon_dev>
我编写个程序不断地往/boot/test_file里写入,代码可以参考这里:
root@icymoon_dev> vim writefile.c
root@icymoon_dev> gcc writefile.c -Wall -o writefile
root@icymoon_dev> nohup ./writefile &
[2] 15865
root@icymoon_dev> nohup: ignoring input and appending output to ‘nohup.out’
写入同时可以观察/boot分区使用情况和新写入的文件,注意,这里du和df看到的增长情况是符合的~~
root@icymoon_dev> du -hs /boot/
398M /boot/
root@icymoon_dev> df | head -n 1 ; df | grep boot
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 499656 407604 55356 89% /boot
root@icymoon_dev> du -hs /boot/test_file
1.6M /boot/test_file
root@icymoon_dev>
然后,【有意思的地方来了】,删除掉正在写入的文件,耐心等待
root@icymoon_dev> rm /boot/test_file
rm: remove regular file ‘/boot/test_file’? y
root@icymoon_dev> df | head -n 1 ; df | grep boot
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 499656 418368 44592 91% /boot
root@icymoon_dev> du -hs /boot/
396M /boot/
告诉我你看到了什么?df看分区写到了91%,但是du看目录还是只有最初的396M。耐心地等下去,哪怕分区写满了,du看目录还是只用了396M。
What?!这是什么鬼操作?!
亲们,这个事情告诉我们,【划重点】不能随便删除正在写入的文件啊~~~
那么,【划重点】这种情况怎么排查呢?lsof查找deleted文件,怎么处理呢?杀进程;
root@icymoon_dev> lsof | head -n 1 ; lsof | grep deleted
COMMAND PID TID USER FD TYPE DEVICE SIZE/OFF NODE NAME
writefile 15865 root 3u REG 8,1 27386928 332 /boot/test_file (deleted)
root@icymoon_dev> df | head -n 1 ; df | grep boot
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/sda1 499656 436684 26276 95% /boot
root@icymoon_dev> kill -9 15865
root@icymoon_dev> df | head -n 1 ; df | grep boot
Filesystem 1K-blocks Used Available Use% Mounted on
[2]+ Killed nohup ./writefile
/dev/sda1 499656 406256 56704 88% /boot
root@icymoon_dev>
3 再进阶版,玩转mount
什么?你说lsof这个太容易查了?咱们再来点别的
3.1 准备工作
先看看怎么把一个文件做成一个文件系统的image并且挂载,了解的朋友请跳过
root@icymoon_dev> dd if=/dev/zero of=disk8M.image bs=1024 count=8192
8192+0 records in
8192+0 records out
8388608 bytes (8.4 MB) copied, 0.0169399 s, 495 MB/s
root@icymoon_dev> mke2fs -F disk8M.image -L "ramdisk" -b 1024 -m 0
mke2fs 1.42.9 (28-Dec-2013)
Discarding device blocks: done
Filesystem label=ramdisk
OS type: Linux
Block size=1024 (log=0)
Fragment size=1024 (log=0)
Stride=0 blocks, Stripe width=0 blocks
2048 inodes, 8192 blocks
0 blocks (0.00%) reserved for the super user
First data block=1
Maximum filesystem blocks=8388608
1 block group
8192 blocks per group, 8192 fragments per group
2048 inodes per group
Allocating group tables: done
Writing inode tables: done
Writing superblocks and filesystem accounting information: done
root@icymoon_dev> sudo chmod 777 disk8M.image
### mount这个image文件到一个目录
root@icymoon_dev> sudo rmdir ramdisk/
root@icymoon_dev> sudo mount -o r,w disk8M.image disk/
mount: wrong fs type, bad option, bad superblock on /dev/loop0,
missing codepage or helper program, or other error
In some cases useful info is found in syslog - try
dmesg | tail or so.
root@icymoon_dev> sudo mount -o rw disk8M.image disk/
### 看看mount的成果
root@icymoon_dev> df | head -n 1;df | grep icymoon
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 7931 45 7886 1% /home/icymoon/disk
3.2 可以开始玩了
先copy进去个文件看看
root@icymoon_dev> df | head -n 1;df | grep icymoon
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 7931 45 7886 1% /home/icymoon/disk
root@icymoon_dev> cp ./file /home/icymoon/disk
root@icymoon_dev> ls /home/icymoon/disk
file lost+found
root@icymoon_dev> df | head -n 1;df | grep icymoon
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop0 7931 1802 6129 23% /home/icymoon/disk
root@icymoon_dev> du -hs /home/icymoon/disk
1.8M /home/icymoon/disk
文件可以正常复制进去,并且df和du显示了占了存储空间,对吧?接下来,如果我们再次挂载一个文件系统到同一个挂载点看看,
root@icymoon_dev> sudo mount -o rw disk8M-2.image disk/
root@icymoon_dev> mount | grep icymoon
/home/icymoon/disk8M.image on /home/icymoon/disk type ext2 (rw,relatime)
/home/icymoon/disk8M-2.image on /home/icymoon/disk type ext2 (rw,relatime)
挂载成功,再检查一下文件大小吧
root@icymoon_dev> sudo du -hs /home/icymoon/disk
13K /home/icymoon/disk
root@icymoon_dev> df | head -n 1;df | grep icymoon
Filesystem 1K-blocks Used Available Use% Mounted on
/dev/loop1 7931 45 7886 1% /home/icymoon/disk
root@icymoon_dev> ls /home/icymoon/disk
lost+found
root@icymoon_dev>
啊啊啊,我的文件哪里去了?查一下上一级挂载点,就会发现空间被占用了,这就是真相了
root@icymoon_dev> df | grep home
/dev/sda3 17970663 11536594 5518904 68% /home ##这里可以看到使用空间增长哦
/dev/loop1 7931 45 7886 1% /home/icymoon/disk
如果,我反复往一个挂载点上挂载很多次?嘿嘿,你试试呀~每次du都只能看到最新挂载上来的设备使用情况,但df...咳咳
3.3 说点正事
通常生产环境常见的这个问题,并不是有人无聊的恶作剧,而是设置好的分区挂载出问题没挂载上(比如当时被挂载的盘坏了神马的),然后程序写到了挂载点所在目录下,再然后,挂载被人为或者程序恢复了······,一切隐藏得天(难)衣(以)无(追)缝(查),遇到这类情况,请大家回忆一下本篇讲的东西,真相,只有一个!~~
4 其他方法,替换df,lsof,du,ls······命令
这个就不多说了,想怎么改,就怎么改吧
PS:以上只供学习娱乐,如果被人揍了,或者玩飞了要从删库到跑路,别来找我,概不负责哈