summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlasdair Kergon <agk@redhat.com>2007-12-22 12:13:29 +0000
committerAlasdair Kergon <agk@redhat.com>2007-12-22 12:13:29 +0000
commitba0c495db710f1aae0fa5e216cb8535b5e4262e6 (patch)
tree004721eae838e384c49fb5df0614ab7c521aa71f
parentb9c69aa63ae01118a27cc1ec629cd8338191c9d3 (diff)
downloadlvm2-ba0c495db710f1aae0fa5e216cb8535b5e4262e6.tar.gz
lvm2-ba0c495db710f1aae0fa5e216cb8535b5e4262e6.tar.xz
lvm2-ba0c495db710f1aae0fa5e216cb8535b5e4262e6.zip
lvconvert uses polldaemon now
-rw-r--r--WHATS_NEW1
-rw-r--r--lib/metadata/mirror.c14
-rw-r--r--man/lvconvert.87
-rw-r--r--tools/commands.h6
-rw-r--r--tools/lvconvert.c108
-rw-r--r--tools/polldaemon.c10
-rw-r--r--tools/polldaemon.h4
-rw-r--r--tools/pvmove.c3
8 files changed, 135 insertions, 18 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 29f7756a..86d9054e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.02.30 -
===================================
+ Extend lvconvert to use polldaemon.
Add support for stacked mirrors.
Major restructuring of pvmove and lvconvert layer manipulation code.
Replace tools/fsadm with scripts/fsadm.sh.
diff --git a/lib/metadata/mirror.c b/lib/metadata/mirror.c
index 72fee93e..d75a3f19 100644
--- a/lib/metadata/mirror.c
+++ b/lib/metadata/mirror.c
@@ -1068,6 +1068,8 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
int in_sync)
{
struct logical_volume *log_lv;
+ const char *suffix;
+ struct lv_segment *seg;
init_mirror_in_sync(in_sync);
@@ -1076,9 +1078,15 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
return NULL;
}
- if (!(log_lv = _create_mirror_log(lv, ah, alloc, lv->name,
- strstr(lv->name, MIRROR_SYNC_LAYER)
- ? "_mlogtmp_%d" : "_mlog"))) {
+ /* Check if the log is for temporary sync layer. */
+ seg = first_seg(lv);
+ if (seg_type(seg, 0) == AREA_LV &&
+ strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
+ suffix = "_mlogtmp_%d";
+ else
+ suffix = "_mlog";
+
+ if (!(log_lv = _create_mirror_log(lv, ah, alloc, lv->name, suffix))) {
log_error("Failed to create mirror log.");
return NULL;
}
diff --git a/man/lvconvert.8 b/man/lvconvert.8
index 613b6545..fbc1d7b9 100644
--- a/man/lvconvert.8
+++ b/man/lvconvert.8
@@ -5,6 +5,7 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot
.B lvconvert
\-m/\-\-mirrors Mirrors [\-\-mirrorlog {disk|core}] [\-\-corelog] [\-R/\-\-regionsize MirrorLogRegionSize]
[\-A/\-\-alloc AllocationPolicy]
+[\-b/\-\-background] [\-i/\-\-interval Seconds]
[\-h/\-?/\-\-help]
[\-v/\-\-verbose]
[\-\-version]
@@ -52,6 +53,12 @@ The optional argument "--corelog" is the same as specifying "--mirrorlog core".
.I \-R, \-\-regionsize MirrorLogRegionSize
A mirror is divided into regions of this size (in MB), and the mirror log
uses this granularity to track which regions are in sync.
+.TP
+.I \-b, \-\-background
+Run the daemon in the background.
+.TP
+.I \-i, \-\-interval Seconds
+Report progress as a percentage at regular intervals.
.br
.TP
.I \-s, \-\-snapshot
diff --git a/tools/commands.h b/tools/commands.h
index 46b4e046..0e610fde 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -91,8 +91,10 @@ xx(lvconvert,
"[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n"
+ "\t[-b|--background]\n"
"\t[-d|--debug]\n"
"\t[-h|-?|--help]\n"
+ "\t[-i|--interval seconds]\n"
"\t[-v|--verbose]\n"
"\t[--version]" "\n"
"\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n\n"
@@ -107,8 +109,8 @@ xx(lvconvert,
"\t[--version]" "\n"
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
- alloc_ARG, chunksize_ARG, corelog_ARG, mirrorlog_ARG, mirrors_ARG,
- regionsize_ARG, snapshot_ARG, test_ARG, zero_ARG)
+ alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
+ mirrorlog_ARG, mirrors_ARG, regionsize_ARG, snapshot_ARG, test_ARG, zero_ARG)
xx(lvcreate,
"Create a logical volume",
diff --git a/tools/lvconvert.c b/tools/lvconvert.c
index b3a1d5c5..e37fc655 100644
--- a/tools/lvconvert.c
+++ b/tools/lvconvert.c
@@ -13,6 +13,7 @@
*/
#include "tools.h"
+#include "polldaemon.h"
#include "lv_alloc.h"
struct lvconvert_params {
@@ -21,7 +22,9 @@ struct lvconvert_params {
const char *origin;
const char *lv_name;
+ const char *lv_name_full;
const char *vg_name;
+ int wait_daemon;
uint32_t chunk_size;
uint32_t region_size;
@@ -70,11 +73,11 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
return 0;
}
- lp->lv_name = (*pargv)[0];
+ lp->lv_name = lp->lv_name_full = (*pargv)[0];
(*pargv)++, (*pargc)--;
- if (strchr(lp->lv_name, '/') &&
- (vg_name = extract_vgname(cmd, lp->lv_name)) &&
+ if (strchr(lp->lv_name_full, '/') &&
+ (vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
lp->vg_name && strcmp(vg_name, lp->vg_name)) {
log_error("Please use a single volume group name "
"(\"%s\" or \"%s\")", vg_name, lp->vg_name);
@@ -89,7 +92,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
return 0;
}
- if ((ptr = strrchr(lp->lv_name, '/')))
+ if ((ptr = strrchr(lp->lv_name_full, '/')))
lp->lv_name = ptr + 1;
if (!apply_lvname_restrictions(lp->lv_name))
@@ -227,6 +230,90 @@ static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
return 1;
}
+
+static struct volume_group *_get_lvconvert_vg(struct cmd_context *cmd,
+ const char *lv_name)
+{
+ dev_close_all();
+
+ return vg_lock_and_read(cmd, extract_vgname(cmd, lv_name),
+ NULL, LCK_VG_WRITE,
+ CLUSTERED | EXPORTED_VG | LVM_WRITE,
+ CORRECT_INCONSISTENT | FAIL_INCONSISTENT);
+}
+
+static struct logical_volume *_get_lvconvert_lv(struct cmd_context *cmd __attribute((unused)),
+ struct volume_group *vg,
+ const char *name,
+ uint32_t lv_type __attribute((unused)))
+{
+ return find_lv(vg, name);
+}
+
+static int _update_lvconvert_mirror(struct cmd_context *cmd __attribute((unused)),
+ struct volume_group *vg __attribute((unused)),
+ struct logical_volume *lv __attribute((unused)),
+ struct list *lvs_changed __attribute((unused)),
+ int first_time __attribute((unused)))
+{
+ /* lvconvert mirror doesn't require periodical metadata update */
+ return 1;
+}
+
+static int _finish_lvconvert_mirror(struct cmd_context *cmd,
+ struct volume_group *vg,
+ struct logical_volume *lv,
+ struct list *lvs_changed __attribute((unused)))
+{
+ if (!collapse_mirrored_lv(lv)) {
+ log_error("Failed to remove temporary sync layer.");
+ return 0;
+ }
+
+ log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
+
+ if (!vg_write(vg))
+ return_0;
+
+ backup(vg);
+
+ if (!suspend_lv(cmd, lv)) {
+ log_error("Failed to lock %s", lv->name);
+ vg_revert(vg);
+ return 0;
+ }
+
+ if (!vg_commit(vg)) {
+ resume_lv(cmd, lv);
+ return 0;
+ }
+
+ log_very_verbose("Updating \"%s\" in kernel", lv->name);
+
+ if (!resume_lv(cmd, lv)) {
+ log_error("Problem reactivating %s", lv->name);
+ return 0;
+ }
+
+ log_print("Logical volume %s converted.", lv->name);
+
+ return 1;
+}
+
+static struct poll_functions _lvconvert_mirror_fns = {
+ .get_copy_vg = _get_lvconvert_vg,
+ .get_copy_lv = _get_lvconvert_lv,
+ .update_metadata = _update_lvconvert_mirror,
+ .finish_copy = _finish_lvconvert_mirror,
+};
+
+static int _lvconvert_poll(struct cmd_context *cmd, const char *lv_name,
+ unsigned background)
+{
+ return poll_daemon(cmd, lv_name, background, 0, &_lvconvert_mirror_fns,
+ "Converted");
+}
+
static int _insert_lvconvert_layer(struct cmd_context *cmd,
struct logical_volume *lv)
{
@@ -284,9 +371,8 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
/* If called with no argument, try collapsing the resync layers */
if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG)) {
- if (!collapse_mirrored_lv(lv))
- return_0;
- goto commit_changes;
+ lp->wait_daemon = 1;
+ return 1;
}
/*
@@ -439,6 +525,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
corelog ? 0U : 1U, lp->pvh, lp->alloc,
MIRROR_BY_LV))
return_0;
+ lp->wait_daemon = 1;
} else {
/* Reduce number of mirrors */
if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
@@ -472,7 +559,8 @@ commit_changes:
return 0;
}
- log_print("Logical volume %s converted.", lv->name);
+ if (!lp->wait_daemon)
+ log_print("Logical volume %s converted.", lv->name);
return 1;
}
@@ -625,5 +713,9 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
error:
unlock_vg(cmd, lp.vg_name);
+
+ if (lp.wait_daemon)
+ ret = _lvconvert_poll(cmd, lp.lv_name_full,
+ arg_count(cmd, background_ARG) ? 1U : 0);
return ret;
}
diff --git a/tools/polldaemon.c b/tools/polldaemon.c
index 28857922..aa5d8838 100644
--- a/tools/polldaemon.c
+++ b/tools/polldaemon.c
@@ -93,9 +93,11 @@ static int _check_mirror_status(struct cmd_context *cmd,
overall_percent = copy_percent(lv_mirr);
if (parms->progress_display)
- log_print("%s: Moved: %.1f%%", name, overall_percent);
+ log_print("%s: %s: %.1f%%", name, parms->progress_title,
+ overall_percent);
else
- log_verbose("%s: Moved: %.1f%%", name, overall_percent);
+ log_verbose("%s: %s: %.1f%%", name, parms->progress_title,
+ overall_percent);
if (segment_percent < 100.0) {
/* The only case the caller *should* try again later */
@@ -224,7 +226,8 @@ static void _poll_for_all_vgs(struct cmd_context *cmd,
}
int poll_daemon(struct cmd_context *cmd, const char *name, unsigned background,
- uint32_t lv_type, struct poll_functions *poll_fns)
+ uint32_t lv_type, struct poll_functions *poll_fns,
+ const char *progress_title)
{
struct daemon_parms parms;
@@ -232,6 +235,7 @@ int poll_daemon(struct cmd_context *cmd, const char *name, unsigned background,
parms.background = background;
parms.interval = arg_uint_value(cmd, interval_ARG, DEFAULT_INTERVAL);
parms.progress_display = 1;
+ parms.progress_title = progress_title;
parms.lv_type = lv_type;
parms.poll_fns = poll_fns;
diff --git a/tools/polldaemon.h b/tools/polldaemon.h
index 9e333cd4..3b5ffa3c 100644
--- a/tools/polldaemon.h
+++ b/tools/polldaemon.h
@@ -42,11 +42,13 @@ struct daemon_parms {
unsigned background;
unsigned outstanding_count;
unsigned progress_display;
+ const char *progress_title;
uint32_t lv_type;
struct poll_functions *poll_fns;
};
int poll_daemon(struct cmd_context *cmd, const char *name, unsigned background,
- uint32_t lv_type, struct poll_functions *poll_fns);
+ uint32_t lv_type, struct poll_functions *poll_fns,
+ const char *progress_title);
#endif
diff --git a/tools/pvmove.c b/tools/pvmove.c
index 2438c6d7..5071b6c7 100644
--- a/tools/pvmove.c
+++ b/tools/pvmove.c
@@ -525,7 +525,8 @@ static struct poll_functions _pvmove_fns = {
int pvmove_poll(struct cmd_context *cmd, const char *pv_name,
unsigned background)
{
- return poll_daemon(cmd, pv_name, background, PVMOVE, &_pvmove_fns);
+ return poll_daemon(cmd, pv_name, background, PVMOVE, &_pvmove_fns,
+ "Moved");
}
int pvmove(struct cmd_context *cmd, int argc, char **argv)