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