From 7438111c1d6e05df06748a9aa43fe9c4cf065131 Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Thu, 6 Jan 2022 22:23:18 +0100 Subject: extract rescandir --- rvnit.c | 129 +++++++++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 88 insertions(+), 41 deletions(-) diff --git a/rvnit.c b/rvnit.c index 7e03bc6..8f7ac73 100644 --- a/rvnit.c +++ b/rvnit.c @@ -39,6 +39,7 @@ struct entry { time_t start; int status; char state; + char seen; }; struct entry services[MAX_SV]; @@ -53,8 +54,8 @@ int newlogfd[2]; sig_atomic_t want_shutdown; sig_atomic_t want_rescan; - -int want_reboot = 0; +sig_atomic_t want_rescandir; +sig_atomic_t want_reboot; void on_sigint(int sig) @@ -85,6 +86,8 @@ restart(int i) int loggerpipe[2] = { -1, -1 }; + LOG("start %s\n", services[i].name); + if (services[i].logfd[0] == -1) { pipe(services[i].logfd); fcntl(services[i].logfd[0], F_SETFL, O_NONBLOCK); @@ -260,6 +263,12 @@ socket_loop(void* ignored) } } + if (cmd == 'r') { + want_rescandir = 1; + want_rescan = 1; + pthread_kill(main_thread, SIGCONT); + } + if (cmd == 'X') { want_shutdown = 1; pthread_kill(main_thread, SIGCONT); @@ -429,15 +438,6 @@ timedwait(int *wstatus, int secs) return pid; } -int -svcmp(void const *a, void const *b) -{ - const struct entry *sv_a = a; - const struct entry *sv_b = b; - - return strcmp(sv_a->name, sv_b->name); -} - /* -1: no error handler, 0: error handler successful, 1: error handler failed */ int on_error() @@ -470,41 +470,26 @@ found: } int -main() +svcmp(void const *a, void const *b) { - pipe(selflogfd); - fcntl(selflogfd[0], F_SETFL, O_NONBLOCK); - fcntl(selflogfd[1], F_SETFL, O_NONBLOCK); - fcntl(selflogfd[0], F_SETFD, FD_CLOEXEC); - fcntl(selflogfd[1], F_SETFD, FD_CLOEXEC); - - pipe(newlogfd); - fcntl(newlogfd[0], F_SETFL, O_NONBLOCK); - fcntl(newlogfd[1], F_SETFL, O_NONBLOCK); - fcntl(newlogfd[0], F_SETFD, FD_CLOEXEC); - fcntl(newlogfd[1], F_SETFD, FD_CLOEXEC); - - main_thread = pthread_self(); - - /* block all signals in the threads */ - sigset_t allset; - sigfillset(&allset); - sigprocmask(SIG_BLOCK, &allset, 0); - pthread_create(&socket_thread, 0, socket_loop, 0); - pthread_create(&logger_thread, 0, logger_loop, 0); - sigprocmask(SIG_UNBLOCK, &allset, 0); + const struct entry *sv_a = a; + const struct entry *sv_b = b; - if (chdir("sv") < 0) { - perror("chdir"); - return 111; - } + return strcmp(sv_a->name, sv_b->name); +} +void +rescandir() +{ DIR *dir = opendir("."); if (!dir) - return 111; + abort(); int i = 0; + for (int j = 0; j < MAX_SV; j++) + services[j].seen = 0; + struct dirent *ent; while ((ent = readdir(dir))) { if (!isdigit(ent->d_name[0]) || !isdigit(ent->d_name[1])) @@ -513,6 +498,16 @@ main() if (ent->d_name[strlen(ent->d_name) - 1] == '~') continue; + while (services[i].state != UNDEF) + i++; + for (int j = 0; j < MAX_SV; j++) + if (strcmp(services[j].name, ent->d_name) == 0) { + services[j].seen = 1; + goto next; /* already know this one */ + } + + services[i].seen = 1; + services[i].level = 10 * (ent->d_name[0] - '0') + (ent->d_name[1] - '0'); snprintf(services[i].name, sizeof services[i].name, @@ -523,14 +518,54 @@ main() services[i].logfd[1] = -1; services[i].logged = 0; i++; + +next: ; } - closedir(dir); + for (int j = 0; j < MAX_SV; j++) + if (services[j].state != UNDEF && services[j].seen == 0) + services[j].state = DOWN; qsort(services, MAX_SV, sizeof services[0], svcmp); + closedir(dir); +} + +int +main() +{ + pipe(selflogfd); + fcntl(selflogfd[0], F_SETFL, O_NONBLOCK); + fcntl(selflogfd[1], F_SETFL, O_NONBLOCK); + fcntl(selflogfd[0], F_SETFD, FD_CLOEXEC); + fcntl(selflogfd[1], F_SETFD, FD_CLOEXEC); + + pipe(newlogfd); + fcntl(newlogfd[0], F_SETFL, O_NONBLOCK); + fcntl(newlogfd[1], F_SETFL, O_NONBLOCK); + fcntl(newlogfd[0], F_SETFD, FD_CLOEXEC); + fcntl(newlogfd[1], F_SETFD, FD_CLOEXEC); + + main_thread = pthread_self(); + + /* block all signals in the threads */ + sigset_t allset; + sigfillset(&allset); + sigprocmask(SIG_BLOCK, &allset, 0); + pthread_create(&socket_thread, 0, socket_loop, 0); + pthread_create(&logger_thread, 0, logger_loop, 0); + sigprocmask(SIG_UNBLOCK, &allset, 0); + + if (chdir("sv") < 0) { + perror("chdir"); + return 111; + } + + rescandir(); + LOG("booting"); + int i; for (level = 0; level < 100; level++) { /* spawn all of level */ int oneshot = 0; @@ -615,11 +650,23 @@ main() if (want_shutdown) break; + if (want_rescandir) { + rescandir(); + want_rescandir = 0; + } + if (want_rescan) { printf("rescanning state\n"); for (i = 0; i < MAX_SV; i++) { - if (services[i].name[2] == 'D' || - services[i].name[2] == 'L') { + if (services[i].name[2] == 'L') { + if (services[i].state == UP && + services[i].pid == 0) + restart(i); + if (services[i].state == DOWN && + services[i].pid > 0) + kill(services[i].pid, SIGTERM); + } + if (services[i].name[2] == 'D') { if (services[i].state == UP && services[i].pid == 0) restart(i); -- cgit 1.4.1