]>
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
37 #include <netinet/in.h>
38 #include <sys/param.h>
39 #include <sys/socket.h>
41 #include <sys/types.h>
55 #include "include/strlcpy.h"
58 lxc_log_define ( monitor
, lxc
);
60 /* routines used by monitor publishers (containers) */
61 int lxc_monitor_fifo_name ( const char * lxcpath
, char * fifo_path
, size_t fifo_path_sz
,
67 rundir
= get_rundir ();
72 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s" , rundir
, lxcpath
);
73 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
74 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo." , rundir
, lxcpath
);
78 ret
= mkdir_p ( fifo_path
, 0755 );
80 ERROR ( "Unable to create monitor fifo directory %s." , fifo_path
);
85 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s/monitor-fifo" , rundir
, lxcpath
);
86 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
87 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo." , rundir
, lxcpath
);
95 static void lxc_monitor_fifo_send ( struct lxc_msg
* msg
, const char * lxcpath
)
98 char fifo_path
[ PATH_MAX
];
100 BUILD_BUG_ON ( sizeof (* msg
) > PIPE_BUF
); /* write not guaranteed atomic */
102 ret
= lxc_monitor_fifo_name ( lxcpath
, fifo_path
, sizeof ( fifo_path
), 0 );
106 /* Open the fifo nonblock in case the monitor is dead, we don't want the
107 * open to wait for a reader since it may never come.
109 fd
= open ( fifo_path
, O_WRONLY
| O_NONBLOCK
);
111 /* It is normal for this open() to fail with ENXIO when there is
112 * no monitor running, so we don't log it.
114 if ( errno
== ENXIO
|| errno
== ENOENT
)
117 SYSWARN ( "Failed to open fifo to send message" );
121 if ( fcntl ( fd
, F_SETFL
, O_WRONLY
) < 0 ) {
126 ret
= lxc_write_nointr ( fd
, msg
, sizeof (* msg
));
127 if ( ret
!= sizeof (* msg
)) {
129 SYSERROR ( "Failed to write to monitor fifo \" %s \" ." , fifo_path
);
136 void lxc_monitor_send_state ( const char * name
, lxc_state_t state
,
139 struct lxc_msg msg
= {. type
= lxc_msg_state
, . value
= state
};
141 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
142 lxc_monitor_fifo_send (& msg
, lxcpath
);
145 void lxc_monitor_send_exit_code ( const char * name
, int exit_code
,
148 struct lxc_msg msg
= {. type
= lxc_msg_exit_code
, . value
= exit_code
};
150 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
151 lxc_monitor_fifo_send (& msg
, lxcpath
);
154 /* routines used by monitor subscribers (lxc-monitor) */
155 int lxc_monitor_close ( int fd
)
160 /* Enforces \0-termination for the abstract unix socket. This is not required
161 * but allows us to print it out.
163 * Older version of liblxc only allowed for 105 bytes to be used for the
164 * abstract unix domain socket name because the code for our abstract unix
165 * socket handling performed invalid checks. Since we \0-terminate we could now
166 * have a maximum of 106 chars. But to not break backwards compatibility we keep
169 int lxc_monitor_sock_name ( const char * lxcpath
, struct sockaddr_un
* addr
) {
175 /* addr.sun_path is only 108 bytes, so we hash the full name and
176 * then append as much of the name as we can fit.
178 memset ( addr
, 0 , sizeof (* addr
));
179 addr
-> sun_family
= AF_UNIX
;
181 /* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
182 len
= strlen ( lxcpath
) + 18 ;
184 ret
= snprintf ( path
, len
, "lxc/%s/monitor-sock" , lxcpath
);
185 if ( ret
< 0 || ( size_t ) ret
>= len
) {
186 ERROR ( "failed to create name for monitor socket" );
190 /* Note: snprintf() will \0-terminate addr->sun_path on the 106th byte
191 * and so the abstract socket name has 105 "meaningful" characters. This
192 * is absolutely intentional. For further info read the comment for this
195 len
= sizeof ( addr
-> sun_path
) - 1 ;
196 hash
= fnv_64a_buf ( path
, ret
, FNV1A_64_INIT
);
197 ret
= snprintf ( addr
-> sun_path
, len
, "@lxc/%016" PRIx64
"/%s" , hash
, lxcpath
);
199 ERROR ( "failed to create hashed name for monitor socket" );
203 /* replace @ with \0 */
204 addr
-> sun_path
[ 0 ] = '\0' ;
205 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 );
210 int lxc_monitor_open ( const char * lxcpath
)
212 struct sockaddr_un addr
;
216 int backoff_ms
[] = { 10 , 50 , 100 };
218 if ( lxc_monitor_sock_name ( lxcpath
, & addr
) < 0 )
221 len
= strlen (& addr
. sun_path
[ 1 ]);
222 DEBUG ( "opening monitor socket %s with len %zu" , & addr
. sun_path
[ 1 ], len
);
223 if ( len
>= sizeof ( addr
. sun_path
) - 1 ) {
224 errno
= ENAMETOOLONG
;
225 SYSERROR ( "The name of monitor socket too long (%zu bytes)" , len
);
229 for ( retry
= 0 ; retry
< sizeof ( backoff_ms
) / sizeof ( backoff_ms
[ 0 ]); retry
++) {
230 fd
= lxc_abstract_unix_connect ( addr
. sun_path
);
231 if ( fd
!= - 1 || errno
!= ECONNREFUSED
)
234 SYSERROR ( "Failed to connect to monitor socket. Retrying in %d ms" , backoff_ms
[ retry
]);
235 usleep ( backoff_ms
[ retry
] * 1000 );
239 SYSERROR ( "Failed to connect to monitor socket" );
246 int lxc_monitor_read_fdset ( struct pollfd
* fds
, nfds_t nfds
, struct lxc_msg
* msg
,
252 ret
= poll ( fds
, nfds
, timeout
* 1000 );
256 return - 2 ; /* timed out */
258 /* Only read from the first ready fd, the others will remain ready for
259 * when this routine is called again.
261 for ( i
= 0 ; i
< nfds
; i
++) {
262 if ( fds
[ i
]. revents
!= 0 ) {
264 ret
= recv ( fds
[ i
]. fd
, msg
, sizeof (* msg
), 0 );
266 SYSERROR ( "Failed to receive message. Did monitord die?" );
273 SYSERROR ( "No ready fd found." );
278 int lxc_monitor_read_timeout ( int fd
, struct lxc_msg
* msg
, int timeout
)
283 fds
. events
= POLLIN
| POLLPRI
;
286 return lxc_monitor_read_fdset (& fds
, 1 , msg
, timeout
);
289 int lxc_monitor_read ( int fd
, struct lxc_msg
* msg
)
291 return lxc_monitor_read_timeout ( fd
, msg
, - 1 );
294 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
296 /* Used to spawn a monitord either on startup of a daemon container, or when
297 * lxc-monitor starts.
299 int lxc_monitord_spawn ( const char * lxcpath
)
303 char pipefd_str
[ INTTYPE_TO_STRLEN ( int )];
306 char * const args
[] = {
313 /* double fork to avoid zombies when monitord exits */
316 SYSERROR ( "Failed to fork()." );
321 DEBUG ( "Going to wait for pid %d." , pid1
);
323 if ( waitpid ( pid1
, NULL
, 0 ) != pid1
)
326 DEBUG ( "Finished waiting on pid %d." , pid1
);
330 if ( pipe ( pipefd
) < 0 ) {
331 SYSERROR ( "Failed to create pipe." );
337 SYSERROR ( "Failed to fork()." );
342 DEBUG ( "Trying to sync with child process." );
344 /* Wait for daemon to create socket. */
347 /* Sync with child, we're ignoring the return from read
348 * because regardless if it works or not, either way we've
349 * synced with the child process. the if-empty-statement
350 * construct is to quiet the warn-unused-result warning.
352 if ( lxc_read_nointr ( pipefd
[ 0 ], & c
, 1 ))
357 DEBUG ( "Successfully synced with child process." );
362 SYSERROR ( "Failed to setsid()." );
366 lxc_check_inherited ( NULL
, true , & pipefd
[ 1 ], 1 );
367 if ( null_stdfds () < 0 ) {
368 SYSERROR ( "Failed to dup2() standard file descriptors to /dev/null." );
374 ret
= snprintf ( pipefd_str
, sizeof ( pipefd_str
), "%d" , pipefd
[ 1 ]);
375 if ( ret
< 0 || ret
>= sizeof ( pipefd_str
)) {
376 ERROR ( "Failed to create pid argument to pass to monitord." );
380 DEBUG ( "Using pipe file descriptor %d for monitord." , pipefd
[ 1 ]);
382 execvp ( args
[ 0 ], args
);
383 SYSERROR ( "failed to exec lxc-monitord" );