Пишем простой модуль ядра Linux. Jdoc:include - метод отображения контента на странице

После того, как репозиторий клонирован с гитхаба, ввожу npm install для установки зависимостей и терплю фейл. Вот листинг процесса:
bimbatron:bem bimba$ npm install > [email protected] postinstall /Users/bimba/BEM > npm run deps > [email protected] deps /Users/bimba/BEM > bower i --allow-root bower EACCES EACCES: permission denied, mkdir "/Users/bimba/.cache/bower/registry/bower.herokuapp.com" Stack trace: Error: EACCES: permission denied, mkdir "/Users/bimba/.cache/bower/registry/bower.herokuapp.com" at Error (native) at Object.fs.mkdirSync (fs.js:922:18) at sync (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/node_modules/mkdirp/index.js:55:12) at Function.sync (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/node_modules/mkdirp/index.js:61:24) at new Cache (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/lib/util/Cache.js:21:16) at RegistryClient. (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/lib/lookup.js:162:35) at Array.forEach (native) at RegistryClient.initCache (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/lib/lookup.js:149:34) at RegistryClient._initCache (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/Client.js:65:27) at new RegistryClient (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-registry-client/Client.js:19:10) Console trace: Error at StandardRenderer.error (/Users/bimba/BEM/node_modules/bower/lib/renderers/StandardRenderer.js:81:37) at Logger. (/Users/bimba/BEM/node_modules/bower/lib/bin/bower.js:110:26) at emitOne (events.js:96:13) at Logger.emit (events.js:188:7) at Logger.emit (/Users/bimba/BEM/node_modules/bower/lib/node_modules/bower-logger/lib/Logger.js:29:39) at /Users/bimba/BEM/node_modules/bower/lib/commands/index.js:48:20 at _rejected (/Users/bimba/BEM/node_modules/bower/lib/node_modules/q/q.js:844:24) at /Users/bimba/BEM/node_modules/bower/lib/node_modules/q/q.js:870:30 at Promise.when (/Users/bimba/BEM/node_modules/bower/lib/node_modules/q/q.js:1122:31) at Promise.promise.promiseDispatch (/Users/bimba/BEM/node_modules/bower/lib/node_modules/q/q.js:788:41) System info: Bower version: 1.7.9 Node version: 6.9.1 OS: Darwin 15.6.0 x64 npm ERR! Darwin 15.6.0 npm ERR! argv "/Users/bimba/.nvm/versions/node/v6.9.1/bin/node" "/Users/bimba/.nvm/versions/node/v6.9.1/bin/npm" "run" "deps" npm ERR! node v6.9.1 npm ERR! npm v3.10.8 npm ERR! code ELIFECYCLE npm ERR! [email protected] deps: `bower i --allow-root` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] deps script "bower i --allow-root". npm ERR! Make sure you have the latest version of node.js and npm installed. npm ERR! If you do, this is most likely a problem with the bem-project-stub package, npm ERR! not with npm itself. npm ERR! Tell the author that this fails on your system: npm ERR! bower i --allow-root npm ERR! You can get information on how to open an issue for this project with: npm ERR! npm bugs bem-project-stub npm ERR! Or if that isn"t available, you can get their info via: npm ERR! npm owner ls bem-project-stub npm ERR! There is likely additional logging output above. npm ERR! Please include the following file with any support request: npm ERR! /Users/bimba/BEM/npm-debug.log npm ERR! Darwin 15.6.0 npm ERR! argv "/Users/bimba/.nvm/versions/node/v6.9.1/bin/node" "/Users/bimba/.nvm/versions/node/v6.9.1/bin/npm" "install" npm ERR! node v6.9.1 npm ERR! npm v3.10.8 npm ERR! code ELIFECYCLE npm ERR! [email protected] postinstall: `npm run deps` npm ERR! Exit status 1 npm ERR! npm ERR! Failed at the [email protected] postinstall script "npm run deps". npm ERR! Make sure you have the latest version of node.js and npm installed. npm ERR! If you do, this is most likely a problem with the bem-project-stub package, npm ERR! not with npm itself. npm ERR! Tell the author that this fails on your system: npm ERR! npm run deps npm ERR! You can get information on how to open an issue for this project with: npm ERR! npm bugs bem-project-stub npm ERR! Or if that isn"t available, you can get their info via: npm ERR! npm owner ls bem-project-stub npm ERR! There is likely additional logging output above. npm ERR! Please include the following file with any support request: npm ERR! /Users/bimba/BEM/npm-debug.log

