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