最近再一次使用到文件锁flock,会使用只是基本技能,那么flock到底是怎么实现的呢?具体原理又是怎样的呢?和以往一样套路-分析源码!
Linux文件锁flock对应的源码是util-linux,git地址https://github.com/karelzak/util-linux
下载下来编译:
./ autogen.sh
./configure
make
编译后在当前目录可以看到生成对应的flock二进制文件。当然还包括其他的二进制,例如dmesg、lscpu、umount、mount等等。
和以往套路一样,gdb 单步走起
前面都是一些参数解析操作,所以我们直接b 279行,到flock的系统调用。
fd就是打开文件/tmp/.flock.lock对应的文件描述符;type默认是排它锁(LOCK_EX),block默认是阻塞式(0)。
Linux系统调用flock我们待会儿再详细分析。
由于默认是阻塞式的,因此如果有进程已经占用了这个文件锁,则flock会一直卡在获取锁。如果进程获取到了文件锁,则不会执行while循环体。继续往下执行
上面已经分析完flock的逻辑,下面重点分析下linux系统调用flock的实现。(注意:linux下文件锁flock是util-linux的系统工具,而下面要介绍的flock是linux的系统调用,文件锁flock是通过系统调用flock实现功能的)
flock系统调用定义在fs/locks.c文件中
从gdb可以看到,fd=7,type=2,block=0。因此flock系统调用参数fd=7,cmd=2
flock对应的lock类型:
flock_make_lock()函数定义:
由于参数fl是NULL,因此会调用locks_alloc_lock()函数分配file_lock,locks_alloc_lock()调用locks_init_lock_heads()对file_lock进行初始化。
看下file_lock的结构已经核心字段的意思。
flock定义在fs/fuse/file.c文件中(具体根据文件系统类型)
看下fuse_file_flock()函数实现: 看下locks_lock_file_wait()函数,主要是等获取锁。
如果锁被占用,则flock_lock_inode_wait()就会循环等待获取锁。