简介:我想从用户空间获取Linux(或至少是ext4)文件的生成编号(
我正在尝试编写一个双向文件同步程序(也称为Unison),但没有中央数据库(很容易,只需在同步根中存储数据)并保留文件移动(如果要支持所有怪异情况(例如将文件移出随后被删除的目录),则非常难以正确处理)。
有一种方法可以唯一地识别文件,这将极大地简化事情。我知道如何通过
我已经阅读了有关NFS使用“生成编号”来唯一标识文件的文章。在NFS中,(
我还没有成功地获取到这个数字。这份ext4文档似乎表明可以从一个ext4文件系统中获取这个数字,但是我无法从用户空间获取它(我不会在内核空间运行这个简单的程序)。请参见
i_generation
)。或者,作为替代方案,获取“出生时间”(文件创建时间)。我正在尝试编写一个双向文件同步程序(也称为Unison),但没有中央数据库(很容易,只需在同步根中存储数据)并保留文件移动(如果要支持所有怪异情况(例如将文件移出随后被删除的目录),则非常难以正确处理)。
有一种方法可以唯一地识别文件,这将极大地简化事情。我知道如何通过
stat
获得inode和设备号,但由于inode可能会被重用(我自己见过这种情况),因此我想使用更稳定的唯一标识。我已经阅读了有关NFS使用“生成编号”来唯一标识文件的文章。在NFS中,(
st_ino
,i_generation
)组合用于唯一标识文件句柄,跨重启和服务器崩溃(或至少防止重复使用相同的文件句柄导致可能的数据损坏)。我还没有成功地获取到这个数字。这份ext4文档似乎表明可以从一个ext4文件系统中获取这个数字,但是我无法从用户空间获取它(我不会在内核空间运行这个简单的程序)。请参见
EXT4_IOC_GETVERSION
。我在我的系统(LMDE,Debian测试版)中找不到适当的头文件。我找到了两个选项:
- 尝试使用内核中的一个 - 失败并显示不应该从用户空间使用。
- 尝试在
<linux/ext2_fs.h>
中使用EXT2_IOC_GETVERSION
- 返回EBADF
(errno
9)。也许是因为我正在尝试从EXT4文件系统获取EXT2信息?或者可能是我在使用ioctl
时做错了什么,这是我第一次尝试使用它。文件已经正确打开,因为在我的情况下,open
调用返回3(应该是有效的)。
代码如下:
#include <sys/ioctl.h>
#include <sys/fcntl.h>
#include <linux/ext2_fs.h>
#include <stdio.h>
#include <errno.h>
int main () {
int fileno = open("generation.c", O_RDONLY);
printf("fileno: %d\n", fileno);
int generation = 0;
if (ioctl(EXT2_IOC_GETVERSION, fileno, &generation)) {
printf("errno: %d\n", errno);
}
printf("generation: %d\n", generation);
}
这段代码在Ubuntu 12.04上报错(errno=9),在LMDE(Debian Testing)上编译时会出现编译错误(EXT2_IOC_GETVERSION
未找到)。
另一种方法是获取文件的创建时间(crtime
或btime
/birth time),但我所有的谷歌搜索结果都表明在Linux的用户空间中似乎无法获取此信息(IIRC FreeBSD有一个系统调用可以实现)。我更喜欢使用crtime
,因为crtime
可能比生成号码更具可移植性(到Windows)。
我知道这将依赖于系统。当找不到唯一的inode(或者在USB闪存上常见的FAT中根本没有inode)时,我希望有一个后备方案。
inotify
不是一个选项。它是一个程序,在文件被修改后同步文件,类似于rsync单向同步。而不像Dropbox那样在后台监视文件变化。
如果没有办法获取这些数字,我也会接受这个答案(当然需要适当的文档支持) :)