master - doc: lvm disk reading
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a2310e2de0c29cc4d43...
Commit: a2310e2de0c29cc4d43cd20148856669b308bc5d
Parent: c9729022bf691a57df25bca43995e9a05c9cf130
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jan 26 06:50:52 2018 -0600
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri May 4 10:54:29 2018 -0500
doc: lvm disk reading
---
doc/lvm-disk-reading.txt | 189 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 189 insertions(+), 0 deletions(-)
diff --git a/doc/lvm-disk-reading.txt b/doc/lvm-disk-reading.txt
new file mode 100644
index 0000000..241a7ab
--- /dev/null
+++ b/doc/lvm-disk-reading.txt
@@ -0,0 +1,189 @@
+LVM disk reading
+
+Reading disks happens in two phases. The first is a discovery phase,
+which determines what's on the disks. The second is a working phase,
+which does a particular job for the command.
+
+
+Phase 1: Discovery
+------------------
+
+Read all the disks on the system to find out:
+- What are the LVM devices?
+- What VG's exist on those devices?
+
+This phase is called "label scan" (although it reads and scans everything,
+not just the label.) It stores the information it discovers (what LVM
+devices exist, and what VGs exist on them) in lvmcache. The devs/VGs info
+in lvmcache is the starting point for phase two.
+
+
+Phase 1 in outline:
+
+For each device:
+
+a. Read the first <N> KB of the device. (N is configurable.)
+
+b. Look for the lvm label_header in the first four sectors,
+ if none exists, it's not an lvm device, so quit looking at it.
+ (By default, label_header is in the second sector.)
+
+c. Look at the pv_header, which follows the label_header.
+ This tells us the location of VG metadata on the device.
+ There can be 0, 1 or 2 copies of VG metadata. The first
+ is always at the start of the device, the second (if used)
+ is at the end.
+
+d. Look at the first mda_header (location came from pv_header
+ in the previous step). This is by default in sector 8,
+ 4096 bytes from the start of the device. This tells us the
+ location of the actual VG metadata text.
+
+e. Look at the first copy of the text VG metadata (location came
+ from mda_header in the previous step). This is by default
+ in sector 9, 4608 bytes from the start of the device.
+ The VG metadata is only partially analyzed to create a basic
+ summary of the VG.
+
+f. Store an "info" entry in lvmcache for this device,
+ indicating that it is an lvm device, and store a "vginfo"
+ entry in lvmcache indicating the name of the VG seen
+ in the metadata in step e.
+
+g. If the pv_header in step c shows a second mda_header
+ location at the end of the device, then read that as
+ in step d, and repeat steps e-f for it.
+
+At the end of phase 1, lvmcache will have a list of devices
+that belong to LVM, and a list of VG names that exist on
+those devices. Each device (info struct) is associated
+with the VG (vginfo struct) it is used in.
+
+
+Phase 1 in code:
+
+The most relevant functions are listed for each step in the outline.
+
+lvmcache_label_scan()
+label_scan()
+
+. dev_cache_scan()
+ choose which devices on the system to look at
+
+. for each dev in dev_cache: bcache prefetch/read
+
+. _process_block() to process data from bcache
+ _find_lvm_header() checks if this is an lvm dev by looking at label_header
+ _text_read() via ops->read() looks at mda/pv/vg data to populate lvmcache
+
+. _read_mda_header_and_metadata()
+ raw_read_mda_header()
+
+. _read_mda_header_and_metadata()
+ read_metadata_location()
+ text_read_metadata_summary()
+ config_file_read_fd()
+ _read_vgsummary() via ops->read_vgsummary()
+
+. _text_read(): lvmcache_add()
+ [adds this device to list of lvm devices]
+ _read_mda_header_and_metadata(): lvmcache_update_vgname_and_id()
+ [adds the VG name to list of VGs]
+
+
+Phase 2: Work
+-------------
+
+This phase carries out the operation requested by the command that was
+run.
+
+Whereas the first phase is based on iterating through each device on the
+system, this phase is based on iterating through each VG name. The list
+of VG names comes from phase 1, which stored the list in lvmcache to be
+used by phase 2.
+
+Some commands may need to iterate through all VG names, while others may
+need to iterate through just one or two.
+
+This phase includes locking each VG as work is done on it, so that two
+commands do not interfere with each other.
+
+
+Phase 2 in outline:
+
+For each VG name:
+
+a. Lock the VG.
+
+b. Repeat the phase 1 scan steps for each device in this VG.
+ The phase 1 information in lvmcache may have changed because no VG lock
+ was held during phase 1. So, repeat the phase 1 steps, but only for the
+ devices in this VG. N.B. for commands that are just reporting data,
+ we skip this step if the data from phase 1 was complete and consistent.
+
+c. Get the list of on-disk metadata locations for this VG.
+ Phase 1 created this list in lvmcache to be used here. At this
+ point we copy it out of lvmcache. In the simple/common case,
+ this is a list of devices in the VG. But, some devices may
+ have 0 or 2 metadata locations instead of the default 1, so it
+ is not always equal to the list of devices. We want to read
+ every copy of the metadata for this VG.
+
+d. For each metadata location on each device in the VG
+ (the list from the previous step):
+
+ 1) Look at the mda_header. The location of the mda_header was saved
+ in the lvmcache info struct by phase 1 (where it came from the
+ pv_header.) The mda_header tells us where the text VG metadata is
+ located.
+
+ 2) Look at the text VG metadata. The location came from mda_header
+ in the previous step. The VG metadata is fully analyzed and used
+ to create an in-memory 'struct volume_group'.
+
+e. Compare the copies of VG metadata that were found in each location.
+ If some copies are older, choose the newest one to use, and update
+ any older copies.
+
+f. Update details about the devices/VG in lvmcache.
+
+g. Pass the 'vg' struct to the command-specific code to work with.
+
+
+Phase 2 in code:
+
+The most relevant functions are listed for each step in the outline.
+
+For each VG name:
+ process_each_vg()
+
+. vg_read()
+ lock_vol()
+
+. vg_read()
+ lvmcache_label_rescan_vg() (if needed)
+ [insert phase 1 steps for scanning devs, but only devs in this vg]
+
+. vg_read()
+ create_instance()
+ _text_create_text_instance()
+ _create_vg_text_instance()
+ lvmcache_fid_add_mdas_vg()
+ [Copies mda locations from info->mdas where it was saved
+ by phase 1, into fid->metadata_areas_in_use. This is
+ the key connection between phase 1 and phase 2.]
+
+. dm_list_iterate_items(mda, &fid->metadata_areas_in_use)
+
+ . _vg_read_raw() via ops->vg_read()
+ raw_read_mda_header()
+
+ . _vg_read_raw()
+ text_read_metadata()
+ config_file_read_fd()
+ _read_vg() via ops->read_vg()
+
+. return the 'vg' struct from vg_read() and use it to do
+ command-specific work
+
+
5 years, 12 months
master - tests: bump raid target version in reshape tests
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c9729022bf691a57df2...
Commit: c9729022bf691a57df25bca43995e9a05c9cf130
Parent: 8bf92875f7f4633d457640af2503c06ffdee7f37
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri May 4 16:56:38 2018 +0200
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri May 4 16:58:11 2018 +0200
tests: bump raid target version in reshape tests
Adjust to target version allowing tests to succeed.
---
test/shell/lvconvert-raid-reshape-load.sh | 2 +-
.../lvconvert-raid-reshape-stripes-load-fail.sh | 5 +----
test/shell/lvconvert-raid-reshape-stripes-load.sh | 2 +-
3 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/test/shell/lvconvert-raid-reshape-load.sh b/test/shell/lvconvert-raid-reshape-load.sh
index 23046e5..cd72d09 100644
--- a/test/shell/lvconvert-raid-reshape-load.sh
+++ b/test/shell/lvconvert-raid-reshape-load.sh
@@ -21,7 +21,7 @@ SKIP_WITH_LVMPOLLD=1
test $(aux total_mem) -gt $((4096*1024)) || skip
which mkfs.ext4 || skip
-aux have_raid 1 13 1 || skip
+aux have_raid 1 13 2 || skip
mount_dir="mnt"
diff --git a/test/shell/lvconvert-raid-reshape-stripes-load-fail.sh b/test/shell/lvconvert-raid-reshape-stripes-load-fail.sh
index e7066be..88722b0 100644
--- a/test/shell/lvconvert-raid-reshape-stripes-load-fail.sh
+++ b/test/shell/lvconvert-raid-reshape-stripes-load-fail.sh
@@ -15,16 +15,13 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
-# FIXME - skippping until properly kernel is released
-skip
-
# Test reshaping under io load
# FIXME: This test requires 3GB in /dev/shm!
test $(aux total_mem) -gt $((4096*1024)) || skip
which mkfs.ext4 || skip
-aux have_raid 1 13 1 || skip
+aux have_raid 1 13 2 || skip
mount_dir="mnt"
diff --git a/test/shell/lvconvert-raid-reshape-stripes-load.sh b/test/shell/lvconvert-raid-reshape-stripes-load.sh
index 2143b4c..1be8d61 100644
--- a/test/shell/lvconvert-raid-reshape-stripes-load.sh
+++ b/test/shell/lvconvert-raid-reshape-stripes-load.sh
@@ -21,7 +21,7 @@ SKIP_WITH_LVMPOLLD=1
test $(aux total_mem) -gt $((4096*1024)) || skip
which mkfs.ext4 || skip
-aux have_raid 1 13 1 || skip
+aux have_raid 1 13 2 || skip
mount_dir="mnt"
5 years, 12 months
master - tests: don't rely on cache target in component-raid.sh
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=8bf92875f7f4633d457...
Commit: 8bf92875f7f4633d457640af2503c06ffdee7f37
Parent: bc50dc6e70453c98e45aaa845db2828e586f9370
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Fri May 4 16:53:16 2018 +0200
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Fri May 4 16:54:01 2018 +0200
tests: don't rely on cache target in component-raid.sh
Lead to unnecessary skips of the test.
---
test/shell/component-raid.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/component-raid.sh b/test/shell/component-raid.sh
index 84f823f..4ef9600 100644
--- a/test/shell/component-raid.sh
+++ b/test/shell/component-raid.sh
@@ -17,7 +17,7 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
-aux have_cache 1 3 0 || skip
+aux have_raid 1 3 0 || skip
aux prepare_vg 5 80
5 years, 12 months
master - Merge branch 'master' of git+ssh://sourceware.org/git/lvm2
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=bc50dc6e70453c98e45...
Commit: bc50dc6e70453c98e45aaa845db2828e586f9370
Parent: ed837e6971ee84aa5b112e021df19901ae400216 f4a60fe00444bbb4aa54e32b0bef90a9c4eca704
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Fri May 4 09:49:55 2018 +0100
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Fri May 4 09:49:55 2018 +0100
Merge branch 'master' of git+ssh://sourceware.org/git/lvm2
daemons/clvmd/lvm-functions.c | 1 -
lib/activate/activate.c | 54 +++---
lib/cache/lvmcache.c | 378 ++++++++++++++++++++++++-----------------
lib/cache/lvmcache.h | 11 +-
lib/commands/toolcontext.c | 12 +-
lib/commands/toolcontext.h | 2 +-
lib/metadata/metadata.c | 4 +-
lib/metadata/raid_manip.c | 21 +--
tools/toollib.c | 4 +-
9 files changed, 278 insertions(+), 209 deletions(-)
6 years
master - Revert "build: Calculate dependencies at same time as compiling."
by Joe Thornber
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ed837e6971ee84aa5b1...
Commit: ed837e6971ee84aa5b112e021df19901ae400216
Parent: 49db9b5e0b35f6b0a47ad10276fb252c09f438ef
Author: Joe Thornber <ejt(a)redhat.com>
AuthorDate: Fri May 4 09:48:40 2018 +0100
Committer: Joe Thornber <ejt(a)redhat.com>
CommitterDate: Fri May 4 09:48:40 2018 +0100
Revert "build: Calculate dependencies at same time as compiling."
This reverts commit 0931067dc5549c443e144d599683b53220021f44.
The dep files should be in the build dir, which is not necc. the src dir.
Easy to fix, but reverting for now until I have time to revisit.
---
make.tmpl.in | 19 +++++++++++++------
1 files changed, 13 insertions(+), 6 deletions(-)
diff --git a/make.tmpl.in b/make.tmpl.in
index d3a80ef..9d5d367 100644
--- a/make.tmpl.in
+++ b/make.tmpl.in
@@ -442,14 +442,12 @@ endif
.LIBPATTERNS = lib%.so lib%.a
-DEPFLAGS=-MT $@ -MMD -MP -MF $*.d
-
# still needed in 2018 for 32bit builds
DEFS+=-D_FILE_OFFSET_BITS=64
%.o: %.c
@echo " [CC] $<"
- $(Q) $(CC) $(DEPFLAGS) -c $(INCLUDES) $(VALGRIND_CFLAGS) $(PROGS_CFLAGS) $(DEFS) $(DEFS_$@) $(WFLAGS) $(WCFLAGS) $(CFLAGS) $(CFLAGS_$@) $< -o $@
+ $(Q) $(CC) -c $(INCLUDES) $(VALGRIND_CFLAGS) $(PROGS_CFLAGS) $(DEFS) $(DEFS_$@) $(WFLAGS) $(WCFLAGS) $(CFLAGS) $(CFLAGS_$@) $< -o $@
%.o: %.cpp
@echo " [CXX] $<"
@@ -509,9 +507,18 @@ $(LIB_STATIC): $(OBJECTS)
$(Q) $(RM) $@
$(Q) $(AR) rsv $@ $(OBJECTS) > /dev/null
-%.d: $(INC_LNS)
-.PRECIOUS: %.d
-
+%.d: %.c $(INC_LNS)
+ @echo " [DEP] $<"
+ $(Q) $(MKDIR_P) $(dir $@); \
+ set -e; \
+ FILE=`echo $@ | sed 's/\\//\\\\\\//g;s/\\.d//g'`; \
+ DEPS=`echo $(DEPS) | sed -e 's/\\//\\\\\\//g'`; \
+ $(CC) -MM $(INCLUDES) $(VALGRIND_CFLAGS) $(PROGS_CFLAGS) $(DEFS) -o $@ $<; \
+ sed -i "s/\(.*\)\.o[ :]*/$$FILE.o $$FILE.d $$FILE.pot: $$DEPS /g" $@; \
+ DEPLIST=`sed 's/ \\\\//;s/.*://;' < $@`; \
+ echo $$DEPLIST | fmt -1 | sed 's/ //g;s/\(.*\)/\1:/' >> $@; \
+ [ -s $@ ] || $(RM) $@
+
%.mo: %.po
@echo " [MSGFMT] $<"
$(Q) $(MSGFMT) -o $@ $<
6 years
master - clvmd: saved_vg code and comment formatting
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f4a60fe00444bbb4aa5...
Commit: f4a60fe00444bbb4aa54e32b0bef90a9c4eca704
Parent: 822a8b62be8aa2949d07bcc8b41f019a34ea5b57
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu May 3 11:41:10 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu May 3 14:54:48 2018 -0500
clvmd: saved_vg code and comment formatting
---
lib/cache/lvmcache.c | 88 ++++++++++++++++++++++++--------------------------
1 files changed, 42 insertions(+), 46 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 56ddab8..745e219 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -211,33 +211,32 @@ static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
{
struct vg_list *vgl;
- if (inval_old) {
- if (svg->saved_vg_old)
- log_debug_cache("lvmcache: inval saved_vg %s old %p",
- svg->saved_vg_old->name, svg->saved_vg_old);
-
- if (svg->saved_vg_old) {
- if ((vgl = dm_zalloc(sizeof(*vgl)))) {
- vgl->vg = svg->saved_vg_old;
- dm_list_add(&svg->saved_vg_to_free, &vgl->list);
- }
+ /*
+ * In practice there appears to only ever be a single invalidated vg,
+ * so making saved_vg_to_free a list instead of a pointer is overkill.
+ * But, without proof otherwise, safer to keep the list.
+ */
+
+ if (inval_old && svg->saved_vg_old) {
+ log_debug_cache("lvmcache: inval saved_vg %s old %p",
+ svg->saved_vg_old->name, svg->saved_vg_old);
+
+ if ((vgl = dm_zalloc(sizeof(*vgl)))) {
+ vgl->vg = svg->saved_vg_old;
+ dm_list_add(&svg->saved_vg_to_free, &vgl->list);
}
svg->saved_vg_old = NULL;
}
- if (inval_new) {
- if (svg->saved_vg_new)
- log_debug_cache("lvmcache: inval saved_vg %s new pre %p",
- svg->saved_vg_new->name, svg->saved_vg_new);
+ if (inval_new && svg->saved_vg_new) {
+ log_debug_cache("lvmcache: inval saved_vg %s new pre %p",
+ svg->saved_vg_new->name, svg->saved_vg_new);
- if (svg->saved_vg_new) {
- if ((vgl = dm_zalloc(sizeof(*vgl)))) {
- vgl->vg = svg->saved_vg_new;
- dm_list_add(&svg->saved_vg_to_free, &vgl->list);
- }
+ if ((vgl = dm_zalloc(sizeof(*vgl)))) {
+ vgl->vg = svg->saved_vg_new;
+ dm_list_add(&svg->saved_vg_to_free, &vgl->list);
}
-
svg->saved_vg_new = NULL;
}
}
@@ -245,23 +244,22 @@ static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
static void _saved_vg_free(struct saved_vg *svg, int free_old, int free_new)
{
struct vg_list *vgl, *vgl2;
+ struct volume_group *vg;
if (free_old) {
- if (svg->saved_vg_old) {
- log_debug_cache("lvmcache: free saved_vg %s old %p",
- svg->saved_vg_old->name, svg->saved_vg_old);
+ if ((vg = svg->saved_vg_old)) {
+ log_debug_cache("lvmcache: free saved_vg old %s %.8s %d old %p",
+ vg->name, (char *)&vg->id, vg->seqno, vg);
- svg->saved_vg_old->saved_in_clvmd = 0;
+ vg->saved_in_clvmd = 0;
+ release_vg(vg);
+ svg->saved_vg_old = NULL;
+ vg = NULL;
}
- if (svg->saved_vg_old)
- release_vg(svg->saved_vg_old);
-
- svg->saved_vg_old = NULL;
-
dm_list_iterate_items_safe(vgl, vgl2, &svg->saved_vg_to_free) {
- log_debug_cache("lvmcache: free saved_vg_to_free %s %p",
- vgl->vg->name, vgl->vg);
+ log_debug_cache("lvmcache: free saved_vg_to_free %s %.8s %d %p",
+ vgl->vg->name, (char *)&vgl->vg->id, vgl->vg->seqno, vgl->vg);
dm_list_del(&vgl->list);
vgl->vg->saved_in_clvmd = 0;
@@ -270,17 +268,15 @@ static void _saved_vg_free(struct saved_vg *svg, int free_old, int free_new)
}
if (free_new) {
- if (svg->saved_vg_new) {
- log_debug_cache("lvmcache: free saved_vg %s new pre %p",
- svg->saved_vg_new->name, svg->saved_vg_new);
+ if ((vg = svg->saved_vg_new)) {
+ log_debug_cache("lvmcache: free saved_vg pre %s %.8s %d %p",
+ vg->name, (char *)&vg->id, vg->seqno, vg);
- svg->saved_vg_new->saved_in_clvmd = 0;
+ vg->saved_in_clvmd = 0;
+ release_vg(vg);
+ svg->saved_vg_new = NULL;
+ vg = NULL;
}
-
- if (svg->saved_vg_new)
- release_vg(svg->saved_vg_new);
-
- svg->saved_vg_new = NULL;
}
}
@@ -419,10 +415,10 @@ struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted)
if (vg && new) {
if (!svg->saved_vg_old)
- log_debug_cache("lvmcache: get new (pre) saved_vg %d %s %p",
+ log_debug_cache("lvmcache: get new saved_vg %d %s %p",
vg->seqno, vg->name, vg);
else
- log_debug_cache("lvmcache: get new (pre) saved_vg %d %s %p old is %d %p",
+ log_debug_cache("lvmcache: get new saved_vg %d %s %p old is %d %p",
vg->seqno, vg->name, vg,
svg->saved_vg_old->seqno,
svg->saved_vg_old);
@@ -484,10 +480,10 @@ struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid)
if (vg && new) {
if (!svg->saved_vg_old)
- log_debug_cache("lvmcache: get_latest new (pre) saved_vg %d %s %p",
+ log_debug_cache("lvmcache: get_latest new saved_vg %d %s %p",
vg->seqno, vg->name, vg);
else
- log_debug_cache("lvmcache: get_latest new (pre) saved_vg %d %s %p old is %d %p",
+ log_debug_cache("lvmcache: get_latest new saved_vg %d %s %p old is %d %p",
vg->seqno, vg->name, vg,
svg->saved_vg_old->seqno,
svg->saved_vg_old);
6 years
master - clvmd: don't save cft and buf for saved_vg
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=822a8b62be8aa2949d0...
Commit: 822a8b62be8aa2949d07bcc8b41f019a34ea5b57
Parent: c016b573ee32ff836f1d427d5cf58eb6480cf7b8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Thu May 3 10:50:38 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu May 3 14:54:48 2018 -0500
clvmd: don't save cft and buf for saved_vg
---
lib/cache/lvmcache.c | 38 --------------------------------------
1 files changed, 0 insertions(+), 38 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 506bcdf..56ddab8 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -87,11 +87,7 @@ struct saved_vg {
*/
char vgid[ID_LEN + 1];
int saved_vg_committed;
- char *saved_vg_old_buf;
- struct dm_config_tree *saved_vg_old_cft;
struct volume_group *saved_vg_old;
- char *saved_vg_new_buf;
- struct dm_config_tree *saved_vg_new_cft;
struct volume_group *saved_vg_new;
struct dm_list saved_vg_to_free;
};
@@ -220,11 +216,6 @@ static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
log_debug_cache("lvmcache: inval saved_vg %s old %p",
svg->saved_vg_old->name, svg->saved_vg_old);
- if (svg->saved_vg_old_buf)
- dm_free(svg->saved_vg_old_buf);
- if (svg->saved_vg_old_cft)
- dm_config_destroy(svg->saved_vg_old_cft);
-
if (svg->saved_vg_old) {
if ((vgl = dm_zalloc(sizeof(*vgl)))) {
vgl->vg = svg->saved_vg_old;
@@ -232,8 +223,6 @@ static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
}
}
- svg->saved_vg_old_buf = NULL;
- svg->saved_vg_old_cft = NULL;
svg->saved_vg_old = NULL;
}
@@ -242,11 +231,6 @@ static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
log_debug_cache("lvmcache: inval saved_vg %s new pre %p",
svg->saved_vg_new->name, svg->saved_vg_new);
- if (svg->saved_vg_new_buf)
- dm_free(svg->saved_vg_new_buf);
- if (svg->saved_vg_new_cft)
- dm_config_destroy(svg->saved_vg_new_cft);
-
if (svg->saved_vg_new) {
if ((vgl = dm_zalloc(sizeof(*vgl)))) {
vgl->vg = svg->saved_vg_new;
@@ -254,8 +238,6 @@ static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
}
}
- svg->saved_vg_new_buf = NULL;
- svg->saved_vg_new_cft = NULL;
svg->saved_vg_new = NULL;
}
}
@@ -272,15 +254,9 @@ static void _saved_vg_free(struct saved_vg *svg, int free_old, int free_new)
svg->saved_vg_old->saved_in_clvmd = 0;
}
- if (svg->saved_vg_old_buf)
- dm_free(svg->saved_vg_old_buf);
- if (svg->saved_vg_old_cft)
- dm_config_destroy(svg->saved_vg_old_cft);
if (svg->saved_vg_old)
release_vg(svg->saved_vg_old);
- svg->saved_vg_old_buf = NULL;
- svg->saved_vg_old_cft = NULL;
svg->saved_vg_old = NULL;
dm_list_iterate_items_safe(vgl, vgl2, &svg->saved_vg_to_free) {
@@ -301,15 +277,9 @@ static void _saved_vg_free(struct saved_vg *svg, int free_old, int free_new)
svg->saved_vg_new->saved_in_clvmd = 0;
}
- if (svg->saved_vg_new_buf)
- dm_free(svg->saved_vg_new_buf);
- if (svg->saved_vg_new_cft)
- dm_config_destroy(svg->saved_vg_new_cft);
if (svg->saved_vg_new)
release_vg(svg->saved_vg_new);
- svg->saved_vg_new_buf = NULL;
- svg->saved_vg_new_cft = NULL;
svg->saved_vg_new = NULL;
}
}
@@ -396,18 +366,10 @@ void lvmcache_save_vg(struct volume_group *vg, int precommitted)
save_vg->saved_in_clvmd = 1;
if (old) {
- /*
- svg->saved_vg_old_buf = save_buf;
- svg->saved_vg_old_cft = save_cft;
- */
svg->saved_vg_old = save_vg;
log_debug_cache("lvmcache: saved old vg %s seqno %d %p",
save_vg->name, save_vg->seqno, save_vg);
} else {
- /*
- svg->saved_vg_new_buf = save_buf;
- svg->saved_vg_new_cft = save_cft;
- */
svg->saved_vg_new = save_vg;
log_debug_cache("lvmcache: saved pre vg %s seqno %d %p",
save_vg->name, save_vg->seqno, save_vg);
6 years
master - clvmd: separate saved_vg from vginfo
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c016b573ee32ff836f1...
Commit: c016b573ee32ff836f1d427d5cf58eb6480cf7b8
Parent: a5e13f2eef5314666e19923a03ae01f479a74fd8
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed May 2 16:58:49 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu May 3 14:54:48 2018 -0500
clvmd: separate saved_vg from vginfo
The clvmd saved_vg data is independent from the normal lvm
lvmcache vginfo data, so separate saved_vg from vginfo.
Normal lvm doesn't need to use save_vg at all, and in clvmd,
lvmcache changes on vginfo can be made without worrying
about unwanted effects on saved_vg.
---
daemons/clvmd/lvm-functions.c | 1 -
lib/cache/lvmcache.c | 399 +++++++++++++++++++++-------------------
lib/cache/lvmcache.h | 10 +-
lib/commands/toolcontext.c | 12 +-
lib/commands/toolcontext.h | 2 +-
lib/metadata/metadata.c | 4 +-
tools/toollib.c | 4 +-
7 files changed, 231 insertions(+), 201 deletions(-)
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index 3bb00d3..34da66d 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -903,7 +903,6 @@ int init_clvm(struct dm_hash_table *excl_uuid)
return 0;
}
- cmd->is_clvmd = 1;
cmd->cmd_line = "clvmd";
/* Check lvm.conf is setup for cluster-LVM */
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 6d50545..506bcdf 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -63,11 +63,12 @@ struct lvmcache_vginfo {
int seqno;
int independent_metadata_location; /* metadata read from independent areas */
int scan_summary_mismatch; /* vgsummary from devs had mismatching seqno or checksum */
+};
+struct saved_vg {
/*
- * The following are not related to lvmcache or vginfo,
- * but are borrowing the vginfo to store the data.
* saved_vg_* are used only by clvmd.
+ * It is not related to lvmcache or vginfo.
*
* For activation/deactivation, these are used to avoid
* clvmd rereading a VG for each LV that is activated.
@@ -83,13 +84,8 @@ struct lvmcache_vginfo {
*
* saved_vg_committed is set to 1 when clvmd gets
* LCK_VG_COMMIT from vg_commit().
- *
- * This data does not really belong in lvmcache, it's unrelated
- * to lvmcache or vginfo, but it's just a convenient place
- * for clvmd to stash the VG (since the same caller isn't
- * present to pass the VG to both suspend and resume in the
- * case of clvmd.)
*/
+ char vgid[ID_LEN + 1];
int saved_vg_committed;
char *saved_vg_old_buf;
struct dm_config_tree *saved_vg_old_cft;
@@ -104,6 +100,7 @@ static struct dm_hash_table *_pvid_hash = NULL;
static struct dm_hash_table *_vgid_hash = NULL;
static struct dm_hash_table *_vgname_hash = NULL;
static struct dm_hash_table *_lock_hash = NULL;
+static struct dm_hash_table *_saved_vg_hash = NULL;
static DM_LIST_INIT(_vginfos);
static DM_LIST_INIT(_found_duplicate_devs);
static DM_LIST_INIT(_unused_duplicate_devs);
@@ -114,7 +111,7 @@ static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
static int _suppress_lock_ordering = 0;
-int lvmcache_init(void)
+int lvmcache_init(struct cmd_context *cmd)
{
/*
* FIXME add a proper lvmcache_locking_reset() that
@@ -138,6 +135,11 @@ int lvmcache_init(void)
if (!(_lock_hash = dm_hash_create(128)))
return 0;
+ if (cmd->is_clvmd) {
+ if (!(_saved_vg_hash = dm_hash_create(128)))
+ return 0;
+ }
+
/*
* Reinitialising the cache clears the internal record of
* which locks are held. The global lock can be held during
@@ -193,79 +195,95 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
-static void _saved_vg_inval(struct lvmcache_vginfo *vginfo, int inval_old, int inval_new)
+static struct saved_vg *_saved_vg_from_vgid(const char *vgid)
+{
+ struct saved_vg *svg;
+ char id[ID_LEN + 1] __attribute__((aligned(8)));
+
+ /* vgid not necessarily NULL-terminated */
+ (void) dm_strncpy(id, vgid, sizeof(id));
+
+ if (!(svg = dm_hash_lookup(_saved_vg_hash, id))) {
+ log_debug_cache("lvmcache: no saved_vg for vgid \"%s\"", id);
+ return NULL;
+ }
+
+ return svg;
+}
+
+static void _saved_vg_inval(struct saved_vg *svg, int inval_old, int inval_new)
{
struct vg_list *vgl;
if (inval_old) {
- if (vginfo->saved_vg_old)
+ if (svg->saved_vg_old)
log_debug_cache("lvmcache: inval saved_vg %s old %p",
- vginfo->saved_vg_old->name, vginfo->saved_vg_old);
+ svg->saved_vg_old->name, svg->saved_vg_old);
- if (vginfo->saved_vg_old_buf)
- dm_free(vginfo->saved_vg_old_buf);
- if (vginfo->saved_vg_old_cft)
- dm_config_destroy(vginfo->saved_vg_old_cft);
+ if (svg->saved_vg_old_buf)
+ dm_free(svg->saved_vg_old_buf);
+ if (svg->saved_vg_old_cft)
+ dm_config_destroy(svg->saved_vg_old_cft);
- if (vginfo->saved_vg_old) {
+ if (svg->saved_vg_old) {
if ((vgl = dm_zalloc(sizeof(*vgl)))) {
- vgl->vg = vginfo->saved_vg_old;
- dm_list_add(&vginfo->saved_vg_to_free, &vgl->list);
+ vgl->vg = svg->saved_vg_old;
+ dm_list_add(&svg->saved_vg_to_free, &vgl->list);
}
}
- vginfo->saved_vg_old_buf = NULL;
- vginfo->saved_vg_old_cft = NULL;
- vginfo->saved_vg_old = NULL;
+ svg->saved_vg_old_buf = NULL;
+ svg->saved_vg_old_cft = NULL;
+ svg->saved_vg_old = NULL;
}
if (inval_new) {
- if (vginfo->saved_vg_new)
+ if (svg->saved_vg_new)
log_debug_cache("lvmcache: inval saved_vg %s new pre %p",
- vginfo->saved_vg_new->name, vginfo->saved_vg_new);
+ svg->saved_vg_new->name, svg->saved_vg_new);
- if (vginfo->saved_vg_new_buf)
- dm_free(vginfo->saved_vg_new_buf);
- if (vginfo->saved_vg_new_cft)
- dm_config_destroy(vginfo->saved_vg_new_cft);
+ if (svg->saved_vg_new_buf)
+ dm_free(svg->saved_vg_new_buf);
+ if (svg->saved_vg_new_cft)
+ dm_config_destroy(svg->saved_vg_new_cft);
- if (vginfo->saved_vg_new) {
+ if (svg->saved_vg_new) {
if ((vgl = dm_zalloc(sizeof(*vgl)))) {
- vgl->vg = vginfo->saved_vg_new;
- dm_list_add(&vginfo->saved_vg_to_free, &vgl->list);
+ vgl->vg = svg->saved_vg_new;
+ dm_list_add(&svg->saved_vg_to_free, &vgl->list);
}
}
- vginfo->saved_vg_new_buf = NULL;
- vginfo->saved_vg_new_cft = NULL;
- vginfo->saved_vg_new = NULL;
+ svg->saved_vg_new_buf = NULL;
+ svg->saved_vg_new_cft = NULL;
+ svg->saved_vg_new = NULL;
}
}
-static void _saved_vg_free(struct lvmcache_vginfo *vginfo, int free_old, int free_new)
+static void _saved_vg_free(struct saved_vg *svg, int free_old, int free_new)
{
struct vg_list *vgl, *vgl2;
if (free_old) {
- if (vginfo->saved_vg_old) {
+ if (svg->saved_vg_old) {
log_debug_cache("lvmcache: free saved_vg %s old %p",
- vginfo->saved_vg_old->name, vginfo->saved_vg_old);
+ svg->saved_vg_old->name, svg->saved_vg_old);
- vginfo->saved_vg_old->saved_in_clvmd = 0;
+ svg->saved_vg_old->saved_in_clvmd = 0;
}
- if (vginfo->saved_vg_old_buf)
- dm_free(vginfo->saved_vg_old_buf);
- if (vginfo->saved_vg_old_cft)
- dm_config_destroy(vginfo->saved_vg_old_cft);
- if (vginfo->saved_vg_old)
- release_vg(vginfo->saved_vg_old);
+ if (svg->saved_vg_old_buf)
+ dm_free(svg->saved_vg_old_buf);
+ if (svg->saved_vg_old_cft)
+ dm_config_destroy(svg->saved_vg_old_cft);
+ if (svg->saved_vg_old)
+ release_vg(svg->saved_vg_old);
- vginfo->saved_vg_old_buf = NULL;
- vginfo->saved_vg_old_cft = NULL;
- vginfo->saved_vg_old = NULL;
+ svg->saved_vg_old_buf = NULL;
+ svg->saved_vg_old_cft = NULL;
+ svg->saved_vg_old = NULL;
- dm_list_iterate_items_safe(vgl, vgl2, &vginfo->saved_vg_to_free) {
+ dm_list_iterate_items_safe(vgl, vgl2, &svg->saved_vg_to_free) {
log_debug_cache("lvmcache: free saved_vg_to_free %s %p",
vgl->vg->name, vgl->vg);
@@ -276,111 +294,144 @@ static void _saved_vg_free(struct lvmcache_vginfo *vginfo, int free_old, int fre
}
if (free_new) {
- if (vginfo->saved_vg_new) {
+ if (svg->saved_vg_new) {
log_debug_cache("lvmcache: free saved_vg %s new pre %p",
- vginfo->saved_vg_new->name, vginfo->saved_vg_new);
+ svg->saved_vg_new->name, svg->saved_vg_new);
- vginfo->saved_vg_new->saved_in_clvmd = 0;
+ svg->saved_vg_new->saved_in_clvmd = 0;
}
- if (vginfo->saved_vg_new_buf)
- dm_free(vginfo->saved_vg_new_buf);
- if (vginfo->saved_vg_new_cft)
- dm_config_destroy(vginfo->saved_vg_new_cft);
- if (vginfo->saved_vg_new)
- release_vg(vginfo->saved_vg_new);
+ if (svg->saved_vg_new_buf)
+ dm_free(svg->saved_vg_new_buf);
+ if (svg->saved_vg_new_cft)
+ dm_config_destroy(svg->saved_vg_new_cft);
+ if (svg->saved_vg_new)
+ release_vg(svg->saved_vg_new);
- vginfo->saved_vg_new_buf = NULL;
- vginfo->saved_vg_new_cft = NULL;
- vginfo->saved_vg_new = NULL;
+ svg->saved_vg_new_buf = NULL;
+ svg->saved_vg_new_cft = NULL;
+ svg->saved_vg_new = NULL;
}
}
static void _drop_metadata(const char *vgname, int drop_precommitted)
{
struct lvmcache_vginfo *vginfo;
+ struct saved_vg *svg;
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)))
return;
+ if (!(svg = _saved_vg_from_vgid(vginfo->vgid)))
+ return;
+
if (drop_precommitted)
- _saved_vg_free(vginfo, 0, 1);
+ _saved_vg_free(svg, 0, 1);
else
- _saved_vg_free(vginfo, 1, 1);
+ _saved_vg_free(svg, 1, 1);
}
void lvmcache_save_vg(struct volume_group *vg, int precommitted)
{
- struct lvmcache_vginfo *vginfo;
+ struct saved_vg *svg;
struct format_instance *fid;
struct format_instance_ctx fic;
struct volume_group *save_vg = NULL;
- struct dm_config_tree *susp_cft = NULL;
- char *susp_buf = NULL;
+ struct dm_config_tree *save_cft = NULL;
+ const struct format_type *fmt;
+ char *save_buf = NULL;
size_t size;
int new = precommitted;
int old = !precommitted;
- if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id)))
- goto_bad;
+ if (!(svg = _saved_vg_from_vgid((const char *)&vg->id))) {
+ /* Nothing is saved yet for this vg */
- /* already saved */
- if (old && vginfo->saved_vg_old &&
- (vginfo->saved_vg_old->seqno == vg->seqno))
- return;
+ if (!(svg = dm_zalloc(sizeof(*svg))))
+ return;
- /* already saved */
- if (new && vginfo->saved_vg_new &&
- (vginfo->saved_vg_new->seqno == vg->seqno))
- return;
+ dm_list_init(&svg->saved_vg_to_free);
+
+ dm_strncpy(svg->vgid, (const char *)vg->id.uuid, sizeof(svg->vgid));
+
+ if (!dm_hash_insert(_saved_vg_hash, svg->vgid, svg)) {
+ log_error("lvmcache: failed to insert saved_vg %s", svg->vgid);
+ return;
+ }
+ } else {
+ /* Nothing to do if we've already saved this seqno */
+
+ if (old && svg->saved_vg_old && (svg->saved_vg_old->seqno == vg->seqno))
+ return;
+
+ if (new && svg->saved_vg_new && (svg->saved_vg_new->seqno == vg->seqno))
+ return;
+
+ /* Invalidate the existing saved_vg that will be replaced */
+
+ _saved_vg_inval(svg, old, new);
+ }
- _saved_vg_inval(vginfo, old, new);
- if (!(size = export_vg_to_buffer(vg, &susp_buf)))
+ if (!(size = export_vg_to_buffer(vg, &save_buf)))
goto_bad;
+ fmt = vg->fid->fmt;
fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
- fic.context.vg_ref.vg_name = vginfo->vgname;
- fic.context.vg_ref.vg_id = vginfo->vgid;
- if (!(fid = vginfo->fmt->ops->create_instance(vginfo->fmt, &fic)))
+ fic.context.vg_ref.vg_name = vg->name;
+ fic.context.vg_ref.vg_id = svg->vgid;
+
+ if (!(fid = fmt->ops->create_instance(fmt, &fic)))
goto_bad;
- if (!(susp_cft = config_tree_from_string_without_dup_node_check(susp_buf)))
+ if (!(save_cft = config_tree_from_string_without_dup_node_check(save_buf)))
goto_bad;
- if (!(save_vg = import_vg_from_config_tree(susp_cft, fid)))
+ if (!(save_vg = import_vg_from_config_tree(save_cft, fid)))
goto_bad;
+ dm_free(save_buf);
+ dm_config_destroy(save_cft);
+
save_vg->saved_in_clvmd = 1;
if (old) {
- vginfo->saved_vg_old_buf = susp_buf;
- vginfo->saved_vg_old_cft = susp_cft;
- vginfo->saved_vg_old = save_vg;
- log_debug_cache("lvmcache saved old vg %s seqno %d %p",
+ /*
+ svg->saved_vg_old_buf = save_buf;
+ svg->saved_vg_old_cft = save_cft;
+ */
+ svg->saved_vg_old = save_vg;
+ log_debug_cache("lvmcache: saved old vg %s seqno %d %p",
save_vg->name, save_vg->seqno, save_vg);
} else {
- vginfo->saved_vg_new_buf = susp_buf;
- vginfo->saved_vg_new_cft = susp_cft;
- vginfo->saved_vg_new = save_vg;
- log_debug_cache("lvmcache saved pre vg %s seqno %d %p",
+ /*
+ svg->saved_vg_new_buf = save_buf;
+ svg->saved_vg_new_cft = save_cft;
+ */
+ svg->saved_vg_new = save_vg;
+ log_debug_cache("lvmcache: saved pre vg %s seqno %d %p",
save_vg->name, save_vg->seqno, save_vg);
}
return;
bad:
- _saved_vg_inval(vginfo, old, new);
- log_debug_cache("lvmcache failed to save pre %d vg %s", precommitted, vg->name);
+ if (save_buf)
+ dm_free(save_buf);
+ if (save_cft)
+ dm_config_destroy(save_cft);
+
+ _saved_vg_inval(svg, old, new);
+ log_debug_cache("lvmcache: failed to save pre %d vg %s", precommitted, vg->name);
}
struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted)
{
- struct lvmcache_vginfo *vginfo;
+ struct saved_vg *svg;
struct volume_group *vg = NULL;
int new = precommitted;
int old = !precommitted;
- if (!(vginfo = lvmcache_vginfo_from_vgid(vgid)))
+ if (!(svg = _saved_vg_from_vgid(vgid)))
goto out;
/*
@@ -389,118 +440,116 @@ struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted)
*/
if (new)
- vg = vginfo->saved_vg_new;
+ vg = svg->saved_vg_new;
else if (old)
- vg = vginfo->saved_vg_old;
+ vg = svg->saved_vg_old;
if (vg && old) {
- if (!vginfo->saved_vg_new)
+ if (!svg->saved_vg_new)
log_debug_cache("lvmcache: get old saved_vg %d %s %p",
vg->seqno, vg->name, vg);
else
log_debug_cache("lvmcache: get old saved_vg %d %s %p new is %d %p",
vg->seqno, vg->name, vg,
- vginfo->saved_vg_new->seqno,
- vginfo->saved_vg_new);
+ svg->saved_vg_new->seqno,
+ svg->saved_vg_new);
}
if (vg && new) {
- if (!vginfo->saved_vg_old)
+ if (!svg->saved_vg_old)
log_debug_cache("lvmcache: get new (pre) saved_vg %d %s %p",
vg->seqno, vg->name, vg);
else
log_debug_cache("lvmcache: get new (pre) saved_vg %d %s %p old is %d %p",
vg->seqno, vg->name, vg,
- vginfo->saved_vg_old->seqno,
- vginfo->saved_vg_old);
+ svg->saved_vg_old->seqno,
+ svg->saved_vg_old);
- if (vginfo->saved_vg_old && (vginfo->saved_vg_old->seqno < vg->seqno)) {
+ if (svg->saved_vg_old && (svg->saved_vg_old->seqno < vg->seqno)) {
log_debug_cache("lvmcache: inval saved_vg_old %d %p for new %d %p %s",
- vginfo->saved_vg_old->seqno, vginfo->saved_vg_old,
+ svg->saved_vg_old->seqno, svg->saved_vg_old,
vg->seqno, vg, vg->name);
- _saved_vg_inval(vginfo, 1, 0);
+ _saved_vg_inval(svg, 1, 0);
}
}
- if (!vg && new && vginfo->saved_vg_old)
+ if (!vg && new && svg->saved_vg_old)
log_warn("lvmcache_get_saved_vg pre %d wanted new but only have old %d %s",
precommitted,
- vginfo->saved_vg_old->seqno,
- vginfo->saved_vg_old->name);
+ svg->saved_vg_old->seqno,
+ svg->saved_vg_old->name);
- if (!vg && old && vginfo->saved_vg_new)
+ if (!vg && old && svg->saved_vg_new)
log_warn("lvmcache_get_saved_vg pre %d wanted old but only have new %d %s",
precommitted,
- vginfo->saved_vg_new->seqno,
- vginfo->saved_vg_new->name);
+ svg->saved_vg_new->seqno,
+ svg->saved_vg_new->name);
out:
if (!vg)
- log_debug_cache("lvmcache no saved vg %s pre %d", vgid, precommitted);
+ log_debug_cache("lvmcache: no saved pre %d %s", precommitted, vgid);
return vg;
}
struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid)
{
- struct lvmcache_vginfo *vginfo;
+ struct saved_vg *svg;
struct volume_group *vg = NULL;
int old = 0;
int new = 0;
- if (!(vginfo = lvmcache_vginfo_from_vgid(vgid)))
+ if (!(svg = _saved_vg_from_vgid(vgid)))
goto out;
- if (vginfo->saved_vg_committed) {
- vg = vginfo->saved_vg_new;
+ if (svg->saved_vg_committed) {
+ vg = svg->saved_vg_new;
new = 1;
} else {
- vg = vginfo->saved_vg_old;
+ vg = svg->saved_vg_old;
old = 1;
}
if (vg && old) {
- if (!vginfo->saved_vg_new)
+ if (!svg->saved_vg_new)
log_debug_cache("lvmcache: get_latest old saved_vg %d %s %p",
vg->seqno, vg->name, vg);
else
log_debug_cache("lvmcache: get_latest old saved_vg %d %s %p new is %d %p",
vg->seqno, vg->name, vg,
- vginfo->saved_vg_new->seqno,
- vginfo->saved_vg_new);
+ svg->saved_vg_new->seqno,
+ svg->saved_vg_new);
}
if (vg && new) {
- if (!vginfo->saved_vg_old)
+ if (!svg->saved_vg_old)
log_debug_cache("lvmcache: get_latest new (pre) saved_vg %d %s %p",
vg->seqno, vg->name, vg);
else
log_debug_cache("lvmcache: get_latest new (pre) saved_vg %d %s %p old is %d %p",
vg->seqno, vg->name, vg,
- vginfo->saved_vg_old->seqno,
- vginfo->saved_vg_old);
+ svg->saved_vg_old->seqno,
+ svg->saved_vg_old);
- if (vginfo->saved_vg_old && (vginfo->saved_vg_old->seqno < vg->seqno)) {
+ if (svg->saved_vg_old && (svg->saved_vg_old->seqno < vg->seqno)) {
log_debug_cache("lvmcache: inval saved_vg_old %d %p for new %d %p %s",
- vginfo->saved_vg_old->seqno, vginfo->saved_vg_old,
+ svg->saved_vg_old->seqno, svg->saved_vg_old,
vg->seqno, vg, vg->name);
- _saved_vg_inval(vginfo, 1, 0);
+ _saved_vg_inval(svg, 1, 0);
}
}
out:
if (!vg)
- log_debug_cache("lvmcache no saved vg %s", vgid);
+ log_debug_cache("lvmcache: no saved vg latest %s", vgid);
return vg;
}
void lvmcache_drop_saved_vgid(const char *vgid)
{
- struct lvmcache_vginfo *vginfo;
+ struct saved_vg *svg;
- if (!(vginfo = lvmcache_vginfo_from_vgid(vgid)))
- return;
-
- _saved_vg_inval(vginfo, 1, 1);
+ if ((svg = _saved_vg_from_vgid(vgid)))
+ _saved_vg_inval(svg, 1, 1);
}
/*
@@ -511,15 +560,20 @@ void lvmcache_drop_saved_vgid(const char *vgid)
void lvmcache_commit_metadata(const char *vgname)
{
struct lvmcache_vginfo *vginfo;
+ struct saved_vg *svg;
if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, NULL)))
return;
- vginfo->saved_vg_committed = 1;
+ if ((svg = _saved_vg_from_vgid(vginfo->vgid)))
+ svg->saved_vg_committed = 1;
}
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
{
+ if (!_saved_vg_hash)
+ return;
+
if (lvmcache_vgname_is_locked(VG_GLOBAL))
return;
@@ -597,11 +651,6 @@ int lvmcache_verify_lock_order(const char *vgname)
void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unused)))
{
- if (!_lock_hash && !lvmcache_init()) {
- log_error("Internal cache initialisation failed");
- return;
- }
-
if (dm_hash_lookup(_lock_hash, vgname))
log_error(INTERNAL_ERROR "Nested locking attempted on VG %s.",
vgname);
@@ -1230,28 +1279,6 @@ next:
goto next;
}
-static void _move_saved_vg(struct lvmcache_vginfo *to, struct lvmcache_vginfo *from)
-{
- to->saved_vg_committed = from->saved_vg_committed;
- to->saved_vg_old_buf = from->saved_vg_old_buf;
- to->saved_vg_old_cft = from->saved_vg_old_cft;
- to->saved_vg_old = from->saved_vg_old;
- to->saved_vg_new_buf = from->saved_vg_new_buf;
- to->saved_vg_new_cft = from->saved_vg_new_cft;
- to->saved_vg_new = from->saved_vg_new;
-
- from->saved_vg_committed= 0;
- from->saved_vg_old_buf = NULL;
- from->saved_vg_old_cft = NULL;
- from->saved_vg_old = NULL;
- from->saved_vg_new_buf = NULL;
- from->saved_vg_new_cft = NULL;
- from->saved_vg_new = NULL;
-
- dm_list_init(&to->saved_vg_to_free);
- dm_list_splice(&to->saved_vg_to_free, &from->saved_vg_to_free);
-}
-
/*
* The initial label_scan at the start of the command is done without
* holding VG locks. Then for each VG identified during the label_scan,
@@ -1295,7 +1322,7 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
{
struct dm_list devs;
struct device_list *devl;
- struct lvmcache_vginfo *vginfo, *tmp;
+ struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info, *info2;
if (lvmetad_used())
@@ -1325,15 +1352,6 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
dm_list_add(&devs, &devl->list);
}
- /*
- * clvmd stashes some copies of a vg on the vginfo struct
- * (FIXME: it shouldn't abuse vginfo and should use its own struct),
- * so when we replace vginfo in clvmd, we need to move the stashed
- * vg's from the old vginfo struct to the new vginfo struct.
- */
- if (cmd->is_clvmd && (tmp = dm_zalloc(sizeof(*tmp))))
- _move_saved_vg(tmp, vginfo);
-
dm_list_iterate_items_safe(info, info2, &vginfo->infos)
lvmcache_del(info);
@@ -1351,11 +1369,6 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
return 0;
}
- if (cmd->is_clvmd && tmp) {
- _move_saved_vg(vginfo, tmp);
- dm_free(tmp);
- }
-
return 1;
}
@@ -1409,11 +1422,6 @@ int lvmcache_label_scan(struct cmd_context *cmd)
_scanning_in_progress = 1;
- if (!_vgname_hash && !lvmcache_init()) {
- log_error("Internal cache initialisation failed");
- goto out;
- }
-
/* FIXME: can this happen? */
if (!cmd->full_filter) {
log_error("label scan is missing full filter");
@@ -1708,7 +1716,6 @@ static int _free_vginfo(struct lvmcache_vginfo *vginfo)
dm_free(vginfo->system_id);
dm_free(vginfo->vgname);
dm_free(vginfo->creation_host);
- _saved_vg_free(vginfo, 1, 1);
if (*vginfo->vgid && _vgid_hash &&
lvmcache_vginfo_from_vgid(vginfo->vgid) == vginfo)
@@ -1922,7 +1929,6 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
return 0;
}
dm_list_init(&vginfo->infos);
- dm_list_init(&vginfo->saved_vg_to_free);
/*
* A different VG (different uuid) can exist with the same name.
@@ -2045,11 +2051,6 @@ out:
int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
{
- if (!_lock_hash && !lvmcache_init()) {
- log_error("Internal cache initialisation failed");
- return 0;
- }
-
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
}
@@ -2419,6 +2420,11 @@ static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
dm_hash_get_key(_lock_hash, n));
}
+static void _destroy_saved_vg(struct saved_vg *svg)
+{
+ _saved_vg_free(svg, 1, 1);
+}
+
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
{
struct dm_hash_node *n;
@@ -2455,6 +2461,12 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
_lock_hash = NULL;
}
+ if (_saved_vg_hash) {
+ dm_hash_iter(_saved_vg_hash, (dm_hash_iterate_fn) _destroy_saved_vg);
+ dm_hash_destroy(_saved_vg_hash);
+ _saved_vg_hash = NULL;
+ }
+
if (!dm_list_empty(&_vginfos))
log_error(INTERNAL_ERROR "_vginfos list should be empty");
dm_list_init(&_vginfos);
@@ -2475,9 +2487,16 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
_destroy_duplicate_device_list(&_found_duplicate_devs); /* should be empty anyway */
_found_duplicate_pvs = 0;
- if (retain_orphans)
- if (!init_lvmcache_orphans(cmd))
- stack;
+ if (retain_orphans) {
+ struct format_type *fmt;
+
+ lvmcache_init(cmd);
+
+ dm_list_iterate_items(fmt, &cmd->formats) {
+ if (!lvmcache_add_orphan_vginfo(fmt->orphan_vg_name, fmt))
+ stack;
+ }
+ }
}
int lvmcache_pvid_is_locked(const char *pvid) {
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 20ce74b..797ff21 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -63,7 +63,7 @@ struct lvmcache_vgsummary {
int seqno;
};
-int lvmcache_init(void);
+int lvmcache_init(struct cmd_context *cmd);
void lvmcache_allow_reads_with_lvmetad(void);
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
@@ -213,11 +213,15 @@ int lvmcache_get_vg_devs(struct cmd_context *cmd,
struct dm_list *devs);
void lvmcache_set_independent_location(const char *vgname);
+int lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
+
+/*
+ * These are clvmd-specific functions and are not related to lvmcache.
+ * FIXME: rename these with a clvm_ prefix in place of lvmcache_
+ */
void lvmcache_save_vg(struct volume_group *vg, int precommitted);
struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted);
struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid);
void lvmcache_drop_saved_vgid(const char *vgid);
-int lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
-
#endif
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 76e15e0..4fdd62f 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1814,7 +1814,7 @@ out:
}
/* Entry point */
-struct cmd_context *create_toolcontext(unsigned is_long_lived,
+struct cmd_context *create_toolcontext(unsigned is_clvmd,
const char *system_dir,
unsigned set_buffering,
unsigned threaded,
@@ -1841,7 +1841,8 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
log_error("Failed to allocate command context");
return NULL;
}
- cmd->is_long_lived = is_long_lived;
+ cmd->is_long_lived = is_clvmd;
+ cmd->is_clvmd = is_clvmd;
cmd->threaded = threaded ? 1 : 0;
cmd->handles_missing_pvs = 0;
cmd->handles_unknown_segments = 0;
@@ -1970,6 +1971,10 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!_init_formats(cmd))
goto_out;
+ if (!lvmcache_init(cmd))
+ goto_out;
+
+ /* FIXME: move into lvmcache_init */
if (!init_lvmcache_orphans(cmd))
goto_out;
@@ -2191,6 +2196,9 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_formats(cmd))
return_0;
+ if (!lvmcache_init(cmd))
+ return_0;
+
if (!init_lvmcache_orphans(cmd))
return_0;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 1d9de0a..34222ee 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -236,7 +236,7 @@ struct cmd_context {
* system_dir may be NULL to use the default value.
* The environment variable LVM_SYSTEM_DIR always takes precedence.
*/
-struct cmd_context *create_toolcontext(unsigned is_long_lived,
+struct cmd_context *create_toolcontext(unsigned is_clvmd,
const char *system_dir,
unsigned set_buffering,
unsigned threaded,
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index d65daaf..16fd6fa 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -4599,7 +4599,7 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd,
if (!(vgname = lvmcache_vgname_from_vgid(cmd->mem, vgid))) {
log_debug_metadata("Reading VG by vgid %.8s no VG name found, retrying.", vgid);
- lvmcache_destroy(cmd, 0, 0);
+ lvmcache_destroy(cmd, 1, 0);
label_scan_destroy(cmd);
lvmcache_label_scan(cmd);
warn_flags |= SKIP_RESCAN;
@@ -4630,7 +4630,7 @@ struct volume_group *vg_read_by_vgid(struct cmd_context *cmd,
return vg;
scan:
- lvmcache_destroy(cmd, 0, 0);
+ lvmcache_destroy(cmd, 1, 0);
label_scan_destroy(cmd);
lvmcache_label_scan(cmd);
warn_flags |= SKIP_RESCAN;
diff --git a/tools/toollib.c b/tools/toollib.c
index 53e7f9a..e633cdd 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -111,7 +111,7 @@ int become_daemon(struct cmd_context *cmd, int skip_lvm)
if (!skip_lvm) {
reset_locking();
lvmcache_destroy(cmd, 1, 1);
- if (!lvmcache_init())
+ if (!lvmcache_init(cmd))
/* FIXME Clean up properly here */
_exit(ECMD_FAILED);
}
@@ -4622,7 +4622,7 @@ int process_each_pv(struct cmd_context *cmd,
log_verbose("Some PVs were not found in first search, retrying.");
lvmcache_destroy(cmd, 0, 0);
- if (!lvmcache_init()) {
+ if (!lvmcache_init(cmd)) {
log_error("Failed to initalize lvm cache.");
ret_max = ECMD_FAILED;
goto out;
6 years
master - clvmd: defer freeing saved vgs
by David Teigland
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=a5e13f2eef5314666e1...
Commit: a5e13f2eef5314666e19923a03ae01f479a74fd8
Parent: 88fe07ad0ac8f12c2a2f4873d9bd32852c2f1536
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Apr 30 16:48:53 2018 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Thu May 3 14:54:48 2018 -0500
clvmd: defer freeing saved vgs
To avoid the chance of freeing a saved vg while another
code path is using it, defer freeing saved vgs until
all the lvmcache content is dropped for the vg.
---
lib/activate/activate.c | 54 +++++++++--------
lib/cache/lvmcache.c | 149 +++++++++++++++++++++++++++++++++++++----------
lib/cache/lvmcache.h | 1 -
3 files changed, 148 insertions(+), 56 deletions(-)
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 2d00dc6..985215a 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -2161,36 +2161,40 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
if (lv && lv_pre)
goto skip_read;
- vg = lvmcache_get_saved_vg(vgid, 0);
- vg_pre = lvmcache_get_saved_vg(vgid, 1);
-
- if (!vg || !vg_pre) {
- log_debug("lv_suspend dropping both saved vgs and rereading");
-
- lvmcache_drop_saved_vgid(vgid);
-
- vg = vg_read_by_vgid(cmd, vgid, 0);
- vg_pre = vg_read_by_vgid(cmd, vgid, 1);
-
- if (!vg || !vg_pre) {
- log_error("lv_suspend could not find vgid %.8s vg %p vg_pre %p",
- vgid, vg, vg_pre);
+ if (!(vg = lvmcache_get_saved_vg(vgid, 0))) {
+ log_debug("lv_suspend did not find saved_vg %.8s so reading", vgid);
+ if (!(vg = vg_read_by_vgid(cmd, vgid, 0))) {
+ log_error("lv_suspend could not read vgid %.8s", vgid);
goto out;
}
+ log_debug("lv_suspend using read vg %s %d %p", vg->name, vg->seqno, vg);
+ } else {
+ log_debug("lv_suspend using saved_vg %s %d %p", vg->name, vg->seqno, vg);
+ }
- /*
- * Note that vg and vg_pre returned by vg_read_by_vgid will
- * not be the same as saved_vg_old/saved_vg_new that would
- * be returned by lvmcache_get_saved_vg() because the saved_vg's
- * are copies of the vg struct that is created by _vg_read.
- * (Should we grab and use the saved_vg to use here instead of
- * the vg returned by vg_read_by_vgid?)
- */
-
- if ((vg->status & EXPORTED_VG) || (vg_pre->status & EXPORTED_VG)) {
- log_error("Volume group \"%s\" is exported", vg->name);
+ if (!(vg_pre = lvmcache_get_saved_vg(vgid, 1))) {
+ log_debug("lv_suspend did not find pre saved_vg %.8s so reading", vgid);
+ if (!(vg_pre = vg_read_by_vgid(cmd, vgid, 1))) {
+ log_error("lv_suspend could not read pre vgid %.8s", vgid);
goto out;
}
+ log_debug("lv_suspend using pre read vg %s %d %p", vg_pre->name, vg_pre->seqno, vg_pre);
+ } else {
+ log_debug("lv_suspend using pre saved_vg %s %d %p", vg_pre->name, vg_pre->seqno, vg_pre);
+ }
+
+ /*
+ * Note that vg and vg_pre returned by vg_read_by_vgid will
+ * not be the same as saved_vg_old/saved_vg_new that would
+ * be returned by lvmcache_get_saved_vg() because the saved_vg's
+ * are copies of the vg struct that is created by _vg_read.
+ * (Should we grab and use the saved_vg to use here instead of
+ * the vg returned by vg_read_by_vgid?)
+ */
+
+ if ((vg->status & EXPORTED_VG) || (vg_pre->status & EXPORTED_VG)) {
+ log_error("Volume group \"%s\" is exported", vg->name);
+ goto out;
}
lv = lv_to_free = find_lv_in_vg_by_lvid(vg, lvid);
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 9023bcc..6d50545 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -97,6 +97,7 @@ struct lvmcache_vginfo {
char *saved_vg_new_buf;
struct dm_config_tree *saved_vg_new_cft;
struct volume_group *saved_vg_new;
+ struct dm_list saved_vg_to_free;
};
static struct dm_hash_table *_pvid_hash = NULL;
@@ -192,13 +193,63 @@ static void _update_cache_lock_state(const char *vgname, int locked)
_update_cache_vginfo_lock_state(vginfo, locked);
}
+static void _saved_vg_inval(struct lvmcache_vginfo *vginfo, int inval_old, int inval_new)
+{
+ struct vg_list *vgl;
+
+ if (inval_old) {
+ if (vginfo->saved_vg_old)
+ log_debug_cache("lvmcache: inval saved_vg %s old %p",
+ vginfo->saved_vg_old->name, vginfo->saved_vg_old);
+
+ if (vginfo->saved_vg_old_buf)
+ dm_free(vginfo->saved_vg_old_buf);
+ if (vginfo->saved_vg_old_cft)
+ dm_config_destroy(vginfo->saved_vg_old_cft);
+
+ if (vginfo->saved_vg_old) {
+ if ((vgl = dm_zalloc(sizeof(*vgl)))) {
+ vgl->vg = vginfo->saved_vg_old;
+ dm_list_add(&vginfo->saved_vg_to_free, &vgl->list);
+ }
+ }
+
+ vginfo->saved_vg_old_buf = NULL;
+ vginfo->saved_vg_old_cft = NULL;
+ vginfo->saved_vg_old = NULL;
+ }
+
+ if (inval_new) {
+ if (vginfo->saved_vg_new)
+ log_debug_cache("lvmcache: inval saved_vg %s new pre %p",
+ vginfo->saved_vg_new->name, vginfo->saved_vg_new);
+
+ if (vginfo->saved_vg_new_buf)
+ dm_free(vginfo->saved_vg_new_buf);
+ if (vginfo->saved_vg_new_cft)
+ dm_config_destroy(vginfo->saved_vg_new_cft);
+
+ if (vginfo->saved_vg_new) {
+ if ((vgl = dm_zalloc(sizeof(*vgl)))) {
+ vgl->vg = vginfo->saved_vg_new;
+ dm_list_add(&vginfo->saved_vg_to_free, &vgl->list);
+ }
+ }
+
+ vginfo->saved_vg_new_buf = NULL;
+ vginfo->saved_vg_new_cft = NULL;
+ vginfo->saved_vg_new = NULL;
+ }
+}
+
static void _saved_vg_free(struct lvmcache_vginfo *vginfo, int free_old, int free_new)
{
+ struct vg_list *vgl, *vgl2;
+
if (free_old) {
if (vginfo->saved_vg_old) {
log_debug_cache("lvmcache: free saved_vg %s old %p",
- vginfo->saved_vg_old->name,
- vginfo->saved_vg_old);
+ vginfo->saved_vg_old->name, vginfo->saved_vg_old);
vginfo->saved_vg_old->saved_in_clvmd = 0;
}
@@ -213,13 +264,21 @@ static void _saved_vg_free(struct lvmcache_vginfo *vginfo, int free_old, int fre
vginfo->saved_vg_old_buf = NULL;
vginfo->saved_vg_old_cft = NULL;
vginfo->saved_vg_old = NULL;
+
+ dm_list_iterate_items_safe(vgl, vgl2, &vginfo->saved_vg_to_free) {
+ log_debug_cache("lvmcache: free saved_vg_to_free %s %p",
+ vgl->vg->name, vgl->vg);
+
+ dm_list_del(&vgl->list);
+ vgl->vg->saved_in_clvmd = 0;
+ release_vg(vgl->vg);
+ }
}
if (free_new) {
if (vginfo->saved_vg_new) {
log_debug_cache("lvmcache: free saved_vg %s new pre %p",
- vginfo->saved_vg_new->name,
- vginfo->saved_vg_new);
+ vginfo->saved_vg_new->name, vginfo->saved_vg_new);
vginfo->saved_vg_new->saved_in_clvmd = 0;
}
@@ -275,7 +334,7 @@ void lvmcache_save_vg(struct volume_group *vg, int precommitted)
(vginfo->saved_vg_new->seqno == vg->seqno))
return;
- _saved_vg_free(vginfo, old, new);
+ _saved_vg_inval(vginfo, old, new);
if (!(size = export_vg_to_buffer(vg, &susp_buf)))
goto_bad;
@@ -310,7 +369,7 @@ void lvmcache_save_vg(struct volume_group *vg, int precommitted)
return;
bad:
- _saved_vg_free(vginfo, old, new);
+ _saved_vg_inval(vginfo, old, new);
log_debug_cache("lvmcache failed to save pre %d vg %s", precommitted, vg->name);
}
@@ -355,13 +414,12 @@ struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted)
vginfo->saved_vg_old->seqno,
vginfo->saved_vg_old);
- /* Do we need to actually set saved_vg_old to match saved_vg_new?
- * By just dropping old, we force a subsequent request for old to
- * reread it rather than just using new. */
-
if (vginfo->saved_vg_old && (vginfo->saved_vg_old->seqno < vg->seqno)) {
- log_debug_cache("lvmcache: drop saved_vg_old because new invalidates");
- _saved_vg_free(vginfo, 1, 0);
+ log_debug_cache("lvmcache: inval saved_vg_old %d %p for new %d %p %s",
+ vginfo->saved_vg_old->seqno, vginfo->saved_vg_old,
+ vg->seqno, vg, vg->name);
+
+ _saved_vg_inval(vginfo, 1, 0);
}
}
@@ -421,13 +479,12 @@ struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid)
vginfo->saved_vg_old->seqno,
vginfo->saved_vg_old);
- /* Do we need to actually set saved_vg_old to match saved_vg_new?
- * By just dropping old, we force a subsequent request for old to
- * reread it rather than just using new. */
-
if (vginfo->saved_vg_old && (vginfo->saved_vg_old->seqno < vg->seqno)) {
- log_debug_cache("lvmcache: drop saved_vg_old because new invalidates");
- _saved_vg_free(vginfo, 1, 0);
+ log_debug_cache("lvmcache: inval saved_vg_old %d %p for new %d %p %s",
+ vginfo->saved_vg_old->seqno, vginfo->saved_vg_old,
+ vg->seqno, vg, vg->name);
+
+ _saved_vg_inval(vginfo, 1, 0);
}
}
out:
@@ -436,16 +493,6 @@ out:
return vg;
}
-void lvmcache_drop_saved_vg(struct volume_group *vg)
-{
- struct lvmcache_vginfo *vginfo;
-
- if (!(vginfo = lvmcache_vginfo_from_vgid((const char *)&vg->id)))
- return;
-
- _saved_vg_free(vginfo, 1, 1);
-}
-
void lvmcache_drop_saved_vgid(const char *vgid)
{
struct lvmcache_vginfo *vginfo;
@@ -453,7 +500,7 @@ void lvmcache_drop_saved_vgid(const char *vgid)
if (!(vginfo = lvmcache_vginfo_from_vgid(vgid)))
return;
- _saved_vg_free(vginfo, 1, 1);
+ _saved_vg_inval(vginfo, 1, 1);
}
/*
@@ -1183,6 +1230,28 @@ next:
goto next;
}
+static void _move_saved_vg(struct lvmcache_vginfo *to, struct lvmcache_vginfo *from)
+{
+ to->saved_vg_committed = from->saved_vg_committed;
+ to->saved_vg_old_buf = from->saved_vg_old_buf;
+ to->saved_vg_old_cft = from->saved_vg_old_cft;
+ to->saved_vg_old = from->saved_vg_old;
+ to->saved_vg_new_buf = from->saved_vg_new_buf;
+ to->saved_vg_new_cft = from->saved_vg_new_cft;
+ to->saved_vg_new = from->saved_vg_new;
+
+ from->saved_vg_committed= 0;
+ from->saved_vg_old_buf = NULL;
+ from->saved_vg_old_cft = NULL;
+ from->saved_vg_old = NULL;
+ from->saved_vg_new_buf = NULL;
+ from->saved_vg_new_cft = NULL;
+ from->saved_vg_new = NULL;
+
+ dm_list_init(&to->saved_vg_to_free);
+ dm_list_splice(&to->saved_vg_to_free, &from->saved_vg_to_free);
+}
+
/*
* The initial label_scan at the start of the command is done without
* holding VG locks. Then for each VG identified during the label_scan,
@@ -1226,7 +1295,7 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
{
struct dm_list devs;
struct device_list *devl;
- struct lvmcache_vginfo *vginfo;
+ struct lvmcache_vginfo *vginfo, *tmp;
struct lvmcache_info *info, *info2;
if (lvmetad_used())
@@ -1256,6 +1325,15 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
dm_list_add(&devs, &devl->list);
}
+ /*
+ * clvmd stashes some copies of a vg on the vginfo struct
+ * (FIXME: it shouldn't abuse vginfo and should use its own struct),
+ * so when we replace vginfo in clvmd, we need to move the stashed
+ * vg's from the old vginfo struct to the new vginfo struct.
+ */
+ if (cmd->is_clvmd && (tmp = dm_zalloc(sizeof(*tmp))))
+ _move_saved_vg(tmp, vginfo);
+
dm_list_iterate_items_safe(info, info2, &vginfo->infos)
lvmcache_del(info);
@@ -1268,6 +1346,16 @@ int lvmcache_label_rescan_vg(struct cmd_context *cmd, const char *vgname, const
label_scan_devs(cmd, &devs);
+ if (!(vginfo = lvmcache_vginfo_from_vgname(vgname, vgid))) {
+ log_warn("VG info not found after rescan of %s", vgname);
+ return 0;
+ }
+
+ if (cmd->is_clvmd && tmp) {
+ _move_saved_vg(vginfo, tmp);
+ dm_free(tmp);
+ }
+
return 1;
}
@@ -1834,6 +1922,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
return 0;
}
dm_list_init(&vginfo->infos);
+ dm_list_init(&vginfo->saved_vg_to_free);
/*
* A different VG (different uuid) can exist with the same name.
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 7cdda43..20ce74b 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -216,7 +216,6 @@ void lvmcache_set_independent_location(const char *vgname);
void lvmcache_save_vg(struct volume_group *vg, int precommitted);
struct volume_group *lvmcache_get_saved_vg(const char *vgid, int precommitted);
struct volume_group *lvmcache_get_saved_vg_latest(const char *vgid);
-void lvmcache_drop_saved_vg(struct volume_group *vg);
void lvmcache_drop_saved_vgid(const char *vgid);
int lvmcache_scan_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
6 years
master - raid: use new internal APIs
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=88fe07ad0ac8f12c2a2...
Commit: 88fe07ad0ac8f12c2a2f4873d9bd32852c2f1536
Parent: 49db9b5e0b35f6b0a47ad10276fb252c09f438ef
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Thu May 3 21:35:32 2018 +0200
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Thu May 3 21:36:50 2018 +0200
raid: use new internal APIs
Use APIs introduced with commit 4ebfd8e8eb68442efc334b35bc1f22eda3e4dd3d
where appropriate to minimize redundant code.
---
lib/metadata/raid_manip.c | 21 +++++----------------
1 files changed, 5 insertions(+), 16 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 1b9ebcf..703f285 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -6789,10 +6789,8 @@ static int _lv_raid_rebuild_or_replace(struct logical_volume *lv,
return 0;
}
- if (lv_is_virtual(seg_lv(raid_seg, s)) ||
- lv_is_virtual(seg_metalv(raid_seg, s)) ||
- lv_is_partial(seg_lv(raid_seg, s)) ||
- lv_is_partial(seg_metalv(raid_seg, s)) ||
+ if (_sublv_is_degraded(seg_lv(raid_seg, s)) ||
+ _sublv_is_degraded(seg_metalv(raid_seg, s)) ||
lv_is_on_pvs(seg_lv(raid_seg, s), remove_pvs) ||
lv_is_on_pvs(seg_metalv(raid_seg, s), remove_pvs)) {
match_count++;
@@ -7122,10 +7120,8 @@ static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
if (!(i % copies))
rebuilds_per_group = 0;
- if (lv_is_partial(seg_lv(raid_seg, s)) ||
- lv_is_partial(seg_metalv(raid_seg, s)) ||
- lv_is_virtual(seg_lv(raid_seg, s)) ||
- lv_is_virtual(seg_metalv(raid_seg, s)))
+ if (_sublv_is_degraded(seg_lv(raid_seg, s)) ||
+ _sublv_is_degraded(seg_metalv(raid_seg, s)))
rebuilds_per_group++;
if (rebuilds_per_group >= copies) {
@@ -7138,14 +7134,7 @@ static int _partial_raid_lv_is_redundant(const struct logical_volume *lv)
return 1; /* Redundant */
}
- for (s = 0; s < raid_seg->area_count; s++) {
- if (lv_is_partial(seg_lv(raid_seg, s)) ||
- lv_is_partial(seg_metalv(raid_seg, s)) ||
- lv_is_virtual(seg_lv(raid_seg, s)) ||
- lv_is_virtual(seg_metalv(raid_seg, s)))
- failed_components++;
- }
-
+ failed_components = _lv_get_nr_failed_components(lv);
if (failed_components == raid_seg->area_count) {
log_verbose("All components of raid LV %s have failed.",
display_lvname(lv));
6 years