]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/monitor.c
Report container exit status to monitord
[mirror_lxc.git] / src / lxc / monitor.c
1 /*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 * Dwight Engen <dwight.engen@oracle.com>
9 *
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
14 *
15 * This library is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
19 *
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 */
24
25 #include <stdio.h>
26 #include <errno.h>
27 #include <unistd.h>
28 #include <string.h>
29 #include <stdlib.h>
30 #include <stddef.h>
31 #include <fcntl.h>
32 #include <inttypes.h>
33 #include <stdint.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/param.h>
37 #include <sys/socket.h>
38 #include <sys/wait.h>
39 #include <netinet/in.h>
40 #include <net/if.h>
41
42 #include "error.h"
43 #include "af_unix.h"
44 #include "log.h"
45 #include "lxclock.h"
46 #include "state.h"
47 #include "monitor.h"
48 #include "utils.h"
49
50 lxc_log_define(lxc_monitor, lxc);
51
52 /* routines used by monitor publishers (containers) */
53 int lxc_monitor_fifo_name(const char *lxcpath, char *fifo_path, size_t fifo_path_sz,
54 int do_mkdirp)
55 {
56 int ret;
57 char *rundir;
58
59 rundir = get_rundir();
60 if (!rundir)
61 return -1;
62
63 if (do_mkdirp) {
64 ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath);
65 if (ret < 0 || ret >= fifo_path_sz) {
66 ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
67 free(rundir);
68 return -1;
69 }
70 ret = mkdir_p(fifo_path, 0755);
71 if (ret < 0) {
72 ERROR("unable to create monitor fifo dir %s", fifo_path);
73 free(rundir);
74 return ret;
75 }
76 }
77 ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
78 if (ret < 0 || ret >= fifo_path_sz) {
79 ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
80 free(rundir);
81 return -1;
82 }
83 free(rundir);
84 return 0;
85 }
86
87 static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
88 {
89 int fd,ret;
90 char fifo_path[PATH_MAX];
91
92 BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */
93
94 ret = lxc_monitor_fifo_name(lxcpath, fifo_path, sizeof(fifo_path), 0);
95 if (ret < 0)
96 return;
97
98 /* open the fifo nonblock in case the monitor is dead, we don't want
99 * the open to wait for a reader since it may never come.
100 */
101 fd = open(fifo_path, O_WRONLY|O_NONBLOCK);
102 if (fd < 0) {
103 /* it is normal for this open to fail ENXIO when there is no
104 * monitor running, so we don't log it
105 */
106 return;
107 }
108
109 if (fcntl(fd, F_SETFL, O_WRONLY) < 0) {
110 close(fd);
111 return;
112 }
113
114 ret = write(fd, msg, sizeof(*msg));
115 if (ret != sizeof(*msg)) {
116 close(fd);
117 SYSERROR("failed to write monitor fifo %s", fifo_path);
118 return;
119 }
120
121 close(fd);
122 }
123
124 void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
125 {
126 struct lxc_msg msg = { .type = lxc_msg_state,
127 .value = state };
128 strncpy(msg.name, name, sizeof(msg.name));
129 msg.name[sizeof(msg.name) - 1] = 0;
130
131 lxc_monitor_fifo_send(&msg, lxcpath);
132 }
133
134 void lxc_monitor_send_exit_code(const char *name, int exit_code, const char *lxcpath)
135 {
136 struct lxc_msg msg = { .type = lxc_msg_exit_code,
137 .value = exit_code };
138 strncpy(msg.name, name, sizeof(msg.name));
139 msg.name[sizeof(msg.name) - 1] = 0;
140
141 lxc_monitor_fifo_send(&msg, lxcpath);
142 }
143
144
145 /* routines used by monitor subscribers (lxc-monitor) */
146 int lxc_monitor_close(int fd)
147 {
148 return close(fd);
149 }
150
151 int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
152 size_t len;
153 int ret;
154 char *sockname = &addr->sun_path[1];
155 char *path;
156 uint64_t hash;
157
158 /* addr.sun_path is only 108 bytes, so we hash the full name and
159 * then append as much of the name as we can fit.
160 */
161 memset(addr, 0, sizeof(*addr));
162 addr->sun_family = AF_UNIX;
163 len = strlen(lxcpath) + 18;
164 path = alloca(len);
165 ret = snprintf(path, len, "lxc/%s/monitor-sock", lxcpath);
166 if (ret < 0 || ret >= len) {
167 ERROR("memory error creating monitor path");
168 return -1;
169 }
170
171 len = sizeof(addr->sun_path) - 1;
172 hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
173 ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath);
174 if (ret < 0)
175 return -1;
176 sockname[sizeof(addr->sun_path)-3] = '\0';
177 INFO("using monitor sock name %s", sockname);
178 return 0;
179 }
180
181 int lxc_monitor_open(const char *lxcpath)
182 {
183 struct sockaddr_un addr;
184 int fd,ret;
185 int retry,backoff_ms[] = {10, 50, 100};
186 size_t len;
187
188 if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
189 return -1;
190
191 fd = socket(PF_UNIX, SOCK_STREAM, 0);
192 if (fd < 0) {
193 ERROR("socket : %s", strerror(errno));
194 return -1;
195 }
196
197 len = strlen(&addr.sun_path[1]) + 1;
198 if (len >= sizeof(addr.sun_path) - 1) {
199 ret = -1;
200 errno = ENAMETOOLONG;
201 goto err1;
202 }
203
204 for (retry = 0; retry < sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) {
205 ret = connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len);
206 if (ret == 0 || errno != ECONNREFUSED)
207 break;
208 ERROR("connect : backing off %d", backoff_ms[retry]);
209 usleep(backoff_ms[retry] * 1000);
210 }
211
212 if (ret < 0) {
213 ERROR("connect : %s", strerror(errno));
214 goto err1;
215 }
216 return fd;
217 err1:
218 close(fd);
219 return ret;
220 }
221
222 int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg,
223 int timeout)
224 {
225 struct timeval tval,*tv = NULL;
226 int ret,i;
227
228 if (timeout != -1) {
229 tv = &tval;
230 tv->tv_sec = timeout;
231 tv->tv_usec = 0;
232 }
233
234 ret = select(nfds, rfds, NULL, NULL, tv);
235 if (ret == -1)
236 return -1;
237 else if (ret == 0)
238 return -2; // timed out
239
240 /* only read from the first ready fd, the others will remain ready
241 * for when this routine is called again
242 */
243 for (i = 0; i < nfds; i++) {
244 if (FD_ISSET(i, rfds)) {
245 ret = recv(i, msg, sizeof(*msg), 0);
246 if (ret <= 0) {
247 SYSERROR("client failed to recv (monitord died?) %s",
248 strerror(errno));
249 return -1;
250 }
251 return ret;
252 }
253 }
254 SYSERROR("no ready fd found?");
255 return -1;
256 }
257
258 int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout)
259 {
260 fd_set rfds;
261
262 FD_ZERO(&rfds);
263 FD_SET(fd, &rfds);
264
265 return lxc_monitor_read_fdset(&rfds, fd+1, msg, timeout);
266 }
267
268 int lxc_monitor_read(int fd, struct lxc_msg *msg)
269 {
270 return lxc_monitor_read_timeout(fd, msg, -1);
271 }
272
273
274 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
275
276 /* used to spawn a monitord either on startup of a daemon container, or when
277 * lxc-monitor starts
278 */
279 int lxc_monitord_spawn(const char *lxcpath)
280 {
281 pid_t pid1,pid2;
282 int pipefd[2];
283 char pipefd_str[11];
284
285 char * const args[] = {
286 LXC_MONITORD_PATH,
287 (char *)lxcpath,
288 pipefd_str,
289 NULL,
290 };
291
292 /* double fork to avoid zombies when monitord exits */
293 pid1 = fork();
294 if (pid1 < 0) {
295 SYSERROR("failed to fork");
296 return -1;
297 }
298
299 if (pid1) {
300 if (waitpid(pid1, NULL, 0) != pid1)
301 return -1;
302 return 0;
303 }
304
305 if (pipe(pipefd) < 0) {
306 SYSERROR("failed to create pipe");
307 exit(EXIT_FAILURE);
308 }
309
310 pid2 = fork();
311 if (pid2 < 0) {
312 SYSERROR("failed to fork");
313 exit(EXIT_FAILURE);
314 }
315 if (pid2) {
316 char c;
317 /* wait for daemon to create socket */
318 close(pipefd[1]);
319 /* sync with child, we're ignoring the return from read
320 * because regardless if it works or not, either way we've
321 * synced with the child process. the if-empty-statement
322 * construct is to quiet the warn-unused-result warning.
323 */
324 if (read(pipefd[0], &c, 1))
325 ;
326 close(pipefd[0]);
327 exit(EXIT_SUCCESS);
328 }
329
330 if (setsid() < 0) {
331 SYSERROR("failed to setsid");
332 exit(EXIT_FAILURE);
333 }
334 lxc_check_inherited(NULL, pipefd[1]);
335 close(0);
336 close(1);
337 close(2);
338 open("/dev/null", O_RDONLY);
339 open("/dev/null", O_RDWR);
340 open("/dev/null", O_RDWR);
341 close(pipefd[0]);
342 sprintf(pipefd_str, "%d", pipefd[1]);
343 execvp(args[0], args);
344 exit(EXIT_FAILURE);
345 }