On Wed, Jun 15, 2016 at 12:43:03PM +0000, Fabien Siron wrote:
> * defs.h (getfdnlproto): Add.

getfdnlproto?  getfdpath is already quite hard to read, but getfdnlproto?

> * utils.c (getfdinode): New function.
> (getfdnlproto): Likewise.
> ---
>  defs.h |  1 +
>  util.c | 68 
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++------
>  2 files changed, 63 insertions(+), 6 deletions(-)
> 
> diff --git a/defs.h b/defs.h
> index e9a9392..95bfc5a 100644
> --- a/defs.h
> +++ b/defs.h
> @@ -556,6 +556,7 @@ extern void pathtrace_select(const char *);
>  extern int pathtrace_match(struct tcb *);
>  extern int getfdpath(struct tcb *, int, char *, unsigned);
>  extern enum sock_proto getfdproto(struct tcb *, int);
> +extern int getfdnlproto(struct tcb *, int, const struct xlat *);
>  
>  extern const char *xlookup(const struct xlat *, const uint64_t);
>  extern const char *xlat_search(const struct xlat *, const size_t, const 
> uint64_t);
> diff --git a/util.c b/util.c
> index c3bcaba..c1ce8c4 100644
> --- a/util.c
> +++ b/util.c
> @@ -502,21 +502,77 @@ getfdproto(struct tcb *tcp, int fd)
>  #endif
>  }
>  
> -void
> -printfd(struct tcb *tcp, int fd)
> +static unsigned long
> +getfdinode(struct tcb *tcp, int fd)
>  {
>       char path[PATH_MAX + 1];
> -     if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
> +     if (getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
>               static const char socket_prefix[] = "socket:[";
>               const size_t socket_prefix_len = sizeof(socket_prefix) - 1;
>               const size_t path_len = strlen(path);
>  
> -             tprintf("%d<", fd);
> -             if (show_fd_path > 1 &&
> -                 strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
> +             if (strncmp(path, socket_prefix, socket_prefix_len) == 0 &&
>                   path[path_len - 1] == ']') {
>                       unsigned long inode =
>                               strtoul(path + socket_prefix_len, NULL, 10);
> +                     return inode;
> +             }
> +     }
> +     return -1;
> +}
> +
> +int
> +getfdnlproto(struct tcb *tcp, int fd, const struct xlat *xprotocols)
> +{
> +     unsigned long inode = getfdinode(tcp, fd);
> +
> +     if (inode != 0) {
> +             char *nl_proto = NULL;
> +             static const char socket_prefix[] = "NETLINK:[";
> +             const size_t socket_prefix_len =
> +                             sizeof(socket_prefix) -1;
> +             nl_proto = get_sockaddr_by_inode_cached(inode);
> +             if (nl_proto == NULL) {
> +                     enum sock_proto proto = getfdproto(tcp, fd);
> +                     nl_proto = get_sockaddr_by_inode(inode, proto);
> +             }
> +             if (nl_proto == NULL)
> +                     return -1;
> +
> +             if (strncmp(nl_proto, socket_prefix,
> +                         socket_prefix_len) == 0) {
> +                     static const char define_prefix[] = "NETLINK_";
> +                     const size_t define_prefix_len =
> +                             sizeof(define_prefix) -1;
> +                     nl_proto += socket_prefix_len;
> +
> +                     for (;xprotocols->str != NULL; xprotocols++) {
> +                             if (strncmp(xprotocols->str,
> +                                            define_prefix,
> +                                         define_prefix_len) != 0)
> +                                     return -1;
> +                             if (strncmp(nl_proto,
> +                                         xprotocols->str + define_prefix_len,
> +                                         strlen(xprotocols->str +
> +                                                define_prefix_len)) == 0)
> +                                     return xprotocols->val;
> +                     }

Something odd has happened with indentation, cannot review.

> +             }
> +     }
> +
> +     return -1;
> +}
> +
> +void
> +printfd(struct tcb *tcp, int fd)
> +{
> +     char path[PATH_MAX + 1];
> +     if (show_fd_path && getfdpath(tcp, fd, path, sizeof(path)) >= 0) {
> +             const size_t path_len = strlen(path);
> +
> +             tprintf("%d<", fd);
> +             if (show_fd_path > 1) {
> +                             unsigned long inode = getfdinode(tcp, fd);

getfdpath is invoked right before getfdinode which in turn invokes
getfdpath, and each getfdpath invocation costs one getxattr syscall...


-- 
ldv

Attachment: pgpBRXzer_dpm.pgp
Description: PGP signature

------------------------------------------------------------------------------
What NetFlow Analyzer can do for you? Monitors network bandwidth and traffic
patterns at an interface-level. Reveals which users, apps, and protocols are 
consuming the most bandwidth. Provides multi-vendor support for NetFlow, 
J-Flow, sFlow and other flows. Make informed decisions using capacity planning
reports. http://sdm.link/zohomanageengine
_______________________________________________
Strace-devel mailing list
Strace-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/strace-devel

Reply via email to