В решении на базе KasperskyOS для кодирования результатов выполнения функций API используется несколько разных типов кодов возврата. Почти все функции API библиотеки libkos, передающие коды возврата, возвращают значения типа Retcode, который определен в заголовочном файле sysroot-*-kos/include/rtl/retcode.h из состава KasperskyOS SDK. Также коды возврата этого типа передаются функциями API библиотеки kdf и функциями API программ, поставляемых в составе KasperskyOS SDK (например, драйверов и других системных программ, созданных для использования в решениях на базе KasperskyOS). Функции транспортного кода, несколько функций API библиотеки libkos для работы с IPC-транспортом и функции некоторых других API, связанных с IPC (например, функции, определенные в заголовочном файле sysroot-*-kos/include/nk/transport.h из состава KasperskyOS SDK), передают коды возврата типа nk_err_t, который определен в заголовочном файле sysroot-*-kos/include/nk/types.h из состава KasperskyOS SDK. Функции интерфейса POSIX и функции API стороннего ПО передают коды возврата других типов.
Разработчику решения рекомендуется кодировать результаты выполнения своих функций, используя коды возврата типа Retcode.
Формат кода возврата типа Retcode
Тип Retcode определен в заголовочном файле retcode.h как 32-битное знаковое целое число:
typedef __INT32_TYPE__ Retcode;
Множество кодов возврата типа Retcode состоит из кода успеха со значением 0 и кодов ошибок. Код ошибки интерпретируется как структура данных, формат которой показан на рисунке ниже.
Формат кода возврата типа Retcode
Этот формат предусматривает наличие нескольких полей, которые содержат не только сведения о результатах выполнения функции (в поле Code), но и следующую дополнительную информацию:
Severity, отличающий код ошибки (1) от кода успеха (0). Это поле используется для обратной совместимости с другими форматами кодов ошибок.Customer, сигнализирующий о том, что код ошибки определен разработчиками решения, а не разработчиками ПО из состава KasperskyOS SDK.Благодаря флагу в поле Customer разработчики решения и разработчики ПО из состава KasperskyOS SDK могут определять коды ошибок из непересекающихся множеств.
Space.Глобальные идентификаторы позволяют определять непересекающиеся множества кодов ошибок. Коды ошибок могут быть общими и специфичными. Общие коды ошибок могут использоваться в API любых компонентов решения и в API любых составных частей компонентов решения (например, драйвер или VFS могут быть составной частью компонента решения). Специфичные коды ошибок используются в API одного или нескольких компонентов решения или в API одной или нескольких составных частей компонентов решения.
Например, идентификатору RC_SPACE_GENERAL соответствуют коды общих ошибок, идентификатору RC_SPACE_KERNEL соответствуют коды ошибок ядра, идентификатору RC_SPACE_DRIVERS соответствуют коды ошибок драйверов.
Facility.Локальные идентификаторы позволяют определять непересекающиеся подмножества кодов ошибок в рамках множества кодов ошибок, которые соответствуют одному глобальному идентификатору. Например, множество кодов ошибок с глобальным идентификатором RC_SPACE_DRIVERS включает непересекающиеся подмножества кодов ошибок с локальными идентификаторами RC_FACILITY_I2C, RC_FACILITY_USB, RC_FACILITY_BLKDEV. (Эти локальные идентификаторы определены в заголовочном файле sysroot-*-kos/include/kdf/facilities.h из состава KasperskyOS SDK.)
Глобальные и локальные идентификаторы специфичных кодов ошибок назначаются разработчиками решения и разработчиками ПО из состава KasperskyOS SDK независимо друг от друга. То есть формируется два множества глобальных идентификаторов. Каждый глобальный идентификатор имеет уникальное смысловое значение в рамках одного множества. Каждый локальный идентификатор имеет уникальное смысловое значение в рамках множества локальных идентификаторов, относящихся к одному глобальному идентификатору.
Такой централизованный подход позволяет избежать появления в решении одинаковых кодов ошибок с разными смысловыми значениями. Это нужно, чтобы исключить проблему транзита кодов ошибок через разные API. Например, такая проблема возникает, когда драйверы вызывают функции библиотеки kdf, получают коды ошибок и возвращают эти коды через свои API. Если формировать коды ошибок без централизованного подхода, то один и тот же код ошибки может иметь разные смысловые значения для библиотеки kdf и для драйвера. В таких условиях драйверы возвращают корректные коды ошибок, если только выполняется преобразование кодов ошибок библиотеки kdf в коды ошибок каждого из драйверов. То есть коды ошибок назначаются так, чтобы не выполнять конвертацию этих кодов при транзите через разные API.
Общие коды возврата типа Retcode
Общие коды возврата типа Retcode, которые определены в заголовочном файле retcode.h, приведены в таблице ниже. Также в этой таблице показано соответствие между кодами возврата типа Retcode и кодами возврата типа nk_err_t, которые определены в заголовочном файле sysroot-*-kos/include/nk/errno.h из состава KasperskyOS SDK. Сведения об этом соответствии требуются, чтобы конвертировать коды возврата этих двух типов между собой. Например, конвертация нужна, если разрабатываемая функция, которая возвращает значения типа Retcode, "оборачивает" функцию транспортного кода, которая возвращает значения типа nk_err_t. При этом следует учитывать, что конвертация возможна не всегда по следующим причинам:
nk_err_t соответствует несколько кодов возврата типа Retcode, то есть невозможно однозначно определить, какому именно коду возврата типа Retcode соответствует код возврата типа nk_err_t, который требуется конвертировать.Общие коды возврата типа Retcode
Код возврата типа Retcode |
Описание |
Код возврата типа nk_err_t |
|---|---|---|
|
Функция завершилась успешно. |
|
|
Параметр функции некорректен. |
|
|
Нет соединения между клиентской и серверной сторонами взаимодействия. Например, отсутствует серверный IPC-дескриптор. |
|
|
Недостаточно памяти для выполнения операции. |
|
|
Недостаточный размер буфера. |
|
|
Функция завершилась с внутренней ошибкой, которая связана с некорректной логикой. Примерами внутренних ошибок являются: выход значений за допустимые пределы, появление нулевых указателей и значений там, где этого быть не должно. |
Нет |
|
Ошибка отправки IPC-сообщения. |
Нет |
|
Ошибка приема IPC-сообщения. |
Нет |
|
IPC-сообщение не было передано из-за источника IPC-сообщения. |
Нет |
|
IPC-сообщение не было передано из-за приемника IPC-сообщения. |
Нет |
|
IPC прервано другим потоком процесса. |
Нет |
|
Формат данных некорректен. |
Нет |
|
Сигнализирует, что функцию нужно вызвать повторно. |
Нет |
|
Функция завершилась с ошибкой. |
Нет |
|
Операция с ресурсом недоступна. |
|
|
Инициализация не выполнена. |
|
|
Функция не реализована. |
Нет |
|
Большой размер буфера. |
|
|
Ресурс временно недоступен. |
Нет |
|
Ресурс не найден. |
Нет |
|
Время ожидания истекло. |
|
|
Операция запрещена механизмами безопасности. |
|
|
Операция приведет к блокировке. |
Нет |
|
Операция прервана. |
|
|
В обработчике прерывания вызвана недопустимая функция. |
Нет |
|
Множество элементов уже содержит добавляемый элемент. |
|
|
Операция не может быть выполнена. |
Нет |
|
Права доступа к ресурсу отозваны. |
|
|
Квота на ресурс превышена. |
Нет |
|
Устройство не найдено. |
Нет |
|
Произошло переполнение. |
Нет |
|
Операция уже выполнена. |
Нет |
|
Операция не была запущена. |
Нет |
|
Источник энтропии может быть ненадежным. |
Нет |
|
Возникла взаимная блокировка. |
Нет |
|
Дескриптор закрыт. |
Нет |
Определение кода ошибки типа Retcode
Чтобы определить код ошибки типа Retcode, разработчику решения нужно использовать макрос MAKE_RETCODE(), определенный в заголовочном файле retcode.h. При этом через параметр customer нужно передать символьную константу RC_CUSTOMER_TRUE.
Пример:
#define LV_EBADREQUEST MAKE_RETCODE(RC_CUSTOMER_TRUE, RC_SPACE_APPS, RC_FACILITY_LogViewer, 5, "Bad request")
Описание ошибки, которое передается через параметр desc, не используется макросом MAKE_RETCODE(). Это описание требуется, чтобы создать базу данных кодов ошибок при сборке решения на базе KasperskyOS. В настоящее время механизм для создания и использования такой базы данных не реализован.
Чтение полей структуры кода ошибки типа Retcode
Макросы RC_GET_CUSTOMER(), RC_GET_SPACE(), RC_GET_FACILITY() и RC_GET_CODE(), определенные в заголовочном файле retcode.h, позволяют читать поля структуры кода ошибки типа Retcode.
Макросы RETCODE_HR_PARAMS() и RETCODE_HR_FMT, определенные в заголовочном файле sysroot-*-kos/include/rtl/retcode_hr.h из состава KasperskyOS SDK, предназначены для форматированного вывода сведений об ошибке типа Retcode.