Первая ошибка, что бросается в глаза, это какой-то путь, в котором содержится упоминание heroku app. пробовал чистить кеш bower"a, не помогает, ошибка появляется снова (кстати, как удалить heroku полностью из системы?).

  • Перевод

Захват Золотого Кольца-0

Linux предоставляет мощный и обширный API для приложений, но иногда его недостаточно. Для взаимодействия с оборудованием или осуществления операций с доступом к привилегированной информации в системе нужен драйвер ядра.

Модуль ядра Linux - это скомпилированный двоичный код, который вставляется непосредственно в ядро Linux, работая в кольце 0, внутреннем и наименее защищённом кольце выполнения команд в процессоре x86–64. Здесь код исполняется совершенно без всяких проверок, но зато на невероятной скорости и с доступом к любым ресурсам системы.

Не для простых смертных

Написание модуля ядра Linux - занятие не для слабонервных. Изменяя ядро, вы рискуете потерять данные. В коде ядра нет стандартной защиты, как в обычных приложениях Linux. Если сделать ошибку, то повесите всю систему.

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

Можно в основном забыть традиционные парадигмы разработки приложений. Кроме загрузки и выгрузки модуля, вы будете писать код, который реагирует на системные события, а не работает по последовательному шаблону. При работе с ядром вы пишете API, а не сами приложения.

У вас также нет доступа к стандартной библиотеке. Хотя ядро предоставляет некоторые функции вроде printk (которая служит заменой printf) и kmalloc (работает похоже на malloc), в основном вы остаётесь наедине с железом. Вдобавок, после выгрузки модуля следует полностью почистить за собой. Здесь нет сборки мусора.

Необходимые компоненты

Прежде чем начать, следует убедиться в наличии всех необходимых инструментов для работы. Самое главное, нужна машина под Linux. Знаю, это неожиданно! Хотя подойдёт любой дистрибутив Linux, в этом примере я использую Ubuntu 16.04 LTS, так что в случае использования других дистрибутивов может понадобиться слегка изменить команды установки.

Во-вторых, нужна или отдельная физическая машина, или виртуальная машина. Лично я предпочитаю работать на виртуальной машине, но выбирайте сами. Не советую использовать свою основную машину из-за потери данных, когда сделаете ошибку. Я говорю «когда», а не «если», потому что вы обязательно подвесите машину хотя бы несколько раз в процессе. Ваши последние изменения в коде могут ещё находиться в буфере записи в момент паники ядра, так что могут повредиться и ваши исходники. Тестирование в виртуальной машине устраняет эти риски.

И наконец, нужно хотя бы немного знать C. Рабочая среда C++ слишком велика для ядра, так что необходимо писать на чистом голом C. Для взаимодействия с оборудованием не помешает и некоторое знание ассемблера.

Установка среды разработки

На Ubuntu нужно запустить:

Apt-get install build-essential linux-headers-`uname -r`
Устанавливаем самые важные инструменты разработки и заголовки ядра, необходимые для данного примера.

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

Начинаем

Приступим к написанию кода. Подготовим нашу среду:

Mkdir ~/src/lkm_example cd ~/src/lkm_example
Запустите любимый редактор (в моём случае это vim) и создайте файл lkm_example.c следующего содержания:

