sunrpc: Save remote presentation address in svc_xprt for trace events

TP_printk defines a format string that is passed to user space for
converting raw trace event records to something human-readable.

My user space's printf (Oracle Linux 7), however, does not have a
%pI format specifier. The result is that what is supposed to be an
IP address in the output of "trace-cmd report" is just a string that
says the field couldn't be displayed.

To fix this, adopt the same approach as the client: maintain a pre-
formated presentation address for occasions when %pI is not
available.

The location of the trace_svc_send trace point is adjusted so that
rqst->rq_xprt is not NULL when the trace event is recorded.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
This commit is contained in:
Chuck Lever 2018-03-27 10:51:00 -04:00 committed by J. Bruce Fields
parent 41f306d0c2
commit ece200ddd5
5 changed files with 43 additions and 58 deletions

View File

@ -83,6 +83,7 @@ struct svc_xprt {
size_t xpt_locallen; /* length of address */ size_t xpt_locallen; /* length of address */
struct sockaddr_storage xpt_remote; /* remote peer's address */ struct sockaddr_storage xpt_remote; /* remote peer's address */
size_t xpt_remotelen; /* length of address */ size_t xpt_remotelen; /* length of address */
char xpt_remotebuf[INET6_ADDRSTRLEN + 10];
struct rpc_wait_queue xpt_bc_pending; /* backchannel wait queue */ struct rpc_wait_queue xpt_bc_pending; /* backchannel wait queue */
struct list_head xpt_users; /* callbacks on free */ struct list_head xpt_users; /* callbacks on free */
@ -152,7 +153,10 @@ static inline void svc_xprt_set_remote(struct svc_xprt *xprt,
{ {
memcpy(&xprt->xpt_remote, sa, salen); memcpy(&xprt->xpt_remote, sa, salen);
xprt->xpt_remotelen = salen; xprt->xpt_remotelen = salen;
snprintf(xprt->xpt_remotebuf, sizeof(xprt->xpt_remotebuf) - 1,
"%pISpc", sa);
} }
static inline unsigned short svc_addr_port(const struct sockaddr *sa) static inline unsigned short svc_addr_port(const struct sockaddr *sa)
{ {
const struct sockaddr_in *sin = (const struct sockaddr_in *)sa; const struct sockaddr_in *sin = (const struct sockaddr_in *)sa;

View File

@ -493,20 +493,18 @@ TRACE_EVENT(svc_recv,
__field(u32, xid) __field(u32, xid)
__field(int, len) __field(int, len)
__field(unsigned long, flags) __field(unsigned long, flags)
__dynamic_array(unsigned char, addr, rqst->rq_addrlen) __string(addr, rqst->rq_xprt->xpt_remotebuf)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xid = be32_to_cpu(rqst->rq_xid); __entry->xid = be32_to_cpu(rqst->rq_xid);
__entry->len = len; __entry->len = len;
__entry->flags = rqst->rq_flags; __entry->flags = rqst->rq_flags;
memcpy(__get_dynamic_array(addr), __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
&rqst->rq_addr, rqst->rq_addrlen);
), ),
TP_printk("addr=%pIScp xid=0x%08x len=%d flags=%s", TP_printk("addr=%s xid=0x%08x len=%d flags=%s",
(struct sockaddr *)__get_dynamic_array(addr), __get_str(addr), __entry->xid, __entry->len,
__entry->xid, __entry->len,
show_rqstp_flags(__entry->flags)) show_rqstp_flags(__entry->flags))
); );
@ -519,19 +517,17 @@ DECLARE_EVENT_CLASS(svc_rqst_event,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u32, xid) __field(u32, xid)
__field(unsigned long, flags) __field(unsigned long, flags)
__dynamic_array(unsigned char, addr, rqst->rq_addrlen) __string(addr, rqst->rq_xprt->xpt_remotebuf)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xid = be32_to_cpu(rqst->rq_xid); __entry->xid = be32_to_cpu(rqst->rq_xid);
__entry->flags = rqst->rq_flags; __entry->flags = rqst->rq_flags;
memcpy(__get_dynamic_array(addr), __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
&rqst->rq_addr, rqst->rq_addrlen);
), ),
TP_printk("addr=%pIScp rq_xid=0x%08x flags=%s", TP_printk("addr=%s xid=0x%08x flags=%s",
(struct sockaddr *)__get_dynamic_array(addr), __get_str(addr), __entry->xid,
__entry->xid,
show_rqstp_flags(__entry->flags)) show_rqstp_flags(__entry->flags))
); );
@ -553,20 +549,18 @@ DECLARE_EVENT_CLASS(svc_rqst_status,
__field(u32, xid) __field(u32, xid)
__field(int, status) __field(int, status)
__field(unsigned long, flags) __field(unsigned long, flags)
__dynamic_array(unsigned char, addr, rqst->rq_addrlen) __string(addr, rqst->rq_xprt->xpt_remotebuf)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xid = be32_to_cpu(rqst->rq_xid); __entry->xid = be32_to_cpu(rqst->rq_xid);
__entry->status = status; __entry->status = status;
__entry->flags = rqst->rq_flags; __entry->flags = rqst->rq_flags;
memcpy(__get_dynamic_array(addr), __assign_str(addr, rqst->rq_xprt->xpt_remotebuf);
&rqst->rq_addr, rqst->rq_addrlen);
), ),
TP_printk("addr=%pIScp rq_xid=0x%08x status=%d flags=%s", TP_printk("addr=%s xid=0x%08x status=%d flags=%s",
(struct sockaddr *)__get_dynamic_array(addr), __get_str(addr), __entry->xid,
__entry->xid,
__entry->status, show_rqstp_flags(__entry->flags)) __entry->status, show_rqstp_flags(__entry->flags))
); );
@ -604,25 +598,18 @@ TRACE_EVENT(svc_xprt_do_enqueue,
__field(struct svc_xprt *, xprt) __field(struct svc_xprt *, xprt)
__field(int, pid) __field(int, pid)
__field(unsigned long, flags) __field(unsigned long, flags)
__dynamic_array(unsigned char, addr, xprt != NULL ? __string(addr, xprt->xpt_remotebuf)
xprt->xpt_remotelen : 0)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xprt = xprt; __entry->xprt = xprt;
__entry->pid = rqst? rqst->rq_task->pid : 0; __entry->pid = rqst? rqst->rq_task->pid : 0;
if (xprt) {
memcpy(__get_dynamic_array(addr),
&xprt->xpt_remote,
xprt->xpt_remotelen);
__entry->flags = xprt->xpt_flags; __entry->flags = xprt->xpt_flags;
} else __assign_str(addr, xprt->xpt_remotebuf);
__entry->flags = 0;
), ),
TP_printk("xprt=0x%p addr=%pIScp pid=%d flags=%s", __entry->xprt, TP_printk("xprt=%p addr=%s pid=%d flags=%s",
__get_dynamic_array_len(addr) != 0 ? __entry->xprt, __get_str(addr),
(struct sockaddr *)__get_dynamic_array(addr) : NULL,
__entry->pid, show_svc_xprt_flags(__entry->flags)) __entry->pid, show_svc_xprt_flags(__entry->flags))
); );
@ -634,18 +621,17 @@ DECLARE_EVENT_CLASS(svc_xprt_event,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(struct svc_xprt *, xprt) __field(struct svc_xprt *, xprt)
__field(unsigned long, flags) __field(unsigned long, flags)
__dynamic_array(unsigned char, addr, xprt->xpt_remotelen) __string(addr, xprt->xpt_remotebuf)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xprt = xprt; __entry->xprt = xprt;
__entry->flags = xprt->xpt_flags; __entry->flags = xprt->xpt_flags;
memcpy(__get_dynamic_array(addr), __assign_str(addr, xprt->xpt_remotebuf);
&xprt->xpt_remote, xprt->xpt_remotelen);
), ),
TP_printk("xprt=0x%p addr=%pIScp flags=%s", __entry->xprt, TP_printk("xprt=%p addr=%s flags=%s",
(struct sockaddr *)__get_dynamic_array(addr), __entry->xprt, __get_str(addr),
show_svc_xprt_flags(__entry->flags)) show_svc_xprt_flags(__entry->flags))
); );
@ -682,25 +668,18 @@ TRACE_EVENT(svc_handle_xprt,
__field(struct svc_xprt *, xprt) __field(struct svc_xprt *, xprt)
__field(int, len) __field(int, len)
__field(unsigned long, flags) __field(unsigned long, flags)
__dynamic_array(unsigned char, addr, xprt != NULL ? __string(addr, xprt->xpt_remotebuf)
xprt->xpt_remotelen : 0)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xprt = xprt; __entry->xprt = xprt;
__entry->len = len; __entry->len = len;
if (xprt) {
memcpy(__get_dynamic_array(addr),
&xprt->xpt_remote,
xprt->xpt_remotelen);
__entry->flags = xprt->xpt_flags; __entry->flags = xprt->xpt_flags;
} else __assign_str(addr, xprt->xpt_remotebuf);
__entry->flags = 0;
), ),
TP_printk("xprt=0x%p addr=%pIScp len=%d flags=%s", __entry->xprt, TP_printk("xprt=%p addr=%s len=%d flags=%s",
__get_dynamic_array_len(addr) != 0 ? __entry->xprt, __get_str(addr),
(struct sockaddr *)__get_dynamic_array(addr) : NULL,
__entry->len, show_svc_xprt_flags(__entry->flags)) __entry->len, show_svc_xprt_flags(__entry->flags))
); );
@ -712,18 +691,16 @@ DECLARE_EVENT_CLASS(svc_deferred_event,
TP_STRUCT__entry( TP_STRUCT__entry(
__field(u32, xid) __field(u32, xid)
__dynamic_array(unsigned char, addr, dr->addrlen) __string(addr, dr->xprt->xpt_remotebuf)
), ),
TP_fast_assign( TP_fast_assign(
__entry->xid = be32_to_cpu(*(__be32 *)(dr->args + __entry->xid = be32_to_cpu(*(__be32 *)(dr->args +
(dr->xprt_hlen>>2))); (dr->xprt_hlen>>2)));
memcpy(__get_dynamic_array(addr), &dr->addr, dr->addrlen); __assign_str(addr, dr->xprt->xpt_remotebuf);
), ),
TP_printk("addr=%pIScp xid=0x%08x", TP_printk("addr=%s xid=0x%08x", __get_str(addr), __entry->xid)
(struct sockaddr *)__get_dynamic_array(addr),
__entry->xid)
); );
DEFINE_EVENT(svc_deferred_event, svc_drop_deferred, DEFINE_EVENT(svc_deferred_event, svc_drop_deferred,

View File

@ -173,6 +173,7 @@ void svc_xprt_init(struct net *net, struct svc_xprt_class *xcl,
set_bit(XPT_BUSY, &xprt->xpt_flags); set_bit(XPT_BUSY, &xprt->xpt_flags);
rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending"); rpc_init_wait_queue(&xprt->xpt_bc_pending, "xpt_bc_pending");
xprt->xpt_net = get_net(net); xprt->xpt_net = get_net(net);
strcpy(xprt->xpt_remotebuf, "uninitialized");
} }
EXPORT_SYMBOL_GPL(svc_xprt_init); EXPORT_SYMBOL_GPL(svc_xprt_init);
@ -894,12 +895,12 @@ int svc_send(struct svc_rqst *rqstp)
len = xprt->xpt_ops->xpo_sendto(rqstp); len = xprt->xpt_ops->xpo_sendto(rqstp);
mutex_unlock(&xprt->xpt_mutex); mutex_unlock(&xprt->xpt_mutex);
rpc_wake_up(&xprt->xpt_bc_pending); rpc_wake_up(&xprt->xpt_bc_pending);
trace_svc_send(rqstp, len);
svc_xprt_release(rqstp); svc_xprt_release(rqstp);
if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN) if (len == -ECONNREFUSED || len == -ENOTCONN || len == -EAGAIN)
len = 0; len = 0;
out: out:
trace_svc_send(rqstp, len);
return len; return len;
} }

