fix: shutdown ordering, silent probe failures, and unused import in the mini clients

- hbc_mini.c: move the probe-thread pthread_join to after the shutdown HTB send,
  so the clean-shutdown notification is no longer delayed behind (and possibly
  lost to a SIGKILL racing) a probe thread blocked in popen()/ping.
- hbc_mini.c: log a LOGW when pthread_create() fails to start the probe thread,
  and when probe_v4/probe_v6 are not IP literals (probe_init), so both previously
  silent no-op failure modes are now diagnosable. Diagnostic only — no behavior
  change to the PROBE_UNKNOWN fallback path.
- hbc_mini.py: remove the unused 'import struct' (F401).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Uc9V1v7iXruubpoLiSE24M
This commit is contained in:
2026-09-22 05:16:36 -04:00
co-authored by Claude Sonnet 5
parent 3c6f7fc868
commit 5243f0a834
2 changed files with 19 additions and 3 deletions
+19 -2
View File
@@ -1310,6 +1310,16 @@ static void probe_init(probe_t *p, const config_t *cfg) {
pthread_mutex_init(&p->mu, NULL);
g_have_timeout = system("command -v timeout >/dev/null 2>&1") == 0;
g_probe_enabled = cfg->probe_enabled;
/* Diagnostic only: sys_local_address already turns a non-literal target into PROBE_UNKNOWN
* (via inet_pton failing there), so this does not change behavior — it just stops that from
* being silent. */
struct in_addr a4;
struct in6_addr a6;
if (inet_pton(AF_INET, p->target[0], &a4) != 1)
LOGW("probe_v4 is not an IPv4 literal: %s", p->target[0]);
if (inet_pton(AF_INET6, p->target[1], &a6) != 1)
LOGW("probe_v6 is not an IPv6 literal: %s", p->target[1]);
}
static void *probe_thread(void *arg) {
@@ -1760,7 +1770,11 @@ int main(int argc, char **argv) {
pthread_create(&tid, NULL, monitor_thread, &tctx);
pthread_t ptid; bool probe_running = false;
if (g_probe_enabled && pthread_create(&ptid, NULL, probe_thread, &g_probe) == 0) probe_running = true;
if (g_probe_enabled) {
int prc = pthread_create(&ptid, NULL, probe_thread, &g_probe);
if (prc == 0) probe_running = true;
else LOGW("pthread_create(probe): %s", strerror(prc));
}
/* Main heartbeat + receive loop */
time_t last_hb = 0;
@@ -1799,7 +1813,6 @@ int main(int argc, char **argv) {
pthread_cancel(tid);
pthread_join(tid, NULL);
if (probe_running) pthread_join(ptid, NULL);
if (send_shutdown) {
kvdict_t sh; kv_clear(&sh);
@@ -1808,6 +1821,10 @@ int main(int argc, char **argv) {
conn_send(primary, "HTB", &sh);
usleep(300000);
}
/* Joined after the shutdown HTB goes out: the probe thread is never cancelled (it can be
* inside popen), so joining it can block for a few seconds — long enough to lose the
* clean-shutdown notification to an impatient supervisor's SIGKILL. */
if (probe_running) pthread_join(ptid, NULL);
for (int i = 0; i < g_nconns; i++) conn_close(&g_conns[i]);
if (g_use_syslog) closelog();
if (g_restart) { LOGI("restarting..."); execv(argv[0], argv); }