<div dir="ltr"><br><br>On Sat, Aug 23, 2014 at 12:33 AM, Loris Degioanni <<a href="mailto:loris@draios.com">loris@draios.com</a>> wrote:<br>> On 8/20/2014 2:33 AM, Rohan Puri wrote:<br>>><br>>> On Tue, Aug 19, 2014 at 10:04 PM, Loris Degioanni <<a href="mailto:loris@draios.com">loris@draios.com</a>><br>
>> wrote:<br>>>><br>>>> Sure, here's some more context.<br>>>><br>>>> I'm one of the developers of sysdig (<a href="http://www.sysdig.org">www.sysdig.org</a>), a tool that<br>
>>> captures system calls and uses them to offer advanced system monitoring.<br>>>> One of the features that our diver offers is the tcpdump-derived concept<br>>>> of "snaplen": when a system call with a buffer is captured, it's<br>
>>> possible to choose how many bytes of that buffer are copied to the<br>>>> driver capture buffer. This makes it possible to tune buffer utilization<br>>>> and CPU usage vs completeness of data.<br>
>>><br>>>> Since this feature is important and heavily used, I'd like to extend it<br>>>> so that the user has per-fd-type snaplen control. A typical use case is:<br>>>> "I want 1000 bytes of each socket buffer, because I'm interested in<br>
>>> looking at protocol activity, but I don't care about files and so I'm ok<br>>>> with just 20 bytes from them". In order for this feature to be useful,<br>>>> it needs to be very fast: we use tracepoints to capture system calls, so<br>
>>> we slow down the original process if we take too long.<br>>>><br>>>> And since I'm here, let me expand my question. Another useful thing to<br>>>> do would be per-filename snaplen. Use case: "I want the whole content of<br>
>>> reads and writes to files that are in /etc, but I want only 20 bytes<br>>>> from any other system call". This would I guess involve unpacking the<br>>>> file structure and retrieving the full file name. Is there any way to do<br>
>>> it safely and efficiently?<br>>>><br>>>> Thanks,<br>>>> Loris<br>>>><br>>>><br>>>> On 8/19/2014 9:02 AM, <a href="mailto:Valdis.Kletnieks@vt.edu">Valdis.Kletnieks@vt.edu</a> wrote:<br>
>>>><br>>>>> On Tue, 19 Aug 2014 08:38:24 -0700, Loris Degioanni said:<br>>>>><br>>>>>> I'm looking for an efficient way to determine the type of an fd (file,<br>>>>>> socket...) given its number, from a kernel module.<br>
>>>><br>>>>> What problem are you trying to solve here? There may be a better API<br>>>>> for<br>>>>> your problem. So step back - what are you trying to accomplish?<br>>>><br>
>>><br>>>> _______________________________________________<br>>>> Kernelnewbies mailing list<br>>>> <a href="mailto:Kernelnewbies@kernelnewbies.org">Kernelnewbies@kernelnewbies.org</a><br>
>>> <a href="http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies">http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies</a><br>>><br>>> Hi Loris,<br>>><br>>> You can get the file type from the fd by doing something like this : -<br>
>><br>>> struct file *file = fget(fd);<br>>> if(!file)<br>>> return error;<br>>> assert(file->f_inode != NULL);<br>>> file_type = (file->f_inode->i_mode & S_IFMT) >> 12;<br>
>><br>>> Also, you can make use of S_IS*(mode) macros, to check for file types.<br>>><br>>> NOTE: fget() makes use of current process's file_struct.<br>>><br>>> Regards,<br>>> - Rohan<br>
><br>><br>> Thanks Rohan,<br>> and for kernels more recent than 3.14 I assume I need to use fdget instead<br>> of fget, right?<br>fdget() calls __fget_light() internally & if you check out the definition of __fget_light(), there is a comment there. Pasting it over here : -<br>
/*<br> * Lightweight file lookup - no refcnt increment if fd table isn't shared.<br> *<br> * You can use this instead of fget if you satisfy all of the following<br> * conditions:<br> * 1) You must call fput_light before exiting the syscall and returning control<br>
* to userspace (i.e. you cannot remember the returned struct file * after<br> * returning to userspace).<br> * 2) You must not call filp_close on the returned struct file * in between<br> * calls to fget_light and fput_light.<br>
* 3) You must not clone the current task in between the calls to fget_light<br> * and fput_light.<br> *<br> * The fput_needed flag returned by fget_light should be passed to the<br> * corresponding fput_light.<br> */<br>
<span class="sewsdo3upn9904e"></span><br>fdget() is different from fget() in 2 ways, if fd table is not shared, meaning files_struct->count is 1 : -<br>1. Doesnt take rcu_read_lock()<br>2. Doesnt increment struct file->f_count.<br>
<br>else it behaves the same as fget(), <b>so yes i think you can use fdget().</b><br>><br>> Loris<br>><br><br>Regards,<br>Rohan<br></div>