#include #include #include MODULE_LICENSE(“GPL”); MODULE_AUTHOR(“Robert W. Oliver II”); MODULE_DESCRIPTION(“A simple example Linux module.”); MODULE_VERSION(“0.01”); static int __init lkm_example_init(void) { printk(KERN_INFO “Hello, World!\n”); return 0; } static void __exit lkm_example_exit(void) { printk(KERN_INFO “Goodbye, World!\n”); } module_init(lkm_example_init); module_exit(lkm_example_exit);
Мы сконструировали самый простой возможный модуль, рассмотрим подробнее самые важные его части:

  • В include перечислены файлы заголовков, необходимые для разработки ядра Linux.
  • В MODULE_LICENSE можно установить разные значения, в зависимости от лицензии модуля. Для просмотра полного списка запустите:

    Grep “MODULE_LICENSE” -B 27 /usr/src/linux-headers-`uname -r`/include/linux/module.h

  • Мы устанавливаем init (загрузка) и exit (выгрузка) как статические функции, которые возвращают целые числа.
  • Обратите внимание на использование printk вместо printf . Также параметры printk отличаются от printf . Например, флаг KERN_INFO для объявления приоритета журналирования для конкретной строки указывается без запятой. Ядро разбирается с этими вещами внутри функции printk для экономии памяти стека.
  • В конце файла можно вызвать module_init и module_exit и указать функции загрузки и выгрузки. Это даёт возможность произвольного именования функций.
Впрочем, пока мы не можем скомпилировать этот файл. Нужен Makefile. Такого базового примера пока достаточно. Обратите внимание, что make очень привередлив к пробелам и табам, так что убедитесь, что используете табы вместо пробелов где положено.

Obj-m += lkm_example.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
Если мы запускаем make , он должен успешно скомпилировать наш модуль. Результатом станет файл lkm_example.ko . Если выскакивают какие-то ошибки, проверьте, что кавычки в исходном коде установлены корректно, а не случайно в кодировке UTF-8.

Теперь можно внедрить модуль и проверить его. Для этого запускаем:

Sudo insmod lkm_example.ko
Если всё нормально, то вы ничего не увидите. Функция printk обеспечивает выдачу не в консоль, а в журнал ядра. Для просмотра нужно запустить:

Sudo dmesg
Вы должны увидеть строку “Hello, World!” с меткой времени в начале. Это значит, что наш модуль ядра загрузился и успешно сделал запись в журнал ядра. Мы можем также проверить, что модуль ещё в памяти:

Lsmod | grep “lkm_example”
Для удаления модуля запускаем:

Sudo rmmod lkm_example
Если вы снова запустите dmesg, то увидите в журнале запись “Goodbye, World!”. Можно снова запустить lsmod и убедиться, что модуль выгрузился.

Как видите, эта процедура тестирования слегка утомительна, но её можно автоматизировать, добавив:

Test: sudo dmesg -C sudo insmod lkm_example.ko sudo rmmod lkm_example.ko dmesg
в конце Makefile, а потом запустив:

Make test
для тестирования модуля и проверки выдачи в журнал ядра без необходимости запускать отдельные команды.

Теперь у нас есть полностью функциональный, хотя и абсолютно тривиальный модуль ядра!

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

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

Вероятно, раньше вы уже имели дело с файлами устройств. Команды с упоминанием /dev/zero , /dev/null и тому подобного взаимодействуют с устройствами “zero” и “null”, которые возвращают ожидаемые значения.

В нашем примере мы возвращаем “Hello, World”. Хотя это не особенно полезная функция для приложений, она всё равно демонстрирует процесс взаимодействия с приложением через файл устройства.

Вот полный листинг:

