master - tests: check thin-pool boundary sizes
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ee5ecde35eca656e85e...
Commit: ee5ecde35eca656e85ee5c83b15ad4029d0acf4d
Parent: 48ffb996c5218472996b1b6d557fa51de0f6e9b7
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 8 11:45:14 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 8 11:58:36 2017 +0200
tests: check thin-pool boundary sizes
---
test/shell/thin-large.sh | 54 ++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 54 insertions(+), 0 deletions(-)
diff --git a/test/shell/thin-large.sh b/test/shell/thin-large.sh
new file mode 100644
index 0000000..da5a7ec
--- /dev/null
+++ b/test/shell/thin-large.sh
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Copyright (C) 2017 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+# 'Exercise logic around boundary sizes of thin-pool data and chunksize
+
+SKIP_WITH_LVMLOCKD=1
+SKIP_WITH_LVMPOLLD=1
+
+. lib/inittest
+
+# FIXME update test to make something useful on <16T
+aux can_use_16T || skip
+
+aux have_thin 1 0 0 || skip
+
+# Prepare ~1P sized devices
+aux prepare_vg 1 1000000000
+
+lvcreate -an -T -L250T $vg/pool250
+
+lvcreate -an -T -L250T --poolmetadatasize 16G $vg/pool16
+
+fail lvcreate -an -T -L250T --chunksize 64K --poolmetadatasize 16G $vg/pool64
+
+# Creation of thin-pool with proper chunk-size but not enough metadata size
+# which can grow later needs to pass
+lvcreate -an -T -L250T --chunksize 1M --poolmetadatasize 4G $vg/pool1024
+
+# Creation of chunk should fit
+lvcreate -an -T -L12T --chunksize 64K --poolmetadatasize 16G $vg/pool64
+
+check lv_field $vg/pool64 chunksize "64.00k"
+
+lvremove -ff $vg
+
+
+### Check also lvconvert ###
+
+lvcreate -an -L250T -n pool $vg
+
+fail lvconvert -y --chunksize 64 --thinpool $vg/pool
+lvconvert -y --chunksize 1M --thinpool $vg/pool
+
+check lv_field $vg/pool chunksize "1.00m"
+
+vgremove -ff $vg
6 years, 10 months
master - thin: disallow creation of too big thin pools
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=48ffb996c5218472996...
Commit: 48ffb996c5218472996b1b6d557fa51de0f6e9b7
Parent: ba3d3210d7fb2ad0379b90869c1e38167346091b
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Jun 8 10:46:22 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 8 11:58:36 2017 +0200
thin: disallow creation of too big thin pools
When a combination of thin-pool chunk size and thin-pool data size
goes beyond addressable limit, such volume creation is directly
prohibited.
Maximum usable thin-pool size is calculated with use of maximal support
metadata size (even when it's created smaller) and given chunk-size.
If the value data size is found to be too big, the command reports
error and operation fails.
Previously thin-pool was created however lots of thin-pool data LV was
not usable and this space in VG has been wasted.
---
WHATS_NEW | 1 +
lib/metadata/thin_manip.c | 17 +++++++++++++++++
2 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index ae704af..fcf3148 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.172 -
===============================
+ Limit maximal size of thin-pool for specific chunk size.
Print a warning about in-use PVs with no VG using them.
Disable automatic clearing of PVs that look like in-use orphans.
Cache format2 flag is now using segment name type field.
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index c2629ac..726b26b 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -563,6 +563,12 @@ static uint64_t _estimate_metadata_size(uint32_t data_extents, uint32_t extent_s
return _estimate_size(data_extents, extent_size, chunk_size);
}
+/* Estimate maximal supportable thin pool data size for given chunk_size */
+static uint64_t _estimate_max_data_size(uint32_t chunk_size)
+{
+ return chunk_size * (DEFAULT_THIN_POOL_MAX_METADATA_SIZE * 2) * SECTOR_SIZE / UINT64_C(64);
+}
+
/* Estimate thin pool chunk size from data and metadata size (in sector units) */
static uint32_t _estimate_chunk_size(uint32_t data_extents, uint32_t extent_size,
uint64_t metadata_size, int attr)
@@ -628,6 +634,7 @@ int update_thin_pool_params(struct cmd_context *cmd,
{
uint64_t pool_metadata_size = (uint64_t) *pool_metadata_extents * extent_size;
uint32_t estimate_chunk_size;
+ uint64_t max_pool_data_size;
const char *str;
if (!*chunk_size &&
@@ -704,6 +711,16 @@ int update_thin_pool_params(struct cmd_context *cmd,
}
}
+ max_pool_data_size = _estimate_max_data_size(*chunk_size);
+ if ((max_pool_data_size / extent_size) < pool_data_extents) {
+ log_error("Selected chunk size %s cannot address more then %s of thin pool data space.",
+ display_size(cmd, *chunk_size), display_size(cmd, max_pool_data_size));
+ return 0;
+ }
+
+ log_print_unless_silent("Thin pool data with chunk size %s can address at most %s of data.",
+ display_size(cmd, *chunk_size), display_size(cmd, max_pool_data_size));
+
if (!validate_thin_pool_chunk_size(cmd, *chunk_size))
return_0;
6 years, 10 months
master - cleanup: use DM limit define
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ba3d3210d7fb2ad0379...
Commit: ba3d3210d7fb2ad0379b90869c1e38167346091b
Parent: 719d0996930dfad8608c49af2f81008b6ca77cb8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Jun 5 11:26:01 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 8 11:07:58 2017 +0200
cleanup: use DM limit define
For calculation use already defined size in libdm, which give better
estimation of maximal size of thin pool metadata.
---
lib/config/defaults.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 05747fa..51542df 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -104,7 +104,7 @@
#define DEFAULT_THIN_REPAIR_OPTION1 ""
#define DEFAULT_THIN_REPAIR_OPTIONS_CONFIG "#S" DEFAULT_THIN_REPAIR_OPTION1
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
-#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
+#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (DM_THIN_MAX_METADATA_SIZE / 2) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY "generic"
6 years, 10 months
master - cleanup: rename internal define
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=719d0996930dfad8608...
Commit: 719d0996930dfad8608c49af2f81008b6ca77cb8
Parent: 39703cb48514415633bc027e49e99e1ee7c4bbb4
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Jun 2 11:18:04 2017 +0200
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Jun 8 11:07:18 2017 +0200
cleanup: rename internal define
More descriptive name of #define.
---
lib/config/defaults.h | 2 +-
lib/metadata/thin_manip.c | 2 +-
liblvm/lvm_lv.c | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 65b81f1..05747fa 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -106,7 +106,7 @@
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
-#define DEFAULT_THIN_POOL_OPTIMAL_SIZE (128 * 1024 * 1024) /* KB */
+#define DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE (128 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY "generic"
#define DEFAULT_THIN_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE 512 /* KB */
diff --git a/lib/metadata/thin_manip.c b/lib/metadata/thin_manip.c
index f9cd3d0..c2629ac 100644
--- a/lib/metadata/thin_manip.c
+++ b/lib/metadata/thin_manip.c
@@ -666,7 +666,7 @@ int update_thin_pool_params(struct cmd_context *cmd,
/* Check if we should eventually use bigger chunk size */
while ((pool_metadata_size >
- (DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) &&
+ (DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE / SECTOR_SIZE)) &&
(*chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE)) {
*chunk_size <<= 1;
pool_metadata_size >>= 1;
diff --git a/liblvm/lvm_lv.c b/liblvm/lvm_lv.c
index d5ca821..46fc3d9 100644
--- a/liblvm/lvm_lv.c
+++ b/liblvm/lvm_lv.c
@@ -507,7 +507,7 @@ static int _lv_set_pool_params(struct lvcreate_params *lp,
pool_metadata_size = extents * vg->extent_size /
(lp->chunk_size * (SECTOR_SIZE / 64));
while ((pool_metadata_size >
- (2 * DEFAULT_THIN_POOL_OPTIMAL_SIZE / SECTOR_SIZE)) &&
+ (2 * DEFAULT_THIN_POOL_OPTIMAL_METADATA_SIZE / SECTOR_SIZE)) &&
lp->chunk_size < DM_THIN_MAX_DATA_BLOCK_SIZE) {
lp->chunk_size <<= 1;
pool_metadata_size >>= 1;
6 years, 10 months
master - lvconvert: reject RAID conversions on inactive LVs
by Heinz Mauelshagen
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=39703cb48514415633b...
Commit: 39703cb48514415633bc027e49e99e1ee7c4bbb4
Parent: 61420309ee34bb77318bf3913eb539b8f85adbda
Author: Heinz Mauelshagen <heinzm(a)redhat.com>
AuthorDate: Wed Jun 7 18:37:04 2017 +0200
Committer: Heinz Mauelshagen <heinzm(a)redhat.com>
CommitterDate: Wed Jun 7 18:37:04 2017 +0200
lvconvert: reject RAID conversions on inactive LVs
Only support RAID conversions on active LVs.
If we'd accept e.g. upconverting linear -> raid1 on inactive
linear LVs, any LV flags passed to the kernel aren't properly
cleared thus errouneously passing them on every activation.
Add respective check to lv_raid_change_image_count() and
move existing one in lv_raid_convert() for better messages.
---
lib/metadata/raid_manip.c | 25 ++++++++++++++++---------
1 files changed, 16 insertions(+), 9 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 8c9069c..5db4a8e 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -3058,6 +3058,13 @@ int lv_raid_change_image_count(struct logical_volume *lv, int yes, uint32_t new_
const char *level = seg->area_count == 1 ? "raid1 with " : "";
const char *resil = new_count < seg->area_count ? "reducing" : "enhancing";
+ /* LV must be active to perform raid conversion operations */
+ if (!lv_is_active(lv)) {
+ log_error("%s must be active to perform this operation.",
+ display_lvname(lv));
+ return 0;
+ }
+
if (new_count != 1 && /* Already prompted for in _raid_remove_images() */
!yes && yes_no_prompt("Are you sure you want to convert %s LV %s to %s%u images %s resilience? [y/n]: ",
lvseg_name(first_seg(lv)), display_lvname(lv), level, new_count, resil) == 'n') {
@@ -6158,6 +6165,15 @@ int lv_raid_convert(struct logical_volume *lv,
uint32_t available_slvs, removed_slvs;
takeover_fn_t takeover_fn;
+ /* FIXME If not active, prompt and activate */
+ /* FIXME Some operations do not require the LV to be active */
+ /* LV must be active to perform raid conversion operations */
+ if (!lv_is_active(lv)) {
+ log_error("%s must be active to perform this operation.",
+ display_lvname(lv));
+ return 0;
+ }
+
new_segtype = new_segtype ? : seg->segtype;
if (!new_segtype) {
log_error(INTERNAL_ERROR "New segtype not specified.");
@@ -6261,15 +6277,6 @@ int lv_raid_convert(struct logical_volume *lv,
(segtype_is_striped_target(new_segtype) &&
(new_stripes == 1)) ? SEG_TYPE_NAME_LINEAR : new_segtype->name);
- /* FIXME If not active, prompt and activate */
- /* FIXME Some operations do not require the LV to be active */
- /* LV must be active to perform raid conversion operations */
- if (!lv_is_active(lv)) {
- log_error("%s must be active to perform this operation.",
- display_lvname(lv));
- return 0;
- }
-
/* In clustered VGs, the LV must be active on this node exclusively. */
if (vg_is_clustered(lv->vg) && !lv_is_active_exclusive_locally(lv)) {
log_error("%s must be active exclusive locally to "
6 years, 10 months
master - test: Update to RAID1 upconvert using recover
by Marian Csontos
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b5aa72441c53d6dc356...
Commit: b5aa72441c53d6dc356f9b67463934fa5c1bd2a8
Parent: acaf3a5d47fd65b2e385a516544f8e6ec8d89b2d
Author: Marian Csontos <mcsontos(a)redhat.com>
AuthorDate: Wed Jun 7 14:26:05 2017 +0200
Committer: Marian Csontos <mcsontos(a)redhat.com>
CommitterDate: Wed Jun 7 14:28:31 2017 +0200
test: Update to RAID1 upconvert using recover
Commit 88e649628863 changed upconverting from linear to RAID using
recover instead of resync.
---
test/shell/lvcreate-large-raid.sh | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/test/shell/lvcreate-large-raid.sh b/test/shell/lvcreate-large-raid.sh
index ca3f715..7540c6f 100644
--- a/test/shell/lvcreate-large-raid.sh
+++ b/test/shell/lvcreate-large-raid.sh
@@ -101,7 +101,7 @@ lvremove -ff $vg1
lvcreate -aey -L 200T -n $lv1 $vg1
lvconvert -y --type raid1 -m 1 $vg1/$lv1
check lv_field $vg1/$lv1 size "200.00t"
-check raid_leg_status $vg1 $lv1 "aa"
+check raid_leg_status $vg1 $lv1 "Aa"
lvremove -ff $vg1
# bz837927 END
6 years, 10 months
master - lvconvert: Don't require a 'force' option during RAID repair.
by Jonathan Brassow
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=acaf3a5d47fd65b2e38...
Commit: acaf3a5d47fd65b2e385a516544f8e6ec8d89b2d
Parent: 88e649628863e78b101c584c513053fc9461c24d
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Jun 6 10:43:49 2017 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Jun 6 10:43:49 2017 -0500
lvconvert: Don't require a 'force' option during RAID repair.
Previously, we were treating non-RAID to RAID up-converts as a "resync"
operation. (The most common example being 'linear -> RAID1'.) RAID to
RAID up-converts or rebuilds of specific RAID images are properly treated
as a "recover" operation.
Since we were treating some up-convert operations as "resync", it was
possible to have scenarios where data corruption or data loss were
possibilities if the RAID hadn't been able to sync completely before a
loss of the primary source devices. In order to ensure that the user took
the proper precautions in such scenarios, we required a '--force' option
to be present. Unfortuneately, the force option was rendered useless
because there was no way to distiguish the failure state of a potentially
destructive repair from a nominal one - making the '--force' option a
requirement for any repair!
We now treat non-RAID to RAID up-converts properly as "recover" operations.
This eliminates the scenarios that can potentially cause data loss or
data corruption; and this eliminates the need for the '--force' requirement.
This patch removes the requirement to specify '--force' for RAID repairs.
---
lib/metadata/raid_manip.c | 31 +------------------------------
1 files changed, 1 insertions(+), 30 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 7e55530..08df32c 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -379,23 +379,6 @@ int lv_raid_in_sync(const struct logical_volume *lv)
return _raid_in_sync(lv);
}
-/* Check if RaidLV @lv is synced or any raid legs of @lv are not synced */
-static int _raid_devs_sync_healthy(struct logical_volume *lv)
-{
- char *raid_health;
-
- if (!_raid_in_sync(lv))
- return 0;
-
- if (!seg_is_raid1(first_seg(lv)))
- return 1;
-
- if (!lv_raid_dev_health(lv, &raid_health))
- return_0;
-
- return (strchr(raid_health, 'a') || strchr(raid_health, 'D')) ? 0 : 1;
-}
-
/*
* _raid_remove_top_layer
* @lv
@@ -2908,20 +2891,8 @@ static int _raid_extract_images(struct logical_volume *lv,
if (!lv_is_on_pvs(seg_lv(seg, s), target_pvs) &&
!lv_is_on_pvs(seg_metalv(seg, s), target_pvs))
continue;
-
- /*
- * Kernel may report raid LV in-sync but still
- * image devices may not be in-sync or faulty.
- */
- if (!_raid_devs_sync_healthy(lv) &&
- (!seg_is_mirrored(seg) || (s == 0 && !force))) {
- log_error("Unable to extract %sRAID image"
- " while RAID array is not in-sync%s.",
- seg_is_mirrored(seg) ? "primary " : "",
- seg_is_mirrored(seg) ? " (use --force option to replace)" : "");
- return 0;
- }
}
+
if (!_extract_image_components(seg, s, &rmeta_lv, &rimage_lv)) {
log_error("Failed to extract %s from %s.",
display_lvname(seg_lv(seg, s)),
6 years, 10 months
master - lvconvert: linear -> raid1 upconvert should cause "recover" not "resync"
by Jonathan Brassow
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=88e649628863e78b101...
Commit: 88e649628863e78b101c584c513053fc9461c24d
Parent: 61420309ee34bb77318bf3913eb539b8f85adbda
Author: Jonathan Brassow <jbrassow(a)redhat.com>
AuthorDate: Tue Jun 6 10:43:12 2017 -0500
Committer: Jonathan Brassow <jbrassow(a)redhat.com>
CommitterDate: Tue Jun 6 10:43:12 2017 -0500
lvconvert: linear -> raid1 upconvert should cause "recover" not "resync"
Two of the sync actions performed by the kernel (aka MD runtime) are
"resync" and "recover". The "resync" refers to when an entirely new array
is going through the process of initializing (or resynchronizing after an
unexpected shutdown). The "recover" is the process of initializing a new
member device to the array. So, a brand new array with all new devices
will undergo "resync". An array with replaced or added sub-LVs will undergo
"recover".
These two states are treated very differently when failures happen. If any
device is lost or replaced while "resync", there are no worries. This is
because any writes created from the inception of the array have occurred to
all the devices and can be safely recovered. Even though non-initialized
portions will still be resync'ed with uninitialized data, it is ok. However,
if a pre-existing device is lost (aka, the original linear device in a
linear -> raid1 convert) during a "recover", data loss can be the result.
Thus, writes are errored by the kernel and recovery is halted. The failed
device must be restored or removed. This is the correct behavior.
Unfortunately, we were treating an up-convert from linear as a "resync"
when we should have been treating it as a "recover". This patch
removes the special case for linear upconvert. It allows each new image
sub-LV to be marked with a rebuild flag and treats the array as 'in-sync'.
This has the correct effect of causing the upconvert to be treated as a
"recover" rather than a "resync". There is no need to flag these two states
differently in LVM metadata, because they are already considered differently
by the kernel RAID metadata. (Any activation/deactivation will properly
resume the "recover" process and not a "resync" process.)
---
lib/metadata/raid_manip.c | 3 ---
1 files changed, 0 insertions(+), 3 deletions(-)
diff --git a/lib/metadata/raid_manip.c b/lib/metadata/raid_manip.c
index 8c9069c..7e55530 100644
--- a/lib/metadata/raid_manip.c
+++ b/lib/metadata/raid_manip.c
@@ -2559,9 +2559,6 @@ static int _raid_add_images_without_commit(struct logical_volume *lv,
* LV to accompany it.
*/
if (seg_is_linear(seg)) {
- /* A complete resync will be done, no need to mark each sub-lv */
- status_mask = ~(LV_REBUILD);
-
/* FIXME: allow setting region size on upconvert from linear */
seg->region_size = get_default_region_size(lv->vg->cmd);
/* MD's bitmap is limited to tracking 2^21 regions */
6 years, 10 months
master - lvmdbusd: Prevent stall when update thread gets exception
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=61420309ee34bb77318...
Commit: 61420309ee34bb77318bf3913eb539b8f85adbda
Parent: 699ccc05cacc32b4707bf12dba4ccbb994469048
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Fri Jun 2 12:29:27 2017 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Fri Jun 2 12:39:04 2017 -0500
lvmdbusd: Prevent stall when update thread gets exception
If during the process of fetching current lvm state we experience an
exception we fail to call set_result on the queued_requests we were
processing. When this happens those threads block forever which causes
the service to stall infinitely. Only clear the queued_requests after
we have called set_result.
---
daemons/lvmdbusd/fetch.py | 10 ++++++++--
1 files changed, 8 insertions(+), 2 deletions(-)
diff --git a/daemons/lvmdbusd/fetch.py b/daemons/lvmdbusd/fetch.py
index 78c3a4b..c053685 100644
--- a/daemons/lvmdbusd/fetch.py
+++ b/daemons/lvmdbusd/fetch.py
@@ -82,10 +82,10 @@ class StateUpdate(object):
@staticmethod
def update_thread(obj):
+ queued_requests = []
while cfg.run.value != 0:
# noinspection PyBroadException
try:
- queued_requests = []
refresh = True
emit_signal = True
cache_refresh = True
@@ -96,7 +96,7 @@ class StateUpdate(object):
wait = not obj.deferred
obj.deferred = False
- if wait:
+ if len(queued_requests) == 0 and wait:
queued_requests.append(obj.queue.get(True, 2))
# Ok we have one or the deferred queue has some,
@@ -131,11 +131,17 @@ class StateUpdate(object):
for i in queued_requests:
i.set_result(num_changes)
+ # Only clear out the requests after we have given them a result
+ # otherwise we can orphan the waiting threads and they never
+ # wake up if we get an exception
+ queued_requests = []
+
except queue.Empty:
pass
except Exception:
st = traceback.format_exc()
log_error("update_thread exception: \n%s" % st)
+ cfg.blackbox.dump()
def __init__(self):
self.lock = threading.RLock()
6 years, 10 months
master - lvmdbusd: Add background command to flight recorder
by Tony Asleson
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=699ccc05cacc32b4707...
Commit: 699ccc05cacc32b4707bf12dba4ccbb994469048
Parent: 192d142e1cd38c1593ec76502d8424997ec01ec8
Author: Tony Asleson <tasleson(a)redhat.com>
AuthorDate: Fri Jun 2 12:25:01 2017 -0500
Committer: Tony Asleson <tasleson(a)redhat.com>
CommitterDate: Fri Jun 2 12:32:51 2017 -0500
lvmdbusd: Add background command to flight recorder
We were not adding background tasks to flight recorder. Add the meta
data to the flight recorder when we start the command and update the meta
data when the command is finished. Locking was added to meta data to
prevent concurrent update and returning string representation as these can
happen in two different threads.
---
daemons/lvmdbusd/background.py | 13 ++++++++++++-
daemons/lvmdbusd/cmdhandler.py | 14 ++++++++------
2 files changed, 20 insertions(+), 7 deletions(-)
diff --git a/daemons/lvmdbusd/background.py b/daemons/lvmdbusd/background.py
index f7f77d5..90e8b68 100644
--- a/daemons/lvmdbusd/background.py
+++ b/daemons/lvmdbusd/background.py
@@ -9,12 +9,13 @@
import subprocess
from . import cfg
-from .cmdhandler import options_to_cli_args
+from .cmdhandler import options_to_cli_args, LvmExecutionMeta
import dbus
from .utils import pv_range_append, pv_dest_ranges, log_error, log_debug,\
add_no_notify
import os
import threading
+import time
def pv_move_lv_cmd(move_options, lv_full_name,
@@ -47,6 +48,11 @@ def _move_merge(interface_name, command, job_state):
# Instruct lvm to not register an event with us
command = add_no_notify(command)
+ #(self, start, ended, cmd, ec, stdout_txt, stderr_txt)
+ meta = LvmExecutionMeta(time.time(), 0, command, -1000, None, None)
+
+ cfg.blackbox.add(meta)
+
process = subprocess.Popen(command, stdout=subprocess.PIPE,
env=os.environ,
stderr=subprocess.PIPE, close_fds=True)
@@ -74,6 +80,11 @@ def _move_merge(interface_name, command, job_state):
out = process.communicate()
+ with meta.lock:
+ meta.ended = time.time()
+ meta.ec = process.returncode
+ meta.stderr_txt = out[1]
+
if process.returncode == 0:
job_state.Percent = 100
else:
diff --git a/daemons/lvmdbusd/cmdhandler.py b/daemons/lvmdbusd/cmdhandler.py
index a883f1e..4fb1670 100644
--- a/daemons/lvmdbusd/cmdhandler.py
+++ b/daemons/lvmdbusd/cmdhandler.py
@@ -37,6 +37,7 @@ cmd_lock = threading.RLock()
class LvmExecutionMeta(object):
def __init__(self, start, ended, cmd, ec, stdout_txt, stderr_txt):
+ self.lock = threading.RLock()
self.start = start
self.ended = ended
self.cmd = cmd
@@ -45,12 +46,13 @@ class LvmExecutionMeta(object):
self.stderr_txt = stderr_txt
def __str__(self):
- return "EC= %d for %s\n" \
- "STARTED: %f, ENDED: %f\n" \
- "STDOUT=%s\n" \
- "STDERR=%s\n" % \
- (self.ec, str(self.cmd), self.start, self.ended, self.stdout_txt,
- self.stderr_txt)
+ with self.lock:
+ return "EC= %d for %s\n" \
+ "STARTED: %f, ENDED: %f\n" \
+ "STDOUT=%s\n" \
+ "STDERR=%s\n" % \
+ (self.ec, str(self.cmd), self.start, self.ended, self.stdout_txt,
+ self.stderr_txt)
class LvmFlightRecorder(object):
6 years, 10 months