Query udev database to obtain device list for device cache
PATCH 2/3 Query udev database to obtain device list for device cache
Use libudev to obtain the list of all block device nodes and associated symlinks and construct the device cache from this information. This avoids accessing inappropriate devices or subdirectories found in /dev that is managed by udev.
There's a new lvm.conf setting that controls this: obtain_device_list_from_udev to control this feature.
If udev is not running or we're scanning a directory that is not managed by udev, the device scan will fallback to original ("full scan") mode.
LVM2 needs to be compiled with udev support (--enable-udev_sync) for this setting to take effect.
Since we need to access the libudev context quite often, we set it once in init_lvm and finalize it in lvm_fin. The common udev wrappers are in lvm-wrappers.[ch]. This avoids calling udev_new frequently (udev_new reads udev config file etc.).
Peter
--- doc/example.conf.in | 10 +++ lib/commands/toolcontext.c | 4 + lib/config/defaults.h | 1 + lib/device/dev-cache.c | 130 +++++++++++++++++++++++++++++++++++--- lib/device/dev-cache.h | 1 + lib/filters/filter-persistent.c | 14 ++++ lib/misc/lvm-globals.c | 11 +++ lib/misc/lvm-globals.h | 2 + lib/misc/lvm-wrappers.c | 72 +++++++++++++++++++++ lib/misc/lvm-wrappers.h | 9 +++ make.tmpl.in | 2 +- tools/lvmcmdline.c | 3 + 12 files changed, 247 insertions(+), 12 deletions(-)
doc/example.conf.in +10 -0
@@ -19,6 +19,16 @@ devices { # to use with LVM2. scan = [ "/dev" ] + # If set, the cache of block device nodes with all associated symlinks + # will be constructed out of the existing udev database content. + # This avoids using and opening any inapplicable non-block devices or + # subdirectories found in the device directory. This setting is applied + # to udev-managed device directory only, other directories will be scanned + # fully. LVM2 needs to be compiled with udev support for this setting to + # take effect. N.B. Any device node or symlink not managed by udev in + # udev directory will be ignored with this setting on. + # obtain_device_list_from_udev = 1 + # If several entries in the scanned directories correspond to the # same block device and the tools need to display a name for device, # all the pathnames are matched against each item in the following
lib/commands/toolcontext.c +4 -0
@@ -592,6 +592,10 @@ static int _init_dev_cache(struct cmd_context *cmd)return 1 ; } +init_obtain_device_list_from_udev (udev_is_running () ? +find_config_tree_bool (cmd,"devices/obtain_device_list_from_udev" , +DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV ) :0 ); +for (cv = cn->v; cv; cv = cv->next) {if (cv->type !=CFG_STRING ) { log_error("Invalid string in config file: "
lib/config/defaults.h +1 -0
@@ -29,6 +29,7 @@#define DEFAULT_DEV_DIR "/dev"#define DEFAULT_PROC_DIR "/proc" +#define DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV 1#define DEFAULT_SYSFS_SCAN 1#define DEFAULT_MD_COMPONENT_DETECTION 1#define DEFAULT_MD_CHUNK_ALIGNMENT 1
lib/device/dev-cache.c +119 -11
194 lines not on this page · raw message
lib/device/dev-cache.h +1 -0
@@ -17,6 +17,7 @@#define _LVM_DEV_CACHE_H#include "device.h" +#include "lvm-wrappers.h" /* * predicate for devices.
lib/filters/filter-persistent.c +14 -0
@@ -103,6 +103,17 @@ int persistent_filter_load(struct dev_filter *f, struct config_tree **cft_out)struct stat info;int r =0 ; +if (obtain_device_list_from_udev ()) { +if (!stat (pf->file, &info)) { +log_very_verbose ("Obtaining device list from " +"udev. Removing obolete %s." , + pf->file); +if (unlink (pf->file) <0 ) +log_sys_error ("unlink" , pf->file); + } +return 1 ; + } +if (!stat (pf->file, &info)) pf->ctime = info.st_ctime;else {
@@ -180,6 +191,9 @@ int persistent_filter_dump(struct dev_filter *f, int merge_existing)int lockfd;int r =0 ; +if (obtain_device_list_from_udev ()) +return 1 ; +if (!f) return_0; pf = (struct pfilter *) f->private;
lib/misc/lvm-globals.c +11 -0
@@ -28,6 +28,7 @@ static int _test = 0;static int _md_filtering =0 ;static int _pvmove =0 ;static int _full_scan_done =0 ;/* Restrict to one full scan during each cmd */ +static int _obtain_device_list_from_udev =DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV ;static int _trust_cache =0 ;/* Don't scan when incomplete VGs encountered */ static int _debug_level =0 ;static int _log_cmd_name =0 ;
@@ -72,6 +73,11 @@ void init_full_scan_done(int level) _full_scan_done = level; } +void init_obtain_device_list_from_udev (int device_list_from_udev) +{ + _obtain_device_list_from_udev = device_list_from_udev; +} +void init_trust_cache (int trustcache) { _trust_cache = trustcache;
@@ -185,6 +191,11 @@ int full_scan_done()return _full_scan_done; } +int obtain_device_list_from_udev () +{ +return _obtain_device_list_from_udev; +} +int trust_cache () {return _trust_cache;
lib/misc/lvm-globals.h +2 -0
@@ -25,6 +25,7 @@ void init_test(int level);void init_md_filtering (int level);void init_pvmove (int level);void init_full_scan_done (int level); +void init_obtain_device_list_from_udev (int device_list_from_udev);void init_trust_cache (int trustcache);void init_debug (int level);void init_cmd_name (int status);
@@ -48,6 +49,7 @@ int test_mode(void);int md_filtering (void );int pvmove_mode (void );int full_scan_done (void ); +int obtain_device_list_from_udev (void );int trust_cache (void );int verbose_level (void );int debug_level (void );
lib/misc/lvm-wrappers.c +72 -0
78 lines not on this page · raw message
lib/misc/lvm-wrappers.h +9 -0
@@ -16,6 +16,15 @@#ifndef _LVM_WRAPPERS_H#define _LVM_WRAPPERS_H +#ifdef UDEV_SYNC_SUPPORT +#include <libudev.h> +struct udev *udev_get_library_context (void ); +#endif + +int udev_init_library_context (void ); +void udev_fin_library_context (void ); +int udev_is_running (void ); +int lvm_getpagesize (void );/*
make.tmpl.in +1 -1
@@ -38,7 +38,7 @@ CLDFLAGS += @CLDFLAGS@ LDDEPS += @LDDEPS@ LDFLAGS += @LDFLAGS@ LIB_SUFFIX = @LIB_SUFFIX@ -LVMINTERNAL_LIBS = -llvm-internal $(DL_LIBS) +LVMINTERNAL_LIBS = -llvm-internal $(UDEV_LIBS) $(DL_LIBS) DL_LIBS = @DL_LIBS@ PTHREAD_LIBS = @PTHREAD_LIBS@ READLINE_LIBS = @READLINE_LIBS@
tools/lvmcmdline.c +3 -0
@@ -1282,6 +1282,8 @@ struct cmd_context *init_lvm(void) {struct cmd_context *cmd; + (void )udev_init_library_context (); +if (!(cmd =create_toolcontext (0 ,NULL ))) return_NULL;
@@ -1313,6 +1315,7 @@ void lvm_fin(struct cmd_context *cmd) {_fin_commands ();destroy_toolcontext (cmd); +udev_fin_library_context (); }static int _run_script (struct cmd_context *cmd,int argc,char **argv)
PATCH 2/3 Query udev database to obtain device list for device cache
Quoted 3 lines · Peter Rajnoha
Use libudev to obtain the list of all block device nodes and associated symlinks and construct the device cache from this information. This avoids accessing inappropriate devices or subdirectories found in /dev that is managed by udev.
ack. it need some testing but definitely it should go in.
Milan