supervise.c (3093B)
1 #include "common.h" 2 #include "defs.h" 3 #include "types.h" 4 #include "util.h" 5 6 #include <errno.h> 7 #include <fcntl.h> 8 #include <linux/limits.h> 9 #include <signal.h> 10 #include <stdio.h> 11 #include <stdlib.h> 12 #include <string.h> 13 #include <sys/file.h> 14 #include <sys/stat.h> 15 #include <unistd.h> 16 17 18 #define RUN_PATH "/run/fiss" 19 20 service_t service; 21 22 const char* current_prog(void) { 23 return "supervise"; 24 } 25 26 int main(int argc, char** argv) { 27 static char path_buffer[PATH_MAX]; 28 static char supervise_path[PATH_MAX]; 29 struct stat sstruct; 30 31 if (argc >= 2 && chdir(argv[1]) == -1) { 32 fprint(1, "unable to change directory to '%s': %s\n", argv[1], strerror(errno)); 33 exit(errno == ENOENT ? EXIT_USER : EXIT_PERM); 34 } 35 36 // reset service struct 37 memset(&service, 0, sizeof service); 38 39 THROW_NULL(getcwd(supervise_path, sizeof supervise_path), "unable to get current directory", EXIT_PERM); 40 41 // copy the last component of {PWD} to name 42 strcpy(service.name, strrchr(supervise_path, '/') + 1); 43 44 path_join(path_buffer, RUN_PATH, "supervise", NULL); 45 46 if (stat(RUN_PATH, &sstruct) == -1) { 47 THROW_MIN(mkdir(RUN_PATH, 0666), "unable to create %s", EXIT_TEMP, RUN_PATH); 48 } else if (!S_ISDIR(sstruct.st_mode)) { 49 fprint(1, "%s exists, but is not a directory", RUN_PATH); 50 exit(EXIT_TEMP); 51 } 52 53 if (stat(path_buffer, &sstruct) == -1) { 54 THROW_MIN(mkdir(path_buffer, 0666), "unable to create %s", EXIT_TEMP, path_buffer); 55 } else if (!S_ISDIR(sstruct.st_mode)) { 56 fprint(1, "%s exists, but is not a directory", RUN_PATH); 57 exit(EXIT_TEMP); 58 } 59 60 // symlink /run/fiss/supervise/<service> to ./supervise 61 THROW_MIN(symlink(path_buffer, "supervise"), "unable to link '%s' to 'supervise'", EXIT_TEMP, path_buffer); 62 63 // open ./supervise/lock 64 THROW_MIN(service.supervise.lock = open("supervise/lock", O_WRONLY | O_CREAT, 0600), "unable to open 'supervise/lock'", EXIT_PERM); 65 66 // lock ./supervise/lock, don't block! That means it will just throw if another instance is running 67 THROW_MIN(flock(service.supervise.lock, LOCK_EX | LOCK_NB), "unable to lock 'supervise/lock', probably an other 'supervise'-instance is running", EXIT_PERM); 68 69 // make fifo at ./supervise/ok, everyone should be able to check at least that 70 // the service is online, thus perm 666 instead of 600 71 THROW_MIN(mkfifo("supervise/ok", 0666), "unable to create 'supervise/control'", EXIT_TEMP); 72 73 // make fifo at ./supervise/control, only root should be able to control the service thus 0600 74 THROW_MIN(mkfifo("supervise/control", 0600), "unable to create 'supervise/control'", EXIT_TEMP); 75 76 // open ./supervise/ok and just leave it like that 77 THROW_MIN(service.supervise.ok = open("supervise/ok", O_RDONLY), "unable to open 'supervise/ok'", EXIT_PERM); 78 79 // open ./supervise/control 80 THROW_MIN(service.supervise.control = open("supervise/control", O_RDONLY), "unable to open 'supervise/control'", EXIT_PERM); 81 82 // open ./supervise/depends 83 THROW_MIN(service.supervise.dependent = open("supervise/depends", O_RDONLY | O_CREAT, 0666), "unable to open 'supervise/depends'", EXIT_PERM); 84 85 THROW_MIN(write_status(), "unable to write status", -1); 86 }