summaryrefslogtreecommitdiff
path: root/lib/unknown
diff options
context:
space:
mode:
authorPetr Rockai <prockai@redhat.com>2009-10-16 17:41:49 +0000
committerPetr Rockai <prockai@redhat.com>2009-10-16 17:41:49 +0000
commitb4048242f58910556478b01987828f3622ab92d9 (patch)
treeb1c377e8e61ec0bdd8bea5960c5f9da9b784e4fe /lib/unknown
parenta1bb606aabd89abda9312cb59cb6edc8e68da111 (diff)
downloadlvm2-b4048242f58910556478b01987828f3622ab92d9.tar.gz
Handle metadata with unknown segment types more gracefully.
Diffstat (limited to 'lib/unknown')
-rw-r--r--lib/unknown/unknown.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/lib/unknown/unknown.c b/lib/unknown/unknown.c
new file mode 100644
index 000000000..c0d3da5c9
--- /dev/null
+++ b/lib/unknown/unknown.c
@@ -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;
+}