LINUX.ORG.RU

Как из блочного устройства сделать обычный файл?

 , , , ,


1

2

Есть блочное устройство энергонезависимой памяти крохотного объёма. Программа отказывается работать с ним, но нормально работает с обычным файлом. Создавать на устройстве ФС как-то расточительно. У меня получилось создать ФС (FAT12) лишь с 1.5-килобайтным заголовком (echo | mkfs.fat -a -b0 -f1 -F12 -r16 -h0 -R1 --mbr=n -n "" -m - -s1 /dev/loop0, например). А хотелось бы совсем без оверхеда.

Второй вариант — написать простенький драйвер FUSE. В принципе, он уже есть и, вероятно, даже заработает, но может быть есть какой-то более простой и распространённый способ как это можно было бы сделать?

Ответ на: комментарий от anonymous

Программа проприетарная. Почему она отказывается, я не знаю. Можно было бы strace на неё натравить, но пока не успел. Пишет ошибку, мол, не могу ни прочитать ни записать. Но если подсунуть ей обычный файл, то всё прекрасно пишет и читает.

stabilitron
() автор топика
Ответ на: комментарий от Vidrele

Попробую. Хотя тоже есть сомнения. Пробовал так, кстати:

mount --bind /dev/mtdblock0 file

file, естественно, тоже видится в системе блочным устройством и прога его тоже не воспринимает.

stabilitron
() автор топика

Не понятно как это будет использоваться, зачем это «блочное устройство энергонезависимой памяти крохотного объёма»?

Самый простой вариант это копия блочного устройств в виде файла, программа работает с файлом-копией, периодическая синхронизация с блочным устройством

futurama ★★★★★
()
Ответ на: комментарий от VIT

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

К слову, программа может не работать с устройством из-за прав доступа. Насколько я помню, для сырого доступа обычно нужен рут.

Vidrele ★★★★★
()
Ответ на: комментарий от futurama

В этой памяти хранятся всякие настройки, часто изменяемые значения, которые должны переживать перезагрузку. Они не могут находиться во флеш-памяти, так как могут перезаписываться по 100 раз в секунду.

stabilitron
() автор топика
Ответ на: комментарий от stabilitron

Я всё ещё не понимаю твоей аппаратной ситуации.

Что мешает программе работать с обычным файлов хоть на диске, хоть на РАМДИСКЕ. Чтобы этот файл пережил перезагрузку копировать его на блочное устройство поблочно без ФС (dd)

futurama ★★★★★
()
Ответ на: комментарий от futurama

Товарищ конечно тот еще партизанин, но по-видимому он хочет поставить и забыть, а так придется вручную копии делать или автомат какой-то колхозить.

VIT ★★
()
Ответ на: комментарий от Vidrele

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

Нет, losetup создаёт именно устройство. Даже если ты как-то заставишь его создать dev-файл вне его штатного пути в /dev/, он всё равно останется файлом блочного устройства. Устройство вместо файла подать на вход может быть и можно, но пользы автору от этого не будет.

firkax ★★★★★
()
Ответ на: комментарий от madcore

Хороший вопрос, кстати! Если делать свой велосипед, то придётся как-то реализовывать атомарность записи. В каком формате прога пишет данные — неизвестно, в каком-то своём проприетарном, видимо. Возможно, что эта атомарность уже в ней реализована и если я полезу туда со своими костылями, то только напортачу.

stabilitron
() автор топика
Ответ на: комментарий от stabilitron

С блочным устройством ты вынужден работать с выравнивание 512 байт. С символьным это ограничение снимается. Поэтому делай как тебе подсказано - натягивай символьный raw поверх блочного и потом это символьное отдавай приложению.

no-dashi-v2 ★★★★
()
Ответ на: комментарий от madcore

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

futurama ★★★★★
()
Ответ на: комментарий от VIT

Поглядел strace-ом вызовы. После успешного открытия файла (или устройства), программа вызывает ftruncte() и если успех, то вызывает mmap() на этот файл. То есть ни блочное, ни символьное устройства не подходят, также не подходят ни ссылки на ни, ни бинд-маунты. Только обычные файлы, к сожалению. Даже когда монтирую через свой FUSE-драйвер с опцией direct_io, то тоже не проканывает, из-за того, что mmap() не дружит с direct_io, насколько я понял.

stabilitron
() автор топика
Ответ на: комментарий от madcore

Примерно так:

static struct fuse_operations retain_operations = {
    .getattr    = my_getattr,
    .readdir    = my_readdir,
    .open       = my_open,
    .release    = my_release,
    .read       = my_read,
    .write      = my_write,
    .truncate   = my_truncate,
    .fsync      = my_fsync,
};

С реализацией указанных функций, для работы с блочным устройством. Например:

static int my_readdir(const char *path, void *buf, fuse_fill_dir_t filler,
                         off_t offset, struct fuse_file_info *fi)
{
    (void) offset;
    (void) fi;
    
    if (strcmp(path, "/") != 0)
        return -ENOENT;
    
    filler(buf, ".", NULL, 0);
    filler(buf, "..", NULL, 0);
    filler(buf, "myfile" + 1, NULL, 0);
    
    return 0;
}

После монтирования (./myfuse /path/to/mountpoint) появляется myfile, на который я и натравливаю программу.

stabilitron
() автор топика
Ответ на: комментарий от VIT

можно просто назвать очередной упоротый небоскрёб из костылей «абстракцией», «парадигмой» «бест практисес» или «так нагляднее и читаемее» и всё вмиг станет по феншую

anonymous
()