前两天一个朋友打电话聊到他遇到的问题:自己动手写的日志备份脚本有问题,当移走日志文件后,应用程序不再写日志到新的文件中,kill 掉应用后才可以..
他的脚本可能是这样的:
mv /log/a_log.trace /log_bak/a_log.trace_xyz touch /log/a_log.trace
相信各位大拿肯定已经知道原因,但是我还在这里说说,为那些可能想知道原因的小童鞋。
那么,弄清楚open函数或者sys_open系统调用,知道文件描述符,即使你没有写过C代码,也知道原因了吧!
文件已经被你mv走了,可以原应用还在运行,仍旧保留着原文件的文件描述符,可是文件其实已经不存在了...
解决办法:不要删除或者移走日志文件,清空这个文件就可以了!
cp -p /log/a_log.trace /log_bak/a_log.trace_xyz cp /dev/null /log/a_log.trace
再来深入一下吧:
什么是虚拟文件系统?
VFS(Virtual File System)是 Linux 内核中的一个软件抽象层。它通过一些数据结构及其方法向实际的文件系统如 ext2,vfat 提供接口机制。在其下是实体的文件系统。虚拟文件系统的主要功用,在于让上层的软件,能够用单一的方式,来跟底层不同的文件系统沟通。在操作系统与之下的各种文件系统之间,虚拟文件系统提供了标准的操作接口,让操作系统能够很快的支持新的文件系统。
一切皆是文件!
一组在逻辑上具有完整意义的信息项的系列。除了普通文件,其他诸如目录、设备、套接字等 也以文件被对待。总之,“一切皆文件”。
文件对象
文件对象是已打开的文件在内存中的表示,主要用于建立进程和磁盘上的文件的对应关系。它由sys_open() 现场创建,由sys_close()销毁。文件对象和物理文件的关系有点像进程和程序的关系一样。当我们站在用户空间来看 待VFS,我们像是只需与文件对象打交道,而无须关心超级块,索引节点或目录项。因为多个进程可以同时打开和操作 同一个文件,所以同一个文件也可能存在多个对应的文件对象。文件对象仅仅在进程观点上代表已经打开的文件,它 反过来指向目录项对象(反过来指向索引节点)。一个文件对应的文件对象可能不是惟一的,但是其对应的索引节点和 目录项对象无疑是惟一的。
struct file { …… struct list_head f_list; /*文件对象链表*/ struct dentry *f_dentry; /*相关目录项对象*/ struct vfsmount *f_vfsmnt; /*相关的安装文件系统*/ struct file_operations *f_op; /*文件操作表*/ …… };