[lvm-devel] LVM2 ./WHATS_NEW lib/metadata/metadata.c lib/m ...
agk at sourceware.org
agk at sourceware.org
Wed Feb 7 13:29:52 UTC 2007
CVSROOT: /cvs/lvm2
Module name: LVM2
Changes by: agk at sourceware.org 2007-02-07 13:29:52
Modified files:
. : WHATS_NEW
lib/metadata : metadata.c metadata.h
Log message:
If a PV reappears after it was removed from its VG, make it an orphan.
Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.569&r2=1.570
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.c.diff?cvsroot=lvm2&r1=1.102&r2=1.103
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/lib/metadata/metadata.h.diff?cvsroot=lvm2&r1=1.152&r2=1.153
--- LVM2/WHATS_NEW 2007/01/31 16:26:22 1.569
+++ LVM2/WHATS_NEW 2007/02/07 13:29:51 1.570
@@ -1,5 +1,7 @@
Version 2.02.22 -
===================================
+ If a PV reappears after it was removed from its VG, make it an orphan.
+ Don't update metadata automatically if VGIDs don't match.
Fix some vgreduce --removemissing command line validation.
Version 2.02.21 - 30th January 2007
--- LVM2/lib/metadata/metadata.c 2006/11/30 23:11:42 1.102
+++ LVM2/lib/metadata/metadata.c 2007/02/07 13:29:52 1.103
@@ -963,6 +963,30 @@
return vg;
}
+static int _update_pv_list(struct list *all_pvs, struct volume_group *vg)
+{
+ struct pv_list *pvl, *pvl2;
+
+ list_iterate_items(pvl, &vg->pvs) {
+ list_iterate_items(pvl2, all_pvs) {
+ if (pvl->pv->dev == pvl2->pv->dev)
+ goto next_pv;
+ }
+ /* PV is not on list so add it. Note that we don't copy it. */
+ if (!(pvl2 = dm_pool_zalloc(vg->cmd->mem, sizeof(*pvl2)))) {
+ log_error("pv_list allocation for '%s' failed",
+ dev_name(pvl->pv->dev));
+ return 0;
+ }
+ pvl2->pv = pvl->pv;
+ list_add(all_pvs, &pvl2->list);
+ next_pv:
+ ;
+ }
+
+ return 1;
+}
+
/* Caller sets consistent to 1 if it's safe for vg_read to correct
* inconsistent metadata on disk (i.e. the VG write lock is held).
* This guarantees only consistent metadata is returned unless PARTIAL_VG.
@@ -982,9 +1006,12 @@
struct volume_group *vg, *correct_vg = NULL;
struct metadata_area *mda;
int inconsistent = 0;
+ int inconsistent_vgid = 0;
int use_precommitted = precommitted;
struct list *pvids;
- struct pv_list *pvl;
+ struct pv_list *pvl, *pvl2;
+ struct list all_pvs;
+ char uuid[64] __attribute((aligned(8)));
if (!*vgname) {
if (use_precommitted) {
@@ -1069,6 +1096,8 @@
}
}
+ list_init(&all_pvs);
+
/* Failed to find VG where we expected it - full scan and retry */
if (!correct_vg) {
inconsistent = 0;
@@ -1104,13 +1133,25 @@
}
if (!correct_vg) {
correct_vg = vg;
+ if (!_update_pv_list(&all_pvs, correct_vg))
+ return_NULL;
continue;
}
+
+ if (strncmp((char *)vg->id.uuid,
+ (char *)correct_vg->id.uuid, ID_LEN)) {
+ inconsistent = 1;
+ inconsistent_vgid = 1;
+ }
+
/* FIXME Also ensure contents same - checksums same? */
if (correct_vg->seqno != vg->seqno) {
inconsistent = 1;
- if (vg->seqno > correct_vg->seqno)
+ if (vg->seqno > correct_vg->seqno) {
+ if (!_update_pv_list(&all_pvs, vg))
+ return_NULL;
correct_vg = vg;
+ }
}
}
@@ -1143,17 +1184,42 @@
return correct_vg;
}
- log_print("Inconsistent metadata copies found - updating "
- "to use version %u", correct_vg->seqno);
+ /* Don't touch if vgids didn't match */
+ if (inconsistent_vgid) {
+ log_error("Inconsistent metadata UUIDs found for "
+ "volume group %s", vgname);
+ *consistent = 0;
+ return correct_vg;
+ }
+
+ log_print("Inconsistent metadata found for VG %s - updating "
+ "to use version %u", vgname, correct_vg->seqno);
+
if (!vg_write(correct_vg)) {
log_error("Automatic metadata correction failed");
return NULL;
}
+
if (!vg_commit(correct_vg)) {
log_error("Automatic metadata correction commit "
"failed");
return NULL;
}
+
+ list_iterate_items(pvl, &all_pvs) {
+ list_iterate_items(pvl2, &correct_vg->pvs) {
+ if (pvl->pv->dev == pvl2->pv->dev)
+ goto next_pv;
+ }
+ if (!id_write_format(&pvl->pv->id, uuid, sizeof(uuid)))
+ return_NULL;
+ log_error("Removing PV %s (%s) that no longer belongs to VG %s",
+ dev_name(pvl->pv->dev), uuid, correct_vg->name);
+ if (!pv_write_orphan(cmd, pvl->pv))
+ return_NULL;
+ next_pv:
+ ;
+ }
}
if ((correct_vg->status & PVMOVE) && !pvmove_mode()) {
@@ -1433,3 +1499,25 @@
return 1;
}
+
+int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv)
+{
+ const char *old_vg_name = pv->vg_name;
+
+ pv->vg_name = ORPHAN;
+ pv->status = ALLOCATABLE_PV;
+
+ if (!dev_get_size(pv->dev, &pv->size)) {
+ log_error("%s: Couldn't get size.", dev_name(pv->dev));
+ return 0;
+ }
+
+ if (!pv_write(cmd, pv, NULL, INT64_C(-1))) {
+ log_error("Failed to clear metadata from physical "
+ "volume \"%s\" after removal from \"%s\"",
+ dev_name(pv->dev), old_vg_name);
+ return 0;
+ }
+
+ return 1;
+}
--- LVM2/lib/metadata/metadata.h 2006/12/13 03:39:58 1.152
+++ LVM2/lib/metadata/metadata.h 2007/02/07 13:29:52 1.153
@@ -423,6 +423,7 @@
int pv_write(struct cmd_context *cmd, struct physical_volume *pv,
struct list *mdas, int64_t label_sector);
+int pv_write_orphan(struct cmd_context *cmd, struct physical_volume *pv);
/* pe_start and pe_end relate to any existing data so that new metadata
* areas can avoid overlap */
More information about the lvm-devel
mailing list