обработка ошибок syscall внутри ядра linux


Я пишу новый syscall внутри ядра linux. Я хочу реализовать систему обработки ошибок, чтобы вернуть пользователю, который использует sycall код, который описывает тип ошибки. Я хотел бы знать, как это делается внутри ядра, так как я хочу следовать стандарту. Я хочу, чтобы пользователь прочитал переменную errno или что-то эквивалентное, чтобы понять ошибку, которая произошла. Спасибо.

P. S. Я, используя последние версии для Linux доступно.

3 4

3 ответа:

Большая часть вашей задачи выполняется автоматически libc и низкоуровневым обработчиком ядра syscall (часть, написанная в сборке). Соглашение ядра для обработки кодов ошибок состоит в том, чтобы возвращать отрицательную константу ошибки, что-то вроде -ENOMEM. Ноль или положительное число указывает на успех. Это используется во всем ядре.

Если вы определили новую точку входа sycall static asmlinkage long my_new_syscall (int param) {...}, ей просто нужно вернуть -ENOMEM (или что-то подобное). Если вы вызвали системный вызов с помощью libc syscall(nr, param), тогда по ошибке он вернет -1 и ENOMEM (в положительном) будет в errno.

Существует множество кодов ошибок, определенных в include/asm-generic/{errno,errno-base}.h, которые можно использовать (например, ENOMEM). Если ни один из них не соответствует вашей цели, вы можете добавить свой собственный номер ошибки к этим файлам, но имейте в виду, что вам также потребуется изменить заголовки ядра, видимые в пользовательском пространстве, чтобы показать тот же номер, поэтому будет сложнее настроить систему для использования ваших изменений. Не делай этого, если тебе не нужно.

Я обнаружил, что могу просто вернуть номер кода, который я хочу, чтобы errno был установлен, вернув сам код в sycall. Все остальное ядро linux делает автоматически.

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

Основные номера ошибок находятся в:

include/asm-generic/errno-base.h

И

include/asm-generic/errno.h.

В системном вызове вы можете вернуть пользователю отрицательное значение существующего значения errno. Например:

return -ENOMEM;