Я работаю над устаревшим проектом 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