LINUX.ORG.RU

возврат ошибок системных вызовов

 , ,


0

1

Есть одна вещь которая меня коробит, это то как сделаны коды возврата в ядре. Идея простая: есть системные вызовы и есть стандартные коды возврата от SUCCESS до всяких EPERM, EBADF и прочих. Когда речь идёт о тривиальных вызовах типа open(«some file») всё понятно (и то бывают дурацкие проблемы со всякими xattrs, selinux и прочим, но selinux хотя бы логи умеет вести). Но есть гораздо более сложные ситуации когда внутри ядра происходит куча всего и одна и код возврата может быть использован в разных местах. Соотв. из userspace понять что там в ведре случилось невозможно. И что, блин, характерно, в логах тоже ничего не найдёшь.

Вот пример такого:

* We only trust the superuser with rebooting the system. */
- if (!capable(CAP_SYS_BOOT))
+ if (!capable(CAP_SYS_BOOT) || !capable(CAP_COMPROMISE_KERNEL))
return -EPERM;

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

Я не требую введения иерархии эксепшенов. Прочто чочу чтобы ядро тоже умело писать в лог :(. Ну хотя бы в дебаг-сборке.

Перемещено mono из talks

★★★★★

И в данном случае без исходников ядра и долгого ковыряния определить почему ядро возвращает EPERM для рутового процесса очень сложно.

Достаточно почитать man. Все коды ошибок там описаны

ERRORS
       EBADF  One or both file descriptors are not valid, or do not have proper read-write mode.

       EINVAL Target file system doesn't support splicing; neither of the descriptors refers to a pipe; or offset given for non-seekable device.

       ENOMEM Out of memory.

Прочто чочу чтобы ядро тоже умело писать в лог

Это потенциальный DDOS, поэтому нет.

ttnl ★★★★★
()

Эээ, так есть же printk. Закинь им патч или просто попроси использовать его для более точного описания ошибок.

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

Достаточно почитать man. Все коды ошибок там описаны

я как раз и пишу о том чем плох этот подход и привёл код когда не понятно почему не работает kexec.

Вот тебе вернули EPERM, а ты рут. Надо починить. Твои действия? Правильно, идём в гугл и/или сырцы. И проковыряться можно очень долго. man errno уже бесполезен.

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

Закинь им патч или просто попроси использовать его для более точного описания ошибок.

Уверен они не пойдут на это. Это же надо перелопачивать всё ядро. А в одном месте где я проковырялся несколько дней я пошлю дополнение к ману.

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

Это потенциальный DDOS

Тем не менее некоторые подсистемы умеют verbose логгирование. Например, scsi, включается в конфиге. Но есть и другие способы решения проблемы. Например, выставлять какой-нить extended errno. Я в какой-то либе такое видел.

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

Омг, ну слава богу я не один такой :). А то я уж думал на меня посыпится град обвинений «как ты посмел трогать веками устоявшуюся архитектуру» :).

Правда, пока весь прогресс это библиотека libexplain которая тупо делает кучу проверок чтобы понять где проблема. Ну хоть какие-то сподвижки.

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

Ядро умеет писать в лог. Есть функция ядра printk(), у нее есть разные уровни, 7 вроде, но точно не помню. И никакой это не DDOS, там нормально сделано, сообщение выдается не сразу, а если ядро занято чем-то серьезным, оно напишет потом, когда освободится. Срочные сообщения выводятся по возможности сразу, но гарантий нет.

hibou ★★★★★
()

Общая тема касается не только ядра, а большинства модульных изолированных систем (ядра, библиотеки, устройства). Одна ошибка на множество случаев: «Read error», «General error», «Permission Denied».

И сиди гадай!

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

Как раз этими вызовами printk и задосят. Каждая запись — это необходимость будить процесс для флаша буфера printk, необходимость работы syslog.

Если не задосят, то это, как минимум, потенциальная возможность.

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

Вот тебе вернули EPERM, а ты рут. Надо починить. Твои действия?

strace — последний системный вызов — man

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

strace — последний системный вызов — man

Это, к сожалению, не всегда работает. Хотя бы потому что не для всего написаны маны, а доки в linux/Documentation устаревают и не всегда полны.

В любом случае выдавать один код на 100500 случаев это ошибка в дизайне.

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

Я же предложил вариант - возвращать extended status в отдельной переменной.

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

Нереально. Это поломает существующие программы.

Когда ломают обратную совместимость, Линус обычно на это реагирует следующим образом:

https://lkml.org/lkml/2012/12/23/75

ttnl ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.