master - lvmetad: two phase vg_update
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=886da20c4dce3f...
Commit: 886da20c4dce3f3ab5c9fdc22580a98b49c6e269
Parent: e6c376ee2dae4539b1cc38ed6d9c5430777d2753
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Wed Jun 8 14:42:03 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:22:21 2016 -0500
lvmetad: two phase vg_update
Previously, a command sent lvmetad new VG metadata in vg_commit().
In vg_commit(), devices are suspended, so any memory allocation
done by the command while sending to lvmetad, or by lvmetad while
updating its cache could deadlock if memory reclaim was triggered.
Now lvmetad is updated in unlock_vg(), after devices are resumed.
The new method for updating VG metadata in lvmetad is in two phases:
1. In vg_write(), before devices are suspended, the command sends
lvmetad a short message ("set_vg_info") telling it what the new
VG seqno will be. lvmetad sees that the seqno is newer than
the seqno of its cached VG, so it sets the INVALID flag for the
cached VG. If sending the message to lvmetad fails, the command
fails before the metadata is committed and the change is not made.
If sending the message succeeds, vg_commit() is called.
2. In unlock_vg(), after devices are resumed, the command sends
lvmetad the standard vg_update message with the new metadata.
lvmetad sees that the seqno in the new metadata matches the
seqno it saved from set_vg_info, and knows it has the latest
copy, so it clears the INVALID flag for the cached VG.
If a command fails between 1 and 2 (after committing the VG on disk,
but before sending lvmetad the new metadata), the cached VG retains
the INVALID flag in lvmetad. A subsequent command will read the
cached VG from lvmetad, see the INVALID flag, ignore the cached
copy, read the VG from disk instead, update the lvmetad copy
with the latest copy from disk, (this clears the INVALID flag
in lvmetad), and use the correct VG metadata for the command.
(This INVALID mechanism already existed for use by lvmlockd.)
---
daemons/lvmetad/lvmetad-core.c | 9 ++-
lib/cache/lvmetad.c | 113 ++++++++++++++++++++++++++++++++-------
lib/cache/lvmetad.h | 5 ++-
lib/format_text/archiver.c | 1 +
lib/locking/locking.h | 6 ++-
lib/metadata/metadata.c | 37 +++++++++----
lib/metadata/pv_manip.c | 2 +-
lib/metadata/replicator_manip.c | 1 +
lib/metadata/vg.c | 1 +
lib/metadata/vg.h | 1 +
liblvm/lvm_pv.c | 5 +-
liblvm/lvm_vg.c | 7 ++-
tools/pvchange.c | 2 +-
tools/pvcreate.c | 2 +-
tools/pvdisplay.c | 2 +-
tools/pvremove.c | 2 +-
tools/pvscan.c | 4 +-
tools/reporter.c | 2 +-
tools/toollib.c | 10 ++--
tools/vgcfgrestore.c | 10 ++--
tools/vgcreate.c | 10 ++--
tools/vgextend.c | 2 +-
tools/vgimportclone.c | 4 +-
tools/vgrename.c | 6 +-
tools/vgscan.c | 2 +-
tools/vgsplit.c | 6 ++
26 files changed, 181 insertions(+), 71 deletions(-)
diff --git a/daemons/lvmetad/lvmetad-core.c b/daemons/lvmetad/lvmetad-core.c
index aab569f..1ec9e3b 100644
--- a/daemons/lvmetad/lvmetad-core.c
+++ b/daemons/lvmetad/lvmetad-core.c
@@ -2464,10 +2464,10 @@ static response set_vg_info(lvmetad_state *s, request r)
{
struct dm_config_tree *vg;
struct vg_info *info;
- const char *name;
- const char *uuid;
+ const char *name = NULL;
+ const char *uuid = NULL;
const int64_t new_version = daemon_request_int(r, "version", -1);
- int64_t cache_version;
+ int64_t cache_version = -1;
if (new_version == -1)
goto out;
@@ -2500,6 +2500,9 @@ vers:
if (cache_version != -1 && new_version != -1 && cache_version >= new_version)
goto out;
inval:
+ DEBUGLOG(s, "set info VG name %s uuid %s cache_version %d new_version %d",
+ name ?: "none", uuid ?: "none", (int)cache_version, (int)new_version);
+
info = dm_hash_lookup(s->vgid_to_info, uuid);
if (!info) {
info = malloc(sizeof(struct vg_info));
diff --git a/lib/cache/lvmetad.c b/lib/cache/lvmetad.c
index a0a17ac..784a529 100644
--- a/lib/cache/lvmetad.c
+++ b/lib/cache/lvmetad.c
@@ -644,10 +644,11 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *id, const char
action = "clear info about all PVs";
else if (!strcmp(id, "vg_clear_outdated_pvs"))
action = "clear the list of outdated PVs";
- else if (!strcmp(id, "vg_update")) {
+ else if (!strcmp(id, "set_vg_info"))
+ action = "set VG info";
+ else if (!strcmp(id, "vg_update"))
action = "update VG";
- action_modifies = 1;
- } else if (!strcmp(id, "vg_remove")) {
+ else if (!strcmp(id, "vg_remove")) {
action = "remove VG";
action_modifies = 1;
} else if (!strcmp(id, "pv_found")) {
@@ -1073,7 +1074,13 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
log_debug_lvmetad("Rescan VG %s because no lvmlockd lock is held", vgname);
rescan = 1;
} else if (dm_config_find_node(reply.cft->root, "vg_invalid")) {
- log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ if (!is_lockd_type(vg->lock_type)) {
+ /* Can happen if a previous command failed/crashed without updating lvmetad. */
+ log_warn("WARNING: Reading VG %s from disk because lvmetad metadata is invalid.", vgname);
+ } else {
+ /* This is normal when the VG was modified by another host. */
+ log_debug_lvmetad("Rescan VG %s because lvmetad returned invalid", vgname);
+ }
rescan = 1;
}
@@ -1137,32 +1144,98 @@ static int _fixup_ignored(struct metadata_area *mda, void *baton) {
return 1;
}
-int lvmetad_vg_update(struct volume_group *vg)
+/*
+ * After the VG is written to disk, but before it's committed,
+ * lvmetad is told the new seqno. lvmetad sets the INVALID
+ * flag on the cached VG and saves the new seqno.
+ *
+ * After the VG is committed on disk, the command sends the
+ * new VG metadata, containing the new seqno. lvmetad sees
+ * that it has the updated metadata and clears the INVALID
+ * flag on the cached VG.
+ *
+ * If the command fails after committing the metadata on disk
+ * but before sending the new metadata to lvmetad, then the
+ * next command that asks lvmetad for the metadata will get
+ * back the INVALID flag. That command will then read the
+ * VG metadata from disk to use, and will send the latest
+ * metadata from disk to lvmetad which will clear the
+ * INVALID flag.
+ */
+
+int lvmetad_vg_update_pending(struct volume_group *vg)
{
+ char uuid[64] __attribute__((aligned(8)));
+ daemon_reply reply;
+
+ if (!lvmetad_used() || test_mode())
+ return 1; /* fake it */
+
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ log_debug_lvmetad("Sending lvmetad pending VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
+ reply = _lvmetad_send(vg->cmd, "set_vg_info",
+ "name = %s", vg->name,
+ "uuid = %s", uuid,
+ "version = %"PRId64, (int64_t)vg->seqno,
+ NULL);
+
+ if (!_lvmetad_handle_reply(reply, "set_vg_info", vg->name, NULL)) {
+ daemon_reply_destroy(reply);
+ return_0;
+ }
+
+ vg->lvmetad_update_pending = 1;
+
+ daemon_reply_destroy(reply);
+ return 1;
+}
+
+int lvmetad_vg_update_finish(struct volume_group *vg)
+{
+ char uuid[64] __attribute__((aligned(8)));
daemon_reply reply;
struct dm_hash_node *n;
struct metadata_area *mda;
char mda_id[128], *num;
+ struct dm_config_tree *vgmeta;
struct pv_list *pvl;
struct lvmcache_info *info;
struct _fixup_baton baton;
- if (!vg)
- return 0;
+ if (!vg->lvmetad_update_pending)
+ return 1;
+
+ if (!(vg->fid->fmt->features & FMT_PRECOMMIT))
+ return 1;
if (!lvmetad_used() || test_mode())
return 1; /* fake it */
- if (!vg->cft_precommitted) {
- log_error(INTERNAL_ERROR "VG update without precommited");
+ if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
+ return_0;
+
+ if (!(vgmeta = export_vg_to_config_tree(vg))) {
+ log_error("Failed to export VG to config tree.");
return 0;
}
- log_debug_lvmetad("Sending lvmetad updated metadata for VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
- reply = _lvmetad_send(vg->cmd, "vg_update", "vgname = %s", vg->name,
- "metadata = %t", vg->cft_precommitted, NULL);
+ log_debug_lvmetad("Sending lvmetad updated VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
+ reply = _lvmetad_send(vg->cmd, "vg_update",
+ "vgname = %s", vg->name,
+ "metadata = %t", vgmeta,
+ NULL);
+
+ dm_config_destroy(vgmeta);
if (!_lvmetad_handle_reply(reply, "vg_update", vg->name, NULL)) {
+ /*
+ * In this failure case, the VG cached in lvmetad remains in
+ * the INVALID state (from lvmetad_vg_update_pending).
+ * A subsequent command will see INVALID, ignore the cached
+ * copy, read the VG from disk, and update the cached copy.
+ */
daemon_reply_destroy(reply);
return 0;
}
@@ -1195,6 +1268,7 @@ int lvmetad_vg_update(struct volume_group *vg)
return 0;
}
+ vg->lvmetad_update_pending = 0;
return 1;
}
@@ -1207,6 +1281,8 @@ int lvmetad_vg_remove(struct volume_group *vg)
if (!lvmetad_used() || test_mode())
return 1; /* just fake it */
+ vg->lvmetad_update_pending = 0;
+
if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
return_0;
@@ -1887,10 +1963,6 @@ scan_more:
/*
* Update lvmetad with the newly read version of the VG.
- * The "precommitted" name is a misnomer in this case,
- * but that is the field which lvmetad_vg_update() uses
- * to send the metadata cft to lvmetad.
- *
* When the seqno is unchanged the cached VG can be left.
*/
if (save_seqno != vg->seqno) {
@@ -1905,10 +1977,13 @@ scan_more:
log_debug_lvmetad("Rescan VG %s updating lvmetad from seqno %u to seqno %u.",
vg->name, vg->seqno, save_seqno);
- vg_ret->cft_precommitted = vgmeta_ret;
- if (!lvmetad_vg_update(vg_ret))
+ /*
+ * If this vg_update fails the cached metadata in
+ * lvmetad will remain invalid.
+ */
+ vg_ret->lvmetad_update_pending = 1;
+ if (!lvmetad_vg_update_finish(vg_ret))
log_error("Failed to update lvmetad with new VG meta");
- vg_ret->cft_precommitted = NULL;
}
dm_config_destroy(vgmeta_ret);
}
diff --git a/lib/cache/lvmetad.h b/lib/cache/lvmetad.h
index 3bb2b7c..9ee4e2d 100644
--- a/lib/cache/lvmetad.h
+++ b/lib/cache/lvmetad.h
@@ -78,7 +78,8 @@ void lvmetad_release_token(void);
* lvmetad_vg_commit. The request is validated immediately and lvmetad_vg_commit
* only constitutes a pointer update.
*/
-int lvmetad_vg_update(struct volume_group *vg);
+int lvmetad_vg_update_pending(struct volume_group *vg);
+int lvmetad_vg_update_finish(struct volume_group *vg);
/*
* Inform lvmetad that a VG has been removed. This is not entirely safe, but is
@@ -171,6 +172,8 @@ void lvmetad_clear_disabled(struct cmd_context *cmd);
# define lvmetad_set_token(a) do { } while (0)
# define lvmetad_release_token() do { } while (0)
# define lvmetad_vg_update(vg) (1)
+# define lvmetad_vg_update_pending(vg) (1)
+# define lvmetad_vg_update_finish(vg) (1)
# define lvmetad_vg_remove(vg) (1)
# define lvmetad_pv_found(cmd, pvid, dev, fmt, label_sector, vg, found_vgnames, changed_vgnames) (1)
# define lvmetad_pv_gone(devno, pv_name) (1)
diff --git a/lib/format_text/archiver.c b/lib/format_text/archiver.c
index 92799e4..2acd8f5 100644
--- a/lib/format_text/archiver.c
+++ b/lib/format_text/archiver.c
@@ -22,6 +22,7 @@
#include "memlock.h"
#include "toolcontext.h"
#include "locking.h"
+#include "lvmetad-client.h"
#include <unistd.h>
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index ceeb73c..18bce2d 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -198,8 +198,10 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
rr; \
})
-#define unlock_vg(cmd, vol) \
+#define unlock_vg(cmd, vg, vol) \
do { \
+ if (vg && !lvmetad_vg_update_finish(vg)) \
+ stack; \
if (is_real_vg(vol) && !sync_dev_names(cmd)) \
stack; \
if (!lock_vol(cmd, vol, LCK_VG_UNLOCK, NULL)) \
@@ -207,7 +209,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
} while (0)
#define unlock_and_release_vg(cmd, vg, vol) \
do { \
- unlock_vg(cmd, vol); \
+ unlock_vg(cmd, vg, vol); \
release_vg(vg); \
} while (0)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index e55463b..e100bc6 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -629,7 +629,7 @@ int vg_remove(struct volume_group *vg)
ret = vg_remove_direct(vg);
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, vg, VG_ORPHANS);
return ret;
}
@@ -3548,6 +3548,17 @@ int vg_write(struct volume_group *vg)
lockd_vg_update(vg);
+ /*
+ * This tells lvmetad the new seqno it should expect to receive
+ * the metadata for after the commit. The cached VG will be
+ * invalid in lvmetad until this command sends the new metadata
+ * after it's committed.
+ */
+ if (!lvmetad_vg_update_pending(vg)) {
+ log_error("Failed to prepare new VG metadata in lvmetad cache.");
+ return 0;
+ }
+
return 1;
}
@@ -3598,10 +3609,6 @@ int vg_commit(struct volume_group *vg)
return cache_updated;
}
- /* Skip if we already did this in vg_write */
- if ((vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
- return_0;
-
cache_updated = _vg_commit_mdas(vg);
set_vg_notify(vg->cmd);
@@ -3641,6 +3648,14 @@ void vg_revert(struct volume_group *vg)
struct metadata_area *mda;
struct lv_list *lvl;
+ /*
+ * This will leave the cached copy in lvmetad INVALID (from
+ * lvmetad_vg_update_pending) and means the VG will be reread from disk
+ * to update the lvmetad copy, which is what we want to ensure that the
+ * cached copy is correct.
+ */
+ vg->lvmetad_update_pending = 0;
+
dm_list_iterate_items(lvl, &vg->lvs) {
if (lvl->lv->new_lock_args) {
lockd_free_lv(vg->cmd, vg, lvl->lv->name, &lvl->lv->lvid.id[1], lvl->lv->lock_args);
@@ -5465,7 +5480,7 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
int consistent = 1;
struct volume_group *vg;
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
dev_close_all();
@@ -5473,13 +5488,13 @@ static struct volume_group *_recover_vg(struct cmd_context *cmd,
return_NULL;
if (!(vg = vg_read_internal(cmd, vg_name, vgid, WARN_PV_READ, &consistent))) {
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return_NULL;
}
if (!consistent) {
release_vg(vg);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return_NULL;
}
@@ -5825,7 +5840,7 @@ static struct volume_group *_vg_lock_and_read(struct cmd_context *cmd, const cha
bad:
if (!already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
bad_no_unlock:
return _vg_make_handle(cmd, vg, failure);
@@ -5926,7 +5941,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
* FIXME: Disallow calling this function if
* critical_section() is true.
*/
- unlock_vg(cmd, vgname);
+ unlock_vg(cmd, NULL, vgname);
return FAILED_LOCKING;
}
lvmcache_force_next_label_scan();
@@ -5939,7 +5954,7 @@ uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname)
}
/* Found vgname so cannot reserve. */
- unlock_vg(cmd, vgname);
+ unlock_vg(cmd, NULL, vgname);
return FAILED_EXIST;
}
diff --git a/lib/metadata/pv_manip.c b/lib/metadata/pv_manip.c
index 567cede..5689a11 100644
--- a/lib/metadata/pv_manip.c
+++ b/lib/metadata/pv_manip.c
@@ -854,7 +854,7 @@ int pvremove_many(struct cmd_context *cmd, struct dm_list *pv_names,
}
out:
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
if (pvslist)
dm_list_iterate_items(pvl, pvslist)
diff --git a/lib/metadata/replicator_manip.c b/lib/metadata/replicator_manip.c
index 5197b63..0501713 100644
--- a/lib/metadata/replicator_manip.c
+++ b/lib/metadata/replicator_manip.c
@@ -17,6 +17,7 @@
#include "metadata.h"
#include "segtype.h"
#include "toolcontext.h"
+#include "lvmetad.h"
/* Add lv as replicator_dev device */
int replicator_dev_add_rimage(struct replicator_device *rdev,
diff --git a/lib/metadata/vg.c b/lib/metadata/vg.c
index 7ac1a2c..01dcad9 100644
--- a/lib/metadata/vg.c
+++ b/lib/metadata/vg.c
@@ -20,6 +20,7 @@
#include "toolcontext.h"
#include "lvmcache.h"
#include "archiver.h"
+#include "lvmetad.h"
struct volume_group *alloc_vg(const char *pool_name, struct cmd_context *cmd,
const char *vg_name)
diff --git a/lib/metadata/vg.h b/lib/metadata/vg.h
index 069cdc8..4ce7151 100644
--- a/lib/metadata/vg.h
+++ b/lib/metadata/vg.h
@@ -51,6 +51,7 @@ struct volume_group {
uint32_t cmd_missing_vgs;/* Flag marks missing VG */
uint32_t seqno; /* Metadata sequence number */
unsigned skip_validate_lock_args : 1;
+ unsigned lvmetad_update_pending: 1;
/*
* The parsed committed (on-disk) copy of this VG; is NULL if this VG is committed
diff --git a/liblvm/lvm_pv.c b/liblvm/lvm_pv.c
index 4c40b8b..3dd8433 100644
--- a/liblvm/lvm_pv.c
+++ b/liblvm/lvm_pv.c
@@ -22,6 +22,7 @@
#include "locking.h"
#include "toolcontext.h"
#include "lvm_misc.h"
+#include "lvmetad.h"
struct lvm_pv_create_params
{
@@ -205,7 +206,7 @@ int lvm_list_pvs_free(struct dm_list *pvlist)
dm_list_iterate_items(pvl, &to_delete->pvslist)
free_pv_fid(pvl->pv);
- unlock_vg(to_delete->cmd, VG_GLOBAL);
+ unlock_vg(to_delete->cmd, NULL, VG_GLOBAL);
to_delete->magic = 0xA5A5A5A5;
restore_user_env(&e);
@@ -437,7 +438,7 @@ static int _pv_create(pv_create_params_t params)
if (!(pvcreate_vol(cmd, params->pv_name, ¶ms->pv_p, 1)))
rc = -1;
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return rc;
}
diff --git a/liblvm/lvm_vg.c b/liblvm/lvm_vg.c
index 8b3fc91..8f83230 100644
--- a/liblvm/lvm_vg.c
+++ b/liblvm/lvm_vg.c
@@ -22,6 +22,7 @@
#include "lvm_misc.h"
#include "lvm2app.h"
#include "display.h"
+#include "lvmetad.h"
int lvm_vg_add_tag(vg_t vg, const char *tag)
{
@@ -84,14 +85,14 @@ static int _lvm_vg_extend(vg_t vg, const char *device)
pvcreate_params_set_defaults(&pp);
if (!vg_extend(vg, 1, &device, &pp)) {
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
return -1;
}
/*
* FIXME: Either commit to disk, or keep holding VG_ORPHANS and
* release in lvm_vg_close().
*/
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
return 0;
}
@@ -165,7 +166,7 @@ static int _lvm_vg_write(vg_t vg)
/* FIXME: do pvremove / label_remove()? */
}
dm_list_init(&vg->removed_pvs);
- unlock_vg(vg->cmd, VG_ORPHANS);
+ unlock_vg(vg->cmd, NULL, VG_ORPHANS);
}
return 0;
diff --git a/tools/pvchange.c b/tools/pvchange.c
index e68e181..8c19268 100644
--- a/tools/pvchange.c
+++ b/tools/pvchange.c
@@ -255,7 +255,7 @@ int pvchange(struct cmd_context *cmd, int argc, char **argv)
ret = process_each_pv(cmd, argc, argv, NULL, 0, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, handle, _pvchange_single);
if (!argc)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
log_print_unless_silent("%d physical volume%s changed / %d physical volume%s not changed",
params.done, params.done == 1 ? "" : "s",
diff --git a/tools/pvcreate.c b/tools/pvcreate.c
index fe6611f..e69eed4 100644
--- a/tools/pvcreate.c
+++ b/tools/pvcreate.c
@@ -156,7 +156,7 @@ int pvcreate(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_FAILED;
else {
/* pvcreate_each_device returns with orphans locked */
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
ret = ECMD_PROCESSED;
}
diff --git a/tools/pvdisplay.c b/tools/pvdisplay.c
index 404e02b..5f033f3 100644
--- a/tools/pvdisplay.c
+++ b/tools/pvdisplay.c
@@ -112,7 +112,7 @@ int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
NULL, _pvdisplay_single);
if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return ret;
}
diff --git a/tools/pvremove.c b/tools/pvremove.c
index e262eb0..28c7b83 100644
--- a/tools/pvremove.c
+++ b/tools/pvremove.c
@@ -58,7 +58,7 @@ int pvremove(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_FAILED;
else {
/* pvcreate_each_device returns with orphans locked */
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
ret = ECMD_PROCESSED;
}
diff --git a/tools/pvscan.c b/tools/pvscan.c
index c29401c..f5367e4 100644
--- a/tools/pvscan.c
+++ b/tools/pvscan.c
@@ -536,7 +536,7 @@ out:
if (!sync_local_dev_names(cmd))
stack;
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return ret;
}
@@ -654,7 +654,7 @@ int pvscan(struct cmd_context *cmd, int argc, char **argv)
params.new_pvs_found, display_size(cmd, params.size_new));
out:
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
destroy_processing_handle(cmd, handle);
return ret;
diff --git a/tools/reporter.c b/tools/reporter.c
index 6f8ed8f..ad0a356 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -1171,7 +1171,7 @@ static int _do_report(struct cmd_context *cmd, struct processing_handle *handle,
dm_report_output(report_handle);
if (lock_global)
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
out:
if (report_handle) {
if (report_in_group && !dm_report_group_pop(handle->report_group))
diff --git a/tools/toollib.c b/tools/toollib.c
index 4c24b16..35b687b 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1962,7 +1962,7 @@ static int _process_vgnameid_list(struct cmd_context *cmd, uint32_t read_flags,
}
if (!vg_read_error(vg) && !already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -2826,7 +2826,7 @@ static int _process_lv_vgnameid_list(struct cmd_context *cmd, uint32_t read_flag
ret_max = ret;
if (!already_locked)
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, vg, vg_name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -3501,7 +3501,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
ret_max = ret;
if (!skip && !already_locked)
- unlock_vg(cmd, vg->name);
+ unlock_vg(cmd, vg, vg->name);
endvg:
release_vg(vg);
if (!lockd_vg(cmd, vg_name, "un", 0, &lockd_state))
@@ -4654,7 +4654,7 @@ int pvcreate_each_device(struct cmd_context *cmd,
* the questions, reacquire the orphans lock, verify that the PVs were
* not used during the questions, then do the create steps.
*/
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
/*
* Process prompts that require asking the user. The orphans lock is
@@ -4941,7 +4941,7 @@ do_command:
return 1;
bad:
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
out:
return 0;
}
diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c
index 8a60ab3..b5a2add 100644
--- a/tools/vgcfgrestore.c
+++ b/tools/vgcfgrestore.c
@@ -70,7 +70,7 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE, NULL)) {
log_error("Unable to lock orphans");
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, vg_name);
return ECMD_FAILED;
}
@@ -81,8 +81,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
arg_str_value(cmd, file_ARG, ""),
arg_count(cmd, force_long_ARG)) :
backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) {
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, NULL, vg_name);
log_error("Restore failed.");
ret = ECMD_FAILED;
goto rescan;
@@ -91,8 +91,8 @@ int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv)
ret = ECMD_PROCESSED;
log_print_unless_silent("Restored volume group %s", vg_name);
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, NULL, vg_name);
rescan:
if (lvmetad_rescan) {
if (!lvmetad_connect(cmd)) {
diff --git a/tools/vgcreate.c b/tools/vgcreate.c
index 14e0d53..1a6a240 100644
--- a/tools/vgcreate.c
+++ b/tools/vgcreate.c
@@ -90,7 +90,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
* VG lock to be released, so the lvmcache destroy rule about locks
* seems to be unwarranted here.
*/
- unlock_vg(cmd, vp_new.vg_name);
+ unlock_vg(cmd, NULL, vp_new.vg_name);
if (!(handle = init_processing_handle(cmd, NULL))) {
log_error("Failed to initialize processing handle.");
@@ -181,8 +181,8 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
goto_bad;
}
- unlock_vg(cmd, VG_ORPHANS);
- unlock_vg(cmd, vp_new.vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
+ unlock_vg(cmd, vg, vp_new.vg_name);
backup(vg);
@@ -222,8 +222,8 @@ out:
return ECMD_PROCESSED;
bad:
- unlock_vg(cmd, vp_new.vg_name);
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, vg, vp_new.vg_name);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
release_vg(vg);
destroy_processing_handle(cmd, handle);
return ECMD_FAILED;
diff --git a/tools/vgextend.c b/tools/vgextend.c
index 4b2a13e..344dff0 100644
--- a/tools/vgextend.c
+++ b/tools/vgextend.c
@@ -204,6 +204,6 @@ int vgextend(struct cmd_context *cmd, int argc, char **argv)
destroy_processing_handle(cmd, handle);
if (!restoremissing)
- unlock_vg(cmd, VG_ORPHANS);
+ unlock_vg(cmd, NULL, VG_ORPHANS);
return ret;
}
diff --git a/tools/vgimportclone.c b/tools/vgimportclone.c
index 7028fbb..09b3a7c 100644
--- a/tools/vgimportclone.c
+++ b/tools/vgimportclone.c
@@ -333,9 +333,9 @@ retry_name:
ret = process_each_vg(cmd, 0, NULL, vp.old_vgname, NULL, READ_FOR_UPDATE | READ_ALLOW_EXPORTED, 0, handle, _vgimportclone_vg_single);
- unlock_vg(cmd, vp.new_vgname);
+ unlock_vg(cmd, NULL, vp.new_vgname);
out:
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
internal_filter_clear();
init_internal_filtering(0);
lvmcache_lock_ordering(1);
diff --git a/tools/vgrename.c b/tools/vgrename.c
index 2006193..293f63c 100644
--- a/tools/vgrename.c
+++ b/tools/vgrename.c
@@ -161,7 +161,7 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
if (!backup_remove(cmd, vg_name))
stack;
- unlock_vg(cmd, vp->vg_name_new);
+ unlock_vg(cmd, vg, vp->vg_name_new);
vp->unlock_new_name = 0;
log_print_unless_silent("Volume group \"%s\" successfully renamed to \"%s\"",
@@ -169,7 +169,7 @@ static int _vgrename_single(struct cmd_context *cmd, const char *vg_name,
return 1;
error:
- unlock_vg(cmd, vp->vg_name_new);
+ unlock_vg(cmd, vg, vp->vg_name_new);
vp->unlock_new_name = 0;
lockd_rename_vg_final(cmd, vg, 0);
@@ -250,7 +250,7 @@ int vgrename(struct cmd_context *cmd, int argc, char **argv)
/* Needed if process_each_vg returns error before calling _single. */
if (vp.unlock_new_name)
- unlock_vg(cmd, vg_name_new);
+ unlock_vg(cmd, NULL, vg_name_new);
destroy_processing_handle(cmd, handle);
return ret;
diff --git a/tools/vgscan.c b/tools/vgscan.c
index e09724a..4deab73 100644
--- a/tools/vgscan.c
+++ b/tools/vgscan.c
@@ -125,6 +125,6 @@ int vgscan(struct cmd_context *cmd, int argc, char **argv)
maxret = ret;
}
- unlock_vg(cmd, VG_GLOBAL);
+ unlock_vg(cmd, NULL, VG_GLOBAL);
return maxret;
}
diff --git a/tools/vgsplit.c b/tools/vgsplit.c
index cb6b0ef..6114a72 100644
--- a/tools/vgsplit.c
+++ b/tools/vgsplit.c
@@ -653,6 +653,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto_bad;
+ lvmetad_vg_update_finish(vg_to);
+
backup(vg_to);
/*
@@ -664,6 +666,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_from) || !vg_commit(vg_from))
goto_bad;
+ lvmetad_vg_update_finish(vg_from);
+
backup(vg_from);
}
@@ -686,6 +690,8 @@ int vgsplit(struct cmd_context *cmd, int argc, char **argv)
if (!vg_write(vg_to) || !vg_commit(vg_to))
goto_bad;
+ lvmetad_vg_update_finish(vg_to);
+
backup(vg_to);
log_print_unless_silent("%s volume group \"%s\" successfully split from \"%s\"",
7 years, 9 months
master - lvmetad: remove unused code for other format types
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=e6c376ee2dae45...
Commit: e6c376ee2dae4539b1cc38ed6d9c5430777d2753
Parent: 8eebb4bfb901caa5330676697557943fdb9733a5
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Tue Jun 7 16:09:45 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:16:35 2016 -0500
lvmetad: remove unused code for other format types
lvmetad is no longer used at all with the lvm1 format,
so the text format is the only one that uses lvmetad.
---
lib/metadata/metadata.c | 7 -------
1 files changed, 0 insertions(+), 7 deletions(-)
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index 9b1fd31..e55463b 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -3546,13 +3546,6 @@ int vg_write(struct volume_group *vg)
if (!_vg_update_vg_precommitted(vg)) /* prepare precommited */
return_0;
- /*
- * If precommit is not supported, changes take effect immediately.
- * FIXME Replace with a more-accurate FMT_COMMIT flag.
- */
- if (!(vg->fid->fmt->features & FMT_PRECOMMIT) && !lvmetad_vg_update(vg))
- return_0;
-
lockd_vg_update(vg);
return 1;
7 years, 9 months
master - WHATS_NEW: add recent changes
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=8eebb4bfb901ca...
Commit: 8eebb4bfb901caa5330676697557943fdb9733a5
Parent: 20f22a8bc0fa84d9abd09f580b93d53d37c4c361
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 27 11:10:58 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:10:58 2016 -0500
WHATS_NEW: add recent changes
---
WHATS_NEW | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/WHATS_NEW b/WHATS_NEW
index 7238568..7a1f3cb 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,11 @@
Version 2.02.158 -
=================================
+ Add a more efficient native vgimportclone command to replace the script.
+ Make lvmlockd always attempt to connect to lvmetad if no connection exists.
+ Let lvmetad handle new connections after shutdown signal.
+ Disable lvmetad when vgcfgrestore begins and enable it again after.
+ Make pvscan do activation if lvmetad is configured but not running.
+ Fix rescanning the PVs for a single VG when using lvmetad.
Pool metadata lvresize uses now same code as resize of normal volume.
Preserve monitoring status when updating thin-pool metadata.
Return 0 (inactive) when status cannot be queried in _lv_active().
7 years, 9 months
master - lvmlockd: fix coverity report
by David Teigland
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=20f22a8bc0fa84...
Commit: 20f22a8bc0fa84d9abd09f580b93d53d37c4c361
Parent: 6c86d942193e35077537753de91970afbcb0acdd
Author: David Teigland <teigland(a)redhat.com>
AuthorDate: Mon Jun 27 11:02:07 2016 -0500
Committer: David Teigland <teigland(a)redhat.com>
CommitterDate: Mon Jun 27 11:02:07 2016 -0500
lvmlockd: fix coverity report
---
daemons/lvmlockd/lvmlockd-core.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/daemons/lvmlockd/lvmlockd-core.c b/daemons/lvmlockd/lvmlockd-core.c
index f61939a..b561529 100644
--- a/daemons/lvmlockd/lvmlockd-core.c
+++ b/daemons/lvmlockd/lvmlockd-core.c
@@ -1031,6 +1031,7 @@ retry:
log_error("lvmetad_open reconnect error %d", err);
memset(&reply, 0, sizeof(reply));
reply.error = err;
+ va_end(ap);
return reply;
} else {
log_debug("lvmetad reconnected");
7 years, 9 months
master - libdm: report: fix field width calculation when using dm_report_column_headings
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=6c86d942193e35...
Commit: 6c86d942193e35077537753de91970afbcb0acdd
Parent: 05196373bec81dcaad490a889388c57e7af1331a
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 14:27:43 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jun 27 14:33:28 2016 +0200
libdm: report: fix field width calculation when using dm_report_column_headings
This fixes commit 0ba5f4b8e977a6f2f45f95777da508b42d84c01a which moved
field recalculation (field width and sort position) from
dm_report_object to dm_report_output but it didn't handle the case when
dm_report_column_headings was used separately to report headings (before
dm_report_outpout call) and hence we ended up with intial widths for
fields in the headings.
If we're using dm_report_column_headings, we need to recalculate
fields if we haven't done so yet, the same way as we do in
dm_report_output.
---
libdm/libdm-report.c | 65 +++++++++++++++++++++++++++++++------------------
1 files changed, 41 insertions(+), 24 deletions(-)
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index ad03c6e..8993201 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -25,7 +25,8 @@
*/
#define RH_SORT_REQUIRED 0x00000100
#define RH_HEADINGS_PRINTED 0x00000200
-#define RH_ALREADY_REPORTED 0x00000400
+#define RH_FIELD_CALC_NEEDED 0x00000400
+#define RH_ALREADY_REPORTED 0x00000800
struct selection {
struct dm_pool *mem;
@@ -1282,6 +1283,8 @@ struct dm_report *dm_report_init(uint32_t *report_types,
if (output_flags & DM_REPORT_OUTPUT_BUFFERED)
rh->flags |= RH_SORT_REQUIRED;
+ rh->flags |= RH_FIELD_CALC_NEEDED;
+
dm_list_init(&rh->field_props);
dm_list_init(&rh->rows);
@@ -4032,6 +4035,7 @@ static void _reset_field_props(struct dm_report *rh)
struct field_properties *fp;
dm_list_iterate_items(fp, &rh->field_props)
fp->width = fp->initial_width;
+ rh->flags |= RH_FIELD_CALC_NEEDED;
}
int dm_report_set_selection(struct dm_report *rh, const char *selection)
@@ -4188,11 +4192,45 @@ static int _report_headings(struct dm_report *rh)
return 0;
}
+static int _should_display_row(struct row *row)
+{
+ return row->field_sel_status || row->selected;
+}
+
+static void _recalculate_fields(struct dm_report *rh)
+{
+ struct row *row;
+ struct dm_report_field *field;
+ size_t len;
+
+ dm_list_iterate_items(row, &rh->rows) {
+ dm_list_iterate_items(field, &row->fields) {
+ if ((rh->flags & RH_SORT_REQUIRED) &&
+ (field->props->flags & FLD_SORT_KEY)) {
+ (*row->sort_fields)[field->props->sort_posn] = field;
+ }
+
+ if (_should_display_row(row)) {
+ len = (int) strlen(field->report_string);
+ if ((len > field->props->width))
+ field->props->width = len;
+
+ }
+ }
+ }
+
+ rh->flags &= ~RH_FIELD_CALC_NEEDED;
+}
+
int dm_report_column_headings(struct dm_report *rh)
{
/* Columns-as-rows does not use _report_headings. */
if (rh->flags & DM_REPORT_OUTPUT_COLUMNS_AS_ROWS)
return 1;
+
+ if (rh->flags & RH_FIELD_CALC_NEEDED)
+ _recalculate_fields(rh);
+
return _report_headings(rh);
}
@@ -4246,11 +4284,6 @@ static int _row_compare(const void *a, const void *b)
return 0; /* Identical */
}
-static int _should_display_row(struct row *row)
-{
- return row->field_sel_status || row->selected;
-}
-
static int _sort_rows(struct dm_report *rh)
{
struct row *(*rows)[];
@@ -4701,9 +4734,6 @@ static int _print_basic_report_header(struct dm_report *rh)
int dm_report_output(struct dm_report *rh)
{
- struct row *row;
- struct dm_report_field *field;
- size_t len;
int r = 0;
if (_is_json_report(rh) &&
@@ -4715,21 +4745,8 @@ int dm_report_output(struct dm_report *rh)
goto out;
}
- dm_list_iterate_items(row, &rh->rows) {
- dm_list_iterate_items(field, &row->fields) {
- if ((rh->flags & RH_SORT_REQUIRED) &&
- (field->props->flags & FLD_SORT_KEY)) {
- (*row->sort_fields)[field->props->sort_posn] = field;
- }
-
- if (_should_display_row(row)) {
- len = (int) strlen(field->report_string);
- if ((len > field->props->width))
- field->props->width = len;
-
- }
- }
- }
+ if (rh->flags & RH_FIELD_CALC_NEEDED)
+ _recalculate_fields(rh);
if ((rh->flags & RH_SORT_REQUIRED))
_sort_rows(rh);
7 years, 9 months
master - reporter: simplify --configreport handling for -S|--select and fix an issue reported by coverity
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=05196373bec81d...
Commit: 05196373bec81dcaad490a889388c57e7af1331a
Parent: 82f4f073bb7eb68aa7cb23a0c6ee75ba03fd0e57
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 10:14:17 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jun 27 11:26:38 2016 +0200
reporter: simplify --configreport handling for -S|--select and fix an issue reported by coverity
Simplify code around _do_get_report_selection - remove "expected_idxs[]"
argument which is superfluous and add "allow_single" switch instead to
allow for recognition of "--configreport <report_name> -S" as well as
single "-S" if needed.
Null pointer dereferences (FORWARD_NULL) /safe/guest2/covscan/LVM2.2.02.158/tools/reporter.c: 961 in _do_report_get_selection()
Null pointer dereferences (FORWARD_NULL) Dereferencing null pointer "single_args".
---
lib/report/report.h | 2 +-
tools/reporter.c | 60 +++++++++++++++++++++++----------------------------
tools/toollib.c | 2 +-
3 files changed, 29 insertions(+), 35 deletions(-)
diff --git a/lib/report/report.h b/lib/report/report.h
index b9028fe..ba3a8fa 100644
--- a/lib/report/report.h
+++ b/lib/report/report.h
@@ -90,7 +90,7 @@ void *report_init(struct cmd_context *cmd, const char *format, const char *keys,
int aligned, int buffered, int headings, int field_prefixes,
int quoted, int columns_as_rows, const char *selection,
int multiple_output);
-int report_get_single_selection(struct cmd_context *cmd, const char **selection);
+int report_get_single_selection(struct cmd_context *cmd, report_type_t report_type, const char **selection);
void *report_init_for_selection(struct cmd_context *cmd, report_type_t *report_type,
const char *selection);
int report_get_prefix_and_desc(report_type_t report_type_id,
diff --git a/tools/reporter.c b/tools/reporter.c
index 40d449c..6f8ed8f 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -29,6 +29,8 @@ typedef enum {
REPORT_IDX_COUNT
} report_idx_t;
+#define REPORT_IDX_FULL_START REPORT_IDX_FULL_VGS
+
struct single_report_args {
report_type_t report_type;
char report_prefix[32];
@@ -748,12 +750,10 @@ static report_idx_t _get_report_idx_from_name(report_type_t report_type, const c
return REPORT_IDX_NULL;
/* Change to basic report type for comparison. */
- if (report_type == LABEL)
+ if ((report_type == LABEL) || (report_type == PVSEGS))
report_type = PVS;
else if (report_type == SEGS)
report_type = LVS;
- else if (report_type == PVSEGS)
- report_type = PVSEGS;
if (!strcasecmp(name, "log"))
idx = REPORT_IDX_LOG;
@@ -778,11 +778,11 @@ static report_idx_t _get_report_idx_from_name(report_type_t report_type, const c
return idx;
}
-static int _should_process_report_idx(report_type_t report_type, report_idx_t idx)
+static int _should_process_report_idx(report_type_t report_type, int allow_single, report_idx_t idx)
{
if (((idx == REPORT_IDX_LOG) && (report_type != CMDLOG)) ||
- ((idx == REPORT_IDX_SINGLE) && ((report_type == FULL) || (report_type == CMDLOG))) ||
- ((idx > REPORT_IDX_LOG) && report_type != FULL))
+ ((idx == REPORT_IDX_SINGLE) && !allow_single) ||
+ ((idx >= REPORT_IDX_FULL_START) && report_type != FULL))
return 0;
return 1;
@@ -867,7 +867,7 @@ static int _get_report_options(struct cmd_context *cmd,
action = OPTS_REPLACE;
}
- if (!_should_process_report_idx(single_args->report_type, idx))
+ if (!_should_process_report_idx(single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)), idx))
continue;
if ((action != OPTS_COMPACT) &&
@@ -932,6 +932,9 @@ static int _get_report_keys(struct cmd_context *cmd,
goto_out;
}
+ if (!_should_process_report_idx(single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)), idx))
+ continue;
+
args->single_args[idx].keys = grouped_arg_str_value(current_group->arg_values, sort_ARG, NULL);
}
@@ -941,16 +944,15 @@ out:
}
static int _do_report_get_selection(struct cmd_context *cmd,
+ report_type_t report_type,
+ int allow_single,
struct report_args *args,
- struct single_report_args *single_args,
- report_idx_t expected_idxs[],
- const char **ret_selection)
+ const char **last_selection)
{
struct arg_value_group_list *current_group;
- const char *final_selection = "", *selection = NULL;
+ const char *final_selection = NULL, *selection = NULL;
const char *report_name = NULL;
report_idx_t idx = REPORT_IDX_SINGLE;
- int i;
dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
if (!grouped_arg_is_set(current_group->arg_values, select_ARG))
@@ -958,27 +960,21 @@ static int _do_report_get_selection(struct cmd_context *cmd,
if (grouped_arg_is_set(current_group->arg_values, configreport_ARG)) {
report_name = grouped_arg_str_value(current_group->arg_values, configreport_ARG, NULL);
- if ((idx = _get_report_idx_from_name(single_args->report_type, report_name)) == REPORT_IDX_NULL)
+ if ((idx = _get_report_idx_from_name(report_type, report_name)) == REPORT_IDX_NULL)
return_0;
}
selection = grouped_arg_str_value(current_group->arg_values, select_ARG, NULL);
- if (single_args) {
- if (!_should_process_report_idx(single_args->report_type, idx))
- continue;
+ if (!_should_process_report_idx(report_type, allow_single, idx))
+ continue;
+ if (args)
args->single_args[idx].selection = selection;
- final_selection = selection;
- } else {
- for (i = 0; expected_idxs[i] != REPORT_IDX_NULL; i++) {
- if (idx == expected_idxs[i])
- final_selection = selection;
- }
- }
+ final_selection = selection;
}
- if (ret_selection)
- *ret_selection = final_selection;
+ if (last_selection)
+ *last_selection = final_selection;
return 1;
}
@@ -987,13 +983,13 @@ static int _get_report_selection(struct cmd_context *cmd,
struct report_args *args,
struct single_report_args *single_args)
{
- return _do_report_get_selection(cmd, args, single_args, NULL, NULL) ? ECMD_PROCESSED : ECMD_FAILED;
+ return _do_report_get_selection(cmd, single_args->report_type, !(single_args->report_type & (CMDLOG | FULL)),
+ args, NULL) ? ECMD_PROCESSED : ECMD_FAILED;
}
-int report_get_single_selection(struct cmd_context *cmd, const char **selection)
+int report_get_single_selection(struct cmd_context *cmd, report_type_t report_type, const char **selection)
{
- report_idx_t expected_idxs[] = {REPORT_IDX_SINGLE, REPORT_IDX_NULL};
- return _do_report_get_selection(cmd, NULL, NULL, expected_idxs, selection);
+ return _do_report_get_selection(cmd, report_type, 1, NULL, selection);
}
static int _set_report_prefix_and_name(struct report_args *args,
@@ -1525,9 +1521,8 @@ bad:
int lastlog(struct cmd_context *cmd, int argc, char **argv)
{
- static report_idx_t expected_idxs[] = {REPORT_IDX_SINGLE, REPORT_IDX_LOG, REPORT_IDX_NULL};
struct dm_report_group *report_group = NULL;
- const char *selection = NULL;
+ const char *selection;
int r = ECMD_FAILED;
if (!cmd->log_rh) {
@@ -1538,8 +1533,7 @@ int lastlog(struct cmd_context *cmd, int argc, char **argv)
if (!report_format_init(cmd, NULL, &report_group, &cmd->log_rh, NULL, NULL))
goto_out;
- if (arg_is_set(cmd, select_ARG) &&
- !_do_report_get_selection(cmd, NULL, NULL, expected_idxs, &selection))
+ if (!_do_report_get_selection(cmd, CMDLOG, 1, NULL, &selection))
goto_out;
if (!dm_report_set_selection(cmd->log_rh, selection)) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 80d0f32..4c24b16 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1771,7 +1771,7 @@ int init_selection_handle(struct cmd_context *cmd, struct processing_handle *han
return 0;
}
- if (!report_get_single_selection(cmd, &selection))
+ if (!report_get_single_selection(cmd, initial_report_type, &selection))
return_0;
sh->report_type = initial_report_type;
7 years, 9 months
master - coverity: fix issues detected in recent code
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=82f4f073bb7eb6...
Commit: 82f4f073bb7eb68aa7cb23a0c6ee75ba03fd0e57
Parent: 15b932a70e4a29f386ea57e1b845d637780b463b
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Mon Jun 27 10:12:41 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Mon Jun 27 11:22:29 2016 +0200
coverity: fix issues detected in recent code
Uninitialized variables (UNINIT) /safe/guest2/covscan/LVM2.2.02.158/tools/toollib.c: 3520 in _process_pvs_in_vgs()
Uninitialized variables (UNINIT) Using uninitialized value "do_report_ret_code".
Null pointer dereferences (REVERSE_INULL) /safe/guest2/covscan/LVM2.2.02.158/libdm/libdm-report.c: 4745 in dm_report_output()
Null pointer dereferences (REVERSE_INULL) Null-checking "rh" suggests that it may be null, but it has already been dereferenced on all paths leading to the check.
Incorrect expression (MISSING_COMMA) /safe/guest2/covscan/LVM2.2.02.158/lib/log/log.c: 280 in _get_log_level_name()
Incorrect expression (MISSING_COMMA) In the initialization of "log_level_names", a suspicious concatenated string ""noticeinfo"" is produced.
Null pointer dereferences (FORWARD_NULL) /safe/guest2/covscan/LVM2.2.02.158/tools/reporter.c: 816 in_get_report_options()
Null pointer dereferences (FORWARD_NULL) Comparing "mem" to null implies that "mem" might be null.
---
lib/log/log.c | 2 +-
libdm/libdm-report.c | 4 ++--
tools/reporter.c | 2 +-
tools/toollib.c | 2 +-
4 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/lib/log/log.c b/lib/log/log.c
index b3453dc..30d71ef 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -277,7 +277,7 @@ static const char *_get_log_level_name(int use_stderr, int level)
"fatal", /* _LOG_FATAL */
"error", /* _LOG_ERROR */
"warn", /* _LOG_WARN */
- "notice" /* _LOG_NOTICE */
+ "notice",/* _LOG_NOTICE */
"info", /* _LOG_INFO */
"debug" /* _LOG_DEBUG */
};
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 6bea34c..ad03c6e 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -4001,7 +4001,7 @@ static int _report_set_selection(struct dm_report *rh, const char *selection, in
goto_bad;
}
- if (!selection || !strcasecmp(selection, SPECIAL_SELECTION_ALL))
+ if (!selection || !selection[0] || !strcasecmp(selection, SPECIAL_SELECTION_ALL))
return 1;
rh->selection->add_new_fields = add_new_fields;
@@ -4742,7 +4742,7 @@ int dm_report_output(struct dm_report *rh)
else
r = _output_as_columns(rh);
out:
- if (r && rh && rh->group_item)
+ if (r && rh->group_item)
rh->group_item->output_done = 1;
return r;
}
diff --git a/tools/reporter.c b/tools/reporter.c
index ee2d251..40d449c 100644
--- a/tools/reporter.c
+++ b/tools/reporter.c
@@ -815,7 +815,7 @@ static int _get_report_options(struct cmd_context *cmd,
if (!(mem = dm_pool_create("report_options", 128))) {
log_error("Failed to create temporary mempool to process report options.");
- goto out;
+ return ECMD_FAILED;
}
if (single_args->report_type == CMDLOG) {
diff --git a/tools/toollib.c b/tools/toollib.c
index 5c61ddd..80d0f32 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -3439,7 +3439,7 @@ static int _process_pvs_in_vgs(struct cmd_context *cmd, uint32_t read_flags,
int skip;
int notfound;
int already_locked;
- int do_report_ret_code;
+ int do_report_ret_code = 1;
log_set_report_object_type(LOG_REPORT_OBJECT_TYPE_VG);
7 years, 9 months
master - doc: Resync kernel docs.
by Alasdair Kergon
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=15b932a70e4a29...
Commit: 15b932a70e4a29f386ea57e1b845d637780b463b
Parent: d914151591dab4ac924fe3b72fb296bc66f2e51c
Author: Alasdair G Kergon <agk(a)redhat.com>
AuthorDate: Sat Jun 25 19:59:49 2016 +0100
Committer: Alasdair G Kergon <agk(a)redhat.com>
CommitterDate: Sat Jun 25 19:59:49 2016 +0100
doc: Resync kernel docs.
---
doc/kernel/cache-policies.txt | 102 +++++++++++++++++++++++--------------
doc/kernel/cache.txt | 15 +++++-
doc/kernel/delay.txt | 1 +
doc/kernel/raid.txt | 33 ++++++++++++
doc/kernel/snapshot.txt | 10 +++-
doc/kernel/statistics.txt | 47 ++++++++++++++++--
doc/kernel/thin-provisioning.txt | 9 +++-
doc/kernel/verity.txt | 40 ++++++++++++++-
8 files changed, 205 insertions(+), 52 deletions(-)
diff --git a/doc/kernel/cache-policies.txt b/doc/kernel/cache-policies.txt
index 0d124a9..d3ca8af 100644
--- a/doc/kernel/cache-policies.txt
+++ b/doc/kernel/cache-policies.txt
@@ -11,7 +11,7 @@ Every bio that is mapped by the target is referred to the policy.
The policy can return a simple HIT or MISS or issue a migration.
Currently there's no way for the policy to issue background work,
-e.g. to start writing back dirty blocks that are going to be evicte
+e.g. to start writing back dirty blocks that are going to be evicted
soon.
Because we map bios, rather than requests it's easy for the policy
@@ -25,53 +25,77 @@ trying to see when the io scheduler has let the ios run.
Overview of supplied cache replacement policies
===============================================
-multiqueue
-----------
+multiqueue (mq)
+---------------
-This policy is the default.
-
-The multiqueue policy has three sets of 16 queues: one set for entries
-waiting for the cache and another two for those in the cache (a set for
-clean entries and a set for dirty entries).
+This policy is now an alias for smq (see below).
-Cache entries in the queues are aged based on logical time. Entry into
-the cache is based on variable thresholds and queue selection is based
-on hit count on entry. The policy aims to take different cache miss
-costs into account and to adjust to varying load patterns automatically.
+The following tunables are accepted, but have no effect:
-Message and constructor argument pairs are:
'sequential_threshold <#nr_sequential_ios>'
'random_threshold <#nr_random_ios>'
'read_promote_adjustment <value>'
'write_promote_adjustment <value>'
'discard_promote_adjustment <value>'
-The sequential threshold indicates the number of contiguous I/Os
-required before a stream is treated as sequential. Once a stream is
-considered sequential it will bypass the cache. The random threshold
-is the number of intervening non-contiguous I/Os that must be seen
-before the stream is treated as random again.
-
-The sequential and random thresholds default to 512 and 4 respectively.
-
-Large, sequential I/Os are probably better left on the origin device
-since spindles tend to have good sequential I/O bandwidth. The
-io_tracker counts contiguous I/Os to try to spot when the I/O is in one
-of these sequential modes. But there are use-cases for wanting to
-promote sequential blocks to the cache (e.g. fast application startup).
-If sequential threshold is set to 0 the sequential I/O detection is
-disabled and sequential I/O will no longer implicitly bypass the cache.
-Setting the random threshold to 0 does _not_ disable the random I/O
-stream detection.
-
-Internally the mq policy determines a promotion threshold. If the hit
-count of a block not in the cache goes above this threshold it gets
-promoted to the cache. The read, write and discard promote adjustment
-tunables allow you to tweak the promotion threshold by adding a small
-value based on the io type. They default to 4, 8 and 1 respectively.
-If you're trying to quickly warm a new cache device you may wish to
-reduce these to encourage promotion. Remember to switch them back to
-their defaults after the cache fills though.
+Stochastic multiqueue (smq)
+---------------------------
+
+This policy is the default.
+
+The stochastic multi-queue (smq) policy addresses some of the problems
+with the multiqueue (mq) policy.
+
+The smq policy (vs mq) offers the promise of less memory utilization,
+improved performance and increased adaptability in the face of changing
+workloads. smq also does not have any cumbersome tuning knobs.
+
+Users may switch from "mq" to "smq" simply by appropriately reloading a
+DM table that is using the cache target. Doing so will cause all of the
+mq policy's hints to be dropped. Also, performance of the cache may
+degrade slightly until smq recalculates the origin device's hotspots
+that should be cached.
+
+Memory usage:
+The mq policy used a lot of memory; 88 bytes per cache block on a 64
+bit machine.
+
+smq uses 28bit indexes to implement it's data structures rather than
+pointers. It avoids storing an explicit hit count for each block. It
+has a 'hotspot' queue, rather than a pre-cache, which uses a quarter of
+the entries (each hotspot block covers a larger area than a single
+cache block).
+
+All this means smq uses ~25bytes per cache block. Still a lot of
+memory, but a substantial improvement nontheless.
+
+Level balancing:
+mq placed entries in different levels of the multiqueue structures
+based on their hit count (~ln(hit count)). This meant the bottom
+levels generally had the most entries, and the top ones had very
+few. Having unbalanced levels like this reduced the efficacy of the
+multiqueue.
+
+smq does not maintain a hit count, instead it swaps hit entries with
+the least recently used entry from the level above. The overall
+ordering being a side effect of this stochastic process. With this
+scheme we can decide how many entries occupy each multiqueue level,
+resulting in better promotion/demotion decisions.
+
+Adaptability:
+The mq policy maintained a hit count for each cache block. For a
+different block to get promoted to the cache it's hit count has to
+exceed the lowest currently in the cache. This meant it could take a
+long time for the cache to adapt between varying IO patterns.
+
+smq doesn't maintain hit counts, so a lot of this problem just goes
+away. In addition it tracks performance of the hotspot queue, which
+is used to decide which blocks to promote. If the hotspot queue is
+performing badly then it starts moving entries more quickly between
+levels. This lets it adapt to new IO patterns very quickly.
+
+Performance:
+Testing smq shows substantially better performance than mq.
cleaner
-------
diff --git a/doc/kernel/cache.txt b/doc/kernel/cache.txt
index 68c0f51..785eab8 100644
--- a/doc/kernel/cache.txt
+++ b/doc/kernel/cache.txt
@@ -221,6 +221,7 @@ Status
<#read hits> <#read misses> <#write hits> <#write misses>
<#demotions> <#promotions> <#dirty> <#features> <features>*
<#core args> <core args>* <policy name> <#policy args> <policy args>*
+<cache metadata mode>
metadata block size : Fixed block size for each metadata block in
sectors
@@ -251,8 +252,18 @@ core args : Key/value pairs for tuning the core
e.g. migration_threshold
policy name : Name of the policy
#policy args : Number of policy arguments to follow (must be even)
-policy args : Key/value pairs
- e.g. sequential_threshold
+policy args : Key/value pairs e.g. sequential_threshold
+cache metadata mode : ro if read-only, rw if read-write
+ In serious cases where even a read-only mode is deemed unsafe
+ no further I/O will be permitted and the status will just
+ contain the string 'Fail'. The userspace recovery tools
+ should then be used.
+needs_check : 'needs_check' if set, '-' if not set
+ A metadata operation has failed, resulting in the needs_check
+ flag being set in the metadata's superblock. The metadata
+ device must be deactivated and checked/repaired before the
+ cache can be made fully operational again. '-' indicates
+ needs_check is not set.
Messages
--------
diff --git a/doc/kernel/delay.txt b/doc/kernel/delay.txt
index 15adc55..a07b592 100644
--- a/doc/kernel/delay.txt
+++ b/doc/kernel/delay.txt
@@ -8,6 +8,7 @@ Parameters:
<device> <offset> <delay> [<write_device> <write_offset> <write_delay>]
With separate write parameters, the first set is only used for reads.
+Offsets are specified in sectors.
Delays are specified in milliseconds.
Example scripts
diff --git a/doc/kernel/raid.txt b/doc/kernel/raid.txt
index ef8ba9f..df2d636 100644
--- a/doc/kernel/raid.txt
+++ b/doc/kernel/raid.txt
@@ -209,6 +209,37 @@ include:
"repair" - Initiate a repair of the array.
"reshape"- Currently unsupported (-EINVAL).
+
+Discard Support
+---------------
+The implementation of discard support among hardware vendors varies.
+When a block is discarded, some storage devices will return zeroes when
+the block is read. These devices set the 'discard_zeroes_data'
+attribute. Other devices will return random data. Confusingly, some
+devices that advertise 'discard_zeroes_data' will not reliably return
+zeroes when discarded blocks are read! Since RAID 4/5/6 uses blocks
+from a number of devices to calculate parity blocks and (for performance
+reasons) relies on 'discard_zeroes_data' being reliable, it is important
+that the devices be consistent. Blocks may be discarded in the middle
+of a RAID 4/5/6 stripe and if subsequent read results are not
+consistent, the parity blocks may be calculated differently at any time;
+making the parity blocks useless for redundancy. It is important to
+understand how your hardware behaves with discards if you are going to
+enable discards with RAID 4/5/6.
+
+Since the behavior of storage devices is unreliable in this respect,
+even when reporting 'discard_zeroes_data', by default RAID 4/5/6
+discard support is disabled -- this ensures data integrity at the
+expense of losing some performance.
+
+Storage devices that properly support 'discard_zeroes_data' are
+increasingly whitelisted in the kernel and can thus be trusted.
+
+For trusted devices, the following dm-raid module parameter can be set
+to safely enable discard support for RAID 4/5/6:
+ 'devices_handle_discards_safely'
+
+
Version History
---------------
1.0.0 Initial version. Support for RAID 4/5/6
@@ -224,3 +255,5 @@ Version History
New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
1.5.1 Add ability to restore transiently failed devices on resume.
1.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check".
+1.6.0 Add discard support (and devices_handle_discard_safely module param).
+1.7.0 Add support for MD RAID0 mappings.
diff --git a/doc/kernel/snapshot.txt b/doc/kernel/snapshot.txt
index 0d5bc46..ad6949b 100644
--- a/doc/kernel/snapshot.txt
+++ b/doc/kernel/snapshot.txt
@@ -41,9 +41,13 @@ useless and be disabled, returning errors. So it is important to monitor
the amount of free space and expand the <COW device> before it fills up.
<persistent?> is P (Persistent) or N (Not persistent - will not survive
-after reboot).
-The difference is that for transient snapshots less metadata must be
-saved on disk - they can be kept in memory by the kernel.
+after reboot). O (Overflow) can be added as a persistent store option
+to allow userspace to advertise its support for seeing "Overflow" in the
+snapshot status. So supported store types are "P", "PO" and "N".
+
+The difference between persistent and transient is with transient
+snapshots less metadata must be saved on disk - they can be kept in
+memory by the kernel.
* snapshot-merge <origin> <COW device> <persistent> <chunksize>
diff --git a/doc/kernel/statistics.txt b/doc/kernel/statistics.txt
index 2a1673a..170ac02 100644
--- a/doc/kernel/statistics.txt
+++ b/doc/kernel/statistics.txt
@@ -13,9 +13,14 @@ the range specified.
The I/O statistics counters for each step-sized area of a region are
in the same format as /sys/block/*/stat or /proc/diskstats (see:
Documentation/iostats.txt). But two extra counters (12 and 13) are
-provided: total time spent reading and writing in milliseconds. All
-these counters may be accessed by sending the @stats_print message to
-the appropriate DM device via dmsetup.
+provided: total time spent reading and writing. When the histogram
+argument is used, the 14th parameter is reported that represents the
+histogram of latencies. All these counters may be accessed by sending
+the @stats_print message to the appropriate DM device via dmsetup.
+
+The reported times are in milliseconds and the granularity depends on
+the kernel ticks. When the option precise_timestamps is used, the
+reported times are in nanoseconds.
Each region has a corresponding unique identifier, which we call a
region_id, that is assigned when the region is created. The region_id
@@ -33,7 +38,9 @@ memory is used by reading
Messages
========
- @stats_create <range> <step> [<program_id> [<aux_data>]]
+ @stats_create <range> <step>
+ [<number_of_optional_arguments> <optional_arguments>...]
+ [<program_id> [<aux_data>]]
Create a new region and return the region_id.
@@ -48,6 +55,29 @@ Messages
"/<number_of_areas>" - the range is subdivided into the specified
number of areas.
+ <number_of_optional_arguments>
+ The number of optional arguments
+
+ <optional_arguments>
+ The following optional arguments are supported
+ precise_timestamps - use precise timer with nanosecond resolution
+ instead of the "jiffies" variable. When this argument is
+ used, the resulting times are in nanoseconds instead of
+ milliseconds. Precise timestamps are a little bit slower
+ to obtain than jiffies-based timestamps.
+ histogram:n1,n2,n3,n4,... - collect histogram of latencies. The
+ numbers n1, n2, etc are times that represent the boundaries
+ of the histogram. If precise_timestamps is not used, the
+ times are in milliseconds, otherwise they are in
+ nanoseconds. For each range, the kernel will report the
+ number of requests that completed within this range. For
+ example, if we use "histogram:10,20,30", the kernel will
+ report four numbers a:b:c:d. a is the number of requests
+ that took 0-10 ms to complete, b is the number of requests
+ that took 10-20 ms to complete, c is the number of requests
+ that took 20-30 ms to complete and d is the number of
+ requests that took more than 30 ms to complete.
+
<program_id>
An optional parameter. A name that uniquely identifies
the userspace owner of the range. This groups ranges together
@@ -55,6 +85,9 @@ Messages
created and ignore those created by others.
The kernel returns this string back in the output of
@stats_list message, but it doesn't use it for anything else.
+ If we omit the number of optional arguments, program id must not
+ be a number, otherwise it would be interpreted as the number of
+ optional arguments.
<aux_data>
An optional parameter. A word that provides auxiliary data
@@ -88,6 +121,10 @@ Messages
Output format:
<region_id>: <start_sector>+<length> <step> <program_id> <aux_data>
+ precise_timestamps histogram:n1,n2,n3,...
+
+ The strings "precise_timestamps" and "histogram" are printed only
+ if they were specified when creating the region.
@stats_print <region_id> [<starting_line> <number_of_lines>]
@@ -168,7 +205,7 @@ statistics on them:
dmsetup message vol 0 @stats_create - /100
-Set the auxillary data string to "foo bar baz" (the escape for each
+Set the auxiliary data string to "foo bar baz" (the escape for each
space must also be escaped, otherwise the shell will consume them):
dmsetup message vol 0 @stats_set_aux 0 foo\\ bar\\ baz
diff --git a/doc/kernel/thin-provisioning.txt b/doc/kernel/thin-provisioning.txt
index 4f67578..1699a55 100644
--- a/doc/kernel/thin-provisioning.txt
+++ b/doc/kernel/thin-provisioning.txt
@@ -296,7 +296,7 @@ ii) Status
underlying device. When this is enabled when loading the table,
it can get disabled if the underlying device doesn't support it.
- ro|rw
+ ro|rw|out_of_data_space
If the pool encounters certain types of device failures it will
drop into a read-only metadata mode in which no changes to
the pool metadata (like allocating new blocks) are permitted.
@@ -314,6 +314,13 @@ ii) Status
module parameter can be used to change this timeout -- it
defaults to 60 seconds but may be disabled using a value of 0.
+ needs_check
+ A metadata operation has failed, resulting in the needs_check
+ flag being set in the metadata's superblock. The metadata
+ device must be deactivated and checked/repaired before the
+ thin-pool can be made fully operational again. '-' indicates
+ needs_check is not set.
+
iii) Messages
create_thin <dev id>
diff --git a/doc/kernel/verity.txt b/doc/kernel/verity.txt
index e15bc1a..89fd8f9 100644
--- a/doc/kernel/verity.txt
+++ b/doc/kernel/verity.txt
@@ -18,11 +18,11 @@ Construction Parameters
0 is the original format used in the Chromium OS.
The salt is appended when hashing, digests are stored continuously and
- the rest of the block is padded with zeros.
+ the rest of the block is padded with zeroes.
1 is the current format that should be used for new devices.
The salt is prepended when hashing and each digest is
- padded with zeros to the power of two.
+ padded with zeroes to the power of two.
<dev>
This is the device containing data, the integrity of which needs to be
@@ -79,6 +79,37 @@ restart_on_corruption
not compatible with ignore_corruption and requires user space support to
avoid restart loops.
+ignore_zero_blocks
+ Do not verify blocks that are expected to contain zeroes and always return
+ zeroes instead. This may be useful if the partition contains unused blocks
+ that are not guaranteed to contain zeroes.
+
+use_fec_from_device <fec_dev>
+ Use forward error correction (FEC) to recover from corruption if hash
+ verification fails. Use encoding data from the specified device. This
+ may be the same device where data and hash blocks reside, in which case
+ fec_start must be outside data and hash areas.
+
+ If the encoding data covers additional metadata, it must be accessible
+ on the hash device after the hash blocks.
+
+ Note: block sizes for data and hash devices must match. Also, if the
+ verity <dev> is encrypted the <fec_dev> should be too.
+
+fec_roots <num>
+ Number of generator roots. This equals to the number of parity bytes in
+ the encoding data. For example, in RS(M, N) encoding, the number of roots
+ is M-N.
+
+fec_blocks <num>
+ The number of encoding data blocks on the FEC device. The block size for
+ the FEC device is <data_block_size>.
+
+fec_start <offset>
+ This is the offset, in <data_block_size> blocks, from the start of the
+ FEC device to the beginning of the encoding data.
+
+
Theory of operation
===================
@@ -98,6 +129,11 @@ per-block basis. This allows for a lightweight hash computation on first read
into the page cache. Block hashes are stored linearly, aligned to the nearest
block size.
+If forward error correction (FEC) support is enabled any recovery of
+corrupted data will be verified using the cryptographic hash of the
+corresponding data. This is why combining error correction with
+integrity checking is essential.
+
Hash Tree
---------
7 years, 9 months
master - man: lvs: move doc about --all so it's ordered alphabetically in the man page
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=d914151591dab4...
Commit: d914151591dab4ac924fe3b72fb296bc66f2e51c
Parent: a910052a2e7da4531ff0e39e569ab2eaa56b1870
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jun 24 14:56:43 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jun 24 14:57:09 2016 +0200
man: lvs: move doc about --all so it's ordered alphabetically in the man page
---
man/lvs.8.in | 20 ++++++++++----------
1 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/man/lvs.8.in b/man/lvs.8.in
index 7bd25a6..3cb2d2b 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -53,6 +53,16 @@ for common options.
.B \-\-aligned
Use with \fB\-\-separator\fP to align the output columns.
.TP
+.B \-\-all
+Include information in the output about internal Logical Volumes that
+are components of normally-accessible Logical Volumes, such as mirrors,
+but which are not independently accessible (e.g. not mountable).
+The names of such Logical Volumes are enclosed within square brackets
+in the output. For example, after creating a mirror using
+.B lvcreate -m1 \-\-mirrorlog disk
+, this option will reveal three internal Logical
+Volumes, with suffixes mimage_0, mimage_1, and mlog.
+.TP
.B \-\-binary
Use binary values "0" or "1" instead of descriptive literal values
for columns that have exactly two valid values to report (not counting
@@ -67,16 +77,6 @@ command's main report is assumed. The log report is available only if
enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
if \fB\-\-logonly\fP option is used.
.TP
-.B \-\-all
-Include information in the output about internal Logical Volumes that
-are components of normally-accessible Logical Volumes, such as mirrors,
-but which are not independently accessible (e.g. not mountable).
-The names of such Logical Volumes are enclosed within square brackets
-in the output. For example, after creating a mirror using
-.B lvcreate -m1 \-\-mirrorlog disk
-, this option will reveal three internal Logical
-Volumes, with suffixes mimage_0, mimage_1, and mlog.
-.TP
.B \-H ", " \-\-history
Include historical logical volumes in the output.
(This has no effect unless logical volumes were removed while the configuration
7 years, 10 months
master - man: document --configreport, --logonly, --reportformat
by Peter Rajnoha
Gitweb: http://git.fedorahosted.org/git/?p=lvm2.git;a=commitdiff;h=a910052a2e7da4...
Commit: a910052a2e7da4531ff0e39e569ab2eaa56b1870
Parent: 9a414245b908bfa1bacb12b6416908de65f0e317
Author: Peter Rajnoha <prajnoha(a)redhat.com>
AuthorDate: Fri Jun 24 14:51:20 2016 +0200
Committer: Peter Rajnoha <prajnoha(a)redhat.com>
CommitterDate: Fri Jun 24 14:51:20 2016 +0200
man: document --configreport, --logonly, --reportformat
---
man/lvchange.8.in | 2 ++
man/lvcreate.8.in | 4 ++++
man/lvdisplay.8.in | 20 ++++++++++++++------
man/lvextend.8.in | 2 ++
man/lvm.8.in | 10 ++++++++++
man/lvreduce.8.in | 2 ++
man/lvremove.8.in | 2 ++
man/lvrename.8.in | 2 ++
man/lvresize.8.in | 2 ++
man/lvs.8.in | 29 ++++++++++++++++++++++++-----
man/lvscan.8.in | 2 ++
man/pvchange.8.in | 2 ++
man/pvcreate.8.in | 2 ++
man/pvdisplay.8.in | 21 ++++++++++++++-------
man/pvmove.8.in | 2 ++
man/pvremove.8.in | 2 ++
man/pvresize.8.in | 2 ++
man/pvs.8.in | 30 ++++++++++++++++++++++++------
man/pvscan.8.in | 4 ++++
man/vgcfgbackup.8.in | 2 ++
man/vgchange.8.in | 2 ++
man/vgck.8.in | 2 ++
man/vgconvert.8.in | 2 ++
man/vgcreate.8.in | 2 ++
man/vgdisplay.8.in | 20 ++++++++++++++------
man/vgexport.8.in | 2 ++
man/vgextend.8.in | 2 ++
man/vgimport.8.in | 2 ++
man/vgmknodes.8.in | 2 ++
man/vgreduce.8.in | 2 ++
man/vgremove.8.in | 2 ++
man/vgrename.8.in | 2 ++
man/vgs.8.in | 30 ++++++++++++++++++++++++------
man/vgscan.8.in | 2 ++
34 files changed, 182 insertions(+), 36 deletions(-)
diff --git a/man/lvchange.8.in b/man/lvchange.8.in
index 2bfe7c0..3800369 100644
--- a/man/lvchange.8.in
+++ b/man/lvchange.8.in
@@ -76,6 +76,8 @@ lvchange \(em change attributes of a logical volume
.RB [ \-r | \-\-readahead
.RB { \fIReadAheadSectors | auto | none }]
.RB [ \-\-refresh ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-resync ]
.RB [ \-S | \-\-select
.IR Selection ]
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index c28bc41..3e2bf32 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -93,6 +93,8 @@ lvcreate \- create a logical volume in an existing volume group
.IR Rate ]
.RB [ \-r | \-\-readahead
.RB { \fIReadAheadSectors | auto | none }]
+.RB [ \-\-reportformat
+.RB {basic | json}]
.RB \%[ \-k | \-\-setactivationskip
.RB { y | n }]
.RB [ \-s | \-\-snapshot ]
@@ -133,6 +135,8 @@ lvcreate \- create a logical volume in an existing volume group
.RB { y | n }]
.RB [ \-n | \-\-name
.IR SnapshotLogicalVolumeName ]
+.RB [ \-\-reportformat
+.RB {basic | json}]
.BR \-s | \-\-snapshot | \-H | \-\-cache
.RI \%{[ VolumeGroup \fB/\fP] OriginalLogicalVolume
.RB \%[ \-V | \-\-virtualsize
diff --git a/man/lvdisplay.8.in b/man/lvdisplay.8.in
index f14fa03..e8e7809 100644
--- a/man/lvdisplay.8.in
+++ b/man/lvdisplay.8.in
@@ -14,6 +14,8 @@ lvdisplay \(em display attributes of a logical volume
.RB [ \-\-maps ]
.RB [ \-\-nosuffix ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-\-units
@@ -30,20 +32,26 @@ lvdisplay \(em display attributes of a logical volume
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [ ,Field ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-segments ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
diff --git a/man/lvextend.8.in b/man/lvextend.8.in
index 8deab54..eefbf79 100644
--- a/man/lvextend.8.in
+++ b/man/lvextend.8.in
@@ -24,6 +24,8 @@ lvextend \(em extend the size of a logical volume
.RB [ \-n | \-\-nofsck ]
.RB [ \-\-noudevsync]
.RB [ \-r | \-\-resizefs ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-use\-policies ]
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
diff --git a/man/lvm.8.in b/man/lvm.8.in
index f8400cf..729518b 100644
--- a/man/lvm.8.in
+++ b/man/lvm.8.in
@@ -466,6 +466,16 @@ for any other command (with the exception of \fBlvmconfig\fP command where the
\fB\-\-profile\fP has special meaning, see \fBlvmconfig\fP(8) for more information).
.
.HP
+.BR \-\-reportformat
+.IR {basic|json}
+.br
+Overrides current output format for reports which is defined globally by
+\fBreport/output_format\fP configuration setting in \fBlvm.conf\fP(5).
+The \fBbasic\fP format is the original format with columns and rows and
+if there is more than one report per command, each report is prefixed
+with report's name for identification. The \fBjson\fP stands for report
+output in JSON format.
+.HP
.BR \-\-config
.IR ConfigurationString
.br
diff --git a/man/lvreduce.8.in b/man/lvreduce.8.in
index 5aca24e..edf0c92 100644
--- a/man/lvreduce.8.in
+++ b/man/lvreduce.8.in
@@ -20,6 +20,8 @@ lvreduce \(em reduce the size of a logical volume
.BR \-L | \-\-size
.RI [ \- ] LogicalVolumeSize [ bBsSkKmMgGtTpPeE ]}
.RB [ \-n | \-\-nofsck ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-r | \-\-resizefs ]
.IR LogicalVolume { Name | Path }
.SH DESCRIPTION
diff --git a/man/lvremove.8.in b/man/lvremove.8.in
index 433c277..fe9375c 100644
--- a/man/lvremove.8.in
+++ b/man/lvremove.8.in
@@ -10,6 +10,8 @@ lvremove \(em remove a logical volume
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-\-help ]
.RB [ \-\-nohistory ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-t | \-\-test ]
diff --git a/man/lvrename.8.in b/man/lvrename.8.in
index fdacac7..de6e519 100644
--- a/man/lvrename.8.in
+++ b/man/lvrename.8.in
@@ -14,6 +14,8 @@ lvrename \(em rename a logical volume
.RB [ \-\-version ]
.RB [ \-f | \-\-force ]
.RB [ \-\-noudevsync ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RI { OldLogicalVolume { Name | Path }
.IR NewLogicalVolume { Name | Path }
|
diff --git a/man/lvresize.8.in b/man/lvresize.8.in
index a5bda53..9cdb787 100644
--- a/man/lvresize.8.in
+++ b/man/lvresize.8.in
@@ -17,6 +17,8 @@ lvresize \(em resize a logical volume
.RI [ + ] MetadataVolumeSize [ bBsSkKmMgG ]]
.RB [ \-f | \-\-force ]
.RB [ \-n | \-\-nofsck ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-r | \-\-resizefs ]
.IR LogicalVolume { Name | Path }
.RI [ PhysicalVolumePath [ :PE [ \-PE ]]...]
diff --git a/man/lvs.8.in b/man/lvs.8.in
index d4bc7f2..7bd25a6 100644
--- a/man/lvs.8.in
+++ b/man/lvs.8.in
@@ -8,22 +8,29 @@ lvs \(em report information about logical volumes
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-H | \-\-history ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-nameprefixes ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [, Field ]]
-.RB [ \-O | \-\-sort
.RI [ + | \- ] Key1 [,[ + | \- ] Key2 [,...]]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-rows ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-segments ]
@@ -51,6 +58,15 @@ Use binary values "0" or "1" instead of descriptive literal values
for columns that have exactly two valid values to report (not counting
the "unknown" value which denotes that the value could not be determined).
.TP
+.B \-\-configreport \fI ReportName
+Make any subsequent \fB\-o, \-\-options\fP, \fB\-O, \-\-sort\fP or
+\fB\-S, \-\-select\fP to apply for \fIReportName\fP where \fIReportName\fP
+is either 'lvs' for command's main report or 'log' for log report.
+If \fB\-\-configreport\fP option is not used to identify a report, then
+command's main report is assumed. The log report is available only if
+enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
+if \fB\-\-logonly\fP option is used.
+.TP
.B \-\-all
Include information in the output about internal Logical Volumes that
are components of normally-accessible Logical Volumes, such as mirrors,
@@ -66,6 +82,9 @@ Include historical logical volumes in the output.
(This has no effect unless logical volumes were removed while the configuration
setting \fBmetadata/record_lvs_history\fP was enabled.)
.TP
+.B \-\-logonly
+Suppress the lvs report itself and display only log report on output.
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/lvscan.8.in b/man/lvscan.8.in
index 0b6e50b..5710e3c 100644
--- a/man/lvscan.8.in
+++ b/man/lvscan.8.in
@@ -11,6 +11,8 @@ lvscan \(em scan (all disks) for Logical Volumes
.RB [ \-h | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.SH DESCRIPTION
lvscan scans all known volume groups or all supported LVM block devices
diff --git a/man/pvchange.8.in b/man/pvchange.8.in
index 5c5b809..c7ddc58 100644
--- a/man/pvchange.8.in
+++ b/man/pvchange.8.in
@@ -16,6 +16,8 @@ pvchange \(em change attributes of a physical volume
.RB [ \-\-metadataignore
.RI { y | n }]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-t | \-\-test ]
diff --git a/man/pvcreate.8.in b/man/pvcreate.8.in
index a50aaa7..97a9909 100644
--- a/man/pvcreate.8.in
+++ b/man/pvcreate.8.in
@@ -31,6 +31,8 @@ pvcreate \(em initialize a disk or partition for use by LVM
.RB [ \-\-restorefile
.IR file ]
.RB [ \-\-norestorefile ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-setphysicalvolumesize
.IR size ]
.RB [ \-u | \-\-uuid
diff --git a/man/pvdisplay.8.in b/man/pvdisplay.8.in
index 5f93634..9bca720 100644
--- a/man/pvdisplay.8.in
+++ b/man/pvdisplay.8.in
@@ -12,6 +12,8 @@ pvdisplay \- display attributes of a physical volume
.RB [ \-\-ignoreskippedcluster ]
.RB [ \-\-maps ]
.RB [ \-\-nosuffix ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-s | \-\-short ]
.RB [ \-S | \-\-select
.IR Selection ]
@@ -30,19 +32,24 @@ pvdisplay \- display attributes of a physical volume
.RB [ \-\-binary ]
.RB [ \-a | \-\-all ]
.RB [ \-\-commandprofile
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
+.RB [ \-\-logonly ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [ ,Field ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...
-.RI ]]
-.RB [ \-S | \-\-select
-.IR Selection ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
diff --git a/man/pvmove.8.in b/man/pvmove.8.in
index 43a4e00..39fdfe4 100644
--- a/man/pvmove.8.in
+++ b/man/pvmove.8.in
@@ -15,6 +15,8 @@ pvmove \(em move physical extents
.RB [ \-i | \-\-interval
.IR Seconds ]
.RB [ \-\-noudevsync ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RB [ \-n | \-\-name
.IR LogicalVolume ]
diff --git a/man/pvremove.8.in b/man/pvremove.8.in
index 5f9b055..6444884 100644
--- a/man/pvremove.8.in
+++ b/man/pvremove.8.in
@@ -12,6 +12,8 @@ pvremove \(em remove a physical volume
.RB [ \-\-version ]
.RB [ \-f [ f ]| \-\-force
.RB [ \-\-force ]]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-y | \-\-yes ]
.I PhysicalVolume
.RI [ PhysicalVolume ...]
diff --git a/man/pvresize.8.in b/man/pvresize.8.in
index 8b78651..b7d8f33 100644
--- a/man/pvresize.8.in
+++ b/man/pvresize.8.in
@@ -10,6 +10,8 @@ pvresize \(em resize a disk or partition in use by LVM2
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
.RB [ \-\-version ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-setphysicalvolumesize
.IR size ]
.I PhysicalVolume
diff --git a/man/pvs.8.in b/man/pvs.8.in
index 24d16fb..0a60b6f 100644
--- a/man/pvs.8.in
+++ b/man/pvs.8.in
@@ -8,22 +8,28 @@ pvs \(em report information about physical volumes
.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-nameprefixes ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field [ ,Field ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-rows ]
.RB [ \-\-segments ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
@@ -51,6 +57,18 @@ Use binary values "0" or "1" instead of descriptive literal values
for columns that have exactly two valid values to report (not counting
the "unknown" value which denotes that the value could not be determined).
.TP
+.B \-\-configreport \fI ReportName
+Make any subsequent \fB\-o, \-\-options\fP, \fB\-O, \-\-sort\fP or
+\fB\-S, \-\-select\fP to apply for \fIReportName\fP where \fIReportName\fP
+is either 'pvs' for command's main report or 'log' for log report.
+If \fB\-\-configreport\fP option is not used to identify a report, then
+command's main report is assumed. The log report is available only if
+enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
+if \fB\-\-logonly\fP option is used.
+.TP
+.B \-\-logonly
+Suppress the pvs report itself and display only log report on output.
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/pvscan.8.in b/man/pvscan.8.in
index 010c091..38f424f 100644
--- a/man/pvscan.8.in
+++ b/man/pvscan.8.in
@@ -13,6 +13,8 @@ pvscan \(em scan all disks for physical volumes
.RB [ \-\-ignorelockingfailure ]
.RB [ \-e | \-\-exported ]
.RB [ \-n | \-\-novolumegroup ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-s | \-\-short ]
.RB [ \-u | \-\-uuid ]
.BR
@@ -23,6 +25,8 @@ pvscan \(em scan all disks for physical volumes
.B \-\-cache
.RB [ \-a | \-\-activate " " \fIay ]
.RB [ \-b | \-\-background ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-major
.I major
.B \-\-minor
diff --git a/man/vgcfgbackup.8.in b/man/vgcfgbackup.8.in
index 898764a..c6f20d9 100644
--- a/man/vgcfgbackup.8.in
+++ b/man/vgcfgbackup.8.in
@@ -11,6 +11,8 @@ vgcfgbackup \(em backup volume group descriptor area
.RB [ \-h | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RI [ VolumeGroupName ...]
.SH DESCRIPTION
diff --git a/man/vgchange.8.in b/man/vgchange.8.in
index e334fd1..3b2fc3e 100644
--- a/man/vgchange.8.in
+++ b/man/vgchange.8.in
@@ -49,6 +49,8 @@ vgchange \(em change attributes of a volume group
.RB [ \-P | \-\-partial ]
.RB [ \-s | \-\-physicalextentsize
.IR PhysicalExtentSize [ bBsSkKmMgGtTpPeE ]]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-\-systemid
diff --git a/man/vgck.8.in b/man/vgck.8.in
index f09e709..b10f57e 100644
--- a/man/vgck.8.in
+++ b/man/vgck.8.in
@@ -7,6 +7,8 @@ vgck \(em check volume group metadata
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RI [ VolumeGroupName ...]
.SH DESCRIPTION
diff --git a/man/vgconvert.8.in b/man/vgconvert.8.in
index c77d529..d864483 100644
--- a/man/vgconvert.8.in
+++ b/man/vgconvert.8.in
@@ -18,6 +18,8 @@ vgconvert \- convert volume group metadata format
.IR NumberOfCopies ]
.RB [ \-\-metadatasize
.IR size ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-version ]
.I VolumeGroupName
.RI [ VolumeGroupName ...]
diff --git a/man/vgcreate.8.in b/man/vgcreate.8.in
index 764d76e..c66753b 100644
--- a/man/vgcreate.8.in
+++ b/man/vgcreate.8.in
@@ -27,6 +27,8 @@ vgcreate \(em create a volume group
.IR NumberOfCopies | unmanaged | all ]
.RB [ \-s | \-\-physicalextentsize
.IR PhysicalExtentSize [ bBsSkKmMgGtTpPeE ]]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-shared ]
.RB [ \-\-systemid
.IR SystemID ]
diff --git a/man/vgdisplay.8.in b/man/vgdisplay.8.in
index 89a7a5a..045a6ae 100644
--- a/man/vgdisplay.8.in
+++ b/man/vgdisplay.8.in
@@ -7,6 +7,8 @@ vgdisplay \(em display attributes of volume groups
.RB [ \-c | \-\-colon ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-s | \-\-short ]
.RB [ \-S | \-\-select
.IR Selection ]
@@ -30,19 +32,25 @@ vgdisplay \(em display attributes of volume groups
.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o|\-\-options
-.RI [ + | \- | # ] Field1 [ ,Field2 ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
-.RB [ \-S | \-\-select
-.IR Selection ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
diff --git a/man/vgexport.8.in b/man/vgexport.8.in
index 08c1d78..6e2ecbf 100644
--- a/man/vgexport.8.in
+++ b/man/vgexport.8.in
@@ -8,6 +8,8 @@ vgexport \- make volume groups unknown to the system
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-v | \-\-verbose ]
diff --git a/man/vgextend.8.in b/man/vgextend.8.in
index 52837db..51bd615 100644
--- a/man/vgextend.8.in
+++ b/man/vgextend.8.in
@@ -9,6 +9,8 @@ vgextend \(em add physical volumes to a volume group
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-restoremissing ]
.RB [ \-f | \-\-force ]
.RB [ \-t | \-\-test ]
diff --git a/man/vgimport.8.in b/man/vgimport.8.in
index cd34049..ba4fdf9 100644
--- a/man/vgimport.8.in
+++ b/man/vgimport.8.in
@@ -6,6 +6,8 @@ vgimport \(em make exported volume groups known to the system
.RB [ \-a | \-\-all ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-v | \-\-verbose ]
diff --git a/man/vgmknodes.8.in b/man/vgmknodes.8.in
index 4f5bbfe..c5bb5d4 100644
--- a/man/vgmknodes.8.in
+++ b/man/vgmknodes.8.in
@@ -8,6 +8,8 @@ vgmknodes \(em recreate volume group directory and logical volume special files
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-\-help ]
.RB [ \-\-refresh ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.RI [[ VolumeGroupName | LogicalVolumePath ]...]
.SH DESCRIPTION
diff --git a/man/vgreduce.8.in b/man/vgreduce.8.in
index 9e70a0a..cce31e8 100644
--- a/man/vgreduce.8.in
+++ b/man/vgreduce.8.in
@@ -11,6 +11,8 @@ vgreduce \(em reduce a volume group
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-removemissing ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
.I VolumeGroupName
diff --git a/man/vgremove.8.in b/man/vgremove.8.in
index 082c1f3..4e600ef 100644
--- a/man/vgremove.8.in
+++ b/man/vgremove.8.in
@@ -9,6 +9,8 @@ vgremove \(em remove a volume group
.RB [ \-f | \-\-force ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-noudevsync ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-t | \-\-test ]
diff --git a/man/vgrename.8.in b/man/vgrename.8.in
index 1f2539b..322d740 100644
--- a/man/vgrename.8.in
+++ b/man/vgrename.8.in
@@ -9,6 +9,8 @@ vgrename \(em rename a volume group
.IR ProfileName ]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-t | \-\-test ]
.RB [ \-v | \-\-verbose ]
.IR OldVolumeGroup { Path | Name | UUID }
diff --git a/man/vgs.8.in b/man/vgs.8.in
index f219665..ab9d9ac 100644
--- a/man/vgs.8.in
+++ b/man/vgs.8.in
@@ -8,21 +8,27 @@ vgs \(em report information about volume groups
.RB [ \-\-binary ]
.RB [ \-\-commandprofile
.IR ProfileName ]
+.RB [[ \-\-configreport
+.IR ReportName ]
+.RB [ \-o | \-\-options
+.RI [ + | \- | # ] Field1 [, Field2 ...]
+.RB [ \-O | \-\-sort
+.RI [ + | \- ] Key1 [, Key2 ...]]
+.RB [ \-S | \-\-select
+.IR Selection ]
+.RB ...]
.RB [ \-d | \-\-debug ]
.RB [ \-h | \-? | \-\-help ]
.RB [ \-\-ignorelockingfailure ]
.RB [ \-\-ignoreskippedcluster ]
+.RB [ \-\-logonly ]
.RB [ \-\-nameprefixes ]
.RB [ \-\-noheadings ]
.RB [ \-\-nosuffix ]
-.RB [ \-o | \-\-options
-.RI [ + | \- | # ] Field1 [ ,Field2 ...]]
-.RB [ \-O | \-\-sort
-.RI [ + | \- ] Key1 [ , [ + | \- ] Key2 ...]]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-\-rows ]
-.RB [ \-S | \-\-select
-.IR Selection ]
.RB [ \-\-separator
.IR Separator ]
.RB [ \-\-unbuffered ]
@@ -49,6 +55,18 @@ Use binary values "0" or "1" instead of descriptive literal values
for columns that have exactly two valid values to report (not counting
the "unknown" value which denotes that the value could not be determined).
.TP
+.B \-\-configreport \fI ReportName
+Make any subsequent \fB\-o, \-\-options\fP, \fB\-O, \-\-sort\fP or
+\fB\-S, \-\-select\fP to apply for \fIReportName\fP where \fIReportName\fP
+is either 'vgs' for command's main report or 'log' for log report.
+If \fB\-\-configreport\fP option is not used to identify a report, then
+command's main report is assumed. The log report is available only if
+enabled by \fBlog/report_command_log\fP \fBlvm.conf\fP(5) setting or
+if \fB\-\-logonly\fP option is used.
+.TP
+.B \-\-logonly
+Suppress the vgs report itself and display only log report on output.
+.TP
.B \-\-nameprefixes
Add an "LVM2_" prefix plus the field name to the output. Useful
with \fB\-\-noheadings\fP to produce a list of field=value pairs that can
diff --git a/man/vgscan.8.in b/man/vgscan.8.in
index 8c699d1..e85d817 100644
--- a/man/vgscan.8.in
+++ b/man/vgscan.8.in
@@ -11,6 +11,8 @@ vgscan \(em scan all disks for volume groups and rebuild caches
.RB [ \-\-mknodes ]
.RB [ \-\-notifydbus ]
.RB [ \-P | \-\-partial ]
+.RB [ \-\-reportformat
+.RB { basic | json }]
.RB [ \-v | \-\-verbose ]
.SH DESCRIPTION
vgscan scans all SCSI, (E)IDE disks, multiple devices and a bunch
7 years, 10 months