1 /*	$NetBSD: import.c,v 1.1.1.1 2008/12/22 00:18:16 haad Exp $	*/
2 
3 /*
4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5  * Copyright (C) 2004-2008 Red Hat, Inc. All rights reserved.
6  *
7  * This file is part of LVM2.
8  *
9  * This copyrighted material is made available to anyone wishing to use,
10  * modify, copy, or redistribute it subject to the terms and conditions
11  * of the GNU Lesser General Public License v.2.1.
12  *
13  * You should have received a copy of the GNU Lesser General Public License
14  * along with this program; if not, write to the Free Software Foundation,
15  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16  */
17 
18 #include "lib.h"
19 #include "metadata.h"
20 #include "import-export.h"
21 #include "display.h"
22 #include "toolcontext.h"
23 #include "lvmcache.h"
24 
25 /* FIXME Use tidier inclusion method */
26 static struct text_vg_version_ops *(_text_vsn_list[2]);
27 
28 static int _text_import_initialised = 0;
29 
30 static void _init_text_import()
31 {
32 	if (_text_import_initialised)
33 		return;
34 
35 	_text_vsn_list[0] = text_vg_vsn1_init();
36 	_text_vsn_list[1] = NULL;
37 	_text_import_initialised = 1;
38 }
39 
40 const char *text_vgname_import(const struct format_type *fmt,
41 			       struct device *dev,
42 			       off_t offset, uint32_t size,
43 			       off_t offset2, uint32_t size2,
44 			       checksum_fn_t checksum_fn, uint32_t checksum,
45 			       struct id *vgid, uint32_t *vgstatus,
46 			       char **creation_host)
47 {
48 	struct config_tree *cft;
49 	struct text_vg_version_ops **vsn;
50 	const char *vgname = NULL;
51 
52 	_init_text_import();
53 
54 	if (!(cft = create_config_tree(NULL, 0)))
55 		return_NULL;
56 
57 	if ((!dev && !read_config_file(cft)) ||
58 	    (dev && !read_config_fd(cft, dev, offset, size,
59 				    offset2, size2, checksum_fn, checksum)))
60 		goto_out;
61 
62 	/*
63 	 * Find a set of version functions that can read this file
64 	 */
65 	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
66 		if (!(*vsn)->check_version(cft))
67 			continue;
68 
69 		if (!(vgname = (*vsn)->read_vgname(fmt, cft, vgid, vgstatus,
70 						   creation_host)))
71 			goto_out;
72 
73 		break;
74 	}
75 
76       out:
77 	destroy_config_tree(cft);
78 	return vgname;
79 }
80 
81 struct volume_group *text_vg_import_fd(struct format_instance *fid,
82 				       const char *file,
83 				       struct device *dev,
84 				       off_t offset, uint32_t size,
85 				       off_t offset2, uint32_t size2,
86 				       checksum_fn_t checksum_fn,
87 				       uint32_t checksum,
88 				       time_t *when, char **desc)
89 {
90 	struct volume_group *vg = NULL;
91 	struct config_tree *cft;
92 	struct text_vg_version_ops **vsn;
93 
94 	_init_text_import();
95 
96 	*desc = NULL;
97 	*when = 0;
98 
99 	if (!(cft = create_config_tree(file, 0)))
100 		return_NULL;
101 
102 	if ((!dev && !read_config_file(cft)) ||
103 	    (dev && !read_config_fd(cft, dev, offset, size,
104 				    offset2, size2, checksum_fn, checksum))) {
105 		log_error("Couldn't read volume group metadata.");
106 		goto out;
107 	}
108 
109 	/*
110 	 * Find a set of version functions that can read this file
111 	 */
112 	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
113 		if (!(*vsn)->check_version(cft))
114 			continue;
115 
116 		if (!(vg = (*vsn)->read_vg(fid, cft)))
117 			goto_out;
118 
119 		(*vsn)->read_desc(fid->fmt->cmd->mem, cft, when, desc);
120 		break;
121 	}
122 
123       out:
124 	destroy_config_tree(cft);
125 	return vg;
126 }
127 
128 struct volume_group *text_vg_import_file(struct format_instance *fid,
129 					 const char *file,
130 					 time_t *when, char **desc)
131 {
132 	return text_vg_import_fd(fid, file, NULL, (off_t)0, 0, (off_t)0, 0, NULL, 0,
133 				 when, desc);
134 }
135 
136 struct volume_group *import_vg_from_buffer(char *buf,
137                                            struct format_instance *fid)
138 {
139 	struct volume_group *vg = NULL;
140 	struct config_tree *cft;
141 	struct text_vg_version_ops **vsn;
142 
143 	_init_text_import();
144 
145 	if (!(cft = create_config_tree_from_string(fid->fmt->cmd, buf)))
146 		return_NULL;
147 
148 	for (vsn = &_text_vsn_list[0]; *vsn; vsn++) {
149 		if (!(*vsn)->check_version(cft))
150 			continue;
151 		if (!(vg = (*vsn)->read_vg(fid, cft)))
152 			stack;
153 		break;
154 	}
155 
156 	destroy_config_tree(cft);
157 	return vg;
158 }
159