]>
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
) {
177 /* addr.sun_path is only 108 bytes, so we hash the full name and
178 * then append as much of the name as we can fit.
180 memset ( addr
, 0 , sizeof (* addr
));
181 addr
-> sun_family
= AF_UNIX
;
183 /* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
184 len
= strlen ( lxcpath
) + 18 ;
186 ret
= snprintf ( path
, len
, "lxc/%s/monitor-sock" , lxcpath
);
187 if ( ret
< 0 || ( size_t ) ret
>= len
) {
188 ERROR ( "Failed to create name for monitor socket" );
192 /* Note: snprintf() will \0-terminate addr->sun_path on the 106th byte
193 * and so the abstract socket name has 105 "meaningful" characters. This
194 * is absolutely intentional. For further info read the comment for this
197 len
= sizeof ( addr
-> sun_path
) - 1 ;
198 hash
= fnv_64a_buf ( path
, ret
, FNV1A_64_INIT
);
199 ret
= snprintf ( addr
-> sun_path
, len
, "@lxc/%016" PRIx64
"/%s" , hash
, lxcpath
);
201 ERROR ( "Failed to create hashed name for monitor socket" );
205 /* replace @ with \0 */
206 addr
-> sun_path
[ 0 ] = '\0' ;
207 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 );
212 int lxc_monitor_open ( const char * lxcpath
)
214 struct sockaddr_un addr
;
218 int backoff_ms
[] = { 10 , 50 , 100 };
220 if ( lxc_monitor_sock_name ( lxcpath
, & addr
) < 0 )
223 len
= strlen (& addr
. sun_path
[ 1 ]);
224 DEBUG ( "Opening monitor socket %s with len %zu" , & addr
. sun_path
[ 1 ], len
);
225 if ( len
>= sizeof ( addr
. sun_path
) - 1 ) {
226 errno
= ENAMETOOLONG
;
227 SYSERROR ( "The name of monitor socket too long (%zu bytes)" , len
);
231 for ( retry
= 0 ; retry
< sizeof ( backoff_ms
) / sizeof ( backoff_ms
[ 0 ]); retry
++) {
232 fd
= lxc_abstract_unix_connect ( addr
. sun_path
);
233 if ( fd
!= - 1 || errno
!= ECONNREFUSED
)
236 SYSERROR ( "Failed to connect to monitor socket. Retrying in %d ms" , backoff_ms
[ retry
]);
237 usleep ( backoff_ms
[ retry
] * 1000 );
241 SYSERROR ( "Failed to connect to monitor socket" );
248 int lxc_monitor_read_fdset ( struct pollfd
* fds
, nfds_t nfds
, struct lxc_msg
* msg
,
254 ret
= poll ( fds
, nfds
, timeout
* 1000 );
258 return - 2 ; /* timed out */
260 /* Only read from the first ready fd, the others will remain ready for
261 * when this routine is called again.
263 for ( i
= 0 ; i
< nfds
; i
++) {
264 if ( fds
[ i
]. revents
!= 0 ) {
266 ret
= recv ( fds
[ i
]. fd
, msg
, sizeof (* msg
), 0 );
268 SYSERROR ( "Failed to receive message. Did monitord die?" );
275 SYSERROR ( "No ready fd found" );
280 int lxc_monitor_read_timeout ( int fd
, struct lxc_msg
* msg
, int timeout
)
285 fds
. events
= POLLIN
| POLLPRI
;
288 return lxc_monitor_read_fdset (& fds
, 1 , msg
, timeout
);
291 int lxc_monitor_read ( int fd
, struct lxc_msg
* msg
)
293 return lxc_monitor_read_timeout ( fd
, msg
, - 1 );
296 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
298 /* Used to spawn a monitord either on startup of a daemon container, or when
299 * lxc-monitor starts.
301 int lxc_monitord_spawn ( const char * lxcpath
)
305 char pipefd_str
[ INTTYPE_TO_STRLEN ( int )];
308 char * const args
[] = {
315 /* double fork to avoid zombies when monitord exits */
318 SYSERROR ( "Failed to fork()" );
323 DEBUG ( "Going to wait for pid %d" , pid1
);
325 if ( waitpid ( pid1
, NULL
, 0 ) != pid1
)
328 DEBUG ( "Finished waiting on pid %d" , pid1
);
332 if ( pipe ( pipefd
) < 0 ) {
333 SYSERROR ( "Failed to create pipe" );
339 SYSERROR ( "Failed to fork()" );
344 DEBUG ( "Trying to sync with child process" );
346 /* Wait for daemon to create socket. */
349 /* Sync with child, we're ignoring the return from read
350 * because regardless if it works or not, either way we've
351 * synced with the child process. the if-empty-statement
352 * construct is to quiet the warn-unused-result warning.
354 if ( lxc_read_nointr ( pipefd
[ 0 ], & c
, 1 ))
359 DEBUG ( "Successfully synced with child process" );
364 SYSERROR ( "Failed to setsid()" );
368 lxc_check_inherited ( NULL
, true , & pipefd
[ 1 ], 1 );
369 if ( null_stdfds () < 0 ) {
370 SYSERROR ( "Failed to dup2() standard file descriptors to /dev/null" );
376 ret
= snprintf ( pipefd_str
, sizeof ( pipefd_str
), "%d" , pipefd
[ 1 ]);
377 if ( ret
< 0 || ret
>= sizeof ( pipefd_str
)) {
378 ERROR ( "Failed to create pid argument to pass to monitord" );
382 DEBUG ( "Using pipe file descriptor %d for monitord" , pipefd
[ 1 ]);
384 execvp ( args
[ 0 ], args
);
385 SYSERROR ( "Failed to exec lxc-monitord" );