2006-08-17 23:56:28 +04:00
/*
* Copyright ( C ) 2006 Red Hat , Inc . All rights reserved .
*
* 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 .
2006-08-17 23:56:28 +04:00
*
2007-08-21 00:55:30 +04:00
* You should have received a copy of the GNU Lesser General Public License
2006-08-17 23:56:28 +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
2006-08-17 23:56:28 +04:00
*/
2018-05-14 12:30:20 +03:00
# include "lib/misc/lib.h"
2006-08-17 23:56:28 +04:00
# include <unistd.h>
2008-12-07 07:23:37 +03:00
# include <fcntl.h>
2006-08-17 23:56:28 +04:00
2011-04-22 15:59:59 +04:00
# ifdef UDEV_SYNC_SUPPORT
2014-04-01 17:17:50 +04:00
# include <libudev.h>
2011-04-22 15:59:59 +04:00
struct udev * _udev ;
int udev_init_library_context ( void )
{
if ( _udev )
devices: rework libudev usage
related to config settings:
obtain_device_info_from_udev (controls if lvm gets
a list of devices from readdir /dev or from libudev)
external_device_info_source (controls if lvm asks
libudev for device information)
. Make the obtain_device_list_from_udev setting
affect only the choice of readdir /dev vs libudev.
The setting no longer controls if udev is used for
device type checks.
. Change obtain_device_list_from_udev default to 0.
This helps avoid boot timeouts due to slow libudev
queries, avoids reported failures from
udev_enumerate_scan_devices, and avoids delays from
"device not initialized in udev database" errors.
Even without errors, for a system booting with 1024 PVs,
lvm2-pvscan times improve from about 100 sec to 15 sec,
and the pvscan command from about 64 sec to about 4 sec.
. For external_device_info_source="none", remove all
libudev device info queries, and use only lvm
native device info.
. For external_device_info_source="udev", first check
lvm native device info, then check libudev info.
. Remove sleep/retry loop when attempting libudev
queries for device info. udev info will simply
be skipped if it's not immediately available.
. Only set up a libdev connection if it will be used by
obtain_device_list_from_udev/external_device_info_source.
. For native multipath component detection, use
/etc/multipath/wwids. If a device has a wwid
matching an entry in the wwids file, then it's
considered a multipath component. This is
necessary to natively detect multipath
components when the mpath device is not set up.
2021-06-09 01:12:09 +03:00
return 1 ;
if ( getenv ( " DM_DISABLE_UDEV " ) )
return 0 ;
2011-04-22 15:59:59 +04:00
if ( ! ( _udev = udev_new ( ) ) ) {
log_error ( " Failed to create udev library context. " ) ;
return 0 ;
}
devices: rework libudev usage
related to config settings:
obtain_device_info_from_udev (controls if lvm gets
a list of devices from readdir /dev or from libudev)
external_device_info_source (controls if lvm asks
libudev for device information)
. Make the obtain_device_list_from_udev setting
affect only the choice of readdir /dev vs libudev.
The setting no longer controls if udev is used for
device type checks.
. Change obtain_device_list_from_udev default to 0.
This helps avoid boot timeouts due to slow libudev
queries, avoids reported failures from
udev_enumerate_scan_devices, and avoids delays from
"device not initialized in udev database" errors.
Even without errors, for a system booting with 1024 PVs,
lvm2-pvscan times improve from about 100 sec to 15 sec,
and the pvscan command from about 64 sec to about 4 sec.
. For external_device_info_source="none", remove all
libudev device info queries, and use only lvm
native device info.
. For external_device_info_source="udev", first check
lvm native device info, then check libudev info.
. Remove sleep/retry loop when attempting libudev
queries for device info. udev info will simply
be skipped if it's not immediately available.
. Only set up a libdev connection if it will be used by
obtain_device_list_from_udev/external_device_info_source.
. For native multipath component detection, use
/etc/multipath/wwids. If a device has a wwid
matching an entry in the wwids file, then it's
considered a multipath component. This is
necessary to natively detect multipath
components when the mpath device is not set up.
2021-06-09 01:12:09 +03:00
if ( ! udev_is_running ( ) ) {
udev_unref ( _udev ) ;
_udev = NULL ;
return 0 ;
}
2011-04-22 15:59:59 +04:00
return 1 ;
}
void udev_fin_library_context ( void )
{
devices: rework libudev usage
related to config settings:
obtain_device_info_from_udev (controls if lvm gets
a list of devices from readdir /dev or from libudev)
external_device_info_source (controls if lvm asks
libudev for device information)
. Make the obtain_device_list_from_udev setting
affect only the choice of readdir /dev vs libudev.
The setting no longer controls if udev is used for
device type checks.
. Change obtain_device_list_from_udev default to 0.
This helps avoid boot timeouts due to slow libudev
queries, avoids reported failures from
udev_enumerate_scan_devices, and avoids delays from
"device not initialized in udev database" errors.
Even without errors, for a system booting with 1024 PVs,
lvm2-pvscan times improve from about 100 sec to 15 sec,
and the pvscan command from about 64 sec to about 4 sec.
. For external_device_info_source="none", remove all
libudev device info queries, and use only lvm
native device info.
. For external_device_info_source="udev", first check
lvm native device info, then check libudev info.
. Remove sleep/retry loop when attempting libudev
queries for device info. udev info will simply
be skipped if it's not immediately available.
. Only set up a libdev connection if it will be used by
obtain_device_list_from_udev/external_device_info_source.
. For native multipath component detection, use
/etc/multipath/wwids. If a device has a wwid
matching an entry in the wwids file, then it's
considered a multipath component. This is
necessary to natively detect multipath
components when the mpath device is not set up.
2021-06-09 01:12:09 +03:00
if ( _udev )
udev_unref ( _udev ) ;
2011-04-22 15:59:59 +04:00
_udev = NULL ;
}
int udev_is_running ( void )
{
struct udev_queue * udev_queue ;
int r ;
if ( ! _udev ) {
2013-11-22 16:24:53 +04:00
log_debug_activation ( " Udev library context not set. " ) ;
2011-04-22 15:59:59 +04:00
goto bad ;
}
if ( ! ( udev_queue = udev_queue_new ( _udev ) ) ) {
2013-01-08 02:30:29 +04:00
log_debug_activation ( " Could not get udev state. " ) ;
2011-04-22 15:59:59 +04:00
goto bad ;
}
r = udev_queue_get_udev_is_active ( udev_queue ) ;
udev_queue_unref ( udev_queue ) ;
return r ;
bad :
2013-01-08 02:30:29 +04:00
log_debug_activation ( " Assuming udev is not running. " ) ;
2011-04-22 15:59:59 +04:00
return 0 ;
}
2016-04-01 16:35:13 +03:00
void * udev_get_library_context ( void )
2011-04-22 15:59:59 +04:00
{
return _udev ;
}
# else /* UDEV_SYNC_SUPPORT */
int udev_init_library_context ( void )
{
return 1 ;
}
2016-04-01 16:35:13 +03:00
void * udev_get_library_context ( void )
{
return NULL ;
}
2011-04-22 15:59:59 +04:00
void udev_fin_library_context ( void )
{
}
int udev_is_running ( void )
{
return 0 ;
}
# endif
2006-08-17 23:56:28 +04:00
int lvm_getpagesize ( void )
{
return getpagesize ( ) ;
}
2008-12-07 07:23:37 +03:00
int read_urandom ( void * buf , size_t len )
{
int fd ;
/* FIXME: we should stat here, and handle other cases */
/* FIXME: use common _io() routine's open/read/close */
if ( ( fd = open ( " /dev/urandom " , O_RDONLY ) ) < 0 ) {
log_sys_error ( " open " , " read_urandom: /dev/urandom " ) ;
return 0 ;
}
if ( read ( fd , buf , len ) ! = ( ssize_t ) len ) {
log_sys_error ( " read " , " read_urandom: /dev/urandom " ) ;
if ( close ( fd ) )
stack ;
return 0 ;
}
if ( close ( fd ) )
stack ;
return 1 ;
}
2014-04-04 04:26:19 +04:00
/*
* Return random integer in [ 0 , max ) interval
*
* The loop rejects numbers that come from an " incomplete " slice of the
* RAND_MAX space . Considering the number space [ 0 , RAND_MAX ] is divided
* into some " max " - sized slices and at most a single smaller slice ,
* between [ n * max , RAND_MAX ] for suitable n , numbers from this last slice
* are discarded because they could distort the distribution in favour of
* smaller numbers .
*/
unsigned lvm_even_rand ( unsigned * seed , unsigned max )
{
unsigned r , ret ;
do {
r = ( unsigned ) rand_r ( seed ) ;
ret = r % max ;
} while ( r - ret > RAND_MAX - max ) ;
return ret ;
}
2014-06-06 16:21:09 +04:00
2014-06-10 12:46:04 +04:00
int cmirrord_is_running ( void )
2014-06-06 16:21:09 +04:00
{
2014-06-10 12:46:04 +04:00
# ifdef CMIRRORD_PIDFILE
2014-06-06 16:21:09 +04:00
return dm_daemon_is_running ( CMIRRORD_PIDFILE ) ;
# else
return 0 ;
# endif
2014-06-10 12:46:04 +04:00
}