[PATCH v3 5/7] Introduce getfdnlproto to obtain netlink protocol from fd
Dmitry V. Levin
ldv at altlinux.org
Fri Jun 17 12:12:28 UTC 2016
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
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 819 bytes
Desc: not available
URL: <http://lists.strace.io/pipermail/strace-devel/attachments/20160617/e60d249f/attachment.bin>
More information about the Strace-devel
mailing list