]>
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>
52 #include "memory_utils.h"
58 #include "include/strlcpy.h"
61 lxc_log_define ( monitor
, lxc
);
63 /* routines used by monitor publishers (containers) */
64 int lxc_monitor_fifo_name ( const char * lxcpath
, char * fifo_path
, size_t fifo_path_sz
,
70 rundir
= get_rundir ();
75 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s" , rundir
, lxcpath
);
76 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
77 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo" , rundir
, lxcpath
);
81 ret
= mkdir_p ( fifo_path
, 0755 );
83 ERROR ( "Unable to create monitor fifo directory %s" , fifo_path
);
88 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s/monitor-fifo" , rundir
, lxcpath
);
89 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
90 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo" , rundir
, lxcpath
);
98 static void lxc_monitor_fifo_send ( struct lxc_msg
* msg
, const char * lxcpath
)
101 char fifo_path
[ PATH_MAX
];
103 BUILD_BUG_ON ( sizeof (* msg
) > PIPE_BUF
); /* write not guaranteed atomic */
105 ret
= lxc_monitor_fifo_name ( lxcpath
, fifo_path
, sizeof ( fifo_path
), 0 );
109 /* Open the fifo nonblock in case the monitor is dead, we don't want the
110 * open to wait for a reader since it may never come.
112 fd
= open ( fifo_path
, O_WRONLY
| O_NONBLOCK
);
114 /* It is normal for this open() to fail with ENXIO when there is
115 * no monitor running, so we don't log it.
117 if ( errno
== ENXIO
|| errno
== ENOENT
)
120 SYSWARN ( "Failed to open fifo to send message" );
124 if ( fcntl ( fd
, F_SETFL
, O_WRONLY
) < 0 ) {
129 ret
= lxc_write_nointr ( fd
, msg
, sizeof (* msg
));
130 if ( ret
!= sizeof (* msg
)) {
132 SYSERROR ( "Failed to write to monitor fifo \" %s \" " , fifo_path
);
139 void lxc_monitor_send_state ( const char * name
, lxc_state_t state
,
142 struct lxc_msg msg
= {. type
= lxc_msg_state
, . value
= state
};
144 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
145 lxc_monitor_fifo_send (& msg
, lxcpath
);
148 void lxc_monitor_send_exit_code ( const char * name
, int exit_code
,
151 struct lxc_msg msg
= {. type
= lxc_msg_exit_code
, . value
= exit_code
};
153 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
154 lxc_monitor_fifo_send (& msg
, lxcpath
);
157 /* routines used by monitor subscribers (lxc-monitor) */
158 int lxc_monitor_close ( int fd
)
163 /* Enforces \0-termination for the abstract unix socket. This is not required
164 * but allows us to print it out.
166 * Older version of liblxc only allowed for 105 bytes to be used for the
167 * abstract unix domain socket name because the code for our abstract unix
168 * socket handling performed invalid checks. Since we \0-terminate we could now
169 * have a maximum of 106 chars. But to not break backwards compatibility we keep
172 int lxc_monitor_sock_name ( const char * lxcpath
, struct sockaddr_un
* addr
)
174 __do_free
char * path
= NULL
;
179 /* addr.sun_path is only 108 bytes, so we hash the full name and
180 * then append as much of the name as we can fit.
182 memset ( addr
, 0 , sizeof (* addr
));
183 addr
-> sun_family
= AF_UNIX
;
185 /* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
186 len
= strlen ( lxcpath
) + 18 ;
187 path
= must_realloc ( NULL
, len
);
188 ret
= snprintf ( path
, len
, "lxc/%s/monitor-sock" , lxcpath
);
189 if ( ret
< 0 || ( size_t ) ret
>= len
) {
190 ERROR ( "Failed to create name for monitor socket" );
194 /* Note: snprintf() will \0-terminate addr->sun_path on the 106th byte
195 * and so the abstract socket name has 105 "meaningful" characters. This
196 * is absolutely intentional. For further info read the comment for this
199 len
= sizeof ( addr
-> sun_path
) - 1 ;
200 hash
= fnv_64a_buf ( path
, ret
, FNV1A_64_INIT
);
201 ret
= snprintf ( addr
-> sun_path
, len
, "@lxc/%016" PRIx64
"/%s" , hash
, lxcpath
);
203 ERROR ( "Failed to create hashed name for monitor socket" );
205 } else if (( size_t ) ret
>= len
) {
206 errno
= ENAMETOOLONG
;
207 SYSERROR ( "The name of monitor socket too long (%d bytes)" , ret
);
211 /* replace @ with \0 */
212 addr
-> sun_path
[ 0 ] = '\0' ;
213 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 );
221 int lxc_monitor_open ( const char * lxcpath
)
223 struct sockaddr_un addr
;
226 int backoff_ms
[] = { 10 , 50 , 100 };
228 if ( lxc_monitor_sock_name ( lxcpath
, & addr
) < 0 )
231 DEBUG ( "Opening monitor socket %s with len %zu" , & addr
. sun_path
[ 1 ], strlen (& addr
. sun_path
[ 1 ]));
233 for ( retry
= 0 ; retry
< sizeof ( backoff_ms
) / sizeof ( backoff_ms
[ 0 ]); retry
++) {
234 fd
= lxc_abstract_unix_connect ( addr
. sun_path
);
235 if ( fd
!= - 1 || errno
!= ECONNREFUSED
)
238 SYSERROR ( "Failed to connect to monitor socket. Retrying in %d ms" , backoff_ms
[ retry
]);
239 usleep ( backoff_ms
[ retry
] * 1000 );
243 SYSERROR ( "Failed to connect to monitor socket" );
250 int lxc_monitor_read_fdset ( struct pollfd
* fds
, nfds_t nfds
, struct lxc_msg
* msg
,
256 ret
= poll ( fds
, nfds
, timeout
* 1000 );
260 return - 2 ; /* timed out */
262 /* Only read from the first ready fd, the others will remain ready for
263 * when this routine is called again.
265 for ( i
= 0 ; i
< nfds
; i
++) {
266 if ( fds
[ i
]. revents
!= 0 ) {
268 ret
= recv ( fds
[ i
]. fd
, msg
, sizeof (* msg
), 0 );
270 SYSERROR ( "Failed to receive message. Did monitord die?" );
277 SYSERROR ( "No ready fd found" );
282 int lxc_monitor_read_timeout ( int fd
, struct lxc_msg
* msg
, int timeout
)
287 fds
. events
= POLLIN
| POLLPRI
;
290 return lxc_monitor_read_fdset (& fds
, 1 , msg
, timeout
);
293 int lxc_monitor_read ( int fd
, struct lxc_msg
* msg
)
295 return lxc_monitor_read_timeout ( fd
, msg
, - 1 );
298 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
300 /* Used to spawn a monitord either on startup of a daemon container, or when
301 * lxc-monitor starts.
303 int lxc_monitord_spawn ( const char * lxcpath
)
307 char pipefd_str
[ INTTYPE_TO_STRLEN ( int )];
310 char * const args
[] = {
317 /* double fork to avoid zombies when monitord exits */
320 SYSERROR ( "Failed to fork()" );
325 DEBUG ( "Going to wait for pid %d" , pid1
);
327 if ( waitpid ( pid1
, NULL
, 0 ) != pid1
)
330 DEBUG ( "Finished waiting on pid %d" , pid1
);
334 if ( pipe ( pipefd
) < 0 ) {
335 SYSERROR ( "Failed to create pipe" );
341 SYSERROR ( "Failed to fork()" );
346 DEBUG ( "Trying to sync with child process" );
348 /* Wait for daemon to create socket. */
351 /* Sync with child, we're ignoring the return from read
352 * because regardless if it works or not, either way we've
353 * synced with the child process. the if-empty-statement
354 * construct is to quiet the warn-unused-result warning.
356 if ( lxc_read_nointr ( pipefd
[ 0 ], & c
, 1 ))
361 DEBUG ( "Successfully synced with child process" );
366 SYSERROR ( "Failed to setsid()" );
370 lxc_check_inherited ( NULL
, true , & pipefd
[ 1 ], 1 );
371 if ( null_stdfds () < 0 ) {
372 SYSERROR ( "Failed to dup2() standard file descriptors to /dev/null" );
378 ret
= snprintf ( pipefd_str
, sizeof ( pipefd_str
), "%d" , pipefd
[ 1 ]);
379 if ( ret
< 0 || ret
>= sizeof ( pipefd_str
)) {
380 ERROR ( "Failed to create pid argument to pass to monitord" );
384 DEBUG ( "Using pipe file descriptor %d for monitord" , pipefd
[ 1 ]);
386 execvp ( args
[ 0 ], args
);
387 SYSERROR ( "Failed to exec lxc-monitord" );