#include #include #include #include #include MODULE_LICENSE(“GPL”); MODULE_AUTHOR(“Robert W. Oliver II”); MODULE_DESCRIPTION(“A simple example Linux module.”); MODULE_VERSION(“0.01”); #define DEVICE_NAME “lkm_example” #define EXAMPLE_MSG “Hello, World!\n” #define MSG_BUFFER_LEN 15 /* Prototypes for device functions */ static int device_open(struct inode *, struct file *); static int device_release(struct inode *, struct file *); static ssize_t device_read(struct file *, char *, size_t, loff_t *); static ssize_t device_write(struct file *, const char *, size_t, loff_t *); static int major_num; static int device_open_count = 0; static char msg_buffer; static char *msg_ptr; /* This structure points to all of the device functions */ static struct file_operations file_ops = { .read = device_read, .write = device_write, .open = device_open, .release = device_release }; /* When a process reads from our device, this gets called. */ static ssize_t device_read(struct file *flip, char *buffer, size_t len, loff_t *offset) { int bytes_read = 0; /* If we’re at the end, loop back to the beginning */ if (*msg_ptr == 0) { msg_ptr = msg_buffer; } /* Put data in the buffer */ while (len && *msg_ptr) { /* Buffer is in user data, not kernel, so you can’t just reference * with a pointer. The function put_user handles this for us */ put_user(*(msg_ptr++), buffer++); len--; bytes_read++; } return bytes_read; } /* Called when a process tries to write to our device */ static ssize_t device_write(struct file *flip, const char *buffer, size_t len, loff_t *offset) { /* This is a read-only device */ printk(KERN_ALERT “This operation is not supported.\n”); return -EINVAL; } /* Called when a process opens our device */ static int device_open(struct inode *inode, struct file *file) { /* If device is open, return busy */ if (device_open_count) { return -EBUSY; } device_open_count++; try_module_get(THIS_MODULE); return 0; } /* Called when a process closes our device */ static int device_release(struct inode *inode, struct file *file) { /* Decrement the open counter and usage count. Without this, the module would not unload. */ device_open_count--; module_put(THIS_MODULE); return 0; } static int __init lkm_example_init(void) { /* Fill buffer with our message */ strncpy(msg_buffer, EXAMPLE_MSG, MSG_BUFFER_LEN); /* Set the msg_ptr to the buffer */ msg_ptr = msg_buffer; /* Try to register character device */ major_num = register_chrdev(0, “lkm_example”, &file_ops); if (major_num < 0) { printk(KERN_ALERT “Could not register device: %d\n”, major_num); return major_num; } else { printk(KERN_INFO “lkm_example module loaded with device major number %d\n”, major_num); return 0; } } static void __exit lkm_example_exit(void) { /* Remember - we have to clean up after ourselves. Unregister the character device. */ unregister_chrdev(major_num, DEVICE_NAME); printk(KERN_INFO “Goodbye, World!\n”); } /* Register module functions */ module_init(lkm_example_init); module_exit(lkm_example_exit);

Тестирование улучшенного примера

Теперь наш пример делает нечто большее, чем просто вывод сообщения при загрузке и выгрузке, так что понадобится менее строгая процедура тестирования. Изменим Makefile только для загрузки модуля, без его выгрузки.

Obj-m += lkm_example.o all: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules clean: make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean test: # We put a - in front of the rmmod command to tell make to ignore # an error in case the module isn’t loaded. -sudo rmmod lkm_example # Clear the kernel log without echo sudo dmesg -C # Insert the module sudo insmod lkm_example.ko # Display the kernel log dmesg
Теперь после запуска make test вы увидите выдачу старшего номера устройства. В нашем примере его автоматически присваивает ядро. Однако этот номер нужен для создания нового устройства.

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

Sudo mknod /dev/lkm_example c MAJOR 0
(в этом примере замените MAJOR значением, полученным в результате выполнения make test или dmesg)

Параметр c в команде mknod говорит mknod, что нам нужно создать файл символьного устройства.

Теперь мы можем получить содержимое с устройства:

Cat /dev/lkm_example
или даже через команду dd:

Dd if=/dev/lkm_example of=test bs=14 count=100
Вы также можете получить доступ к этому файлу из приложений. Это необязательно должны быть скомпилированные приложения -  даже у скриптов Python, Ruby и PHP есть доступ к этим данным.

Когда мы закончили с устройством, удаляем его и выгружаем модуль:

Sudo rm /dev/lkm_example sudo rmmod lkm_example

Заключение

Надеюсь, вам понравились наши шалости в пространстве ядра. Хотя показанные примеры примитивны, эти структуры можно использовать для создания собственных модулей, выполняющих очень сложные задачи.

Просто помните, что в пространстве ядра всё под вашу ответственность. Там для вашего кода нет поддержки или второго шанса. Если делаете проект для клиента, заранее запланируйте двойное, если не тройное время на отладку. Код ядра должен быть идеален, насколько это возможно, чтобы гарантировать цельность и надёжность систем, на которых он запускается.

