通过文件路径获取设备物理块大小失败:ioctl调用报不恰当设备错误
解决通过挂载点调用BLKPBSZGET ioctl失败的问题
问题原因
BLKPBSZGET 是块设备专属的ioctl命令,仅能作用于块设备节点(如 /dev/sdc)的文件描述符。你打开的是挂载点目录 /tmp,该文件描述符对应的是文件系统层对象,而非底层块设备,因此这类针对块设备的ioctl不被支持,触发 Inappropriate ioctl for device 错误。
解决方案
要获取挂载点对应设备的物理块大小,需先找到挂载点关联的块设备路径,再打开该块设备文件执行ioctl。
步骤1:获取挂载点对应的块设备路径
可通过解析 /proc/mounts 文件实现,该文件记录了系统所有挂载信息,从中匹配挂载点字段即可得到对应块设备路径。
步骤2:修正后的代码实现
以下代码先解析 /proc/mounts 找到块设备,再打开设备执行 BLKPBSZGET:
#include <stdlib.h> #include <stdio.h> #include <fcntl.h> #include <linux/fs.h> #include <sys/ioctl.h> #include <string.h> #include <errno.h> #include <unistd.h> // 从/proc/mounts中提取挂载点对应的块设备路径 int get_block_device_for_mount(const char *mount_point, char *dev_path, size_t dev_path_len) { FILE *fp = fopen("/proc/mounts", "r"); if (!fp) { fprintf(stderr, "Failed to open /proc/mounts: %s\n", strerror(errno)); return -1; } char line[1024]; while (fgets(line, sizeof(line), fp)) { char dev[256], mount[256]; // 解析每行:设备路径 挂载点 其余字段 if (sscanf(line, "%255s %255s", dev, mount) != 2) { continue; } // 匹配目标挂载点 if (strcmp(mount, mount_point) == 0) { strncpy(dev_path, dev, dev_path_len - 1); dev_path[dev_path_len - 1] = '\0'; fclose(fp); return 0; } } fprintf(stderr, "No block device found for mount point: %s\n", mount_point); fclose(fp); return -1; } int main() { const char *mount_point = "/tmp"; char dev_path[256]; // 获取块设备路径 if (get_block_device_for_mount(mount_point, dev_path, sizeof(dev_path)) != 0) { return EXIT_FAILURE; } // 打开块设备文件(需root权限,执行时加sudo) const int fd = open(dev_path, O_RDONLY); if (fd == -1) { fprintf(stderr, "Failed to open block device %s: %s\n", dev_path, strerror(errno)); return EXIT_FAILURE; } unsigned long pbsz = 0; if (ioctl(fd, BLKPBSZGET, &pbsz) == -1) { fprintf(stderr, "ioctl BLKPBSZGET failed: %s\n", strerror(errno)); close(fd); return EXIT_FAILURE; } printf("Physical block size for %s (mounted at %s): %lu\n", dev_path, mount_point, pbsz); close(fd); return EXIT_SUCCESS; }
注意事项
- 执行程序时需要root权限(前缀加
sudo),因为块设备文件通常仅对root开放访问权限。 - 若挂载点为绑定挂载、tmpfs等特殊类型,需根据场景调整解析逻辑,常规磁盘挂载场景下上述代码可正常工作。
内容的提问来源于stack exchange,提问作者Harry
相关产品推荐
相关产品推荐

