master - lvmdbusd: Change print statement to py3 syntax
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=41ebed707700e9...
Commit: 41ebed707700e926d4224bc62289ea47014d9a0d
Parent: b717c5efae942c845f07d695593cfb2406627fe9
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Jun 6 15:06:50 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Fri Jun 10 15:28:42 2016 -0500
lvmdbusd: Change print statement to py3 syntax
---
daemons/lvmdbusd/objectmanager.py | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmdbusd/objectmanager.py b/daemons/lvmdbusd/objectmanager.py
index f28c5c8..f8f6d97 100644
--- a/daemons/lvmdbusd/objectmanager.py
+++ b/daemons/lvmdbusd/objectmanager.py
@@ -124,8 +124,8 @@ class ObjectManager(AutomatedProperties):
with self.rlock:
path, props = dbus_object.emit_data()
- # print 'Registering object path %s for %s' %
- # (path, dbus_object.lvm_id)
+ # print('Registering object path %s for %s' %
+ # (path, dbus_object.lvm_id))
# We want fast access to the object by a number of different ways
# so we use multiple hashs with different keys
7 years, 11 months
master - lvmdbusd: Bug fix for missing LV properties
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=b717c5efae942c...
Commit: b717c5efae942c845f07d695593cfb2406627fe9
Parent: e04705b305626d37cbd076b47d6ad37c9b1b282e
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Fri Jun 10 11:58:55 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Fri Jun 10 15:28:42 2016 -0500
lvmdbusd: Bug fix for missing LV properties
When we are processing the LVs we need to build up dbus objects from least
dependent to most dependent, so that we have information available when
constructing.
---
daemons/lvmdbusd/lv.py | 41 ++++++++++++++++++++++++++++++++++++++++-
1 files changed, 40 insertions(+), 1 deletions(-)
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 61cf7d3..2786f68 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -24,6 +24,39 @@ from . import background
from .utils import round_size
+# Try and build a key for a LV, so that we sort the LVs with least dependencies
+# first. This may be error prone because of the flexibility LVM
+# provides and what you can stack.
+def get_key(i):
+
+ name = i['lv_name']
+ parent = i['lv_parent']
+ pool = i['pool_lv']
+ a1 = ""
+ a2 = ""
+
+ if name[0] == '[':
+ a1 = '#'
+
+ # We have a parent
+ if parent:
+ # Check if parent is hidden
+ if parent[0] == '[':
+ a2 = '##'
+ else:
+ a2 = '#'
+
+ # If a LV has a pool, then it should be sorted/loaded after the pool
+ # lv, unless it's a hidden too, then after other hidden, but before visible
+ if pool:
+ if pool[0] != '[':
+ a2 += '~'
+ else:
+ a1 = '$' + a1
+
+ return "%s%s%s" % (a1, a2, name)
+
+
# noinspection PyUnusedLocal
def lvs_state_retrieve(selection, cache_refresh=True):
rc = []
@@ -31,7 +64,13 @@ def lvs_state_retrieve(selection, cache_refresh=True):
if cache_refresh:
cfg.db.refresh()
- for l in cfg.db.fetch_lvs(selection):
+ # When building up the model, it's best to process LVs with the least
+ # dependencies to those that are dependant upon other LVs. Otherwise, when
+ # we are trying to gather information we could be in a position where we
+ # don't have information available yet.
+ lvs = sorted(cfg.db.fetch_lvs(selection), key=get_key)
+
+ for l in lvs:
rc.append(LvState(
l['lv_uuid'], l['lv_name'],
l['lv_path'], n(l['lv_size']),
7 years, 11 months
master - lvmdbusd: Add data_lv and metadata_lv to cache pool interface
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e04705b305626d...
Commit: e04705b305626d37cbd076b47d6ad37c9b1b282e
Parent: 3bf43a65fefbda1b2628fbbc77ad40e3780a8d84
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Mon Jun 6 15:03:02 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Fri Jun 10 15:28:42 2016 -0500
lvmdbusd: Add data_lv and metadata_lv to cache pool interface
See: https://bugzilla.redhat.com/show_bug.cgi?id=1342558
---
daemons/lvmdbusd/lv.py | 46 +++++++++++++++++++++++++++++-----------------
1 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 149547f..61cf7d3 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -311,6 +311,23 @@ class LvCommon(AutomatedProperties):
# noinspection PyPep8Naming
class Lv(LvCommon):
+ def _fetch_hidden(self, name):
+
+ # The name is vg/name
+ full_name = "%s/%s" % (self.vg_name_lookup(), name)
+
+ o = cfg.om.get_object_by_lvm_id(full_name)
+ if o:
+ return o.dbus_object_path()
+
+ return '/'
+
+ def _get_data_meta(self):
+
+ # Get the data
+ return (self._fetch_hidden(self.state.data_lv),
+ self._fetch_hidden(self.state.metadata_lv))
+
# noinspection PyUnusedLocal,PyPep8Naming
def __init__(self, object_path, object_state):
super(Lv, self).__init__(object_path, object_state)
@@ -634,23 +651,6 @@ class LvThinPool(Lv):
_DataLv_meta = ("o", THIN_POOL_INTERFACE)
_MetaDataLv_meta = ("o", THIN_POOL_INTERFACE)
- def _fetch_hidden(self, name):
-
- # The name is vg/name
- full_name = "%s/%s" % (self.vg_name_lookup(), name)
-
- o = cfg.om.get_object_by_lvm_id(full_name)
- if o:
- return o.dbus_object_path()
-
- return '/'
-
- def _get_data_meta(self):
-
- # Get the data
- return (self._fetch_hidden(self.state.data_lv),
- self._fetch_hidden(self.state.metadata_lv))
-
def __init__(self, object_path, object_state):
super(LvThinPool, self).__init__(object_path, object_state)
self.set_interface(THIN_POOL_INTERFACE)
@@ -707,9 +707,21 @@ class LvThinPool(Lv):
# noinspection PyPep8Naming
class LvCachePool(Lv):
+ _DataLv_meta = ("o", CACHE_POOL_INTERFACE)
+ _MetaDataLv_meta = ("o", CACHE_POOL_INTERFACE)
+
def __init__(self, object_path, object_state):
super(LvCachePool, self).__init__(object_path, object_state)
self.set_interface(CACHE_POOL_INTERFACE)
+ self._data_lv, self._metadata_lv = self._get_data_meta()
+
+ @property
+ def DataLv(self):
+ return self._data_lv
+
+ @property
+ def MetaDataLv(self):
+ return self._metadata_lv
@staticmethod
def _cache_lv(lv_uuid, lv_name, lv_object_path, cache_options):
7 years, 11 months
master - lvmdbusd: Add roles property to LV common interface
by tasleson
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=3bf43a65fefbda...
Commit: 3bf43a65fefbda1b2628fbbc77ad40e3780a8d84
Parent: 8a667f5887f62525cebe7e57ffe6e049ce17c7dd
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Fri Jun 3 17:07:37 2016 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Fri Jun 10 15:28:42 2016 -0500
lvmdbusd: Add roles property to LV common interface
See: https://bugzilla.redhat.com/show_bug.cgi?id=1342559
---
daemons/lvmdbusd/lv.py | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmdbusd/lv.py b/daemons/lvmdbusd/lv.py
index 42219b3..149547f 100644
--- a/daemons/lvmdbusd/lv.py
+++ b/daemons/lvmdbusd/lv.py
@@ -179,6 +179,7 @@ class LvState(State):
@utils.dbus_property(LV_COMMON_INTERFACE, 'HiddenLvs', "ao")
class LvCommon(AutomatedProperties):
_Tags_meta = ("as", LV_COMMON_INTERFACE)
+ _Roles_meta = ("as", LV_COMMON_INTERFACE)
_IsThinVolume_meta = ("b", LV_COMMON_INTERFACE)
_IsThinPool_meta = ("b", LV_COMMON_INTERFACE)
_Active_meta = ("b", LV_COMMON_INTERFACE)
@@ -281,6 +282,10 @@ class LvCommon(AutomatedProperties):
return utils.parse_tags(self.state.Tags)
@property
+ def Roles(self):
+ return utils.parse_tags(self.state.role)
+
+ @property
def lvm_id(self):
return self.state.lvm_id
7 years, 11 months
master - WHATS_NEW: add recent changes
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8a667f5887f625...
Commit: 8a667f5887f62525cebe7e57ffe6e049ce17c7dd
Parent: ad414e5ad61a25b97975c1d2e060e65050d45a69
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Fri Jun 10 13:39:23 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Fri Jun 10 13:39:23 2016 -0500
WHATS_NEW: add recent changes
---
WHATS_NEW | 2 ++
1 files changed, 2 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 0f8ebda..9c8ae71 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,7 @@
Version 2.02.156 -
================================
+ Don't allow duplicate orphan PVs to be used with vgcreate/vgextend/pvcreate.
+ Improve handling of lvmetad update failures.
Yes/No prompt accepts '^[ ^t]*([Yy]([Ee]([Ss]|)|)|[Nn]([Oo]|))[ ^t]*$'.
If available, also collect output from lsblk command when running lvmdump -s.
Fix regression in blkdeactivate causing dm and md devices to be skipped. (2.02.155)
7 years, 11 months
master - cleanup: typo in WHATS_NEW_DM
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=ad414e5ad61a25...
Commit: ad414e5ad61a25b97975c1d2e060e65050d45a69
Parent: 35612bd27c203774948c84005c9fb9237746c34a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 3 15:33:27 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 10 16:01:22 2016 +0200
cleanup: typo in WHATS_NEW_DM
---
WHATS_NEW_DM | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 9c84854..371e8b5 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -104,7 +104,7 @@ Version 1.02.110 - 30th October 2015
Correct use of max_write_behind parameter when generating raid target line.
Fix dm-event systemd service to make sure it is executed before mounting.
-Version 1.02.109 - 22nd September 2016
+Version 1.02.109 - 22nd September 2015
======================================
Update man pages for dmsetup and dmstats.
Improve help text for dmsetup.
7 years, 11 months
master - display: yes no prompt improvement
by Zdenek Kabelac
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=35612bd27c2037...
Commit: 35612bd27c203774948c84005c9fb9237746c34a
Parent: cfdc87b62331875c2f10cca2c41f486d40b2a67c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Jun 8 20:52:14 2016 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Fri Jun 10 16:00:31 2016 +0200
display: yes no prompt improvement
Original code missed to catch all apperances of SIGINT.
Also enhance logging when running in shell without tty.
Accept this regex as valid input:
'^[ ^t]*([Yy]([Ee]([Ss]|)|)|[Nn]([Oo]|))[ ^t]*$'
---
WHATS_NEW | 1 +
lib/display/display.c | 100 +++++++++++++++++++++++++++++++++++++------------
2 files changed, 77 insertions(+), 24 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 0afd527..0f8ebda 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.156 -
================================
+ Yes/No prompt accepts '^[ ^t]*([Yy]([Ee]([Ss]|)|)|[Nn]([Oo]|))[ ^t]*$'.
If available, also collect output from lsblk command when running lvmdump -s.
Fix regression in blkdeactivate causing dm and md devices to be skipped. (2.02.155)
diff --git a/lib/display/display.c b/lib/display/display.c
index 0151d01..19421e7 100644
--- a/lib/display/display.c
+++ b/lib/display/display.c
@@ -831,50 +831,102 @@ void display_name_error(name_error_t name_error)
* Prompt for y or n from stdin.
* Defaults to 'no' in silent mode.
* All callers should support --yes and/or --force to override this.
+ *
+ * Accepted are either _yes[] or _no[] strings or just their outset.
+ * When running without 'tty' stdin is printed to stderr.
+ * 'Yes' is accepted ONLY with '\n'.
*/
char yes_no_prompt(const char *prompt, ...)
{
- int c = 0, ret = 0, cb = 0;
+ /* Lowercase Yes/No strings */
+ static const char _yes[] = "yes";
+ static const char _no[] = "no";
+ const char *answer = NULL;
+ int c = silent_mode() ? EOF : 0;
+ int i, ret = 0, sig = 0;
+ char buf[12];
va_list ap;
sigint_allow();
- do {
- if (c == '\n' || !c) {
+
+ for (;;) {
+ if (!ret) {
+ /* Show prompt */
va_start(ap, prompt);
vfprintf(stderr, prompt, ap);
va_end(ap);
fflush(stderr);
- if (silent_mode()) {
- fputc('n', stderr);
- ret = 'n';
+
+ if (c == EOF)
break;
- }
- ret = 0;
+
+ i = 0;
+ answer = NULL;
}
+ nextchar:
+ if ((sig = sigint_caught()))
+ break; /* Check if already interrupted before getchar() */
+
if ((c = getchar()) == EOF) {
- ret = 'n'; /* SIGINT */
- cb = 1;
- break;
+ /* SIGNAL or no chars on stdin (missing '\n') or ^D */
+ if (!i)
+ break; /* Just shown prompt,-> print [n]\n */
+
+ goto invalid; /* Note: c holds EOF */
}
+ if ((i < (sizeof(buf) - 4)) && isprint(c))
+ buf[i++] = c;
+
c = tolower(c);
- if ((c == 'y') || (c == 'n')) {
- /* If both 'y' and 'n' given, begin again. */
- if (ret && c != ret)
- ret = -1;
- else
- ret = c;
- }
- } while (ret < 1 || c != '\n');
- sigint_restore();
+ if ((ret > 0) && (c == answer[0]))
+ answer++; /* Matching, next char */
+ else if (c == '\n') {
+ if (feof(stdin))
+ fputc('\n', stderr);
+ if (ret > 0)
+ break; /* Answered */
+ invalid:
+ if (i >= (sizeof(buf) - 4)) {
+ /* '...' for missing input */
+ i = sizeof(buf) - 1;
+ buf[i - 1] = buf[i - 2] = buf[i - 3] = '.';
+ }
+ buf[i] = 0;
+ log_warn("WARNING: Invalid input '%s'.", buf);
+ ret = 0; /* Otherwise refresh prompt */
+ } else if (!ret && (c == _yes[0])) {
+ ret = 'y';
+ answer = _yes + 1; /* Expecting 'Yes' */
+ } else if (!ret && (c == _no[0])) {
+ ret = 'n';
+ answer = _no + 1; /* Expecting 'No' */
+ } else if (!ret && isspace(c)) {
+ /* Ignore any whitespace before */
+ --i;
+ goto nextchar;
+ } else if ((ret > 0) && isspace(c)) {
+ /* Ignore any whitespace after */
+ while (*answer)
+ answer++; /* jump to end-of-word */
+ } else
+ ret = -1; /* Read till '\n' and refresh */
+ }
- if (cb && !sigint_caught())
- fputc(ret, stderr);
+ sigint_restore();
- if (c != '\n')
- fputc('\n', stderr);
+ /* For other then Yes answer check there is really no interrupt */
+ if (sig || sigint_caught()) {
+ stack;
+ ret = 'n';
+ } else if (c == EOF) {
+ fputs("[n]\n", stderr);
+ ret = 'n';
+ } else
+ /* Not knowing if it's terminal, makes this hard.... */
+ log_verbose("Accepted input: [%c]", ret);
return ret;
}
7 years, 11 months
master - lvmdump: also collect output from lsblk command when running lvmdump -s
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=cfdc87b6233187...
Commit: cfdc87b62331875c2f10cca2c41f486d40b2a67c
Parent: 86f92714574487cce6a9de785ba2ff93b23a98f7
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Thu Jun 9 13:51:09 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Thu Jun 9 13:54:15 2016 +0200
lvmdump: also collect output from lsblk command when running lvmdump -s
lsblk provides nice and quick overview of the storage/sysfs structure
that is useful for debugging - collect its output when running lvmdump -s.
---
WHATS_NEW | 1 +
man/lvmdump.8.in | 9 +++++----
scripts/lvmdump.sh | 11 ++++++++++-
3 files changed, 16 insertions(+), 5 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 2e7e138..0afd527 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.156 -
================================
+ If available, also collect output from lsblk command when running lvmdump -s.
Fix regression in blkdeactivate causing dm and md devices to be skipped. (2.02.155)
Version 2.02.155 - 3rd June 2016
diff --git a/man/lvmdump.8.in b/man/lvmdump.8.in
index f9c2284..d0e102e 100644
--- a/man/lvmdump.8.in
+++ b/man/lvmdump.8.in
@@ -85,10 +85,11 @@ history for all yet uncollected results of polling operations already finished
including reason.
.TP
.B \-s
-Gather system info and context. Currently, this encompasses systemd info
-and context only: overall state of systemd units present in the system,
-more detailed status of units controlling LVM functionality and the content
-of systemd journal for current boot.
+Gather system info and context. Currently, this encompasses info gathered
+by calling lsblk command and various systemd info and context: overall state
+of systemd units present in the system, more detailed status of units
+controlling LVM functionality and the content of systemd journal for
+current boot.
.TP
.B \-u
Gather udev info and context: /etc/udev/udev.conf file, udev daemon version
diff --git a/scripts/lvmdump.sh b/scripts/lvmdump.sh
index a813537..bfe79d9 100755
--- a/scripts/lvmdump.sh
+++ b/scripts/lvmdump.sh
@@ -252,13 +252,22 @@ if (( $sysreport )); then
SYSTEMCTL=$(which systemctl 2>> $log)
JOURNALCTL=$(which journalctl 2>> $log)
+ LSBLK=$(which lsblk 2>> $log)
+
+ log "$MKDIR -p \"$sysreport_dir\""
+
+ if test -z "LSBLK"; then
+ myecho "WARNING: lsblk not found"
+ else
+ log "$LSBLK -O >> \"$sysreport_dir/lsblk\""
+ log "$LSBLK -s >> \"$sysreport_dir/lsblk_s\""
+ fi
if test -z "$SYSTEMCTL"; then
myecho "WARNING: systemctl not found"
elif test -z "$JOURNALCTL"; then
myecho "WARNING: journalctl not found"
else
- log "$MKDIR -p \"$sysreport_dir\""
log "$JOURNALCTL -b --no-pager -o short-precise > \"$sysreport_dir/journal_content\" 2>> \"$log\""
log "$SYSTEMCTL status -l --no-pager -n $log_lines -o short-precise dm-event.socket dm-event.service \
lvm2-monitor.service \
7 years, 11 months
master - vgcreate, pvcreate, vgextend: don't use a device with duplicates
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=86f92714574487...
Commit: 86f92714574487cce6a9de785ba2ff93b23a98f7
Parent: 199b7b55c21270d62ce35f32b16df200417dc41c
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 6 15:39:51 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Jun 7 15:21:07 2016 -0500
vgcreate, pvcreate, vgextend: don't use a device with duplicates
If duplicate orphan PVs exist, don't allow one of them to be
used for vgcreate/pvcreate/vgextend.
---
lib/cache/lvmcache.c | 10 ++++++++++
lib/cache/lvmcache.h | 2 ++
tools/toollib.c | 9 +++++++++
3 files changed, 21 insertions(+), 0 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 87b25f1..9d89b80 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -1519,6 +1519,16 @@ const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
return dev->pvid;
}
+int lvmcache_pvid_in_unchosen_duplicates(const char *pvid)
+{
+ struct device_list *devl;
+
+ dm_list_iterate_items(devl, &_unused_duplicate_devs) {
+ if (!strncmp(devl->dev->pvid, pvid, ID_LEN))
+ return 1;
+ }
+ return 0;
+}
static int _free_vginfo(struct lvmcache_vginfo *vginfo)
{
diff --git a/lib/cache/lvmcache.h b/lib/cache/lvmcache.h
index 5f85b03..4b8b942 100644
--- a/lib/cache/lvmcache.h
+++ b/lib/cache/lvmcache.h
@@ -213,4 +213,6 @@ int lvmcache_dev_is_unchosen_duplicate(struct device *dev);
void lvmcache_remove_unchosen_duplicate(struct device *dev);
+int lvmcache_pvid_in_unchosen_duplicates(const char *pvid);
+
#endif
diff --git a/tools/toollib.c b/tools/toollib.c
index 7cde806..9353814 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3908,6 +3908,15 @@ static int _pvcreate_check_single(struct cmd_context *cmd,
}
/*
+ * Don't allow using a device with duplicates.
+ */
+ if (lvmcache_pvid_in_unchosen_duplicates(pd->dev->pvid)) {
+ log_error("Cannot use device %s with duplicates.", pd->name);
+ dm_list_move(&pp->arg_fail, &pd->list);
+ return 1;
+ }
+
+ /*
* What kind of device is this: an orphan PV, an uninitialized/unused
* device, a PV used in a VG.
*/
7 years, 11 months
master - lvmcache: fix duplicate handling with multiple scans
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=199b7b55c21270...
Commit: 199b7b55c21270d62ce35f32b16df200417dc41c
Parent: 01156de6f70ba5b1c8e2ae23c655ccd36ac59441
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 6 15:20:55 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Tue Jun 7 15:15:51 2016 -0500
lvmcache: fix duplicate handling with multiple scans
Some commands scan labels to populate lvmcache multiple
times, i.e. lvmcache_init, scan labels to fill lvmcache,
lvmcache_destroy, then later repeat
Each time labels are scanned, duplicates are detected,
and preferred devices are chosen. Each time this is done
within a single command, we want to choose the same
preferred devices. So, check for existing preferences
when choosing preferred devices.
This also fixes a problem with the list of unused duplicate
devs when run in an lvm shell. The devs had been allocated
from cmd memory, resulting in invalid list entries between
commands.
---
lib/cache/lvmcache.c | 90 ++++++++++++++++++++++++++++++++++++++-----
lib/commands/toolcontext.c | 2 +
lib/commands/toolcontext.h | 1 +
3 files changed, 82 insertions(+), 11 deletions(-)
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 1af6363..87b25f1 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -97,6 +97,8 @@ int lvmcache_init(void)
_vgs_locked = 0;
dm_list_init(&_vginfos);
+ dm_list_init(&_found_duplicate_devs);
+ dm_list_init(&_unused_duplicate_devs);
if (!(_vgname_hash = dm_hash_create(128)))
return 0;
@@ -471,6 +473,16 @@ void lvmcache_remove_unchosen_duplicate(struct device *dev)
}
}
+static void _destroy_duplicate_device_list(struct dm_list *head)
+{
+ struct device_list *devl, *devl2;
+
+ dm_list_iterate_items_safe(devl, devl2, head) {
+ dm_list_del(&devl->list);
+ dm_free(devl);
+ }
+ dm_list_init(head);
+}
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
struct lvmcache_info *info)
@@ -807,17 +819,22 @@ int vg_has_duplicate_pvs(struct volume_group *vg)
return 0;
}
-int lvmcache_dev_is_unchosen_duplicate(struct device *dev)
+static int _dev_in_device_list(struct device *dev, struct dm_list *head)
{
struct device_list *devl;
- dm_list_iterate_items(devl, &_unused_duplicate_devs) {
+ dm_list_iterate_items(devl, head) {
if (devl->dev == dev)
return 1;
}
return 0;
}
+int lvmcache_dev_is_unchosen_duplicate(struct device *dev)
+{
+ return _dev_in_device_list(dev, &_unused_duplicate_devs);
+}
+
/*
* Compare _found_duplicate_devs entries with the corresponding duplicate dev
* in lvmcache. There may be multiple duplicates in _found_duplicate_devs for
@@ -843,6 +860,7 @@ static void _choose_preferred_devs(struct cmd_context *cmd,
char uuid[64] __attribute__((aligned(8)));
const char *reason = "none";
struct dm_list altdevs;
+ struct dm_list new_unused;
struct dev_types *dt = cmd->dev_types;
struct device_list *devl, *devl_safe, *alt, *del;
struct lvmcache_info *info;
@@ -854,8 +872,11 @@ static void _choose_preferred_devs(struct cmd_context *cmd,
int has_fs1, has_fs2;
int has_lv1, has_lv2;
int same_size1, same_size2;
+ int prev_unchosen1, prev_unchosen2;
int change;
+ dm_list_init(&new_unused);
+
/*
* Create a list of all alternate devs for the same pvid: altdevs.
*/
@@ -873,8 +894,11 @@ next:
}
}
- if (!alt)
+ if (!alt) {
+ _destroy_duplicate_device_list(&_unused_duplicate_devs);
+ dm_list_splice(&_unused_duplicate_devs, &new_unused);
return;
+ }
/*
* Find the device for the pvid that's currently in lvmcache.
@@ -904,6 +928,21 @@ next:
continue;
}
+ prev_unchosen1 = _dev_in_device_list(dev1, &_unused_duplicate_devs);
+ prev_unchosen2 = _dev_in_device_list(dev2, &_unused_duplicate_devs);
+
+ if (!prev_unchosen1 && !prev_unchosen2) {
+ /*
+ * The cmd list saves the unchosen preference across
+ * lvmcache_destroy. Sometimes a single command will
+ * fill lvmcache, destroy it, and refill it, and we
+ * want the same duplicate preference to be preserved
+ * in each instance of lvmcache for a single command.
+ */
+ prev_unchosen1 = _dev_in_device_list(dev1, &cmd->unused_duplicate_devs);
+ prev_unchosen2 = _dev_in_device_list(dev2, &cmd->unused_duplicate_devs);
+ }
+
dev1_major = MAJOR(dev1->dev);
dev1_minor = MINOR(dev1->dev);
dev2_major = MAJOR(dev2->dev);
@@ -941,6 +980,11 @@ next:
dev_name(dev1), (unsigned long long)dev1_size,
dev_name(dev2), (unsigned long long)dev2_size);
+ log_debug_cache("PV %s: %s was prev %s. %s was prev %s.",
+ devl->dev->pvid,
+ dev_name(dev1), prev_unchosen1 ? "not chosen" : "<none>",
+ dev_name(dev2), prev_unchosen2 ? "not chosen" : "<none>");
+
log_debug_cache("PV %s: %s %s subsystem. %s %s subsystem.",
devl->dev->pvid,
dev_name(dev1), in_subsys1 ? "is in" : "is not in",
@@ -963,7 +1007,14 @@ next:
change = 0;
- if (has_lv1 && !has_lv2) {
+ if (prev_unchosen1 && !prev_unchosen2) {
+ /* change to 2 (NB when unchosen is set we unprefer) */
+ change = 1;
+ reason = "of previous preference";
+ } else if (prev_unchosen2 && !prev_unchosen1) {
+ /* keep 1 (NB when unchosen is set we unprefer) */
+ reason = "of previous preference";
+ } else if (has_lv1 && !has_lv2) {
/* keep 1 */
reason = "device is used by LV";
} else if (has_lv2 && !has_lv1) {
@@ -1023,7 +1074,7 @@ next:
dm_list_move(add_cache_devs, &alt->list);
- if ((del = dm_pool_alloc(cmd->mem, sizeof(*del)))) {
+ if ((del = dm_zalloc(sizeof(*del)))) {
del->dev = info->dev;
dm_list_add(del_cache_devs, &del->list);
}
@@ -1039,7 +1090,7 @@ next:
* duplicates not being used in lvmcache.
*/
- dm_list_splice(&_unused_duplicate_devs, &altdevs);
+ dm_list_splice(&new_unused, &altdevs);
goto next;
}
@@ -1087,6 +1138,11 @@ int lvmcache_label_scan(struct cmd_context *cmd)
log_very_verbose("Scanning device labels");
+ /*
+ * Duplicates found during this label scan are added to _found_duplicate_devs().
+ */
+ _destroy_duplicate_device_list(&_found_duplicate_devs);
+
while ((dev = dev_iter_get(iter))) {
(void) label_read(dev, &label, UINT64_C(0));
dev_count++;
@@ -2127,7 +2183,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller,
* use it.
*/
- if (!(devl = dm_pool_alloc(fmt->cmd->mem, sizeof(*devl))))
+ if (!(devl = dm_zalloc(sizeof(*devl))))
return_NULL;
devl->dev = dev;
@@ -2266,13 +2322,25 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
log_error(INTERNAL_ERROR "_vginfos list should be empty");
dm_list_init(&_vginfos);
+ /*
+ * Copy the current _unused_duplicate_devs into a cmd list before
+ * destroying _unused_duplicate_devs.
+ *
+ * One command can init/populate/destroy lvmcache multiple times. Each
+ * time it will encounter duplicates and choose the preferrred devs.
+ * We want the same preferred devices to be chosen each time, so save
+ * the unpreferred devs here so that _choose_preferred_devs can use
+ * this to make the same choice each time.
+ */
+ dm_list_init(&cmd->unused_duplicate_devs);
+ lvmcache_get_unused_duplicate_devs(cmd, &cmd->unused_duplicate_devs);
+ _destroy_duplicate_device_list(&_unused_duplicate_devs);
+ _destroy_duplicate_device_list(&_found_duplicate_devs); /* should be empty anyway */
+ _found_duplicate_pvs = 0;
+
if (retain_orphans)
if (!init_lvmcache_orphans(cmd))
stack;
-
- dm_list_init(&_found_duplicate_devs);
- dm_list_init(&_unused_duplicate_devs);
- _found_duplicate_pvs = 0;
}
int lvmcache_pvid_is_locked(const char *pvid) {
diff --git a/lib/commands/toolcontext.c b/lib/commands/toolcontext.c
index 1e3f14a..076f48d 100644
--- a/lib/commands/toolcontext.c
+++ b/lib/commands/toolcontext.c
@@ -1977,6 +1977,8 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!init_lvmcache_orphans(cmd))
goto_out;
+ dm_list_init(&cmd->unused_duplicate_devs);
+
if (!_init_segtypes(cmd))
goto_out;
diff --git a/lib/commands/toolcontext.h b/lib/commands/toolcontext.h
index 2cecf27..f4beae1 100644
--- a/lib/commands/toolcontext.h
+++ b/lib/commands/toolcontext.h
@@ -197,6 +197,7 @@ struct cmd_context {
const char *report_list_item_separator;
const char *time_format;
unsigned rand_seed;
+ struct dm_list unused_duplicate_devs; /* save preferences between lvmcache instances */
};
/*
7 years, 11 months