53
53
"tcp_send failure"
54
54
]
55
55
56
+
56
57
class RdsInfo :
57
58
"""Class to implement standard RDS info operations."""
58
59
60
+ USAGE_MSG = (
61
+ "Usage: python rds_info.py <option>\n "
62
+ "Available options:\n "
63
+ " -I: Get RDS InfiniBand connections\n "
64
+ " -T: Get RDS TCP Connections\n "
65
+ " -c: Get RDS counters\n "
66
+ " -k: Get RDS socket information\n "
67
+ " -n: Get RDS connection details\n "
68
+ " -p: Get RDS connection paths\n "
69
+ " -r: Get RDS receive queues\n "
70
+ " -s: Get RDS send queues\n "
71
+ " -t: Get RDS retransmit queues\n "
72
+ " --help: Show this help message\n "
73
+ )
74
+
59
75
libc = ctypes .CDLL ("libc.so.6" , use_errno = True )
60
76
61
77
def create_rds_socket (self ):
@@ -67,10 +83,12 @@ def create_rds_socket(self):
67
83
def get_rds_info_data (self , sock_fd , query_type ):
68
84
"""Retrieve RDS information data."""
69
85
data_len = ctypes .c_int (0 )
70
- res = self .libc .getsockopt (sock_fd , SOL_RDS , query_type , None , ctypes .byref (data_len ))
86
+ res = self .libc .getsockopt (
87
+ sock_fd , SOL_RDS , query_type , None , ctypes .byref (data_len ))
71
88
if res < 0 :
72
89
data_buffer = ctypes .create_string_buffer (int (data_len .value ))
73
- res = self .libc .getsockopt (sock_fd , SOL_RDS , query_type , data_buffer , ctypes .byref (data_len ))
90
+ res = self .libc .getsockopt (
91
+ sock_fd , SOL_RDS , query_type , data_buffer , ctypes .byref (data_len ))
74
92
if res < 0 :
75
93
return None
76
94
@@ -120,7 +138,8 @@ def get_down_time(conn_time, attempt_time):
120
138
@staticmethod
121
139
def decode_flags (value ):
122
140
"""Decode RDS Flags."""
123
- flags = "" .join ([char if value & (1 << i ) else "-" for i , char in enumerate ("scCE" )])
141
+ flags = "" .join (
142
+ [char if value & (1 << i ) else "-" for i , char in enumerate ("scCE" )])
124
143
return flags
125
144
126
145
def get_rds_ib_conns (self , sock_fd ):
@@ -142,10 +161,11 @@ def get_rds_ib_conns(self, sock_fd):
142
161
src_qp = self .htosi (data [i + 76 :i + 80 ], True )
143
162
dst_qp = self .htosi (data [i + 88 :i + 92 ], True )
144
163
145
- res .append (f"{ saddr :14} { daddr :14} { tos :3} { sol :2} { s_dev :31} { d_dev :32} { src_qp :9} { dst_qp :9} " )
164
+ res .append (
165
+ f"{ saddr :14} { daddr :14} { tos :3} { sol :2} { s_dev :31} { d_dev :32} { src_qp :9} { dst_qp :9} " )
146
166
return "\n " .join (res )
147
167
148
- def get_rds_tcp_sockets (self , sock_fd ):
168
+ def get_rds_tcp_conns (self , sock_fd ):
149
169
"""Get RDS_INFO_TCP_SOCKETS from socket and parse it."""
150
170
data , each = self .get_rds_info_data (sock_fd , RDS_INFO_TCP_SOCKETS )
151
171
@@ -160,9 +180,12 @@ def get_rds_tcp_sockets(self, sock_fd):
160
180
rport = str (int (data [i + 10 :i + 12 ].hex (), 16 ))
161
181
hdr_remain = str (int (data [i + 12 :i + 13 ].hex (), 16 ))
162
182
data_remain = str (int (data [i + 13 :i + 14 ].hex (), 16 ))
163
- sent_nxt = str (self .little_endian_to_unsigned (data [i + 28 :i + 32 ].hex (), 32 ))
164
- exp_una = str (self .little_endian_to_unsigned (data [i + 32 :i + 36 ].hex (), 32 ))
165
- seen_una = str (self .little_endian_to_unsigned (data [i + 36 :i + 40 ].hex (), 32 ))
183
+ sent_nxt = str (self .little_endian_to_unsigned (
184
+ data [i + 28 :i + 32 ].hex (), 32 ))
185
+ exp_una = str (self .little_endian_to_unsigned (
186
+ data [i + 32 :i + 36 ].hex (), 32 ))
187
+ seen_una = str (self .little_endian_to_unsigned (
188
+ data [i + 36 :i + 40 ].hex (), 32 ))
166
189
167
190
res .append (
168
191
f"{ laddr :15} { lport :5} { raddr :15} { rport :5} "
@@ -194,10 +217,13 @@ def get_rds_conns(self, sock_fd):
194
217
for i in range (0 , len (data ), each ):
195
218
laddr = socket .inet_ntoa (data [i + 16 :i + 20 ])
196
219
raddr = socket .inet_ntoa (data [i + 20 :i + 24 ])
197
- tos = str (struct .unpack ("<b" , data [i + 41 : i + 42 ])[0 ])
198
- next_tx = str (self .little_endian_to_unsigned (data [i + 0 : i + 4 ].hex (), 32 ))
199
- next_rx = str (self .little_endian_to_unsigned (data [i + 8 : i + 12 ].hex (), 32 ))
200
- flags = self .decode_flags (int (struct .unpack ("<b" , data [i + 40 : i + 41 ])[0 ]))
220
+ tos = str (struct .unpack ("<b" , data [i + 41 : i + 42 ])[0 ])
221
+ next_tx = str (self .little_endian_to_unsigned (
222
+ data [i + 0 : i + 4 ].hex (), 32 ))
223
+ next_rx = str (self .little_endian_to_unsigned (
224
+ data [i + 8 : i + 12 ].hex (), 32 ))
225
+ flags = self .decode_flags (
226
+ int (struct .unpack ("<b" , data [i + 40 : i + 41 ])[0 ]))
201
227
202
228
res .append (f"{ laddr } { raddr } { tos } { next_rx } { next_tx } { flags } " )
203
229
@@ -215,21 +241,22 @@ def get_rds_sockets(self, sock_fd):
215
241
res = []
216
242
217
243
for i in range (0 , len (data ), each ):
218
- laddr = socket .inet_ntoa (data [i + 4 : i + 8 ])
219
- raddr = socket .inet_ntoa (data [i + 8 : i + 12 ])
220
- lport = str (int (data [i + 12 : i + 14 ].hex (), 16 ))
221
- rport = str (int (data [i + 14 : i + 16 ].hex (), 16 ))
244
+ laddr = socket .inet_ntoa (data [i + 4 : i + 8 ])
245
+ raddr = socket .inet_ntoa (data [i + 8 : i + 12 ])
246
+ lport = str (int (data [i + 12 : i + 14 ].hex (), 16 ))
247
+ rport = str (int (data [i + 14 : i + 16 ].hex (), 16 ))
222
248
223
- snd_buf = str (struct .unpack ("<I" , data [i : i + 4 ])[0 ])
224
- rcv_buf = self .little_endian_to_unsigned (data [i + 16 : i + 20 ].hex (), 32 )
225
- inode = str (struct .unpack ("<Q" , data [i + 20 : i + 28 ])[0 ])
249
+ snd_buf = str (struct .unpack ("<I" , data [i : i + 4 ])[0 ])
250
+ rcv_buf = self .little_endian_to_unsigned (
251
+ data [i + 16 : i + 20 ].hex (), 32 )
252
+ inode = str (struct .unpack ("<Q" , data [i + 20 : i + 28 ])[0 ])
226
253
227
254
# Default values for pid and comm
228
255
pid , comm = "NA" , "NA"
229
256
230
257
try :
231
258
cong = self .htosi (data [i + 32 :i + 36 ], True )
232
- pid = struct .unpack ("<I" , data [i + 28 : i + 32 ])[0 ]
259
+ pid = struct .unpack ("<I" , data [i + 28 : i + 32 ])[0 ]
233
260
comm = psutil .Process (pid ).name ()
234
261
except (psutil .NoSuchProcess , psutil .AccessDenied , struct .error ):
235
262
comm , pid , cong = "NA" , "NA" , - 1
@@ -273,13 +300,13 @@ def get_rds_queues(self, sock_fd, arg):
273
300
res = []
274
301
275
302
for i in range (0 , len (data ), each ):
276
- laddr = str (socket .inet_ntoa (data [i + 12 : i + 16 ]))
277
- raddr = str (socket .inet_ntoa (data [i + 16 : i + 20 ]))
278
- lport = str (int (data [i + 20 : i + 22 ].hex (), 16 ))
279
- rport = str (int (data [i + 22 : i + 24 ].hex (), 16 ))
280
- tos = str (struct .unpack ("<b" , data [i + 24 : i + 25 ])[0 ])
281
- seq = str (struct .unpack ("<Q" , data [i : i + 8 ])[0 ])
282
- byte = str (struct .unpack ("<I" , data [i + 8 : i + 12 ])[0 ])
303
+ laddr = str (socket .inet_ntoa (data [i + 12 : i + 16 ]))
304
+ raddr = str (socket .inet_ntoa (data [i + 16 : i + 20 ]))
305
+ lport = str (int (data [i + 20 : i + 22 ].hex (), 16 ))
306
+ rport = str (int (data [i + 22 : i + 24 ].hex (), 16 ))
307
+ tos = str (struct .unpack ("<b" , data [i + 24 : i + 25 ])[0 ])
308
+ seq = str (struct .unpack ("<Q" , data [i : i + 8 ])[0 ])
309
+ byte = str (struct .unpack ("<I" , data [i + 8 : i + 12 ])[0 ])
283
310
284
311
res .append (f"{ laddr } { lport } { raddr } { rport } { tos } { seq } { byte } " )
285
312
return "\n " .join (res )
@@ -295,17 +322,19 @@ def get_rds_paths(self, sock_fd):
295
322
res = []
296
323
297
324
# Header for the main connection paths
298
- res .append (f"{ 'LocalAddr' :<15} { 'RemoteAddr' :<15} { 'Tos' :<4} { 'Trans' :<10} " )
325
+ res .append (
326
+ f"{ 'LocalAddr' :<15} { 'RemoteAddr' :<15} { 'Tos' :<4} { 'Trans' :<10} " )
299
327
300
328
for i in range (0 , len (data ), each ):
301
- saddr = socket .inet_ntoa (data [i + 12 : i + 16 ])
302
- daddr = socket .inet_ntoa (data [i + 28 : i + 32 ])
303
- tos = str (struct .unpack ("<b" , data [i + 48 : i + 49 ])[0 ])
304
- trans = data [i + 32 : i + 48 ].split (b"\x00 " , maxsplit = 1 )[0 ].decode ("utf-8" )
329
+ saddr = socket .inet_ntoa (data [i + 12 : i + 16 ])
330
+ daddr = socket .inet_ntoa (data [i + 28 : i + 32 ])
331
+ tos = str (struct .unpack ("<b" , data [i + 48 : i + 49 ])[0 ])
332
+ trans = data [i + 32 : i +
333
+ 48 ].split (b"\x00 " , maxsplit = 1 )[0 ].decode ("utf-8" )
305
334
306
335
res .append (f"{ saddr :<15} { daddr :<15} { tos :<4} { trans :<10} " )
307
336
308
- path_num = int (struct .unpack ("<b" , data [i + 49 : i + 50 ])[0 ])
337
+ path_num = int (struct .unpack ("<b" , data [i + 49 : i + 50 ])[0 ])
309
338
310
339
res += "\n "
311
340
@@ -315,30 +344,31 @@ def get_rds_paths(self, sock_fd):
315
344
f"{ 'Attempts' :<10} { 'RDS' :<5} { 'Down(Secs)' :<13} { 'Reason' :<15} "
316
345
)
317
346
318
- path_data = data [i + 50 : i + 346 ]
347
+ path_data = data [i + 50 : i + 346 ]
319
348
for j in range (0 , len (path_data ), 37 ):
320
- attempt_time = self .parse_time (path_data [j + 0 : j + 8 ])
321
- conn_time = self .parse_time (path_data [j + 8 : j + 16 ])
322
- reset_time = self .parse_time (path_data [j + 16 : j + 24 ])
349
+ attempt_time = self .parse_time (path_data [j + 0 : j + 8 ])
350
+ conn_time = self .parse_time (path_data [j + 8 : j + 16 ])
351
+ reset_time = self .parse_time (path_data [j + 16 : j + 24 ])
323
352
324
- reason = int (struct .unpack ("<I" , path_data [j + 24 : j + 28 ])[0 ])
353
+ reason = int (struct .unpack ("<I" , path_data [j + 24 : j + 28 ])[0 ])
325
354
reason = (
326
355
CONN_DROP_REASONS [reason ]
327
356
if reason < len (CONN_DROP_REASONS )
328
357
else str (reason )
329
358
)
330
359
331
- attempts = str (struct .unpack ("<I" , path_data [j + 28 : j + 32 ])[0 ])
332
- p_no = str (struct .unpack ("<b" , path_data [j + 32 : j + 33 ])[0 ])
360
+ attempts = str (struct .unpack (
361
+ "<I" , path_data [j + 28 : j + 32 ])[0 ])
362
+ p_no = str (struct .unpack ("<b" , path_data [j + 32 : j + 33 ])[0 ])
333
363
334
364
rds_flags = self .decode_flags (
335
- int (struct .unpack ("<b" , path_data [j + 36 : j + 37 ])[0 ])
365
+ int (struct .unpack ("<b" , path_data [j + 36 : j + 37 ])[0 ])
336
366
)
337
367
338
368
down = "---"
339
369
if rds_flags == "--C-" and reset_time != "---" :
340
370
down = self .get_down_time (
341
- path_data [j + 8 : j + 16 ], path_data [j + 0 : j + 8 ]
371
+ path_data [j + 8 : j + 16 ], path_data [j + 0 : j + 8 ]
342
372
)
343
373
344
374
res .append (
@@ -355,20 +385,9 @@ def main(self, option):
355
385
"""
356
386
Wrapper function for all the above RDS-INFO options
357
387
"""
358
- infos = {
359
- "-I" : self .get_rds_ib_conns ,
360
- "-T" : self .get_rds_tcp_sockets ,
361
- "-c" : self .get_rds_counters ,
362
- "-k" : self .get_rds_sockets ,
363
- "-n" : self .get_rds_conns ,
364
- '-p' : self .get_rds_paths ,
365
- "-r" : lambda sock_fd : self .get_rds_queues (sock_fd , '-r' ),
366
- "-s" : lambda sock_fd : self .get_rds_queues (sock_fd , '-s' ),
367
- "-t" : lambda sock_fd : self .get_rds_queues (sock_fd , '-t' )
368
- }
369
388
infos = {
370
389
"-I" : {"method" : self .get_rds_ib_conns , "description" : "Get RDS InfiniBand connections" },
371
- "-T" : {"method" : self .get_rds_tcp_sockets , "description" : "Get RDS TCP socket information " },
390
+ "-T" : {"method" : self .get_rds_tcp_conns , "description" : "Get RDS TCP connetions " },
372
391
"-c" : {"method" : self .get_rds_counters , "description" : "Get RDS counters" },
373
392
"-k" : {"method" : self .get_rds_sockets , "description" : "Get RDS socket information" },
374
393
"-n" : {"method" : self .get_rds_conns , "description" : "Get RDS connection details" },
@@ -380,24 +399,21 @@ def main(self, option):
380
399
"description" : "Get RDS retransmit queues" },
381
400
}
382
401
383
-
384
402
# If the user requests help or an invalid option is passed
385
403
if option == "--help" or option not in infos :
386
- print ("Usage: python script.py <option>" )
387
- print ("Available options:" )
388
- for key , value in infos .items ():
389
- print (f" { key } : { value ['description' ]} " )
404
+ print (self .USAGE_MSG )
390
405
return ""
391
406
392
407
sock_fd = self .create_rds_socket ()
393
408
res = infos [option ]["method" ](sock_fd )
394
409
self .libc .close (sock_fd )
395
410
return res
396
411
412
+
397
413
if __name__ == "__main__" :
398
414
# Ensure an argument is passed
399
415
if len (sys .argv ) != 2 :
400
- print ("Usage: python rds_info.py <option>" )
416
+ print (RdsInfo . USAGE_MSG )
401
417
sys .exit (1 )
402
418
403
419
cmd_option = sys .argv [1 ]
0 commit comments