Как вы знаете из статьи что такое ядро Linux, ядро является монолитным. Это значит, что весь исполняемый код сосредоточен в одном файле. Такая архитектура имеет некоторые недостатки, например, невозможность установки новых драйверов без пересборки ядра. Но разработчики нашли решение и этой проблеме, добавив систему модулей.

Ядро Linux позволяет драйверам оборудования, файловых систем, и некоторым другим компонентам быть скомпилированными отдельно - как модули, а не как часть самого ядра. Таким образом, вы можете обновлять драйвера не пересобирая ядро, а также динамически расширять его функциональность. А еще это значит, что вы можете включить в ядре только самое необходимое, а все остальное подключать с помощью модулей. Это очень просто.

В этой статье мы рассмотрим модули ядра Linux, основы работы с ними, просмотр уже загруженных модулей, загрузку, установку и отключение модулей. А также полное отключение, добавление в черный список и добавление новых модулей ядра.

Модули ядра Linux собираются только под определенную версию ядра, есть способ запуска модуля независимо от версии ядра, если они совместимы с помощью dkms, но об этом мы поговорим позже.

Находятся все модули в папке /lib/modules/. Учитывая, что модули рассчитаны только для определенной версии ядра, то в этой папке создается отдельная подпапка, для каждой установленной в системе версии ядра. В этой папке находятся сами модули и дополнительные конфигурационные файлы, модули отсортированы по категориям, в зависимости от назначения например:

ls /lib/modules/4.1.20-11-default/kernel/

arch Documentation fs lib net sound
crypto drivers kernel mm security

Перед тем как переходить к практике, давайте коротко рассмотрим основные команды для управления модулями.

  • lsmod - посмотреть загруженные модули
  • modinfo - информация о модуле
  • insmod - загрузить модуль
  • rmmod - удалить модуль

Работа с модулями ядра Linux выполняется, в основном, с помощью этих команд, но могут использовать и другие.

Все модули

Такая задача возникает нечасто, но если вы хотите посмотреть все установленные модули ядра Linux в системе, делается очень просто. Все модули расположены в папке /lib/modules, а поэтому очень просто вычислить их все одной командой, или даже просто зайти в папку файловым менеджером и посмотреть.

В Ubuntu команда будет выглядеть вот так:

dpkg -S *.ko | grep /lib/modules

Можно смастерить такую конструкцию с помощью find:

find /lib/modules -name *.ko

Можем искать только для текущего ядра:

find /lib/modules/$(uname -r) -name *.ko

Также, все модули записаны в конфигурационном файле /lib/modules/modules.aliases, поэтому мы можем просто посмотреть его содержимое:

Если хотим проверить установлен ли определенный модуль ядра Linux, отфильтруем вывод любой из команд с помощью grep:

find /lib/modules -name *.ko | grep vbox

/lib/modules/4.1.20-11-default/weak-updates/misc/vboxnetadp.ko
/lib/modules/4.1.20-11-default/weak-updates/misc/vboxvideo.ko

Что загружено?

Все информация о загруженных модулях хранится в файле /proc/modules, мы можем ее вывести командой:

cat /proc/modules

tun 32768 2 - Live 0xffffffffa07a9000
vboxpci 28672 0 - Live 0xffffffffa07a1000 (O)
vboxnetadp 28672 0 - Live 0xffffffffa0632000 (O)
vboxnetflt 32768 0 - Live 0xffffffffa06f3000 (O)
af_packet 40960 8 - Live 0xffffffffa065b000

Но для этого дела есть более цивилизованные методы. Это утилита lsmod и modinfo. Чтобы посмотреть загруженные модули ядра linux выполните:

Module Size Used by
ctr 16384 2
ccm 20480 2
fuse 106496 3
bnep 20480 2
bluetooth 532480 5 bnep

Удобно проверять загружен ли модуль с помощью grep:

sudo lsmod | grep vbox

А более подробную информацию о каждом модуле можно получить с помощью утилиты modinfo:

filename: /lib/modules/4.1.20-11-default/kernel/fs/fuse/fuse.ko
alias: devname:fuse
alias: char-major-10-229
alias: fs-fuseblk
alias: fs-fuse
license: GPL
description: Filesystem in Userspace
author: Miklos Szeredi
alias: fs-fusectl
srcversion: 739DE4A12CE441C9FBD74C7

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

