prepare the 0.3 release
[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;
18e85696 301 return add_proc(ctx, tid, NULL, 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));
18e85696
JD
505 if (tmpfile->name)
506 newfile->name = strdup(tmpfile->name);
507 else
508 newfile->name = NULL;
b093de8a
MB
509 newfile->ref = new;
510 g_ptr_array_add(new->process_files_table,
511 newfile);
512 g_ptr_array_add(dst->files_table, newfile);
513 } else {
514 g_ptr_array_add(new->process_files_table, NULL);
515 g_ptr_array_add(dst->files_table, NULL);
516 }
1fc22eb4
JD
517 /*
518 * if the process died during the last period, we remove all
519 * files associated with if after the copy
520 */
521 if (tmp->death > 0 && tmp->death < end) {
e05a35a6 522 /* FIXME : close the files before */
1fc22eb4 523 g_ptr_array_remove(tmp->process_files_table, tmpfile);
559c9f86 524 g_free(tmpfile);
1fc22eb4
JD
525 }
526 }
527 g_ptr_array_add(dst->process_table, new);
528
529 /*
530 * if the process died during the last period, we remove it from
531 * the current process list after the copy
532 */
533 if (tmp->death > 0 && tmp->death < end) {
534 g_ptr_array_remove(lttngtop.process_table, tmp);
85db4618 535 /* FIXME : TRUE does not mean clears the object in it */
1fc22eb4
JD
536 g_ptr_array_free(tmp->threads, TRUE);
537 free(tmp->comm);
538 g_ptr_array_free(tmp->process_files_table, TRUE);
85db4618 539 /* FIXME : clear elements */
1fc22eb4 540 g_hash_table_destroy(tmp->perf);
559c9f86 541 g_free(tmp);
1fc22eb4
JD
542 }
543 }
544 rotate_perfcounter();
545
546 for (i = 0; i < lttngtop.cpu_table->len; i++) {
547 tmpcpu = g_ptr_array_index(lttngtop.cpu_table, i);
559c9f86 548 newcpu = g_new0(struct cputime, 1);
1fc22eb4 549 memcpy(newcpu, tmpcpu, sizeof(struct cputime));
85db4618 550 newcpu->perf = g_hash_table_new(g_str_hash, g_str_equal);
1fc22eb4
JD
551 g_hash_table_foreach(tmpcpu->perf, copy_perf_counter, newcpu->perf);
552 /*
553 * note : we don't care about the current process pointer in the copy
554 * so the reference is invalid after the memcpy
555 */
556 g_ptr_array_add(dst->cpu_table, newcpu);
557 }
da4353bb
JD
558 if (lttngtop.kprobes_table) {
559 for (i = 0; i < lttngtop.kprobes_table->len; i++) {
560 tmpprobe = g_ptr_array_index(lttngtop.kprobes_table, i);
561 newprobe = g_new0(struct kprobes, 1);
562 memcpy(newprobe, tmpprobe, sizeof(struct kprobes));
563 tmpprobe->count = 0;
564 g_ptr_array_add(dst->kprobes_table, newprobe);
565 }
246d5992 566 }
85db4618 567 /* FIXME : better algo */
1fc22eb4
JD
568 /* create the threads index if required */
569 for (i = 0; i < dst->process_table->len; i++) {
570 tmp = g_ptr_array_index(dst->process_table, i);
571 if (tmp->pid == tmp->tid) {
572 for (j = 0; j < dst->process_table->len; j++) {
573 tmp2 = g_ptr_array_index(dst->process_table, j);
574 if (tmp2->pid == tmp->pid) {
575 tmp2->threadparent = tmp;
576 g_ptr_array_add(tmp->threads, tmp2);
577 }
578 }
579 }
580 }
581
582 // update_global_stats(dst);
583 cleanup_processtop();
584
585 return dst;
586}
587
928f18a6
MB
588
589enum bt_cb_ret handle_statedump_process_state(struct bt_ctf_event *call_data,
590 void *private_data)
591{
2e0a1190 592 const struct bt_definition *scope;
928f18a6
MB
593 struct processtop *proc;
594 unsigned long timestamp;
11d218ce 595 int64_t pid, tid, ppid, vtid, vpid, vppid;
18e85696 596 char *procname = NULL, *hostname = NULL;
928f18a6 597
c78f2cdc 598 timestamp = bt_ctf_get_timestamp(call_data);
928f18a6
MB
599 if (timestamp == -1ULL)
600 goto error;
601
602 scope = bt_ctf_get_top_level_scope(call_data,
603 BT_EVENT_FIELDS);
604 pid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
605 scope, "_pid"));
606 if (bt_ctf_field_get_error()) {
607 fprintf(stderr, "Missing pid context info\n");
608 goto error;
609 }
11d218ce
JD
610 ppid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
611 scope, "_ppid"));
612 if (bt_ctf_field_get_error()) {
8fe4d0cf 613 goto end;
11d218ce 614 }
928f18a6
MB
615 tid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
616 scope, "_tid"));
617 if (bt_ctf_field_get_error()) {
618 fprintf(stderr, "Missing tid context info\n");
619 goto error;
620 }
11d218ce
JD
621 vtid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
622 scope, "_vtid"));
623 if (bt_ctf_field_get_error()) {
624 fprintf(stderr, "Missing vtid context info\n");
625 goto error;
626 }
627 vpid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
628 scope, "_vpid"));
629 if (bt_ctf_field_get_error()) {
b7194a4e 630 fprintf(stderr, "Missing vpid context info\n");
11d218ce
JD
631 goto error;
632 }
633 vppid = bt_ctf_get_int64(bt_ctf_get_field(call_data,
634 scope, "_vppid"));
635 if (bt_ctf_field_get_error()) {
b7194a4e 636 fprintf(stderr, "Missing vppid context info\n");
11d218ce
JD
637 goto error;
638 }
639
928f18a6
MB
640 scope = bt_ctf_get_top_level_scope(call_data,
641 BT_EVENT_FIELDS);
642 procname = bt_ctf_get_char_array(bt_ctf_get_field(call_data,
643 scope, "_name"));
644 if (bt_ctf_field_get_error()) {
645 fprintf(stderr, "Missing process name context info\n");
646 goto error;
647 }
648
649 proc = find_process_tid(&lttngtop, tid, procname);
650 if (proc == NULL)
1d2391b4
JD
651 proc = add_proc(&lttngtop, tid, procname, timestamp, hostname);
652 update_proc(proc, pid, tid, ppid, vpid, vtid, vppid, procname, hostname);
928f18a6 653
96aa77de
JD
654 if (proc) {
655 free(proc->comm);
656 proc->comm = strdup(procname);
657 proc->pid = pid;
658 }
928f18a6 659
8fe4d0cf 660end:
928f18a6
MB
661 return BT_CB_OK;
662
663error:
664 return BT_CB_ERROR_STOP;
665}
b520ab45
JD
666
667struct tm format_timestamp(uint64_t timestamp)
668{
669 struct tm tm;
670 uint64_t ts_sec = 0, ts_nsec;
671 time_t time_s;
672
673 ts_nsec = timestamp;
674 ts_sec += ts_nsec / NSEC_PER_SEC;
675 ts_nsec = ts_nsec % NSEC_PER_SEC;
676
677 time_s = (time_t) ts_sec;
678
679 localtime_r(&time_s, &tm);
680
681 return tm;
682}
57bff788
JD
683
684int *lookup_tid_list(int tid)
685{
ea5d1dc9 686 if (!tid_filter_list)
da4353bb
JD
687 return NULL;
688
ea5d1dc9 689 return g_hash_table_lookup(tid_filter_list, (gpointer) &tid);
57bff788 690}
c8d75a13 691
114cae59 692struct host *lookup_hostname_list(const char *hostname)
c8d75a13 693{
114cae59 694 if (!hostname || !global_host_list)
c8d75a13
JD
695 return NULL;
696
114cae59 697 return g_hash_table_lookup(global_host_list, (gpointer) hostname);
c8d75a13 698}
da4353bb 699
114cae59 700int is_hostname_filtered(const char *hostname)
906c08f6 701{
114cae59 702 struct host *host;
906c08f6 703
114cae59
JD
704 host = lookup_hostname_list(hostname);
705 if (host)
706 return host->filter;
707 return 0;
906c08f6
JD
708}
709
da4353bb
JD
710int *lookup_filter_tid_list(int tid)
711{
712 return g_hash_table_lookup(global_filter_list, (gpointer) &tid);
713}
714
b99227ca 715void add_filter_tid_list(struct processtop *proc)
da4353bb
JD
716{
717 unsigned long *hash_tid;
718
719 hash_tid = malloc(sizeof(unsigned long));
b99227ca 720 *hash_tid = proc->tid;
da4353bb 721 g_hash_table_insert(global_filter_list,
b99227ca 722 (gpointer) (unsigned long) hash_tid, proc);
da4353bb
JD
723}
724
725void remove_filter_tid_list(int tid)
726{
727 g_hash_table_remove(global_filter_list,
728 (gpointer) (unsigned long) &tid);
729}
467097ac 730
b99227ca 731struct host *add_hostname_list(char *hostname, int filter)
467097ac
JD
732{
733 struct host *host;
734
b99227ca
JD
735 host = lookup_hostname_list(hostname);
736 if (host)
737 return host;
467097ac
JD
738
739 host = g_new0(struct host, 1);
740 host->hostname = strdup(hostname);
741 host->filter = filter;
742 g_hash_table_insert(global_host_list,
743 (gpointer) host->hostname,
744 (gpointer) host);
b99227ca
JD
745
746 return host;
747}
748
749void update_hostname_filter(struct host *host)
750{
751 struct processtop *tmp;
752 int i;
753
754 for (i = 0; i < lttngtop.process_table->len; i++) {
755 tmp = g_ptr_array_index(lttngtop.process_table, i);
756 if (tmp->host == host) {
757 if (host->filter)
758 add_filter_tid_list(tmp);
759 else
760 remove_filter_tid_list(tmp->tid);
761 }
762 }
467097ac 763}
26e46dde
JD
764
765char *lookup_procname(const char *procname)
766{
767 if (!procname || !global_procname_list)
768 return NULL;
769
770 return g_hash_table_lookup(global_procname_list, (gpointer) procname);
771}
772
773char *add_procname_list(char *procname, int filter)
774{
775 char *proc;
776
777 proc = lookup_procname(procname);
778 if (proc)
779 return proc;
780
781 proc = strdup(procname);
782 g_hash_table_insert(global_procname_list,
783 (gpointer) procname, (gpointer) procname);
784
785 return proc;
786}
This page took 0.100157 seconds and 4 git commands to generate.