]>
git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/monitor.c
2 * lxc: linux Container library
4 * (C) Copyright IBM Corp. 2007, 2008
7 * Daniel Lezcano <daniel.lezcano at free.fr>
8 * Dwight Engen <dwight.engen@oracle.com>
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.
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.
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
34 #include <sys/types.h>
36 #include <sys/param.h>
37 #include <sys/socket.h>
39 #include <netinet/in.h>
50 lxc_log_define(lxc_monitor
, lxc
);
52 /* routines used by monitor publishers (containers) */
53 int lxc_monitor_fifo_name(const char *lxcpath
, char *fifo_path
, size_t fifo_path_sz
,
59 rundir
= get_rundir();
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
);
66 ret
= mkdir_p(fifo_path
, 0755);
68 ERROR("unable to create monitor fifo dir %s", fifo_path
);
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
);
80 static void lxc_monitor_fifo_send(struct lxc_msg
*msg
, const char *lxcpath
)
83 char fifo_path
[PATH_MAX
];
85 BUILD_BUG_ON(sizeof(*msg
) > PIPE_BUF
); /* write not guaranteed atomic */
87 ret
= lxc_monitor_fifo_name(lxcpath
, fifo_path
, sizeof(fifo_path
), 0);
91 fd
= open(fifo_path
, O_WRONLY
);
93 /* it is normal for this open to fail when there is no monitor
94 * running, so we don't log it
99 ret
= write(fd
, msg
, sizeof(*msg
));
100 if (ret
!= sizeof(*msg
)) {
102 SYSERROR("failed to write monitor fifo %s", fifo_path
);
109 void lxc_monitor_send_state(const char *name
, lxc_state_t state
, const char *lxcpath
)
111 struct lxc_msg msg
= { .type
= lxc_msg_state
,
113 strncpy(msg
.name
, name
, sizeof(msg
.name
));
114 msg
.name
[sizeof(msg
.name
) - 1] = 0;
116 lxc_monitor_fifo_send(&msg
, lxcpath
);
120 /* routines used by monitor subscribers (lxc-monitor) */
121 int lxc_monitor_close(int fd
)
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.
131 #define FNV1A_64_INIT ((uint64_t)0xcbf29ce484222325ULL)
132 static uint64_t fnv_64a_buf(void *buf
, size_t len
, uint64_t hval
)
136 for(bp
= buf
; bp
< (unsigned char *)buf
+ len
; bp
++)
138 /* xor the bottom with the current octet */
139 hval
^= (uint64_t)*bp
;
142 * multiply by the 64 bit FNV magic prime mod 2^64
144 hval
+= (hval
<< 1) + (hval
<< 4) + (hval
<< 5) +
145 (hval
<< 7) + (hval
<< 8) + (hval
<< 40);
151 int lxc_monitor_sock_name(const char *lxcpath
, struct sockaddr_un
*addr
) {
154 char *sockname
= &addr
->sun_path
[1];
155 char path
[PATH_MAX
+18];
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.
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
);
170 hash
= fnv_64a_buf(path
, ret
, FNV1A_64_INIT
);
171 ret
= snprintf(sockname
, len
, "lxc/%016" PRIx64
"/%s", hash
, lxcpath
);
174 sockname
[sizeof(addr
->sun_path
)-2] = '\0';
175 INFO("using monitor sock name %s", sockname
);
179 int lxc_monitor_open(const char *lxcpath
)
181 struct sockaddr_un addr
;
183 int retry
,backoff_ms
[] = {10, 50, 100};
186 if (lxc_monitor_sock_name(lxcpath
, &addr
) < 0)
189 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
191 ERROR("socket : %s", strerror(errno
));
195 len
= strlen(&addr
.sun_path
[1]) + 1;
196 if (len
>= sizeof(addr
.sun_path
) - 1) {
198 errno
= ENAMETOOLONG
;
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
)
206 ERROR("connect : backing off %d", backoff_ms
[retry
]);
207 usleep(backoff_ms
[retry
] * 1000);
211 ERROR("connect : %s", strerror(errno
));
220 int lxc_monitor_read_fdset(fd_set
*rfds
, int nfds
, struct lxc_msg
*msg
,
223 struct timeval tval
,*tv
= NULL
;
228 tv
->tv_sec
= timeout
;
232 ret
= select(nfds
, rfds
, NULL
, NULL
, tv
);
236 return -2; // timed out
238 /* only read from the first ready fd, the others will remain ready
239 * for when this routine is called again
241 for (i
= 0; i
< nfds
; i
++) {
242 if (FD_ISSET(i
, rfds
)) {
243 ret
= recv(i
, msg
, sizeof(*msg
), 0);
245 SYSERROR("client failed to recv (monitord died?) %s",
252 SYSERROR("no ready fd found?");
256 int lxc_monitor_read_timeout(int fd
, struct lxc_msg
*msg
, int timeout
)
263 return lxc_monitor_read_fdset(&rfds
, fd
+1, msg
, timeout
);
266 int lxc_monitor_read(int fd
, struct lxc_msg
*msg
)
268 return lxc_monitor_read_timeout(fd
, msg
, -1);
272 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
274 /* used to spawn a monitord either on startup of a daemon container, or when
277 int lxc_monitord_spawn(const char *lxcpath
)
283 char * const args
[] = {
290 /* double fork to avoid zombies when monitord exits */
293 SYSERROR("failed to fork");
298 if (waitpid(pid1
, NULL
, 0) != pid1
)
303 if (pipe(pipefd
) < 0) {
304 SYSERROR("failed to create pipe");
310 SYSERROR("failed to fork");
315 /* wait for daemon to create socket */
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.
322 if (read(pipefd
[0], &c
, 1))
329 SYSERROR("failed to setsid");
335 open("/dev/null", O_RDONLY
);
336 open("/dev/null", O_RDWR
);
337 open("/dev/null", O_RDWR
);
339 sprintf(pipefd_str
, "%d", pipefd
[1]);
340 execvp(args
[0], args
);