我不知道为什么这段代码不能在 NFS4 下运行,使用 NFS3 可以完美运行。这个想法是避免在进程仍在读取文件时写入文件。
我想调试,但我们的系统管理员无法调试。这可能是原因。在我们的 NFS4 安装下,我总是会遇到这种情况
if ( flock(fp,LOCK_EX) == -1)
printf("Error: file %s is already locked\n", fileName);
整个程序是:
#include <sys/file.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char **argv){
if (argc<2){
printf("Usage:\n a.out fileName\n");
return 1;
}
char *fileName=argv[1];
int fp;
/* block the file, I know a process can write
rendering my information useless*/
fp=open(fileName,O_RDONLY);
if ( flock(fp,LOCK_EX) == -1){
printf("Error: file %s is already locked\n", fileName);
}
else{
printf("OK: file %s was locked\n",fileName );
}
/* read and parse the fileName
another process should not be able to write or
modify the fileName while I am reading it
*/
return 0;
}
编辑:我想澄清一下。这是我正在使用的代码片段。fileName 应该是一个有效的现有文件
我正在阅读文件名并制作副本,编辑一些部分。我知道,当我这样做时,外部进程可以更新文件名。我想使用信号量来避免修改这个文件,直到我完成它。该程序运行良好,直到停止这样做。唯一的区别是文件名所在的文件系统。它从 NFS3 更新到 NFS4。甚至操作系统 (SLE15.2) 与内核 5.3.18 相同,并且使用 strerror(errno) 在 NFS4 上产生 seg 错误。我做 print("%d",error) 时的唯一提示是 9 应该是“错误的文件描述符”
谢谢你的帮助
朱莉娅
这部分代码:
真的只能告诉你锁失败或成功,而不是为什么。您应该更改它以报告
errno
失败的原因,因为它可能表明您的锁定存在更基本的问题 - 例如尝试打开您无权访问或不存在的文件。您可能还希望包含
errno.h
在包含列表中,以确保您找到正确的变量。我刚刚检查了flock的联机帮助页,在NOTES部分是重要的部分:
您只是打开文件进行读取,这就是群调用失败的原因。
NFS v3 在协议级别没有锁定支持。该功能由附加的(nfs 协议外部的)锁管理器提供。另一方面,NFS v4 将锁定作为规范的一部分。此外,有两种类型的锁。一是字节范围锁,二是访问共享。尽管后一种是您正在寻找的,但 POSIX API 没有公开它,因此不适用于 linux 和 unix。
要使锁定与 nfs v4 和 v3 一起使用,您需要使用可用作fcntl或lockf函数的字节范围锁定。
检查 nfs 开发人员(包括我自己)使用的锁定测试代码,以验证独立于协议版本的客户端/服务器行为。
http://git.linux-nfs.org/?p=steved/cthon04.git;a=blob;f=lock/tlock.c;h=8c837a87976d17c58a25c9bd08d9f935e4521402;hb=HEAD#l835