summaryrefslogtreecommitdiffstats
path: root/tools
diff options
context:
space:
mode:
authorZdenek Kabelac <zkabelac@redhat.com>2012-06-28 14:52:23 +0200
committerZdenek Kabelac <zkabelac@redhat.com>2012-07-18 14:38:34 +0200
commit48367c5be9b39cd118caeb6b8e554be347d2fd8c (patch)
tree8c159876a15394de789b74b15b67da1cff8d75ca /tools
parent46b9cc1248941cc43f953e1a6b285ebe64a62077 (diff)
downloadlvm2-48367c5be9b39cd118caeb6b8e554be347d2fd8c.tar.gz
lvm2-48367c5be9b39cd118caeb6b8e554be347d2fd8c.tar.xz
lvm2-48367c5be9b39cd118caeb6b8e554be347d2fd8c.zip
thin: add lvchange for discard and zero change
Update lvchange to allow change of 'zero' flag for thinpool. Add support for changing discard handling. N.B. from/to ignore could be only changed for inactive pool.
Diffstat (limited to 'tools')
-rw-r--r--tools/commands.h7
-rw-r--r--tools/lvchange.c88
2 files changed, 92 insertions, 3 deletions
diff --git a/tools/commands.h b/tools/commands.h
index fe7403da..88c170ae 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -69,6 +69,7 @@ xx(lvchange,
"\t[--deltag Tag]\n"
"\t[-f|--force]\n"
"\t[-h|--help]\n"
+ "\t[--discard {ignore|nopassdown|passdown}]\n"
"\t[--ignorelockingfailure]\n"
"\t[--ignoremonitoring]\n"
"\t[--monitor {y|n}]\n"
@@ -84,14 +85,16 @@ xx(lvchange,
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
"\t[-y|--yes]\n"
- "\t[--version]" "\n"
+ "\t[--version]\n"
+ "\t[-Z|--zero {y|n}]\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
alloc_ARG, autobackup_ARG, activate_ARG, available_ARG, contiguous_ARG,
force_ARG, ignorelockingfailure_ARG, ignoremonitoring_ARG, major_ARG,
minor_ARG, monitor_ARG, noudevsync_ARG, partial_ARG, permission_ARG,
persistent_ARG, poll_ARG, readahead_ARG, resync_ARG, refresh_ARG,
- addtag_ARG, deltag_ARG, sysinit_ARG, test_ARG, yes_ARG)
+ addtag_ARG, deltag_ARG, sysinit_ARG, test_ARG, yes_ARG,
+ discard_ARG, zero_ARG)
xx(lvconvert,
"Change logical volume layout",
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 9054ac78..a24d26c2 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -89,6 +89,77 @@ out:
return r;
}
+static int lvchange_pool_update(struct cmd_context *cmd,
+ struct logical_volume *lv)
+{
+ int r = 0;
+ int update = 0;
+ unsigned val;
+ thin_discard_t discard;
+
+ if (!lv_is_thin_pool(lv)) {
+ log_error("Logical volume \"%s\" is not a thinpool.", lv->name);
+ return 0;
+ }
+
+ if (arg_count(cmd, discard_ARG)) {
+ discard = arg_uint_value(cmd, discard_ARG, 0);
+ if (discard != first_seg(lv)->discard) {
+ if (((discard == THIN_DISCARD_IGNORE) ||
+ (first_seg(lv)->discard == THIN_DISCARD_IGNORE)) &&
+ lv_is_active(lv))
+ log_error("Cannot change discard state for active "
+ "logical volume \"%s\".", lv->name);
+ else {
+ first_seg(lv)->discard = discard;
+ update++;
+ }
+ } else
+ log_error("Logical volume \"%s\" already uses discard %s.",
+ lv->name, get_pool_discard_name(discard));
+ }
+
+ if (arg_count(cmd, zero_ARG)) {
+ val = arg_uint_value(cmd, zero_ARG, 1);
+ if (val != first_seg(lv)->zero_new_blocks) {
+ first_seg(lv)->zero_new_blocks = val;
+ update++;
+ } else
+ log_error("Logical volume \"%s\" already %szero new blocks.",
+ lv->name, val ? "" : "does not ");
+ }
+
+ if (!update)
+ return 0;
+
+ log_very_verbose("Updating logical volume \"%s\" on disk(s).", lv->name);
+ if (!vg_write(lv->vg))
+ return_0;
+
+ if (!suspend_lv_origin(cmd, lv)) {
+ log_error("Failed to update active %s/%s (deactivation is needed).",
+ lv->vg->name, lv->name);
+ vg_revert(lv->vg);
+ goto out;
+ }
+
+ if (!vg_commit(lv->vg)) {
+ if (!resume_lv_origin(cmd, lv))
+ stack;
+ goto_out;
+ }
+
+ if (!resume_lv_origin(cmd, lv)) {
+ log_error("Problem reactivating %s.", lv->name);
+ goto out;
+ }
+
+ r = 1;
+out:
+ backup(lv->vg);
+ return r;
+}
+
static int lvchange_monitoring(struct cmd_context *cmd,
struct logical_volume *lv)
{
@@ -545,6 +616,8 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
if (!(lv->vg->status & LVM_WRITE) &&
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
+ arg_count(cmd, discard_ARG) ||
+ arg_count(cmd, zero_ARG) ||
arg_count(cmd, alloc_ARG))) {
log_error("Only -a permitted with read-only volume "
"group \"%s\"", lv->vg->name);
@@ -670,6 +743,17 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
+ if (arg_count(cmd, discard_ARG) ||
+ arg_count(cmd, zero_ARG)) {
+ if (!archived && !archive(lv->vg)) {
+ stack;
+ return ECMD_FAILED;
+ }
+ archived = 1;
+ doit += lvchange_pool_update(cmd, lv);
+ docmds++;
+ }
+
/* add tag */
if (arg_count(cmd, addtag_ARG)) {
if (!archived && !archive(lv->vg)) {
@@ -747,7 +831,9 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) ||
- arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG);
+ arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG) ||
+ arg_count(cmd, discard_ARG) ||
+ arg_count(cmd, zero_ARG);
if (!update &&
!arg_count(cmd, activate_ARG) && !arg_count(cmd, refresh_ARG) &&