LIBTRACEFS(3)

πŸ’… LIBTRACEFS(3) β€” libtracefs Manual πŸ’…

okay so bestie, welcome to the libtracefs corner of the manual universe. this one's all about the little helper functions that handle tracing guests. yes, guests. like VMs. we're being hospitable. 🫢


✨ NAME ✨

tracefs_find_cid_pid, tracefs_instance_find_cid_pid, tracefs_time_conversion β€” helper functions to handle tracing guests πŸ’–


πŸ¦‹ SYNOPSIS πŸ¦‹

#include <tracefs.h>

char *tracefs_find_cid_pid(int cid);
char *tracefs_instance_find_cid_pid(struct tracefs_instance *instance, int cid);
int tracefs_time_conversion(int cpu, int *shift, int *multi, long long *offset);

🌸 DESCRIPTION 🌸

so, tracefs_find_cid_pid() is lowkey doing detective work: it uses tracing to follow the wakeups of connecting to the given cid, all so it can find the pid of the guest thread that belongs to the vsocket cid. then it goes and reads the proc file system to find the thread leader, and it returns the pid of that thread leader. icon behaviour honestly. πŸ”πŸ‘‘

tracefs_instance_find_cid_pid() is literally the same as tracefs_find_cid_pid() β€” same energy, same job β€” except it lets you define the instance to use for the tracing. and if you pass NULL? it'll just use the top level buffer to do the tracing. easy. πŸ’…

and tracefs_time_conversion()? that one returns the values the kernel uses to convert the raw time stamp counter into nanoseconds for the given cpu. ngl this is the good stuff. the pointers for shift, multi and offset can be NULL and they'll just be ignored, otherwise they get set with the shift, multiplier and offset repectively. no cap. ✨


πŸŽ€ RETURN VALUE πŸŽ€

both tracefs_find_cid_pid() and tracefs_instance_find_cid_pid() will return the pid of the guest main thread that belongs to the cid, or -1 on error (or if it's simply not found). main character or nothing, periodt. πŸ’€


πŸ”₯ EXAMPLE πŸ”₯

#include <stdlib.h>
#include <unistd.h>
#include <tracefs.h>

#define MAX_CID         256

static void find_cid(struct tracefs_instance *instance, int cid)
{
        int pid;

        pid = tracefs_instance_find_cid_pid(instance, cid);
        if (pid >= 0)
                printf("%d\t%d\n", cid, pid);
}

static int find_cids(void)
{
        struct tracefs_instance *instance;
        char *name;
        int cid;
        int ret;

        ret = asprintf(&name, "vsock_find-%d\n", getpid());
        if (ret < 0)
                return ret;

        instance = tracefs_instance_create(name);
        free(name);
        if (!instance)
                return -1;

        for (cid = 0; cid < MAX_CID; cid++)
                find_cid(instance, cid);

        tracefs_event_disable(instance, NULL, NULL);
        tracefs_instance_destroy(instance);
        tracefs_instance_free(instance);
        return 0;
}

struct time_info {
        int             shift;
        int             multi;
};

static void show_time_conversion(void)
{
        struct time_info *tinfo;
        int cpus;
        int cpu;
        int ret;

        cpus = sysconf(_SC_NPROCESSORS_CONF);
        tinfo = calloc(cpus, sizeof(*tinfo));
        if (!tinfo)
                exit(-1);

        for (cpu = 0; cpu < cpus; cpu++) {
                ret  = tracefs_time_conversion(cpu,
                                                &tinfo[cpu].shift,
                                                &tinfo[cpu].multi,
                                                NULL);
                if (ret)
                        break;
        }
        if (cpu != cpus) {
                if (!cpu) {
                        perror("tracefs_time_conversion");
                        exit(-1);
                }
                printf("Only read %d of %d CPUs", cpu, cpus);
                cpus = cpu + 1;
        }

        /* Check if all the shift and mult values are the same */
        for (cpu = 1; cpu < cpus; cpu++) {
                if (tinfo[cpu - 1].shift != tinfo[cpu].shift)
                        break;
                if (tinfo[cpu - 1].multi != tinfo[cpu].multi)
                        break;
        }

        if (cpu == cpus) {
                printf("All cpus have:\n");
                printf(" shift:  %d\n", tinfo[0].shift);
                printf(" multi:  %d\n", tinfo[0].multi);
                printf("\n");
                return;
        }

        for (cpu = 0; cpu < cpus; cpu++) {
                printf("CPU: %d\n", cpu);
                printf(" shift:  %d\n", tinfo[cpu].shift);
                printf(" multi:  %d\n", tinfo[cpu].multi);
                printf("\n");
        }
}

int main(int argc, char *argv[])
{
        show_time_conversion();
        find_cids();
        exit(0);
}

🧚 FILES 🧚

  • tracefs.h β€” the header file you include to get access to the library APIs. bestie you literally cannot skip this one. πŸ“Ž
  • -ltracefs β€” the linker switch you add when building a program that uses the library. yes it's a flag, yes it's iconic.

🌈 SEE ALSO 🌈

libtracefs(3), libtraceevent(3), trace-cmd(1)

go read those too, iykyk 🌟


πŸ‘‘ AUTHOR πŸ‘‘

  • Steven Rostedt <rostedt@goodmis.org[1]>
  • Tzvetomir Stoyanov <tz.stoyanov@gmail.com[2]>

πŸ’œ REPORTING BUGS πŸ’œ

report bugs to <linux-trace-devel@vger.kernel.org[3]>. we love a bug report, fr fr. πŸ›


🌺 LICENSE 🌺

libtracefs is Free Software licensed under the GNU LGPL 2.1. periodt. πŸ’š


⭐ RESOURCES ⭐

https://git.kernel.org/pub/scm/libs/libtrace/libtracefs.git/


πŸ“ COPYING πŸ“

Copyright (C) 2020 VMware, Inc. Free use of this software is granted under the terms of the GNU Public License (GPL). πŸ’–


πŸ™ˆ NOTES πŸ™ˆ

  1. rostedt@goodmis.org mailto:rostedt@goodmis.org
  2. tz.stoyanov@gmail.com mailto:tz.stoyanov@gmail.com
  3. linux-trace-devel@vger.kernel.org mailto:linux-trace-devel@vger.kernel.org

and that's the whole page bestie!! 🌈✨ this was libtracefs 1.8.4, dated 10/21/2026, and honestly? she ate. πŸ’…πŸŽ€πŸ¦‹

πŸ“¦ where this page comes from