блкид на docker контейнер - PullRequest
2 голосов
/ 05 мая 2020

Я работаю над устаревшим проектом C ++, который использует функции из blkid / blkid.h для доступа к файлам на локальном жестком диске.

Поскольку проект довольно большой и его сложно скомпилировать / запустить, я подумал было бы неплохо запустить его в контейнере. Создание файла докеров для создания образов прошло нормально, проблемы начались при фактическом запуске устаревшего проекта в контейнере.

Я получаю ошибки при попытке доступа к файлам на диске с помощью « blkid_devno_to_devname » чтобы получить идентификатор устройства для записи.

Вот пример программы, которая воспроизводит мою проблему

#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 записывает, но я не вижу никакой.

Будь то на том, монтировать или даже на c на уровне ontainer (я имею в виду файлы ни на томе, ни при монтировании).

При монтировании я ожидал, что идентификатор устройства будет правильным, поскольку, как я понимаю, монтирование дает контейнеру доступ к физическому диск (по крайней мере, в моем случае - может быть не совсем так).

Так почему же blkid_devno_to_devname ничего не возвращает в контейнере docker? Что я неправильно понимаю?

PS для записи, blkid или / etc / fstab тоже ничего не возвращает в контейнере.

Заметки для читателей о моей системе :

  • работа на виртуальной машине на windows (Oracle VM) с установленным ubuntu 18.
  • docker версия: 19.03.6
  • Драйвер: overlay2
...