]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/monitor.c
lxc-monitord.log should not be created with mode 0666
[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 const char *rundir;
58
59 rundir = get_rundir();
60 if (do_mkdirp) {
61 ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s", rundir, lxcpath);
62 if (ret < 0 || ret >= fifo_path_sz) {
63 ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
64 return -1;
65 }
66 ret = mkdir_p(fifo_path, 0755);
67 if (ret < 0) {
68 ERROR("unable to create monitor fifo dir %s", fifo_path);
69 return ret;
70 }
71 }
72 ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
73 if (ret < 0 || ret >= fifo_path_sz) {
74 ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
75 return -1;
76 }
77 return 0;
78 }
79
80 static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
81 {
82 int fd,ret;
83 char fifo_path[PATH_MAX];
84
85 BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */
86
87 ret = lxc_monitor_fifo_name(lxcpath, fifo_path, sizeof(fifo_path), 0);
88 if (ret < 0)
89 return;
90
91 fd = open(fifo_path, O_WRONLY);
92 if (fd < 0) {
93 /* it is normal for this open to fail when there is no monitor
94 * running, so we don't log it
95 */
96 return;
97 }
98
99 ret = write(fd, msg, sizeof(*msg));
100 if (ret != sizeof(*msg)) {
101 close(fd);
102 SYSERROR("failed to write monitor fifo %s", fifo_path);
103 return;
104 }
105
106 close(fd);
107 }
108
109 void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
110 {
111 struct lxc_msg msg = { .type = lxc_msg_state,
112 .value = state };
113 strncpy(msg.name, name, sizeof(msg.name));
114 msg.name[sizeof(msg.name) - 1] = 0;
115
116 lxc_monitor_fifo_send(&msg, lxcpath);
117 }
118
119
120 /* routines used by monitor subscribers (lxc-monitor) */
121 int lxc_monitor_close(int fd)
122 {
123 return close(fd);
124 }
125
126 /* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
127 * FNV has good anti collision properties and we're not worried
128 * about pre-image resistance or one-way-ness, we're just trying to make
129 * the name unique in the 108 bytes of space we have.
130 */
131 #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
132 static uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
133 {
134 unsigned char *bp;
135
136 for(bp = buf; bp < (unsigned char *)buf + len; bp++)
137 {
138 /* xor the bottom with the current octet */
139 hval ^= (uint64_t)*bp;
140
141 /* gcc optimised:
142 * multiply by the 64 bit FNV magic prime mod 2^64
143 */
144 hval += (hval << 1) + (hval << 4) + (hval << 5) +
145 (hval << 7) + (hval << 8) + (hval << 40);
146 }
147
148 return hval;
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[PATH_MAX+18];
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 = sizeof(addr->sun_path) - 1;
164 ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath);
165 if (ret < 0 || ret >= sizeof(path)) {
166 ERROR("lxcpath %s too long for monitor unix socket", lxcpath);
167 return -1;
168 }
169
170 hash = fnv_64a_buf(path, ret, FNV1A_64_INIT);
171 ret = snprintf(sockname, len, "lxc/%016" PRIx64 "/%s", hash, lxcpath);
172 if (ret < 0)
173 return -1;
174 sockname[sizeof(addr->sun_path)-2] = '\0';
175 INFO("using monitor sock name %s", sockname);
176 return 0;
177 }
178
179 int lxc_monitor_open(const char *lxcpath)
180 {
181 struct sockaddr_un addr;
182 int fd,ret;
183 int retry,backoff_ms[] = {10, 50, 100};
184 size_t len;
185
186 if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
187 return -1;
188
189 fd = socket(PF_UNIX, SOCK_STREAM, 0);
190 if (fd < 0) {
191 ERROR("socket : %s", strerror(errno));
192 return -1;
193 }
194
195 len = strlen(&addr.sun_path[1]) + 1;
196 if (len >= sizeof(addr.sun_path) - 1) {
197 ret = -1;
198 errno = ENAMETOOLONG;
199 goto err1;
200 }
201
202 for (retry = 0; retry < sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) {
203 ret = connect(fd, (struct sockaddr *)&addr, offsetof(struct sockaddr_un, sun_path) + len);
204 if (ret == 0 || errno != ECONNREFUSED)
205 break;
206 ERROR("connect : backing off %d", backoff_ms[retry]);
207 usleep(backoff_ms[retry] * 1000);
208 }
209
210 if (ret < 0) {
211 ERROR("connect : %s", strerror(errno));
212 goto err1;
213 }
214 return fd;
215 err1:
216 close(fd);
217 return ret;
218 }
219
220 int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg,
221 int timeout)
222 {
223 struct timeval tval,*tv = NULL;
224 int ret,i;
225
226 if (timeout != -1) {
227 tv = &tval;
228 tv->tv_sec = timeout;
229 tv->tv_usec = 0;
230 }
231
232 ret = select(nfds, rfds, NULL, NULL, tv);
233 if (ret == -1)
234 return -1;
235 else if (ret == 0)
236 return -2; // timed out
237
238 /* only read from the first ready fd, the others will remain ready
239 * for when this routine is called again
240 */
241 for (i = 0; i < nfds; i++) {
242 if (FD_ISSET(i, rfds)) {
243 ret = recv(i, msg, sizeof(*msg), 0);
244 if (ret <= 0) {
245 SYSERROR("client failed to recv (monitord died?) %s",
246 strerror(errno));
247 return -1;
248 }
249 return ret;
250 }
251 }
252 SYSERROR("no ready fd found?");
253 return -1;
254 }
255
256 int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout)
257 {
258 fd_set rfds;
259
260 FD_ZERO(&rfds);
261 FD_SET(fd, &rfds);
262
263 return lxc_monitor_read_fdset(&rfds, fd+1, msg, timeout);
264 }
265
266 int lxc_monitor_read(int fd, struct lxc_msg *msg)
267 {
268 return lxc_monitor_read_timeout(fd, msg, -1);
269 }
270
271
272 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
273
274 /* used to spawn a monitord either on startup of a daemon container, or when
275 * lxc-monitor starts
276 */
277 int lxc_monitord_spawn(const char *lxcpath)
278 {
279 pid_t pid1,pid2;
280 int pipefd[2];
281 char pipefd_str[11];
282
283 char * const args[] = {
284 LXC_MONITORD_PATH,
285 (char *)lxcpath,
286 pipefd_str,
287 NULL,
288 };
289
290 /* double fork to avoid zombies when monitord exits */
291 pid1 = fork();
292 if (pid1 < 0) {
293 SYSERROR("failed to fork");
294 return -1;
295 }
296
297 if (pid1) {
298 if (waitpid(pid1, NULL, 0) != pid1)
299 return -1;
300 return 0;
301 }
302
303 if (pipe(pipefd) < 0) {
304 SYSERROR("failed to create pipe");
305 exit(EXIT_FAILURE);
306 }
307
308 pid2 = fork();
309 if (pid2 < 0) {
310 SYSERROR("failed to fork");
311 exit(EXIT_FAILURE);
312 }
313 if (pid2) {
314 char c;
315 /* wait for daemon to create socket */
316 close(pipefd[1]);
317 /* sync with child, we're ignoring the return from read
318 * because regardless if it works or not, either way we've
319 * synced with the child process. the if-empty-statement
320 * construct is to quiet the warn-unused-result warning.
321 */
322 if (read(pipefd[0], &c, 1))
323 ;
324 close(pipefd[0]);
325 exit(EXIT_SUCCESS);
326 }
327
328 if (setsid() < 0) {
329 SYSERROR("failed to setsid");
330 exit(EXIT_FAILURE);
331 }
332 close(0);
333 close(1);
334 close(2);
335 open("/dev/null", O_RDONLY);
336 open("/dev/null", O_RDWR);
337 open("/dev/null", O_RDWR);
338 close(pipefd[0]);
339 sprintf(pipefd_str, "%d", pipefd[1]);
340 execvp(args[0], args);
341 exit(EXIT_FAILURE);
342 }