|
16 | 16 | #include <fcntl.h>
|
17 | 17 | #include <fts.h>
|
18 | 18 | #include <limits.h>
|
| 19 | +#include <resolv.h> /* for b64_ntop */ |
19 | 20 | #include <stdarg.h>
|
20 | 21 | #include <stdio.h>
|
21 | 22 | #include <stdlib.h>
|
@@ -62,6 +63,7 @@ RB_GENERATE(raw_event_by_pidtime, raw_event,
|
62 | 63 | struct quark {
|
63 | 64 | unsigned int hz;
|
64 | 65 | u64 boottime;
|
| 66 | + char machine_id[1024]; |
65 | 67 | } quark;
|
66 | 68 |
|
67 | 69 | struct raw_event *
|
@@ -444,6 +446,43 @@ process_by_pid_cmp(struct quark_process *a, struct quark_process *b)
|
444 | 446 | return (0);
|
445 | 447 | }
|
446 | 448 |
|
| 449 | +static void |
| 450 | +process_entity_id(struct quark_queue *qq, struct quark_process *qp) |
| 451 | +{ |
| 452 | + sha256_context ctx; |
| 453 | + u64 pid64_le, start_le; |
| 454 | + u8 digest[SHA256_SIZE_BYTES]; |
| 455 | + char digest_p[45]; |
| 456 | + size_t machine_len; |
| 457 | + |
| 458 | + /* No proc_time_boot, bail */ |
| 459 | + if ((qp->flags & QUARK_F_PROC) == 0) |
| 460 | + return; |
| 461 | + /* Already known, bail */ |
| 462 | + if (qp->flags & QUARK_F_ENTITYID) |
| 463 | + return; |
| 464 | + /* No machine_id, bail */ |
| 465 | + if ((machine_len = strlen(quark.machine_id)) == 0) |
| 466 | + return; |
| 467 | + |
| 468 | + /* Historically little endian */ |
| 469 | + pid64_le = htole64(qp->pid); |
| 470 | + start_le = htole64(qp->proc_time_boot); |
| 471 | + |
| 472 | + sha256_init(&ctx); |
| 473 | + sha256_hash(&ctx, quark.machine_id, machine_len); |
| 474 | + sha256_hash(&ctx, &pid64_le, sizeof(pid64_le)); |
| 475 | + sha256_hash(&ctx, &start_le, sizeof(start_le)); |
| 476 | + sha256_done(&ctx, digest); |
| 477 | + |
| 478 | + b64_ntop(digest, sizeof(digest), digest_p, sizeof(digest_p)); |
| 479 | + digest_p[sizeof(digest_p) - 1] = 0; |
| 480 | + |
| 481 | + /* Let it truncate, entity_id is only 12 bytes */ |
| 482 | + (void)strlcpy(qp->entity_id, digest_p, sizeof(qp->entity_id)); |
| 483 | + qp->flags |= QUARK_F_ENTITYID; |
| 484 | +} |
| 485 | + |
447 | 486 | /*
|
448 | 487 | * Socket stuff
|
449 | 488 | */
|
@@ -580,6 +619,8 @@ event_flag_str(u64 flag)
|
580 | 619 | return "CMDLINE";
|
581 | 620 | case QUARK_F_CWD:
|
582 | 621 | return "CWD";
|
| 622 | + case QUARK_F_ENTITYID: |
| 623 | + return "EID"; |
583 | 624 | default:
|
584 | 625 | return "?";
|
585 | 626 | }
|
@@ -1012,6 +1053,10 @@ quark_event_dump(const struct quark_event *qev, FILE *f)
|
1012 | 1053 | entry_leader_type_str(qp->proc_entry_leader_type),
|
1013 | 1054 | qp->proc_entry_leader);
|
1014 | 1055 | }
|
| 1056 | + if (qp->flags & QUARK_F_ENTITYID) { |
| 1057 | + flagname = event_flag_str(QUARK_F_ENTITYID); |
| 1058 | + P(" %.4s\tentity_id=%s\n", flagname, qp->entity_id); |
| 1059 | + } |
1015 | 1060 | if (qp->flags & QUARK_F_CWD) {
|
1016 | 1061 | flagname = event_flag_str(QUARK_F_CWD);
|
1017 | 1062 | P(" %.4s\tcwd=%s\n", flagname, qp->cwd);
|
@@ -1258,6 +1303,9 @@ raw_event_process(struct quark_queue *qq, struct raw_event *src)
|
1258 | 1303 |
|
1259 | 1304 | /* Don't set cwd as it's not valid on exit */
|
1260 | 1305 | comm = raw_task->comm;
|
| 1306 | + |
| 1307 | + /* Depends on QUARK_F_PROC, idempotent */ |
| 1308 | + process_entity_id(qq, qp); |
1261 | 1309 | }
|
1262 | 1310 | if (raw_comm != NULL)
|
1263 | 1311 | comm = raw_comm->comm; /* raw_comm always overrides */
|
@@ -1968,6 +2016,39 @@ fetch_boottime(void)
|
1968 | 2016 | return (btime * NS_PER_S);
|
1969 | 2017 | }
|
1970 | 2018 |
|
| 2019 | +static int |
| 2020 | +fetch_machine_id(char *buf, size_t len) |
| 2021 | +{ |
| 2022 | + int fd; |
| 2023 | + char *id; |
| 2024 | + const char **path, *all_paths[] = { |
| 2025 | + "/etc/machine-id", |
| 2026 | + "/var/lib/dbus/machine-id", |
| 2027 | + "/var/db/dbus/machine-id", |
| 2028 | + NULL |
| 2029 | + }; |
| 2030 | + |
| 2031 | + for (fd = -1, path = all_paths; *path != NULL; path++) { |
| 2032 | + fd = open("/etc/machine-id", O_RDONLY); |
| 2033 | + if (fd != -1) |
| 2034 | + break; |
| 2035 | + } |
| 2036 | + if (fd == -1) |
| 2037 | + return (-1); |
| 2038 | + /* Historically the final newline is included, so keep it. */ |
| 2039 | + if ((id = load_file_nostat(fd, NULL)) == NULL) { |
| 2040 | + close(fd); |
| 2041 | + warnx("can't load machine_id"); |
| 2042 | + return (-1); |
| 2043 | + } |
| 2044 | + close(fd); |
| 2045 | + |
| 2046 | + if (strlcpy(buf, id, len) >= len) |
| 2047 | + warnx("machine_id truncated, ignoring"); |
| 2048 | + |
| 2049 | + return (0); |
| 2050 | +} |
| 2051 | + |
1971 | 2052 | /*
|
1972 | 2053 | * Aggregation is a relationship between a parent event and a child event. In a
|
1973 | 2054 | * fork+exec cenario, fork is the parent, exec is the child.
|
@@ -2028,6 +2109,12 @@ quark_init(void)
|
2028 | 2109 | qwarn("can't fetch btime");
|
2029 | 2110 | return (-1);
|
2030 | 2111 | }
|
| 2112 | + if (fetch_machine_id(quark.machine_id, |
| 2113 | + sizeof(quark.machine_id)) == -1) { |
| 2114 | + qwarn("can't fetch machine id, ignoring"); |
| 2115 | + quark.machine_id[0] = 0; |
| 2116 | + } |
| 2117 | + |
2031 | 2118 | quark.hz = hz;
|
2032 | 2119 | quark.boottime = boottime;
|
2033 | 2120 |
|
|
0 commit comments