summary refs log tree commit diff
diff options
context:
space:
mode:
authorLeah Neukirchen <leah@vuxu.org>2022-01-06 19:35:30 +0100
committerLeah Neukirchen <leah@vuxu.org>2022-01-06 19:35:30 +0100
commitf4809e60629353a13c3eb699d675f866dd6075cd (patch)
tree3dd0948fc32704d4bedb873d6b14012f39736180
parent4c2f9d65c43160a030e64f97b2c57c211e2af909 (diff)
downloadrvnit-f4809e60629353a13c3eb699d675f866dd6075cd.tar.gz
rvnit-f4809e60629353a13c3eb699d675f866dd6075cd.tar.xz
rvnit-f4809e60629353a13c3eb699d675f866dd6075cd.zip
run previous E service when startup oneshot fails, possibly retry
-rw-r--r--rvnit.c49
1 files changed, 49 insertions, 0 deletions
diff --git a/rvnit.c b/rvnit.c
index 0cd8d3d..4c9505c 100644
--- a/rvnit.c
+++ b/rvnit.c
@@ -419,6 +419,37 @@ svcmp(void const *a, void const *b)
 	return strcmp(sv_a->name, sv_b->name);
 }
 
+/* -1: no error handler, 0: error handler successful, 1: error handler failed */
+int
+on_error()
+{
+	int e = -1;
+
+	for (int l = level; l >= 0; l--) {
+		for (int i = 0; i < MAX_SV; i++) {
+			if (services[i].level != l)
+				continue;
+			if (services[i].name[2] == 'E') {
+				e = i;
+				goto found;
+			}
+		}
+	}
+
+	// no error handler, keep going
+	return -1;
+
+found:
+	restart(e);
+	int status = 0;
+	pid_t pid = waitpid(services[e].pid, &status, 0);
+	reap(pid, status);
+
+	if (WEXITSTATUS(status) == 111)
+		return -1;  // keep going
+	return status != 0;
+}
+
 int
 main()
 {
@@ -518,6 +549,22 @@ main()
 				continue;
 
 			if (services[i].name[2] == 'S') {
+
+				if (services[i].status != 0) {
+					LOG("oneshot %s failed, running error services for level=%d", services[i].name, level);
+
+					int r = on_error();
+					if (r == 0) {
+						restart(i);
+						continue;
+					} if (r < 0) {
+						LOG("no error handler, going on");
+					} if (r > 0) {
+						LOG("fatal error, shutting down at level=%d", level);
+						goto fatal;
+					}
+				}
+
 				oneshot--;
 			} else if (services[i].name[2] == 'D' ||
 			    services[i].name[2] == 'L') {
@@ -581,6 +628,8 @@ main()
 	LOG("shutting down");
 
 	for (level = 99; level >= 0; level--) {
+fatal:		; // arrives with level < 99
+
 		/* kill all of level */
 		int oneshot = 0;
 		int daemons = 0;