]>
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
32 #include <netinet/in.h>
39 #include <sys/param.h>
40 #include <sys/socket.h>
42 #include <sys/types.h>
57 #include "include/strlcpy.h"
60 lxc_log_define ( monitor
, lxc
);
62 /* routines used by monitor publishers (containers) */
63 int lxc_monitor_fifo_name ( const char * lxcpath
, char * fifo_path
, size_t fifo_path_sz
,
69 rundir
= get_rundir ();
74 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s" , rundir
, lxcpath
);
75 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
76 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo" , rundir
, lxcpath
);
80 ret
= mkdir_p ( fifo_path
, 0755 );
82 ERROR ( "Unable to create monitor fifo directory %s." , fifo_path
);
87 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s/monitor-fifo" , rundir
, lxcpath
);
88 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
89 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo" , rundir
, lxcpath
);
97 static void lxc_monitor_fifo_send ( struct lxc_msg
* msg
, const char * lxcpath
)
100 char fifo_path
[ PATH_MAX
];
102 BUILD_BUG_ON ( sizeof (* msg
) > PIPE_BUF
); /* write not guaranteed atomic */
104 ret
= lxc_monitor_fifo_name ( lxcpath
, fifo_path
, sizeof ( fifo_path
), 0 );
108 /* Open the fifo nonblock in case the monitor is dead, we don't want the
109 * open to wait for a reader since it may never come.
111 fd
= open ( fifo_path
, O_WRONLY
| O_NONBLOCK
);
113 /* It is normal for this open() to fail with ENXIO when there is
114 * no monitor running, so we don't log it.
116 if ( errno
== ENXIO
|| errno
== ENOENT
)
119 SYSWARN ( "Failed to open fifo to send message" );
123 if ( fcntl ( fd
, F_SETFL
, O_WRONLY
) < 0 ) {
128 ret
= lxc_write_nointr ( fd
, msg
, sizeof (* msg
));
129 if ( ret
!= sizeof (* msg
)) {
131 SYSERROR ( "Failed to write to monitor fifo \" %s \" " , fifo_path
);
138 void lxc_monitor_send_state ( const char * name
, lxc_state_t state
,
141 struct lxc_msg msg
= {. type
= lxc_msg_state
, . value
= state
};
143 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
144 lxc_monitor_fifo_send (& msg
, lxcpath
);
147 void lxc_monitor_send_exit_code ( const char * name
, int exit_code
,
150 struct lxc_msg msg
= {. type
= lxc_msg_exit_code
, . value
= exit_code
};
152 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
153 lxc_monitor_fifo_send (& msg
, lxcpath
);
156 /* routines used by monitor subscribers (lxc-monitor) */
157 int lxc_monitor_close ( int fd
)
162 /* Enforces \0-termination for the abstract unix socket. This is not required
163 * but allows us to print it out.
165 * Older version of liblxc only allowed for 105 bytes to be used for the
166 * abstract unix domain socket name because the code for our abstract unix
167 * socket handling performed invalid checks. Since we \0-terminate we could now
168 * have a maximum of 106 chars. But to not break backwards compatibility we keep
171 int lxc_monitor_sock_name ( const char * lxcpath
, struct sockaddr_un
* addr
)
178 /* addr.sun_path is only 108 bytes, so we hash the full name and
179 * then append as much of the name as we can fit.
181 memset ( addr
, 0 , sizeof (* addr
));
182 addr
-> sun_family
= AF_UNIX
;
184 /* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
185 len
= strlen ( lxcpath
) + 18 ;
187 ret
= snprintf ( path
, len
, "lxc/%s/monitor-sock" , lxcpath
);
188 if ( ret
< 0 || ( size_t ) ret
>= len
) {
189 ERROR ( "Failed to create name for monitor socket" );
193 /* Note: snprintf() will \0-terminate addr->sun_path on the 106th byte
194 * and so the abstract socket name has 105 "meaningful" characters. This
195 * is absolutely intentional. For further info read the comment for this
198 len
= sizeof ( addr
-> sun_path
) - 1 ;
199 hash
= fnv_64a_buf ( path
, ret
, FNV1A_64_INIT
);
200 ret
= snprintf ( addr
-> sun_path
, len
, "@lxc/%016" PRIx64
"/%s" , hash
, lxcpath
);
202 ERROR ( "Failed to create hashed name for monitor socket" );
204 } else if (( size_t ) ret
>= len
) {
205 errno
= ENAMETOOLONG
;
206 SYSERROR ( "The name of monitor socket too long (%d bytes)" , ret
);
210 /* replace @ with \0 */
211 addr
-> sun_path
[ 0 ] = '\0' ;
212 INFO ( "Using monitor socket name \" %s \" (length of socket name %zu must be <= %zu)" , & addr
-> sun_path
[ 1 ], strlen (& addr
-> sun_path
[ 1 ]), sizeof ( addr
-> sun_path
) - 3 );
220 int lxc_monitor_open ( const char * lxcpath
)
222 struct sockaddr_un addr
;
225 int backoff_ms
[] = { 10 , 50 , 100 };
227 if ( lxc_monitor_sock_name ( lxcpath
, & addr
) < 0 )
230 DEBUG ( "Opening monitor socket %s with len %zu" , & addr
. sun_path
[ 1 ], strlen (& addr
. sun_path
[ 1 ]));
232 for ( retry
= 0 ; retry
< sizeof ( backoff_ms
) / sizeof ( backoff_ms
[ 0 ]); retry
++) {
233 fd
= lxc_abstract_unix_connect ( addr
. sun_path
);
234 if ( fd
!= - 1 || errno
!= ECONNREFUSED
)
237 SYSERROR ( "Failed to connect to monitor socket. Retrying in %d ms" , backoff_ms
[ retry
]);
238 usleep ( backoff_ms
[ retry
] * 1000 );
242 SYSERROR ( "Failed to connect to monitor socket" );
249 int lxc_monitor_read_fdset ( struct pollfd
* fds
, nfds_t nfds
, struct lxc_msg
* msg
,
255 ret
= poll ( fds
, nfds
, timeout
* 1000 );
259 return - 2 ; /* timed out */
261 /* Only read from the first ready fd, the others will remain ready for
262 * when this routine is called again.
264 for ( i
= 0 ; i
< nfds
; i
++) {
265 if ( fds
[ i
]. revents
!= 0 ) {
267 ret
= recv ( fds
[ i
]. fd
, msg
, sizeof (* msg
), 0 );
269 SYSERROR ( "Failed to receive message. Did monitord die?" );
276 SYSERROR ( "No ready fd found" );
281 int lxc_monitor_read_timeout ( int fd
, struct lxc_msg
* msg
, int timeout
)
286 fds
. events
= POLLIN
| POLLPRI
;
289 return lxc_monitor_read_fdset (& fds
, 1 , msg
, timeout
);
292 int lxc_monitor_read ( int fd
, struct lxc_msg
* msg
)
294 return lxc_monitor_read_timeout ( fd
, msg
, - 1 );
297 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
299 /* Used to spawn a monitord either on startup of a daemon container, or when
300 * lxc-monitor starts.
302 int lxc_monitord_spawn ( const char * lxcpath
)
306 char pipefd_str
[ INTTYPE_TO_STRLEN ( int )];
309 char * const args
[] = {
316 /* double fork to avoid zombies when monitord exits */
319 SYSERROR ( "Failed to fork()" );
324 DEBUG ( "Going to wait for pid %d" , pid1
);
326 if ( waitpid ( pid1
, NULL
, 0 ) != pid1
)
329 DEBUG ( "Finished waiting on pid %d" , pid1
);
333 if ( pipe ( pipefd
) < 0 ) {
334 SYSERROR ( "Failed to create pipe" );
340 SYSERROR ( "Failed to fork()" );
345 DEBUG ( "Trying to sync with child process" );
347 /* Wait for daemon to create socket. */
350 /* Sync with child, we're ignoring the return from read
351 * because regardless if it works or not, either way we've
352 * synced with the child process. the if-empty-statement
353 * construct is to quiet the warn-unused-result warning.
355 if ( lxc_read_nointr ( pipefd
[ 0 ], & c
, 1 ))
360 DEBUG ( "Successfully synced with child process" );
365 SYSERROR ( "Failed to setsid()" );
369 lxc_check_inherited ( NULL
, true , & pipefd
[ 1 ], 1 );
370 if ( null_stdfds () < 0 ) {
371 SYSERROR ( "Failed to dup2() standard file descriptors to /dev/null" );
377 ret
= snprintf ( pipefd_str
, sizeof ( pipefd_str
), "%d" , pipefd
[ 1 ]);
378 if ( ret
< 0 || ret
>= sizeof ( pipefd_str
)) {
379 ERROR ( "Failed to create pid argument to pass to monitord" );
383 DEBUG ( "Using pipe file descriptor %d for monitord" , pipefd
[ 1 ]);
385 execvp ( args
[ 0 ], args
);
386 SYSERROR ( "Failed to exec lxc-monitord" );