ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

statvfs系统调用失败,错误为定义的数据类型,值太大

2019-10-26 12:50:31  阅读:385  来源: 互联网

标签:system-calls glibc filesystems c-3 linux


我的服务器上安装了Red Hat Enterprise Linux Server 6.6(2.6.32-504.el6.x86_64),并且具有以下分区层次结构.

Filesystem      Size  Used Avail Use% Mounted on
/dev/sda2       7.9G  1.7G  5.9G  22% /
tmpfs           5.4G  8.0K  5.4G   1% /dev/shm
/dev/sda8        53G  1.4G   49G   3% /mysql/data
/dev/sda6       7.9G  4.5G  3.1G  60% /usr/BWhttpd
/dev/sda4        32G  989M   29G   4% /var
/dev/sdb1        25T   37M   25T   1% /media1
/dev/sdc1        25T   37M   25T   1% /media2
/dev/sdd1        25T   37M   25T   1% /media3
/dev/sde1        22T   21T  1.1T  95% /media4

我在每个上发出statvfs调用

/mediax

分区,但系统调用失败,错误为定义的数据类型,值太大.

我能够找到系统调用返回的错误EOVERFLOW,但不确定struct statvfs的哪个成员导致此错误.

它是否需要对/ mediax分区的大小做任何事情.

Note: Partitions are of xfs file system type.

解决方法:

man 2 statfs手册页所述:

The original Linux statfs() and fstatfs() system calls were not designed with extremely large file sizes in mind. Subsequently, Linux 2.6 added new statfs64() and fstatfs64() system calls that employ a new structure, statfs64. The new structure contains the same fields as the original statfs structure, but the sizes of various fields are increased, to accommodate large file sizes. The glibc statfs() and fstatfs() wrapper functions transparently deal with the kernel differences.

在您的情况下,由于某种原因,您正在使用非64位版本的syscall.

Linux内核使用四个不同的系统调用(以及可选的兼容版本)实现fstat * fs *()和stat * fs *()库调用:fstatfs(),fstatfs64(),statfs()和statfs64().所有这四个都在内核源代码中的fs/statfs.c中定义,并使用内核内部函数vfs_statfs()将必要的信息收集到struct kstatfs结构中.

statfs()和fstatfs()都使用内核内部函数do_statfs_native()(在fs/statfs.c中)将字段从内核结构kstatfs复制到用户空间结构statfs缓冲区.问题是,许多内核结构字段都大于用户空间缓冲区中的字段. do_statfs_native()验证值是否适合,否则,将返回-EOVERFLOW.

这是我发现的唯一一种情况,它可能导致四个syscall中的任何一个返回-EOVERFLOW.

对于statfs64()和fstatfs64(),内核函数do_statfs64()用于将字段从内核内部结构kstatfs复制到用户空间结构statfs64缓冲区.用户空间缓冲区字段至少与内核结构字段一样大,因此没有溢出的风险. (该函数从不返回-EOVERFLOW.)

解决方法是确保您使用struct statfs的64位版本以及相应的syscall.

为了确保glibc使用正确的结构版本(可以正确描述非常大的文件系统的版本),请确保您拥有

#define _FILE_OFFSET_BITS 64

在任何#includes之前;或者,将-D_FILE_OFFSET_BITS = 64添加到您的编译器标志中.

所有这一切都是为了确保glibc知道您正在Linux 2.6或更高版本的内核(3.x,4.x等)上运行,并且一定要尝试正确使用结构的版本-大小的字段.

或者,您可以定义_LARGEFILE64_SOURCE,以在系统调用周围公开struct statfs64和struct statvfs64类型以及相应的statfs64()和statvfs64()包装器.这样可以避免让glibc做任何猜测,并确保您使用可以正确描述所有Linux文件系统大小的syscall版本.

这两个选项都适用于所有32位和64位Linux体系结构.

标签:system-calls,glibc,filesystems,c-3,linux
来源: https://codeday.me/bug/20191026/1936737.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有