[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

[lvm-devel] [PATCH] (3/11) introduce vg_read_for_update



Hi,

this is mostly the initial implementation of vg_read_for_update, that will
later be used for most cases where vg_read is called with the intention of
updating the VG and writing it out again. Implies various requirements that
updates usually have.

Yours,
   Petr.

PS: I have noticed a slight forward-dependence of this patch -- ORPHAN_LOCK is
defined I believe in one of the later patches.

Tue Oct 14 14:41:10 CEST 2008  Petr Rockai <me mornfall net>
  * Do not require LVM_WRITE flag when opening orphan VG for update.
Tue Sep 30 23:35:37 CEST 2008  me mornfall net
  * Allow opening orphan VGs through vg_lock_and_read.
Sat Jul 12 13:26:05 CEST 2008  me mornfall net
  * Get rid of spurious log_error.
Sat Jul 12 11:55:46 CEST 2008  me mornfall net
  * When EXISTENCE_CHECK is given, we do not attempt auto-recovery.
Sat Jul 12 11:55:11 CEST 2008  me mornfall net
  * Use goto_bad in vg_lock_and_read, to avoid missed unlocks.
Sat Jul 12 11:55:06 CEST 2008  me mornfall net
  * Implement vg_read_for_update, first go.
Sat Jul 12 11:24:28 CEST 2008  me mornfall net
  * Make CORRECT_INCONSISTENT default if VG is locked for writing in vg_lock_and_read. Set INCONSISTENT_VG if read-only and no FAIL_INCONSISTENT was given.
Thu Oct 30 18:09:46 CET 2008  Petr Rockai <me mornfall net>
  tagged base 8-1
diff -rN -p -u old-lvmlib-b/lib/metadata/metadata.c new-lvmlib-b/lib/metadata/metadata.c
--- old-lvmlib-b/lib/metadata/metadata.c	2008-10-30 18:13:09.377836370 +0100
+++ new-lvmlib-b/lib/metadata/metadata.c	2008-10-30 18:13:09.441838220 +0100
@@ -2401,8 +2401,52 @@ int vg_check_status(const struct volume_
 }
 
 /*
+ * High-level read-for-update function.
+ * Failures:
+ *  - metadata inconsistent and automatic correction failed
+ *  - VG is read-only
+ *  - VG is EXPORTED, unless flags has ALLOW_EXPORTED
+ *  - VG is not RESIZEABLE, unless flags has ALLOW_NONRESIZEABLE
+ *
+ * If EXISTENCE_CHECK is set in flags, if the VG exists, a non-NULL struct
+ * volume_group will be returned every time, but if it has INCONSISTENT_VG set,
+ * the other fields will be uninitialized. You *have to* check for
+ * INCONSISTENT_VG if passing EXISTENCE_CHECK. You also *must not* use it if it
+ * has INCONSISTENT_VG set.
+ */
+vg_t *vg_read_for_update(struct cmd_context *cmd, const char *vg_name,
+			 const char *vgid, uint32_t flags)
+{
+	uint32_t status = CLUSTERED | EXPORTED_VG | LVM_WRITE;
+	uint32_t lock = LCK_VG_WRITE;
+	uint32_t misc = FAIL_INCONSISTENT;
+
+	if (flags & ALLOW_EXPORTED)
+		status &= ~EXPORTED_VG;
+
+	if (flags & REQUIRE_RESIZEABLE)
+		status |= RESIZEABLE_VG;
+
+	if (flags & LOCK_NONBLOCK)
+		lock |= LCK_NONBLOCK;
+
+	if (flags & EXISTENCE_CHECK)
+		misc |= EXISTENCE_CHECK;
+
+	return vg_lock_and_read(cmd, vg_name, vgid, lock,
+				status, misc);
+}
+
+/*
  * vg_lock_and_read - consolidate vg locking, reading, and status flag checking
  *
+ * misc_flags:
+ *  FAIL_INCONSISTENT: treat inconsistency as failure, disables autocorrection
+ *  
+ * Not setting FAIL_INCONSISTENT and not locking for write will give you
+ * inconsistent metadata. There is no other way to get inconsistent metadata
+ * from this function. Otherwise, autocorrection will kick in.
+ *
  * Returns:
  * NULL - failure
  * non-NULL - success; volume group handle
@@ -2414,11 +2458,12 @@ vg_t *vg_lock_and_read(struct cmd_contex
 {
 	struct volume_group *vg;
 	int consistent = 1;
+	int consistent_in;
 
-	if (!(misc_flags & CORRECT_INCONSISTENT))
+	if (misc_flags & FAIL_INCONSISTENT || !(lock_flags & LCK_WRITE))
 		consistent = 0;
 
-	if (!validate_name(vg_name)) {
+	if (!validate_name(vg_name) && !is_orphan_vg(vg_name)) {
 		log_error("Volume group name %s has invalid characters",
 			  vg_name);
 		return NULL;
@@ -2429,19 +2474,33 @@ vg_t *vg_lock_and_read(struct cmd_contex
 		return NULL;
 	}
 
-	if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent)) ||
-	    ((misc_flags & FAIL_INCONSISTENT) && !consistent)) {
+	if (misc_flags & ORPHAN_LOCK)
+		status_flags &= ~LVM_WRITE;
+
+	if (misc_flags & EXISTENCE_CHECK)
+		consistent = 0;
+
+	consistent_in = consistent;
+	/* If consistent == 1, we get NULL if correction fails. */
+	if (!(vg = vg_read_internal(cmd, vg_name, vgid, &consistent))) {
+		if (((misc_flags & FAIL_INCONSISTENT) && !consistent)) {
+			if (!(misc_flags & EXISTENCE_CHECK))
+				log_error("Volume group \"%s\" inconsistent.",
+					  vg_name);
+			goto_bad;
+		}
 		log_error("Volume group \"%s\" not found", vg_name);
-		unlock_vg(cmd, vg_name);
-		return NULL;
+		vg->status |= INCONSISTENT_VG;
+		goto_bad;
 	}
 
-	if (!vg_check_status(vg, status_flags)) {
-		unlock_vg(cmd, vg_name);
-		return NULL;
-	}
+	if (!vg_check_status(vg, status_flags))
+		goto_bad;
 
 	return vg;
+ bad:
+	unlock_vg(cmd, vg_name);
+	return NULL;
 }
 
 /*
diff -rN -p -u old-lvmlib-b/lib/metadata/metadata-exported.h new-lvmlib-b/lib/metadata/metadata-exported.h
--- old-lvmlib-b/lib/metadata/metadata-exported.h	2008-10-30 18:13:09.377836370 +0100
+++ new-lvmlib-b/lib/metadata/metadata-exported.h	2008-10-30 18:13:09.437837991 +0100
@@ -82,6 +82,7 @@ struct pv_segment;
 #define LVM_WRITE             	0x00000200U	/* LV VG */
 #define CLUSTERED         	0x00000400U	/* VG */
 //#define SHARED            	0x00000800U	/* VG */
