eal/ppc: use compiler builtins for atomics
[dpdk.git] / usertools / dpdk-telemetry.py
1 #! /usr/bin/env python3
2 # SPDX-License-Identifier: BSD-3-Clause
3 # Copyright(c) 2020 Intel Corporation
4
5 """
6 Script to be used with V2 Telemetry.
7 Allows the user input commands and read the Telemetry response.
8 """
9
10 import socket
11 import os
12 import sys
13 import json
14 import errno
15 import readline
16 import argparse
17
18 # global vars
19 TELEMETRY_VERSION = "v2"
20 CMDS = []
21
22
23 def read_socket(sock, buf_len, echo=True):
24     """ Read data from socket and return it in JSON format """
25     reply = sock.recv(buf_len).decode()
26     try:
27         ret = json.loads(reply)
28     except json.JSONDecodeError:
29         print("Error in reply: ", reply)
30         sock.close()
31         raise
32     if echo:
33         print(json.dumps(ret))
34     return ret
35
36
37 def get_app_name(pid):
38     """ return the app name for a given PID, for printing """
39     proc_cmdline = os.path.join('/proc', str(pid), 'cmdline')
40     try:
41         with open(proc_cmdline) as f:
42             argv0 = f.read(1024).split('\0')[0]
43             return os.path.basename(argv0)
44     except IOError as e:
45         # ignore file not found errors
46         if e.errno != errno.ENOENT:
47             raise
48     return None
49
50
51 def handle_socket(path):
52     """ Connect to socket and handle user input """
53     prompt = ''  # this evaluates to false in conditions
54     sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)
55     global CMDS
56
57     if os.isatty(sys.stdin.fileno()):
58         prompt = '--> '
59         print("Connecting to " + path)
60     try:
61         sock.connect(path)
62     except OSError:
63         print("Error connecting to " + path)
64         sock.close()
65         return
66     json_reply = read_socket(sock, 1024, prompt)
67     output_buf_len = json_reply["max_output_len"]
68     app_name = get_app_name(json_reply["pid"])
69     if app_name and prompt:
70         print('Connected to application: "%s"' % app_name)
71
72     # get list of commands for readline completion
73     sock.send("/".encode())
74     CMDS = read_socket(sock, output_buf_len, False)["/"]
75
76     # interactive prompt
77     try:
78         text = input(prompt).strip()
79         while text != "quit":
80             if text.startswith('/'):
81                 sock.send(text.encode())
82                 read_socket(sock, output_buf_len)
83             text = input(prompt).strip()
84     except EOFError:
85         pass
86     finally:
87         sock.close()
88
89
90 def readline_complete(text, state):
91     """ Find any matching commands from the list based on user input """
92     all_cmds = ['quit'] + CMDS
93     if text:
94         matches = [c for c in all_cmds if c.startswith(text)]
95     else:
96         matches = all_cmds
97     return matches[state]
98
99
100 def get_dpdk_runtime_dir(fp):
101     """ Using the same logic as in DPDK's EAL, get the DPDK runtime directory
102     based on the file-prefix and user """
103     if (os.getuid() == 0):
104         return os.path.join('/var/run/dpdk', fp)
105     return os.path.join(os.environ.get('XDG_RUNTIME_DIR', '/tmp'), 'dpdk', fp)
106
107
108 readline.parse_and_bind('tab: complete')
109 readline.set_completer(readline_complete)
110 readline.set_completer_delims(readline.get_completer_delims().replace('/', ''))
111
112 parser = argparse.ArgumentParser()
113 parser.add_argument('-f', '--file-prefix', default='rte',
114                     help='Provide file-prefix for DPDK runtime directory')
115 args = parser.parse_args()
116 rd = get_dpdk_runtime_dir(args.file_prefix)
117 handle_socket(os.path.join(rd, 'dpdk_telemetry.{}'.format(TELEMETRY_VERSION)))