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