register.c (2364B) download
1#include "config.h"
2#include "service.h"
3#include "util.h"
4
5#include <errno.h>
6#include <fcntl.h>
7#include <limits.h>
8#include <stdio.h>
9#include <string.h>
10#include <sys/stat.h>
11#include <unistd.h>
12
13
14static int init_supervise(struct service* s) {
15 int fd;
16 struct stat st;
17
18 if (fstatat(s->dir, "supervise", &st, 0) == -1 && mkdirat(s->dir, "supervise", 0755) == -1) {
19 return -1;
20 }
21
22 if (fstatat(s->dir, "supervise/ok", &st, 0) == -1 && mkfifoat(s->dir, "supervise/ok", 0666) == -1) {
23 fprint(1, "cannot create fifo at supervise/ok: %r\n");
24 return -1;
25 }
26
27 if (fstatat(s->dir, "supervise/control", &st, 0) == -1 && mkfifoat(s->dir, "supervise/control", 0644) == -1) {
28 fprint(1, "cannot create fifo at supervise/control: %r\n");
29 return -1;
30 }
31
32 if (openat(s->dir, "supervise/ok", O_RDONLY | O_NONBLOCK) == -1) {
33 fprint(1, "cannot open supervise/ok: %r\n");
34 return -1;
35 }
36
37 if ((s->control = openat(s->dir, "supervise/control", O_RDONLY | O_NONBLOCK)) == -1) {
38 fprint(1, "cannot open supervise/ok: %r\n");
39 return -1;
40 }
41
42 if ((fd = openat(s->dir, "supervise/lock", O_CREAT | O_WRONLY, 0644)) == -1) {
43 fprint(1, "cannot create supervise/lock: %r\n");
44 return -1;
45 }
46 close(fd);
47
48 return 0;
49}
50
51struct service* service_register(int dir, const char* name, bool is_log_service) {
52 struct service* s;
53 struct stat st;
54
55 if ((s = service_get(name)) == NULL) {
56 s = &services[services_size++];
57 s->state = STATE_INACTIVE;
58 s->restart = S_DOWN;
59 s->last_exit = EXIT_NONE;
60 s->return_code = 0;
61 s->fail_count = 0;
62 s->log_service = NULL;
63 s->paused = false;
64 s->log_pipe.read = 0;
65 s->log_pipe.write = 0;
66 s->is_log_service = is_log_service;
67 s->stop_timeout = 0;
68
69 if ((s->dir = openat(dir, name, O_DIRECTORY)) == -1) {
70 print_errno("error: cannot open '%s': %s\n", name);
71 services_size--;
72 return NULL;
73 }
74
75 if (init_supervise(s) == -1) {
76 services_size--;
77 return NULL;
78 }
79
80 strncpy(s->name, name, sizeof(s->name));
81
82 service_update_state(s, -1);
83 }
84
85 if (s->is_log_service) {
86 if (s->log_pipe.read == 0 || s->log_pipe.write == 0)
87 pipe((int*) &s->log_pipe);
88
89 } else if (!s->log_service && fstatat(s->dir, "log", &st, 0) != -1 && S_ISDIR(st.st_mode)) {
90 s->log_service = service_register(s->dir, "log", true);
91 }
92
93 service_write(s);
94
95 return s;
96}