1 # -*- coding: utf-8 -*-
3 # SPDX-License-Identifier: LGPL-2.1-only
5 # Copyright (C) 2015 Philippe Proulx <pproulx@efficios.com>
6 # Copyright (C) 2014 David Goulet <dgoulet@efficios.com>
7 # Copyright (C) 2015 Jérémie Galarneau <jeremie.galarneau@efficios.com>
9 from __future__
import unicode_literals
10 import lttngust
.debug
as dbg
14 # server command header
15 _server_cmd_header_struct
= struct
.Struct('>QII')
18 # server command header size
19 _SERVER_CMD_HEADER_SIZE
= _server_cmd_header_struct
.size
22 # agent protocol symbol size
23 _LTTNG_SYMBOL_NAME_LEN
= 256
26 class _ServerCmdHeader(object):
27 def __init__(self
, data_size
, cmd_id
, cmd_version
):
28 self
.data_size
= data_size
30 self
.cmd_version
= cmd_version
33 def _server_cmd_header_from_data(data
):
35 data_size
, cmd_id
, cmd_version
= _server_cmd_header_struct
.unpack(data
)
36 except (Exception) as e
:
37 dbg
._pdebug
('cannot decode command header: {}'.format(e
))
40 return _ServerCmdHeader(data_size
, cmd_id
, cmd_version
)
43 class _ServerCmd(object):
44 def __init__(self
, header
):
48 def from_data(cls
, header
, data
):
49 raise NotImplementedError()
52 class _ServerCmdList(_ServerCmd
):
54 def from_data(cls
, header
, data
):
58 class _ServerCmdEnable(_ServerCmd
):
60 _loglevel_struct
= struct
.Struct('>II')
61 # filter expression size
62 _filter_exp_len_struct
= struct
.Struct('>I')
64 def __init__(self
, header
, loglevel
, loglevel_type
, name
, filter_exp
):
65 super(self
.__class
__, self
).__init
__(header
)
66 self
.loglevel
= loglevel
67 self
.loglevel_type
= loglevel_type
69 self
.filter_expression
= filter_exp
70 dbg
._pdebug
('server enable command {}'.format(self
.__dict
__))
73 def from_data(cls
, header
, data
):
75 loglevel
, loglevel_type
= cls
._loglevel
_struct
.unpack_from(data
)
76 name_start
= cls
._loglevel
_struct
.size
77 name_end
= name_start
+ _LTTNG_SYMBOL_NAME_LEN
78 data_name
= data
[name_start
:name_end
]
79 name
= data_name
.rstrip(b
'\0').decode()
81 filter_exp_start
= name_end
+ cls
._filter
_exp
_len
_struct
.size
82 filter_exp_len
, = cls
._filter
_exp
_len
_struct
.unpack_from(
83 data
[name_end
:filter_exp_start
])
84 filter_exp_end
= filter_exp_start
+ filter_exp_len
86 filter_exp
= data
[filter_exp_start
:filter_exp_end
].rstrip(
89 return cls(header
, loglevel
, loglevel_type
, name
, filter_exp
)
90 except (Exception) as e
:
91 dbg
._pdebug
('cannot decode enable command: {}'.format(e
))
95 class _ServerCmdDisable(_ServerCmd
):
96 def __init__(self
, header
, name
):
97 super(self
.__class
__, self
).__init
__(header
)
101 def from_data(cls
, header
, data
):
103 name
= data
.rstrip(b
'\0').decode()
105 return cls(header
, name
)
106 except (Exception) as e
:
107 dbg
._pdebug
('cannot decode disable command: {}'.format(e
))
111 class _ServerCmdRegistrationDone(_ServerCmd
):
113 def from_data(cls
, header
, data
):
117 _SERVER_CMD_ID_TO_SERVER_CMD
= {
120 3: _ServerCmdDisable
,
121 4: _ServerCmdRegistrationDone
,
125 def _server_cmd_from_data(header
, data
):
126 if header
.cmd_id
not in _SERVER_CMD_ID_TO_SERVER_CMD
:
129 return _SERVER_CMD_ID_TO_SERVER_CMD
[header
.cmd_id
].from_data(header
, data
)
132 _CLIENT_CMD_REPLY_STATUS_SUCCESS
= 1
133 _CLIENT_CMD_REPLY_STATUS_INVALID_CMD
= 2
136 class _ClientCmdReplyHeader(object):
137 _payload_struct
= struct
.Struct('>I')
139 def __init__(self
, status_code
=_CLIENT_CMD_REPLY_STATUS_SUCCESS
):
140 self
.status_code
= status_code
143 return self
._payload
_struct
.pack(self
.status_code
)
146 class _ClientCmdReplyEnable(_ClientCmdReplyHeader
):
150 class _ClientCmdReplyDisable(_ClientCmdReplyHeader
):
154 class _ClientCmdReplyList(_ClientCmdReplyHeader
):
155 _nb_events_struct
= struct
.Struct('>I')
156 _data_size_struct
= struct
.Struct('>I')
158 def __init__(self
, names
, status_code
=_CLIENT_CMD_REPLY_STATUS_SUCCESS
):
159 super(self
.__class
__, self
).__init
__(status_code
)
163 upper_data
= super(self
.__class
__, self
).get_data()
164 nb_events_data
= self
._nb
_events
_struct
.pack(len(self
.names
))
167 for name
in self
.names
:
168 names_data
+= name
.encode() + b
'\0'
170 data_size_data
= self
._data
_size
_struct
.pack(len(names_data
))
172 return upper_data
+ data_size_data
+ nb_events_data
+ names_data
175 class _ClientRegisterCmd(object):
176 _payload_struct
= struct
.Struct('>IIII')
178 def __init__(self
, domain
, pid
, major
, minor
):
185 return self
._payload
_struct
.pack(self
.domain
, self
.pid
, self
.major
,