Есть одна вещь которая меня коробит, это то как сделаны коды возврата в ядре. Идея простая: есть системные вызовы и есть стандартные коды возврата от 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