Git fork
at reftables-rust 114 lines 3.0 kB view raw
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#define TR2_ENVVAR_PARENT_SID "GIT_TRACE2_PARENT_SID" 8 9static struct strbuf tr2sid_buf = STRBUF_INIT; 10static 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 */ 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 struct 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 git_hash_update(&ctx, hostname, strlen(hostname)); 50 git_hash_final(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/* 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 */ 71static void tr2_sid_compute(void) 72{ 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 90 tr2_sid_append_my_sid_component(); 91 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}