这可能有点深奥,但是我有一个奇怪的与stat()的问题。
特别是 – 在Linux系统上安装了Isilon存储NFS。 我有一个在同一个文件上运行fstat时获得时间差的进程。
我可以使用一点C来重现这一点,它没有比open-write-stat-close更复杂; 开放-STATclosures
这两个数字偶尔会有几个毫秒的差别 – 一个文件可能会比实际上显得“老”。
我不清楚“stat”是从主机还是从服务器读取时间。 而且我也不清楚问题是否与Isilon有关(尽pipe在NetApp存储上似乎没有发生这种情况)。
任何人都可以给我一点洞察可能会发生什么?
举个例子:
time mismatch: 1468936451.862865611 != 1468936451.860183107
第一个是文件句柄打开时读取的时间。 第二个是closures(和fsync )后读取的时间。
正如你所看到的那样 – 文件在服务器上比在客户端上老一些。
C来testing这个是:
#include <stdio.h> #include <stdlib.h> #include <fcntl.h> #include <unistd.h> #include <sys/stat.h> #include <sys/types.h> int main () { while (1) { struct stat sb[2]; /* * Open file */ int fd = open ("test.dat", O_CREAT | O_RDWR | O_APPEND, 0644); if (fd < 0) { perror ("failed to open file (1)"); return EXIT_FAILURE; } /* * Write to it */ write (fd, "", 1); /* * Ensure it's sync'd to disk */ if (fsync (fd) < 0) { perror ("failed to fsync file"); return EXIT_FAILURE; } /* * Stat the file */ if (fstat (fd, &(sb[0])) < 0) { perror ("failed to fstat file (1)"); return EXIT_FAILURE; } /* * Close it */ close (fd); /* * Open file */ fd = open ("test.dat", O_RDONLY); if (fd < 0) { perror ("failed to open file (2)"); return EXIT_FAILURE; } /* * Stat it again */ if (fstat (fd, &(sb[1])) < 0) { perror ("failed to fstat file (2)"); return EXIT_FAILURE; } /* * Close it */ close (fd); /* * Check the times match */ if (sb[0].st_mtime != sb[1].st_mtime || sb[0].st_mtim.tv_nsec !=sb[1].st_mtim.tv_nsec) { printf ("time mismatch: %d.%09ld != %d.%09ld\n", (int)(sb[0].st_mtime), sb[0].st_mtim.tv_nsec, (int)(sb[1].st_mtime), sb[1].st_mtim.tv_nsec); } } }
你可以通过在NFS挂载中运行它来触发它,然后从另一个系统调用'stat'(shell命令是好的)。 例如在isilon本身:
while true do stat test.dat done
这让我错误如:
time mismatch: 1468936613.313045037 != 1468936613.310174576 time mismatch: 1468936613.547768543 != 1468936613.544878047 time mismatch: 1468936615.228495345 != 1468936615.225862947 time mismatch: 1468936619.036053897 != 1468936619.033362349 time mismatch: 1468936619.988151772 != 1468936619.985529620 time mismatch: 1468936664.541226541 != 1468936664.538549678 time mismatch: 1468936666.165674866 != 1468936666.163171366 time mismatch: 1468936666.787528027 != 1468936666.784797051 time mismatch: 1468936711.334376729 != 1468936711.331868927
而且…我不认为应该。
编辑:
情节变厚了 – 运行上面的内容并捕获数据包时,来自服务器的NFS GETATTR调用的响应不一致。 我得到两个不同的时间戳。
挂载选项似乎没有什么区别 – 但我们尝试设置noac和actimeo=0 , sync lookupcache=none等。
我们的isilon节点都是ntp-synced到相同的来源。 像往常一样,他们之间有一个小的漂移。
我们发现我们可以采用isi export modify --zone <zoneid> <exportnumber> --time-delta 1的forms应用一个解决方法 – isi export modify --zone <zoneid> <exportnumber> --time-delta 1
这将时间戳的分辨率设置为1秒而不是1ns。 然而,尽pipe减less了发生问题的频率,但它仍然会发生 – 只是不那么频繁,因为它只发生在“1s”边界。