diff options
author | Chuck Lever <chuck.lever@oracle.com> | 2006-08-22 20:06:18 -0400 |
---|---|---|
committer | Trond Myklebust <Trond.Myklebust@netapp.com> | 2006-09-22 23:24:47 -0400 |
commit | edb267a688fcee5335d596752f117a30c7152e44 (patch) | |
tree | b73a91f17f22baa81a3c0a4df1b01929680a2807 | |
parent | 39d7bbcb5ba5e9d8d658b70903dd7939400e57db (diff) |
SUNRPC: add xprt switch API for printing formatted remote peer addresses
Add a new method to the transport switch API to provide a way to convert
the opaque contents of xprt->addr to a human-readable string.
Test plan:
Compile kernel with CONFIG_NFS enabled.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: Trond Myklebust <Trond.Myklebust@netapp.com>
-rw-r--r-- | include/linux/sunrpc/xprt.h | 11 | ||||
-rw-r--r-- | net/sunrpc/xprtsock.c | 79 |
2 files changed, 82 insertions, 8 deletions
diff --git a/include/linux/sunrpc/xprt.h b/include/linux/sunrpc/xprt.h index 84122559fa17..8372ab8fc9b5 100644 --- a/include/linux/sunrpc/xprt.h +++ b/include/linux/sunrpc/xprt.h | |||
@@ -51,6 +51,14 @@ struct rpc_timeout { | |||
51 | unsigned char to_exponential; | 51 | unsigned char to_exponential; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | enum rpc_display_format_t { | ||
55 | RPC_DISPLAY_ADDR = 0, | ||
56 | RPC_DISPLAY_PORT, | ||
57 | RPC_DISPLAY_PROTO, | ||
58 | RPC_DISPLAY_ALL, | ||
59 | RPC_DISPLAY_MAX, | ||
60 | }; | ||
61 | |||
54 | struct rpc_task; | 62 | struct rpc_task; |
55 | struct rpc_xprt; | 63 | struct rpc_xprt; |
56 | struct seq_file; | 64 | struct seq_file; |
@@ -103,6 +111,7 @@ struct rpc_rqst { | |||
103 | 111 | ||
104 | struct rpc_xprt_ops { | 112 | struct rpc_xprt_ops { |
105 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); | 113 | void (*set_buffer_size)(struct rpc_xprt *xprt, size_t sndsize, size_t rcvsize); |
114 | char * (*print_addr)(struct rpc_xprt *xprt, enum rpc_display_format_t format); | ||
106 | int (*reserve_xprt)(struct rpc_task *task); | 115 | int (*reserve_xprt)(struct rpc_task *task); |
107 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); | 116 | void (*release_xprt)(struct rpc_xprt *xprt, struct rpc_task *task); |
108 | void (*rpcbind)(struct rpc_task *task); | 117 | void (*rpcbind)(struct rpc_task *task); |
@@ -207,6 +216,8 @@ struct rpc_xprt { | |||
207 | void (*old_data_ready)(struct sock *, int); | 216 | void (*old_data_ready)(struct sock *, int); |
208 | void (*old_state_change)(struct sock *); | 217 | void (*old_state_change)(struct sock *); |
209 | void (*old_write_space)(struct sock *); | 218 | void (*old_write_space)(struct sock *); |
219 | |||
220 | char * address_strings[RPC_DISPLAY_MAX]; | ||
210 | }; | 221 | }; |
211 | 222 | ||
212 | #define XPRT_LAST_FRAG (1 << 0) | 223 | #define XPRT_LAST_FRAG (1 << 0) |
diff --git a/net/sunrpc/xprtsock.c b/net/sunrpc/xprtsock.c index 4c98b89a5b48..cb8e6c34e12f 100644 --- a/net/sunrpc/xprtsock.c +++ b/net/sunrpc/xprtsock.c | |||
@@ -125,6 +125,47 @@ static inline void xs_pktdump(char *msg, u32 *packet, unsigned int count) | |||
125 | } | 125 | } |
126 | #endif | 126 | #endif |
127 | 127 | ||
128 | static void xs_format_peer_addresses(struct rpc_xprt *xprt) | ||
129 | { | ||
130 | struct sockaddr_in *addr = (struct sockaddr_in *) &xprt->addr; | ||
131 | char *buf; | ||
132 | |||
133 | buf = kzalloc(20, GFP_KERNEL); | ||
134 | if (buf) { | ||
135 | snprintf(buf, 20, "%u.%u.%u.%u", | ||
136 | NIPQUAD(addr->sin_addr.s_addr)); | ||
137 | } | ||
138 | xprt->address_strings[RPC_DISPLAY_ADDR] = buf; | ||
139 | |||
140 | buf = kzalloc(8, GFP_KERNEL); | ||
141 | if (buf) { | ||
142 | snprintf(buf, 8, "%u", | ||
143 | ntohs(addr->sin_port)); | ||
144 | } | ||
145 | xprt->address_strings[RPC_DISPLAY_PORT] = buf; | ||
146 | |||
147 | if (xprt->prot == IPPROTO_UDP) | ||
148 | xprt->address_strings[RPC_DISPLAY_PROTO] = "udp"; | ||
149 | else | ||
150 | xprt->address_strings[RPC_DISPLAY_PROTO] = "tcp"; | ||
151 | |||
152 | buf = kzalloc(48, GFP_KERNEL); | ||
153 | if (buf) { | ||
154 | snprintf(buf, 48, "addr=%u.%u.%u.%u port=%u proto=%s", | ||
155 | NIPQUAD(addr->sin_addr.s_addr), | ||
156 | ntohs(addr->sin_port), | ||
157 | xprt->prot == IPPROTO_UDP ? "udp" : "tcp"); | ||
158 | } | ||
159 | xprt->address_strings[RPC_DISPLAY_ALL] = buf; | ||
160 | } | ||
161 | |||
162 | static void xs_free_peer_addresses(struct rpc_xprt *xprt) | ||
163 | { | ||
164 | kfree(xprt->address_strings[RPC_DISPLAY_ADDR]); | ||
165 | kfree(xprt->address_strings[RPC_DISPLAY_PORT]); | ||
166 | kfree(xprt->address_strings[RPC_DISPLAY_ALL]); | ||
167 | } | ||
168 | |||
128 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) | 169 | #define XS_SENDMSG_FLAGS (MSG_DONTWAIT | MSG_NOSIGNAL) |
129 | 170 | ||
130 | static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len) | 171 | static inline int xs_send_head(struct socket *sock, struct sockaddr *addr, int addrlen, struct xdr_buf *xdr, unsigned int base, unsigned int len) |
@@ -490,6 +531,7 @@ static void xs_destroy(struct rpc_xprt *xprt) | |||
490 | 531 | ||
491 | xprt_disconnect(xprt); | 532 | xprt_disconnect(xprt); |
492 | xs_close(xprt); | 533 | xs_close(xprt); |
534 | xs_free_peer_addresses(xprt); | ||
493 | kfree(xprt->slot); | 535 | kfree(xprt->slot); |
494 | } | 536 | } |
495 | 537 | ||
@@ -965,6 +1007,19 @@ static unsigned short xs_get_random_port(void) | |||
965 | } | 1007 | } |
966 | 1008 | ||
967 | /** | 1009 | /** |
1010 | * xs_print_peer_address - format an IPv4 address for printing | ||
1011 | * @xprt: generic transport | ||
1012 | * @format: flags field indicating which parts of the address to render | ||
1013 | */ | ||
1014 | static char *xs_print_peer_address(struct rpc_xprt *xprt, enum rpc_display_format_t format) | ||
1015 | { | ||
1016 | if (xprt->address_strings[format] != NULL) | ||
1017 | return xprt->address_strings[format]; | ||
1018 | else | ||
1019 | return "unprintable"; | ||
1020 | } | ||
1021 | |||
1022 | /** | ||
968 | * xs_set_port - reset the port number in the remote endpoint address | 1023 | * xs_set_port - reset the port number in the remote endpoint address |
969 | * @xprt: generic transport | 1024 | * @xprt: generic transport |
970 | * @port: new port number | 1025 | * @port: new port number |
@@ -1019,8 +1074,6 @@ static void xs_udp_connect_worker(void *args) | |||
1019 | if (xprt->shutdown || !xprt_bound(xprt)) | 1074 | if (xprt->shutdown || !xprt_bound(xprt)) |
1020 | goto out; | 1075 | goto out; |
1021 | 1076 | ||
1022 | dprintk("RPC: xs_udp_connect_worker for xprt %p\n", xprt); | ||
1023 | |||
1024 | /* Start by resetting any existing state */ | 1077 | /* Start by resetting any existing state */ |
1025 | xs_close(xprt); | 1078 | xs_close(xprt); |
1026 | 1079 | ||
@@ -1034,6 +1087,9 @@ static void xs_udp_connect_worker(void *args) | |||
1034 | goto out; | 1087 | goto out; |
1035 | } | 1088 | } |
1036 | 1089 | ||
1090 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | ||
1091 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1092 | |||
1037 | if (!xprt->inet) { | 1093 | if (!xprt->inet) { |
1038 | struct sock *sk = sock->sk; | 1094 | struct sock *sk = sock->sk; |
1039 | 1095 | ||
@@ -1102,8 +1158,6 @@ static void xs_tcp_connect_worker(void *args) | |||
1102 | if (xprt->shutdown || !xprt_bound(xprt)) | 1158 | if (xprt->shutdown || !xprt_bound(xprt)) |
1103 | goto out; | 1159 | goto out; |
1104 | 1160 | ||
1105 | dprintk("RPC: xs_tcp_connect_worker for xprt %p\n", xprt); | ||
1106 | |||
1107 | if (!xprt->sock) { | 1161 | if (!xprt->sock) { |
1108 | /* start from scratch */ | 1162 | /* start from scratch */ |
1109 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { | 1163 | if ((err = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, &sock)) < 0) { |
@@ -1119,6 +1173,9 @@ static void xs_tcp_connect_worker(void *args) | |||
1119 | /* "close" the socket, preserving the local port */ | 1173 | /* "close" the socket, preserving the local port */ |
1120 | xs_tcp_reuse_connection(xprt); | 1174 | xs_tcp_reuse_connection(xprt); |
1121 | 1175 | ||
1176 | dprintk("RPC: worker connecting xprt %p to address: %s\n", | ||
1177 | xprt, xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1178 | |||
1122 | if (!xprt->inet) { | 1179 | if (!xprt->inet) { |
1123 | struct sock *sk = sock->sk; | 1180 | struct sock *sk = sock->sk; |
1124 | 1181 | ||
@@ -1260,6 +1317,7 @@ static void xs_tcp_print_stats(struct rpc_xprt *xprt, struct seq_file *seq) | |||
1260 | 1317 | ||
1261 | static struct rpc_xprt_ops xs_udp_ops = { | 1318 | static struct rpc_xprt_ops xs_udp_ops = { |
1262 | .set_buffer_size = xs_udp_set_buffer_size, | 1319 | .set_buffer_size = xs_udp_set_buffer_size, |
1320 | .print_addr = xs_print_peer_address, | ||
1263 | .reserve_xprt = xprt_reserve_xprt_cong, | 1321 | .reserve_xprt = xprt_reserve_xprt_cong, |
1264 | .release_xprt = xprt_release_xprt_cong, | 1322 | .release_xprt = xprt_release_xprt_cong, |
1265 | .rpcbind = rpc_getport, | 1323 | .rpcbind = rpc_getport, |
@@ -1277,6 +1335,7 @@ static struct rpc_xprt_ops xs_udp_ops = { | |||
1277 | }; | 1335 | }; |
1278 | 1336 | ||
1279 | static struct rpc_xprt_ops xs_tcp_ops = { | 1337 | static struct rpc_xprt_ops xs_tcp_ops = { |
1338 | .print_addr = xs_print_peer_address, | ||
1280 | .reserve_xprt = xprt_reserve_xprt, | 1339 | .reserve_xprt = xprt_reserve_xprt, |
1281 | .release_xprt = xs_tcp_release_xprt, | 1340 | .release_xprt = xs_tcp_release_xprt, |
1282 | .rpcbind = rpc_getport, | 1341 | .rpcbind = rpc_getport, |
@@ -1301,8 +1360,6 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1301 | { | 1360 | { |
1302 | size_t slot_table_size; | 1361 | size_t slot_table_size; |
1303 | 1362 | ||
1304 | dprintk("RPC: setting up udp-ipv4 transport...\n"); | ||
1305 | |||
1306 | xprt->max_reqs = xprt_udp_slot_table_entries; | 1363 | xprt->max_reqs = xprt_udp_slot_table_entries; |
1307 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); | 1364 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); |
1308 | xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); | 1365 | xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); |
@@ -1332,6 +1389,10 @@ int xs_setup_udp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1332 | else | 1389 | else |
1333 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); | 1390 | xprt_set_timeout(&xprt->timeout, 5, 5 * HZ); |
1334 | 1391 | ||
1392 | xs_format_peer_addresses(xprt); | ||
1393 | dprintk("RPC: set up transport to address %s\n", | ||
1394 | xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1395 | |||
1335 | return 0; | 1396 | return 0; |
1336 | } | 1397 | } |
1337 | 1398 | ||
@@ -1345,8 +1406,6 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1345 | { | 1406 | { |
1346 | size_t slot_table_size; | 1407 | size_t slot_table_size; |
1347 | 1408 | ||
1348 | dprintk("RPC: setting up tcp-ipv4 transport...\n"); | ||
1349 | |||
1350 | xprt->max_reqs = xprt_tcp_slot_table_entries; | 1409 | xprt->max_reqs = xprt_tcp_slot_table_entries; |
1351 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); | 1410 | slot_table_size = xprt->max_reqs * sizeof(xprt->slot[0]); |
1352 | xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); | 1411 | xprt->slot = kzalloc(slot_table_size, GFP_KERNEL); |
@@ -1375,5 +1434,9 @@ int xs_setup_tcp(struct rpc_xprt *xprt, struct rpc_timeout *to) | |||
1375 | else | 1434 | else |
1376 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); | 1435 | xprt_set_timeout(&xprt->timeout, 2, 60 * HZ); |
1377 | 1436 | ||
1437 | xs_format_peer_addresses(xprt); | ||
1438 | dprintk("RPC: set up transport to address %s\n", | ||
1439 | xs_print_peer_address(xprt, RPC_DISPLAY_ALL)); | ||
1440 | |||
1378 | return 0; | 1441 | return 0; |
1379 | } | 1442 | } |