Запуск модулей ядра

Загрузить модуль ядра Linux можно с помощью команд modprobe или insmod.

Например, загрузим модуль vboxdrv

sudo modprobe vboxdrv

Чтобы загрузить модуль ядра linux с помощью insmod необходимо передать адрес файла модуля:

sudo insmod /lib/modules/4.1.20-11-default/weak-updates/misc/vboxdrv.ko

Напоминаю, что его можно узнать с помощью команды modinfo. Запуск модуля ядра Linux предпочтительно выполнять с помощью modprobe, поскольку эта команда не только находит файл модуля в файловой системе, но и загружает все его зависимости.

Удаление модулей ядра

Здесь аналогично две команды - modprobe, позволяет удалить модуль если ей передать опцию -r, а также есть команда rmmod. Начнем с modprobe:

sudo modprobe -r vboxdrv

Другая команда в этом случае выглядит немного проще:

sudo rmmod vboxdrv

rmmod: ERROR: Module vboxdrv is in use by: vboxnetadp vboxnetflt vboxpci

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

rmmod vboxnetadp vboxnetflt vboxpci

Блокирование загрузки модулей

Иногда, во время загрузки системы для используемых нами устройств, загружаются не те модули ядра Linux, они либо не поддерживают нужную функциональность либо конфликтуют с другими модулями. Ярким примером можно назвать загрузку драйвера b43 вместо brcmsmac для беспроводных адаптеров Broadcom. Чтобы решить эту проблему вы можете добавлять модули в черный список. Для этого достаточно добавить одну строчку в файл /etc/modprobe.d/blacklist.conf:

vi /etc/modprobe.d/blacklist.conf

Этот код добавит в черный список модуль b43.

Установка модулей ядра Linux

Собранные для этой версии ядра модули вы можете просто скопировать в нужную папку, собственно, мы так и поступаем, когда собираем ядро из исходников. Но с проприетарными драйверами и другими внешними драйверами, не поставляемыми в комплекте с ядром дело обстоит иначе. Эти модули поддерживают несколько версий ядра, но для их установки используется специальная технология - DKMS (Dynamic Kernel Module Support). Причем модуль, установленный таким образом один раз, будет пересобираться для каждой новой версии ядра автоматически.

wget http://tenet.dl.sourceforge.net/project/e1000/ixgbe%20stable/4.3.15/ixgbe-4.3.15.tar.gz
$ sudo tar -xf ixgbe-4.3.15.tar.gz -C /usr/local/src
$ sudo mv /usr/local/src/ixgbe-4.3.15/src /usr/src/ixgbe-4.3.15

Создадим конфигурационный файл:

sudo vi /usr/src/ixgbe-4.3.15/dkms.conf

PACKAGE_NAME="ixgbe"
PACKAGE_VERSION="4.3.15"
BUILT_MODULE_NAME="ixgbe"
DEST_MODULE_LOCATION="/kernel/drivers/net/ethernet/intel/ixgbe/"
AUTOINSTALL="yes"

Добавим модуль в дерево ядра:

sudo dkms add -m ixgbe -v 4.3.15

Запускаем сборку, для текущего ядра:

sudo dkms build -m ixgbe -v 4.3.15

И устанавливаем:

sudo dkms install -m ixgbe -v 4.3.15

Установка модулей ядра завершена. Теперь вы можете посмотреть информацию о драйвере или загрузить его:

dkms status | grep ixgbe

Выводы

Скорее всего, вам редко придется возиться с этими модулями. Но работа с модулями ядра будет необходима, если ваш дистрибутив не поддерживает аппаратное обеспечение вашего устройства из коробки, а также когда вы работаете со сторонним программным обеспечением, таким как VirtualBox, Vmware и т д. Но очень полезно знать как обращаться с модулями, когда вам нужно добавить или удалить их. Даже если у вас нет необходимости в этом сейчас, вы можете протестировать, как все работает, чтобы быть вооруженным потом.

После обновления версии друпала на одном из сайтов, где было много рукописных модулей, я, к своему изумлению, обнаружил несколько подряд сообщений об ошибках такого вот содержания:

