]>
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();
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
);
70 ret
= mkdir_p(fifo_path
, 0755);
72 ERROR("unable to create monitor fifo dir %s", fifo_path
);
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
);
87 static void lxc_monitor_fifo_send(struct lxc_msg
*msg
, const char *lxcpath
)
90 char fifo_path
[PATH_MAX
];
92 BUILD_BUG_ON(sizeof(*msg
) > PIPE_BUF
); /* write not guaranteed atomic */
94 ret
= lxc_monitor_fifo_name(lxcpath
, fifo_path
, sizeof(fifo_path
), 0);
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.
101 fd
= open(fifo_path
, O_WRONLY
|O_NONBLOCK
);
103 /* it is normal for this open to fail ENXIO when there is no
104 * monitor running, so we don't log it
109 if (fcntl(fd
, F_SETFL
, O_WRONLY
) < 0) {
114 ret
= write(fd
, msg
, sizeof(*msg
));
115 if (ret
!= sizeof(*msg
)) {
117 SYSERROR("failed to write monitor fifo %s", fifo_path
);
124 void lxc_monitor_send_state(const char *name
, lxc_state_t state
, const char *lxcpath
)
126 struct lxc_msg msg
= { .type
= lxc_msg_state
,
128 strncpy(msg
.name
, name
, sizeof(msg
.name
));
129 msg
.name
[sizeof(msg
.name
) - 1] = 0;
131 lxc_monitor_fifo_send(&msg
, lxcpath
);
134 void lxc_monitor_send_exit_code(const char *name
, int exit_code
, const char *lxcpath
)
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;
141 lxc_monitor_fifo_send(&msg
, lxcpath
);
145 /* routines used by monitor subscribers (lxc-monitor) */
146 int lxc_monitor_close(int fd
)
151 int lxc_monitor_sock_name(const char *lxcpath
, struct sockaddr_un
*addr
) {
154 char *sockname
= &addr
->sun_path
[1];
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
= strlen(lxcpath
) + 18;
165 ret
= snprintf(path
, len
, "lxc/%s/monitor-sock", lxcpath
);
166 if (ret
< 0 || ret
>= len
) {
167 ERROR("memory error creating monitor path");
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
);
176 sockname
[sizeof(addr
->sun_path
)-3] = '\0';
177 INFO("using monitor sock name %s", sockname
);
181 int lxc_monitor_open(const char *lxcpath
)
183 struct sockaddr_un addr
;
185 int retry
,backoff_ms
[] = {10, 50, 100};
188 if (lxc_monitor_sock_name(lxcpath
, &addr
) < 0)
191 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
193 ERROR("socket : %s", strerror(errno
));
197 len
= strlen(&addr
.sun_path
[1]) + 1;
198 if (len
>= sizeof(addr
.sun_path
) - 1) {
200 errno
= ENAMETOOLONG
;
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
)
208 ERROR("connect : backing off %d", backoff_ms
[retry
]);
209 usleep(backoff_ms
[retry
] * 1000);
213 ERROR("connect : %s", strerror(errno
));
222 int lxc_monitor_read_fdset(fd_set
*rfds
, int nfds
, struct lxc_msg
*msg
,
225 struct timeval tval
,*tv
= NULL
;
230 tv
->tv_sec
= timeout
;
234 ret
= select(nfds
, rfds
, NULL
, NULL
, tv
);
238 return -2; // timed out
240 /* only read from the first ready fd, the others will remain ready
241 * for when this routine is called again
243 for (i
= 0; i
< nfds
; i
++) {
244 if (FD_ISSET(i
, rfds
)) {
245 ret
= recv(i
, msg
, sizeof(*msg
), 0);
247 SYSERROR("client failed to recv (monitord died?) %s",
254 SYSERROR("no ready fd found?");
258 int lxc_monitor_read_timeout(int fd
, struct lxc_msg
*msg
, int timeout
)
265 return lxc_monitor_read_fdset(&rfds
, fd
+1, msg
, timeout
);
268 int lxc_monitor_read(int fd
, struct lxc_msg
*msg
)
270 return lxc_monitor_read_timeout(fd
, msg
, -1);
274 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
276 /* used to spawn a monitord either on startup of a daemon container, or when
279 int lxc_monitord_spawn(const char *lxcpath
)
285 char * const args
[] = {
292 /* double fork to avoid zombies when monitord exits */
295 SYSERROR("failed to fork");
300 if (waitpid(pid1
, NULL
, 0) != pid1
)
305 if (pipe(pipefd
) < 0) {
306 SYSERROR("failed to create pipe");
312 SYSERROR("failed to fork");
317 /* wait for daemon to create socket */
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.
324 if (read(pipefd
[0], &c
, 1))
331 SYSERROR("failed to setsid");
334 lxc_check_inherited(NULL
, pipefd
[1]);
338 open("/dev/null", O_RDONLY
);
339 open("/dev/null", O_RDWR
);
340 open("/dev/null", O_RDWR
);
342 sprintf(pipefd_str
, "%d", pipefd
[1]);
343 execvp(args
[0], args
);