2004-02-13 17:46:04 +03:00
/*
2007-08-21 00:55:30 +04:00
* Copyright ( C ) 2004 - 2007 Red Hat , Inc . All rights reserved .
2004-02-13 17:46:04 +03: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
2004-02-13 17:46:04 +03:00
*/
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
# include "lib/filters/filter.h"
2004-02-13 17:46:04 +03:00
2013-11-13 17:56:29 +04:00
# ifdef __linux__
2004-03-26 21:54:55 +03:00
2021-11-02 23:42:26 +03:00
static int _accept_p ( struct cmd_context * cmd , struct dev_filter * f , struct device * dev , const char * use_filter_name )
2004-02-13 17:46:04 +03:00
{
2021-11-02 23:42:26 +03:00
char path [ PATH_MAX ] ;
2023-10-03 19:39:39 +03:00
const char * sysfs_dir = f - > private ;
2007-10-10 15:31:21 +04:00
struct stat info ;
2004-02-13 17:46:04 +03:00
2021-11-02 23:42:26 +03:00
dev - > filtered_flags & = ~ DEV_FILTERED_SYSFS ;
2004-02-13 17:46:04 +03:00
2021-11-02 23:42:26 +03:00
/*
* Any kind of device id other than devname has been set
* using sysfs so we know that sysfs info exists for dev .
*/
if ( dev - > id & & dev - > id - > idtype & & ( dev - > id - > idtype ! = DEV_ID_TYPE_DEVNAME ) )
return 1 ;
2004-02-13 17:46:04 +03:00
2024-05-28 17:17:53 +03:00
if ( dm_snprintf ( path , sizeof ( path ) , " %sdev/block/%u:%u " ,
sysfs_dir , MAJOR ( dev - > dev ) , MINOR ( dev - > dev ) ) < 0 ) {
2023-10-03 19:39:39 +03:00
log_debug ( " failed to create sysfs path " ) ;
return 1 ;
}
if ( lstat ( path , & info ) ) {
log_debug_devs ( " %s: Skipping (sysfs) " , dev_name ( dev ) ) ;
dev - > filtered_flags | = DEV_FILTERED_SYSFS ;
return 0 ;
2004-02-13 17:46:04 +03:00
}
2017-07-19 17:16:12 +03:00
return 1 ;
2004-02-13 17:46:04 +03:00
}
static void _destroy ( struct dev_filter * f )
{
2010-09-22 05:36:13 +04:00
if ( f - > use_count )
log_error ( INTERNAL_ERROR " Destroying sysfs filter while in use %u times. " , f - > use_count ) ;
2021-11-02 23:42:26 +03:00
free ( f ) ;
2004-02-13 17:46:04 +03:00
}
2023-10-03 19:39:39 +03:00
static int _check_sys_dev_block ( const char * sysfs_dir )
2021-11-09 20:54:48 +03:00
{
char path [ PATH_MAX ] ;
struct stat info ;
2023-10-03 19:39:39 +03:00
if ( dm_snprintf ( path , sizeof ( path ) , " %sdev/block " , sysfs_dir ) < 0 )
return_0 ;
if ( lstat ( path , & info ) ) {
log_debug ( " filter-sysfs disabled: /sys/dev/block not found " ) ;
return 0 ;
2021-11-09 20:54:48 +03:00
}
2023-10-03 19:39:39 +03:00
return 1 ;
2021-11-09 20:54:48 +03:00
}
2023-10-03 19:39:39 +03:00
struct dev_filter * sysfs_filter_create ( const char * sysfs_dir )
2004-02-13 17:46:04 +03:00
{
struct dev_filter * f ;
2023-10-03 19:39:39 +03:00
size_t len ;
2004-02-13 17:46:04 +03:00
2023-10-18 03:19:15 +03:00
if ( ! sysfs_dir | | ! * sysfs_dir ) {
2008-09-19 07:42:37 +04:00
log_verbose ( " No proc filesystem found: skipping sysfs filter " ) ;
return NULL ;
}
2021-11-09 20:54:48 +03:00
/* support old kernels that don't have this */
2023-10-03 19:39:39 +03:00
if ( ! _check_sys_dev_block ( sysfs_dir ) )
return NULL ;
2021-11-09 20:54:48 +03:00
2023-10-03 19:39:39 +03:00
len = strlen ( sysfs_dir ) + 1 ;
if ( ! ( f = zalloc ( sizeof ( * f ) + len ) ) )
return NULL ;
2004-02-13 17:46:04 +03:00
f - > passes_filter = _accept_p ;
f - > destroy = _destroy ;
2010-09-22 05:36:13 +04:00
f - > use_count = 0 ;
2018-12-07 23:35:22 +03:00
f - > name = " sysfs " ;
2013-08-14 02:26:58 +04:00
2023-10-03 19:39:39 +03:00
memcpy ( f + 1 , sysfs_dir , len ) ;
f - > private = ( f + 1 ) ;
2013-08-14 02:26:58 +04:00
log_debug_devs ( " Sysfs filter initialised. " ) ;
2004-02-13 17:46:04 +03:00
return f ;
}
2004-03-26 21:54:55 +03:00
# else
2010-07-09 19:34:40 +04:00
struct dev_filter * sysfs_filter_create ( const char * sysfs_dir __attribute__ ( ( unused ) ) )
2004-03-26 21:54:55 +03:00
{
return NULL ;
}
# endif