From 77a3297e507300ed35189d1fe5920e8436ecc502 Mon Sep 17 00:00:00 2001 From: Xinyi Wang Date: Wed, 27 Sep 2023 12:07:06 -0700 Subject: [PATCH] print the process that starts watchman Summary: Print out the parent command of watchman Note watchman can both run in foreground and run as a background daemon, which in the second case it has multiple forks. In this diff, I obtain parent pid before watchman process fork in to client and server and pass it down Reviewed By: chadaustin Differential Revision: D49693503 fbshipit-source-id: 836f916a41cd3fb7ee1e22e33295b4c723200de1 --- watchman/main.cpp | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/watchman/main.cpp b/watchman/main.cpp index 25e12cc20f3f..b3c75d8e0e8a 100644 --- a/watchman/main.cpp +++ b/watchman/main.cpp @@ -29,6 +29,7 @@ #include "watchman/PDU.h" #include "watchman/PerfSample.h" #include "watchman/ProcessLock.h" +#include "watchman/ProcessUtil.h" #include "watchman/ThreadPool.h" #include "watchman/UserDir.h" #include "watchman/WatchmanConfig.h" @@ -107,7 +108,27 @@ void detect_low_process_priority() { #endif } -[[noreturn]] static void run_service(ProcessLock::Handle&&) { +/* + * Detect the command that starts watchman + */ +std::optional detect_starting_command(pid_t ppid) { +#ifndef _WIN32 + try { + auto processInfo = lookupProcessInfo(ppid).get(); + return processInfo.name; + } catch (const std::exception& e) { + logf( + ERR, + "Failed to lookup process info for pid {} exception {} \n", + ppid, + e.what()); + } + +#endif + return std::nullopt; +} + +[[noreturn]] static void run_service(ProcessLock::Handle&&, pid_t ppid) { #ifndef _WIN32 // Before we redirect stdin/stdout to the log files, move any inetd-provided // socket to a different descriptor number. @@ -149,16 +170,18 @@ void detect_low_process_priority() { char hostname[256]; gethostname(hostname, sizeof(hostname)); hostname[sizeof(hostname) - 1] = '\0'; + auto startingCommandName = detect_starting_command(ppid); logf( ERR, - "Watchman {} {} starting up on {}\n", + "Watchman {} {} starting up on {} by command {}\n", PACKAGE_VERSION, #ifdef WATCHMAN_BUILD_INFO WATCHMAN_BUILD_INFO, #else "", #endif - hostname); + hostname, + startingCommandName.value_or("")); } #ifndef _WIN32 @@ -247,7 +270,7 @@ static void close_random_fds() { auto& pid_file = get_pid_file(); auto processLock = ProcessLock::acquire(pid_file); - run_service(processLock.writePid(pid_file)); + run_service(processLock.writePid(pid_file), getppid()); } namespace { @@ -296,6 +319,7 @@ static SpawnResult run_service_as_daemon() { } auto& processLock = std::get(acquireResult); + auto parentPid = getppid(); // the double-fork-and-setsid trick establishes a // child process that runs in its own process group @@ -319,7 +343,7 @@ static SpawnResult run_service_as_daemon() { // We are the child. Let's populate the pid file and start listening on the // socket. - run_service(processLock.writePid(get_pid_file())); + run_service(processLock.writePid(get_pid_file()), parentPid); } #endif