Command to create a live local session
[lttngtop.git] / src / common.c
CommitLineData
1fc22eb4 1/*
aa15ac1c 2 * Copyright (C) 2011-2012 Julien Desfossez
1fc22eb4
JD
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License Version 2 as
6 * published by the Free Software Foundation;
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
71bd7ce1
AM
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
1fc22eb4
JD
16 */
17
1dec520a 18#include <babeltrace/ctf/events.h>
1fc22eb4 19#include <stdlib.h>
ceb3a221 20#include <linux/unistd.h>
1fc22eb4
JD
21#include <string.h>
22#include "common.h"
23
4adc8274 24uint64_t get_cpu_id(const struct bt_ctf_event *event)
d67167cd 25{
2e0a1190 26 const struct bt_definition *scope;
d67167cd
JD
27 uint64_t cpu_id;
28
29 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_PACKET_CONTEXT);
30 cpu_id = bt_ctf_get_uint64(bt_ctf_get_field(event, scope, "cpu_id"));
31 if (bt_ctf_field_get_error()) {
32 fprintf(stderr, "[error] get cpu_id\n");
33 return -1ULL;
34 }
35
36 return cpu_id;
37}
38
4adc8274 39uint64_t get_context_tid(const struct bt_ctf_event *event)
1dec520a 40{
2e0a1190 41 const struct bt_definition *scope;
1dec520a
JD
42 uint64_t tid;
43
44 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
45 tid = bt_ctf_get_int64(bt_ctf_get_field(event,
46 scope, "_tid"));
47 if (bt_ctf_field_get_error()) {
8fe4d0cf
JD
48 tid = bt_ctf_get_int64(bt_ctf_get_field(event,
49 scope, "_vtid"));
50 if (bt_ctf_field_get_error()) {
51 fprintf(stderr, "Missing tid context info\n");
52 return -1ULL;
53 }
1dec520a
JD
54 }
55
56 return tid;
57}
58
4adc8274 59uint64_t get_context_pid(const struct bt_ctf_event *event)
1dec520a 60{
2e0a1190 61 const struct bt_definition *scope;
1dec520a
JD
62 uint64_t pid;
63
64 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
65 pid = bt_ctf_get_int64(bt_ctf_get_field(event,
66 scope, "_pid"));
67 if (bt_ctf_field_get_error()) {
8fe4d0cf
JD
68 /* Try UST pid */
69 pid = bt_ctf_get_int64(bt_ctf_get_field(event,
70 scope, "_vpid"));
71 if (bt_ctf_field_get_error()) {
72 fprintf(stderr, "Missing pid context info\n");
73 return -1ULL;
74 }
1dec520a
JD
75 }
76
77 return pid;
78}
79
4adc8274 80uint64_t get_context_ppid(const struct bt_ctf_event *event)
1dec520a 81{
2e0a1190 82 const struct bt_definition *scope;
1dec520a
JD
83 uint64_t ppid;
84
85 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
86 ppid = bt_ctf_get_int64(bt_ctf_get_field(event,
87 scope, "_ppid"));
88 if (bt_ctf_field_get_error()) {
1dec520a
JD
89 return -1ULL;
90 }
91
92 return ppid;
93}
94
1402044a
JD
95uint64_t get_context_vtid(const struct bt_ctf_event *event)
96{
3160c7a9 97 const struct bt_definition *scope;
1402044a
JD
98 uint64_t vtid;
99
100 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
101 vtid = bt_ctf_get_int64(bt_ctf_get_field(event,
102 scope, "_vtid"));
103 if (bt_ctf_field_get_error()) {
104 return -1ULL;
105 }
106
107 return vtid;
108}
109
110uint64_t get_context_vpid(const struct bt_ctf_event *event)
111{
3160c7a9 112 const struct bt_definition *scope;
1402044a
JD
113 uint64_t vpid;
114
115 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
116 vpid = bt_ctf_get_int64(bt_ctf_get_field(event,
117 scope, "_vpid"));
118 if (bt_ctf_field_get_error()) {
119 return -1ULL;
120 }
121
122 return vpid;
123}
124
125uint64_t get_context_vppid(const struct bt_ctf_event *event)
126{
3160c7a9 127 const struct bt_definition *scope;
1402044a
JD
128 uint64_t vppid;
129
130 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
131 vppid = bt_ctf_get_int64(bt_ctf_get_field(event,
132 scope, "_vppid"));
133 if (bt_ctf_field_get_error()) {
134 return -1ULL;
135 }
136
137 return vppid;
138}
139
4adc8274 140char *get_context_comm(const struct bt_ctf_event *event)
1dec520a 141{
2e0a1190 142 const struct bt_definition *scope;
1dec520a
JD
143 char *comm;
144
145 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
146 comm = bt_ctf_get_char_array(bt_ctf_get_field(event,
147 scope, "_procname"));
148 if (bt_ctf_field_get_error()) {
149 fprintf(stderr, "Missing comm context info\n");
150 return NULL;
151 }
152
153 return comm;
154}
155
c8d75a13
JD
156char *get_context_hostname(const struct bt_ctf_event *event)
157{
3160c7a9 158 const struct bt_definition *scope;
c8d75a13
JD
159 char *hostname;
160
161 scope = bt_ctf_get_top_level_scope(event, BT_STREAM_EVENT_CONTEXT);
162 hostname = bt_ctf_get_char_array(bt_ctf_get_field(event,
163 scope, "_hostname"));
164 if (bt_ctf_field_get_error()) {
165 return NULL;
166 }
167
168 return hostname;
169}
170
59288610
MB
171/*
172 * To get the parent process, put the pid in the tid field
173 * because the parent process gets pid = tid
59288610 174 */
08d1cfbe 175struct processtop *find_process_tid(struct lttngtop *ctx, int tid, const char *comm)
1fc22eb4 176{
1fc22eb4
JD
177 struct processtop *tmp;
178
30b646c4
JD
179 tmp = g_hash_table_lookup(ctx->process_hash_table,
180 (gconstpointer) (unsigned long) tid);
181
182 return tmp;
1fc22eb4
JD
183}
184
185struct processtop* add_proc(struct lttngtop *ctx, int tid, char *comm,
906c08f6 186 unsigned long timestamp, char *hostname)
1fc22eb4
JD
187{
188 struct processtop *newproc;
b99227ca 189 struct host *host;
1fc22eb4
JD
190
191 /* if the PID already exists, we just rename the process */
192 /* FIXME : need to integrate with clone/fork/exit to be accurate */
193 newproc = find_process_tid(ctx, tid, comm);
96aa77de 194
1fc22eb4 195 if (!newproc) {
559c9f86 196 newproc = g_new0(struct processtop, 1);
1fc22eb4
JD
197 newproc->tid = tid;
198 newproc->birth = timestamp;
199 newproc->process_files_table = g_ptr_array_new();
ceb3a221 200 newproc->files_history = NULL;
b093de8a
MB
201 newproc->totalfileread = 0;
202 newproc->totalfilewrite = 0;
203 newproc->fileread = 0;
204 newproc->filewrite = 0;
205 newproc->syscall_info = NULL;
59288610 206 newproc->threadparent = NULL;
1fc22eb4 207 newproc->threads = g_ptr_array_new();
85db4618 208 newproc->perf = g_hash_table_new(g_str_hash, g_str_equal);
1fc22eb4 209 g_ptr_array_add(ctx->process_table, newproc);
30b646c4
JD
210 g_hash_table_insert(ctx->process_hash_table,
211 (gpointer) (unsigned long) tid, newproc);
da4353bb 212 if (lookup_tid_list(tid)) {
b99227ca 213 add_filter_tid_list(newproc);
da4353bb 214 }
e05a35a6
JD
215 ctx->nbnewthreads++;
216 ctx->nbthreads++;
1fc22eb4
JD
217 }
218 newproc->comm = strdup(comm);
906c08f6 219 if (hostname) {
b99227ca
JD
220 host = lookup_hostname_list(hostname);
221 if (!host)
222 host = add_hostname_list(hostname, 0);
223 if (!newproc->host || (newproc->host != host))
224 newproc->host = host;
114cae59 225 if (is_hostname_filtered(hostname)) {
b99227ca 226 add_filter_tid_list(newproc);
906c08f6
JD
227 }
228 }
1fc22eb4
JD
229
230 return newproc;
231}
232
233struct processtop* update_proc(struct processtop* proc, int pid, int tid,
c8d75a13 234 int ppid, int vpid, int vtid, int vppid, char *comm, char *hostname)
1fc22eb4 235{
b99227ca
JD
236 struct host *host;
237
1fc22eb4
JD
238 if (proc) {
239 proc->pid = pid;
240 proc->tid = tid;
241 proc->ppid = ppid;
1402044a
JD
242 proc->vpid = vpid;
243 proc->vtid = vtid;
244 proc->vppid = vppid;
1fc22eb4
JD
245 if (strcmp(proc->comm, comm) != 0) {
246 free(proc->comm);
247 proc->comm = strdup(comm);
248 }
b99227ca
JD
249 if (hostname && !proc->host) {
250 host = lookup_hostname_list(hostname);
251 if (!host)
252 host = add_hostname_list(hostname, 0);
253 if (!proc->host || (proc->host != host))
254 proc->host = host;
114cae59 255 if (is_hostname_filtered(hostname)) {
b99227ca 256 add_filter_tid_list(proc);
1d2391b4
JD
257 }
258 }
1fc22eb4
JD
259 }
260 return proc;
261}
262
263/*
264 * This function just sets the time of death of a process.
265 * When we rotate the cputime we remove it from the process list.
266 */
267void death_proc(struct lttngtop *ctx, int tid, char *comm,
268 unsigned long timestamp)
269{
270 struct processtop *tmp;
271 tmp = find_process_tid(ctx, tid, comm);
30b646c4
JD
272
273 g_hash_table_remove(ctx->process_hash_table,
274 (gpointer) (unsigned long) tid);
e05a35a6 275 if (tmp && strcmp(tmp->comm, comm) == 0) {
1fc22eb4 276 tmp->death = timestamp;
e05a35a6
JD
277 ctx->nbdeadthreads++;
278 ctx->nbthreads--;
279 }
1fc22eb4
JD
280}
281
282struct processtop* get_proc(struct lttngtop *ctx, int tid, char *comm,
906c08f6 283 unsigned long timestamp, char *hostname)
1fc22eb4
JD
284{
285 struct processtop *tmp;
1d2391b4 286
1fc22eb4 287 tmp = find_process_tid(ctx, tid, comm);
1d2391b4 288 if (tmp && strcmp(tmp->comm, comm) == 0) {
1fc22eb4 289 return tmp;
1d2391b4 290 }
906c08f6 291 return add_proc(ctx, tid, comm, timestamp, hostname);
1fc22eb4
JD
292}
293
59288610 294struct processtop *get_proc_pid(struct lttngtop *ctx, int tid, int pid,
906c08f6 295 unsigned long timestamp, char *hostname)
59288610
MB
296{
297 struct processtop *tmp;
298 tmp = find_process_tid(ctx, tid, NULL);
299 if (tmp && tmp->pid == pid)
300 return tmp;
906c08f6 301 return add_proc(ctx, tid, "Unknown", timestamp, hostname);
59288610
MB
302}
303
1fc22eb4
JD
304void add_thread(struct processtop *parent, struct processtop *thread)
305{
306 gint i;
307 struct processtop *tmp;
308
96aa77de
JD
309 if (!parent)
310 return;
311
1fc22eb4
JD
312 for (i = 0; i < parent->threads->len; i++) {
313 tmp = g_ptr_array_index(parent->threads, i);
314 if (tmp == thread)
315 return;
316 }
317 g_ptr_array_add(parent->threads, thread);
318}
319
320struct cputime* add_cpu(int cpu)
321{
322 struct cputime *newcpu;
323
559c9f86 324 newcpu = g_new0(struct cputime, 1);
1fc22eb4
JD
325 newcpu->id = cpu;
326 newcpu->current_task = NULL;
85db4618 327 newcpu->perf = g_hash_table_new(g_str_hash, g_str_equal);
1fc22eb4
JD
328
329 g_ptr_array_add(lttngtop.cpu_table, newcpu);
330
331 return newcpu;
332}
333struct cputime* get_cpu(int cpu)
334{
335 gint i;
336 struct cputime *tmp;
337
338 for (i = 0; i < lttngtop.cpu_table->len; i++) {
339 tmp = g_ptr_array_index(lttngtop.cpu_table, i);
340 if (tmp->id == cpu)
341 return tmp;
342 }
343
344 return add_cpu(cpu);
345}
346
347/*
348 * At the end of a sampling period, we need to display the cpu time for each
349 * process and to reset it to zero for the next period
350 */
351void rotate_cputime(unsigned long end)
352{
353 gint i;
354 struct cputime *tmp;
355 unsigned long elapsed;
356
357 for (i = 0; i < lttngtop.cpu_table->len; i++) {
358 tmp = g_ptr_array_index(lttngtop.cpu_table, i);
359 elapsed = end - tmp->task_start;
360 if (tmp->current_task) {
361 tmp->current_task->totalcpunsec += elapsed;
362 tmp->current_task->threadstotalcpunsec += elapsed;
363 if (tmp->current_task->pid != tmp->current_task->tid &&
364 tmp->current_task->threadparent) {
365 tmp->current_task->threadparent->threadstotalcpunsec += elapsed;
366 }
367 }
368 tmp->task_start = end;
369 }
370}
371
372void reset_perf_counter(gpointer key, gpointer value, gpointer user_data)
373{
374 ((struct perfcounter*) value)->count = 0;
375}
376
377void copy_perf_counter(gpointer key, gpointer value, gpointer new_table)
378{
379 struct perfcounter *newperf;
59288610 380
559c9f86 381 newperf = g_new0(struct perfcounter, 1);
1fc22eb4
JD
382 newperf->count = ((struct perfcounter *) value)->count;
383 newperf->visible = ((struct perfcounter *) value)->visible;
384 newperf->sort = ((struct perfcounter *) value)->sort;
85db4618 385 g_hash_table_insert((GHashTable *) new_table, strdup(key), newperf);
1fc22eb4
JD
386}
387
30b646c4
JD
388void copy_process_table(gpointer key, gpointer value, gpointer new_table)
389{
390 g_hash_table_insert((GHashTable *) new_table, key, value);
391}
392
1fc22eb4
JD
393void rotate_perfcounter() {
394 int i;
395 struct processtop *tmp;
b99227ca 396
1fc22eb4
JD
397 for (i = 0; i < lttngtop.process_table->len; i++) {
398 tmp = g_ptr_array_index(lttngtop.process_table, i);
399 g_hash_table_foreach(tmp->perf, reset_perf_counter, NULL);
400 }
401}
402
403void cleanup_processtop()
404{
b093de8a 405 gint i, j;
1fc22eb4 406 struct processtop *tmp;
b093de8a 407 struct files *tmpf; /* a temporary file */
1fc22eb4
JD
408
409 for (i = 0; i < lttngtop.process_table->len; i++) {
410 tmp = g_ptr_array_index(lttngtop.process_table, i);
411 tmp->totalcpunsec = 0;
412 tmp->threadstotalcpunsec = 0;
b093de8a
MB
413 tmp->fileread = 0;
414 tmp->filewrite = 0;
415
416 for (j = 0; j < tmp->process_files_table->len; j++) {
417 tmpf = g_ptr_array_index(tmp->process_files_table, j);
418 if (tmpf != NULL) {
419 tmpf->read = 0;
420 tmpf->write = 0;
ceb3a221
MB
421
422 if (tmpf->flag == __NR_close)
423 g_ptr_array_index(
424 tmp->process_files_table, j
425 ) = NULL;
b093de8a
MB
426 }
427 }
1fc22eb4
JD
428 }
429}
430
e05a35a6
JD
431void reset_global_counters()
432{
433 lttngtop.nbnewproc = 0;
434 lttngtop.nbdeadproc = 0;
435 lttngtop.nbnewthreads = 0;
436 lttngtop.nbdeadthreads = 0;
437 lttngtop.nbnewfiles = 0;
438 lttngtop.nbclosedfiles = 0;
439}
440
441void copy_global_counters(struct lttngtop *dst)
442{
443 dst->nbproc = lttngtop.nbproc;
444 dst->nbnewproc = lttngtop.nbnewproc;
445 dst->nbdeadproc = lttngtop.nbdeadproc;
446 dst->nbthreads = lttngtop.nbthreads;
447 dst->nbnewthreads = lttngtop.nbnewthreads;
448 dst->nbdeadthreads = lttngtop.nbdeadthreads;
449 dst->nbfiles = lttngtop.nbfiles;
450 dst->nbnewfiles = lttngtop.nbnewfiles;
451 dst->nbclosedfiles = lttngtop.nbclosedfiles;
452 reset_global_counters();
453}
454
1fc22eb4
JD
455struct lttngtop* get_copy_lttngtop(unsigned long start, unsigned long end)
456{
457 gint i, j;
458 unsigned long time;
459 struct lttngtop *dst;
460 struct processtop *tmp, *tmp2, *new;
461 struct cputime *tmpcpu, *newcpu;
462 struct files *tmpfile, *newfile;
246d5992 463 struct kprobes *tmpprobe, *newprobe;
1fc22eb4 464
559c9f86 465 dst = g_new0(struct lttngtop, 1);
1fc22eb4
JD
466 dst->start = start;
467 dst->end = end;
e05a35a6 468 copy_global_counters(dst);
1fc22eb4
JD
469 dst->process_table = g_ptr_array_new();
470 dst->files_table = g_ptr_array_new();
471 dst->cpu_table = g_ptr_array_new();
246d5992 472 dst->kprobes_table = g_ptr_array_new();
30b646c4
JD
473 dst->process_hash_table = g_hash_table_new(g_direct_hash, g_direct_equal);
474 g_hash_table_foreach(lttngtop.process_hash_table, copy_process_table,
475 dst->process_hash_table);
1fc22eb4
JD
476
477 rotate_cputime(end);
478
1fc22eb4
JD
479 for (i = 0; i < lttngtop.process_table->len; i++) {
480 tmp = g_ptr_array_index(lttngtop.process_table, i);
559c9f86 481 new = g_new0(struct processtop, 1);
1fc22eb4
JD
482
483 memcpy(new, tmp, sizeof(struct processtop));
484 new->threads = g_ptr_array_new();
485 new->comm = strdup(tmp->comm);
486 new->process_files_table = g_ptr_array_new();
ceb3a221 487 new->files_history = tmp->files_history;
85db4618 488 new->perf = g_hash_table_new(g_str_hash, g_str_equal);
1fc22eb4
JD
489 g_hash_table_foreach(tmp->perf, copy_perf_counter, new->perf);
490
1fc22eb4 491 /* compute the stream speed */
85db4618
JD
492 if (end - start != 0) {
493 time = (end - start) / NSEC_PER_SEC;
b093de8a
MB
494 new->fileread = new->fileread/(time);
495 new->filewrite = new->filewrite/(time);
1fc22eb4
JD
496 }
497
498 for (j = 0; j < tmp->process_files_table->len; j++) {
499 tmpfile = g_ptr_array_index(tmp->process_files_table, j);
1fc22eb4 500
b093de8a
MB
501 newfile = malloc(sizeof(struct files));
502
503 if (tmpfile != NULL) {
504 memcpy(newfile, tmpfile, sizeof(struct files));
505 newfile->name = strdup(tmpfile->name);
506 newfile->ref = new;
507 g_ptr_array_add(new->process_files_table,
508 newfile);
509 g_ptr_array_add(dst->files_table, newfile);
510 } else {
511 g_ptr_array_add(new->process_files_table, NULL);
512 g_ptr_array_add(dst->files_table, NULL);
513 }
1fc22eb4
JD
514 /*
515 * if the process died during the last period, we remove all
516 * files associated with if after the copy
517 */
518 if (tmp->death > 0 && tmp->death < end) {
e05a35a6 519 /* FIXME : close the files before */
1fc22eb4 520 g_ptr_array_remove(tmp->process_files_table, tmpfile);
559c9f86 521 g_free(tmpfile);
1fc22eb4
JD
522 }
523 }
524 g_ptr_array_add(dst->process_table, new);
525
526 /*
527 * if the process died during the last period, we remove it from
528 * the current process list after the copy
529 */
530 if (tmp->death > 0 && tmp->death < end) {
531 g_ptr_array_remove(lttngtop.process_table, tmp);
85db4618 532 /* FIXME : TRUE does not mean clears the object in it */
1fc22eb4
JD
533 g_ptr_array_free(tmp->threads, TRUE);
534 free(tmp->comm);
535 g_ptr_array_free(tmp->process_files_table, TRUE);
85db4618 536 /* FIXME : clear elements */
1fc22eb4 537 g_hash_table_destroy(tmp->perf);
559c9f86 538 g_free(tmp);
1fc22eb4
JD
539 }
540 }
541 rotate_perfcounter();
542
543 for (i = 0; i < lttngtop.cpu_table->len; i++) {
544 tmpcpu = g_ptr_array_index(lttngtop.cpu_table, i);
559c9f86 545 newcpu = g_new0(struct cputime, 1);
1fc22eb4 546 memcpy(newcpu, tmpcpu, sizeof(struct cputime));
85db4618 547 newcpu->perf = g_hash_table_new(g_str_hash, g_str_equal);
1fc22eb4
JD
548 g_hash_table_foreach(tmpcpu->perf, copy_perf_counter, newcpu->perf);
549 /*
550 * note : we don't care about the current process pointer in the copy
551 * so the reference is invalid after the memcpy
552 */
553 g_ptr_array_add(dst->cpu_table, newcpu);
554 }
da4353bb
JD
555 if (lttngtop.kprobes_table) {
556 for (i = 0; i < lttngtop.kprobes_table->len; i++) {
557 tmpprobe = g_ptr_array_index(lttngtop.kprobes_table, i);
558 newprobe = g_new0(struct kprobes, 1);
559 memcpy(newprobe, tmpprobe, sizeof(struct kprobes));
560 tmpprobe->count = 0;
561 g_ptr_array_add(dst->kprobes_table, newprobe);
562 }
246d5992 563 }
85db4618 564 /* FIXME : better algo */
1fc22eb4
JD
565 /* create the threads index if required */
566 for (i = 0; i < dst->process_table->len; i++) {
567 tmp = g_ptr_array_index(dst->process_table, i);
568 if (tmp->pid == tmp->tid) {
569 for (j = 0; j < dst->process_table->len; j++) {
570 tmp2 = g_ptr_array_index(dst->process_table, j);
571 if (tmp2->pid == tmp->pid) {
572 tmp2->threadparent = tmp;
573 g_ptr_array_add(tmp->threads, tmp2);
574 }
575 }
576 }
577 }
578
579 // update_global_stats(dst);
580 cleanup_processtop();
581
582 return dst;
583}
584
928f18a6
MB
585
586enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data,
587 void *private_data)
588{
2e0a1190 589 const struct bt_definition *scope;
928f18a6
MB
590 struct processtop *proc;
591 unsigned long timestamp;
11d218ce 592 int64_t pid, tid, ppid, vtid, vpid, vppid;
1d2391b4 593 char *procname, *hostname = NULL;
928f18a6 594
c78f2cdc 595 timestamp = bt_ctf_get_timestamp(call_data);
928f18a6
MB
596 if (timestamp == -1ULL)
597 goto error;
598
599 scope = bt_ctf_get_top_level_scope(call_data,
600 BT_EVENT_FIELDS);
601 pid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
602 scope, "_pid"));
603 if (bt_ctf_field_get_error()) {
604 fprintf(stderr, "Missing pid context info\n");
605 goto error;
606 }
11d218ce
JD
607 ppid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
608 scope, "_ppid"));
609 if (bt_ctf_field_get_error()) {
8fe4d0cf 610 goto end;
11d218ce 611 }
928f18a6
MB
612 tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
613 scope, "_tid"));
614 if (bt_ctf_field_get_error()) {
615 fprintf(stderr, "Missing tid context info\n");
616 goto error;
617 }
11d218ce
JD
618 vtid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
619 scope, "_vtid"));
620 if (bt_ctf_field_get_error()) {
621 fprintf(stderr, "Missing vtid context info\n");
622 goto error;
623 }
624 vpid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
625 scope, "_vpid"));
626 if (bt_ctf_field_get_error()) {
b7194a4e 627 fprintf(stderr, "Missing vpid context info\n");
11d218ce
JD
628 goto error;
629 }
630 vppid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
631 scope, "_vppid"));
632 if (bt_ctf_field_get_error()) {
b7194a4e 633 fprintf(stderr, "Missing vppid context info\n");
11d218ce
JD
634 goto error;
635 }
636
928f18a6
MB
637 scope = bt_ctf_get_top_level_scope(call_data,
638 BT_EVENT_FIELDS);
639 procname = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
640 scope, "_name"));
641 if (bt_ctf_field_get_error()) {
642 fprintf(stderr, "Missing process name context info\n");
643 goto error;
644 }
645
646 proc = find_process_tid(&lttngtop, tid, procname);
647 if (proc == NULL)
1d2391b4
JD
648 proc = add_proc(&lttngtop, tid, procname, timestamp, hostname);
649 update_proc(proc, pid, tid, ppid, vpid, vtid, vppid, procname, hostname);
928f18a6 650
96aa77de
JD
651 if (proc) {
652 free(proc->comm);
653 proc->comm = strdup(procname);
654 proc->pid = pid;
655 }
928f18a6 656
8fe4d0cf 657end:
928f18a6
MB
658 return BT_CB_OK;
659
660error:
661 return BT_CB_ERROR_STOP;
662}
b520ab45
JD
663
664struct tm format_timestamp(uint64_t timestamp)
665{
666 struct tm tm;
667 uint64_t ts_sec = 0, ts_nsec;
668 time_t time_s;
669
670 ts_nsec = timestamp;
671 ts_sec += ts_nsec / NSEC_PER_SEC;
672 ts_nsec = ts_nsec % NSEC_PER_SEC;
673
674 time_s = (time_t) ts_sec;
675
676 localtime_r(&time_s, &tm);
677
678 return tm;
679}
57bff788
JD
680
681int *lookup_tid_list(int tid)
682{
ea5d1dc9 683 if (!tid_filter_list)
da4353bb
JD
684 return NULL;
685
ea5d1dc9 686 return g_hash_table_lookup(tid_filter_list, (gpointer) &tid);
57bff788 687}
c8d75a13 688
114cae59 689struct host *lookup_hostname_list(const char *hostname)
c8d75a13 690{
114cae59 691 if (!hostname || !global_host_list)
c8d75a13
JD
692 return NULL;
693
114cae59 694 return g_hash_table_lookup(global_host_list, (gpointer) hostname);
c8d75a13 695}
da4353bb 696
114cae59 697int is_hostname_filtered(const char *hostname)
906c08f6 698{
114cae59 699 struct host *host;
906c08f6 700
114cae59
JD
701 host = lookup_hostname_list(hostname);
702 if (host)
703 return host->filter;
704 return 0;
906c08f6
JD
705}
706
da4353bb
JD
707int *lookup_filter_tid_list(int tid)
708{
709 return g_hash_table_lookup(global_filter_list, (gpointer) &tid);
710}
711
b99227ca 712void add_filter_tid_list(struct processtop *proc)
da4353bb
JD
713{
714 unsigned long *hash_tid;
715
716 hash_tid = malloc(sizeof(unsigned long));
b99227ca 717 *hash_tid = proc->tid;
da4353bb 718 g_hash_table_insert(global_filter_list,
b99227ca 719 (gpointer) (unsigned long) hash_tid, proc);
da4353bb
JD
720}
721
722void remove_filter_tid_list(int tid)
723{
724 g_hash_table_remove(global_filter_list,
725 (gpointer) (unsigned long) &tid);
726}
467097ac 727
b99227ca 728struct host *add_hostname_list(char *hostname, int filter)
467097ac
JD
729{
730 struct host *host;
731
b99227ca
JD
732 host = lookup_hostname_list(hostname);
733 if (host)
734 return host;
467097ac
JD
735
736 host = g_new0(struct host, 1);
737 host->hostname = strdup(hostname);
738 host->filter = filter;
739 g_hash_table_insert(global_host_list,
740 (gpointer) host->hostname,
741 (gpointer) host);
b99227ca
JD
742
743 return host;
744}
745
746void update_hostname_filter(struct host *host)
747{
748 struct processtop *tmp;
749 int i;
750
751 for (i = 0; i < lttngtop.process_table->len; i++) {
752 tmp = g_ptr_array_index(lttngtop.process_table, i);
753 if (tmp->host == host) {
754 if (host->filter)
755 add_filter_tid_list(tmp);
756 else
757 remove_filter_tid_list(tmp->tid);
758 }
759 }
467097ac 760}
26e46dde
JD
761
762char *lookup_procname(const char *procname)
763{
764 if (!procname || !global_procname_list)
765 return NULL;
766
767 return g_hash_table_lookup(global_procname_list, (gpointer) procname);
768}
769
770char *add_procname_list(char *procname, int filter)
771{
772 char *proc;
773
774 proc = lookup_procname(procname);
775 if (proc)
776 return proc;
777
778 proc = strdup(procname);
779 g_hash_table_insert(global_procname_list,
780 (gpointer) procname, (gpointer) procname);
781
782 return proc;
783}
This page took 0.061598 seconds and 4 git commands to generate.