]>
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
)) {
72 SYSERROR("failed to write monitor fifo %s", fifo_path
);
79 void lxc_monitor_send_state(const char *name
, lxc_state_t state
, const char *lxcpath
)
81 struct lxc_msg msg
= { .type
= lxc_msg_state
,
83 strncpy(msg
.name
, name
, sizeof(msg
.name
));
84 msg
.name
[sizeof(msg
.name
) - 1] = 0;
86 lxc_monitor_fifo_send(&msg
, lxcpath
);
90 /* routines used by monitor subscribers (lxc-monitor) */
91 int lxc_monitor_close(int fd
)
96 int lxc_monitor_sock_name(const char *lxcpath
, struct sockaddr_un
*addr
) {
99 char *sockname
= &addr
->sun_path
[0]; // 1 for abstract
101 /* addr.sun_path is only 108 bytes.
102 * should we take a hash of lxcpath? a subset of it? ftok()? we need
103 * to make sure it is unique.
105 memset(addr
, 0, sizeof(*addr
));
106 addr
->sun_family
= AF_UNIX
;
107 len
= sizeof(addr
->sun_path
) - 1;
108 ret
= snprintf(sockname
, len
, "%s/monitor-sock", lxcpath
);
109 if (ret
< 0 || ret
>= len
) {
110 ERROR("lxcpath too long for unix socket");
116 int lxc_monitor_open(const char *lxcpath
)
118 struct sockaddr_un addr
;
120 int retry
,backoff_ms
[] = {10, 50, 100};
122 if (lxc_monitor_sock_name(lxcpath
, &addr
) < 0)
125 fd
= socket(PF_UNIX
, SOCK_STREAM
, 0);
127 ERROR("socket : %s", strerror(errno
));
131 for (retry
= 0; retry
< sizeof(backoff_ms
)/sizeof(backoff_ms
[0]); retry
++) {
132 ret
= connect(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));
133 if (ret
== 0 || errno
!= ECONNREFUSED
)
135 ERROR("connect : backing off %d", backoff_ms
[retry
]);
136 usleep(backoff_ms
[retry
] * 1000);
140 ERROR("connect : %s", strerror(errno
));
149 int lxc_monitor_read_timeout(int fd
, struct lxc_msg
*msglxc
, int timeout
)
162 ret
= select(fd
+1, &rfds
, NULL
, NULL
, &tv
);
166 return -2; // timed out
169 ret
= recv(fd
, msglxc
, sizeof(*msglxc
), 0);
171 SYSERROR("client failed to recv (monitord died?) %s",
178 int lxc_monitor_read(int fd
, struct lxc_msg
*msg
)
180 return lxc_monitor_read_timeout(fd
, msg
, -1);
185 /* used to spawn a monitord either on startup of a daemon container, or when
188 int lxc_monitord_spawn(const char *lxcpath
)
194 char * const args
[] = {
195 "/usr/bin/lxc-monitord",
201 /* double fork to avoid zombies when monitord exits */
204 SYSERROR("failed to fork");
209 waitpid(pid1
, NULL
, 0);
213 if (pipe(pipefd
) < 0) {
214 SYSERROR("failed to create pipe");
220 SYSERROR("failed to fork");
225 /* wait for daemon to create socket */
227 /* sync with child, we're ignoring the return from read
228 * because regardless if it works or not, either way we've
229 * synced with the child process. the if-empty-statement
230 * construct is to quiet the warn-unused-result warning.
232 if (read(pipefd
[0], &c
, 1)) ;
239 SYSERROR("failed to setsid");
245 open("/dev/null", O_RDONLY
);
246 open("/dev/null", O_RDWR
);
247 open("/dev/null", O_RDWR
);
249 sprintf(pipefd_str
, "%d", pipefd
[1]);
250 execvp(args
[0], args
);