]>
Commit | Line | Data |
---|---|---|
a64acf72 | 1 | #include "git-compat-util.h" |
41771fa4 | 2 | #include "hex.h" |
a64acf72 | 3 | #include "strbuf.h" |
08881b9a | 4 | #include "trace2/tr2_tbuf.h" |
ee4512ed JH |
5 | #include "trace2/tr2_sid.h" |
6 | ||
e4b75d6a | 7 | #define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID" |
ee4512ed JH |
8 | |
9 | static struct strbuf tr2sid_buf = STRBUF_INIT; | |
10 | static int tr2sid_nr_git_parents; | |
11 | ||
08881b9a JH |
12 | /* |
13 | * 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 | * | |
15beaaa3 | 24 | * where <process> is a 9 character string containing the least significant |
08881b9a JH |
25 | * 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 | */ | |
31 | static 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 | ||
ee4512ed JH |
59 | /* |
60 | * 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 | */ | |
71 | static void tr2_sid_compute(void) | |
72 | { | |
ee4512ed JH |
73 | 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 | ||
08881b9a | 90 | tr2_sid_append_my_sid_component(); |
ee4512ed JH |
91 | |
92 | setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1); | |
93 | } | |
94 | ||
95 | const char *tr2_sid_get(void) | |
96 | { | |
97 | if (!tr2sid_buf.len) | |
98 | tr2_sid_compute(); | |
99 | ||
100 | return tr2sid_buf.buf; | |
101 | } | |
102 | ||
103 | int tr2_sid_depth(void) | |
104 | { | |
105 | if (!tr2sid_buf.len) | |
106 | tr2_sid_compute(); | |
107 | ||
108 | return tr2sid_nr_git_parents; | |
109 | } | |
110 | ||
111 | void tr2_sid_release(void) | |
112 | { | |
113 | strbuf_release(&tr2sid_buf); | |
114 | } |