From 5f102b3421873a6111e477b40fdbe1a93ef258b9 Mon Sep 17 00:00:00 2001 From: David Teigland Date: Wed, 16 Jan 2019 14:19:09 -0600 Subject: [PATCH] hints: invalidate when pvscan --cache sees a new PV An idea from Zdenek for better ensuring valid hints by invalidating them when pvscan --cache sees a new PV, which is a case where we know that hints should be invalidated. This is triggered from systemd/udev logic, and there may be some cases where it would invalidate hints that the existing methods wouldn't detect. --- lib/label/hints.c | 15 +++++++++++++++ lib/label/hints.h | 2 ++ test/shell/hints.sh | 23 +++++++++++++++++++++-- tools/pvscan.c | 16 ++++++++++++++++ 4 files changed, 54 insertions(+), 2 deletions(-) diff --git a/lib/label/hints.c b/lib/label/hints.c index a9c40c223..4fe44b023 100644 --- a/lib/label/hints.c +++ b/lib/label/hints.c @@ -1025,6 +1025,21 @@ void clear_hint_file(struct cmd_context *cmd) stack; } +/* + * This is used when pvscan --cache sees a new PV, which + * means we should refresh hints. It could catch some case + * which the other methods of detecting stale hints may miss. + */ +void invalidate_hints(struct cmd_context *cmd) +{ + /* No commands are using hints. */ + if (!cmd->enable_hints) + return; + + if (!_touch_newhints()) + stack; +} + /* * Currently, all the commands using hints (ALLOW_HINTS) take an optional or * required first position arg of a VG name or LV name. If some other command diff --git a/lib/label/hints.h b/lib/label/hints.h index a17214cdd..469e8c41d 100644 --- a/lib/label/hints.h +++ b/lib/label/hints.h @@ -28,6 +28,8 @@ int write_hint_file(struct cmd_context *cmd, int newhints); void clear_hint_file(struct cmd_context *cmd); +void invalidate_hints(struct cmd_context *cmd); + int get_hints(struct cmd_context *cmd, struct dm_list *hints, int *newhints, struct dm_list *devs_in, struct dm_list *devs_out); diff --git a/test/shell/hints.sh b/test/shell/hints.sh index bdaf3be3d..31628b0e8 100644 --- a/test/shell/hints.sh +++ b/test/shell/hints.sh @@ -273,11 +273,12 @@ diff $HINTS $PREV # # pvs (no change), pvscan (hints are new), pvs (no change) +rm $HINTS $PREV pvs cp $HINTS $PREV -diff $HINTS $PREV -cp $HINTS $PREV +# this next pvscan recreates the hints file pvscan --cache +# the only diff will be "Created by pvscan ..." vs "Created by pvs ..." not diff $HINTS $PREV cp $HINTS $PREV pvs @@ -285,6 +286,8 @@ diff $HINTS $PREV grep 'Created by pvscan' $HINTS # dev4 is a PV not used by a VG, dev5 is not a PV # using dd to copy skirts hint tracking so dev5 won't be seen +# (unless the dd triggers udev which triggers pvscan --cache $dev5, +# but I've not seen that happen in tests so far.) dd if="$dev4" of="$dev5" bs=1M # this pvs won't see dev5 pvs > foo @@ -314,6 +317,22 @@ not grep "$dev5" foo grep "$dev4" $HINTS not grep "$dev5" $HINTS +# +# Test pvscan --cache forces refresh +# + +rm $HINTS $PREV +pvs +cp $HINTS $PREV +# this next pvscan creates newhints to trigger a refresh +pvscan --cache "$dev5" +cat $NEWHINTS +# this next pvs creates new hints +pvs +# the only diff will be "Created by..." +not diff $HINTS $PREV + + # # Test incorrect dev-to-pvid info in hints is detected diff --git a/tools/pvscan.c b/tools/pvscan.c index da1e4354b..098c50261 100644 --- a/tools/pvscan.c +++ b/tools/pvscan.c @@ -17,6 +17,7 @@ #include "lib/cache/lvmcache.h" #include "lib/metadata/metadata.h" +#include "lib/label/hints.h" #include @@ -632,6 +633,7 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv) int do_activate = arg_is_set(cmd, activate_ARG); int all_vgs = 0; int add_errors = 0; + int add_single_count = 0; int ret = ECMD_PROCESSED; dm_list_init(&single_devs); @@ -750,6 +752,8 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv) if (dev->flags & DEV_FILTER_OUT_SCAN) continue; + add_single_count++; + /* * Devices that exist and pass the lvmetad filter * are online. @@ -801,6 +805,8 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv) if (dev->flags & DEV_FILTER_OUT_SCAN) continue; + add_single_count++; + /* * Devices that exist and pass the lvmetad filter * are online. @@ -811,6 +817,16 @@ int pvscan_cache_cmd(struct cmd_context *cmd, int argc, char **argv) } activate: + /* + * When a new PV appears, the system runs pvscan --cache dev. + * This also means that existing hints are invalid, and + * we can force hints to be refreshed here. There may be + * cases where this detects a change that the other methods + * of detecting invalid hints doesn't catch. + */ + if (add_single_count) + invalidate_hints(cmd); + /* * Special case: pvscan --cache -aay dev * where dev has no VG metadata, and it's the final device to