Я хотел бы написать драйвер блочного устройства Linux. Драйверу не потребуется доступ к оборудованию, поэтому он может находиться в пользовательском пространстве.
Для начала я попытался собрать пример драйвера блочного устройства с помощью этого Makefile:
obj-m = sbd.o
KVERSION = $(shell pwd)
PWD = $(shell pwd)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
Однако я получаю эти ошибки, которые я не знаю, как исправить. Вот стандартный вывод и стандартный вывод:
make -C /lib/modules/2.6.31-19-generic/build M=/home/andreas/sp/nivoa/src/driver/sbd modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.31-19-generic'
CC [M] /home/andreas/sp/nivoa/src/driver/sbd/sbd.o
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:72: error: expected ‘)’ before ‘*’ token
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:128: warning: initialization from incompatible pointer type
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c: In function ‘sbd_init’:
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: ‘sbd_request’ undeclared (first use in this function)
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: (Each undeclared identifier is reported only once
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:143: error: for each function it appears in.)
/home/andreas/sp/nivoa/src/driver/sbd/sbd.c:146: error: implicit declaration of function ‘blk_queue_hardsect_size’
make[2]: *** [/home/andreas/sp/nivoa/src/driver/sbd/sbd.o] Error 1
make[1]: *** [_module_/home/andreas/sp/nivoa/src/driver/sbd] Error 2
make[1]: Leaving directory `/usr/src/linux-headers-2.6.31-19-generic'
make: *** [all] Error 2
Любая помощь по этому вопросу будет принята с благодарностью.
Спасибо, Андреас
Ответ 1 · рейтинг 13 · MarkR
Не существует "официального" способа создания блочных драйверов в пользовательском пространстве, однако люди часто делают это, используя (ab) драйвер NBD для связи по петлевой сети с демоном, который слушает обычный сокет и говорит по протоколу NBD. См. документы NBD для получения дополнительной информации.
Ваш пример относится к блочному устройству режима ядра, которое необходимо собрать как модуль ядра. И поскольку внутреннее устройство ядра постоянно меняется, теперь оно, по-видимому, несовместимо.
Ответ 2 · рейтинг 7 · hillu
Следуя предложению MarkR, можно даже использовать протокол NBD через пару сокетов AF_UNIX, поэтому дополнительный локальный демон не требуется. Программа, реализующая этот протокол, должна будет настроить пару сокетов и разветвить дочерний элемент. И родитель, и потомок закрывают один конец пары сокетов. Один из них начинает принимать запросы на своем конце сокета, а другой подключает драйвер NBD к своему концу сокета.
Ответ 3 · рейтинг 4 · Ofir
Всегда смотрит на первую ошибку:
В вашем случае это похоже на проблему с включенными файлами, например. request_queue_t не определен.
Поскольку это устаревший тип, вы, вероятно, используете более новую версию linux/blkdev.h, чем в примере кода.
Попробуйте добавить typedef struct request_queue request_queue_t;
Ответ 4 · рейтинг 4 · schoppenhauer
Хотя использование NBD, как было предложено ранее, хорошо, возможно, лучший способ (используемый, например, virtualbox-fuse) - создать файловую систему FUSE, которая экспортирует один файл, который затем можно использовать через lossup.
Ответ 5 · рейтинг 1 · Rich
Вы можете использовать НБД. Используя nbdkit, вы даже можете писать виртуальные блочные устройства в скрипт оболочки или другие языки сценариев (однако придерживайтесь C, если хотите добиться максимальной производительности) . Я выступил с докладом на эту тему на FOSDEM 2019, где написал живую демонстрацию блочное устройство ядра Linux в сценарии оболочки.