View File

@ -1310,6 +1310,7 @@ static void svc_tcp_init(struct svc_sock *svsk, struct svc_serv *serv)
set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags); set_bit(XPT_CONG_CTRL, &svsk->sk_xprt.xpt_flags);
if (sk->sk_state == TCP_LISTEN) { if (sk->sk_state == TCP_LISTEN) {
dprintk("setting up TCP socket for listening\n"); dprintk("setting up TCP socket for listening\n");
strcpy(svsk->sk_xprt.xpt_remotebuf, "listener");
set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags); set_bit(XPT_LISTENER, &svsk->sk_xprt.xpt_flags);
sk->sk_data_ready = svc_tcp_listen_data_ready; sk->sk_data_ready = svc_tcp_listen_data_ready;
set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags);

View File

@ -401,8 +401,10 @@ static struct svcxprt_rdma *rdma_create_xprt(struct svc_serv *serv,
*/ */
set_bit(XPT_CONG_CTRL, &cma_xprt->sc_xprt.xpt_flags); set_bit(XPT_CONG_CTRL, &cma_xprt->sc_xprt.xpt_flags);
if (listener) if (listener) {
strcpy(cma_xprt->sc_xprt.xpt_remotebuf, "listener");
set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags); set_bit(XPT_LISTENER, &cma_xprt->sc_xprt.xpt_flags);
}
return cma_xprt; return cma_xprt;
} }