2007-02-10 12:43:58 +03:00
/*
2007-10-16 12:27:08 +04:00
* Copyright ( C ) 2002 - 2007 Jeff Dike ( jdike @ { addtoit , linux . intel } . com )
2005-04-17 02:20:36 +04:00
* Licensed under the GPL
*/
# include <stdio.h>
# include <unistd.h>
# include <errno.h>
# include "os.h"
struct dog_data {
int stdin ;
int stdout ;
int close_me [ 2 ] ;
} ;
static void pre_exec ( void * d )
{
struct dog_data * data = d ;
dup2 ( data - > stdin , 0 ) ;
dup2 ( data - > stdout , 1 ) ;
dup2 ( data - > stdout , 2 ) ;
2007-10-16 12:27:08 +04:00
close ( data - > stdin ) ;
close ( data - > stdout ) ;
close ( data - > close_me [ 0 ] ) ;
close ( data - > close_me [ 1 ] ) ;
2005-04-17 02:20:36 +04:00
}
int start_watchdog ( int * in_fd_ret , int * out_fd_ret , char * sock )
{
struct dog_data data ;
int in_fds [ 2 ] , out_fds [ 2 ] , pid , n , err ;
2011-07-26 04:12:55 +04:00
char pid_buf [ sizeof ( " nnnnnnn \0 " ) ] , c ;
2005-04-17 02:20:36 +04:00
char * pid_args [ ] = { " /usr/bin/uml_watchdog " , " -pid " , pid_buf , NULL } ;
2007-02-10 12:43:58 +03:00
char * mconsole_args [ ] = { " /usr/bin/uml_watchdog " , " -mconsole " , NULL ,
2005-04-17 02:20:36 +04:00
NULL } ;
char * * args = NULL ;
err = os_pipe ( in_fds , 1 , 0 ) ;
2007-10-16 12:27:08 +04:00
if ( err < 0 ) {
2005-04-17 02:20:36 +04:00
printk ( " harddog_open - os_pipe failed, err = %d \n " , - err ) ;
goto out ;
}
err = os_pipe ( out_fds , 1 , 0 ) ;
2007-10-16 12:27:08 +04:00
if ( err < 0 ) {
2005-04-17 02:20:36 +04:00
printk ( " harddog_open - os_pipe failed, err = %d \n " , - err ) ;
goto out_close_in ;
}
data . stdin = out_fds [ 0 ] ;
data . stdout = in_fds [ 1 ] ;
data . close_me [ 0 ] = out_fds [ 1 ] ;
data . close_me [ 1 ] = in_fds [ 0 ] ;
2007-10-16 12:27:08 +04:00
if ( sock ! = NULL ) {
2005-04-17 02:20:36 +04:00
mconsole_args [ 2 ] = sock ;
args = mconsole_args ;
}
else {
/* XXX The os_getpid() is not SMP correct */
2007-10-16 12:26:56 +04:00
sprintf ( pid_buf , " %d " , os_getpid ( ) ) ;
2005-04-17 02:20:36 +04:00
args = pid_args ;
}
2007-07-16 10:38:56 +04:00
pid = run_helper ( pre_exec , & data , args ) ;
2005-04-17 02:20:36 +04:00
2007-10-16 12:27:08 +04:00
close ( out_fds [ 0 ] ) ;
close ( in_fds [ 1 ] ) ;
2005-04-17 02:20:36 +04:00
2007-10-16 12:27:08 +04:00
if ( pid < 0 ) {
2005-04-17 02:20:36 +04:00
err = - pid ;
printk ( " harddog_open - run_helper failed, errno = %d \n " , - err ) ;
goto out_close_out ;
}
2007-10-16 12:27:08 +04:00
n = read ( in_fds [ 0 ] , & c , sizeof ( c ) ) ;
if ( n = = 0 ) {
2005-04-17 02:20:36 +04:00
printk ( " harddog_open - EOF on watchdog pipe \n " ) ;
2008-02-24 02:23:49 +03:00
helper_wait ( pid ) ;
2005-04-17 02:20:36 +04:00
err = - EIO ;
goto out_close_out ;
}
2007-10-16 12:27:08 +04:00
else if ( n < 0 ) {
2005-04-17 02:20:36 +04:00
printk ( " harddog_open - read of watchdog pipe failed, "
2007-10-16 12:27:08 +04:00
" err = %d \n " , errno ) ;
2008-02-24 02:23:49 +03:00
helper_wait ( pid ) ;
2005-04-17 02:20:36 +04:00
err = n ;
goto out_close_out ;
}
* in_fd_ret = in_fds [ 0 ] ;
* out_fd_ret = out_fds [ 1 ] ;
2007-02-10 12:43:58 +03:00
return 0 ;
2005-04-17 02:20:36 +04:00
out_close_in :
2007-10-16 12:27:08 +04:00
close ( in_fds [ 0 ] ) ;
close ( in_fds [ 1 ] ) ;
2005-04-17 02:20:36 +04:00
out_close_out :
2007-10-16 12:27:08 +04:00
close ( out_fds [ 0 ] ) ;
close ( out_fds [ 1 ] ) ;
2005-04-17 02:20:36 +04:00
out :
2007-02-10 12:43:58 +03:00
return err ;
2005-04-17 02:20:36 +04:00
}
void stop_watchdog ( int in_fd , int out_fd )
{
2007-10-16 12:27:08 +04:00
close ( in_fd ) ;
close ( out_fd ) ;
2005-04-17 02:20:36 +04:00
}
int ping_watchdog ( int fd )
{
int n ;
char c = ' \n ' ;
2007-10-16 12:27:08 +04:00
n = write ( fd , & c , sizeof ( c ) ) ;
if ( n ! = sizeof ( c ) ) {
printk ( " ping_watchdog - write failed, ret = %d, err = %d \n " ,
n , errno ) ;
if ( n < 0 )
2007-02-10 12:43:58 +03:00
return n ;
return - EIO ;
2005-04-17 02:20:36 +04:00
}
return 1 ;
}