]> git.proxmox.com Git - mirror_lxc.git/blame - src/lxc/monitor.c
hash lxcname for use in monitor unix socket sun_path[108]
[mirror_lxc.git] / src / lxc / monitor.c
CommitLineData
0ad19a3f 1/*
2 * lxc: linux Container library
3 *
4 * (C) Copyright IBM Corp. 2007, 2008
5 *
6 * Authors:
9afe19d6 7 * Daniel Lezcano <daniel.lezcano at free.fr>
e51d4895 8 * Dwight Engen <dwight.engen@oracle.com>
0ad19a3f 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
250b1eec 22 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
0ad19a3f 23 */
e51d4895 24
0ad19a3f 25#include <stdio.h>
26#include <errno.h>
27#include <unistd.h>
28#include <string.h>
29#include <stdlib.h>
30#include <fcntl.h>
b45c7011
DE
31#include <inttypes.h>
32#include <stdint.h>
0ad19a3f 33#include <sys/types.h>
34#include <sys/stat.h>
35#include <sys/param.h>
0ad19a3f 36#include <sys/socket.h>
e51d4895 37#include <sys/wait.h>
0ad19a3f 38#include <netinet/in.h>
39#include <net/if.h>
b113348e 40
e2bcd7db 41#include "error.h"
31c53c2e 42#include "af_unix.h"
00b3c2e2 43
36eb9bde 44#include <lxc/log.h>
9e60f51d 45#include <lxc/lxclock.h>
00b3c2e2
CLG
46#include <lxc/state.h>
47#include <lxc/monitor.h>
e51d4895 48#include <lxc/utils.h>
36eb9bde
CLG
49
50lxc_log_define(lxc_monitor, lxc);
0ad19a3f 51
e51d4895 52/* routines used by monitor publishers (containers) */
9e60f51d
DE
53int 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 process_lock();
67 ret = mkdir_p(fifo_path, 0755);
68 process_unlock();
69 if (ret < 0) {
70 ERROR("unable to create monitor fifo dir %s", fifo_path);
71 return ret;
72 }
73 }
74 ret = snprintf(fifo_path, fifo_path_sz, "%s/lxc/%s/monitor-fifo", rundir, lxcpath);
75 if (ret < 0 || ret >= fifo_path_sz) {
76 ERROR("rundir/lxcpath (%s/%s) too long for monitor fifo", rundir, lxcpath);
77 return -1;
78 }
79 return 0;
80}
81
e51d4895 82static void lxc_monitor_fifo_send(struct lxc_msg *msg, const char *lxcpath)
0ad19a3f 83{
e51d4895
DE
84 int fd,ret;
85 char fifo_path[PATH_MAX];
86
87 BUILD_BUG_ON(sizeof(*msg) > PIPE_BUF); /* write not guaranteed atomic */
9e60f51d
DE
88
89 ret = lxc_monitor_fifo_name(lxcpath, fifo_path, sizeof(fifo_path), 0);
90 if (ret < 0)
9123e471 91 return;
80f41298 92
e51d4895
DE
93 fd = open(fifo_path, O_WRONLY);
94 if (fd < 0) {
95 /* it is normal for this open to fail when there is no monitor
96 * running, so we don't log it
97 */
31c53c2e 98 return;
e51d4895 99 }
0ad19a3f 100
e51d4895
DE
101 ret = write(fd, msg, sizeof(*msg));
102 if (ret != sizeof(*msg)) {
e8b9ac8f 103 close(fd);
e51d4895
DE
104 SYSERROR("failed to write monitor fifo %s", fifo_path);
105 return;
106 }
0ad19a3f 107
108 close(fd);
109}
110
9123e471 111void lxc_monitor_send_state(const char *name, lxc_state_t state, const char *lxcpath)
eae6543d 112{
113 struct lxc_msg msg = { .type = lxc_msg_state,
114 .value = state };
80f41298 115 strncpy(msg.name, name, sizeof(msg.name));
f3bc28bd 116 msg.name[sizeof(msg.name) - 1] = 0;
eae6543d 117
e51d4895 118 lxc_monitor_fifo_send(&msg, lxcpath);
0ad19a3f 119}
120
e51d4895
DE
121
122/* routines used by monitor subscribers (lxc-monitor) */
123int lxc_monitor_close(int fd)
0ad19a3f 124{
e51d4895
DE
125 return close(fd);
126}
127
b45c7011
DE
128/* Note we don't use SHA-1 here as we don't want to depend on HAVE_GNUTLS.
129 * FNV has good anti collision properties and we're not worried
130 * about pre-image resistance or one-way-ness, we're just trying to make
131 * the name unique in the 108 bytes of space we have.
132 */
133#define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
134static uint64_t fnv_64a_buf(void *buf, size_t len, uint64_t hval)
135{
136 unsigned char *bp;
137
138 for(bp = buf; bp < (unsigned char *)buf + len; bp++)
139 {
140 /* xor the bottom with the current octet */
141 hval ^= (uint64_t)*bp;
142
143 /* gcc optimised:
144 * multiply by the 64 bit FNV magic prime mod 2^64
145 */
146 hval += (hval << 1) + (hval << 4) + (hval << 5) +
147 (hval << 7) + (hval << 8) + (hval << 40);
148 }
149
150 return hval;
151}
152
e51d4895
DE
153int lxc_monitor_sock_name(const char *lxcpath, struct sockaddr_un *addr) {
154 size_t len;
155 int ret;
b45c7011
DE
156 char *sockname = &addr->sun_path[1];
157 char path[PATH_MAX+18];
158 uint64_t hash;
e51d4895 159
b45c7011
DE
160 /* addr.sun_path is only 108 bytes, so we hash the full name and
161 * then append as much of the name as we can fit.
9123e471 162 */
e51d4895
DE
163 memset(addr, 0, sizeof(*addr));
164 addr->sun_family = AF_UNIX;
165 len = sizeof(addr->sun_path) - 1;
b45c7011
DE
166 ret = snprintf(path, sizeof(path), "lxc/%s/monitor-sock", lxcpath);
167 if (ret < 0 || ret >= sizeof(path)) {
168 ERROR("lxcpath %s too long for monitor unix socket", lxcpath);
9e60f51d
DE
169 return -1;
170 }
9e60f51d 171
b45c7011
DE
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)
9123e471 175 return -1;
b45c7011
DE
176 sockname[sizeof(addr->sun_path)-2] = '\0';
177 INFO("using monitor sock name %s", sockname);
e51d4895
DE
178 return 0;
179}
0ad19a3f 180
e51d4895
DE
181int 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
187 if (lxc_monitor_sock_name(lxcpath, &addr) < 0)
188 return -1;
189
190 fd = socket(PF_UNIX, SOCK_STREAM, 0);
2c396e12
MN
191 if (fd < 0) {
192 ERROR("socket : %s", strerror(errno));
31c53c2e 193 return -1;
2c396e12 194 }
0ad19a3f 195
e51d4895
DE
196 for (retry = 0; retry < sizeof(backoff_ms)/sizeof(backoff_ms[0]); retry++) {
197 ret = connect(fd, (struct sockaddr *)&addr, sizeof(addr));
198 if (ret == 0 || errno != ECONNREFUSED)
199 break;
200 ERROR("connect : backing off %d", backoff_ms[retry]);
201 usleep(backoff_ms[retry] * 1000);
0ad19a3f 202 }
203
e51d4895
DE
204 if (ret < 0) {
205 ERROR("connect : %s", strerror(errno));
206 goto err1;
207 }
0ad19a3f 208 return fd;
e51d4895
DE
209err1:
210 close(fd);
211 return ret;
0ad19a3f 212}
213
8d06bd13
DE
214int lxc_monitor_read_fdset(fd_set *rfds, int nfds, struct lxc_msg *msg,
215 int timeout)
0ad19a3f 216{
8d06bd13
DE
217 struct timeval tval,*tv = NULL;
218 int ret,i;
72d0e1cb
SG
219
220 if (timeout != -1) {
8d06bd13
DE
221 tv = &tval;
222 tv->tv_sec = timeout;
223 tv->tv_usec = 0;
72d0e1cb 224 }
0ad19a3f 225
8d06bd13
DE
226 ret = select(nfds, rfds, NULL, NULL, tv);
227 if (ret == -1)
75b1e198 228 return -1;
8d06bd13
DE
229 else if (ret == 0)
230 return -2; // timed out
231
232 /* only read from the first ready fd, the others will remain ready
233 * for when this routine is called again
234 */
235 for (i = 0; i < nfds; i++) {
236 if (FD_ISSET(i, rfds)) {
237 ret = recv(i, msg, sizeof(*msg), 0);
238 if (ret <= 0) {
239 SYSERROR("client failed to recv (monitord died?) %s",
240 strerror(errno));
241 return -1;
242 }
243 return ret;
244 }
0ad19a3f 245 }
8d06bd13
DE
246 SYSERROR("no ready fd found?");
247 return -1;
248}
249
250int lxc_monitor_read_timeout(int fd, struct lxc_msg *msg, int timeout)
251{
252 fd_set rfds;
253
254 FD_ZERO(&rfds);
255 FD_SET(fd, &rfds);
256
257 return lxc_monitor_read_fdset(&rfds, fd+1, msg, timeout);
0ad19a3f 258}
259
72d0e1cb
SG
260int lxc_monitor_read(int fd, struct lxc_msg *msg)
261{
262 return lxc_monitor_read_timeout(fd, msg, -1);
263}
264
e51d4895
DE
265
266
267/* used to spawn a monitord either on startup of a daemon container, or when
268 * lxc-monitor starts
269 */
270int lxc_monitord_spawn(const char *lxcpath)
0ad19a3f 271{
e51d4895
DE
272 pid_t pid1,pid2;
273 int pipefd[2];
274 char pipefd_str[11];
275
276 char * const args[] = {
31f58b3f 277 "lxc-monitord",
e51d4895
DE
278 (char *)lxcpath,
279 pipefd_str,
280 NULL,
281 };
282
283 /* double fork to avoid zombies when monitord exits */
284 pid1 = fork();
285 if (pid1 < 0) {
286 SYSERROR("failed to fork");
287 return -1;
288 }
289
290 if (pid1) {
f2bbe86d
DE
291 if (waitpid(pid1, NULL, 0) != pid1)
292 return -1;
e51d4895
DE
293 return 0;
294 }
295
296 if (pipe(pipefd) < 0) {
297 SYSERROR("failed to create pipe");
298 exit(EXIT_FAILURE);
299 }
300
301 pid2 = fork();
302 if (pid2 < 0) {
303 SYSERROR("failed to fork");
304 exit(EXIT_FAILURE);
305 }
306 if (pid2) {
307 char c;
308 /* wait for daemon to create socket */
309 close(pipefd[1]);
310 /* sync with child, we're ignoring the return from read
311 * because regardless if it works or not, either way we've
312 * synced with the child process. the if-empty-statement
313 * construct is to quiet the warn-unused-result warning.
314 */
315 if (read(pipefd[0], &c, 1)) ;
316 close(pipefd[0]);
317 exit(EXIT_SUCCESS);
318 }
319
320 umask(0);
321 if (setsid() < 0) {
322 SYSERROR("failed to setsid");
323 exit(EXIT_FAILURE);
324 }
325 close(0);
326 close(1);
327 close(2);
328 open("/dev/null", O_RDONLY);
329 open("/dev/null", O_RDWR);
330 open("/dev/null", O_RDWR);
331 close(pipefd[0]);
332 sprintf(pipefd_str, "%d", pipefd[1]);
333 execvp(args[0], args);
334 exit(EXIT_FAILURE);
0ad19a3f 335}