]> sourceware.org Git - lvm2.git/blob - liblvm/lvm_vg.c
Refer to details of snapshot of raid problem.
[lvm2.git] / liblvm / lvm_vg.c
1 /*
2 * Copyright (C) 2008,2009 Red Hat, Inc. All rights reserved.
3 *
4 * This file is part of LVM2.
5 *
6 * This copyrighted material is made available to anyone wishing to use,
7 * modify, copy, or redistribute it subject to the terms and conditions
8 * of the GNU Lesser General Public License v.2.1.
9 *
10 * You should have received a copy of the GNU Lesser General Public License
11 * along with this program; if not, write to the Free Software Foundation,
12 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
13 */
14
15 #include "lib.h"
16 #include "toolcontext.h"
17 #include "metadata.h"
18 #include "archiver.h"
19 #include "locking.h"
20 #include "lvmcache.h"
21 #include "lvm_misc.h"
22 #include "lvm2app.h"
23
24 int lvm_vg_add_tag(vg_t vg, const char *tag)
25 {
26 if (vg_read_error(vg))
27 return -1;
28
29 if (!vg_check_write_mode(vg))
30 return -1;
31
32 if (!vg_change_tag(vg, tag, 1))
33 return -1;
34 return 0;
35 }
36
37
38 int lvm_vg_remove_tag(vg_t vg, const char *tag)
39 {
40 if (vg_read_error(vg))
41 return -1;
42
43 if (!vg_check_write_mode(vg))
44 return -1;
45
46 if (!vg_change_tag(vg, tag, 0))
47 return -1;
48 return 0;
49 }
50
51
52 vg_t lvm_vg_create(lvm_t libh, const char *vg_name)
53 {
54 struct volume_group *vg;
55
56 vg = vg_create((struct cmd_context *)libh, vg_name);
57 /* FIXME: error handling is still TBD */
58 if (vg_read_error(vg)) {
59 release_vg(vg);
60 return NULL;
61 }
62 vg->open_mode = 'w';
63 return (vg_t) vg;
64 }
65
66 int lvm_vg_extend(vg_t vg, const char *device)
67 {
68 struct pvcreate_params pp;
69
70 if (vg_read_error(vg))
71 return -1;
72
73 if (!vg_check_write_mode(vg))
74 return -1;
75
76 if (!lock_vol(vg->cmd, VG_ORPHANS, LCK_VG_WRITE)) {
77 log_error("Can't get lock for orphan PVs");
78 return -1;
79 }
80
81 pvcreate_params_set_defaults(&pp);
82 if (!vg_extend(vg, 1, &device, &pp)) {
83 unlock_vg(vg->cmd, VG_ORPHANS);
84 return -1;
85 }
86 /*
87 * FIXME: Either commit to disk, or keep holding VG_ORPHANS and
88 * release in lvm_vg_close().
89 */
90 unlock_vg(vg->cmd, VG_ORPHANS);
91 return 0;
92 }
93
94 int lvm_vg_reduce(vg_t vg, const char *device)
95 {
96 if (vg_read_error(vg))
97 return -1;
98 if (!vg_check_write_mode(vg))
99 return -1;
100
101 if (!vg_reduce(vg, device))
102 return -1;
103 return 0;
104 }
105
106 int lvm_vg_set_extent_size(vg_t vg, uint32_t new_size)
107 {
108 if (vg_read_error(vg))
109 return -1;
110 if (!vg_check_write_mode(vg))
111 return -1;
112
113 if (!vg_set_extent_size(vg, new_size / SECTOR_SIZE))
114 return -1;
115 return 0;
116 }
117
118 int lvm_vg_write(vg_t vg)
119 {
120 struct pv_list *pvl;
121
122 if (vg_read_error(vg))
123 return -1;
124 if (!vg_check_write_mode(vg))
125 return -1;
126
127 if (dm_list_empty(&vg->pvs)) {
128 if (!vg_remove(vg))
129 return -1;
130 return 0;
131 }
132
133 if (! dm_list_empty(&vg->removed_pvs)) {
134 if (!lock_vol(vg->cmd, VG_ORPHANS, LCK_VG_WRITE)) {
135 log_error("Can't get lock for orphan PVs");
136 return 0;
137 }
138 }
139
140 if (!archive(vg))
141 return -1;
142
143 /* Store VG on disk(s) */
144 if (!vg_write(vg) || !vg_commit(vg))
145 return -1;
146
147 if (! dm_list_empty(&vg->removed_pvs)) {
148 dm_list_iterate_items(pvl, &vg->removed_pvs) {
149 pv_write_orphan(vg->cmd, pvl->pv);
150 pv_set_fid(pvl->pv, NULL);
151 /* FIXME: do pvremove / label_remove()? */
152 }
153 dm_list_init(&vg->removed_pvs);
154 unlock_vg(vg->cmd, VG_ORPHANS);
155 }
156
157 return 0;
158 }
159
160 int lvm_vg_close(vg_t vg)
161 {
162 if (vg_read_error(vg) == FAILED_LOCKING)
163 release_vg(vg);
164 else
165 unlock_and_release_vg(vg->cmd, vg, vg->name);
166 return 0;
167 }
168
169 int lvm_vg_remove(vg_t vg)
170 {
171 if (vg_read_error(vg))
172 return -1;
173 if (!vg_check_write_mode(vg))
174 return -1;
175
176 if (!vg_remove_check(vg))
177 return -1;
178
179 vg_remove_pvs(vg);
180
181 return 0;
182 }
183
184 vg_t lvm_vg_open(lvm_t libh, const char *vgname, const char *mode,
185 uint32_t flags)
186 {
187 uint32_t internal_flags = 0;
188 struct volume_group *vg;
189
190 if (!strncmp(mode, "w", 1))
191 internal_flags |= READ_FOR_UPDATE;
192 else if (strncmp(mode, "r", 1)) {
193 log_errno(EINVAL, "Invalid VG open mode");
194 return NULL;
195 }
196
197 vg = vg_read((struct cmd_context *)libh, vgname, NULL, internal_flags);
198 if (vg_read_error(vg)) {
199 /* FIXME: use log_errno either here in inside vg_read */
200 release_vg(vg);
201 return NULL;
202 }
203 /* FIXME: combine this with locking ? */
204 vg->open_mode = mode[0];
205
206 return (vg_t) vg;
207 }
208
209 struct dm_list *lvm_vg_list_pvs(vg_t vg)
210 {
211 struct dm_list *list;
212 pv_list_t *pvs;
213 struct pv_list *pvl;
214
215 if (dm_list_empty(&vg->pvs))
216 return NULL;
217
218 if (!(list = dm_pool_zalloc(vg->vgmem, sizeof(*list)))) {
219 log_errno(ENOMEM, "Memory allocation fail for dm_list.");
220 return NULL;
221 }
222 dm_list_init(list);
223
224 dm_list_iterate_items(pvl, &vg->pvs) {
225 if (!(pvs = dm_pool_zalloc(vg->vgmem, sizeof(*pvs)))) {
226 log_errno(ENOMEM,
227 "Memory allocation fail for lvm_pv_list.");
228 return NULL;
229 }
230 pvs->pv = pvl->pv;
231 dm_list_add(list, &pvs->list);
232 }
233 return list;
234 }
235
236 struct dm_list *lvm_vg_list_lvs(vg_t vg)
237 {
238 struct dm_list *list;
239 lv_list_t *lvs;
240 struct lv_list *lvl;
241
242 if (dm_list_empty(&vg->lvs))
243 return NULL;
244
245 if (!(list = dm_pool_zalloc(vg->vgmem, sizeof(*list)))) {
246 log_errno(ENOMEM, "Memory allocation fail for dm_list.");
247 return NULL;
248 }
249 dm_list_init(list);
250
251 dm_list_iterate_items(lvl, &vg->lvs) {
252 if (!(lvs = dm_pool_zalloc(vg->vgmem, sizeof(*lvs)))) {
253 log_errno(ENOMEM,
254 "Memory allocation fail for lvm_lv_list.");
255 return NULL;
256 }
257 lvs->lv = lvl->lv;
258 dm_list_add(list, &lvs->list);
259 }
260 return list;
261 }
262
263 struct dm_list *lvm_vg_get_tags(const vg_t vg)
264 {
265 return tag_list_copy(vg->vgmem, &vg->tags);
266 }
267
268 uint64_t lvm_vg_get_seqno(const vg_t vg)
269 {
270 return vg_seqno(vg);
271 }
272
273 uint64_t lvm_vg_is_clustered(const vg_t vg)
274 {
275 return vg_is_clustered(vg);
276 }
277
278 uint64_t lvm_vg_is_exported(const vg_t vg)
279 {
280 return vg_is_exported(vg);
281 }
282
283 uint64_t lvm_vg_is_partial(const vg_t vg)
284 {
285 return (vg_missing_pv_count(vg) != 0);
286 }
287
288 /* FIXME: invalid handle? return INTMAX? */
289 uint64_t lvm_vg_get_size(const vg_t vg)
290 {
291 return SECTOR_SIZE * vg_size(vg);
292 }
293
294 uint64_t lvm_vg_get_free_size(const vg_t vg)
295 {
296 return SECTOR_SIZE * vg_free(vg);
297 }
298
299 uint64_t lvm_vg_get_extent_size(const vg_t vg)
300 {
301 return SECTOR_SIZE * vg_extent_size(vg);
302 }
303
304 uint64_t lvm_vg_get_extent_count(const vg_t vg)
305 {
306 return vg_extent_count(vg);
307 }
308
309 uint64_t lvm_vg_get_free_extent_count(const vg_t vg)
310 {
311 return vg_free_count(vg);
312 }
313
314 uint64_t lvm_vg_get_pv_count(const vg_t vg)
315 {
316 return vg_pv_count(vg);
317 }
318
319 uint64_t lvm_vg_get_max_pv(const vg_t vg)
320 {
321 return vg_max_pv(vg);
322 }
323
324 uint64_t lvm_vg_get_max_lv(const vg_t vg)
325 {
326 return vg_max_lv(vg);
327 }
328
329 const char *lvm_vg_get_uuid(const vg_t vg)
330 {
331 return vg_uuid_dup(vg);
332 }
333
334 const char *lvm_vg_get_name(const vg_t vg)
335 {
336 return dm_pool_strndup(vg->vgmem, (const char *)vg->name, NAME_LEN+1);
337 }
338
339
340 struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name)
341 {
342 return get_property(NULL, vg, NULL, NULL, NULL, name);
343 }
344
345 int lvm_vg_set_property(const vg_t vg, const char *name,
346 struct lvm_property_value *value)
347 {
348 return set_property(NULL, vg, NULL, name, value);
349 }
350
351 struct dm_list *lvm_list_vg_names(lvm_t libh)
352 {
353 return get_vgnames((struct cmd_context *)libh, 0);
354 }
355
356 struct dm_list *lvm_list_vg_uuids(lvm_t libh)
357 {
358 return get_vgids((struct cmd_context *)libh, 0);
359 }
360
361 /*
362 * FIXME: Elaborate on when to use, side-effects, .cache file, etc
363 */
364 int lvm_scan(lvm_t libh)
365 {
366 if (!lvmcache_label_scan((struct cmd_context *)libh, 2))
367 return -1;
368 return 0;
369 }
This page took 0.051658 seconds and 5 git commands to generate.