It wasn't obvious to me the best way to pass in a pointer to the ipv4 (and ipv6 address) to a dynamic trace point (unless I create a temp string first in generic_ip_connect and do the conversion (via "%pI4" and "%pI6" with sprintf) e.g. sprintf(ses->ip_addr, "%pI4", &addr->sin_addr); The approach I tried passing in the pointer to sin_addr (the ipv4_address) caused an oops on loading it the first time and the warning: [14928.818532] event smb3_ipv4_connect has unsafe dereference of argument 3 [14928.818534] print_fmt: "conn_id=0x%llx server=%s addr=%pI4:%d", REC->conn_id, __get_str(hostname), REC->ipaddr, REC->port What I tried was the following (also see attached diff) to print the ipv4 address that we were trying to connect to DECLARE_EVENT_CLASS(smb3_connect_class, TP_PROTO(char *hostname, __u64 conn_id, __u16 port, struct in_addr *ipaddr), TP_ARGS(hostname, conn_id, port, ipaddr), TP_STRUCT__entry( __string(hostname, hostname) __field(__u64, conn_id) __field(__u16, port) __field(const void *, ipaddr) ), TP_fast_assign( __entry->port = port; __entry->conn_id = conn_id; __entry->ipaddr = ipaddr; __assign_str(hostname, hostname); ), TP_printk("conn_id=0x%llx server=%s addr=%pI4:%d", __entry->conn_id, __get_str(hostname), __entry->ipaddr, __entry->port) ) #define DEFINE_SMB3_CONNECT_EVENT(name) \ DEFINE_EVENT(smb3_connect_class, smb3_##name, \ TP_PROTO(char *hostname, \ __u64 conn_id, \ __u16 port, \ struct in_addr *ipaddr), \ TP_ARGS(hostname, conn_id, port, ipaddr)) DEFINE_SMB3_CONNECT_EVENT(ipv4_connect); Any ideas how to pass in the ipv4 address - or is it better to convert it to a string before we call the trace point (which seems wasteful to me but there must be examples of how to pass in structs to printks in trace in Linux) -- Thanks, Steve
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index e6e261dfd107..4cbfca90a47c 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -2590,6 +2590,8 @@ generic_ip_connect(struct TCP_Server_Info *server) sfamily = AF_INET; cifs_dbg(FYI, "%s: connecting to %pI4:%d\n", __func__, &ipv4->sin_addr, ntohs(sport)); + trace_smb3_ipv4_connect(server->hostname, server->conn_id, + ntohs(sport), &ipv4->sin_addr); } if (socket == NULL) { diff --git a/fs/cifs/trace.h b/fs/cifs/trace.h index dafcb6ab050d..3162f484fb85 100644 --- a/fs/cifs/trace.h +++ b/fs/cifs/trace.h @@ -11,7 +11,7 @@ #define _CIFS_TRACE_H #include <linux/tracepoint.h> - +#include <linux/inet.h> /* * Please use this 3-part article as a reference for writing new tracepoints: * https://lwn.net/Articles/379903/ @@ -854,6 +854,41 @@ DEFINE_EVENT(smb3_lease_err_class, smb3_##name, \ DEFINE_SMB3_LEASE_ERR_EVENT(lease_err); +DECLARE_EVENT_CLASS(smb3_connect_class, + TP_PROTO(char *hostname, + __u64 conn_id, + __u16 port, + struct in_addr *ipaddr), + TP_ARGS(hostname, conn_id, port, ipaddr), + TP_STRUCT__entry( + __string(hostname, hostname) + __field(__u64, conn_id) + __field(__u16, port) + __field(const void *, ipaddr) + ), + TP_fast_assign( + __entry->port = port; + __entry->conn_id = conn_id; + __entry->ipaddr = ipaddr; + __assign_str(hostname, hostname); + ), + TP_printk("conn_id=0x%llx server=%s addr=%pI4:%d", + __entry->conn_id, + __get_str(hostname), + __entry->ipaddr, + __entry->port) +) + +#define DEFINE_SMB3_CONNECT_EVENT(name) \ +DEFINE_EVENT(smb3_connect_class, smb3_##name, \ + TP_PROTO(char *hostname, \ + __u64 conn_id, \ + __u16 port, \ + struct in_addr *ipaddr), \ + TP_ARGS(hostname, conn_id, port, ipaddr)) + +DEFINE_SMB3_CONNECT_EVENT(ipv4_connect); + DECLARE_EVENT_CLASS(smb3_reconnect_class, TP_PROTO(__u64 currmid, __u64 conn_id,