master - format_text: Use explicit alignment in wrapping calc.
by Alasdair Kergon
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=14b1e5270dbca71870a...
Commit: 14b1e5270dbca71870a79b37d6614e2cb96b180f
Parent: 4c88c4626d9870d4fa146f7596a37853cf965a39
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Fri Dec 8 01:11:34 2017 +0000
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Fri Dec 8 01:18:46 2017 +0000
format_text: Use explicit alignment in wrapping calc.
Expand out the metadata wrapping calculations to prepare
to support a larger alignment.
The current alignment is 512 bytes so
(mdac_area_start + rlocn->offset) % alignment is zero.
---
lib/format_text/format-text.c | 29 +++++++++++++++++------------
lib/format_text/layout.h | 1 +
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index 09ce693..c96fad9 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -472,19 +472,24 @@ static struct raw_locn *_find_vg_rlocn(struct device_area *dev_area,
/*
* Determine offset for uncommitted metadata
*/
-static uint64_t _next_rlocn_offset(struct raw_locn *rlocn,
- struct mda_header *mdah)
+static uint64_t _next_rlocn_offset(struct raw_locn *rlocn, struct mda_header *mdah, uint64_t mdac_area_start, uint64_t alignment)
{
+ uint64_t new_start_offset;
+
if (!rlocn)
/* Find an empty slot */
/* FIXME Assume only one VG per mdah for now */
- return MDA_HEADER_SIZE;
+ return alignment;
+
+ /* Calculate new start position within buffer rounded up to absolute alignment */
+ new_start_offset = rlocn->offset + rlocn->size +
+ (alignment - (mdac_area_start + rlocn->offset + rlocn->size) % alignment);
- /* Start of free space - round up to next sector; circular */
- return ((rlocn->offset + rlocn->size +
- (SECTOR_SIZE - rlocn->size % SECTOR_SIZE) -
- MDA_HEADER_SIZE) % (mdah->size - MDA_HEADER_SIZE))
- + MDA_HEADER_SIZE;
+ /* If new location is beyond the end of the buffer, wrap around back to start of circular buffer */
+ if (new_start_offset > mdah->size - MDA_HEADER_SIZE)
+ new_start_offset -= (mdah->size - MDA_HEADER_SIZE);
+
+ return new_start_offset;
}
static int _raw_holds_vgname(struct format_instance *fid,
@@ -643,9 +648,6 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
if (!(mdah = raw_read_mda_header(fid->fmt, &mdac->area, mda_is_primary(mda))))
goto_out;
- rlocn = _find_vg_rlocn(&mdac->area, mdah, mda_is_primary(mda), old_vg_name ? : vg->name, &noprecommit);
- mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah);
-
if (!fidtc->raw_metadata_buf &&
!(fidtc->raw_metadata_buf_size =
text_vg_export_raw(vg, "", &fidtc->raw_metadata_buf))) {
@@ -653,6 +655,9 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
goto out;
}
+ rlocn = _find_vg_rlocn(&mdac->area, mdah, mda_is_primary(mda), old_vg_name ? : vg->name, &noprecommit);
+
+ mdac->rlocn.offset = _next_rlocn_offset(rlocn, mdah, mdac->area.start, MDA_ORIGINAL_ALIGNMENT);
mdac->rlocn.size = fidtc->raw_metadata_buf_size;
if (mdac->rlocn.offset + mdac->rlocn.size > mdah->size)
@@ -683,7 +688,7 @@ static int _vg_write_raw(struct format_instance *fid, struct volume_group *vg,
goto_out;
if (new_wrap) {
- log_debug_metadata("Writing metadata to %s at %" PRIu64 " len %" PRIu64,
+ log_debug_metadata("Writing wrapped metadata to %s at %" PRIu64 " len %" PRIu64,
dev_name(mdac->area.dev), mdac->area.start +
MDA_HEADER_SIZE, new_wrap);
diff --git a/lib/format_text/layout.h b/lib/format_text/layout.h
index c88812f..1746b9c 100644
--- a/lib/format_text/layout.h
+++ b/lib/format_text/layout.h
@@ -102,6 +102,7 @@ struct mda_context {
#define MDA_HEADER_SIZE 512
#define LVM2_LABEL "LVM2 001"
#define MDA_SIZE_MIN (8 * (unsigned) lvm_getpagesize())
+#define MDA_ORIGINAL_ALIGNMENT 512 /* Original alignment used for start of VG metadata content */
int vgname_from_mda(const struct format_type *fmt, struct mda_header *mdah, int primary_mda,
struct device_area *dev_area, struct lvmcache_vgsummary *vgsummary,
6 years, 4 months
master - debug: update debug msg
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4c88c4626d9870d4fa1...
Commit: 4c88c4626d9870d4fa146f7596a37853cf965a39
Parent: 717714b24ffbf648a1b22e9306484944a514c565
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 7 17:54:41 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 21:00:39 2017 +0100
debug: update debug msg
Use _node_name.
---
libdm/libdm-deptree.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 6ba20a4..98dda44 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -2786,9 +2786,9 @@ static int _dm_tree_revert_activated(struct dm_tree_node *parent)
struct dm_tree_node *child;
dm_list_iterate_items_gen(child, &parent->activated, activated_list) {
- log_debug_activation("Reverting %s.", child->name);
+ log_debug_activation("Reverting %s.", _node_name(child));
if (child->callback) {
- log_debug_activation("Dropping callback for %s.", child->name);
+ log_debug_activation("Dropping callback for %s.", _node_name(child));
child->callback = NULL;
}
if (!_deactivate_node(child->name, child->info.major, child->info.minor,
6 years, 4 months
master - cleanup: use log_warn
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=717714b24ffbf648a1b...
Commit: 717714b24ffbf648a1b22e9306484944a514c565
Parent: f173274fe4888cc73eb573cf2c6913f54641c1aa
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 7 10:42:30 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 21:00:39 2017 +0100
cleanup: use log_warn
---
libdm/libdm-common.c | 14 +++++++-------
1 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/libdm/libdm-common.c b/libdm/libdm-common.c
index f5c6062..2ab5bd1 100644
--- a/libdm/libdm-common.c
+++ b/libdm/libdm-common.c
@@ -1917,13 +1917,13 @@ int dm_device_has_holders(uint32_t major, uint32_t minor)
if (dm_snprintf(sysfs_path, PATH_MAX, "%sdev/block/%" PRIu32
":%" PRIu32 "/holders", _sysfs_dir, major, minor) < 0) {
- log_error("sysfs_path dm_snprintf failed");
+ log_warn("WARNING: sysfs_path dm_snprintf failed.");
return 0;
}
if (stat(sysfs_path, &st)) {
if (errno != ENOENT)
- log_sys_error("stat", sysfs_path);
+ log_sys_debug("stat", sysfs_path);
return 0;
}
@@ -1939,13 +1939,13 @@ static int _mounted_fs_on_device(const char *kernel_dev_name)
int r = 0;
if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs", _sysfs_dir) < 0) {
- log_error("sysfs_path dm_snprintf failed");
+ log_warn("WARNING: sysfs_path dm_snprintf failed.");
return 0;
}
if (!(d = opendir(sysfs_path))) {
if (errno != ENOENT)
- log_sys_error("opendir", sysfs_path);
+ log_sys_debug("opendir", sysfs_path);
return 0;
}
@@ -1955,7 +1955,7 @@ static int _mounted_fs_on_device(const char *kernel_dev_name)
if (dm_snprintf(sysfs_path, PATH_MAX, "%sfs/%s/%s",
_sysfs_dir, dirent->d_name, kernel_dev_name) < 0) {
- log_error("sysfs_path dm_snprintf failed");
+ log_warn("WARNING: sysfs_path dm_snprintf failed.");
break;
}
@@ -1965,13 +1965,13 @@ static int _mounted_fs_on_device(const char *kernel_dev_name)
break;
}
else if (errno != ENOENT) {
- log_sys_error("stat", sysfs_path);
+ log_sys_debug("stat", sysfs_path);
break;
}
}
if (closedir(d))
- log_error("_fs_present_on_device: %s: closedir failed", kernel_dev_name);
+ log_sys_debug("closedir", kernel_dev_name);
return r;
}
6 years, 4 months
master - cleanup: reorder calling of pool checking tools
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f173274fe4888cc73eb...
Commit: f173274fe4888cc73eb573cf2c6913f54641c1aa
Parent: 820b1b98fce4a370e9b54ffbc8cbe4b3d0e962f3
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 7 17:49:15 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 21:00:39 2017 +0100
cleanup: reorder calling of pool checking tools
Test for zero header before even starting to create argument list for
execution of thin/cache_check tool.
---
lib/activate/dev_manager.c | 70 ++++++++++++++++++++++---------------------
1 files changed, 36 insertions(+), 34 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index c050f34..ced50fa 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1912,11 +1912,42 @@ static int _pool_callback(struct dm_tree_node *node,
const struct logical_volume *mlv = first_seg(pool_lv)->metadata_lv;
long buf[64 / sizeof(long)]; /* buffer for short disk header (64B) */
int args = 0;
- const char *argv[19] = { /* Max supported 15 args */
- find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL) /* argv[0] */
- };
+ char *mpath;
+ const char *argv[19] = { 0 }; /* Max supported 15 args */
+
+ if (!(mpath = lv_dmpath_dup(data->dm->mem, mlv))) {
+ log_error("Failed to build device path for checking pool metadata %s.",
+ display_lvname(mlv));
+ return 0;
+ }
+
+ if (data->skip_zero) {
+ if ((fd = open(mpath, O_RDONLY)) < 0) {
+ log_sys_error("open", mpath);
+ return 0;
+ }
+ /* let's assume there is no problem to read 64 bytes */
+ if (read(fd, buf, sizeof(buf)) < (int)sizeof(buf)) {
+ log_sys_error("read", mpath);
+ if (close(fd))
+ log_sys_error("close", mpath);
+ return 0;
+ }
+ for (ret = 0; ret < (int) DM_ARRAY_SIZE(buf); ++ret)
+ if (buf[ret])
+ break;
+
+ if (close(fd))
+ log_sys_error("close", mpath);
+
+ if (ret == (int) DM_ARRAY_SIZE(buf)) {
+ log_debug_activation("Metadata checking skipped, detected empty disk header on %s.",
+ mpath);
+ return 1;
+ }
+ }
- if (!*argv[0])
+ if (!(argv[0] = find_config_tree_str_allow_empty(pool_lv->vg->cmd, data->exec, NULL)))
return 1; /* Checking disabled */
if (!(cn = find_config_tree_array(mlv->vg->cmd, data->opts, NULL))) {
@@ -1939,36 +1970,7 @@ static int _pool_callback(struct dm_tree_node *node,
return 0;
}
- if (!(argv[++args] = lv_dmpath_dup(data->dm->mem, mlv))) {
- log_error("Failed to build pool metadata path.");
- return 0;
- }
-
- if (data->skip_zero) {
- if ((fd = open(argv[args], O_RDONLY)) < 0) {
- log_sys_error("open", argv[args]);
- return 0;
- }
- /* let's assume there is no problem to read 64 bytes */
- if (read(fd, buf, sizeof(buf)) < (int)sizeof(buf)) {
- log_sys_error("read", argv[args]);
- if (close(fd))
- log_sys_error("close", argv[args]);
- return 0;
- }
- for (ret = 0; ret < (int) DM_ARRAY_SIZE(buf); ++ret)
- if (buf[ret])
- break;
-
- if (close(fd))
- log_sys_error("close", argv[args]);
-
- if (ret == (int) DM_ARRAY_SIZE(buf)) {
- log_debug_activation("%s skipped, detect empty disk header on %s.",
- argv[0], argv[args]);
- return 1;
- }
- }
+ argv[++args] = mpath;
if (!(ret = exec_cmd(pool_lv->vg->cmd, (const char * const *)argv,
&status, 0))) {
6 years, 4 months
master - libdm: drop extra structure copy
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=820b1b98fce4a370e9b...
Commit: 820b1b98fce4a370e9b54ffbc8cbe4b3d0e962f3
Parent: 82ae02bc6a6788aabb10ac8a95287feea37ab88c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 7 17:47:06 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 21:00:39 2017 +0100
libdm: drop extra structure copy
When doing resume, directly pass location where new updated info
needs to be stored.
_resume_node() ensures the info is ONLY updated when the function
is successful and never changes it on error path.
---
libdm/libdm-deptree.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 745fec3..6ba20a4 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1848,7 +1848,6 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
int resolvable_name_conflict, awaiting_peer_rename = 0;
void *handle = NULL;
struct dm_tree_node *child = dnode;
- struct dm_info newinfo;
const char *name;
const char *uuid;
int priority;
@@ -1913,14 +1912,11 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
if (!_resume_node(child->name, child->info.major, child->info.minor,
child->props.read_ahead, child->props.read_ahead_flags,
- &newinfo, &child->dtree->cookie, child->udev_flags, child->info.suspended)) {
+ &child->info, &child->dtree->cookie, child->udev_flags, child->info.suspended)) {
log_error("Unable to resume %s.", _node_name(child));
r = 0;
continue;
}
-
- /* Update cached info */
- child->info = newinfo;
}
if (awaiting_peer_rename)
priority--; /* redo priority level */
@@ -2814,7 +2810,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
int r = 1, node_created = 0;
void *handle = NULL;
struct dm_tree_node *child;
- struct dm_info newinfo;
int update_devs_flag = 0;
/* Preload children first */
@@ -2870,7 +2865,7 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!_resume_node(child->name, child->info.major, child->info.minor,
child->props.read_ahead, child->props.read_ahead_flags,
- &newinfo, &child->dtree->cookie, child->udev_flags,
+ &child->info, &child->dtree->cookie, child->udev_flags,
child->info.suspended)) {
log_error("Unable to resume %s.", _node_name(child));
/* If the device was not previously active, we might as well remove this node. */
@@ -2883,7 +2878,7 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
continue;
}
- if (!child->info.live_table) {
+ if (node_created) {
/* Collect newly introduced devices for revert */
dm_list_add_h(&dnode->activated, &child->activated_list);
@@ -2900,8 +2895,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
}
}
- /* Update cached info */
- child->info = newinfo;
/*
* Prepare for immediate synchronization with udev and flush all stacked
* dev node operations if requested by immediate_dev_node property. But
6 years, 4 months
master - libdm: use delay_resume_if_extended
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=82ae02bc6a6788aabb1...
Commit: 82ae02bc6a6788aabb10ac8a95287feea37ab88c
Parent: 297d5915c3c927cba3a63bc9d6d1747271d06641
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 7 20:28:03 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 21:00:39 2017 +0100
libdm: use delay_resume_if_extended
Update the logic towards more explicit logic.
Preload tree normally does not want to resume, only
in certain cases of extension or new loaded nodes can be
resumed. So introduce new internal variable delay_resume_if_extended
controlable by target.
Patch itself is not changing current existing behaviour,
and rather documents existing problem in more readable way.
lvm2 needs to introduce explicit mechanism how to support more
fain-grained (and safe) logic to i.e. resize thin-pool which
can be sitting on cached raid volume.
---
libdm/libdm-deptree.c | 55 ++++++++++++++++++++++++++++--------------------
1 files changed, 32 insertions(+), 23 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index f463eab..745fec3 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -233,6 +233,19 @@ struct load_properties {
unsigned delay_resume_if_new;
/*
+ * Preload tree normally only loads and not resume, but there is
+ * automatic resume when target is extended, as it's believed
+ * there can be no i/o flying to this 'new' extedend space
+ * from any device above. Reason is that preloaded target above
+ * may actually need to see its bigger subdevice before it
+ * gets suspended. As long as devices are simple linears
+ * there is no problem to resume bigger device in preload (before commit).
+ * However complex targets like thin-pool (raid,cache...)
+ * they shall not be resumed before their commit.
+ */
+ unsigned delay_resume_if_extended;
+
+ /*
* Call node_send_messages(), set to 2 if there are messages
* When != 0, it validates matching transaction id, thus thin-pools
* where transation_id is passed as 0 are never validated, this
@@ -2745,6 +2758,18 @@ static int _load_node(struct dm_tree_node *dnode)
PRIu64 " for %s.%s", existing_table_size,
seg_start, _node_name(dnode),
dnode->props.size_changed ? "" : " (Ignoring.)");
+
+ /*
+ * FIXME: code here has known design problem.
+ * LVM2 does NOT resize thin-pool on top of other LV in 2 steps -
+ * where raid would be resized with 1st. transaction
+ * followed by 2nd. thin-pool resize - RHBZ #1285063
+ */
+ if (existing_table_size && dnode->props.delay_resume_if_extended) {
+ log_debug_activation("Resume of table of extended device %s delayed.",
+ _node_name(dnode));
+ dnode->props.size_changed = 0;
+ }
}
}
@@ -2791,7 +2816,6 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
struct dm_tree_node *child;
struct dm_info newinfo;
int update_devs_flag = 0;
- struct load_segment *seg;
/* Preload children first */
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
@@ -2816,6 +2840,10 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!child->info.exists && !(node_created = _create_node(child)))
return_0;
+ /* Propagate delayed resume from exteded child node */
+ if (child->props.delay_resume_if_extended)
+ dnode->props.delay_resume_if_extended = 1;
+
if (!child->info.inactive_table &&
child->props.segment_count &&
!_load_node(child)) {
@@ -2833,32 +2861,10 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
return_0;
}
- /* Propagate device size change change */
- if (child->props.size_changed > 0 && !dnode->props.size_changed)
- dnode->props.size_changed = 1;
- else if (child->props.size_changed < 0)
- dnode->props.size_changed = -1;
-
/* No resume for a device without parents or with unchanged or smaller size */
if (!dm_tree_node_num_children(child, 1) || (child->props.size_changed <= 0))
continue;
- if (!node_created && (dm_list_size(&child->props.segs) == 1)) {
- /* If thin-pool child nodes were preloaded WITH changed size
- * skip device resume, as this is likely resize of data or
- * metadata device and so thin pool needs suspend before
- * resume operation.
- * Note: child->props.segment_count is already 0 here
- */
- seg = dm_list_item(dm_list_last(&child->props.segs),
- struct load_segment);
- if (seg->type == SEG_THIN_POOL) {
- log_debug_activation("Skipping resume of thin-pool %s.",
- child->name);
- continue;
- }
- }
-
if (!child->info.inactive_table && !child->info.suspended)
continue;
@@ -3527,6 +3533,9 @@ int dm_tree_node_add_thin_pool_target(struct dm_tree_node *node,
seg->metadata->props.delay_resume_if_new = 0;
seg->pool->props.delay_resume_if_new = 0;
+ /* Preload must not resume extended running thin-pool before it's committed */
+ node->props.delay_resume_if_extended = 1;
+
/* Validate only transaction_id > 0 when activating thin-pool */
node->props.send_messages = transaction_id ? 1 : 0;
seg->transaction_id = transaction_id;
6 years, 4 months
master - libdm: avoid checking status on activation
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=297d5915c3c927cba3a...
Commit: 297d5915c3c927cba3a63bc9d6d1747271d06641
Parent: 4a4ea47f709287444f3b0d8e0581ce17e730ef4c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Thu Dec 7 17:52:01 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 21:00:36 2017 +0100
libdm: avoid checking status on activation
Variable props.send_messages has 3 states and was not used properly
here. Activation in this moment does not need to verify thin-pool status
as that has been already checked on preload.
So only if there are some real messages (value 2) call function
for sending them.
---
WHATS_NEW_DM | 1 +
libdm/libdm-deptree.c | 2 +-
2 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index dfa5a97..d9503c2 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.146 -
====================================
+ Activation tree of thin pool skips duplicated check of pool status.
Remove code supporting replicator target.
Do not ignore failure of _info_by_dev().
Propagate delayed resume for pvmove subvolumes.
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index ef5da59..f463eab 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1920,7 +1920,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
* resume should continue further, just whole command
* has to report failure.
*/
- if (r && dnode->props.send_messages &&
+ if (r && (dnode->props.send_messages > 1) &&
!(r = _node_send_messages(dnode, uuid_prefix, uuid_prefix_len, 1)))
stack;
6 years, 4 months
master - libdm: add help func _get_last_load_segment
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=4a4ea47f709287444f3...
Commit: 4a4ea47f709287444f3b0d8e0581ce17e730ef4c
Parent: c3e224ad0ebd473268b171204c8985c9c642f590
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Dec 6 13:23:37 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 20:59:37 2017 +0100
libdm: add help func _get_last_load_segment
Share code for same functionality.
---
libdm/libdm-deptree.c | 40 ++++++++++++++++++++++++----------------
1 files changed, 24 insertions(+), 16 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 1ef1700..ef5da59 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1485,6 +1485,16 @@ out:
return r;
}
+static struct load_segment *_get_last_load_segment(struct dm_tree_node *node)
+{
+ if (dm_list_empty(&node->props.segs)) {
+ log_error("Node %s is missing a segment.", _node_name(node));
+ return NULL;
+ }
+
+ return dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
+}
+
/* For preload pass only validate pool's transaction_id */
static int _node_send_messages(struct dm_tree_node *dnode,
const char *uuid_prefix,
@@ -1497,10 +1507,12 @@ static int _node_send_messages(struct dm_tree_node *dnode,
const char *uuid;
int have_messages;
- if (!dnode->info.exists || (dm_list_size(&dnode->props.segs) != 1))
+ if (!dnode->info.exists)
return 1;
- seg = dm_list_item(dm_list_last(&dnode->props.segs), struct load_segment);
+ if (!(seg = _get_last_load_segment(dnode)))
+ return_0;
+
if (seg->type != SEG_THIN_POOL)
return 1;
@@ -3146,12 +3158,8 @@ int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
struct dm_tree_node *log_node = NULL;
struct load_segment *seg;
- if (!node->props.segment_count) {
- log_error(INTERNAL_ERROR "Attempt to add target area to missing segment.");
- return 0;
- }
-
- seg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
+ if (!(seg = _get_last_load_segment(node)))
+ return_0;
if (log_uuid) {
if (!(seg->uuid = dm_pool_strdup(node->dtree->mem, log_uuid))) {
@@ -3429,13 +3437,16 @@ static struct load_segment *_get_single_load_segment(struct dm_tree_node *node,
{
struct load_segment *seg;
+ if (!(seg = _get_last_load_segment(node)))
+ return_NULL;
+
+ /* Never used past _load_node(), so can test segment_count */
if (node->props.segment_count != 1) {
log_error("Node %s must have only one segment.",
_dm_segtypes[type].target);
return NULL;
}
- seg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
if (seg->type != type) {
log_error("Node %s has segment type %s.",
_dm_segtypes[type].target,
@@ -3741,12 +3752,8 @@ int dm_tree_node_add_target_area(struct dm_tree_node *node,
return_0;
}
- if (!node->props.segment_count) {
- log_error(INTERNAL_ERROR "Attempt to add target area to missing segment.");
- return 0;
- }
-
- seg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
+ if (!(seg = _get_last_load_segment(node)))
+ return_0;
if (!_add_area(node, seg, dev_node, offset))
return_0;
@@ -3758,7 +3765,8 @@ int dm_tree_node_add_null_area(struct dm_tree_node *node, uint64_t offset)
{
struct load_segment *seg;
- seg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
+ if (!(seg = _get_last_load_segment(node)))
+ return_0;
switch (seg->type) {
case SEG_RAID0:
6 years, 4 months
master - thin: missing type is error
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=c3e224ad0ebd473268b...
Commit: c3e224ad0ebd473268b171204c8985c9c642f590
Parent: 2208ebfe16e5b5cd54c762a5a06edd0681d62fa9
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Dec 6 13:21:01 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 20:59:37 2017 +0100
thin: missing type is error
---
libdm/libdm-deptree.c | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index b844a57..1ef1700 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1394,9 +1394,9 @@ static int _thin_pool_get_status(struct dm_tree_node *dnode,
dm_get_next_target(dmt, NULL, &start, &length, &type, ¶ms);
- if (type && (strcmp(type, "thin-pool") != 0)) {
+ if (!type || (strcmp(type, "thin-pool") != 0)) {
log_error("Expected thin-pool target for %s and got %s.",
- _node_name(dnode), type);
+ _node_name(dnode), type ? : "no target");
goto out;
}
6 years, 4 months
master - thin: always clear memory before parsing status
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=2208ebfe16e5b5cd54c...
Commit: 2208ebfe16e5b5cd54c762a5a06edd0681d62fa9
Parent: 2166d7be72c7371f0f94934625252646c5164a2c
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Wed Dec 6 13:24:41 2017 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Thu Dec 7 20:59:28 2017 +0100
thin: always clear memory before parsing status
Ensure there cannot be 'reused' any data from some previous call.
---
WHATS_NEW | 1 +
libdm/libdm-deptree.c | 2 +-
libdm/libdm-targets.c | 4 +++-
3 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index a5ec3e7..4659d55 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.177 -
====================================
+ Ensure _node_send_message always uses clean status of thin pool.
Fix lvmlockd to use pool lock when accessing _tmeta volume.
Report expected sanlock_convert errors only when retries fail.
Avoid blocking in sanlock_convert on SH to EX lock conversion.
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 34a1547..b844a57 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -1493,7 +1493,7 @@ static int _node_send_messages(struct dm_tree_node *dnode,
{
struct load_segment *seg;
struct thin_message *tmsg;
- struct dm_status_thin_pool stp = { 0 };
+ struct dm_status_thin_pool stp;
const char *uuid;
int have_messages;
diff --git a/libdm/libdm-targets.c b/libdm/libdm-targets.c
index 6577f07..990d275 100644
--- a/libdm/libdm-targets.c
+++ b/libdm/libdm-targets.c
@@ -350,6 +350,8 @@ int parse_thin_pool_status(const char *params, struct dm_status_thin_pool *s)
{
int pos;
+ memset(s, 0, sizeof(*s));
+
if (!params) {
log_error("Failed to parse invalid thin params.");
return 0;
@@ -406,7 +408,7 @@ int dm_get_status_thin_pool(struct dm_pool *mem, const char *params,
{
struct dm_status_thin_pool *s;
- if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_thin_pool)))) {
+ if (!(s = dm_pool_alloc(mem, sizeof(struct dm_status_thin_pool)))) {
log_error("Failed to allocate thin_pool status structure.");
return 0;
}
6 years, 4 months