User warning: The following module is missing from the file system:...

дальше шли имена тех самых модулей, которые система не обнаружила. Модули эти когда-то писал я сам, но в процессе создания они как-то объединились с другими, переименовались или еще что-то... в общем для истории они потеряны. Сначала я решил плюнуть на все это, но очень быстро надпись меня стала раздражать, и я полез разбираться по ссылке, которая была указана рядом с сообщением о проблеме. Почитав инфы я понял, что был неправ, когда удалял модули сразу прямо с сервера, а не пользовался для этого опциями админпанели. Не буду сейчас в подробностях описывать чем это плохо, но делать этого не стоило, но вот сам Друпал таких недостойных поступков разработчиков никак не пресекал. И вот в версии 7.50 и выше создатели этой славной CMS решили призвать всех к порядку.

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

Вот и все. Я обещал три шага, а получилось шесть. Но это не значит, что все сложно, просто я растягивал удовольствие:) Удачи!

]

Modules are used to extend and modify the way ZNC functions. Users interact with modules most commonly by messaging a special user on IRC. For example, to view the highlight keywords in your watch list, you"d send /msg *watch list . When ZNC sees that the nick you"re messaging starts with an asterisk, it doesn"t forward the message to the IRCd/server but instead sends it to the proper module for processing. In this case, the watch module will get the message and reply to you with a listing of your keywords. This makes for a very convenient and standard way of configuring or otherwise communicating with your loaded modules, as well as a common and standard way for your loaded modules to display status or other information. Notice that this is for loaded modules. You must load a given module, for example /znc loadmod watch , before you can interface with the watch module. Most modules will reply to /msg *module help with a listing of available commands.

ZNC modules are loaded either globally , per-network , or on a per-user basis. Each module defines for itself whether it is available to load as global, network-specific and/or user-specific. User level and network modules can do things ranging from manipulating the incoming/outgoing messages to implementing a full blown Twitter client . They can also do more traditional IRC tasks such as challenge based auto-op , setting you away , or logging to disk . Each user gets to load and configure their own set of modules to customize their experience to suit their preference.

Global modules are loadable by admins and provide functionality or change behavior for all users. For example, the partyline module has to be global since it provides functionality for all users on a given ZNC instance to be able to communicate with each other from within ZNC itself. Global modules can do everything that user-level modules can do, as well as a few extras. They can replace ZNC"s authentication system , modify the config-writing process, deal with CAP, etc.

Feel free to create wikipages about modules you have created, but don"t forget to add a download link, contact information, and use the same layout as the rest of the modules. Contributions are always much appreciated.

Module List [ edit ]

Global Modules [ edit ]

adminlog Log user connects, disconnects, and failed logins to a file and/or to syslog. blockuser Blocks certain users from using ZNC, saying their account was disabled. certauth This module lets users to log in via SSL client keys. cyrusauth This module is intended for admins who run a shell/web/email/etc server and want to provide ZNC access to their existing users. fail2ban Block IPs for some time after a failed login. identfile Posts the ident of a user to a file when they are trying to connect. imapauth Allow users to authenticate via IMAP. lastseen Logs when a user last logged in to ZNC. modperl Loads Perl scripts as ZNC modules. modpython Allows you to use modules written on Python. notify_connect Sends a notice to all admins when a user logs in or out of ZNC. partyline Allows ZNC users to join internal channels and query other ZNC users on the same ZNC. webadmin Allows you to add/remove/edit users and settings on the fly via a web browser.

User Modules [ edit ]

