[lvm-devel] LVM2 lib/format_text/flags.c lib/format_text/i ...
agk at sourceware.org
agk at sourceware.org
Thu Jan 10 18:35:52 UTC 2008
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk at sourceware.org 2008-01-10 18:35:51
Modified files:
lib/format_text: flags.c import_vsn1.c
lib/metadata : metadata-exported.h mirror.c
lib/report : columns.h report.c
man : lvs.8 pvs.8 vgs.8
tools : lvchange.c lvconvert.c tools.h
Log message:
Various lvconvert/polldaemon-related fixes from NEC. See lvm-devel
for original patches & explanations.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/flags.c.diff?cvsroot=lvm2&r1=1.30&r2=1.31
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/format_text/import_vsn1.c.diff?cvsroot=lvm2&r1=1.45&r2=1.46
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata-exported.h.diff?cvsroot=lvm2&r1=1.30&r2=1.31
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/mirror.c.diff?cvsroot=lvm2&r1=1.51&r2=1.52
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/columns.h.diff?cvsroot=lvm2&r1=1.26&r2=1.27
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/report/report.c.diff?cvsroot=lvm2&r1=1.70&r2=1.71
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/lvs.8.diff?cvsroot=lvm2&r1=1.7&r2=1.8
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/pvs.8.diff?cvsroot=lvm2&r1=1.3&r2=1.4
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/vgs.8.diff?cvsroot=lvm2&r1=1.5&r2=1.6
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvchange.c.diff?cvsroot=lvm2&r1=1.84&r2=1.85
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/lvconvert.c.diff?cvsroot=lvm2&r1=1.52&r2=1.53
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/tools.h.diff?cvsroot=lvm2&r1=1.59&r2=1.60
--- LVM2/lib/format_text/flags.c 2007/08/20 20:55:26 1.30
+++ LVM2/lib/format_text/flags.c 2008/01/10 18:35:50 1.31
@@ -60,6 +60,7 @@
{VIRTUAL, NULL},
{SNAPSHOT, NULL},
{ACTIVATE_EXCL, NULL},
+ {CONVERTING, NULL},
{0, NULL}
};
--- LVM2/lib/format_text/import_vsn1.c 2007/11/09 16:51:53 1.45
+++ LVM2/lib/format_text/import_vsn1.c 2008/01/10 18:35:50 1.46
@@ -86,6 +86,22 @@
return 1;
}
+static int _is_converting(struct logical_volume *lv)
+{
+ struct lv_segment *seg;
+
+ if (lv->status & MIRRORED) {
+ seg = first_seg(lv);
+ /* Can't use is_temporary_mirror() because the metadata for
+ * seg_lv may not be read in and flags may not be set yet. */
+ if (seg_type(seg, 0) == AREA_LV &&
+ strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER))
+ return 1;
+ }
+
+ return 0;
+}
+
static int _read_id(struct id *id, struct config_node *cn, const char *path)
{
struct config_value *cv;
@@ -343,6 +359,9 @@
if (seg_is_virtual(seg))
lv->status |= VIRTUAL;
+ if (_is_converting(lv))
+ lv->status |= CONVERTING;
+
return 1;
}
--- LVM2/lib/metadata/metadata-exported.h 2008/01/07 20:42:57 1.30
+++ LVM2/lib/metadata/metadata-exported.h 2008/01/10 18:35:50 1.31
@@ -69,6 +69,7 @@
#define MIRROR_NOTSYNCED 0x00080000U /* LV */
//#define ACTIVATE_EXCL 0x00100000U /* LV - internal use only */
//#define PRECOMMITTED 0x00200000U /* VG - internal use only */
+#define CONVERTING 0x00400000U /* LV */
#define LVM_READ 0x00000100U /* LV VG */
#define LVM_WRITE 0x00000200U /* LV VG */
--- LVM2/lib/metadata/mirror.c 2007/12/22 12:13:29 1.51
+++ LVM2/lib/metadata/mirror.c 2008/01/10 18:35:50 1.52
@@ -134,13 +134,34 @@
return 1;
}
+static int _merge_mirror_images(struct logical_volume *lv,
+ const struct list *mimages)
+{
+ uint32_t addition = list_size(mimages);
+ struct logical_volume **img_lvs;
+ struct lv_list *lvl;
+ int i = 0;
+
+ if (!addition)
+ return 1;
+
+ if (!(img_lvs = alloca(sizeof(*img_lvs) * addition)))
+ return_0;
+
+ list_iterate_items(lvl, mimages)
+ img_lvs[i++] = lvl->lv;
+
+ return lv_add_mirror_lvs(lv, img_lvs, addition,
+ MIRROR_IMAGE, first_seg(lv)->region_size);
+}
+
/*
* Remove num_removed images from mirrored_seg
*/
static int _remove_mirror_images(struct logical_volume *lv,
uint32_t num_removed,
struct list *removable_pvs,
- unsigned remove_log, struct list *orphan_lvs)
+ unsigned remove_log, unsigned collapse)
{
uint32_t m;
uint32_t s, s1;
@@ -162,9 +183,16 @@
old_area_count, old_area_count - num_removed,
remove_log ? " and no log volume" : "");
+ if (collapse &&
+ (removable_pvs || (old_area_count - num_removed != 1))) {
+ log_error("Incompatible parameters to _remove_mirror_images");
+ return 0;
+ }
+
/* Move removable_pvs to end of array */
if (removable_pvs) {
- for (s = 0; s < mirrored_seg->area_count; s++) {
+ for (s = 0; s < mirrored_seg->area_count &&
+ old_area_count - new_area_count < num_removed; s++) {
all_pvs_removable = 1;
sub_lv = seg_lv(mirrored_seg, s);
list_iterate_items(seg, &sub_lv->segments) {
@@ -197,11 +225,8 @@
mirrored_seg->areas[new_area_count] = mirrored_seg->areas[s];
mirrored_seg->areas[s] = area;
}
- /* Found enough matches? */
- if (old_area_count - new_area_count == num_removed)
- break;
}
- if (old_area_count == new_area_count) {
+ if (num_removed && old_area_count == new_area_count) {
log_error("No mirror images found using specified PVs.");
return 0;
}
@@ -235,7 +260,12 @@
lv->status &= ~MIRRORED;
lv->status &= ~MIRROR_NOTSYNCED;
remove_log = 1;
- }
+ if (collapse && !_merge_mirror_images(lv, &tmp_orphan_lvs)) {
+ log_error("Failed to add mirror images");
+ return 0;
+ }
+ } else if (remove_log)
+ mirrored_seg->log_lv = NULL;
if (remove_log && log_lv) {
log_lv->status &= ~MIRROR_LOG;
@@ -272,11 +302,7 @@
}
/* Save or delete the 'orphan' LVs */
- if (orphan_lvs) {
- *orphan_lvs = tmp_orphan_lvs;
- orphan_lvs->n->p = orphan_lvs;
- orphan_lvs->p->n = orphan_lvs;
- } else {
+ if (!collapse) {
list_iterate_items(lvl, &tmp_orphan_lvs)
if (!_delete_lv(lv, lvl->lv))
return 0;
@@ -302,18 +328,19 @@
num_removed = existing_mirrors - num_mirrors;
- while (num_removed) {
+ /* num_removed can be 0 if the function is called just to remove log */
+ do {
if (num_removed < first_seg(lv)->area_count)
removed_once = num_removed;
else
removed_once = first_seg(lv)->area_count - 1;
if (!_remove_mirror_images(lv, removed_once,
- removable_pvs, remove_log, NULL))
+ removable_pvs, remove_log, 0))
return_0;
num_removed -= removed_once;
- }
+ } while (num_removed);
return 1;
}
@@ -334,27 +361,6 @@
return 0;
}
-static int _merge_mirror_images(struct logical_volume *lv,
- const struct list *mimages)
-{
- uint32_t addition = list_size(mimages);
- struct logical_volume **img_lvs;
- struct lv_list *lvl;
- int i = 0;
-
- if (!addition)
- return 1;
-
- if (!(img_lvs = alloca(sizeof(*img_lvs) * addition)))
- return_0;
-
- list_iterate_items(lvl, mimages)
- img_lvs[i++] = lvl->lv;
-
- return lv_add_mirror_lvs(lv, img_lvs, addition,
- MIRROR_IMAGE, first_seg(lv)->region_size);
-}
-
/*
* Return a temporary LV for resyncing added mirror image.
* Add other mirror legs to lvs list.
@@ -390,7 +396,6 @@
int collapse_mirrored_lv(struct logical_volume *lv)
{
struct logical_volume *tmp_lv, *parent_lv;
- struct list lvlist;
while ((tmp_lv = _find_tmp_mirror(lv))) {
parent_lv = find_parent_for_layer(lv, tmp_lv);
@@ -400,18 +405,12 @@
return 1;
}
- list_init(&lvlist);
if (!_remove_mirror_images(parent_lv,
first_seg(parent_lv)->area_count - 1,
- NULL, 1, &lvlist)) {
+ NULL, 1, 1)) {
log_error("Failed to release mirror images");
return 0;
}
-
- if (!_merge_mirror_images(parent_lv, &lvlist)) {
- log_error("Failed to add mirror images");
- return 0;
- }
}
return 1;
@@ -1277,6 +1276,13 @@
return 0;
}
+ /* For corelog mirror, activation code depends on
+ * the global mirror_in_sync status. As we are adding
+ * a new mirror, it should be set as 'out-of-sync'
+ * so that the sync starts. */
+ if (!log_count)
+ init_mirror_in_sync(0);
+
if (flags & MIRROR_BY_SEG) {
if (log_count) {
log_error("Persistent log is not supported on "
--- LVM2/lib/report/columns.h 2007/12/14 21:53:02 1.26
+++ LVM2/lib/report/columns.h 2008/01/10 18:35:51 1.27
@@ -33,6 +33,7 @@
FIELD(LVS, lv, NUM, "Snap%", lvid, 6, snpercent, "snap_percent", "For snapshots, the percentage full if LV is active.")
FIELD(LVS, lv, NUM, "Copy%", lvid, 6, copypercent, "copy_percent", "For mirrors and pvmove, current percentage in-sync.")
FIELD(LVS, lv, STR, "Move", lvid, 4, movepv, "move_pv", "For pvmove, Source PV of temporary LV created by pvmove")
+FIELD(LVS, lv, STR, "Convert", lvid, 7, convertlv, "convert_lv", "For lvconvert, Name of temporary LV created by lvconvert")
FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, "lv_tags", "Tags, if any.")
FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, "mirror_log", "For mirrors, the LV holding the synchronisation log.")
FIELD(LVS, lv, STR, "Modules", lvid, 7, modules, "modules", "Kernel device-mapper modules required for this LV.")
--- LVM2/lib/report/report.c 2007/12/22 02:12:59 1.70
+++ LVM2/lib/report/report.c 2008/01/10 18:35:51 1.71
@@ -272,7 +272,7 @@
return dm_report_field_uint64(rh, field, &_minusone);
}
-static int _lv_mimage_in_sync(struct logical_volume *lv)
+static int _lv_mimage_in_sync(const struct logical_volume *lv)
{
float percent;
struct lv_segment *seg = first_seg(lv);
@@ -306,6 +306,8 @@
if (lv->status & PVMOVE)
repstr[0] = 'p';
+ else if (lv->status & CONVERTING)
+ repstr[0] = 'c';
else if (lv->status & MIRRORED) {
if (lv->status & MIRROR_NOTSYNCED)
repstr[0] = 'M';
@@ -548,6 +550,32 @@
return 1;
}
+static int _convertlv_disp(struct dm_report *rh, struct dm_pool *mem __attribute((unused)),
+ struct dm_report_field *field,
+ const void *data, void *private __attribute((unused)))
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+ const char *name = NULL;
+ struct lv_segment *seg;
+
+ if (lv->status & CONVERTING) {
+ if (lv->status & MIRRORED) {
+ seg = first_seg(lv);
+
+ /* Temporary mirror is always area_num == 0 */
+ if (seg_type(seg, 0) == AREA_LV &&
+ is_temporary_mirror_layer(seg_lv(seg, 0)))
+ name = seg_lv(seg, 0)->name;
+ }
+ }
+
+ if (name)
+ return dm_report_field_string(rh, field, &name);
+
+ dm_report_field_set_value(field, "", NULL);
+ return 1;
+}
+
static int _size32_disp(struct dm_report *rh __attribute((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
--- LVM2/man/lvs.8 2007/12/22 02:12:59 1.7
+++ LVM2/man/lvs.8 2008/01/10 18:35:51 1.8
@@ -47,7 +47,8 @@
.RS
.IP 1 3
Volume type: (m)irrored, (M)irrored without initial sync, (o)rigin, (p)vmove, (s)napshot,
-invalid (S)napshot, (v)irtual, mirror (i)mage, mirror (I)mage out-of-sync
+invalid (S)napshot, (v)irtual, mirror (i)mage, mirror (I)mage out-of-sync,
+under (c)onversion
.IP 2 3
Permissions: (w)riteable, (r)ead-only
.IP 3 3
@@ -82,6 +83,7 @@
of 1000 (S.I.) instead of 1024. Can also specify custom (u)nits e.g.
\-\-units 3M
.SH SEE ALSO
+.BR lvm (8),
.BR lvdisplay (8),
.BR pvs (8),
.BR vgs (8)
--- LVM2/man/pvs.8 2007/01/18 22:33:24 1.3
+++ LVM2/man/pvs.8 2008/01/10 18:35:51 1.4
@@ -58,6 +58,7 @@
of 1000 (S.I.) instead of 1024. Can also specify custom (u)nits e.g.
\-\-units 3M
.SH SEE ALSO
+.BR lvm (8),
.BR pvdisplay (8),
.BR lvs (8),
.BR vgs (8)
--- LVM2/man/vgs.8 2007/03/27 13:35:33 1.5
+++ LVM2/man/vgs.8 2008/01/10 18:35:51 1.6
@@ -71,6 +71,7 @@
of 1000 (S.I.) instead of 1024. Can also specify custom (u)nits e.g.
\-\-units 3M
.SH SEE ALSO
+.BR lvm (8),
.BR vgdisplay (8),
.BR pvs (8),
.BR lvs (8)
--- LVM2/tools/lvchange.c 2007/12/05 19:24:32 1.84
+++ LVM2/tools/lvchange.c 2008/01/10 18:35:51 1.85
@@ -106,6 +106,8 @@
{
int activate;
const char *pvname;
+ char *lv_full_name;
+ uint32_t len;
activate = arg_uint_value(cmd, available_ARG, 0);
@@ -158,6 +160,18 @@
pvname);
pvmove_poll(cmd, pvname, 1);
}
+
+ if (lv->status & CONVERTING) {
+ len = strlen(lv->vg->name) + strlen(lv->name) + 2;
+ if (!(lv_full_name = alloca(len)))
+ return_0;
+ if (!dm_snprintf(lv_full_name, len, "%s/%s",
+ lv->vg->name, lv->name))
+ return_0;
+ log_verbose("Spawning background lvconvert process for %s",
+ lv->name);
+ lvconvert_poll(cmd, lv_full_name, 1);
+ }
}
return 1;
--- LVM2/tools/lvconvert.c 2007/12/22 12:13:29 1.52
+++ LVM2/tools/lvconvert.c 2008/01/10 18:35:51 1.53
@@ -270,6 +270,8 @@
return 0;
}
+ lv->status &= ~CONVERTING;
+
log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
if (!vg_write(vg))
@@ -307,8 +309,8 @@
.finish_copy = _finish_lvconvert_mirror,
};
-static int _lvconvert_poll(struct cmd_context *cmd, const char *lv_name,
- unsigned background)
+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");
@@ -370,7 +372,8 @@
existing_mirrors = lv_mirror_count(lv);
/* 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) &&
+ !arg_count(cmd, corelog_ARG)) {
lp->wait_daemon = 1;
return 1;
}
@@ -496,7 +499,8 @@
lp->pvh, lp->alloc))
return_0;
} else if (seg->log_lv && corelog) {
- if (!remove_mirror_log(cmd, lv, lp->pvh))
+ if (!remove_mirror_log(cmd, lv,
+ lp->pv_count ? lp->pvh : NULL))
return_0;
} else {
/* No change */
@@ -511,25 +515,46 @@
"without initial resync");
return 0;
}
- /* FIXME: can't have multiple mlogs. force corelog. */
- corelog = 1;
- if (!_insert_lvconvert_layer(cmd, lv)) {
+ /*
+ * Log addition/removal should be done before the layer
+ * insertion to make the end result consistent with
+ * linear-to-mirror conversion.
+ */
+ if (!seg->log_lv && !corelog) {
+ if (!add_mirror_log(cmd, lv, 1,
+ adjusted_mirror_region_size(
+ lv->vg->extent_size,
+ lv->le_count,
+ lp->region_size),
+ lp->pvh, lp->alloc))
+ return_0;
+ } else if (seg->log_lv && corelog) {
+ if (!remove_mirror_log(cmd, lv,
+ lp->pv_count ? lp->pvh : NULL))
+ return_0;
+ }
+ /* Insert a temporary layer for syncing,
+ * only if the original lv is using disk log. */
+ if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
log_error("Failed to insert resync layer");
return 0;
}
+ /* FIXME: can't have multiple mlogs. force corelog. */
if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
adjusted_mirror_region_size(
lv->vg->extent_size,
lv->le_count,
lp->region_size),
- corelog ? 0U : 1U, lp->pvh, lp->alloc,
+ 0U, lp->pvh, lp->alloc,
MIRROR_BY_LV))
return_0;
+ lv->status |= CONVERTING;
lp->wait_daemon = 1;
} else {
/* Reduce number of mirrors */
if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
- 0, lp->pv_count ? lp->pvh : NULL, 0))
+ corelog ? 1U : 0U,
+ lp->pv_count ? lp->pvh : NULL, 0))
return_0;
}
@@ -681,6 +706,7 @@
struct lv_list *lvl;
struct lvconvert_params lp;
int ret = ECMD_FAILED;
+ struct lvinfo info;
if (!_read_params(&lp, cmd, argc, argv)) {
stack;
@@ -714,8 +740,14 @@
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);
+ if (ret == ECMD_PROCESSED && lp.wait_daemon) {
+ if (!lv_info(cmd, lvl->lv, &info, 1, 0) || !info.exists) {
+ log_print("Conversion starts after activation");
+ return ret;
+ }
+ ret = lvconvert_poll(cmd, lp.lv_name_full,
+ arg_count(cmd, background_ARG) ? 1U : 0);
+ }
+
return ret;
}
--- LVM2/tools/tools.h 2007/11/09 16:51:54 1.59
+++ LVM2/tools/tools.h 2008/01/10 18:35:51 1.60
@@ -165,5 +165,6 @@
const char *command_name(struct cmd_context *cmd);
int pvmove_poll(struct cmd_context *cmd, const char *pv, unsigned background);
+int lvconvert_poll(struct cmd_context *cmd, const char *lv_name, unsigned background);
#endif
More information about the lvm-devel
mailing list