diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c index 1c4302ec3..9626dc7a7 100644 --- a/lib/commands/toolcontext.c +++ b/lib/commands/toolcontext.c @@ -1229,7 +1229,7 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd) * (currently not used for devs match to device id using syfs) */ if (find_config_tree_bool(cmd, devices_sysfs_scan_CFG, NULL)) { - if ((filters[nr_filt] = sysfs_filter_create())) + if ((filters[nr_filt] = sysfs_filter_create(cmd->device_id_sysfs_dir ?: dm_sysfs_dir()))) nr_filt++; } diff --git a/lib/filters/filter-sysfs.c b/lib/filters/filter-sysfs.c index d8de7940b..806363201 100644 --- a/lib/filters/filter-sysfs.c +++ b/lib/filters/filter-sysfs.c @@ -15,19 +15,14 @@ #include "lib/misc/lib.h" #include "lib/filters/filter.h" -static int _sys_dev_block_found; - #ifdef __linux__ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name) { char path[PATH_MAX]; - const char *sysfs_dir; + const char *sysfs_dir = f->private; struct stat info; - if (!_sys_dev_block_found) - return 1; - dev->filtered_flags &= ~DEV_FILTERED_SYSFS; /* @@ -37,19 +32,16 @@ static int _accept_p(struct cmd_context *cmd, struct dev_filter *f, struct devic if (dev->id && dev->id->idtype && (dev->id->idtype != DEV_ID_TYPE_DEVNAME)) return 1; - sysfs_dir = dm_sysfs_dir(); - if (sysfs_dir && *sysfs_dir) { - if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", - sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) { - log_debug("failed to create sysfs path"); - return 1; - } + if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d", + sysfs_dir, (int)MAJOR(dev->dev), (int)MINOR(dev->dev)) < 0) { + 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; - } + if (lstat(path, &info)) { + log_debug_devs("%s: Skipping (sysfs)", dev_name(dev)); + dev->filtered_flags |= DEV_FILTERED_SYSFS; + return 0; } return 1; @@ -62,53 +54,51 @@ static void _destroy(struct dev_filter *f) free(f); } -static void _check_sys_dev_block(void) +static int _check_sys_dev_block(const char *sysfs_dir) { char path[PATH_MAX]; - const char *sysfs_dir; struct stat info; - sysfs_dir = dm_sysfs_dir(); - if (sysfs_dir && *sysfs_dir) { - if (dm_snprintf(path, sizeof(path), "%sdev/block", sysfs_dir) < 0) - return; + 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"); - _sys_dev_block_found = 0; - } else { - _sys_dev_block_found = 1; - } + if (lstat(path, &info)) { + log_debug("filter-sysfs disabled: /sys/dev/block not found"); + return 0; } + + return 1; } -struct dev_filter *sysfs_filter_create(void) +struct dev_filter *sysfs_filter_create(const char *sysfs_dir) { - const char *sysfs_dir = dm_sysfs_dir(); struct dev_filter *f; + size_t len; - if (!*sysfs_dir) { + if (!sysfs_dir || *sysfs_dir) { log_verbose("No proc filesystem found: skipping sysfs filter"); return NULL; } /* support old kernels that don't have this */ - _check_sys_dev_block(); + if (!_check_sys_dev_block(sysfs_dir)) + return NULL; - if (!(f = zalloc(sizeof(*f)))) - goto_bad; + len = strlen(sysfs_dir) + 1; + if (!(f = zalloc(sizeof(*f) + len))) + return NULL; f->passes_filter = _accept_p; f->destroy = _destroy; f->use_count = 0; f->name = "sysfs"; + memcpy(f + 1, sysfs_dir, len); + f->private = (f + 1); + log_debug_devs("Sysfs filter initialised."); return f; - - bad: - return NULL; } #else diff --git a/lib/filters/filter.h b/lib/filters/filter.h index 4cdfa2c9b..7707456dc 100644 --- a/lib/filters/filter.h +++ b/lib/filters/filter.h @@ -28,7 +28,7 @@ struct dev_filter *fwraid_filter_create(struct dev_types *dt); struct dev_filter *mpath_filter_create(struct dev_types *dt); struct dev_filter *partitioned_filter_create(struct dev_types *dt); struct dev_filter *persistent_filter_create(struct dev_types *dt, struct dev_filter *f); -struct dev_filter *sysfs_filter_create(void); +struct dev_filter *sysfs_filter_create(const char *sysfs_dir); struct dev_filter *signature_filter_create(struct dev_types *dt); struct dev_filter *deviceid_filter_create(struct cmd_context *cmd);