2005-10-17 21:56:27 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2011-01-13 17:51:32 +03:00
* Copyright ( C ) 2004 - 2011 Red Hat , Inc . All rights reserved .
2005-10-17 21:56:27 +04:00
*
* This file is part of LVM2 .
*
* This copyrighted material is made available to anyone wishing to use ,
* modify , copy , or redistribute it subject to the terms and conditions
2007-08-21 00:55:30 +04:00
* of the GNU Lesser General Public License v .2 .1 .
2005-10-17 21:56:27 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2005-10-17 21:56:27 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include "lib.h"
2009-02-28 03:54:06 +03:00
# include "device.h"
# include "locking.h"
2005-10-17 21:56:27 +04:00
# include "lvm-exec.h"
2009-02-28 03:54:06 +03:00
# include "toolcontext.h"
2011-01-10 22:49:42 +03:00
# include "activate.h"
2005-10-17 21:56:27 +04:00
# include <unistd.h>
# include <sys/wait.h>
2009-02-24 18:48:00 +03:00
/*
* Create verbose string with list of parameters
*/
2009-02-28 02:40:11 +03:00
static char * _verbose_args ( const char * const argv [ ] , char * buf , size_t sz )
2009-02-24 18:48:00 +03:00
{
int pos = 0 ;
2009-02-28 02:40:11 +03:00
int len ;
unsigned i ;
2009-02-24 18:48:00 +03:00
2009-02-28 02:40:11 +03:00
buf [ 0 ] = ' \0 ' ;
for ( i = 0 ; argv [ i ] ; i + + ) {
if ( ( len = dm_snprintf ( buf + pos , sz - pos ,
" %s " , argv [ i ] ) ) < 0 )
/* Truncated */
break ;
2009-02-24 18:48:00 +03:00
pos + = len ;
}
return buf ;
}
2005-10-17 21:56:27 +04:00
/*
* Execute and wait for external command
*/
2011-01-13 17:51:32 +03:00
int exec_cmd ( struct cmd_context * cmd , const char * const argv [ ] ,
int * rstatus , int sync_needed )
2005-10-17 21:56:27 +04:00
{
pid_t pid ;
int status ;
2009-02-28 02:40:11 +03:00
char buf [ PATH_MAX * 2 ] ;
2005-10-17 21:56:27 +04:00
2011-01-13 17:51:32 +03:00
if ( rstatus )
* rstatus = - 1 ;
if ( sync_needed )
if ( ! sync_local_dev_names ( cmd ) ) /* Flush ops and reset dm cookie */
return_0 ;
2011-01-10 22:31:02 +03:00
2011-09-19 16:48:02 +04:00
log_verbose ( " Executing: %s " , _verbose_args ( argv , buf , sizeof ( buf ) ) ) ;
2005-10-17 21:56:27 +04:00
if ( ( pid = fork ( ) ) = = - 1 ) {
log_error ( " fork failed: %s " , strerror ( errno ) ) ;
return 0 ;
}
if ( ! pid ) {
/* Child */
2009-02-28 03:54:06 +03:00
reset_locking ( ) ;
dev_close_all ( ) ;
/* FIXME Fix effect of reset_locking on cache then include this */
/* destroy_toolcontext(cmd); */
2005-10-17 21:56:27 +04:00
/* FIXME Use execve directly */
2011-08-04 18:30:51 +04:00
execvp ( argv [ 0 ] , ( char * * ) argv ) ;
2009-02-24 18:48:00 +03:00
log_sys_error ( " execvp " , argv [ 0 ] ) ;
2009-07-14 01:26:41 +04:00
_exit ( errno ) ;
2005-10-17 21:56:27 +04:00
}
/* Parent */
if ( wait4 ( pid , & status , 0 , NULL ) ! = pid ) {
log_error ( " wait4 child process %u failed: %s " , pid ,
strerror ( errno ) ) ;
return 0 ;
}
if ( ! WIFEXITED ( status ) ) {
log_error ( " Child %u exited abnormally " , pid ) ;
return 0 ;
}
if ( WEXITSTATUS ( status ) ) {
2010-11-01 17:17:35 +03:00
if ( rstatus ) {
* rstatus = WEXITSTATUS ( status ) ;
2011-09-19 22:38:43 +04:00
log_verbose ( " %s failed: %u " , argv [ 0 ] , * rstatus ) ;
2010-11-01 17:17:35 +03:00
} else
log_error ( " %s failed: %u " , argv [ 0 ] , WEXITSTATUS ( status ) ) ;
2005-10-17 21:56:27 +04:00
return 0 ;
}
2010-11-01 17:17:35 +03:00
if ( rstatus )
* rstatus = 0 ;
2005-10-17 21:56:27 +04:00
return 1 ;
}