2001-10-22 18:39:12 +04:00
/*
2008-01-30 17:00:02 +03:00
* Copyright ( C ) 2001 - 2004 Sistina Software , Inc . All rights reserved .
2013-06-03 01:27:34 +04:00
* Copyright ( C ) 2004 - 2013 Red Hat , Inc . All rights reserved .
2001-10-22 18:39:12 +04:00
*
2004-03-30 23:35:44 +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 .
2004-03-30 23:35:44 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program ; if not , write to the Free Software Foundation ,
2016-01-21 13:49:46 +03:00
* Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
2001-10-22 18:39:12 +04:00
*/
2018-06-08 15:40:53 +03:00
# include "base/memory/zalloc.h"
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
# include "lib/filters/filter.h"
# include "lib/device/device.h"
2001-10-22 18:39:12 +04:00
2018-12-07 23:35:22 +03:00
static int _and_p ( struct cmd_context * cmd , struct dev_filter * f , struct device * dev , const char * use_filter_name )
2001-10-22 18:39:12 +04:00
{
2013-06-03 10:38:07 +04:00
struct dev_filter * * filters ;
2018-05-04 01:12:07 +03:00
int ret ;
2001-10-22 18:39:12 +04:00
2018-05-04 01:12:07 +03:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters ) {
2018-12-07 23:35:22 +03:00
if ( use_filter_name & & strcmp ( ( * filters ) - > name , use_filter_name ) )
continue ;
ret = ( * filters ) - > passes_filter ( cmd , * filters , dev , use_filter_name ) ;
2018-05-04 01:12:07 +03:00
if ( ! ret )
2013-08-14 02:26:58 +04:00
return 0 ; /* No 'stack': a filter, not an error. */
2018-05-04 01:12:07 +03:00
}
2003-01-08 19:41:22 +03:00
2001-10-22 18:39:12 +04:00
return 1 ;
}
2018-12-07 23:35:22 +03:00
static int _and_p_with_dev_ext_info ( struct cmd_context * cmd , struct dev_filter * f , struct device * dev , const char * use_filter_name )
2014-12-15 17:12:42 +03:00
{
int r ;
2014-12-15 18:27:33 +03:00
dev_ext_enable ( dev , external_device_info_source ( ) ) ;
2018-12-07 23:35:22 +03:00
r = _and_p ( cmd , f , dev , use_filter_name ) ;
2014-12-15 17:12:42 +03:00
dev_ext_disable ( dev ) ;
return r ;
}
2006-04-19 19:33:07 +04:00
static void _composite_destroy ( struct dev_filter * f )
2001-10-22 18:39:12 +04:00
{
2013-06-03 10:38:07 +04:00
struct dev_filter * * filters ;
2001-10-22 18:39:12 +04:00
2010-09-22 05:36:13 +04:00
if ( f - > use_count )
log_error ( INTERNAL_ERROR " Destroying composite filter while in use %u times. " , f - > use_count ) ;
2013-06-03 10:38:07 +04:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters )
2001-10-22 18:39:12 +04:00
( * filters ) - > destroy ( * filters ) ;
2018-06-08 15:40:53 +03:00
free ( f - > private ) ;
free ( f ) ;
2001-10-22 18:39:12 +04:00
}
2020-10-20 23:17:56 +03:00
static void _wipe ( struct cmd_context * cmd , struct dev_filter * f , struct device * dev , const char * use_filter_name )
2013-06-02 23:59:57 +04:00
{
struct dev_filter * * filters ;
2020-10-20 23:17:56 +03:00
for ( filters = ( struct dev_filter * * ) f - > private ; * filters ; + + filters ) {
if ( use_filter_name & & strcmp ( ( * filters ) - > name , use_filter_name ) )
continue ;
2013-06-02 23:59:57 +04:00
if ( ( * filters ) - > wipe )
2020-10-20 23:17:56 +03:00
( * filters ) - > wipe ( cmd , * filters , dev , use_filter_name ) ;
}
2013-06-02 23:59:57 +04:00
}
2014-12-15 17:12:42 +03:00
struct dev_filter * composite_filter_create ( int n , int use_dev_ext_info , struct dev_filter * * filters )
2001-10-22 18:39:12 +04:00
{
2004-05-04 22:28:15 +04:00
struct dev_filter * * filters_copy , * cft ;
2001-10-22 18:39:12 +04:00
2008-01-30 16:19:47 +03:00
if ( ! filters )
return_NULL ;
2001-10-22 18:39:12 +04:00
2018-06-08 15:40:53 +03:00
if ( ! ( filters_copy = malloc ( sizeof ( * filters ) * ( n + 1 ) ) ) ) {
2013-06-03 10:38:07 +04:00
log_error ( " Composite filters allocation failed. " ) ;
2001-10-22 18:39:12 +04:00
return NULL ;
}
2004-02-13 17:46:04 +03:00
memcpy ( filters_copy , filters , sizeof ( * filters ) * n ) ;
filters_copy [ n ] = NULL ;
2018-06-08 15:40:53 +03:00
if ( ! ( cft = zalloc ( sizeof ( * cft ) ) ) ) {
2013-06-03 10:38:07 +04:00
log_error ( " Composite filters allocation failed. " ) ;
2018-06-08 15:40:53 +03:00
free ( filters_copy ) ;
2004-02-13 17:46:04 +03:00
return NULL ;
2001-10-22 18:39:12 +04:00
}
2014-12-15 17:12:42 +03:00
cft - > passes_filter = use_dev_ext_info ? _and_p_with_dev_ext_info : _and_p ;
2006-04-19 19:33:07 +04:00
cft - > destroy = _composite_destroy ;
2013-06-02 23:59:57 +04:00
cft - > wipe = _wipe ;
2010-09-22 05:36:13 +04:00
cft - > use_count = 0 ;
2004-05-04 22:28:15 +04:00
cft - > private = filters_copy ;
2018-12-07 23:35:22 +03:00
cft - > name = " composite " ;
2001-10-22 18:39:12 +04:00
2013-08-14 02:26:58 +04:00
log_debug_devs ( " Composite filter initialised. " ) ;
2004-05-04 22:28:15 +04:00
return cft ;
2001-10-22 18:39:12 +04:00
}