On Sun, Jun 06, 2021 at 02:15:23PM +0800, heming.z...@suse.com wrote:
> dev_cache_scan //order: O(n^2)
>  + _insert_dirs //O(n)
>  | if obtain_device_list_from_udev() true
>  |   _insert_udev_dir //O(n)
>  |
>  + dev_cache_index_devs //O(n)

I've been running some experiments and trying some patches to improve
this.  By setting obtain_device_list_from_udev=0, and using the attached
patch to disable dev_cache_index_devs, the pvscan is much better.

systemctl status lvm2-pvscan appears to show that the pvscan command
itself runs for only 2-4 seconds, while the service as a whole takes
around 15 seconds.  See the 16 sec gap below from the end of pvscan
to the systemd Started message.  If that's accurate, the remaining delay
would lie outside lvm.

Jul 02 15:27:57 localhost.localdomain systemd[1]: Starting LVM event activation 
on device 253:1710...
Jul 02 15:28:00 localhost.localdomain lvm[65620]:   pvscan[65620] PV 
/dev/mapper/mpathalz online, VG 1ed02c7d-0019-43c4-91b5-f220f3521ba9 is 
complete.
Jul 02 15:28:00 localhost.localdomain lvm[65620]:   pvscan[65620] VG 
1ed02c7d-0019-43c4-91b5-f220f3521ba9 run autoactivation.
Jul 02 15:28:00 localhost.localdomain lvm[65620]:   1 logical volume(s) in 
volume group "1ed02c7d-0019-43c4-91b5-f220f3521ba9" now active
Jul 02 15:28:16 localhost.localdomain systemd[1]: Started LVM event activation 
on device 253:1710.

>From f862af22f499e2828cf14ae52b9f3382816b66c5 Mon Sep 17 00:00:00 2001
From: David Teigland <teigl...@redhat.com>
Date: Thu, 1 Jul 2021 17:25:43 -0500
Subject: [PATCH] pvscan: skip indexing devices used by LVs

dev_cache_index_devs() is taking a large amount of time
when there are many PVs.  The index keeps track of
devices that are currently in use by active LVs.  This
info is used to print warnings for users in some limited
cases.

The checks/warnings that are enabled by the index are not
needed by pvscan --cache, so disable it in this case.

This may be expanded to other cases in future commits.
dev_cache_index_devs should also be improved in another
commit to avoid the extreme delays with many devices.
---
 lib/commands/toolcontext.c | 1 +
 lib/commands/toolcontext.h | 1 +
 lib/device/dev-cache.c     | 9 +++++----
 lib/device/dev-cache.h     | 2 +-
 lib/metadata/metadata.c    | 3 ++-
 tools/lvmdevices.c         | 2 +-
 tools/pvscan.c             | 2 ++
 7 files changed, 13 insertions(+), 7 deletions(-)

diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index e2be89d0f480..b295a20efe52 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1608,6 +1608,7 @@ struct cmd_context *create_toolcontext(unsigned is_clvmd,
        cmd->handles_missing_pvs = 0;
        cmd->handles_unknown_segments = 0;
        cmd->hosttags = 0;
+       cmd->check_devs_used = 1;
        dm_list_init(&cmd->arg_value_groups);
        dm_list_init(&cmd->formats);
        dm_list_init(&cmd->segtypes);
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index a47b7d760317..34808ce46b41 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -192,6 +192,7 @@ struct cmd_context {
        unsigned filter_nodata_only:1;          /* only use filters that do not 
require data from the dev */
        unsigned run_by_dmeventd:1;             /* command is being run by 
dmeventd */
        unsigned sysinit:1;                     /* --sysinit is used */
+       unsigned check_devs_used:1;             /* check devs used by LVs */
 
        /*
         * Devices and filtering.
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index d7fa93fd6fdb..bb0d0f211d36 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -1139,7 +1139,7 @@ static int _insert(const char *path, const struct stat 
*info,
        return 1;
 }
 
-void dev_cache_scan(void)
+void dev_cache_scan(struct cmd_context *cmd)
 {
        log_debug_devs("Creating list of system devices.");
 
@@ -1147,7 +1147,8 @@ void dev_cache_scan(void)
 
        _insert_dirs(&_cache.dirs);
 
-       (void) dev_cache_index_devs();
+       if (cmd->check_devs_used)
+               (void) dev_cache_index_devs();
 }
 
 int dev_cache_has_scanned(void)
@@ -1583,7 +1584,7 @@ struct device *dev_cache_get_by_devt(struct cmd_context 
*cmd, dev_t dev, struct
 
                log_debug_devs("Device num not found in dev_cache repeat 
dev_cache_scan for %d:%d",
                                (int)MAJOR(dev), (int)MINOR(dev));
-               dev_cache_scan();
+               dev_cache_scan(cmd);
                d = (struct device *) btree_lookup(_cache.devices, (uint32_t) 
dev);
 
                if (!d)
@@ -1953,7 +1954,7 @@ int setup_devices(struct cmd_context *cmd)
         * This will not open or read any devices, but may look at sysfs 
properties.
         * This list of devs comes from looking /dev entries, or from asking 
libudev.
         */
-       dev_cache_scan();
+       dev_cache_scan(cmd);
 
        /*
         * Match entries from cmd->use_devices with device structs in dev-cache.
diff --git a/lib/device/dev-cache.h b/lib/device/dev-cache.h
index 9b7e39d33cf1..c3f5eddda802 100644
--- a/lib/device/dev-cache.h
+++ b/lib/device/dev-cache.h
@@ -48,7 +48,7 @@ int dev_cache_exit(void);
  */
 int dev_cache_check_for_open_devices(void);
 
-void dev_cache_scan(void);
+void dev_cache_scan(struct cmd_context *cmd);
 int dev_cache_has_scanned(void);
 
 int dev_cache_add_dir(const char *path);
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index d5b28a58f200..0cbf678690b7 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -5132,7 +5132,8 @@ struct volume_group *vg_read(struct cmd_context *cmd, 
const char *vg_name, const
        if (!check_pv_dev_sizes(vg))
                log_warn("WARNING: One or more devices used as PVs in VG %s 
have changed sizes.", vg->name);
 
-       _check_devs_used_correspond_with_vg(vg);
+       if (cmd->check_devs_used)
+               _check_devs_used_correspond_with_vg(vg);
 
        if (!_access_vg_lock_type(cmd, vg, lockd_state, &failure)) {
                /* Either FAILED_LOCK_TYPE or FAILED_LOCK_MODE were set. */
diff --git a/tools/lvmdevices.c b/tools/lvmdevices.c
index 3448bdd14722..5117277a091d 100644
--- a/tools/lvmdevices.c
+++ b/tools/lvmdevices.c
@@ -171,7 +171,7 @@ int lvmdevices(struct cmd_context *cmd, int argc, char 
**argv)
                log_error("Failed to read the devices file.");
                return ECMD_FAILED;
        }
-       dev_cache_scan();
+       dev_cache_scan(cmd);
        device_ids_match(cmd);
 
        if (arg_is_set(cmd, check_ARG) || arg_is_set(cmd, update_ARG)) {
diff --git a/tools/pvscan.c b/tools/pvscan.c
index f8d27372b4ae..464501ad54c4 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -1627,6 +1627,8 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, 
char **argv)
 
        dm_list_init(&complete_vgnames);
 
+       cmd->check_devs_used = 0;
+
        if (do_activate &&
            !find_config_tree_bool(cmd, global_event_activation_CFG, NULL)) {
                log_verbose("Ignoring pvscan --cache -aay because 
event_activation is disabled.");
-- 
2.10.1

_______________________________________________
linux-lvm mailing list
linux-lvm@redhat.com
https://listman.redhat.com/mailman/listinfo/linux-lvm
read the LVM HOW-TO at http://tldp.org/HOWTO/LVM-HOWTO/

Reply via email to