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

[lvm-devel] [PATCH, v3] unknown segment types



Hi again,

I have done some changes to the patch, namely (we have discussed those with
Alasdair on IRC):

Wed Oct  7 22:25:28 CEST 2009  Petr Rockai <me mornfall net>
  * Move filtering logic from export to import, cleaning up code a bit.
Wed Oct  7 22:09:05 CEST 2009  Petr Rockai <me mornfall net>
  * Get rid of a global variable (use batons instead).
Wed Oct  7 22:08:22 CEST 2009  Petr Rockai <me mornfall net>
  * Improve log_warn message (unknown -> unrecognised).

Dave, this patch should apply cleanly to CVS as of *right now*. I don't know
about the previous one.

Yours,
   Petr.

Wed Oct  7 22:47:59 CEST 2009  Petr Rockai <me mornfall net>
  * Resolve conflicts.
Wed Oct  7 22:25:28 CEST 2009  Petr Rockai <me mornfall net>
  * Move filtering logic from export to import, cleaning up code a bit.
Wed Oct  7 22:09:05 CEST 2009  Petr Rockai <me mornfall net>
  * Get rid of a global variable (use batons instead).
Wed Oct  7 22:08:22 CEST 2009  Petr Rockai <me mornfall net>
  * Improve log_warn message (unknown -> unrecognised).
Tue Jul 21 16:37:39 CEST 2009  Petr Rockai <me mornfall net>
  * Prevent (most) commands from touching VGs with unknown segments.
Tue Jul 21 15:15:46 CEST 2009  Petr Rockai <me mornfall net>
  * Avoid bad memory access.
Tue Jul 21 15:15:38 CEST 2009  Petr Rockai <me mornfall net>
  * Flag unknown segment types.
Tue Jul 21 15:15:17 CEST 2009  Petr Rockai <me mornfall net>
  * Fix bug in test script for unknown segtype.
Sun Jul 19 18:22:52 CEST 2009  Petr Rockai <me mornfall net>
  * First iteration of unknown segment handler.
