From 06769a66a616d4d984eb91614bb3e88d289de79c Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Sat, 12 Feb 2022 23:44:54 +0100 Subject: rvnitctl: hack some start/stop commands ala sv This is quite ugly still but shows a polling approach works. Services need to be up/down for 250ms for the start/stop to succeed. --- rvnitctl.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 91 insertions(+), 1 deletion(-) diff --git a/rvnitctl.c b/rvnitctl.c index 9920f30..5fca706 100644 --- a/rvnitctl.c +++ b/rvnitctl.c @@ -1,11 +1,58 @@ #include #include +#include #include #include #include +#include #include +int +check(const char *path, const char *service) +{ + struct sockaddr_un addr = { 0 }; + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, path, sizeof addr.sun_path - 1); + int connfd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); + if (connfd < 0) { + perror("socket"); + exit(111); + } + + if (connect(connfd, (struct sockaddr *)&addr, sizeof addr) < 0) { + perror("connect"); + exit(111); + } + + write(connfd, "s", 1); + + // XXX what if too low? + char buf[4096]; + ssize_t rd = read(connfd, buf, sizeof buf); + if (rd < 0) { + perror("read"); + exit(111); + } + + char *p; + char *f = strstr(buf, service); + if (f && (f == buf || f[-1] == '\n') && + f[strlen(service)+1] == ' ' && + (p = strstr(f, "pid="))) { + p += 4; + printf("found pid %c\n", p[0]); + if (isdigit(p[0])) { + close(connfd); + return 1; // has pid >= 0 + } + } + // XXX fix multiple strstr matches + + close(connfd); + return 0; +} + int main(int argc, char *argv[]) { @@ -24,6 +71,8 @@ main(int argc, char *argv[]) strcmp(argv[1], "k") != 0 && strcmp(argv[1], "kill") != 0 && strcmp(argv[1], "1") != 0 && strcmp(argv[1], "2") != 0 && + strcmp(argv[1], "start") != 0 && + strcmp(argv[1], "stop") != 0 && strcmp(argv[1], "Restart") != 0 && strcmp(argv[1], "Shutdown") != 0)) { dprintf(2, "usage: rvnitctl COMMAND [SERVICE]\n"); @@ -49,7 +98,14 @@ main(int argc, char *argv[]) exit(111); } - dprintf(connfd, "%c%s", *argv[1], argv[2] ? argv[2] : ""); + char cmd = argv[1][0]; + + if (strcmp(argv[1], "start") == 0 && argv[2]) + cmd = 'u'; + else if (strcmp(argv[1], "stop") == 0 && argv[2]) + cmd = 'd'; + + dprintf(connfd, "%c%s", cmd, argv[2] ? argv[2] : ""); int status = 1; @@ -66,5 +122,39 @@ main(int argc, char *argv[]) write(1, buf, rd); } while (rd > 0); + if (strcmp(argv[1], "start") == 0 && argv[2]) { + int i; + int up = 0; + for (i = 7*4; i > 0; i--) { + if (check(path, argv[2])) { + if (++up >= 2) + break; + } else { + up = 0; + } + nanosleep(&(struct timespec){0, 250000000}, 0); + } + if (up < 2) { + fprintf(stderr, "start failed\n"); + return 1; + } + } else if (strcmp(argv[1], "stop") == 0 && argv[2]) { + int i; + int down = 0; + for (i = 7*4; i > 0; i--) { + if (!check(path, argv[2])) { + if (++down >= 2) + break; + } else { + down = 0; + } + nanosleep(&(struct timespec){0, 250000000}, 0); + } + if (down < 2) { + fprintf(stderr, "stop failed\n"); + return 1; + } + } + return status; } -- cgit 1.4.1