2015-05-09 02:59:18 +03:00
/*
* Copyright ( C ) 2015 Red Hat , Inc .
*
* 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
* of the GNU Lesser General Public License v .2 .1 .
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program ; if not , write to the Free Software Foundation ,
* Inc . , 59 Temple Place , Suite 330 , Boston , MA 02111 - 1307 USA
*/
# include "lvmpolld-common.h"
/* extract this info from autoconf/automake files */
# define LVPOLL_CMD "lvpoll"
# define MIN_ARGV_SIZE 8
static const char * const const polling_ops [ ] = { [ PVMOVE ] = LVMPD_REQ_PVMOVE ,
[ CONVERT ] = LVMPD_REQ_CONVERT ,
[ MERGE ] = LVMPD_REQ_MERGE ,
[ MERGE_THIN ] = LVMPD_REQ_MERGE_THIN } ;
const char * polling_op ( enum poll_type type )
{
return type < POLL_TYPE_MAX ? polling_ops [ type ] : " <undefined> " ;
}
static int add_to_cmd_arr ( const char * * * cmdargv , const char * str , unsigned * ind )
{
const char * * newargv = * cmdargv ;
if ( * ind & & ! ( * ind % MIN_ARGV_SIZE ) ) {
newargv = dm_realloc ( * cmdargv , ( * ind / MIN_ARGV_SIZE + 1 ) * MIN_ARGV_SIZE * sizeof ( char * ) ) ;
if ( ! newargv )
return 0 ;
* cmdargv = newargv ;
}
* ( * cmdargv + ( * ind ) + + ) = str ;
return 1 ;
}
const char * * cmdargv_ctr ( const struct lvmpolld_lv * pdlv , const char * lvm_binary , unsigned abort_polling , unsigned handle_missing_pvs )
{
unsigned i = 0 ;
const char * * cmd_argv = dm_malloc ( MIN_ARGV_SIZE * sizeof ( char * ) ) ;
if ( ! cmd_argv )
return NULL ;
/* path to lvm2 binary */
if ( ! add_to_cmd_arr ( & cmd_argv , lvm_binary , & i ) )
goto err ;
/* cmd to execute */
if ( ! add_to_cmd_arr ( & cmd_argv , LVPOLL_CMD , & i ) )
goto err ;
/* transfer internal polling interval */
if ( pdlv - > sinterval & &
( ! add_to_cmd_arr ( & cmd_argv , " --interval " , & i ) | |
! add_to_cmd_arr ( & cmd_argv , pdlv - > sinterval , & i ) ) )
goto err ;
/* pass abort param */
if ( abort_polling & &
! add_to_cmd_arr ( & cmd_argv , " --abort " , & i ) )
goto err ;
/* pass handle-missing-pvs. used by mirror polling operation */
if ( handle_missing_pvs & &
! add_to_cmd_arr ( & cmd_argv , " --handlemissingpvs " , & i ) )
goto err ;
/* one of: "convert", "pvmove", "merge", "merge_thin" */
if ( ! add_to_cmd_arr ( & cmd_argv , " --polloperation " , & i ) | |
! add_to_cmd_arr ( & cmd_argv , polling_ops [ pdlv - > type ] , & i ) )
goto err ;
/* vg/lv name */
if ( ! add_to_cmd_arr ( & cmd_argv , pdlv - > lvname , & i ) )
goto err ;
2015-05-11 16:22:18 +03:00
/* disable metadata backup */
if ( ! add_to_cmd_arr ( & cmd_argv , " -An " , & i ) )
goto err ;
2015-05-09 02:59:18 +03:00
/* terminating NULL */
if ( ! add_to_cmd_arr ( & cmd_argv , NULL , & i ) )
goto err ;
return cmd_argv ;
err :
dm_free ( cmd_argv ) ;
return NULL ;
}
/* FIXME: in fact exclude should be va list */
static int copy_env ( const char * * * cmd_envp , unsigned * i , const char * exclude )
{
const char * const * tmp = ( const char * const * ) environ ;
if ( ! tmp )
return 0 ;
while ( * tmp ) {
if ( strncmp ( * tmp , exclude , strlen ( exclude ) ) & & ! add_to_cmd_arr ( cmd_envp , * tmp , i ) )
return 0 ;
tmp + + ;
}
return 1 ;
}
const char * * cmdenvp_ctr ( const struct lvmpolld_lv * pdlv )
{
unsigned i = 0 ;
const char * * cmd_envp = dm_malloc ( MIN_ARGV_SIZE * sizeof ( char * ) ) ;
if ( ! cmd_envp )
return NULL ;
/* copy whole environment from lvmpolld, exclude LVM_SYSTEM_DIR if set */
if ( ! copy_env ( & cmd_envp , & i , " LVM_SYSTEM_DIR= " ) )
goto err ;
/* Add per client LVM_SYSTEM_DIR variable if set */
if ( * pdlv - > lvm_system_dir_env & & ! add_to_cmd_arr ( & cmd_envp , pdlv - > lvm_system_dir_env , & i ) )
goto err ;
/* terminating NULL */
if ( ! add_to_cmd_arr ( & cmd_envp , NULL , & i ) )
goto err ;
return cmd_envp ;
err :
dm_free ( cmd_envp ) ;
return NULL ;
}