diff -rN -u -p old-unknown-segtype_rebase/lib/commands/toolcontext.c new-unknown-segtype_rebase/lib/commands/toolcontext.c
--- old-unknown-segtype_rebase/lib/commands/toolcontext.c	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/commands/toolcontext.c	2009-10-07 22:48:21.000000000 +0200
@@ -1085,6 +1085,7 @@ struct cmd_context *create_toolcontext(u
 	memset(cmd, 0, sizeof(*cmd));
 	cmd->is_long_lived = is_long_lived;
 	cmd->handles_missing_pvs = 0;
+	cmd->handles_unknown_segments = 0;
 	cmd->hosttags = 0;
 	dm_list_init(&cmd->formats);
 	dm_list_init(&cmd->segtypes);
diff -rN -u -p old-unknown-segtype_rebase/lib/commands/toolcontext.h new-unknown-segtype_rebase/lib/commands/toolcontext.h
--- old-unknown-segtype_rebase/lib/commands/toolcontext.h	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/commands/toolcontext.h	2009-10-07 22:48:21.000000000 +0200
@@ -69,6 +69,7 @@ struct cmd_context {
 	char **argv;
 	unsigned is_long_lived:1;	/* Optimises persistent_filter handling */
 	unsigned handles_missing_pvs:1;
+	unsigned handles_unknown_segments:1;
 	unsigned partial_activation:1;
 	unsigned si_unit_consistency:1;
 
diff -rN -u -p old-unknown-segtype_rebase/lib/config/config.c new-unknown-segtype_rebase/lib/config/config.c
--- old-unknown-segtype_rebase/lib/config/config.c	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/config/config.c	2009-10-07 22:48:21.000000000 +0200
@@ -71,6 +71,8 @@ struct cs {
 struct output_line {
 	FILE *fp;
 	struct dm_pool *mem;
+	putline_fn putline;
+	void *putline_baton;
 };
 
 static void _get_token(struct parser *p, int tok_prev);
@@ -80,8 +82,8 @@ static struct config_node *_section(stru
 static struct config_value *_value(struct parser *p);
 static struct config_value *_type(struct parser *p);
 static int _match_aux(struct parser *p, int t);
-static struct config_value *_create_value(struct parser *p);
-static struct config_node *_create_node(struct parser *p);
+static struct config_value *_create_value(struct dm_pool *mem);
+static struct config_node *_create_node(struct dm_pool *mem);
 static char *_dup_tok(struct parser *p);
 
 static const int sep = '/';
@@ -403,10 +405,14 @@ static int _line_end(struct output_line 
 	}
 
 	line = dm_pool_end_object(outline->mem);
-	if (!outline->fp)
-		log_print("%s", line);
-	else
-		fprintf(outline->fp, "%s\n", line);
+	if (outline->putline)
+		outline->putline(line, outline->putline_baton);
+	else {
+		if (!outline->fp)
+			log_print("%s", line);
+		else
+			fprintf(outline->fp, "%s\n", line);
+	}
 
 	return 1;
 }
@@ -498,6 +504,21 @@ static int _write_config(struct config_n
 	return 1;
 }
 
+int write_config_node(struct config_node *cn, putline_fn putline, void *baton)
+{
+	struct output_line outline;
+	outline.fp = NULL;
+	outline.mem = dm_pool_create("config_line", 1024);
+	outline.putline = putline;
+	outline.putline_baton = baton;
+	if (!_write_config(cn, 0, &outline, 0)) {
+		dm_pool_destroy(outline.mem);
+		return_0;
+	}
+	dm_pool_destroy(outline.mem);
+	return 1;
+}
+
 int write_config_file(struct config_tree *cft, const char *file,
 		      int argc, char **argv)
 {
@@ -505,6 +526,7 @@ int write_config_file(struct config_tree
 	int r = 1;
 	struct output_line outline;
 	outline.fp = NULL;
+	outline.putline = NULL;
 
 	if (!file)
 		file = "stdout";
@@ -567,7 +589,7 @@ static struct config_node *_section(stru
 {
 	/* IDENTIFIER SECTION_B_CHAR VALUE* SECTION_E_CHAR */
 	struct config_node *root, *n, *l = NULL;
-	if (!(root = _create_node(p)))
+	if (!(root = _create_node(p->mem)))
 		return_0;
 
 	if (!(root->key = _dup_tok(p)))
@@ -622,7 +644,7 @@ static struct config_value *_value(struc
 		 * Special case for an empty array.
 		 */
 		if (!h) {
-			if (!(h = _create_value(p)))
+			if (!(h = _create_value(p->mem)))
 				return NULL;
 
 			h->type = CFG_EMPTY_ARRAY;
@@ -637,7 +659,7 @@ static struct config_value *_value(struc
 static struct config_value *_type(struct parser *p)
 {
 	/* [+-]{0,1}[0-9]+ | [0-9]*\.[0-9]* | ".*" */
-	struct config_value *v = _create_value(p);
+	struct config_value *v = _create_value(p->mem);
 
 	if (!v)
 		return NULL;
@@ -833,9 +855,9 @@ static void _eat_space(struct parser *p)
 /*
  * memory management
  */
-static struct config_value *_create_value(struct parser *p)
+static struct config_value *_create_value(struct dm_pool *mem)
 {
-	struct config_value *v = dm_pool_alloc(p->mem, sizeof(*v));
+	struct config_value *v = dm_pool_alloc(mem, sizeof(*v));
 
 	if (v)
 		memset(v, 0, sizeof(*v));
@@ -843,9 +865,9 @@ static struct config_value *_create_valu
 	return v;
 }
 
-static struct config_node *_create_node(struct parser *p)
+static struct config_node *_create_node(struct dm_pool *mem)
 {
-	struct config_node *n = dm_pool_alloc(p->mem, sizeof(*n));
+	struct config_node *n = dm_pool_alloc(mem, sizeof(*n));
 
 	if (n)
 		memset(n, 0, sizeof(*n));
@@ -1297,3 +1319,33 @@ unsigned maybe_config_section(const char
 	else
 		return 0;
 }
+
+static struct config_value *_clone_config_value(struct dm_pool *mem, const struct config_value *v)
+{
+	if (!v)
+		return NULL;
+	struct config_value *new = _create_value(mem);
+	new->type = v->type;
+	if (v->type == CFG_STRING)
+		new->v.str = dm_pool_strdup(mem, v->v.str);
+	else
+		new->v = v->v;
+	new->next = _clone_config_value(mem, v->next);
+	return new;
+}
+
+struct config_node *clone_config_node(struct dm_pool *mem, const struct config_node *cn,
+				      int siblings)
+{
+	if (!cn)
+		return NULL;
+	struct config_node *new = _create_node(mem);
+	new->key = dm_pool_strdup(mem, cn->key);
+	new->child = clone_config_node(mem, cn->child, 1);
+	new->v = _clone_config_value(mem, cn->v);
+	if (siblings)
+		new->sib = clone_config_node(mem, cn->sib, siblings);
+	else
+		new->sib = NULL;
+	return new;
+}
diff -rN -u -p old-unknown-segtype_rebase/lib/config/config.h new-unknown-segtype_rebase/lib/config/config.h
--- old-unknown-segtype_rebase/lib/config/config.h	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/config/config.h	2009-10-07 22:48:21.000000000 +0200
@@ -69,6 +69,10 @@ int read_config_fd(struct config_tree *c
 int read_config_file(struct config_tree *cft);
 int write_config_file(struct config_tree *cft, const char *file,
 		      int argc, char **argv);
+
+typedef int (*putline_fn)(const char *line, void *baton);
+int write_config_node(struct config_node *cn, putline_fn putline, void *baton);
+
 time_t config_file_timestamp(struct config_tree *cft);
 int config_file_changed(struct config_tree *cft);
 int merge_config_tree(struct cmd_context *cmd, struct config_tree *cft,
@@ -114,4 +118,6 @@ unsigned maybe_config_section(const char
 
 const char *config_parent_name(const struct config_node *n);
 
+struct config_node *clone_config_node(struct dm_pool *mem, const struct config_node *cn,
+				      int siblings);
 #endif
diff -rN -u -p old-unknown-segtype_rebase/lib/format_text/export.c new-unknown-segtype_rebase/lib/format_text/export.c
--- old-unknown-segtype_rebase/lib/format_text/export.c	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/format_text/export.c	2009-10-07 22:48:21.000000000 +0200
@@ -293,6 +293,16 @@ int out_text(struct formatter *f, const 
 	return r;
 }
 
+static int _out_line(const char *line, void *_f) {
+	struct formatter *f = (struct formatter *) _f;
+	return out_text(f, "%s", line);
+}
+
+int out_config_node(struct formatter *f, const struct config_node *cn)
+{
+	return write_config_node(cn, _out_line, f);
+}
+
 static int _print_header(struct formatter *f,
 			 const char *desc)
 {
diff -rN -u -p old-unknown-segtype_rebase/lib/format_text/text_export.h new-unknown-segtype_rebase/lib/format_text/text_export.h
--- old-unknown-segtype_rebase/lib/format_text/text_export.h	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/format_text/text_export.h	2009-10-07 22:48:21.000000000 +0200
@@ -21,6 +21,7 @@
 
 struct formatter;
 struct lv_segment;
+struct config_node;
 
 int out_size(struct formatter *f, uint64_t size, const char *fmt, ...)
     __attribute__ ((format(printf, 3, 4)));
@@ -31,6 +32,8 @@ int out_hint(struct formatter *f, const 
 int out_text(struct formatter *f, const char *fmt, ...)
     __attribute__ ((format(printf, 2, 3)));
 
+int out_config_node(struct formatter *f, const struct config_node *cn);
+
 int out_areas(struct formatter *f, const struct lv_segment *seg,
 	      const char *type);
 
diff -rN -u -p old-unknown-segtype_rebase/lib/Makefile.in new-unknown-segtype_rebase/lib/Makefile.in
--- old-unknown-segtype_rebase/lib/Makefile.in	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/Makefile.in	2009-10-07 22:48:21.000000000 +0200
@@ -47,6 +47,7 @@ SOURCES =\
 	device/device.c \
 	display/display.c \
 	error/errseg.c \
+	unknown/unknown.c \
 	filters/filter-composite.c \
 	filters/filter-persistent.c \
 	filters/filter-regex.c \
diff -rN -u -p old-unknown-segtype_rebase/lib/metadata/metadata.c new-unknown-segtype_rebase/lib/metadata/metadata.c
--- old-unknown-segtype_rebase/lib/metadata/metadata.c	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/metadata/metadata.c	2009-10-07 22:48:21.000000000 +0200
@@ -23,6 +23,7 @@
 #include "memlock.h"
 #include "str_list.h"
 #include "pv_alloc.h"
+#include "segtype.h"
 #include "activate.h"
 #include "display.h"
 #include "locking.h"
@@ -738,6 +739,23 @@ static struct volume_group *_vg_make_han
 	return (struct volume_group *)vg;
 }
 
+int vg_has_unknown_segments(const struct volume_group *vg)
+{
+	struct lv_list *lvl;
+	struct lv_segment *seg;
+
+	/* foreach LV */
+	dm_list_iterate_items(lvl, &vg->lvs) {
+		/* foreach segment */
+		dm_list_iterate_items(seg, &lvl->lv->segments) {
+			if (seg_unknown(seg))
+				return 1;
+		}
+
+	}
+	return 0;
+}
+
 /*
  * Create a VG with default parameters.
  * Returns:
@@ -2192,6 +2210,13 @@ int vg_write(struct volume_group *vg)
 		return 0;
 	}
 
+	if (vg_has_unknown_segments(vg) && !vg->cmd->handles_unknown_segments) {
+		log_error("Cannot update volume group %s with unknown segments in it!",
+			  vg->name);
+		return 0;
+	}
+
+
 	if (dm_list_empty(&vg->fid->metadata_areas)) {
 		log_error("Aborting vg_write: No metadata areas to write to!");
 		return 0;
@@ -3317,6 +3342,11 @@ static struct volume_group *_vg_lock_and
 		}
 	}
 
+	/*
+	 * Check that the tool can handle tricky cases -- missing PVs and
+	 * unknown segment types.
+	 */
+
 	if (!cmd->handles_missing_pvs && vg_missing_pv_count(vg) &&
 	    (lock_flags & LCK_WRITE)) {
 		log_error("Cannot change VG %s while PVs are missing!",
@@ -3325,6 +3355,14 @@ static struct volume_group *_vg_lock_and
 		goto_bad;
 	}
 
+	if (!cmd->handles_unknown_segments && vg_has_unknown_segments(vg) &&
+	    (lock_flags & LCK_WRITE)) {
+		log_error("Cannot change VG %s with unknown segments in it!",
+			  vg->name);
+		failure |= FAILED_INCONSISTENT; /* FIXME new failure code here? */
+		goto_bad;
+	}
+
 	failure |= _vg_bad_status_bits(vg, status_flags);
 	if (failure)
 		goto_bad;
diff -rN -u -p old-unknown-segtype_rebase/lib/metadata/metadata-exported.h new-unknown-segtype_rebase/lib/metadata/metadata-exported.h
--- old-unknown-segtype_rebase/lib/metadata/metadata-exported.h	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/metadata/metadata-exported.h	2009-10-07 22:48:21.000000000 +0200
@@ -298,6 +298,7 @@ struct lv_segment {
 	uint32_t region_size;	/* For mirrors - in sectors */
 	uint32_t extents_copied;
 	struct logical_volume *log_lv;
+	void *segtype_private;
 
 	struct dm_list tags;
 
@@ -734,6 +735,8 @@ int vg_check_write_mode(struct volume_gr
 #define vg_is_exported(vg) (vg_status((vg)) & EXPORTED_VG)
 #define vg_is_resizeable(vg) (vg_status((vg)) & RESIZEABLE_VG)
 
+int vg_has_unknown_segments(const struct volume_group *vg);
+
 struct vgcreate_params {
 	char *vg_name;
 	uint32_t extent_size;
diff -rN -u -p old-unknown-segtype_rebase/lib/metadata/segtype.c new-unknown-segtype_rebase/lib/metadata/segtype.c
--- old-unknown-segtype_rebase/lib/metadata/segtype.c	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/metadata/segtype.c	2009-10-07 22:48:21.000000000 +0200
@@ -27,6 +27,11 @@ struct segment_type *get_segtype_from_st
 			return segtype;
 	}
 
-	log_error("Unrecognised segment type %s", str);
-	return NULL;
+	if (!(segtype = init_unknown_segtype(cmd, str)))
+		return_NULL;
+
+	segtype->library = NULL;
+	dm_list_add(&cmd->segtypes, &segtype->list);
+	log_warn("WARNING: Unrecognised segment type %s", str);
+	return segtype;
 }
diff -rN -u -p old-unknown-segtype_rebase/lib/metadata/segtype.h new-unknown-segtype_rebase/lib/metadata/segtype.h
--- old-unknown-segtype_rebase/lib/metadata/segtype.h	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/lib/metadata/segtype.h	2009-10-07 22:48:21.000000000 +0200
@@ -35,6 +35,7 @@ struct dev_manager;
 #define SEG_VIRTUAL		0x00000020U
 #define SEG_CANNOT_BE_ZEROED	0x00000040U
 #define SEG_MONITORED		0x00000080U
+#define SEG_UNKNOWN		0x80000000U
 
 #define seg_is_mirrored(seg)	((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0)
 #define seg_is_striped(seg)	((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0)
@@ -43,6 +44,7 @@ struct dev_manager;
 #define seg_can_split(seg)	((seg)->segtype->flags & SEG_CAN_SPLIT ? 1 : 0)
 #define seg_cannot_be_zeroed(seg) ((seg)->segtype->flags & SEG_CANNOT_BE_ZEROED ? 1 : 0)
 #define seg_monitored(seg)	((seg)->segtype->flags & SEG_MONITORED ? 1 : 0)
+#define seg_unknown(seg)	((seg)->segtype->flags & SEG_UNKNOWN ? 1 : 0)
 
 #define segtype_is_striped(segtype)	((segtype)->flags & SEG_AREAS_STRIPED ? 1 : 0)
 #define segtype_is_mirrored(segtype)	((segtype)->flags & SEG_AREAS_MIRRORED ? 1 : 0)
@@ -105,6 +107,7 @@ struct segment_type *init_striped_segtyp
 struct segment_type *init_zero_segtype(struct cmd_context *cmd);
 struct segment_type *init_error_segtype(struct cmd_context *cmd);
 struct segment_type *init_free_segtype(struct cmd_context *cmd);
+struct segment_type *init_unknown_segtype(struct cmd_context *cmd, const char *name);
 
 #ifdef SNAPSHOT_INTERNAL
 struct segment_type *init_snapshot_segtype(struct cmd_context *cmd);
diff -rN -u -p old-unknown-segtype_rebase/lib/unknown/unknown.c new-unknown-segtype_rebase/lib/unknown/unknown.c
--- old-unknown-segtype_rebase/lib/unknown/unknown.c	1970-01-01 01:00:00.000000000 +0100
+++ new-unknown-segtype_rebase/lib/unknown/unknown.c	2009-10-07 22:48:21.000000000 +0200
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of LVM2.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "lib.h"
+#include "toolcontext.h"
+#include "segtype.h"
+#include "display.h"
+#include "text_export.h"
+#include "text_import.h"
+#include "config.h"
+#include "str_list.h"
+#include "targets.h"
+#include "lvm-string.h"
+#include "activate.h"
+#include "str_list.h"
+#include "metadata.h"
+
+static const char *_unknown_name(const struct lv_segment *seg)
+{
+
+	return seg->segtype->name;
+}
+
+static int _unknown_text_import(struct lv_segment *seg, const struct config_node *sn,
+				struct dm_hash_table *pv_hash)
+{
+	struct config_node *new, *last = NULL, *current, *head = NULL;
+	log_verbose("importing unknown segment");
+	for (current = sn; current != NULL; current = current->sib) {
+		if (!strcmp(current->key, "type") || !strcmp(current->key, "start_extent") ||
+		    !strcmp(current->key, "tags") || !strcmp(current->key, "extent_count"))
+			continue;
+		new = clone_config_node(seg->lv->vg->vgmem, current, 0);
+		if (!new)
+			return_0;
+		if (last)
+			last->sib = new;
+		if (!head)
+			head = new;
+		last = new;
+	}
+	seg->segtype_private = head;
+	return 1;
+}
+
+static int _unknown_text_export(const struct lv_segment *seg, struct formatter *f)
+{
+	struct config_node *cn = seg->segtype_private;
+	return out_config_node(f, cn);
+}
+
+#ifdef DEVMAPPER_SUPPORT
+static int _unknown_add_target_line(struct dev_manager *dm __attribute((unused)),
+				struct dm_pool *mem __attribute((unused)),
+				struct cmd_context *cmd __attribute((unused)),
+				void **target_state __attribute((unused)),
+				struct lv_segment *seg __attribute((unused)),
+				struct dm_tree_node *node, uint64_t len,
+				uint32_t *pvmove_mirror_count __attribute((unused)))
+{
+	return dm_tree_node_add_error_target(node, len);
+}
+#endif
+
+static void _unknown_destroy(const struct segment_type *segtype)
+{
+	dm_free((void *)segtype);
+}
+
+static struct segtype_handler _unknown_ops = {
+	.name = _unknown_name,
+	.text_import = _unknown_text_import,
+	.text_export = _unknown_text_export,
+#ifdef DEVMAPPER_SUPPORT
+	.add_target_line = _unknown_add_target_line,
+#endif
+	.destroy = _unknown_destroy,
+};
+
+struct segment_type *init_unknown_segtype(struct cmd_context *cmd, const char *name)
+{
+	struct segment_type *segtype = dm_malloc(sizeof(*segtype));
+
+	if (!segtype)
+		return_NULL;
+
+	segtype->cmd = cmd;
+	segtype->ops = &_unknown_ops;
+	segtype->name = dm_pool_strdup(cmd->mem, name);
+	segtype->private = NULL;
+	segtype->flags = SEG_UNKNOWN | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
+
+	log_very_verbose("Initialised segtype: %s", segtype->name);
+
+	return segtype;
+}
diff -rN -u -p old-unknown-segtype_rebase/test/t-unknown-segment.sh new-unknown-segtype_rebase/test/t-unknown-segment.sh
--- old-unknown-segtype_rebase/test/t-unknown-segment.sh	1970-01-01 01:00:00.000000000 +0100
+++ new-unknown-segtype_rebase/test/t-unknown-segment.sh	2009-10-07 22:48:21.000000000 +0200
@@ -0,0 +1,31 @@
+#!/bin/sh
+# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+
+. ./test-utils.sh
+
+aux prepare_vg 4
+
+lvcreate -l 1 -n $lv1 $vg
+lvcreate -l 2 -m 1 -n $lv2 $vg
+
+vgcfgbackup -f bak0
+sed -e 's,striped,unstriped,;s,mirror,unmirror,' -i.orig bak0
+vgcfgrestore -f bak0 $vg
+
+vgcfgbackup -f bak1
+cat bak1
+sed -e 's,unstriped,striped,;s,unmirror,mirror,' -i.orig bak1
+vgcfgrestore -f bak1 $vg
+vgcfgbackup -f bak2
+
+egrep -v 'description|seqno|creation_time' < bak0.orig > a
+egrep -v 'description|seqno|creation_time' < bak2 > b
+diff -u a b
diff -rN -u -p old-unknown-segtype_rebase/tools/vgcfgrestore.c new-unknown-segtype_rebase/tools/vgcfgrestore.c
--- old-unknown-segtype_rebase/tools/vgcfgrestore.c	2009-10-07 22:48:21.000000000 +0200
+++ new-unknown-segtype_rebase/tools/vgcfgrestore.c	2009-10-07 22:48:21.000000000 +0200
@@ -56,6 +56,8 @@ int vgcfgrestore(struct cmd_context *cmd
 		return ECMD_FAILED;
 	}
 
+	cmd->handles_unknown_segments = 1;
+
 	if (!(arg_count(cmd, file_ARG) ?
 	      backup_restore_from_file(cmd, vg_name,
 				       arg_str_value(cmd, file_ARG, "")) :

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