diff options
author | Leah Neukirchen <leah@vuxu.org> | 2024-03-04 18:53:58 +0100 |
---|---|---|
committer | Leah Neukirchen <leah@vuxu.org> | 2024-03-04 18:53:58 +0100 |
commit | 6e1c3313884ea208eb193418c2f1a0f5d4078b1c (patch) | |
tree | 34d5da9992ae382cb688128a682261ad58132db4 | |
parent | dd8da679a0c22c4009b842305cabe00ec5c77712 (diff) | |
download | nitro-6e1c3313884ea208eb193418c2f1a0f5d4078b1c.tar.gz nitro-6e1c3313884ea208eb193418c2f1a0f5d4078b1c.tar.xz nitro-6e1c3313884ea208eb193418c2f1a0f5d4078b1c.zip |
remove log/ dirs, use symlinks instead
This also allows sharing loggers.
-rw-r--r-- | README.md | 7 | ||||
-rw-r--r-- | nitro.c | 116 |
2 files changed, 54 insertions, 69 deletions
diff --git a/README.md b/README.md index c721d63..f8e0caa 100644 --- a/README.md +++ b/README.md @@ -46,8 +46,9 @@ can contain several files: process finished. It is passed two arguments, the exit status of the `run` process (or -1 if it was killed by a signal) and the signal that killed it (or 0, if it exited regularly). -- `log`, another service that is brought up. The standard output - of `run` is connected to the standard input by a pipe. +- `log`, a symlink to another service directory. + The standard output of `run` is connected to the standard input of the + service under `log` by a pipe. - `down`, an optional file that causes nitro to not bring up this service by default. - Service directories ending with '@' are ignored; they can be used @@ -58,7 +59,7 @@ You may find runit's `chpst` useful when writing `run` scripts. ## Special services - `LOG`: this service is used as a logging service for all services - that don't have a `log` directory. + that don't have a `log` symlink. - `SYS`: `SYS/setup` is run before other services are brought up. You can already use `nitroctl` in `rc.boot/setup` to bring up services in a certain order. diff --git a/nitro.c b/nitro.c index 0f4dc0c..64a909e 100644 --- a/nitro.c +++ b/nitro.c @@ -830,76 +830,63 @@ add_service(const char *name) int i; for (i = 0; i < max_service; i++) if (strcmp(services[i].name, name) == 0) - break; - - if (i == max_service) { - if (strlen(name) >= sizeof (services[i].name)) { - return -1; - } - - if (max_service >= MAXSV - 1) { - prn(2, "- nitro: too many services, limit=%d\n", MAXSV); - return -1; - } - - max_service++; - - strcpy(services[i].name, name); - services[i].pid = 0; - services[i].logpipe[0] = -1; - services[i].logpipe[1] = -1; - services[i].state = PROC_DELAY; - services[i].startstop = time_now(); - services[i].timeout = 1; - services[i].deadline = 0; - services[i].islog = 0; - } + return i; - services[i].seen = 1; - return i; -} + /* else set up a new service */ -int -add_log_service(char *name, int first) -{ - /* check loggee exists */ - int j = -1; - int i = find_service(name); - if (i < 0) + if (strlen(name) >= sizeof (services[i].name)) { return -1; - - char buf[PATH_MAX]; - sprn(buf, buf + sizeof buf, "%s/log", name); - - struct stat st; - if (stat_slash_to_at(name, "log", &st) < 0 || !S_ISDIR(st.st_mode)) + } else if (max_service >= MAXSV - 1) { + prn(2, "- nitro: too many services, limit=%d\n", MAXSV); return -1; + } - j = add_service(buf); - if (j < 0) - return -1; - services[j].islog = 1; + max_service++; - if (first && stat_slash(buf, "down", &st) == 0) { - services[j].state = PROC_DOWN; - services[j].timeout = 0; - } + strcpy(services[i].name, name); + services[i].pid = 0; + services[i].state = PROC_DELAY; + services[i].startstop = time_now(); + services[i].timeout = 1; + services[i].deadline = 0; + services[i].islog = 0; - if (services[j].logpipe[0] == -1) { - if (pipe(services[j].logpipe) < 0) { - prn(2, "- nitro: can't create log pipe: errno=%d\n", errno); - services[j].logpipe[0] = -1; - services[j].logpipe[1] = -1; - } else { - fcntl(services[j].logpipe[0], F_SETFD, FD_CLOEXEC); - fcntl(services[j].logpipe[1], F_SETFD, FD_CLOEXEC); + char log_target[PATH_MAX]; + char log_link[PATH_MAX]; + sprn(log_link, log_link + sizeof log_link, "%s/log", name); + + ssize_t r = readlink(log_link, log_target, sizeof log_target - 1); + if (r < 0 || (size_t)r >= sizeof log_target - 1) { + if (errno == EINVAL) + prn(2, "warning: ignoring log, it is not a symlink: %s\n", name); + services[i].logpipe[0] = -1; + services[i].logpipe[1] = -1; + } else { + log_target[r] = 0; + char *target_name = strrchr(log_target, '/'); + if (target_name) + target_name++; + else + target_name = log_target; + + int j = add_service(target_name); + services[j].islog = 1; + if (services[j].logpipe[0] == -1) { + if (pipe(services[j].logpipe) < 0) { + prn(2, "- nitro: can't create log pipe: errno=%d\n", errno); + services[j].logpipe[0] = -1; + services[j].logpipe[1] = -1; + } else { + fcntl(services[j].logpipe[0], F_SETFD, FD_CLOEXEC); + fcntl(services[j].logpipe[1], F_SETFD, FD_CLOEXEC); + } } - } - services[i].logpipe[0] = services[j].logpipe[0]; - services[i].logpipe[1] = services[j].logpipe[1]; + services[i].logpipe[0] = services[j].logpipe[0]; + services[i].logpipe[1] = services[j].logpipe[1]; + } - return j; + return i; } void @@ -933,12 +920,12 @@ rescan(int first) if (i < 0) continue; + services[i].seen = 1; + if (first && stat_slash(name, "down", &st) == 0) { services[i].state = PROC_DOWN; services[i].timeout = 0; } - - add_log_service(name, first); } for (i = 0; i < max_service; i++) @@ -1196,11 +1183,8 @@ handle_control_sock() { struct stat st; int i = find_service(buf + 1); - if (stat_slash_to_at(buf + 1, ".", &st) == 0) { + if (stat_slash_to_at(buf + 1, ".", &st) == 0) i = add_service(buf + 1); - if (i >= 0 && !services[i].islog) - add_log_service(buf + 1, 0); - } if (i < 0) goto fail; |