]>
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>
54 #include "include/strlcpy.h"
57 lxc_log_define ( monitor
, lxc
);
59 /* routines used by monitor publishers (containers) */
60 int lxc_monitor_fifo_name ( const char * lxcpath
, char * fifo_path
, size_t fifo_path_sz
,
66 rundir
= get_rundir ();
71 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s" , rundir
, lxcpath
);
72 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
73 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo." , rundir
, lxcpath
);
77 ret
= mkdir_p ( fifo_path
, 0755 );
79 ERROR ( "Unable to create monitor fifo directory %s." , fifo_path
);
84 ret
= snprintf ( fifo_path
, fifo_path_sz
, "%s/lxc/%s/monitor-fifo" , rundir
, lxcpath
);
85 if ( ret
< 0 || ( size_t ) ret
>= fifo_path_sz
) {
86 ERROR ( "rundir/lxcpath (%s/%s) too long for monitor fifo." , rundir
, lxcpath
);
94 static void lxc_monitor_fifo_send ( struct lxc_msg
* msg
, const char * lxcpath
)
97 char fifo_path
[ PATH_MAX
];
99 BUILD_BUG_ON ( sizeof (* msg
) > PIPE_BUF
); /* write not guaranteed atomic */
101 ret
= lxc_monitor_fifo_name ( lxcpath
, fifo_path
, sizeof ( fifo_path
), 0 );
105 /* Open the fifo nonblock in case the monitor is dead, we don't want the
106 * open to wait for a reader since it may never come.
108 fd
= open ( fifo_path
, O_WRONLY
| O_NONBLOCK
);
110 /* It is normal for this open() to fail with ENXIO when there is
111 * no monitor running, so we don't log it.
113 if ( errno
== ENXIO
|| errno
== ENOENT
)
116 SYSWARN ( "Failed to open fifo to send message" );
120 if ( fcntl ( fd
, F_SETFL
, O_WRONLY
) < 0 ) {
125 ret
= lxc_write_nointr ( fd
, msg
, sizeof (* msg
));
126 if ( ret
!= sizeof (* msg
)) {
128 SYSERROR ( "Failed to write to monitor fifo \" %s \" ." , fifo_path
);
135 void lxc_monitor_send_state ( const char * name
, lxc_state_t state
,
138 struct lxc_msg msg
= {. type
= lxc_msg_state
, . value
= state
};
140 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
141 lxc_monitor_fifo_send (& msg
, lxcpath
);
144 void lxc_monitor_send_exit_code ( const char * name
, int exit_code
,
147 struct lxc_msg msg
= {. type
= lxc_msg_exit_code
, . value
= exit_code
};
149 ( void ) strlcpy ( msg
. name
, name
, sizeof ( msg
. name
));
150 lxc_monitor_fifo_send (& msg
, lxcpath
);
153 /* routines used by monitor subscribers (lxc-monitor) */
154 int lxc_monitor_close ( int fd
)
159 /* Enforces \0-termination for the abstract unix socket. This is not required
160 * but allows us to print it out.
162 * Older version of liblxc only allowed for 105 bytes to be used for the
163 * abstract unix domain socket name because the code for our abstract unix
164 * socket handling performed invalid checks. Since we \0-terminate we could now
165 * have a maximum of 106 chars. But to not break backwards compatibility we keep
168 int lxc_monitor_sock_name ( const char * lxcpath
, struct sockaddr_un
* addr
) {
174 /* addr.sun_path is only 108 bytes, so we hash the full name and
175 * then append as much of the name as we can fit.
177 memset ( addr
, 0 , sizeof (* addr
));
178 addr
-> sun_family
= AF_UNIX
;
180 /* strlen("lxc/") + strlen("/monitor-sock") + 1 = 18 */
181 len
= strlen ( lxcpath
) + 18 ;
183 ret
= snprintf ( path
, len
, "lxc/%s/monitor-sock" , lxcpath
);
184 if ( ret
< 0 || ( size_t ) ret
>= len
) {
185 ERROR ( "failed to create name for monitor socket" );
189 /* Note: snprintf() will \0-terminate addr->sun_path on the 106th byte
190 * and so the abstract socket name has 105 "meaningful" characters. This
191 * is absolutely intentional. For further info read the comment for this
194 len
= sizeof ( addr
-> sun_path
) - 1 ;
195 hash
= fnv_64a_buf ( path
, ret
, FNV1A_64_INIT
);
196 ret
= snprintf ( addr
-> sun_path
, len
, "@lxc/%016" PRIx64
"/%s" , hash
, lxcpath
);
198 ERROR ( "failed to create hashed name for monitor socket" );
202 /* replace @ with \0 */
203 addr
-> sun_path
[ 0 ] = '\0' ;
204 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 );
209 int lxc_monitor_open ( const char * lxcpath
)
211 struct sockaddr_un addr
;
215 int backoff_ms
[] = { 10 , 50 , 100 };
217 if ( lxc_monitor_sock_name ( lxcpath
, & addr
) < 0 )
220 len
= strlen (& addr
. sun_path
[ 1 ]);
221 DEBUG ( "opening monitor socket %s with len %zu" , & addr
. sun_path
[ 1 ], len
);
222 if ( len
>= sizeof ( addr
. sun_path
) - 1 ) {
223 errno
= ENAMETOOLONG
;
224 SYSERROR ( "The name of monitor socket too long (%zu bytes)" , len
);
228 for ( retry
= 0 ; retry
< sizeof ( backoff_ms
) / sizeof ( backoff_ms
[ 0 ]); retry
++) {
229 fd
= lxc_abstract_unix_connect ( addr
. sun_path
);
230 if ( fd
!= - 1 || errno
!= ECONNREFUSED
)
233 SYSERROR ( "Failed to connect to monitor socket. Retrying in %d ms" , backoff_ms
[ retry
]);
234 usleep ( backoff_ms
[ retry
] * 1000 );
238 SYSERROR ( "Failed to connect to monitor socket" );
245 int lxc_monitor_read_fdset ( struct pollfd
* fds
, nfds_t nfds
, struct lxc_msg
* msg
,
251 ret
= poll ( fds
, nfds
, timeout
* 1000 );
255 return - 2 ; /* timed out */
257 /* Only read from the first ready fd, the others will remain ready for
258 * when this routine is called again.
260 for ( i
= 0 ; i
< nfds
; i
++) {
261 if ( fds
[ i
]. revents
!= 0 ) {
263 ret
= recv ( fds
[ i
]. fd
, msg
, sizeof (* msg
), 0 );
265 SYSERROR ( "Failed to receive message. Did monitord die?" );
272 SYSERROR ( "No ready fd found." );
277 int lxc_monitor_read_timeout ( int fd
, struct lxc_msg
* msg
, int timeout
)
282 fds
. events
= POLLIN
| POLLPRI
;
285 return lxc_monitor_read_fdset (& fds
, 1 , msg
, timeout
);
288 int lxc_monitor_read ( int fd
, struct lxc_msg
* msg
)
290 return lxc_monitor_read_timeout ( fd
, msg
, - 1 );
293 #define LXC_MONITORD_PATH LIBEXECDIR "/lxc/lxc-monitord"
295 /* Used to spawn a monitord either on startup of a daemon container, or when
296 * lxc-monitor starts.
298 int lxc_monitord_spawn ( const char * lxcpath
)
302 char pipefd_str
[ LXC_NUMSTRLEN64
];
305 char * const args
[] = {
312 /* double fork to avoid zombies when monitord exits */
315 SYSERROR ( "Failed to fork()." );
320 DEBUG ( "Going to wait for pid %d." , pid1
);
322 if ( waitpid ( pid1
, NULL
, 0 ) != pid1
)
325 DEBUG ( "Finished waiting on pid %d." , pid1
);
329 if ( pipe ( pipefd
) < 0 ) {
330 SYSERROR ( "Failed to create pipe." );
336 SYSERROR ( "Failed to fork()." );
341 DEBUG ( "Trying to sync with child process." );
343 /* Wait for daemon to create socket. */
346 /* Sync with child, we're ignoring the return from read
347 * because regardless if it works or not, either way we've
348 * synced with the child process. the if-empty-statement
349 * construct is to quiet the warn-unused-result warning.
351 if ( lxc_read_nointr ( pipefd
[ 0 ], & c
, 1 ))
356 DEBUG ( "Successfully synced with child process." );
361 SYSERROR ( "Failed to setsid()." );
365 lxc_check_inherited ( NULL
, true , & pipefd
[ 1 ], 1 );
366 if ( null_stdfds () < 0 ) {
367 SYSERROR ( "Failed to dup2() standard file descriptors to /dev/null." );
373 ret
= snprintf ( pipefd_str
, LXC_NUMSTRLEN64
, "%d" , pipefd
[ 1 ]);
374 if ( ret
< 0 || ret
>= LXC_NUMSTRLEN64
) {
375 ERROR ( "Failed to create pid argument to pass to monitord." );
379 DEBUG ( "Using pipe file descriptor %d for monitord." , pipefd
[ 1 ]);
381 execvp ( args
[ 0 ], args
);
382 SYSERROR ( "failed to exec lxc-monitord" );