1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-02 01:18:26 +03:00

lvconvert uses polldaemon now

This commit is contained in:
Alasdair Kergon 2007-12-22 12:13:29 +00:00
parent b9c69aa63a
commit ba0c495db7
8 changed files with 135 additions and 18 deletions

View File

@ -1,5 +1,6 @@
Version 2.02.30 - Version 2.02.30 -
=================================== ===================================
Extend lvconvert to use polldaemon.
Add support for stacked mirrors. Add support for stacked mirrors.
Major restructuring of pvmove and lvconvert layer manipulation code. Major restructuring of pvmove and lvconvert layer manipulation code.
Replace tools/fsadm with scripts/fsadm.sh. Replace tools/fsadm with scripts/fsadm.sh.

View File

@ -1068,6 +1068,8 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
int in_sync) int in_sync)
{ {
struct logical_volume *log_lv; struct logical_volume *log_lv;
const char *suffix;
struct lv_segment *seg;
init_mirror_in_sync(in_sync); init_mirror_in_sync(in_sync);
@ -1076,9 +1078,15 @@ static struct logical_volume *_set_up_mirror_log(struct cmd_context *cmd,
return NULL; return NULL;
} }
if (!(log_lv = _create_mirror_log(lv, ah, alloc, lv->name, /* Check if the log is for temporary sync layer. */
strstr(lv->name, MIRROR_SYNC_LAYER) seg = first_seg(lv);
? "_mlogtmp_%d" : "_mlog"))) { 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."); log_error("Failed to create mirror log.");
return NULL; return NULL;
} }

View File

@ -5,6 +5,7 @@ lvconvert \- convert a logical volume from linear to mirror or snapshot
.B lvconvert .B lvconvert
\-m/\-\-mirrors Mirrors [\-\-mirrorlog {disk|core}] [\-\-corelog] [\-R/\-\-regionsize MirrorLogRegionSize] \-m/\-\-mirrors Mirrors [\-\-mirrorlog {disk|core}] [\-\-corelog] [\-R/\-\-regionsize MirrorLogRegionSize]
[\-A/\-\-alloc AllocationPolicy] [\-A/\-\-alloc AllocationPolicy]
[\-b/\-\-background] [\-i/\-\-interval Seconds]
[\-h/\-?/\-\-help] [\-h/\-?/\-\-help]
[\-v/\-\-verbose] [\-v/\-\-verbose]
[\-\-version] [\-\-version]
@ -52,6 +53,12 @@ The optional argument "--corelog" is the same as specifying "--mirrorlog core".
.I \-R, \-\-regionsize MirrorLogRegionSize .I \-R, \-\-regionsize MirrorLogRegionSize
A mirror is divided into regions of this size (in MB), and the mirror log 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. 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 .br
.TP .TP
.I \-s, \-\-snapshot .I \-s, \-\-snapshot

View File

