diff options
author | David Teigland <teigland@redhat.com> | 2015-10-15 13:30:31 -0500 |
---|---|---|
committer | David Teigland <teigland@redhat.com> | 2015-10-16 16:01:02 -0500 |
commit | ff0977954281db7650d6c0f50e853a2f881181d9 (patch) | |
tree | 82a966edbf816d23ee16e03488fdb7d944ca326e | |
parent | 4895df4cbb9829e39eaa80f99a376bd6fc4a4d1b (diff) | |
download | lvm2-ff0977954281db7650d6c0f50e853a2f881181d9.tar.gz |
pvscan: --cache should scan all devices
When running pvscan --cache, the intention is to scan
all devices, i.e. the equivalent of running
'pvscan --cache dev' for each device. But, some devices
holding duplicate PVs were being skipped, and lvmetad
was not being told about them.
This was a side effect of the fact that the lvmcache
layer is used internally during scanning (it's used
to transfer info between the different stages of the
command: label reading, vg reading, sending the vg.)
An unwanted side effect of using lvmcache is that it
eliminates duplicate PVs if it sees them. This
prevented the command from sending some duplicate PVs
to lvmetad (when the first duplicate was preferred
over the second.)
The fix is to drop the lvmcache state between scanning
each PV. There is no need to keep any cache state between
each PV being scanned (there's nothing being reused), and
the unneeded state is causing lvmcache to eliminate
duplicates which is harmful for pvscan --cache.
Also, remove clvm locking from pvscan_lvmetad. This is
not needed since lvmetad cannot be used with clvm. It
was interfering with clearing the cache.
-rw-r--r-- | lib/cache/lvmetad.c | 16 | ||||
-rw-r--r-- | tools/pvscan.c | 8 |
2 files changed, 16 insertions, 8 deletions
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c index e315a73b3..090f0d722 100644 --- a/lib/cache/lvmetad.c +++ b/lib/cache/lvmetad.c @@ -1386,6 +1386,7 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler struct dev_iter *iter; struct device *dev; daemon_reply reply; + struct lvmcache_info *info; int r = 1; char *future_token; int was_silent; @@ -1425,6 +1426,21 @@ static int _lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler } if (!lvmetad_pvscan_single(cmd, dev, handler, ignore_obsolete)) r = 0; + + /* + * The fact that lvmcache is used to transport data between + * steps within pvscan_single is an implementation detail; + * we don't really need or want any caching since we're just + * scanning each device once to populate lvmetad. We need + * to clear lvmcache after scanning each PV to avoid a side + * effect of lvmcache, which is that it eliminates duplicate + * PVs and prevents duplicate PVs from being sent to lvmetad. + * lvmetad wants to know about duplicate PVs. So, we just + * drop the lvmcache data after scanning each PV so that + * state from scanning one PV will not affect the next one. + */ + if ((info = lvmcache_info_from_pvid(dev->pvid, 0))) + lvmcache_del(info); } init_silent(was_silent); diff --git a/tools/pvscan.c b/tools/pvscan.c index 3adb91c63..150ad72ed 100644 --- a/tools/pvscan.c +++ b/tools/pvscan.c @@ -221,11 +221,6 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) return EINVALID_CMD_LINE; } - if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) { - log_error("Unable to obtain global lock."); - return ECMD_FAILED; - } - /* Scan everything? */ if (!argc && !devno_args) { if (!lvmetad_pvscan_all_devs(cmd, handler)) @@ -319,9 +314,6 @@ static int _pvscan_lvmetad(struct cmd_context *cmd, int argc, char **argv) } out: - if (!sync_local_dev_names(cmd)) - stack; - unlock_vg(cmd, VG_GLOBAL); return ret; } |