Merge pull request #2416 from pi-hole/tweak/search_proc

Check for existing NTP client when starting FTL
This commit is contained in:
Dominik
2025-04-20 19:12:40 +02:00
committed by GitHub
3 changed files with 66 additions and 0 deletions

View File

@@ -41,6 +41,8 @@
#include "database/message-table.h" #include "database/message-table.h"
// check_capability() // check_capability()
#include "capabilities.h" #include "capabilities.h"
// search_proc()
#include "procps.h"
// Required accuracy of the NTP sync in seconds in order to start the NTP server // Required accuracy of the NTP sync in seconds in order to start the NTP server
// thread. If the NTP sync is less accurate than this value, the NTP server // thread. If the NTP sync is less accurate than this value, the NTP server
@@ -746,6 +748,13 @@ bool ntp_start_sync_thread(pthread_attr_t *attr)
ntp_server_start(); ntp_server_start();
return false; return false;
} }
// Return early if a clock disciplining NTP client is detected
// Checks chrony, the ntp family (ntp, ntpsec and openntpd), and ntpd-rs
if(search_proc("chronyd") > 0 || search_proc("ntpd") > 0 || search_proc("ntp-daemon") > 0)
{
log_info("Clock disciplining NTP client detected, not starting embedded NTP client/server");
return false;
}
// Check if we have the ambient capabilities to set the system time. // Check if we have the ambient capabilities to set the system time.
// Without CAP_SYS_TIME, we cannot set the system time and the NTP // Without CAP_SYS_TIME, we cannot set the system time and the NTP

View File

@@ -359,3 +359,59 @@ bool parse_proc_stat(unsigned long *total_sum, unsigned long *idle_sum)
return true; return true;
} }
/**
* @brief Searches for a process by its name in the /proc filesystem.
*
* This function iterates through the directories in /proc, which represent
* process IDs (PIDs), and checks the "comm" file in each directory to find
* a process with a matching name.
*
* @param name The name of the process to search for.
*
* @return The PID of the process if found, or -1 if no matching process is found
* or if an error occurs (e.g., unable to open /proc or a file).
*
* @note This function assumes the /proc filesystem is available and accessible.
* It also assumes that the "comm" file in each process directory contains
* the name of the process.
*/
pid_t search_proc(const char *name)
{
DIR *dir = opendir("/proc");
if(dir == NULL)
return -1;
struct dirent *entry;
while((entry = readdir(dir)) != NULL)
{
// Check if the entry is a directory and contains only digits
// We skip ".", "..", "self", and friends
if(entry->d_type == DT_DIR && isdigit(entry->d_name[0]))
{
char filename[64];
snprintf(filename, sizeof(filename), "/proc/%s/comm", entry->d_name);
FILE *file = fopen(filename, "r");
if(file != NULL)
{
char comm[PROC_PATH_SIZ + 1] = { 0 };
// Read the command name from the file
if(fscanf(file, "%"xstr(PROC_PATH_SIZ)"s", comm) == 1)
{
if(strcmp(comm, name) == 0)
{
// Found a matching process
fclose(file);
closedir(dir);
return atoi(entry->d_name);
}
}
fclose(file);
}
}
}
// No process found with the given name
closedir(dir);
return -1;
}

View File

@@ -49,5 +49,6 @@ struct proc_meminfo {
bool getProcessMemory(struct proc_mem *mem, const unsigned long total_memory); bool getProcessMemory(struct proc_mem *mem, const unsigned long total_memory);
bool parse_proc_meminfo(struct proc_meminfo *mem); bool parse_proc_meminfo(struct proc_meminfo *mem);
bool parse_proc_stat(unsigned long *total_sum, unsigned long *idle_sum); bool parse_proc_stat(unsigned long *total_sum, unsigned long *idle_sum);
pid_t search_proc(const char *name);
#endif // PROCPS_H #endif // PROCPS_H