2

我正在开发一个遗留 C++ 项目,该项目使用 blkid/blkid.h 中的函数来访问本地硬盘上的文件。

由于该项目相当大且难以编译/运行,我认为在容器中运行它是一个好主意。创建 dockerfile 来创建图像很顺利,问题是在容器中实际运行遗留项目时开始的。

尝试使用“ blkid_devno_to_devname ”访问磁盘上的文件以获取要写入的设备 ID 时出现错误。

这是一个重现我的问题的示例程序

#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <blkid/blkid.h>

int main() {
  struct stat st;
  std::string path = "my_file_path";
  if (stat(path.data(), &st))
  {
    std::cout << "cannot get file statistics for file " << path << std::endl;
  }
  char *device_path = blkid_devno_to_devname(st.st_dev);
  if(device_path == NULL)
  {
    std::cout << "cannot get device path for device ID " + std::to_string(st.st_dev) << std::endl;
  }
}

在我机器上的常规文件上,device_path 不为 null,但在 docker 上运行它总是返回 null。

我不清楚的是 docker 容器如何看到它写入的磁盘。

为了深入研究,我查看了 stat ( https://en.wikibooks.org/wiki/C_Programming/POSIX_Reference/sys/stat.h ) 附带的不同宏,我将它们打印在具有不同类型文件的容器上的文件上(符号链接、文件、目录)。

我修改了上面的小程序来添加这个:

  std::cout << "mode:" << st.st_mode << std::endl;
  std::cout << "S_ISREG:" << S_ISREG(st.st_mode) << std::endl;
  std::cout << "S_ISDIR:" << S_ISDIR(st.st_mode) << std::endl;
  std::cout << "S_ISCHR:" << S_ISCHR(st.st_mode) << std::endl;
  std::cout << "S_ISBLK:" << S_ISBLK(st.st_mode) << std::endl;
  std::cout << "S_ISFIFO:" << S_ISFIFO(st.st_mode) << std::endl;
  std::cout << "S_ISLNK:" << S_ISLNK(st.st_mode) << std::endl;
  std::cout << "S_ISSOCK:" << S_ISSOCK(st.st_mode) << std::endl;

我认为根据 docker 写入的图层类型会有所不同,但我没有看到任何内容。

无论是在卷上、挂载上,还是在容器层上(我的意思是既不是卷上也不是挂载上的文件)。

在安装时,我预计设备 ID 是正确的,因为据我了解,安装是让容器访问物理驱动器(至少在我的情况下 - 通常可能不是真的)。

那么为什么 blkid_devno_to_devname 没有在 docker 容器上返回任何内容呢?我没有正确理解什么?

PS 作为记录, blkid 或 /etc/fstab 也不会在容器上返回任何内容。

关于我的系统的读者注意事项:

  • 在安装了 ubuntu 18 的 Windows(Oracle VM)上的 VM 上工作。
  • 码头工人版本:19.03.6
  • 驱动程序:overlay2
4

0 回答 0