My suggestion is to go for a system call, but only call it :
-- when the process starts
-- when receiving a SIG_UPDTRACING
+- when the thread starts
+- when receiving a SIGRTMIN+3 (multithread ?)
+
+Note : save the thread ID (process ID) in the logging function and the update
+handler. Use it as a comparison to check if we are a forked child thread.
+Start a brand new buffer list in that case.
+
Two possibilities :
syscall get_tracing_info
-first parameter : active traces mask (32 bits : 32 traces).
+parameter 1 : trace buffer map address. (id)
+
+parameter 2 : active ? (int)
Concurrency
Multiple traces
By having the number of active traces, we can allocate as much buffers as we
-need. The only thing is that the buffers will only be allocated when receiving
-the signal/starting the process and getting the number of traces actives.
+need. Allocation is done in the kernel with relay_open. User space mapping is
+done when receiving the signal/starting the process and getting the number of
+traces actives.
It means that we must make sure to only update the data structures used by
tracing functions once the buffers are created.
-When adding a new buffer, we should call the set_tracing_info syscall and give
-the new buffers array to the kernel. It's an array of 32 pointers to user pages.
-They will be used by the kernel to get the last pages when the thread dies.
+We could have a syscall "get_next_buffer" that would basically mmap the next
+unmmapped buffer, or return NULL is all buffers are mapped.
If we remove a trace, the kernel should stop the tracing, and then get the last
buffer for this trace. What is important is to make sure no writers are still
accessing this memory area. When the control comes back to the writer, at the
end of the write in a trace, if the trace is marked for switch/delete and the
tracing_level is 0 (after the decrement of the writer itself), then the
- writer must buffer switch, set_tracing_info to NULL and then delete the
- memory area.
+ writer must buffer switch, and then delete the memory area.
Filter
The update tracing info signal will make the thread get the new filter
information. Getting this information will also happen upon process creation.
-parameter 2 for the get tracing info : array of 32 ints (32 bits).
-Each integer is the filter mask for a trace. As there are up to 32 active
-traces, we have 32 integers for filter.
+parameter 3 for the get tracing info : a integer containing the 32 bits mask.
Buffer switch
If a thread dies unexpectedly, we want the kernel to get the last bits of
information before the thread crashes.
-syscall set_tracing_info
-
-parameter 1 : array of 32 user space pointers to current pages or NULL.
-
-
Memory protection
-We want each process to be usable to make a trace unreadable, and each process
-to have its own memory space.
+If a process corrupt its own mmaped buffers, the rest of the trace will be
+readable, and each process have its own memory space.
Two possibilities :
+API :
+
+syscall 1 :
+
+in :
+buffer : NULL means get new traces
+ non NULL means to get the information for the specified buffer
+out :
+buffer : returns the address of the trace buffer
+active : is the trace active ?
+filter : 32 bits filter mask
+
+return : 0 on success, 1 on error.
+
+int ltt_update(void **buffer, int *active, int *filter);
+
+syscall 2 :
+
+in :
+buffer : Switch the specified buffer.
+return : 0 on success, 1 on error.
+
+int ltt_switch(void *buffer);
+
+
+Signal :
+
+SIGRTMIN+3
+(like hardware fault and expiring timer : to the thread, see p. 413 of Advances
+prog. in the UNIX env.)
+
+Will update for itself only : it will remove unnecessary concurrency.
+
+
+
+
+
+
+
+