Смонтировать образ vfat win linux, используя C - PullRequest
1 голос
/ 18 февраля 2020

Я пытаюсь смонтировать образ диска vfat из DOS, используя. C

if( mount( "/mypath/disk.img", "/mypath/img/", "vfat", MS_DIRSYNC | MS_SYNCHRONOUS, "utf8" ) ) { 
  printf( "Error mount %s errno=%d %s\n", dst.c_str(), errno, strerror( errno ) );
}

Я все время получаю сообщение об ошибке "Требуется блочное устройство". Должен ли я добавить какой-либо параметр или флаг?

Примечание: я могу смонтировать из bash того же файла в той же цели без ошибок.

ОБНОВЛЕНИЕ: У меня был хороший результат, используя Функция для установки ISO. Когда я запускаю программу, она остается сложенной при вызове ioctl(loop_device_fd, LOOP_CLR_FD, 0);. Когда я выхожу из программы (ctrl- c), образ монтируется. Нужно ли LOOP_CLR_FD завершить все шаги? Кроме того, он монтируется только для чтения и, по-видимому, невозможно изменить его для чтения / записи.

const auto loop_control = std::fopen( "/dev/loop-control", "r" );
const auto loop_control_fd = fileno(loop_control);
const auto devnr = ioctl(loop_control_fd, LOOP_CTL_GET_FREE);
std::stringstream loopname;
loopname << "/dev/loop" << devnr;
const auto loop_device_name = loopname.str();
const auto loop_device = std::fopen(loop_device_name.c_str(), "r");
const auto loop_device_fd = fileno(loop_device);
const auto image = std::fopen( dst.c_str(), "r" );
const auto image_fd = fileno(image);
//Associate the loop device with the open file whose file descriptor is passed as the (third) ioctl(2) argument.
ioctl(loop_device_fd, LOOP_SET_FD, image_fd);
const auto result = mount(loop_device_name.c_str(), dst_path_img.c_str(), "vfat", MS_RDONLY, NULL);
if( result ) {
printf( "Error mount %s errno=%d %s\n", dst.c_str(), errno, strerror( errno ) );
return;
}
ioctl(loop_device_fd, LOOP_CLR_FD, 0);

Ответы [ 3 ]

1 голос
/ 18 февраля 2020

Поскольку образ диска на самом деле не является устройством, его нельзя подключить напрямую. То, что вы пытаетесь сделать, это монтировать через устройство oop. Эквивалент командной строки: mount /mypath/disk.img /mypath/img -t vfat -o loop

Я не уверен, но попробуйте решить проблему, добавив "loop, utf8" в качестве последнего параметра.

1 голос
/ 19 февраля 2020

Пример кода по приведенной выше ссылке, кажется, прекрасно монтирует ваш образ, с небольшими изменениями для извлечения свободного устройства l oop (я предполагаю, что это образ дискеты Dos3.3 с allbootdisks.com):

#include <sys/mount.h>
#include <linux/loop.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>

int main()
{
    int control_fd, file_fd, device_fd;
    char loop_device[16];

    control_fd = open("/dev/loop-control", O_RDWR);
    if (control_fd < 0) {
        perror("open loop control device failed");
        return 1;
    }

    int loop_id = ioctl(control_fd, LOOP_CTL_GET_FREE);
    sprintf(loop_device, "/dev/loop%d", loop_id);
    close(control_fd);

    printf("using loop device: %s\n", loop_device);

    file_fd = open("./Dos3.3.img", O_RDWR);
    if (file_fd < 0) {
        perror("open backing file failed");
        return 1;
    }

    device_fd = open(loop_device, O_RDWR);
    if (device_fd < 0) {
        perror("open loop device failed");
        close(file_fd);
        return 1;
    }

    if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) {
        perror("ioctl LOOP_SET_FD failed");
        close(file_fd);
        close(device_fd);
        return 1;
    }

    close(file_fd);

    if (mount(loop_device, "./mnt/", "vfat", MS_DIRSYNC | MS_SYNCHRONOUS, "") < 0) {
        perror("mount failed");
    } else {
        printf("mount successful\n");
    }

    // always free loop device in the end
    ioctl(device_fd, LOOP_CLR_FD, 0);      
    close(device_fd);
}
1 голос
/ 18 февраля 2020

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

Попробуйте устройство с обратной связью! Устройство обратной связи может дать вам ссылку на операционную систему на этот образ /mypath/disk.img как на блочное устройство. Вы можете создать петлевое устройство в bash примерно так:

# set up a block device
losetup -fP /mypath/disk.img
# now list the loopback devices 
losetup -a

В любом случае, это решение в bash, но, безусловно, есть библиотека где-то за c.

...