master - lvremove: validate removed component LV is not active
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=73e93ef5e5e42018c70...
Commit: 73e93ef5e5e42018c701149a51db17e247dbb9a6
Parent: ca9cbd92c40affa5ea5597de2d0ebd18382d9dab
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Mar 2 16:32:05 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:42:07 2018 +0100
lvremove: validate removed component LV is not active
This is the 'last' place where a LV is present in metadata.
Any removed device should not be left active in dm table.
So this check is an extra validation protection to capture any
forgotten deactivation (adding 1 extra ioctl into lvremove path)
---
lib/metadata/lv_manip.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 915a032..ff82b2d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -1518,6 +1518,13 @@ int lv_reduce(struct logical_volume *lv, uint32_t extents)
if (lv_is_raid(lv) && extents != lv->le_count)
extents =_round_to_stripe_boundary(lv->vg, extents,
seg_is_raid1(seg) ? 0 : _raid_stripes_count(seg), 0);
+
+ if ((extents == lv->le_count) && lv_is_component(lv) && lv_is_active(lv)) {
+ /* When LV is removed, make sure it is inactive */
+ log_error(INTERNAL_ERROR "Removing still active LV %s.", display_lvname(lv));
+ return 0;
+ }
+
return _lv_reduce(lv, extents, 1);
}
6 years, 1 month
master - activation: add base lv component function
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ca9cbd92c40affa5ea5...
Commit: ca9cbd92c40affa5ea5597de2d0ebd18382d9dab
Parent: 6481471c9d74038da457b74ef1f2b0c15931bfa8
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Feb 27 14:13:00 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:42:05 2018 +0100
activation: add base lv component function
Introduce:
lv_is_component() check is LV is actually a component device.
lv_component_is_active() checking if any component device is active.
lv_holder_is_active() is any component holding device is active.
---
WHATS_NEW | 1 +
lib/activate/activate.c | 111 +++++++++++++++++++++++++++++++++++++-
lib/activate/activate.h | 7 ++-
lib/activate/dev_manager.c | 2 +-
lib/metadata/metadata-exported.h | 11 ++++
5 files changed, 129 insertions(+), 3 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index b282caa..9656da7 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Extend internal library to recognize and work with component LV.
Skip duplicate check for active LV when prompting for its removal.
Activate correct lock holding LV when it is cached.
Do not modify archived metadata when removing striped raid.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index f5e9ef9..aa230fe 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -2860,3 +2860,112 @@ void activation_exit(void)
dev_manager_exit();
}
#endif
+
+static int _component_cb(struct logical_volume *lv, void *data)
+{
+ struct logical_volume **component_lv = (struct logical_volume **) data;
+
+ if (lv_is_locked(lv) || lv_is_pvmove(lv) ||/* ignoring */
+ /* thin-pool is special and it's using layered device */
+ (lv_is_thin_pool(lv) && pool_is_active(lv)))
+ return -1;
+
+ if (lv_is_active(lv)) {
+ if (!lv_is_component(lv) || lv_is_visible(lv))
+ return -1; /* skip whole subtree */
+
+ log_debug_activation("Found active component LV %s.", display_lvname(lv));
+ *component_lv = lv;
+ return 0; /* break any further processing */
+ }
+
+ return 1;
+}
+
+/*
+ * Finds out for any LV if any of its component LVs are active.
+ * Function first checks if an existing LV is visible and active eventually
+ * it's lock holding LV is already active. In such case sub LV cannot be
+ * actived alone and no further checking is needed.
+ *
+ * Returns active component LV if there is such.
+ */
+const struct logical_volume *lv_component_is_active(const struct logical_volume *lv)
+{
+ const struct logical_volume *component_lv = NULL;
+ const struct logical_volume *holder_lv = lv_lock_holder(lv);
+
+ if ((holder_lv != lv) && lv_is_active(holder_lv))
+ return NULL; /* Lock holding LV is active, do not check components */
+
+ if (_component_cb((struct logical_volume *) lv, &holder_lv) == 1)
+ (void) for_each_sub_lv((struct logical_volume *) lv, _component_cb,
+ (void*) &component_lv);
+
+ return component_lv;
+}
+
+/*
+ * Finds out if any LV above is active, as stacked device tree can be composed of
+ * chained set of LVs.
+ *
+ * Returns active holder LV if there is such.
+ */
+const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv)
+{
+ const struct logical_volume *holder;
+ const struct seg_list *sl;
+
+ if (lv_is_locked(lv) || lv_is_pvmove(lv))
+ return NULL; /* Skip pvmove/locked LV tracking */
+
+ dm_list_iterate_items(sl, &lv->segs_using_this_lv) {
+ /* Recursive call for upper-stack holder */
+ if ((holder = lv_holder_is_active(sl->seg->lv)))
+ return holder;
+
+ if (lv_is_active(sl->seg->lv)) {
+ log_debug_activation("Found active holder LV %s.", display_lvname(sl->seg->lv));
+ return sl->seg->lv;
+ }
+ }
+
+ return NULL;
+}
+
+static int _deactivate_sub_lv_cb(struct logical_volume *lv, void *data)
+{
+ struct logical_volume **slv = data;
+
+ if (lv_is_thin_pool(lv) || lv_is_external_origin(lv))
+ return -1;
+
+ if (!deactivate_lv(lv->vg->cmd, lv)) {
+ *slv = lv;
+ return 0;
+ }
+
+ return 1;
+}
+
+/*
+ * Deactivates LV toghether with explicit deactivation call made also for all its component LVs.
+ */
+int deactivate_lv_with_sub_lv(const struct logical_volume *lv)
+{
+ struct logical_volume *flv;
+
+ if (!deactivate_lv(lv->vg->cmd, lv)) {
+ log_error("Cannot deactivate logical volume %s.",
+ display_lvname(lv));
+ return 0;
+ }
+
+ if (!for_each_sub_lv((struct logical_volume *)lv, _deactivate_sub_lv_cb, &flv)) {
+ log_error("Cannot deactivate subvolume %s of logical volume %s.",
+ display_lvname(flv), display_lvname(lv));
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/lib/activate/activate.h b/lib/activate/activate.h
index 8d06867..dc4d3cd 100644
--- a/lib/activate/activate.h
+++ b/lib/activate/activate.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2016 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -198,6 +198,11 @@ int lv_is_active_exclusive(const struct logical_volume *lv);
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
int lv_is_active_exclusive_remotely(const struct logical_volume *lv);
+/* Check is any component LV is active */
+const struct logical_volume *lv_component_is_active(const struct logical_volume *lv);
+const struct logical_volume *lv_holder_is_active(const struct logical_volume *lv);
+int deactivate_lv_with_sub_lv(const struct logical_volume *lv);
+
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer, const char *target_type);
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 2faf1cc..8bf0e47 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2017 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 71df955..cd7ff8a 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -253,6 +253,17 @@
#define lv_is_removed(lv) (((lv)->status & LV_REMOVED) ? 1 : 0)
+/* Recognize component LV (matching lib/misc/lvm-string.c _lvname_has_reserved_component_string()) */
+#define lv_is_component(lv) (lv_is_cache_origin(lv) || ((lv)->status & (\
+ CACHE_POOL_DATA |\
+ CACHE_POOL_METADATA |\
+ MIRROR_IMAGE |\
+ MIRROR_LOG |\
+ RAID_IMAGE |\
+ RAID_META |\
+ THIN_POOL_DATA |\
+ THIN_POOL_METADATA)) ? 1 : 0)
+
int lv_layout_and_role(struct dm_pool *mem, const struct logical_volume *lv,
struct dm_list **layout, struct dm_list **role);
6 years, 1 month
master - debug: update comment
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=6481471c9d74038da45...
Commit: 6481471c9d74038da457b74ef1f2b0c15931bfa8
Parent: b6e7a0b490a3fa2e43675a4d3fb3d25daaac831e
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Mar 2 15:06:36 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:40:34 2018 +0100
debug: update comment
---
lib/metadata/lv_manip.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index d4a6107..915a032 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -4371,9 +4371,9 @@ static int _for_each_sub_lv(struct logical_volume *lv, int level,
if (level++) {
if (!(r = fn(lv, data)))
return_0;
- /* Only r == 1 lets you run for_each... */
if (r == -1)
return 1;
+ /* Only r != -1 continues with for_each_sub_lv()... */
}
if (lv_is_cow(lv) && lv_is_virtual_origin(org = origin_from_cow(lv))) {
6 years, 1 month
master - cleanup: more usage of dm_strncpy
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b6e7a0b490a3fa2e436...
Commit: b6e7a0b490a3fa2e43675a4d3fb3d25daaac831e
Parent: f04abd1f8a7eea9edf473be17ae1e2aea1a00ee6
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Mar 2 16:25:37 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:40:34 2018 +0100
cleanup: more usage of dm_strncpy
Use existing wrapper function arournd strncpy + buf[] = 0;
---
daemons/clvmd/lvm-functions.c | 3 +--
daemons/lvmetad/lvmetad-core.c | 15 ++++++---------
lib/cache/lvmcache.c | 17 ++++++-----------
lib/device/dev-cache.c | 6 ++----
lib/format_text/archive.c | 3 +--
lib/format_text/format-text.c | 6 ++----
lib/misc/lvm-globals.c | 6 ++----
lib/misc/sharedlib.c | 3 +--
tools/command.c | 3 +--
9 files changed, 22 insertions(+), 40 deletions(-)
diff --git a/daemons/clvmd/lvm-functions.c b/daemons/clvmd/lvm-functions.c
index e872fbe..c845e6d 100644
--- a/daemons/clvmd/lvm-functions.c
+++ b/daemons/clvmd/lvm-functions.c
@@ -807,8 +807,7 @@ static void lvm2_log_fn(int level, const char *file, int line, int dm_errno,
if (level != _LOG_ERR && level != _LOG_FATAL)
return;
- strncpy(last_error, message, sizeof(last_error));
- last_error[sizeof(last_error)-1] = '\0';
+ (void) dm_strncpy(last_error, message, sizeof(last_error));
}
/* This checks some basic cluster-LVM configuration stuff */
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index 04a7224..eeb3f20 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2705,9 +2705,8 @@ static response handler(daemon_state s, client_handle h, request r)
if (!prev_in_progress && this_in_progress) {
/* New update is starting (filter token is replaced by update token) */
- memcpy(prev_token, state->token, 128);
- strncpy(state->token, token, 128);
- state->token[127] = 0;
+ (void) dm_strncpy(prev_token, state->token, sizeof(prev_token));
+ (void) dm_strncpy(state->token, token, sizeof(state->token));
state->update_begin = _monotonic_seconds();
state->update_timeout = update_timeout;
state->update_pid = pid;
@@ -2728,9 +2727,8 @@ static response handler(daemon_state s, client_handle h, request r)
(int)(_monotonic_seconds() - state->update_begin),
state->update_cmd);
- memcpy(prev_token, state->token, 128);
- strncpy(state->token, token, 128);
- state->token[127] = 0;
+ (void) dm_strncpy(prev_token, state->token, sizeof(prev_token));
+ (void) dm_strncpy(state->token, token, sizeof(state->token));
state->update_begin = _monotonic_seconds();
state->update_timeout = update_timeout;
state->update_pid = pid;
@@ -2762,9 +2760,8 @@ static response handler(daemon_state s, client_handle h, request r)
(int)(_monotonic_seconds() - state->update_begin),
state->update_pid, token);
- memcpy(prev_token, state->token, 128);
- strncpy(state->token, token, 128);
- state->token[127] = 0;
+ (void) dm_strncpy(prev_token, state->token, sizeof(prev_token));
+ (void) dm_strncpy(state->token, token, sizeof(state->token));
state->update_begin = 0;
state->update_timeout = 0;
state->update_pid = 0;
diff --git a/lib/cache/lvmcache.c b/lib/cache/lvmcache.c
index 4022ea6..5ff2827 100644
--- a/lib/cache/lvmcache.c
+++ b/lib/cache/lvmcache.c
@@ -617,8 +617,7 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid)
}
/* vgid not necessarily NULL-terminated */
- strncpy(&id[0], vgid, ID_LEN);
- id[ID_LEN] = '\0';
+ (void) dm_strncpy(id, vgid, sizeof(id));
if (!(vginfo = dm_hash_lookup(_vgid_hash, id))) {
log_debug_cache("lvmcache has no info for vgid \"%s\"", id);
@@ -719,8 +718,7 @@ struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, struct device *d
if (!_pvid_hash || !pvid)
return NULL;
- strncpy(&id[0], pvid, ID_LEN);
- id[ID_LEN] = '\0';
+ (void) dm_strncpy(id, pvid, sizeof(id));
if (!(info = dm_hash_lookup(_pvid_hash, id)))
return NULL;
@@ -1646,8 +1644,7 @@ static int _lvmcache_update_vgid(struct lvmcache_info *info,
return 1;
}
- strncpy(vginfo->vgid, vgid, ID_LEN);
- vginfo->vgid[ID_LEN] = '\0';
+ (void) dm_strncpy(vginfo->vgid, vgid, sizeof(vginfo->vgid));
if (!dm_hash_insert(_vgid_hash, vginfo->vgid, vginfo)) {
log_error("_lvmcache_update: vgid hash insertion failed: %s",
vginfo->vgid);
@@ -2055,10 +2052,8 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
.lock_type = vg->lock_type
};
- pvid_s[sizeof(pvid_s) - 1] = '\0';
-
dm_list_iterate_items(pvl, &vg->pvs) {
- strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
+ (void) dm_strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s));
/* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = lvmcache_info_from_pvid(pvid_s, pvl->pv->dev, 0)) &&
!lvmcache_update_vgname_and_id(info, &vgsummary))
@@ -2162,8 +2157,8 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller,
struct device_list *devl;
int created = 0;
- strncpy(pvid_s, pvid, sizeof(pvid_s) - 1);
- pvid_s[sizeof(pvid_s) - 1] = '\0';
+ (void) dm_strncpy(pvid_s, pvid, sizeof(pvid_s));
+
if (!id_write_format((const struct id *)&pvid_s, uuid, sizeof(uuid)))
stack;
diff --git a/lib/device/dev-cache.c b/lib/device/dev-cache.c
index 2f74c81..711c2d8 100644
--- a/lib/device/dev-cache.c
+++ b/lib/device/dev-cache.c
@@ -275,10 +275,8 @@ static int _compare_paths(const char *path0, const char *path1)
if (slash1 < slash0)
return 1;
- strncpy(p0, path0, sizeof(p0) - 1);
- p0[sizeof(p0) - 1] = '\0';
- strncpy(p1, path1, sizeof(p1) - 1);
- p1[sizeof(p1) - 1] = '\0';
+ (void) dm_strncpy(p0, path0, sizeof(p0));
+ (void) dm_strncpy(p1, path1, sizeof(p1));
s0 = p0 + 1;
s1 = p1 + 1;
diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c
index a81a83b..2186de8 100644
--- a/lib/format_text/archive.c
+++ b/lib/format_text/archive.c
@@ -80,8 +80,7 @@ static int _split_vg(const char *filename, char *vgname, size_t vgsize,
if (vg_len + 1 > vgsize)
return 0;
- strncpy(vgname, filename, vg_len);
- vgname[vg_len] = '\0';
+ (void) dm_strncpy(vgname, filename, vg_len + 1);
return 1;
}
diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c
index e1603e7..2e7e2b8 100644
--- a/lib/format_text/format-text.c
+++ b/lib/format_text/format-text.c
@@ -1143,10 +1143,8 @@ static int _vg_write_file(struct format_instance *fid __attribute__((unused)),
if (slash == 0)
strcpy(temp_dir, ".");
else if (slash - tc->path_edit < PATH_MAX) {
- strncpy(temp_dir, tc->path_edit,
- (size_t) (slash - tc->path_edit));
- temp_dir[slash - tc->path_edit] = '\0';
-
+ (void) dm_strncpy(temp_dir, tc->path_edit,
+ (size_t) (slash - tc->path_edit + 1));
} else {
log_error("Text format failed to determine directory.");
return 0;
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index 9c78f3e..be33091 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -205,8 +205,7 @@ void init_detect_internal_vg_cache_corruption(int detect)
void set_cmd_name(const char *cmd)
{
- strncpy(_cmd_name, cmd, sizeof(_cmd_name) - 1);
- _cmd_name[sizeof(_cmd_name) - 1] = '\0';
+ (void) dm_strncpy(_cmd_name, cmd, sizeof(_cmd_name));
}
const char *get_cmd_name(void)
@@ -216,8 +215,7 @@ const char *get_cmd_name(void)
void set_sysfs_dir_path(const char *path)
{
- strncpy(_sysfs_dir_path, path, sizeof(_sysfs_dir_path) - 1);
- _sysfs_dir_path[sizeof(_sysfs_dir_path) - 1] = '\0';
+ (void) dm_strncpy(_sysfs_dir_path, path, sizeof(_sysfs_dir_path));
}
const char *log_command_name(void)
diff --git a/lib/misc/sharedlib.c b/lib/misc/sharedlib.c
index db1ba43..2532f79 100644
--- a/lib/misc/sharedlib.c
+++ b/lib/misc/sharedlib.c
@@ -37,8 +37,7 @@ void get_shared_library_path(struct cmd_context *cmd, const char *libname,
!(cmd->lib_dir = find_config_tree_str(cmd, global_library_dir_CFG, NULL))) ||
(dm_snprintf(path, path_len, "%s/%s", cmd->lib_dir,
libname) == -1) || stat(path, &info) == -1) {
- strncpy(path, libname, path_len - 1);
- path[path_len - 1] = '\0';
+ (void) dm_strncpy(path, libname, path_len);
}
}
diff --git a/tools/command.c b/tools/command.c
index f974474..10efedb 100644
--- a/tools/command.c
+++ b/tools/command.c
@@ -492,8 +492,7 @@ static uint64_t _lv_to_bits(struct command *cmd, char *name)
int argc;
int i;
- memset(buf, 0, sizeof(buf));
- strncpy(buf, name, LVTYPE_LEN-1);
+ (void) dm_strncpy(buf, name, LVTYPE_LEN);
_split_line(buf, &argc, argv, '_');
6 years, 1 month
master - lvremove: drop duplicate check for active LV
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=f04abd1f8a7eea9edf4...
Commit: f04abd1f8a7eea9edf473be17ae1e2aea1a00ee6
Parent: 23de09aeb87ec10bd1a553ea8868e2f946117232
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Mar 6 13:31:06 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:40:31 2018 +0100
lvremove: drop duplicate check for active LV
Since this code branch already tested LV is active,
avoid repeating same query.
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 3 +--
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 3ed3e5a..b282caa 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Skip duplicate check for active LV when prompting for its removal.
Activate correct lock holding LV when it is cached.
Do not modify archived metadata when removing striped raid.
Fix memleak on error path when obtaining lv_raid_data_offset.
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 88b0d9d..d4a6107 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6040,8 +6040,7 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
if ((force == PROMPT) &&
!lv_is_pending_delete(lv) &&
- lv_is_visible(lv) &&
- lv_is_active(lv)) {
+ lv_is_visible(lv)) {
if (yes_no_prompt("Do you really want to remove%s active "
"%slogical volume %s? [y/n]: ",
ask_discard ? " and DISCARD" : "",
6 years, 1 month
master - lvcreate: fix activation of cached LV
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=23de09aeb87ec10bd1a...
Commit: 23de09aeb87ec10bd1a553ea8868e2f946117232
Parent: b2f1254c14b7b86789e542be14041252a652eec2
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Mar 5 12:54:39 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:39:27 2018 +0100
lvcreate: fix activation of cached LV
Since LV for caching can be already a stacked LV, proper activation
needs to use lock holding LV.
---
WHATS_NEW | 1 +
tools/lvcreate.c | 2 ++
2 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 49b995e..3ed3e5a 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Activate correct lock holding LV when it is cached.
Do not modify archived metadata when removing striped raid.
Fix memleak on error path when obtaining lv_raid_data_offset.
Fix compatibility size test of extended external origin.
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index 7f86a37..e901968 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -1222,6 +1222,8 @@ static int _determine_cache_argument(struct volume_group *vg,
return_0; /* FIXME */
/* Put origin into resulting activation state first */
+ lv = (struct logical_volume *)lv_lock_holder(lv);
+
if (is_change_activating(lp->activate)) {
if ((lp->activate == CHANGE_AAY) &&
!lv_passes_auto_activation_filter(cmd, lv)) {
6 years, 1 month
master - raid: move VG update after archiving happened
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=b2f1254c14b7b86789e...
Commit: b2f1254c14b7b86789e542be14041252a652eec2
Parent: ce199db848e663ffa040015106725553eafb1c98
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Tue Mar 6 13:38:00 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:38:15 2018 +0100
raid: move VG update after archiving happened
Update of LV le_count needs to happen after archive().
---
WHATS_NEW | 1 +
lib/metadata/lv_manip.c | 14 +++++++-------
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 52cf4bc..49b995e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Do not modify archived metadata when removing striped raid.
Fix memleak on error path when obtaining lv_raid_data_offset.
Fix compatibility size test of extended external origin.
Add external_origin visiting in for_each_sub_lv().
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 044214c..88b0d9d 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -6077,13 +6077,6 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
is_last_pool = 1;
}
- /* Special case removing a striped raid LV with allocated reshape space */
- if (seg && seg->reshape_len) {
- if (!(seg->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED)))
- return_0;
- lv->le_count = seg->len = seg->area_len = seg_lv(seg, 0)->le_count * seg->area_count;
- }
-
/* Used cache pool, COW or historical LV cannot be activated */
if (!lv_is_used_cache_pool(lv) &&
!lv_is_cow(lv) && !lv_is_historical(lv) &&
@@ -6097,6 +6090,13 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!archive(vg))
return 0;
+ /* Special case removing a striped raid LV with allocated reshape space */
+ if (seg && seg->reshape_len) {
+ if (!(seg->segtype = get_segtype_from_string(cmd, SEG_TYPE_NAME_STRIPED)))
+ return_0;
+ lv->le_count = seg->len = seg->area_len = seg_lv(seg, 0)->le_count * seg->area_count;
+ }
+
/* Clear thin pool stacked messages */
if (pool_lv && !pool_has_message(first_seg(pool_lv), lv, 0) &&
!update_pool_lv(pool_lv, 1)) {
6 years, 1 month
master - raid: fix error path for lv_raid_data_offset
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=ce199db848e663ffa04...
Commit: ce199db848e663ffa040015106725553eafb1c98
Parent: 9be086fbeef0a24fc6f441dec29ee2385bca0280
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Fri Mar 2 15:49:12 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:36:11 2018 +0100
raid: fix error path for lv_raid_data_offset
Avoid using allocated status on error path.
---
WHATS_NEW | 1 +
lib/activate/activate.c | 6 ++++--
2 files changed, 5 insertions(+), 2 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 46f66b0..52cf4bc 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.178 -
=====================================
+ Fix memleak on error path when obtaining lv_raid_data_offset.
Fix compatibility size test of extended external origin.
Add external_origin visiting in for_each_sub_lv().
Ensure cluster commands drop their device cache before locking VG.
diff --git a/lib/activate/activate.c b/lib/activate/activate.c
index 3052f31..f5e9ef9 100644
--- a/lib/activate/activate.c
+++ b/lib/activate/activate.c
@@ -1006,8 +1006,10 @@ int lv_raid_data_offset(const struct logical_volume *lv, uint64_t *data_offset)
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
return_0;
- if (!(r = dev_manager_raid_status(dm, lv, &status)))
- stack;
+ if (!(r = dev_manager_raid_status(dm, lv, &status))) {
+ dev_manager_destroy(dm);
+ return_0;
+ }
*data_offset = status->data_offset;
6 years, 1 month
master - thin: pass environment to scripts
by Zdenek Kabelac
Gitweb: https://sourceware.org/git/?p=lvm2.git;a=commitdiff;h=9be086fbeef0a24fc6f...
Commit: 9be086fbeef0a24fc6f441dec29ee2385bca0280
Parent: 406d6de651fd1ae3bda80f3597d7aa8733b0389a
Author: Zdenek Kabelac <zkabelac(a)redhat.com>
AuthorDate: Mon Mar 5 15:09:16 2018 +0100
Committer: Zdenek Kabelac <zkabelac(a)redhat.com>
CommitterDate: Tue Mar 6 15:35:04 2018 +0100
thin: pass environment to scripts
When dmeventd thin plugin forks a configurable script, switch to use
execvp to pass whole environment present to dmeventd - so all configured
paths present at dmeventd startup are visible to script.
This was likely not a problem for common user enviroment,
however in test suite case variable like LVM_SYSTEM_DIR were
not actually used from test itself but rather from
a system present lvm.conf and this may have cause strange
behavior of a testing script.
---
WHATS_NEW_DM | 1 +
daemons/dmeventd/plugins/thin/dmeventd_thin.c | 18 +++++++++---------
2 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM
index 52593c5..5c1f4a1 100644
--- a/WHATS_NEW_DM
+++ b/WHATS_NEW_DM
@@ -1,5 +1,6 @@
Version 1.02.147 -
=====================================
+ Configured command for thin pool threshold handling gets whole environment.
Fix tests for failing dm_snprintf() in stats code.
Parsing mirror status accepts 'userspace' keyword in status.
Introduce dm_malloc_aligned for page alignment of buffers.
diff --git a/daemons/dmeventd/plugins/thin/dmeventd_thin.c b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
index 404519b..29b0391 100644
--- a/daemons/dmeventd/plugins/thin/dmeventd_thin.c
+++ b/daemons/dmeventd/plugins/thin/dmeventd_thin.c
@@ -64,23 +64,23 @@ DM_EVENT_LOG_FN("thin")
static int _run_command(struct dso_state *state)
{
- char val[3][36];
- char *env[] = { val[0], val[1], val[2], NULL };
+ char val[16];
int i;
/* Mark for possible lvm2 command we are running from dmeventd
* lvm2 will not try to talk back to dmeventd while processing it */
- (void) dm_snprintf(val[0], sizeof(val[0]), "LVM_RUN_BY_DMEVENTD=1");
+ (void) setenv("LVM_RUN_BY_DMEVENTD", "1", 1);
if (state->data_percent) {
/* Prepare some known data to env vars for easy use */
- (void) dm_snprintf(val[1], sizeof(val[1]), "DMEVENTD_THIN_POOL_DATA=%d",
- state->data_percent / DM_PERCENT_1);
- (void) dm_snprintf(val[2], sizeof(val[2]), "DMEVENTD_THIN_POOL_METADATA=%d",
- state->metadata_percent / DM_PERCENT_1);
+ if (dm_snprintf(val, sizeof(val), "%d",
+ state->data_percent / DM_PERCENT_1) != -1)
+ (void) setenv("DMEVENTD_THIN_POOL_DATA", val, 1);
+ if (dm_snprintf(val, sizeof(val), "%d",
+ state->metadata_percent / DM_PERCENT_1) != -1)
+ (void) setenv("DMEVENTD_THIN_POOL_METADATA", val, 1);
} else {
/* For an error event it's for a user to check status and decide */
- env[1] = NULL;
log_debug("Error event processing.");
}
@@ -95,7 +95,7 @@ static int _run_command(struct dso_state *state)
/* child */
(void) close(0);
for (i = 3; i < 255; ++i) (void) close(i);
- execve(state->argv[0], state->argv, env);
+ execvp(state->argv[0], state->argv);
_exit(errno);
} else if (state->pid == -1) {
log_error("Can't fork command %s.", state->cmd_str);
6 years, 1 month