blob: 09c4ef0d17378748ee67a870301f7b086bcf6163 [file] [log] [blame]
Elijah Newrena64acf72023-03-21 06:26:02 +00001#include "git-compat-util.h"
Elijah Newren41771fa2023-02-24 00:09:27 +00002#include "hex.h"
Elijah Newrena64acf72023-03-21 06:26:02 +00003#include "strbuf.h"
Jeff Hostetler08881b92019-04-15 13:39:49 -07004#include "trace2/tr2_tbuf.h"
Jeff Hostetleree4512e2019-02-22 14:25:01 -08005#include "trace2/tr2_sid.h"
6
SZEDER Gábore4b75d62019-05-19 16:43:08 +02007#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID"
Jeff Hostetleree4512e2019-02-22 14:25:01 -08008
9static struct strbuf tr2sid_buf = STRBUF_INIT;
10static int tr2sid_nr_git_parents;
11
12/*
Jeff Hostetler08881b92019-04-15 13:39:49 -070013 * Compute the final component of the SID representing the current process.
14 * This should uniquely identify the process and be a valid filename (to
15 * allow writing trace2 data to per-process files). It should also be fixed
16 * length for possible use as a database key.
17 *
18 * "<yyyymmdd>T<hhmmss>.<fraction>Z-<host>-<process>"
19 *
20 * where <host> is a 9 character string:
21 * "H<first_8_chars_of_sha1_of_hostname>"
22 * "Localhost" when no hostname.
23 *
Elijah Newren15beaaa2019-11-05 17:07:23 +000024 * where <process> is a 9 character string containing the least significant
Jeff Hostetler08881b92019-04-15 13:39:49 -070025 * 32 bits in the process-id.
26 * "P<pid>"
27 * (This is an abribrary choice. On most systems pid_t is a 32 bit value,
28 * so limit doesn't matter. On larger systems, a truncated value is fine
29 * for our purposes here.)
30 */
31static void tr2_sid_append_my_sid_component(void)
32{
33 const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA1];
34 struct tr2_tbuf tb_now;
35 git_hash_ctx ctx;
36 pid_t pid = getpid();
37 unsigned char hash[GIT_MAX_RAWSZ + 1];
38 char hex[GIT_MAX_HEXSZ + 1];
39 char hostname[HOST_NAME_MAX + 1];
40
41 tr2_tbuf_utc_datetime(&tb_now);
42 strbuf_addstr(&tr2sid_buf, tb_now.buf);
43
44 strbuf_addch(&tr2sid_buf, '-');
45 if (xgethostname(hostname, sizeof(hostname)))
46 strbuf_add(&tr2sid_buf, "Localhost", 9);
47 else {
48 algo->init_fn(&ctx);
49 algo->update_fn(&ctx, hostname, strlen(hostname));
50 algo->final_fn(hash, &ctx);
51 hash_to_hex_algop_r(hex, hash, algo);
52 strbuf_addch(&tr2sid_buf, 'H');
53 strbuf_add(&tr2sid_buf, hex, 8);
54 }
55
56 strbuf_addf(&tr2sid_buf, "-P%08"PRIx32, (uint32_t)pid);
57}
58
59/*
Jeff Hostetleree4512e2019-02-22 14:25:01 -080060 * Compute a "unique" session id (SID) for the current process. This allows
61 * all events from this process to have a single label (much like a PID).
62 *
63 * Export this into our environment so that all child processes inherit it.
64 *
65 * If we were started by another git instance, use our parent's SID as a
66 * prefix. (This lets us track parent/child relationships even if there
67 * is an intermediate shell process.)
68 *
69 * Additionally, count the number of nested git processes.
70 */
71static void tr2_sid_compute(void)
72{
Jeff Hostetleree4512e2019-02-22 14:25:01 -080073 const char *parent_sid;
74
75 if (tr2sid_buf.len)
76 return;
77
78 parent_sid = getenv(TR2_ENVVAR_PARENT_SID);
79 if (parent_sid && *parent_sid) {
80 const char *p;
81 for (p = parent_sid; *p; p++)
82 if (*p == '/')
83 tr2sid_nr_git_parents++;
84
85 strbuf_addstr(&tr2sid_buf, parent_sid);
86 strbuf_addch(&tr2sid_buf, '/');
87 tr2sid_nr_git_parents++;
88 }
89
Jeff Hostetler08881b92019-04-15 13:39:49 -070090 tr2_sid_append_my_sid_component();
Jeff Hostetleree4512e2019-02-22 14:25:01 -080091
92 setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1);
93}
94
95const char *tr2_sid_get(void)
96{
97 if (!tr2sid_buf.len)
98 tr2_sid_compute();
99
100 return tr2sid_buf.buf;
101}
102
103int tr2_sid_depth(void)
104{
105 if (!tr2sid_buf.len)
106 tr2_sid_compute();
107
108 return tr2sid_nr_git_parents;
109}
110
111void tr2_sid_release(void)
112{
113 strbuf_release(&tr2sid_buf);
114}