Use compiler-agnostic defines to silence warning
[lttng-tools.git] / src / bin / lttng-sessiond / ust-abi-internal.hpp
... / ...
CommitLineData
1/*
2 * Copyright 2010-2012 Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
3 *
4 * SPDX-License-Identifier: MIT
5 *
6 * Copied from LTTng-UST lttng/ust-abi.h
7 *
8 * LTTng-UST ABI header
9 *
10 */
11
12#ifndef LTTNG_UST_ABI_INTERNAL_H
13#define LTTNG_UST_ABI_INTERNAL_H
14
15#include <common/macros.hpp>
16
17#include <stdint.h>
18
19#ifndef LTTNG_PACKED
20#error "LTTNG_PACKED should be defined"
21#endif
22
23#ifndef lttng_ust_stringify
24#define lttng_ust_stringify1(x) #x
25#define lttng_ust_stringify(x) lttng_ust_stringify1(x)
26#endif /* lttng_ust_stringify */
27
28#define LTTNG_UST_ABI_SYM_NAME_LEN 256
29#define LTTNG_UST_ABI_PROCNAME_LEN 16
30
31/* UST comm magic number, used to validate protocol and endianness. */
32#define LTTNG_UST_ABI_COMM_MAGIC 0xC57C57C5
33
34/* Version for ABI between liblttng-ust, sessiond, consumerd */
35#define LTTNG_UST_ABI_MAJOR_VERSION 10
36#define LTTNG_UST_ABI_MAJOR_VERSION_OLDEST_COMPATIBLE 8
37#define LTTNG_UST_ABI_MINOR_VERSION 0
38
39#define LTTNG_UST_ABI_CMD_MAX_LEN 4096U
40
41enum lttng_ust_abi_instrumentation {
42 LTTNG_UST_ABI_TRACEPOINT = 0,
43 LTTNG_UST_ABI_PROBE = 1,
44 LTTNG_UST_ABI_FUNCTION = 2,
45};
46
47enum lttng_ust_abi_loglevel_type {
48 LTTNG_UST_ABI_LOGLEVEL_ALL = 0,
49 LTTNG_UST_ABI_LOGLEVEL_RANGE = 1,
50 LTTNG_UST_ABI_LOGLEVEL_SINGLE = 2,
51};
52
53enum lttng_ust_abi_output {
54 LTTNG_UST_ABI_MMAP = 0,
55};
56
57enum lttng_ust_abi_chan_type {
58 LTTNG_UST_ABI_CHAN_PER_CPU = 0,
59 LTTNG_UST_ABI_CHAN_METADATA = 1,
60};
61
62struct lttng_ust_abi_tracer_version {
63 uint32_t major;
64 uint32_t minor;
65 uint32_t patchlevel;
66} LTTNG_PACKED;
67
68#define LTTNG_UST_ABI_CHANNEL_PADDING (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
69/*
70 * Given that the consumerd is limited to 64k file descriptors, we
71 * cannot expect much more than 1MB channel structure size. This size is
72 * depends on the number of streams within a channel, which depends on
73 * the number of possible CPUs on the system.
74 */
75#define LTTNG_UST_ABI_CHANNEL_DATA_MAX_LEN 1048576U
76struct lttng_ust_abi_channel {
77 uint64_t len;
78 int32_t type; /* enum lttng_ust_abi_chan_type */
79 char padding[LTTNG_UST_ABI_CHANNEL_PADDING];
80 char data[]; /* variable sized data */
81} LTTNG_PACKED;
82
83#define LTTNG_UST_ABI_STREAM_PADDING1 (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
84struct lttng_ust_abi_stream {
85 uint64_t len; /* shm len */
86 uint32_t stream_nr; /* stream number */
87 char padding[LTTNG_UST_ABI_STREAM_PADDING1];
88 /*
89 * shm_fd and wakeup_fd are send over unix socket as file
90 * descriptors after this structure.
91 */
92} LTTNG_PACKED;
93
94#define LTTNG_UST_ABI_EVENT_PADDING1 8
95#define LTTNG_UST_ABI_EVENT_PADDING2 (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
96struct lttng_ust_abi_event {
97 int32_t instrumentation; /* enum lttng_ust_abi_instrumentation */
98 char name[LTTNG_UST_ABI_SYM_NAME_LEN]; /* event name */
99
100 int32_t loglevel_type; /* enum lttng_ust_abi_loglevel_type */
101 int32_t loglevel; /* value, -1: all */
102 uint64_t token; /* User-provided token */
103 char padding[LTTNG_UST_ABI_EVENT_PADDING1];
104
105 /* Per instrumentation type configuration */
106 union {
107 char padding[LTTNG_UST_ABI_EVENT_PADDING2];
108 } u;
109} LTTNG_PACKED;
110
111#define LTTNG_UST_ABI_EVENT_NOTIFIER_PADDING 32
112struct lttng_ust_abi_event_notifier {
113 struct lttng_ust_abi_event event;
114 uint64_t error_counter_index;
115 char padding[LTTNG_UST_ABI_EVENT_NOTIFIER_PADDING];
116} LTTNG_PACKED;
117
118#define LTTNG_UST_ABI_EVENT_NOTIFIER_NOTIFICATION_PADDING 32
119struct lttng_ust_abi_event_notifier_notification {
120 uint64_t token;
121 uint16_t capture_buf_size;
122 char padding[LTTNG_UST_ABI_EVENT_NOTIFIER_NOTIFICATION_PADDING];
123} LTTNG_PACKED;
124
125enum lttng_ust_abi_key_token_type {
126 LTTNG_UST_ABI_KEY_TOKEN_STRING = 0, /* arg: strtab_offset. */
127 LTTNG_UST_ABI_KEY_TOKEN_EVENT_NAME = 1, /* no arg. */
128 LTTNG_UST_ABI_KEY_TOKEN_PROVIDER_NAME = 2, /* no arg. */
129};
130
131enum lttng_ust_abi_counter_arithmetic {
132 LTTNG_UST_ABI_COUNTER_ARITHMETIC_MODULAR = 0,
133 LTTNG_UST_ABI_COUNTER_ARITHMETIC_SATURATION = 1,
134};
135
136enum lttng_ust_abi_counter_bitness {
137 LTTNG_UST_ABI_COUNTER_BITNESS_32 = 0,
138 LTTNG_UST_ABI_COUNTER_BITNESS_64 = 1,
139};
140
141struct lttng_ust_abi_key_token {
142 uint32_t len; /* length of child structure. */
143 uint32_t type; /* enum lttng_ust_abi_key_token_type */
144 /*
145 * The size of this structure is fixed because it is embedded into
146 * children structures.
147 */
148} LTTNG_PACKED;
149
150/* Length of this structure excludes the following string. */
151struct lttng_ust_abi_key_token_string {
152 struct lttng_ust_abi_key_token parent;
153 uint32_t string_len; /* string length (includes \0) */
154
155 char str[]; /* Null-terminated string following this structure. */
156} LTTNG_PACKED;
157
158/*
159 * token types event_name and provider_name don't have specific fields,
160 * so they do not need to derive their own specific child structure.
161 */
162
163/*
164 * Dimension indexing: All events should use the same key type to index
165 * a given map dimension.
166 */
167enum lttng_ust_abi_key_type {
168 LTTNG_UST_ABI_KEY_TYPE_TOKENS = 0, /* Dimension key is a set of tokens. */
169 LTTNG_UST_ABI_KEY_TYPE_INTEGER = 1, /* Dimension key is an integer value. */
170};
171
172struct lttng_ust_abi_counter_key_dimension {
173 uint32_t len; /* length of child structure */
174 uint32_t key_type; /* enum lttng_ust_abi_key_type */
175 /*
176 * The size of this structure is fixed because it is embedded into
177 * children structures.
178 */
179} LTTNG_PACKED;
180
181struct lttng_ust_abi_counter_key_dimension_tokens {
182 struct lttng_ust_abi_counter_key_dimension parent;
183 uint32_t nr_key_tokens;
184
185 /* Followed by an array of nr_key_tokens struct lttng_ust_abi_key_token elements. */
186} LTTNG_PACKED;
187
188/*
189 * The "integer" key type is not implemented yet, but when it will be
190 * introduced in the future, its specific key dimension will allow
191 * defining the function to apply over input argument, bytecode to run
192 * and so on.
193 */
194
195enum lttng_ust_abi_counter_action {
196 LTTNG_UST_ABI_COUNTER_ACTION_INCREMENT = 0,
197
198 /*
199 * Can be extended with additional actions, such as decrement,
200 * set value, run bytecode, and so on.
201 */
202};
203
204struct lttng_ust_abi_counter_event {
205 uint32_t len; /* length of this structure */
206 uint32_t action; /* enum lttng_ust_abi_counter_action */
207
208 struct lttng_ust_abi_event event;
209 uint32_t number_key_dimensions; /* array of dimensions is an array of var. len. elements. */
210
211 /*
212 * Followed by additional data specific to the action, and by a
213 * variable-length array of key dimensions.
214 */
215} LTTNG_PACKED;
216
217enum lttng_ust_abi_counter_dimension_flags {
218 LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_UNDERFLOW = (1 << 0),
219 LTTNG_UST_ABI_COUNTER_DIMENSION_FLAG_OVERFLOW = (1 << 1),
220};
221
222struct lttng_ust_abi_counter_dimension {
223 uint32_t key_type; /* enum lttng_ust_abi_key_type */
224 uint32_t flags; /* enum lttng_ust_abi_counter_dimension_flags */
225 uint64_t size; /* dimension size (count of entries) */
226 uint64_t underflow_index;
227 uint64_t overflow_index;
228} LTTNG_PACKED;
229
230enum lttng_ust_abi_counter_conf_flags {
231 LTTNG_UST_ABI_COUNTER_CONF_FLAG_COALESCE_HITS = (1 << 0),
232};
233
234struct lttng_ust_abi_counter_conf {
235 uint32_t len; /* Length of fields before var. len. data. */
236 uint32_t flags; /* enum lttng_ust_abi_counter_conf_flags */
237 uint32_t arithmetic; /* enum lttng_ust_abi_counter_arithmetic */
238 uint32_t bitness; /* enum lttng_ust_abi_counter_bitness */
239 int64_t global_sum_step;
240 uint32_t number_dimensions;
241 uint32_t elem_len; /* array stride (size of lttng_ust_abi_counter_dimension) */
242} LTTNG_PACKED;
243
244struct lttng_ust_abi_counter_global {
245 uint32_t len; /* Length of this structure */
246 uint64_t shm_len; /* shm len */
247} LTTNG_PACKED;
248
249struct lttng_ust_abi_counter_cpu {
250 uint32_t len; /* Length of this structure */
251 uint64_t shm_len; /* shm len */
252 uint32_t cpu_nr;
253} LTTNG_PACKED;
254
255enum lttng_ust_abi_field_type {
256 LTTNG_UST_ABI_FIELD_OTHER = 0,
257 LTTNG_UST_ABI_FIELD_INTEGER = 1,
258 LTTNG_UST_ABI_FIELD_ENUM = 2,
259 LTTNG_UST_ABI_FIELD_FLOAT = 3,
260 LTTNG_UST_ABI_FIELD_STRING = 4,
261};
262
263#define LTTNG_UST_ABI_FIELD_ITER_PADDING (LTTNG_UST_ABI_SYM_NAME_LEN + 28)
264struct lttng_ust_abi_field_iter {
265 char event_name[LTTNG_UST_ABI_SYM_NAME_LEN];
266 char field_name[LTTNG_UST_ABI_SYM_NAME_LEN];
267 int32_t type; /* enum lttng_ust_abi_field_type */
268 int loglevel; /* event loglevel */
269 int nowrite;
270 char padding[LTTNG_UST_ABI_FIELD_ITER_PADDING];
271} LTTNG_PACKED;
272
273enum lttng_ust_abi_context_type {
274 LTTNG_UST_ABI_CONTEXT_VTID = 0,
275 LTTNG_UST_ABI_CONTEXT_VPID = 1,
276 LTTNG_UST_ABI_CONTEXT_PTHREAD_ID = 2,
277 LTTNG_UST_ABI_CONTEXT_PROCNAME = 3,
278 LTTNG_UST_ABI_CONTEXT_IP = 4,
279 LTTNG_UST_ABI_CONTEXT_PERF_THREAD_COUNTER = 5,
280 LTTNG_UST_ABI_CONTEXT_CPU_ID = 6,
281 LTTNG_UST_ABI_CONTEXT_APP_CONTEXT = 7,
282 LTTNG_UST_ABI_CONTEXT_CGROUP_NS = 8,
283 LTTNG_UST_ABI_CONTEXT_IPC_NS = 9,
284 LTTNG_UST_ABI_CONTEXT_MNT_NS = 10,
285 LTTNG_UST_ABI_CONTEXT_NET_NS = 11,
286 LTTNG_UST_ABI_CONTEXT_PID_NS = 12,
287 LTTNG_UST_ABI_CONTEXT_USER_NS = 13,
288 LTTNG_UST_ABI_CONTEXT_UTS_NS = 14,
289 LTTNG_UST_ABI_CONTEXT_VUID = 15,
290 LTTNG_UST_ABI_CONTEXT_VEUID = 16,
291 LTTNG_UST_ABI_CONTEXT_VSUID = 17,
292 LTTNG_UST_ABI_CONTEXT_VGID = 18,
293 LTTNG_UST_ABI_CONTEXT_VEGID = 19,
294 LTTNG_UST_ABI_CONTEXT_VSGID = 20,
295 LTTNG_UST_ABI_CONTEXT_TIME_NS = 21,
296};
297
298struct lttng_ust_abi_perf_counter_ctx {
299 uint32_t type;
300 uint64_t config;
301 char name[LTTNG_UST_ABI_SYM_NAME_LEN];
302} LTTNG_PACKED;
303
304#define LTTNG_UST_ABI_CONTEXT_PADDING1 16
305#define LTTNG_UST_ABI_CONTEXT_PADDING2 (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
306struct lttng_ust_abi_context {
307 int32_t ctx; /* enum lttng_ust_abi_context_type */
308 char padding[LTTNG_UST_ABI_CONTEXT_PADDING1];
309
310 union {
311 struct lttng_ust_abi_perf_counter_ctx perf_counter;
312 struct {
313 /* Includes trailing '\0'. */
314 uint32_t provider_name_len;
315 uint32_t ctx_name_len;
316 } app_ctx;
317 char padding[LTTNG_UST_ABI_CONTEXT_PADDING2];
318 } u;
319} LTTNG_PACKED;
320
321/*
322 * Tracer channel attributes.
323 */
324#define LTTNG_UST_ABI_CHANNEL_ATTR_PADDING (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
325struct lttng_ust_abi_channel_attr {
326 uint64_t subbuf_size; /* bytes */
327 uint64_t num_subbuf; /* power of 2 */
328 int overwrite; /* 1: overwrite, 0: discard */
329 unsigned int switch_timer_interval; /* usec */
330 unsigned int read_timer_interval; /* usec */
331 int32_t output; /* enum lttng_ust_abi_output */
332 union {
333 struct {
334 int64_t blocking_timeout; /* Blocking timeout (usec) */
335 } s;
336 char padding[LTTNG_UST_ABI_CHANNEL_ATTR_PADDING];
337 } u;
338} LTTNG_PACKED;
339
340#define LTTNG_UST_ABI_TRACEPOINT_ITER_PADDING 16
341struct lttng_ust_abi_tracepoint_iter {
342 char name[LTTNG_UST_ABI_SYM_NAME_LEN]; /* provider:name */
343 int loglevel;
344 char padding[LTTNG_UST_ABI_TRACEPOINT_ITER_PADDING];
345} LTTNG_PACKED;
346
347enum lttng_ust_abi_object_type {
348 LTTNG_UST_ABI_OBJECT_TYPE_UNKNOWN = -1,
349 LTTNG_UST_ABI_OBJECT_TYPE_CHANNEL = 0,
350 LTTNG_UST_ABI_OBJECT_TYPE_STREAM = 1,
351 LTTNG_UST_ABI_OBJECT_TYPE_EVENT = 2,
352 LTTNG_UST_ABI_OBJECT_TYPE_CONTEXT = 3,
353 LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER_GROUP = 4,
354 LTTNG_UST_ABI_OBJECT_TYPE_EVENT_NOTIFIER = 5,
355 LTTNG_UST_ABI_OBJECT_TYPE_COUNTER = 6,
356 LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_GLOBAL = 7,
357 LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_CPU = 8,
358 LTTNG_UST_ABI_OBJECT_TYPE_COUNTER_EVENT = 9,
359};
360
361#define LTTNG_UST_ABI_OBJECT_DATA_PADDING1 32
362#define LTTNG_UST_ABI_OBJECT_DATA_PADDING2 (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
363
364struct lttng_ust_abi_object_data {
365 int32_t type; /* enum lttng_ust_abi_object_type */
366 int handle;
367 uint64_t size;
368 char padding1[LTTNG_UST_ABI_OBJECT_DATA_PADDING1];
369 union {
370 struct {
371 void *data;
372 int32_t type; /* enum lttng_ust_abi_chan_type */
373 int wakeup_fd;
374 } channel;
375 struct {
376 int shm_fd;
377 int wakeup_fd;
378 uint32_t stream_nr;
379 } stream;
380 struct {
381 void *data;
382 } counter;
383 struct {
384 int shm_fd;
385 } counter_global;
386 struct {
387 int shm_fd;
388 uint32_t cpu_nr;
389 } counter_cpu;
390 char padding2[LTTNG_UST_ABI_OBJECT_DATA_PADDING2];
391 } u;
392} LTTNG_PACKED;
393
394enum lttng_ust_abi_calibrate_type {
395 LTTNG_UST_ABI_CALIBRATE_TRACEPOINT,
396};
397
398#define LTTNG_UST_ABI_CALIBRATE_PADDING1 16
399#define LTTNG_UST_ABI_CALIBRATE_PADDING2 (LTTNG_UST_ABI_SYM_NAME_LEN + 32)
400struct lttng_ust_abi_calibrate {
401 enum lttng_ust_abi_calibrate_type type; /* type (input) */
402 char padding[LTTNG_UST_ABI_CALIBRATE_PADDING1];
403
404 union {
405 char padding[LTTNG_UST_ABI_CALIBRATE_PADDING2];
406 } u;
407} LTTNG_PACKED;
408
409#define LTTNG_UST_ABI_FILTER_BYTECODE_MAX_LEN 65536
410#define LTTNG_UST_ABI_FILTER_PADDING 32
411struct lttng_ust_abi_filter_bytecode {
412 uint32_t len;
413 uint32_t reloc_offset;
414 uint64_t seqnum;
415 char padding[LTTNG_UST_ABI_FILTER_PADDING];
416 char data[0];
417} LTTNG_PACKED;
418
419#define LTTNG_UST_ABI_CAPTURE_BYTECODE_MAX_LEN 65536
420#define LTTNG_UST_ABI_CAPTURE_PADDING 32
421struct lttng_ust_abi_capture_bytecode {
422 uint32_t len;
423 uint32_t reloc_offset;
424 uint64_t seqnum;
425 char padding[LTTNG_UST_ABI_CAPTURE_PADDING];
426 char data[0];
427} LTTNG_PACKED;
428
429#define LTTNG_UST_ABI_EXCLUSION_PADDING 32
430struct lttng_ust_abi_event_exclusion {
431 uint32_t count;
432 char padding[LTTNG_UST_ABI_EXCLUSION_PADDING];
433 char names[LTTNG_UST_ABI_SYM_NAME_LEN][0];
434} LTTNG_PACKED;
435
436#define LTTNG_UST_ABI_CMD(minor) (minor)
437#define LTTNG_UST_ABI_CMDR(minor, type) (minor)
438#define LTTNG_UST_ABI_CMDW(minor, type) (minor)
439#define LTTNG_UST_ABI_CMDV(minor, var_len_cmd_type) (minor)
440
441/* Handled by object descriptor */
442#define LTTNG_UST_ABI_RELEASE LTTNG_UST_ABI_CMD(0x1)
443
444/* Handled by object cmd */
445
446/* LTTng-UST commands */
447#define LTTNG_UST_ABI_SESSION LTTNG_UST_ABI_CMD(0x40)
448#define LTTNG_UST_ABI_TRACER_VERSION LTTNG_UST_ABI_CMDR(0x41, struct lttng_ust_abi_tracer_version)
449#define LTTNG_UST_ABI_TRACEPOINT_LIST LTTNG_UST_ABI_CMD(0x42)
450#define LTTNG_UST_ABI_WAIT_QUIESCENT LTTNG_UST_ABI_CMD(0x43)
451#define LTTNG_UST_ABI_REGISTER_DONE LTTNG_UST_ABI_CMD(0x44)
452#define LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST LTTNG_UST_ABI_CMD(0x45)
453#define LTTNG_UST_ABI_EVENT_NOTIFIER_GROUP_CREATE LTTNG_UST_ABI_CMD(0x46)
454
455/* Session commands */
456#define LTTNG_UST_ABI_CHANNEL LTTNG_UST_ABI_CMDW(0x51, struct lttng_ust_abi_channel)
457#define LTTNG_UST_ABI_SESSION_START LTTNG_UST_ABI_CMD(0x52)
458#define LTTNG_UST_ABI_SESSION_STOP LTTNG_UST_ABI_CMD(0x53)
459#define LTTNG_UST_ABI_SESSION_STATEDUMP LTTNG_UST_ABI_CMD(0x54)
460
461/* Channel commands */
462#define LTTNG_UST_ABI_STREAM LTTNG_UST_ABI_CMD(0x60)
463#define LTTNG_UST_ABI_EVENT LTTNG_UST_ABI_CMDW(0x61, struct lttng_ust_abi_event)
464
465/* Event and channel commands */
466#define LTTNG_UST_ABI_CONTEXT LTTNG_UST_ABI_CMDW(0x70, struct lttng_ust_abi_context)
467#define LTTNG_UST_ABI_FLUSH_BUFFER LTTNG_UST_ABI_CMD(0x71)
468
469/* Event, event notifier, channel and session commands */
470#define LTTNG_UST_ABI_ENABLE LTTNG_UST_ABI_CMD(0x80)
471#define LTTNG_UST_ABI_DISABLE LTTNG_UST_ABI_CMD(0x81)
472
473/* Tracepoint list commands */
474#define LTTNG_UST_ABI_TRACEPOINT_LIST_GET LTTNG_UST_ABI_CMD(0x90)
475#define LTTNG_UST_ABI_TRACEPOINT_FIELD_LIST_GET LTTNG_UST_ABI_CMD(0x91)
476
477/* Event and event notifier commands */
478#define LTTNG_UST_ABI_FILTER LTTNG_UST_ABI_CMD(0xA0)
479#define LTTNG_UST_ABI_EXCLUSION LTTNG_UST_ABI_CMD(0xA1)
480
481/* Event notifier group commands */
482#define LTTNG_UST_ABI_EVENT_NOTIFIER_CREATE \
483 LTTNG_UST_ABI_CMDV(0xB0, struct lttng_ust_abi_event_notifier)
484
485/* Event notifier commands */
486#define LTTNG_UST_ABI_CAPTURE LTTNG_UST_ABI_CMD(0xB6)
487
488/* Session and event notifier group commands */
489/* (0xC0) reserved for old ABI. */
490#define LTTNG_UST_ABI_COUNTER LTTNG_UST_ABI_CMDV(0xC1, struct lttng_ust_abi_counter_conf)
491
492/* Counter commands */
493/* (0xD0, 0xD1) reserved for old ABI. */
494#define LTTNG_UST_ABI_COUNTER_GLOBAL LTTNG_UST_ABI_CMDV(0xD2, struct lttng_ust_abi_counter_global)
495#define LTTNG_UST_ABI_COUNTER_CPU LTTNG_UST_ABI_CMDV(0xD3, struct lttng_ust_abi_counter_cpu)
496#define LTTNG_UST_ABI_COUNTER_EVENT LTTNG_UST_ABI_CMDV(0xD4, struct lttng_ust_abi_counter_event)
497
498#define LTTNG_UST_ABI_ROOT_HANDLE 0
499
500#endif /* LTTNG_UST_ABI_INTERNAL_H */
This page took 0.040485 seconds and 5 git commands to generate.