Skip to content

Commit

Permalink
Merge pull request #1116 from pi-hole/development
Browse files Browse the repository at this point in the history
Pi-hole FTL v5.8.1
  • Loading branch information
PromoFaux committed Apr 21, 2021
2 parents bdaff4b + d429598 commit b90ab8b
Show file tree
Hide file tree
Showing 13 changed files with 203 additions and 47 deletions.
39 changes: 27 additions & 12 deletions src/api/socket.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,8 +313,8 @@ static void *telnet_connection_handler_thread(void *socket_desc)

// Set thread name
char threadname[16];
sprintf(threadname,"telnet-%i",sock);
prctl(PR_SET_NAME,threadname,0,0,0);
sprintf(threadname, "telnet-%i", sock);
prctl(PR_SET_NAME, threadname, 0, 0, 0);
//Receive from client
ssize_t n;
while((n = recv(sock,client_message,SOCKETBUFFERLEN-1, 0)))
Expand Down Expand Up @@ -364,8 +364,8 @@ static void *socket_connection_handler_thread(void *socket_desc)

// Set thread name
char threadname[16];
sprintf(threadname,"socket-%i",sock);
prctl(PR_SET_NAME,threadname,0,0,0);
sprintf(threadname, "socket-%i", sock);
prctl(PR_SET_NAME, threadname, 0, 0, 0);

// Receive from client
ssize_t n;
Expand Down Expand Up @@ -414,15 +414,18 @@ void *telnet_listening_thread_IPv4(void *args)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

// Set thread name
prctl(PR_SET_NAME,"telnet-IPv4",0,0,0);
thread_names[TELNETv4] = "telnet-IPv4";
prctl(PR_SET_NAME, thread_names[TELNETv4], 0, 0, 0);

// Initialize IPv4 telnet socket
ipv4telnet = bind_to_telnet_port_IPv4(&telnetfd4);
if(!ipv4telnet)
return NULL;

thread_cancellable[TELNETv4] = true;

// Listen as long as this thread is not canceled
while(true)
while(!killed)
{
// Look for new clients that want to connect
const int csck = listener(telnetfd4, 4);
Expand All @@ -446,7 +449,9 @@ void *telnet_listening_thread_IPv4(void *args)
logg("WARNING: Unable to open telnet processing thread: %s", strerror(errno));
}
}
return false;

logg("Terminating IPv4 telnet thread");
return NULL;
}

void *telnet_listening_thread_IPv6(void *args)
Expand All @@ -460,7 +465,8 @@ void *telnet_listening_thread_IPv6(void *args)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

// Set thread name
prctl(PR_SET_NAME,"telnet-IPv6",0,0,0);
thread_names[TELNETv6] = "telnet-IPv6";
prctl(PR_SET_NAME, thread_names[TELNETv6], 0, 0, 0);

// Initialize IPv6 telnet socket but only if IPv6 interfaces are available
if(!ipv6_available())
Expand All @@ -470,8 +476,10 @@ void *telnet_listening_thread_IPv6(void *args)
if(!ipv6telnet)
return NULL;

thread_cancellable[TELNETv6] = true;

// Listen as long as this thread is not canceled
while(true)
while(!killed)
{
// Look for new clients that want to connect
const int csck = listener(telnetfd6, 6);
Expand All @@ -495,7 +503,9 @@ void *telnet_listening_thread_IPv6(void *args)
logg("WARNING: Unable to open telnet processing thread: %s", strerror(errno));
}
}
return false;

logg("Terminating IPv6 telnet thread");
return NULL;
}

void *socket_listening_thread(void *args)
Expand All @@ -509,7 +519,8 @@ void *socket_listening_thread(void *args)
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

// Set thread name
prctl(PR_SET_NAME,"socket listener",0,0,0);
thread_names[SOCKET] = "telnet-socket";
prctl(PR_SET_NAME, thread_names[SOCKET], 0, 0, 0);

// Return early to avoid CPU spinning if Unix socket is not available
sock_avail = bind_to_unix_socket(&socketfd);
Expand All @@ -519,8 +530,10 @@ void *socket_listening_thread(void *args)
return NULL;
}

thread_cancellable[SOCKET] = true;

// Listen as long as this thread is not canceled
while(true)
while(!killed)
{
// Look for new clients that want to connect
const int csck = listener(socketfd, 0);
Expand All @@ -541,6 +554,8 @@ void *socket_listening_thread(void *args)
logg("WARNING: Unable to open socket processing thread: %s", strerror(errno));
}
}

logg("Terminating socket thread");
return NULL;
}

Expand Down
49 changes: 32 additions & 17 deletions src/daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "database/common.h"
// destroy_shmem()
#include "shmem.h"
// killed
#include "signals.h"

pthread_t threads[THREADS_MAX] = { 0 };
bool resolver_ready = false;
Expand Down Expand Up @@ -168,24 +170,27 @@ pid_t FTL_gettid(void)
#endif // SYS_gettid
}

