delete_module - выгружает модуль ядра
delete_module(2)
выгружает модуль ядра
ОБЗОР
int delete_module(const char *
name
, int
flags
);
Замечание: В заголовочных файлах glibc эта функция отсутствует; смотрите
ЗАМЕЧАНИЯ.
ОПИСАНИЕ
Вызов
delete_module() пытается удалить неиспользуемый загруженный модуль
с именем
name. Если у модуля есть функция
exit, то она выполняется
перед выгрузкой. Аргумент
flags используется для изменения поведения
системного вызова — это описано далее. Данный системный вызов требует особых
прав.
Удаление модуля выполняется по следующим правилам:
1.
Если какой-то другой модуль зависит от выгружаемого (т.е., использует его
символы), то вызов завершается с ошибкой.
2.
В противном случае, если счётчик ссылок на модуль (т.е. количество
процессов, использующих модуль в данный момент) равно нулю, то модуль
немедленно выгружается.
3.
Если у модуля ненулевой счётчик ссылок, то поведение зависит от битов,
установленных в
flags. Обычно (смотрите
ЗАМЕЧАНИЯ) всегда указывается
флаг
O_NONBLOCK, а иногда добавляется
O_TRUNC.
Различные комбинации значений в flags дают разный эффект:
flags == O_NONBLOCK
Вызов сразу завершается с ошибкой.
flags == (O_NONBLOCK | O_TRUNC)
Модуль немедленно выгружается, независимо от того, равен счётчик ссылок 0
или нет.
(flags & O_NONBLOCK) == 0
Если в flags не указан O_NONBLOCK, то выполняются следующие шаги:
Модуль помечается, что больше ссылаться на него запрещается.
Если счётчик ссылок модуля не равен нулю, то вызывающий переходит в
непрерываемое состояние сна (TASK_UNINTERRUPTIBLE) до тех пор, пока
счётчик ссылок не станет равным 0 — в этот момент вызов разблокируется.
Модуль выгружается как обычно.
Флаг O_TRUNC имеет ещё один эффект. По умолчанию, если модуль имеет
функцию init, не имеет функции exit, то попытка удаления модуля
завершается с ошибкой. Однако, если указан O_TRUNC, то это требование не
учитывается.
Использовать флаг O_TRUNC опасно! Если ядро не собрано с параметром
CONFIG_MODULE_FORCE_UNLOAD, то этот флаг просто игнорируется (обычно
параметр CONFIG_MODULE_FORCE_UNLOAD включают). Использование этого флага
приводит к примешиванию (taints) в ядре (TAINT_FORCED_RMMOD).
ВОЗВРАЩАЕМОЕ ЗНАЧЕНИЕ
При успешном выполнении возвращается ноль. В случае ошибки возвращается -1,
а errno устанавливается в соответствующее значение.
ОШИБКИ
EBUSY
Модуль не «живой» (т.е., он всё ещё инициализируется или уже помечен для
удаления); или модуль имеет функцию init, но не имеет функции exit и в
flags не указан флаг O_TRUNC.
EFAULT
Значение name указывает на расположение вне доступного адресного
пространства процесса.
ENOENT
Модуль с таким именем не существует.
EPERM
Вызывающий не имеет прав (не имеет мандата CAP_SYS_MODULE), или отключена
выгрузка модулей (смотрите /proc/sys/kernel/modules_disabled в
proc(5)).
EWOULDBLOCK
Другие модули зависят от этого модуля; или в flags указан флаг
O_NONBLOCK, но счётчик ссылок модуля не равен 0 и в flags не указан
флаг O_TRUNC.
СООТВЕТСТВИЕ СТАНДАРТАМ
Вызов delete_module() есть только в Linux.
ЗАМЕЧАНИЯ
Системный вызов delete_module() не поддерживается glibc. В заголовочных
файлах glibc он не объявлен, но в недавнем прошлом glibc экспортировал ABI
для этого системного вызова. Поэтому чтобы получить данный системный вызов
достаточно вручную объявить интерфейс в своём коде; или же вы можете вызвать
его через syscall(2).
Непрерываемый сон, который может начаться, если в flags не указан флаг
O_NONBLOCK, считается нежелательным, так как спящий процесс находится в
неубиваемом состоянии. В Linux 3.7 указание O_NONBLOCK необязательно, но
в будущих ядрах, он, вероятно, станет обязательным.
Linux версии 2.4 и более ранние
В Linux версии 2.4 и более ранних системный вызов принимал один аргумент:
int delete_module(const char *name);
Если значение name равно NULL, то все неиспользуемые модули, помеченные
для автоматической вычистки, удаляются.
Есть и некоторые другие отличия в поведении delete_module() в Linux 2.4 и
более ранних, но они пока не описаны в этой справочной странице.