admin (Now controlpanel) Allows you to add/remove/edit users and settings on the fly via IRC messages. autoattach Watches your detached channels and reattaches you automatically when there is specified activity in a channel you added to your autoattach list. autoreply Gives a automatic reply if someone messages you while you are away. block_motd Blocks the server"s Message of the Day. bouncedcc Bounces DCC transfers through the znc server instead of sending them directly to the user. buffextras Add nick changes, joins, parts, topic changes etc. to your playback buffer. chansaver Saves channels to config when user joins and parts. charset Normalizes (i.e. converts) character encodings. clearbufferonmsg This module attempts to bridge the gap between being inundated with old buffer if you have KeepBuffer=true; and possibly missing messages when you ping out, if you have KeepBuffer=false. clientnotify Notify about new incoming connections to your user. controlpanel Allows you to add/remove/edit users and settings on the fly via IRC messages. ctcpflood This module tries to block CTCP floods. dcc This module allows you to transfer files to and from ZNC disconkick This module will kick your client from all channels if ZNC disconnects from server. flooddetach This module detaches you from channels which are flooded. listsockets This module displays a list of all open sockets in ZNC. log Log chat activity to file. missingmotd This user module will send 422 to clients when they login. notes Keep and replay notes. This is an example of WebMods . sample This is an example module to help with writing modules to do whatever you want. send_raw Allows you to send raw traffic to IRC from other users. shell Access your Unix shell via query right inside of your IRC client.

Network Modules [ edit ]

autocycle Rejoin a channel when you are the only one there (to gain operator status). autoop Automatically give operator status to the good guys. modtcl Allows you to run Tcl scripts in ZNC. autovoice Automatically give voice status to everyone who joins some channel. awaynick Change your nick while you are away. awaystore When you are set away or detached, this module will save all private messages for you. The messages can be read until you delete them. This module will also set you away when you are idle some time. cert This module lets users use their own SSL certificate to connect to a server. crypt Encryption for channel/private messages. keepnick Tries to get and keep your primary nick if it is taken. kickrejoin Implements auto-rejoin-on-kick. modules_online Fakes online status of ZNC modules to fix some clients. nickserv Auths you with NickServ. perform Performs commands on connect. Auths you with Q (and a little more). raw View all of the raw traffic. route_replies Routes back answers to the right client when connected with multiple clients. sasl Allows you to authenticate to an IRC network via SASL savebuff Saves your channel buffers into an encrypted file so they can survive restarts and reboots. schat SSL (encrypted) DCC chats. simple_away Automatically set you away on IRC when disconnected from the bouncer. stickychan Keeps you in specified channels. watch Monitor activity for specific text patterns from specific users and have the text sent to a special query window.

More Modules [ edit ]

Managing Modules [ edit ]

Modules can be added or removed easily. Modules can be stored in ~/.znc/modules and /usr/local/lib/znc by default. ZNC installs its modules to that second directory, which in fact is ${prefix}/lib/znc , but this can be changed with ./configure --module-prefix=DIR before compiling.

ZNC will first look in the local sub-directory modules when searching for modules. Only files that end with ".so" will be seen as a module. To remove modules you can simply delete them from the folder. No other configuration changes or restarts are necessary. To remove, but also keep a module for later use you can also change the name, like: mv sample.so sample.so_ .

To compile a new module you must first save the source as a ".cpp" file. Compiling modules describes the process in detail.

Global, user, and network modules can be (un)loaded from webadmin or via the *status query window, like:

/msg *status LoadMod [--type=global|user|network] /msg *status UnloadMod [--type=global|user|network]

  • configuration
  • [--type=global|user|network] optionally specifies whether to (un)load the module as a global, user, or network module. Not all modules can be loaded at all levels; see individual Module documentation to find out where it may be loaded.
  • is based on the modules file name, excluding the ".so" extension.
  • Are specific for each module and not required: You can provide parameters when loading the module, or you can set up the module after loading it.

So, to load the log module at the global level (as opposed to user or network) and remove all color/formatting control codes with the -sanitize parameter, you would type:

/msg *status LoadMod --type=global log -sanitize

For older versions of ZNC, you won"t have the option to specify [--type=global|user|network] . In that case, just use:

/msg *status LoadMod /msg *status UnloadMod

Please keep in mind that a user is not able to load a module if the directive "DenyLoadMod" is set to true. Trying to load a module will fail with "Unable to load [] Access Denied.".

If a module prevents ZNC from starting up and therefore you can"t unload the module using webadmin , you can edit znc.conf and remove the corresponding LoadModule line.

Using modules [ edit ]

It is recommended to read the module"s wikipage if you want to find out how a module works. Alternatively the following command can be used to get a command list:

/msg * help

  • * is the StatusPrefix set in your configuration . Usually it"s just an asterisk ("*").