// Clean up on exit
void cleanup(const int ret)
static void terminate_threads(void)
{
int s;
struct timespec ts;
// Terminate threads before closing database connections and finishing shared memory
logg("Asking threads to cancel");
for(int i = 0; i < THREADS_MAX; i++)
{
pthread_cancel(threads[i]);
}
// Try to join threads to ensure cancelation has succeeded
killed = true;
// Try to join threads to ensure cancellation has succeeded
logg("Waiting for threads to join");
for(int i = 0; i < THREADS_MAX; i++)
{
if(thread_cancellable[i])
{
logg("Thread %s (%d) is idle, terminating it.",
thread_names[i], i);
pthread_cancel(threads[i]);
}

if (clock_gettime(CLOCK_REALTIME, &ts) == -1)
{
logg("Cannot get clock time, canceling thread instead of joining");
logg("Thread %s (%d) is busy, cancelling it (cannot set timout).",
thread_names[i], i);
pthread_cancel(threads[i]);
continue;
}
Expand All @@ -195,25 +200,35 @@ void cleanup(const int ret)

if((s = pthread_timedjoin_np(threads[i], NULL, &ts)) != 0)
{
logg("Thread %d (%ld) timed out (%s), canceling it.",
i, (long)threads[i], strerror(s));
logg("Thread %s (%d) is still busy, cancelling it.",
thread_names[i], i);
pthread_cancel(threads[i]);
continue;
}
}
logg("All threads joined");
}

// Clean up on exit
void cleanup(const int ret)
{
// Do proper cleanup only if FTL started successfully
if(resolver_ready)
{
terminate_threads();

// Close database connection
gravityDB_close();
// Close database connection
gravityDB_close();

// Close sockets and delete Unix socket file handle
close_telnet_socket();
close_unix_socket(true);
// Close sockets and delete Unix socket file handle
close_telnet_socket();
close_unix_socket(true);
}

// Empty API port file, port 0 = truncate file
saveport(0);

//Remove PID file
// Remove PID file
removepid();

// Remove shared memory objects
Expand Down
7 changes: 4 additions & 3 deletions src/database/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include "sqlite3-ext.h"
// import_aliasclients()
#include "aliasclients.h"
// add_additional_info_column()
#include "query-table.h"

bool DBdeleteoldqueries = false;
long int lastdbindex = 0;
Expand Down Expand Up @@ -300,10 +302,9 @@ void db_init(void)
// Update to version 7 if lower
if(dbversion < 7)
{
// Update to version 7: Create message table
// Update to version 7: Add additional_info column to queries table
logg("Updating long-term database to version 7");
if(dbquery(db, "ALTER TABLE queries ADD COLUMN additional_info TEXT;") != SQLITE_OK ||
!dbquery(db, "INSERT OR REPLACE INTO ftl (id, value) VALUES ( %u, %i );", DB_VERSION, 7) != SQLITE_OK)
if(!add_additional_info_column(db))
{
logg("Column additional_info not initialized, database not available");
dbclose(&db);
Expand Down
56 changes: 50 additions & 6 deletions src/database/database-thread.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,21 @@
void *DB_thread(void *val)
{
// Set thread name
prctl(PR_SET_NAME,"database",0,0,0);
thread_names[DB] = "database";
prctl(PR_SET_NAME, thread_names[DB], 0, 0, 0);

// Save timestamp as we do not want to store immediately
// to the database
time_t lastDBsave = time(NULL) - time(NULL)%config.DBinterval;

// Run as long as this thread is not canceled
while(true)
// Run until shutdown of the process
while(!killed)
{
sqlite3 *db = dbopen(false);
if(db == NULL)
{
// Sleep 5 seconds and try again
sleepms(5000);
thread_sleepms(DB, 5000);
continue;
}
time_t now = time(NULL);
Expand All @@ -59,6 +60,13 @@ void *DB_thread(void *val)
DB_save_queries(db);
unlock_shm();

// Intermediate cancellation-point
if(killed)
{
dbclose(&db);
break;
}

// Check if GC should be done on the database
if(DBdeleteoldqueries && config.maxDBdays != -1)
{
Expand All @@ -73,22 +81,57 @@ void *DB_thread(void *val)
set_event(PARSE_NEIGHBOR_CACHE);
}

// Intermediate cancellation-point
if(killed)
{
dbclose(&db);
break;
}

// Update MAC vendor strings once a month (the MAC vendor
// database is not updated very often)
if(now % 2592000L == 0)
updateMACVendorRecords(db);

// Intermediate cancellation-point
if(killed)
{
dbclose(&db);
break;
}

if(get_and_clear_event(PARSE_NEIGHBOR_CACHE))
parse_neighbor_cache(db);

// Intermediate cancellation-point
if(killed)
{
dbclose(&db);
break;
}

// Process database related event queue elements
if(get_and_clear_event(RELOAD_GRAVITY))
FTL_reload_all_domainlists();

// Intermediate cancellation-point
if(killed)
{
dbclose(&db);
break;
}

// Reload privacy level from pihole-FTL.conf
if(get_and_clear_event(RELOAD_PRIVACY_LEVEL))
get_privacy_level(NULL);

// Intermediate cancellation-point
if(killed)
{
dbclose(&db);
break;
}

// Import alias-clients
if(get_and_clear_event(REIMPORT_ALIASCLIENTS))
{
Expand All @@ -100,9 +143,10 @@ void *DB_thread(void *val)
// Close database connection
dbclose(&db);

// Sleep 1 second
sleepms(1000);
// Sleep 1 sec
thread_sleepms(DB, 1000);
}

logg("Terminating database thread");
return NULL;
}

0 comments on commit b90ab8b

Please sign in to comment.