+#define INCONSISTENT_VG         0x00001000U	/* VG */
 
 /* Format features flags */
 #define FMT_SEGMENTS		0x00000001U	/* Arbitrary segment params? */
@@ -99,6 +100,12 @@ struct pv_segment;
 #define CORRECT_INCONSISTENT    0x00000001U /* Correct inconsistent metadata */
 #define FAIL_INCONSISTENT       0x00000002U /* Fail if metadata inconsistent */
 
+/* vg_read_for_update flags */
+#define ALLOW_EXPORTED 0x1
+#define REQUIRE_RESIZEABLE 0x2
+#define EXISTENCE_CHECK 0x4
+#define LOCK_NONBLOCK 0x8
+
 /* Mirror conversion type flags */
 #define MIRROR_BY_SEG		0x00000001U	/* segment-by-segment mirror */
 #define MIRROR_BY_LV		0x00000002U	/* mirror using whole mimage LVs */
@@ -348,10 +355,13 @@ int is_orphan(const pv_t *pv);
 int vgs_are_compatible(struct cmd_context *cmd,
 		       struct volume_group *vg_from,
 		       struct volume_group *vg_to);
+
 vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
 		       const char *vgid,
 		       uint32_t lock_flags, uint32_t status_flags,
 		       uint32_t misc_flags);
+vg_t *vg_read_for_update(struct cmd_context *cmd, const char *vg_name,
+			 const char *vgid, uint32_t flags);
 
 /* pe_start and pe_end relate to any existing data so that new metadata
 * areas can avoid overlap */
diff -rN -p -u old-lvmlib-b/lib/metadata/metadata.h new-lvmlib-b/lib/metadata/metadata.h
--- old-lvmlib-b/lib/metadata/metadata.h	2008-10-30 18:13:09.373837748 +0100
+++ new-lvmlib-b/lib/metadata/metadata.h	2008-10-30 18:13:09.441838220 +0100
@@ -74,6 +74,7 @@
 //#define LVM_WRITE             	0x00000200U	/* LV VG */
 //#define CLUSTERED         	0x00000400U	/* VG */
 #define SHARED            	0x00000800U	/* VG */
+//#define INCONSISTENT_VG         0x00001000U	/* VG */
 
 /* Format features flags */
 //#define FMT_SEGMENTS		0x00000001U	/* Arbitrary segment params? */

-- 
Peter Rockai | me()mornfall!net | prockai()redhat!com
 http://blog.mornfall.net | http://web.mornfall.net

"In My Egotistical Opinion, most people's C programs should be
 indented six feet downward and covered with dirt."
     -- Blair P. Houghton on the subject of C program indentation

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]