Coverage Report

Created: 2024-09-08 06:23

/src/git/trace2/tr2_sid.c
Line
Count
Source (jump to first uncovered line)
1
#include "git-compat-util.h"
2
#include "hex.h"
3
#include "strbuf.h"
4
#include "trace2/tr2_tbuf.h"
5
#include "trace2/tr2_sid.h"
6
7
0
#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID"
8
9
static struct strbuf tr2sid_buf = STRBUF_INIT;
10
static int tr2sid_nr_git_parents;
11
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
 *
24
 * where <process> is a 9 character string containing the least significant
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
0
{
33
0
  const struct git_hash_algo *algo = &hash_algos[GIT_HASH_SHA1];
34
0
  struct tr2_tbuf tb_now;
35
0
  git_hash_ctx ctx;
36
0
  pid_t pid = getpid();
37
0
  unsigned char hash[GIT_MAX_RAWSZ + 1];
38
0
  char hex[GIT_MAX_HEXSZ + 1];
39
0
  char hostname[HOST_NAME_MAX + 1];
40
41
0
  tr2_tbuf_utc_datetime(&tb_now);
42
0
  strbuf_addstr(&tr2sid_buf, tb_now.buf);
43
44
0
  strbuf_addch(&tr2sid_buf, '-');
45
0
  if (xgethostname(hostname, sizeof(hostname)))
46
0
    strbuf_add(&tr2sid_buf, "Localhost", 9);
47
0
  else {
48
0
    algo->init_fn(&ctx);
49
0
    algo->update_fn(&ctx, hostname, strlen(hostname));
50
0
    algo->final_fn(hash, &ctx);
51
0
    hash_to_hex_algop_r(hex, hash, algo);
52
0
    strbuf_addch(&tr2sid_buf, 'H');
53
0
    strbuf_add(&tr2sid_buf, hex, 8);
54
0
  }
55
56
0
  strbuf_addf(&tr2sid_buf, "-P%08"PRIx32, (uint32_t)pid);
57
0
}
58
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
0
{
73
0
  const char *parent_sid;
74
75
0
  if (tr2sid_buf.len)
76
0
    return;
77
78
0
  parent_sid = getenv(TR2_ENVVAR_PARENT_SID);
79
0
  if (parent_sid && *parent_sid) {
80
0
    const char *p;
81
0
    for (p = parent_sid; *p; p++)
82
0
      if (*p == '/')
83
0
        tr2sid_nr_git_parents++;
84
85
0
    strbuf_addstr(&tr2sid_buf, parent_sid);
86
0
    strbuf_addch(&tr2sid_buf, '/');
87
0
    tr2sid_nr_git_parents++;
88
0
  }
89
90
0
  tr2_sid_append_my_sid_component();
91
92
0
  setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1);
93
0
}
94
95
const char *tr2_sid_get(void)
96
0
{
97
0
  if (!tr2sid_buf.len)
98
0
    tr2_sid_compute();
99
100
0
  return tr2sid_buf.buf;
101
0
}
102
103
int tr2_sid_depth(void)
104
0
{
105
0
  if (!tr2sid_buf.len)
106
0
    tr2_sid_compute();
107
108
0
  return tr2sid_nr_git_parents;
109
0
}
110
111
void tr2_sid_release(void)
112
0
{
113
0
  strbuf_release(&tr2sid_buf);
114
0
}