@ -91,8 +91,10 @@ xx(lvconvert,
"[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n" "[-m|--mirrors Mirrors [{--mirrorlog {disk|core}|--corelog}]]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n" "\t[-R|--regionsize MirrorLogRegionSize]\n"
"\t[--alloc AllocationPolicy]\n" "\t[--alloc AllocationPolicy]\n"
"\t[-b|--background]\n"
"\t[-d|--debug]\n" "\t[-d|--debug]\n"
"\t[-h|-?|--help]\n" "\t[-h|-?|--help]\n"
"\t[-i|--interval seconds]\n"
"\t[-v|--verbose]\n" "\t[-v|--verbose]\n"
"\t[--version]" "\n" "\t[--version]" "\n"
"\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n\n" "\tLogicalVolume[Path] [PhysicalVolume[Path]...]\n\n"
@ -107,8 +109,8 @@ xx(lvconvert,
"\t[--version]" "\n" "\t[--version]" "\n"
"\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n", "\tOriginalLogicalVolume[Path] SnapshotLogicalVolume[Path]\n",
alloc_ARG, chunksize_ARG, corelog_ARG, mirrorlog_ARG, mirrors_ARG, alloc_ARG, background_ARG, chunksize_ARG, corelog_ARG, interval_ARG,
regionsize_ARG, snapshot_ARG, test_ARG, zero_ARG) mirrorlog_ARG, mirrors_ARG, regionsize_ARG, snapshot_ARG, test_ARG, zero_ARG)
xx(lvcreate, xx(lvcreate,
"Create a logical volume", "Create a logical volume",

View File

@ -13,6 +13,7 @@
*/ */
#include "tools.h" #include "tools.h"
#include "polldaemon.h"
#include "lv_alloc.h" #include "lv_alloc.h"
struct lvconvert_params { struct lvconvert_params {
@ -21,7 +22,9 @@ struct lvconvert_params {
const char *origin; const char *origin;
const char *lv_name; const char *lv_name;
const char *lv_name_full;
const char *vg_name; const char *vg_name;
int wait_daemon;
uint32_t chunk_size; uint32_t chunk_size;
uint32_t region_size; uint32_t region_size;
@ -70,11 +73,11 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
return 0; return 0;
} }
lp->lv_name = (*pargv)[0]; lp->lv_name = lp->lv_name_full = (*pargv)[0];
(*pargv)++, (*pargc)--; (*pargv)++, (*pargc)--;
if (strchr(lp->lv_name, '/') && if (strchr(lp->lv_name_full, '/') &&
(vg_name = extract_vgname(cmd, lp->lv_name)) && (vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
lp->vg_name && strcmp(vg_name, lp->vg_name)) { lp->vg_name && strcmp(vg_name, lp->vg_name)) {
log_error("Please use a single volume group name " log_error("Please use a single volume group name "
"(\"%s\" or \"%s\")", vg_name, lp->vg_name); "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
@ -89,7 +92,7 @@ static int _lvconvert_name_params(struct lvconvert_params *lp,
return 0; return 0;
} }
if ((ptr = strrchr(lp->lv_name, '/'))) if ((ptr = strrchr(lp->lv_name_full, '/')))
lp->lv_name = ptr + 1; lp->lv_name = ptr + 1;
if (!apply_lvname_restrictions(lp->lv_name)) 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; 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, static int _insert_lvconvert_layer(struct cmd_context *cmd,
struct logical_volume *lv) 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 called with no argument, try collapsing the resync layers */
if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG)) { if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG)) {
if (!collapse_mirrored_lv(lv)) lp->wait_daemon = 1;
return_0; return 1;
goto commit_changes;
} }
/* /*
@ -439,6 +525,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
corelog ? 0U : 1U, lp->pvh, lp->alloc, corelog ? 0U : 1U, lp->pvh, lp->alloc,
MIRROR_BY_LV)) MIRROR_BY_LV))
return_0; return_0;
lp->wait_daemon = 1;
} else { } else {
/* Reduce number of mirrors */ /* Reduce number of mirrors */
if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors, if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
@ -472,7 +559,8 @@ commit_changes:
return 0; return 0;
} }
log_print("Logical volume %s converted.", lv->name); if (!lp->wait_daemon)
log_print("Logical volume %s converted.", lv->name);
return 1; return 1;
} }
@ -625,5 +713,9 @@ int lvconvert(struct cmd_context * cmd, int argc, char **argv)
error: error:
unlock_vg(cmd, lp.vg_name); 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; return ret;
} }

View File

@ -93,9 +93,11 @@ static int _check_mirror_status(struct cmd_context *cmd,
overall_percent = copy_percent(lv_mirr); overall_percent = copy_percent(lv_mirr);
if (parms->progress_display) if (parms->progress_display)
log_print("%s: Moved: %.1f%%", name, overall_percent); log_print("%s: %s: %.1f%%", name, parms->progress_title,
overall_percent);
else 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) { if (segment_percent < 100.0) {
/* The only case the caller *should* try again later */ /* 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, 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; struct daemon_parms parms;
@ -232,6 +235,7 @@ int poll_daemon(struct cmd_context *cmd, const char *name, unsigned background,
parms.background = background; parms.background = background;
parms.interval = arg_uint_value(cmd, interval_ARG, DEFAULT_INTERVAL); parms.interval = arg_uint_value(cmd, interval_ARG, DEFAULT_INTERVAL);
parms.progress_display = 1; parms.progress_display = 1;
parms.progress_title = progress_title;
parms.lv_type = lv_type; parms.lv_type = lv_type;
parms.poll_fns = poll_fns; parms.poll_fns = poll_fns;

View File

@ -42,11 +42,13 @@ struct daemon_parms {
unsigned background; unsigned background;
unsigned outstanding_count; unsigned outstanding_count;
unsigned progress_display; unsigned progress_display;
const char *progress_title;
uint32_t lv_type; uint32_t lv_type;
struct poll_functions *poll_fns; struct poll_functions *poll_fns;
}; };
int poll_daemon(struct cmd_context *cmd, const char *name, unsigned background, 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 #endif

View File

@ -525,7 +525,8 @@ static struct poll_functions _pvmove_fns = {
int pvmove_poll(struct cmd_context *cmd, const char *pv_name, int pvmove_poll(struct cmd_context *cmd, const char *pv_name,
unsigned background) 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) int pvmove(struct cmd_context *cmd, int argc, char **argv)