Skip to content

Commit

Permalink
print the process that starts watchman
Browse files Browse the repository at this point in the history
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
  • Loading branch information
Xinyi Wang authored and facebook-github-bot committed Sep 27, 2023
1 parent 5f6d432 commit 77a3297
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions watchman/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<std::string> 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.
Expand Down Expand Up @@ -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
"<no build info set>",
#endif
hostname);
hostname,
startingCommandName.value_or("<unknown_command>"));
}

#ifndef _WIN32
Expand Down Expand Up @@ -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 {
Expand Down Expand Up @@ -296,6 +319,7 @@ static SpawnResult run_service_as_daemon() {
}

auto& processLock = std::get<ProcessLock>(acquireResult);
auto parentPid = getppid();

// the double-fork-and-setsid trick establishes a
// child process that runs in its own process group
Expand All @@ -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

Expand Down

0 comments on commit 77a3297

Please sign in to comment.