Библиотека сайта rus-linux.net
Цилюрик О.И. Модули ядра Linux | ||
Назад | Вперед |
Более экзотические возможности
Существует ещё большое разнообразие возможностей для программиста, пишущего в адресном пространстве ядра (или для поддержки собственных операций в пространстве ядра). Они используются гораздо реже, чем типовые средства, разбираемые выше, но они весьма значимы, и некоторые из них должны быть хотя бы коротко обозначены.
Примечание: Многие из таких возможностей, реализующие действия, аналогичные таким же в пространстве пользователя (в более привычном контексте), в литературе и обсуждениях относят к общей группе «хелперы», где информацию о них и следует искать.
Запуск процессов из ядра
Новые процессы пользовательского пространства могут создаваться кодом ядра, так же, как они создаются и пользовательским кодом вызовами группы exec*().
Примечание: Процессы из пользовательского кода создаются в два шага: выполнением fork() создаётся новое адресное пространство, которое и станет пространством нового процесса, после чего вызывается функция семейства exec().
Простейший пример демонстрирует возможность порождения новых процессов в системе по инициативе ядра (архив exec.tgz):
mod_exec.c :
#include <linux/module.h> static char *str; module_param( str, charp, S_IRUGO ); int __init exec_init( void ) { int rc; char *argv[] = { "wall", "this is wall message", NULL }; static char *envp[] = { NULL }; if( str ) argv[ 1 ] = str; rc = call_usermodehelper( "/usr/bin/wall", argv, envp, 0 ); if( rc ) printk( KERN_INFO "failed to execute : %s %s\n", argv[ 0 ], argv[ 1 ] ); else printk( KERN_INFO "execute : %s %s\n", argv[ 0 ], argv[ 1 ] ); return -1; } module_init( exec_init ); MODULE_LICENSE( "GPL" ); MODULE_AUTHOR( "Oleg Tsiliuric <olej@front.ru>" ); MODULE_VERSION( "1.1" );
Вызов call_usermodehelper() получает параметры точно так же, как вызов пользовательского пространства execve() (через который выполняются все вызовы семейства exec*()), детали смотрите в справочной странице :
$ man 2 execve
Срабатывание созданного модуля:
$ sudo insmod mod_exec.ko
this is wall messageom root@notebook.localdomain (Tue May 3 22:32:00 2011): insmod: error inserting 'mod_exec.ko': -1 Operation not permitted
$ dmesg | tail -n1
execute : wall this is wall message
- модуль успешно загружается, видно нормальный запуск автономного пользовательского приложения... некоторый диссонанс вносит нарушение целостности текстового сообщения, посланного терминалу, в типовом запуске этой программы это должно выглядеть так:
$ wall this is wall message
Broadcast message from olej@notebook.localdomain (pts/2) (Tue May 3 22:33:57this is wall message
В этом и есть особенность и ограниченность метода: процесс запускается без управляющего терминала и с нестандартным для него окружением! Если в качестве пользовательского процесса, заменив строку запуска, использовать:
char *argv[] = { "/bin/echo", "this is wall message", NULL };
То результатом будет:
$ sudo insmod mod_exec.ko str=XXX
insmod: error inserting 'mod_exec.ko': -1 Operation not permitted
$ dmesg | tail -n1
execute : /bin/echo XXX
- мы имеем совершенно нормальный запуск пользовательского процесса ... но в глухо-немом варианте, без ожидаемого вывода в терминал, поскольку не существует терминала, в который надлежало бы производить такой вывод.
Всю основную работу по созданию и запуску процесса, как легко видеть, выполняет вызов (<linux/kmod.h>):
static inline int call_usermodehelper( char *path, char **argv, char **envp, enum umh_wait wait ); enum umh_wait { UMH_NO_WAIT = -1, /* don't wait at all */ UMH_WAIT_EXEC = 0, /* wait for the exec, but not the process */ UMH_WAIT_PROC = 1, /* wait for the process to complete */ };
Предыдущий раздел: | Оглавление | Следующий раздел: |
Устройства USB | Сигналы |