]>
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
31 #include <sys/types.h>
33 #include <sys/param.h>
34 #include <sys/socket.h>
36 #include <netinet/in.h>
43 #include <lxc/state.h>
44 #include <lxc/monitor.h>
45 #include <lxc/utils.h>
47 lxc_log_define(lxc_monitor
, lxc
);
49 /* routines used by monitor publishers (containers) */
50 static void lxc_monitor_fifo_send(struct lxc_msg
*msg
, const char *lxcpath
)
53 char fifo_path
[PATH_MAX
];
55 BUILD_BUG_ON(sizeof(*msg
) > PIPE_BUF
); /* write not guaranteed atomic */
56 ret
= snprintf(fifo_path
, sizeof(fifo_path
), "%s/monitor-fifo", lxcpath
);
57 if (ret
< 0 || ret
>= sizeof(fifo_path
)) {
58 ERROR("lxcpath too long to open monitor fifo");
62 fd
= open(fifo_path
, O_WRONLY
);
64 /* it is normal for this open to fail when there is no monitor
65 * running, so we don't log it
70 ret
= write(fd
, msg
, sizeof(*msg
));
71 if (ret
!= sizeof(*msg
)) {
73 SYSERROR("failed to write monitor fifo %s", fifo_path
);
80 void lxc_monitor_send_state(const char *name
, lxc_state_t state
, const char *lxcpath
)
82 struct lxc_msg msg
= { .type
= lxc_msg_state
,
84 strncpy(msg
.name
, name
, sizeof(msg
.name
));
85 msg
.name
[sizeof(msg
.name
) - 1] = 0;
87 lxc_monitor_fifo_send(&msg
, lxcpath
);
91 /* routines used by monitor subscribers (lxc-monitor) */
92 int lxc_monitor_close(int fd
)
97 int lxc_monitor_sock_name(const char *lxcpath
, struct sockaddr_un
*addr
) {
100 char *sockname
= &addr
->sun_path
[0]; // 1 for abstract
102 /* addr.sun_path is only 108 bytes.
103 * should we take a hash of lxcpath? a subset of it? ftok()? we need
104 * to make sure it is unique.
106 memset(addr
, 0, sizeof(*addr
));
107 addr
->sun_family
= AF_UNIX
;
108 len
= sizeof(addr
->sun_path
) - 1;
109 ret
= snprintf(sockname
, len
, "%s/monitor-sock", lxcpath
);
110 if (ret
< 0 || ret
>= len
) {
111 ERROR("lxcpath too long for unix socket");
117 int lxc_monitor_open(const char *lxcpath
)
119 struct sockaddr_un addr
;
121 int retry
,backoff_ms
[] = {10, 50, 100};
123 if (lxc_monitor_sock_name(lxcpath
, &addr
) < 0)
126 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
128 ERROR("socket : %s", strerror(errno
));
132 for (retry
= 0; retry
< sizeof(backoff_ms
)/sizeof(backoff_ms
[0]); retry
++) {
133 ret
= connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
134 if (ret
== 0 || errno
!= ECONNREFUSED
)
136 ERROR("connect : backing off %d", backoff_ms
[retry
]);
137 usleep(backoff_ms
[retry
] * 1000);
141 ERROR("connect : %s", strerror(errno
));
150 int lxc_monitor_read_fdset(fd_set
*rfds
, int nfds
, struct lxc_msg
*msg
,
153 struct timeval tval
,*tv
= NULL
;
158 tv
->tv_sec
= timeout
;
162 ret
= select(nfds
, rfds
, NULL
, NULL
, tv
);
166 return -2; // timed out
168 /* only read from the first ready fd, the others will remain ready
169 * for when this routine is called again
171 for (i
= 0; i
< nfds
; i
++) {
172 if (FD_ISSET(i
, rfds
)) {
173 ret
= recv(i
, msg
, sizeof(*msg
), 0);
175 SYSERROR("client failed to recv (monitord died?) %s",
182 SYSERROR("no ready fd found?");
186 int lxc_monitor_read_timeout(int fd
, struct lxc_msg
*msg
, int timeout
)
193 return lxc_monitor_read_fdset(&rfds
, fd
+1, msg
, timeout
);
196 int lxc_monitor_read(int fd
, struct lxc_msg
*msg
)
198 return lxc_monitor_read_timeout(fd
, msg
, -1);
203 /* used to spawn a monitord either on startup of a daemon container, or when
206 int lxc_monitord_spawn(const char *lxcpath
)
212 char * const args
[] = {
219 /* double fork to avoid zombies when monitord exits */
222 SYSERROR("failed to fork");
227 if (waitpid(pid1
, NULL
, 0) != pid1
)
232 if (pipe(pipefd
) < 0) {
233 SYSERROR("failed to create pipe");
239 SYSERROR("failed to fork");
244 /* wait for daemon to create socket */
246 /* sync with child, we're ignoring the return from read
247 * because regardless if it works or not, either way we've
248 * synced with the child process. the if-empty-statement
249 * construct is to quiet the warn-unused-result warning.
251 if (read(pipefd
[0], &c
, 1)) ;
258 SYSERROR("failed to setsid");
264 open("/dev/null", O_RDONLY
);
265 open("/dev/null", O_RDWR
);
266 open("/dev/null", O_RDWR
);
268 sprintf(pipefd_str
, "%d", pipefd
[1]);
269 execvp(args
[0], args
);