无法使用 32 位可执行文件(在 64 位 OS 上)以编程方式访问 EFS 文件
Cannot access EFS file programmatically with 32bits executable (on a 64bits OS)
我在 Amazon EFS 文件系统上以编程方式访问文件时遇到问题:同一个 C 程序可以使用 64 位可执行文件,但不能使用 32 位可执行文件。
挂载点是/EFS,下面的程序将同时列出EFS目录(/EFS/data)和本地目录(/home/centos):
这里是测试程序:
#include <stdio.h>
#include <dirent.h>
int main(void) {
struct dirent *d;
char efs_dir[] = "/EFS/data";
char local_dir[] = "/home/centos";
printf("EFS dir : %s\n",efs_dir);
DIR *dirEFS = opendir(efs_dir);
if (dirEFS == NULL) {
printf("Could not open current directory");
return 1;
}
while ((d = readdir(dirEFS)) != NULL)
printf("%s\n", d->d_name);
closedir(dirEFS);
printf("\nlocal filesystem dir : %s\n",local_dir);
DIR *dirLOCAL = opendir(local_dir);
if (dirLOCAL == NULL) {
printf("Could not open current directory");
return 1;
}
while ((d = readdir(dirLOCAL)) != NULL)
printf("%s\n", d->d_name);
closedir(dirLOCAL);
return 0;
}
Unix 视图:
[centos@ec2-instance ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p1 20G 3.4G 16G 19% /
tmpfs 3.7G 0 3.7G 0% /dev/shm
/dev/nvme1n1p1 94G 6.1G 83G 7% /opt/data
fs-XXXXXXXX.eu-west-3.amazonaws.com:/
8.0E 5.3G 8.0E 1% /EFS
[centos@ec2-instance ~]$]$ ls -l /EFS/data
-rw-r--r-- 1 centos centos 2796 Sep 15 12:18 efs_file1.txt
-rw-r--r-- 1 centos centos 2812 Sep 15 12:18 efs_file2.txt
-rw-r--r-- 1 centos centos 3625 Sep 15 12:18 efs_file3.txt
-rw-r--r-- 1 centos centos 2768 Sep 15 12:18 efs_file4.txt
[centos@ec2-instance ~]$]$ ls -l /home/centos
-rw-rw-r-- 1 centos centos 2796 Sep 15 14:15 local_file1.txt
-rw-rw-r-- 1 centos centos 2812 Sep 15 14:15 local_file2.txt
-rw-rw-r-- 1 centos centos 3625 Sep 15 14:15 local_file3.txt
-rw-rw-r-- 1 centos centos 2768 Sep 15 14:15 local_file4.txt
-rw-r--r-- 1 centos centos 792 Sep 15 14:21 test_dir.c
-rwxrwxr-x 1 centos centos 7392 Sep 15 14:22 test_dir
当我在 32 位兼容模式下编译 test_dir.c 时,EFS 目录没有结果:
[centos@ec2-instance ~]$ gcc test_dir.c -o test_dir -m32
[centos@ec2-instance ~]$ ./test_dir
EFS dir : /EFS/data
local filesystem dir : /home/centos
test_dir
.
..
local_file1.txt
local_file2.txt
local_file3.txt
local_file4.txt
test_dir.c
但是对于 64 位可执行文件来说没问题:
[centos@ec2-instance ~]$ gcc test_dir.c -o test_dir
[centos@ec2-instance ~]$ ./test_dir
EFS dir : /EFS/data
.
..
efs_file1.txt
efs_file2.txt
efs_file3.txt
efs_file4.txt
local filesystem dir : /home/centos
test_dir
.
..
local_file1.txt
local_file2.txt
local_file3.txt
local_file4.txt
test_dir.c
有人知道这里发生了什么吗?
谢谢。
编辑(解决方案):使用内核选项 nfs 将 64 位索引节点数压缩为 32 位。enable_ino64=0
[root@eai ~]# cat /etc/modprobe.d/nfs.conf
options nfs enable_ino64=0
[root@eai ~]# reboot
大功告成!谢谢 DNT.
函数readdir
returns一个索引节点。在您的 32 位构建中,它期望找到 32 位索引节点。但是对于具有 64 位 inode 的文件系统,如果特定的 inode 编号不能用 32 位表示,它将失败。
要查看 inode 编号,您可能需要使用 ls -li /EFS/data/efs_file1.txt
。最左边的数字是inode号,超过4294967295就是64bit,32bitreaddir
无法处理
我在 Amazon EFS 文件系统上以编程方式访问文件时遇到问题:同一个 C 程序可以使用 64 位可执行文件,但不能使用 32 位可执行文件。
挂载点是/EFS,下面的程序将同时列出EFS目录(/EFS/data)和本地目录(/home/centos):
这里是测试程序:
#include <stdio.h>
#include <dirent.h>
int main(void) {
struct dirent *d;
char efs_dir[] = "/EFS/data";
char local_dir[] = "/home/centos";
printf("EFS dir : %s\n",efs_dir);
DIR *dirEFS = opendir(efs_dir);
if (dirEFS == NULL) {
printf("Could not open current directory");
return 1;
}
while ((d = readdir(dirEFS)) != NULL)
printf("%s\n", d->d_name);
closedir(dirEFS);
printf("\nlocal filesystem dir : %s\n",local_dir);
DIR *dirLOCAL = opendir(local_dir);
if (dirLOCAL == NULL) {
printf("Could not open current directory");
return 1;
}
while ((d = readdir(dirLOCAL)) != NULL)
printf("%s\n", d->d_name);
closedir(dirLOCAL);
return 0;
}
Unix 视图:
[centos@ec2-instance ~]$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/nvme0n1p1 20G 3.4G 16G 19% /
tmpfs 3.7G 0 3.7G 0% /dev/shm
/dev/nvme1n1p1 94G 6.1G 83G 7% /opt/data
fs-XXXXXXXX.eu-west-3.amazonaws.com:/
8.0E 5.3G 8.0E 1% /EFS
[centos@ec2-instance ~]$]$ ls -l /EFS/data
-rw-r--r-- 1 centos centos 2796 Sep 15 12:18 efs_file1.txt
-rw-r--r-- 1 centos centos 2812 Sep 15 12:18 efs_file2.txt
-rw-r--r-- 1 centos centos 3625 Sep 15 12:18 efs_file3.txt
-rw-r--r-- 1 centos centos 2768 Sep 15 12:18 efs_file4.txt
[centos@ec2-instance ~]$]$ ls -l /home/centos
-rw-rw-r-- 1 centos centos 2796 Sep 15 14:15 local_file1.txt
-rw-rw-r-- 1 centos centos 2812 Sep 15 14:15 local_file2.txt
-rw-rw-r-- 1 centos centos 3625 Sep 15 14:15 local_file3.txt
-rw-rw-r-- 1 centos centos 2768 Sep 15 14:15 local_file4.txt
-rw-r--r-- 1 centos centos 792 Sep 15 14:21 test_dir.c
-rwxrwxr-x 1 centos centos 7392 Sep 15 14:22 test_dir
当我在 32 位兼容模式下编译 test_dir.c 时,EFS 目录没有结果:
[centos@ec2-instance ~]$ gcc test_dir.c -o test_dir -m32
[centos@ec2-instance ~]$ ./test_dir
EFS dir : /EFS/data
local filesystem dir : /home/centos
test_dir
.
..
local_file1.txt
local_file2.txt
local_file3.txt
local_file4.txt
test_dir.c
但是对于 64 位可执行文件来说没问题:
[centos@ec2-instance ~]$ gcc test_dir.c -o test_dir
[centos@ec2-instance ~]$ ./test_dir
EFS dir : /EFS/data
.
..
efs_file1.txt
efs_file2.txt
efs_file3.txt
efs_file4.txt
local filesystem dir : /home/centos
test_dir
.
..
local_file1.txt
local_file2.txt
local_file3.txt
local_file4.txt
test_dir.c
有人知道这里发生了什么吗? 谢谢。
编辑(解决方案):使用内核选项 nfs 将 64 位索引节点数压缩为 32 位。enable_ino64=0
[root@eai ~]# cat /etc/modprobe.d/nfs.conf
options nfs enable_ino64=0
[root@eai ~]# reboot
大功告成!谢谢 DNT.
函数readdir
returns一个索引节点。在您的 32 位构建中,它期望找到 32 位索引节点。但是对于具有 64 位 inode 的文件系统,如果特定的 inode 编号不能用 32 位表示,它将失败。
要查看 inode 编号,您可能需要使用 ls -li /EFS/data/efs_file1.txt
。最左边的数字是inode号,超过4294967295就是64bit,32bitreaddir
无法处理