Good design to expose debug info from kernel module
Gilboa Davara
gilboad at gmail.com
Mon Mar 30 17:08:38 IDT 2015
On Mon, Mar 30, 2015 at 3:44 PM, Elazar Leibovich <elazarl at gmail.com> wrote:
> Sounds good, thanks (although it'll be harder to use from non-C programs).
I usually complement each kernel module with a user-mode C library
wrapped inside a nice / easy to use (...) C++ class that handles the
"difficult bits".
It far easier to make a C++ class that handles idiot-proof (E.g.
string commands) data than doing it inside the kernel.
(Plus, when a user mode library goes up the flame due to bad input,
you don't end up with a dead machine...)
> Do you have a good idea how to stream information as a response to ioctl?
Use TLV (type / length / value-array).
typedef union _answer_data_ {
int __out error_code;
int __out next_answer_time;
struct access_info {
int __out access_count;
int __out user_count;
};
} answer_data_t;
typedef struct _debug_request_
{
request_t request_type;
void *request_pointer;
answer_t answer_type; <--------------- Answer type. ( Enum, define, etc ).
int answer_buffer_size; <--------------- User supplied answer
buffer size (in answer_data union units).
int __out answer_buffer_used; <-------- Answer buffer used size
(number of answers copied by the kernel).
answer_data_t *answer_data_array; <-- Answer buffer array
(user-mode pointer).
} debug_request_t;
Now, in-case of multiple answers, you simply
copy_to_user((void *)&debug_request_copy->answer_data_array[count],
(void *)&kernel_answer,
sizeof(answer_data_t));
count ++;
.. To copy each answer to the user buffer.
Once the array is depleted, the kernel function returns with a valid
error code (E.g. -EEXIST) and tells to the user mode caller that
there's additional data to be read (E.g. until the kernel returns
-EWOULDBLOCK).
Alternatively (and somewhat more complex) you can setup mmap over file
handle, and simply map a static kernel buffer directly to the user
mode. Though, unless you need to stream huge amounts of data and/or
ioctl performance penalty [50-200ns] is too high, I wouldn't bother.
BTW, Most likely your are aware of this, but just in case, never
access the user mode buffer directly. When you first access the
request buffer you copy it (copy_from_user) to kernel debug_request
(no need to allocate it, considering its size, you shouldn't have any
issues using stack, even on i386).
- Gilboa
More information about the Linux-il
mailing list