commit 8be66b2a0d7df39d851422638fab95c9aa852aeb
parent 9c7d7b4f0d6f3b742d65f50c65e2112a9ee7deb1
Author: Friedel Schön <[email protected]>
Date: Mon, 5 Jun 2023 14:01:37 +0200
implementing service_update_state instead of service_update_status
Diffstat:
8 files changed, 49 insertions(+), 76 deletions(-)
diff --git a/include/service.h b/include/service.h
@@ -116,5 +116,5 @@ const char* service_status_name(service_t* s);
void service_stop(service_t* s);
int service_supervise(const char* service_dir, const char* runlevel);
void service_update_dependency(service_t* s);
-void service_update_status(service_t* s);
bool service_is_dependency(service_t* s);
+void service_update_state(service_t* s, int state);
diff --git a/src/handle_command.c b/src/handle_command.c
@@ -98,16 +98,11 @@ void service_handle_command(service_t* s, service_command_t command, char data)
s->fail_count = 0;
if (s->state == STATE_DEAD)
- s->state = STATE_INACTIVE;
+ service_update_state(s, STATE_INACTIVE);
- s->status_change = time(NULL);
- service_update_status(s);
break;
case X_EXIT:
// ignored
return;
}
-
- s->status_change = time(NULL);
- service_update_status(s);
}
diff --git a/src/handle_exit.c b/src/handle_exit.c
@@ -14,20 +14,18 @@ static void do_finish(service_t* s) {
struct stat st;
if (fstatat(s->dir, "finish", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_FINISHING;
if ((s->pid = fork_dup_cd_exec(s->dir, "./finish", null_fd, null_fd, null_fd)) == -1) {
print_error("error: cannot execute ./finish: %s\n");
- s->state = STATE_INACTIVE;
+ service_update_state(s, STATE_INACTIVE);
+ } else {
+ service_update_state(s, STATE_FINISHING);
}
} else if (s->fail_count == SV_FAIL_MAX) {
- s->state = STATE_DEAD;
+ service_update_state(s, STATE_DEAD);
printf("%s died\n", s->name);
} else {
- s->state = STATE_INACTIVE;
+ service_update_state(s, STATE_INACTIVE);
}
-
- s->status_change = time(NULL);
- service_update_status(s);
}
@@ -73,16 +71,16 @@ void service_handle_exit(service_t* s, bool signaled, int return_code) {
case STATE_FINISHING:
if (s->fail_count == SV_FAIL_MAX) {
- s->state = STATE_DEAD;
+ service_update_state(s, STATE_DEAD);
printf("%s died\n", s->name);
} else {
- s->state = STATE_INACTIVE;
+ service_update_state(s, STATE_INACTIVE);
}
break;
case STATE_STARTING:
if (!signaled && return_code == 0) {
if (fstatat(s->dir, "stop", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_ACTIVE_BACKGROUND;
+ service_update_state(s, STATE_ACTIVE_BACKGROUND);
} else {
do_finish(s);
}
@@ -103,7 +101,4 @@ void service_handle_exit(service_t* s, bool signaled, int return_code) {
case STATE_INACTIVE:
printf("warn: %s died but was set to inactive\n", s->name);
}
-
- s->status_change = time(NULL);
- service_update_status(s);
}
diff --git a/src/register.c b/src/register.c
@@ -113,8 +113,7 @@ service_t* service_register(int dir, const char* name, bool is_log_service) {
strncpy(s->name, name, sizeof(s->name));
- s->status_change = time(NULL);
- service_update_status(s);
+ service_update_state(s, -1);
}
if (s->is_log_service) {
diff --git a/src/start.c b/src/start.c
@@ -86,14 +86,14 @@ void service_run(service_t* s) {
struct stat st;
if (fstatat(s->dir, "run", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_ACTIVE_FOREGROUND;
+ service_update_state(s, STATE_ACTIVE_FOREGROUND);
} else if (fstatat(s->dir, "start", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_STARTING;
+ service_update_state(s, STATE_STARTING);
} else if (fstatat(s->dir, "depends", &st, 0) != -1 && st.st_mode & S_IREAD) {
- s->state = STATE_ACTIVE_DUMMY;
+ service_update_state(s, STATE_ACTIVE_DUMMY);
} else {
- fprintf(stderr, "warn: %s: `run`, `start` or `depends` not found\n", s->name);
- s->state = STATE_INACTIVE;
+ // fprintf(stderr, "warn: %s: `run`, `start` or `depends` not found\n", s->name);
+ service_update_state(s, STATE_INACTIVE);
}
if (s->state != STATE_ACTIVE_DUMMY) {
@@ -131,8 +131,6 @@ void service_run(service_t* s) {
_exit(1);
}
}
- s->status_change = time(NULL);
- service_update_status(s);
}
void service_start(service_t* s) {
@@ -148,13 +146,12 @@ void service_start(service_t* s) {
}
if (fstatat(s->dir, "setup", &st, 0) != -1 && st.st_mode & S_IXUSR) {
- s->state = STATE_SETUP;
if ((s->pid = fork_dup_cd_exec(s->dir, "./setup", null_fd, null_fd, null_fd)) == -1) {
print_error("error: cannot execute ./setup: %s\n");
- s->state = STATE_INACTIVE;
+ service_update_state(s, STATE_INACTIVE);
+ } else {
+ service_update_state(s, STATE_SETUP);
}
- s->status_change = time(NULL);
- service_update_status(s);
} else {
service_run(s);
}
diff --git a/src/status.c b/src/status.c
@@ -11,7 +11,7 @@
#include <unistd.h>
-void service_update_status(service_t* s) {
+static void service_update_status(service_t* s) {
int fd;
const char* stat_human;
service_serial_t stat_runit;
@@ -56,3 +56,26 @@ void service_update_status(service_t* s) {
renameat(s->dir, "supervise/stat.new", s->dir, "supervise/stat");
renameat(s->dir, "supervise/pid.new", s->dir, "supervise/pid");
}
+
+void service_update_state(service_t* s, int state) {
+ if (state != -1)
+ s->state = state;
+
+ s->status_change = time(NULL);
+ service_update_status(s);
+
+ for (int i = 0; i < services_size; i++) {
+ s = &services[i];
+ if (s->state == STATE_DEAD)
+ continue;
+ if (service_need_restart(s)) {
+ if (s->state == STATE_INACTIVE) {
+ service_start(s);
+ }
+ } else {
+ if (s->state != STATE_INACTIVE) {
+ service_stop(s);
+ }
+ }
+ }
+}
diff --git a/src/stop.c b/src/stop.c
@@ -13,34 +13,23 @@ void service_stop(service_t* s) {
switch (s->state) {
case STATE_ACTIVE_DUMMY:
service_handle_exit(s, false, 0);
-
- s->status_change = time(NULL);
- service_update_status(s);
- break;
- case STATE_ACTIVE_FOREGROUND:
- case STATE_SETUP:
- kill(s->pid, SIGTERM);
-
- s->status_change = time(NULL);
- service_update_status(s);
break;
case STATE_ACTIVE_BACKGROUND:
- s->state = STATE_STOPPING;
if ((s->pid = fork_dup_cd_exec(s->dir, "./stop", null_fd, null_fd, null_fd)) == -1) {
print_error("error: cannot execute ./stop: %s\n");
- s->state = STATE_INACTIVE;
+ service_update_state(s, STATE_INACTIVE);
+ } else {
+ service_update_state(s, STATE_STOPPING);
}
-
- s->status_change = time(NULL);
- service_update_status(s);
break;
+ case STATE_ACTIVE_FOREGROUND:
+ case STATE_SETUP:
case STATE_STARTING:
case STATE_STOPPING:
case STATE_FINISHING:
kill(s->pid, SIGTERM);
- s->status_change = time(NULL);
- service_update_status(s);
+ service_update_state(s, -1);
break;
case STATE_INACTIVE:
case STATE_DEAD:
diff --git a/src/supervise.c b/src/supervise.c
@@ -44,30 +44,6 @@ static void signal_child(int unused) {
service_handle_exit(s, WIFSIGNALED(status), WIFSIGNALED(status) ? WTERMSIG(status) : WEXITSTATUS(status));
}
-static void check_services(void) {
- service_t* s;
-
- for (int i = 0; i < services_size; i++) {
- s = &services[i];
- if (s->state == STATE_DEAD)
- continue;
- if (service_need_restart(s)) {
- if (s->state == STATE_INACTIVE) {
- service_start(s);
- s->status_change = time(NULL);
- service_update_status(s);
- }
- } else {
- if (s->state != STATE_INACTIVE) {
- service_stop(s);
- s->status_change = time(NULL);
- service_update_status(s);
- }
- }
- }
-}
-
-
static void control_sockets(void) {
service_t* s;
char cmd, chr;
@@ -118,7 +94,6 @@ int service_supervise(const char* service_dir_, const char* runlevel_) {
// accept connections and handle requests
while (daemon_running) {
service_refresh_directory();
- check_services();
control_sockets();
sleep(SV_CHECK_INTERVAL);
}