Main class implementing Python access to the VPP statistics segment
| 117 | |
| 118 | |
| 119 | class VPPStats: |
| 120 | """Main class implementing Python access to the VPP statistics segment""" |
| 121 | |
| 122 | # pylint: disable=too-many-instance-attributes |
| 123 | shared_headerfmt = Struct("QPQQPP") |
| 124 | default_socketname = "/run/vpp/stats.sock" |
| 125 | |
| 126 | def __init__(self, socketname=default_socketname, timeout=10): |
| 127 | self.socketname = socketname |
| 128 | self.timeout = timeout |
| 129 | self.directory = {} |
| 130 | self.lock = StatsLock(self) |
| 131 | self.connected = False |
| 132 | self.size = 0 |
| 133 | self.last_epoch = 0 |
| 134 | self.statseg = 0 |
| 135 | |
| 136 | def connect(self): |
| 137 | """Connect to stats segment""" |
| 138 | if self.connected: |
| 139 | return |
| 140 | sock = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) |
| 141 | |
| 142 | # Our connect races the corresponding recv_fds call in VPP, if we beat |
| 143 | # VPP then we will try (unsuccessfully) to receive file descriptors and |
| 144 | # will have gone away before VPP can respond to our connect. A short |
| 145 | # timeout here stops this error occurring. |
| 146 | sock.settimeout(1) |
| 147 | sock.connect(self.socketname) |
| 148 | |
| 149 | mfd = recv_fd(sock) |
| 150 | sock.close() |
| 151 | |
| 152 | stat_result = os.fstat(mfd) |
| 153 | self.statseg = mmap.mmap( |
| 154 | mfd, stat_result.st_size, mmap.PROT_READ, mmap.MAP_SHARED |
| 155 | ) |
| 156 | os.close(mfd) |
| 157 | |
| 158 | self.size = stat_result.st_size |
| 159 | if self.version != 2: |
| 160 | raise Exception("Incompatbile stat segment version {}".format(self.version)) |
| 161 | |
| 162 | self.refresh() |
| 163 | self.connected = True |
| 164 | |
| 165 | def disconnect(self): |
| 166 | """Disconnect from stats segment""" |
| 167 | if self.connected: |
| 168 | self.statseg.close() |
| 169 | self.connected = False |
| 170 | |
| 171 | @property |
| 172 | def version(self): |
| 173 | """Get version of stats segment""" |
| 174 | return self.shared_headerfmt.unpack_from(self.statseg)[0] |
| 175 | |
| 176 | @property |