]>
Commit | Line | Data |
---|---|---|
930a1434 DW |
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" | |
930a1434 | 16 | #include "toolcontext.h" |
d01a6a2c | 17 | #include "metadata.h" |
930a1434 DW |
18 | #include "archiver.h" |
19 | #include "locking.h" | |
fe63e644 | 20 | #include "lvmcache.h" |
a8ab5867 | 21 | #include "lvm_misc.h" |
8961b1d5 | 22 | #include "lvm2app.h" |
bae6bc62 | 23 | |
a8ab5867 DW |
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 | ||
7510963f | 52 | vg_t lvm_vg_create(lvm_t libh, const char *vg_name) |
930a1434 | 53 | { |
7510963f | 54 | struct volume_group *vg; |
f6ffb81b DW |
55 | |
56 | vg = vg_create((struct cmd_context *)libh, vg_name); | |
57 | /* FIXME: error handling is still TBD */ | |
58 | if (vg_read_error(vg)) { | |
077a6755 | 59 | release_vg(vg); |
f6ffb81b DW |
60 | return NULL; |
61 | } | |
afcd9399 | 62 | vg->open_mode = 'w'; |
7510963f | 63 | return (vg_t) vg; |
930a1434 DW |
64 | } |
65 | ||
7510963f | 66 | int lvm_vg_extend(vg_t vg, const char *device) |
930a1434 | 67 | { |
c24a4ff2 DW |
68 | struct pvcreate_params pp; |
69 | ||
930a1434 | 70 | if (vg_read_error(vg)) |
f864285b | 71 | return -1; |
930a1434 | 72 | |
afcd9399 DW |
73 | if (!vg_check_write_mode(vg)) |
74 | return -1; | |
75 | ||
0b7cc76a DW |
76 | if (!lock_vol(vg->cmd, VG_ORPHANS, LCK_VG_WRITE)) { |
77 | log_error("Can't get lock for orphan PVs"); | |
f864285b | 78 | return -1; |
0b7cc76a DW |
79 | } |
80 | ||
accb1738 | 81 | pvcreate_params_set_defaults(&pp); |
aec21154 | 82 | if (!vg_extend(vg, 1, &device, &pp)) { |
0b7cc76a | 83 | unlock_vg(vg->cmd, VG_ORPHANS); |
f864285b | 84 | return -1; |
0b7cc76a DW |
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); | |
f864285b | 91 | return 0; |
930a1434 DW |
92 | } |
93 | ||
7510963f | 94 | int lvm_vg_reduce(vg_t vg, const char *device) |
dfe213f8 DW |
95 | { |
96 | if (vg_read_error(vg)) | |
97 | return -1; | |
afcd9399 DW |
98 | if (!vg_check_write_mode(vg)) |
99 | return -1; | |
dfe213f8 | 100 | |
aec21154 | 101 | if (!vg_reduce(vg, device)) |
dfe213f8 DW |
102 | return -1; |
103 | return 0; | |
104 | } | |
105 | ||
7510963f | 106 | int lvm_vg_set_extent_size(vg_t vg, uint32_t new_size) |
930a1434 DW |
107 | { |
108 | if (vg_read_error(vg)) | |
f864285b | 109 | return -1; |
afcd9399 DW |
110 | if (!vg_check_write_mode(vg)) |
111 | return -1; | |
930a1434 | 112 | |
9e7b0091 | 113 | if (!vg_set_extent_size(vg, new_size / SECTOR_SIZE)) |
f864285b | 114 | return -1; |
930a1434 DW |
115 | return 0; |
116 | } | |
117 | ||
7510963f | 118 | int lvm_vg_write(vg_t vg) |
930a1434 | 119 | { |
dfe213f8 DW |
120 | struct pv_list *pvl; |
121 | ||
930a1434 | 122 | if (vg_read_error(vg)) |
f864285b | 123 | return -1; |
afcd9399 DW |
124 | if (!vg_check_write_mode(vg)) |
125 | return -1; | |
930a1434 | 126 | |
dfe213f8 | 127 | if (dm_list_empty(&vg->pvs)) { |
a5609e30 DW |
128 | if (!vg_remove(vg)) |
129 | return -1; | |
130 | return 0; | |
dfe213f8 DW |
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 | ||
f864285b DW |
140 | if (!archive(vg)) |
141 | return -1; | |
930a1434 DW |
142 | |
143 | /* Store VG on disk(s) */ | |
f864285b DW |
144 | if (!vg_write(vg) || !vg_commit(vg)) |
145 | return -1; | |
dfe213f8 DW |
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); | |
2c67b829 | 150 | pv_set_fid(pvl->pv, NULL); |
dfe213f8 DW |
151 | /* FIXME: do pvremove / label_remove()? */ |
152 | } | |
153 | dm_list_init(&vg->removed_pvs); | |
154 | unlock_vg(vg->cmd, VG_ORPHANS); | |
155 | } | |
156 | ||
930a1434 DW |
157 | return 0; |
158 | } | |
159 | ||
7510963f | 160 | int lvm_vg_close(vg_t vg) |
930a1434 | 161 | { |
8a68d954 | 162 | if (vg_read_error(vg) == FAILED_LOCKING) |
077a6755 | 163 | release_vg(vg); |
8a68d954 | 164 | else |
077a6755 | 165 | unlock_and_release_vg(vg->cmd, vg, vg->name); |
f864285b | 166 | return 0; |
930a1434 DW |
167 | } |
168 | ||
7510963f | 169 | int lvm_vg_remove(vg_t vg) |
930a1434 DW |
170 | { |
171 | if (vg_read_error(vg)) | |
f864285b | 172 | return -1; |
afcd9399 DW |
173 | if (!vg_check_write_mode(vg)) |
174 | return -1; | |
930a1434 | 175 | |
d50795ed DW |
176 | if (!vg_remove_check(vg)) |
177 | return -1; | |
178 | ||
40b4d1c3 DW |
179 | vg_remove_pvs(vg); |
180 | ||
930a1434 DW |
181 | return 0; |
182 | } | |
729f472c | 183 | |
7510963f | 184 | vg_t lvm_vg_open(lvm_t libh, const char *vgname, const char *mode, |
729f472c DW |
185 | uint32_t flags) |
186 | { | |
187 | uint32_t internal_flags = 0; | |
7510963f | 188 | struct volume_group *vg; |
729f472c DW |
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 */ | |
077a6755 | 200 | release_vg(vg); |
729f472c DW |
201 | return NULL; |
202 | } | |
afcd9399 DW |
203 | /* FIXME: combine this with locking ? */ |
204 | vg->open_mode = mode[0]; | |
729f472c | 205 | |
7510963f | 206 | return (vg_t) vg; |
729f472c | 207 | } |
6c6c8214 | 208 | |
7510963f | 209 | struct dm_list *lvm_vg_list_pvs(vg_t vg) |
6c6c8214 DW |
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)))) { | |
df621aa3 | 219 | log_errno(ENOMEM, "Memory allocation fail for dm_list."); |
6c6c8214 DW |
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)))) { | |
a57262a7 | 226 | log_errno(ENOMEM, |
df621aa3 | 227 | "Memory allocation fail for lvm_pv_list."); |
6c6c8214 DW |
228 | return NULL; |
229 | } | |
230 | pvs->pv = pvl->pv; | |
231 | dm_list_add(list, &pvs->list); | |
232 | } | |
233 | return list; | |
234 | } | |
235 | ||
7510963f | 236 | struct dm_list *lvm_vg_list_lvs(vg_t vg) |
6c6c8214 DW |
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)))) { | |
df621aa3 | 246 | log_errno(ENOMEM, "Memory allocation fail for dm_list."); |
6c6c8214 DW |
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)))) { | |
a57262a7 | 253 | log_errno(ENOMEM, |
df621aa3 | 254 | "Memory allocation fail for lvm_lv_list."); |
6c6c8214 DW |
255 | return NULL; |
256 | } | |
257 | lvs->lv = lvl->lv; | |
258 | dm_list_add(list, &lvs->list); | |
259 | } | |
260 | return list; | |
261 | } | |
f032ed74 | 262 | |
a8ab5867 DW |
263 | struct dm_list *lvm_vg_get_tags(const vg_t vg) |
264 | { | |
265 | return tag_list_copy(vg->vgmem, &vg->tags); | |
266 | } | |
267 | ||
7510963f | 268 | uint64_t lvm_vg_get_seqno(const vg_t vg) |
9ac1af71 DW |
269 | { |
270 | return vg_seqno(vg); | |
271 | } | |
272 | ||
fca43425 DW |
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 | ||
83f25cd1 | 288 | /* FIXME: invalid handle? return INTMAX? */ |
7510963f | 289 | uint64_t lvm_vg_get_size(const vg_t vg) |
83f25cd1 | 290 | { |
9e7b0091 | 291 | return SECTOR_SIZE * vg_size(vg); |
83f25cd1 DW |
292 | } |
293 | ||
7510963f | 294 | uint64_t lvm_vg_get_free_size(const vg_t vg) |
83f25cd1 | 295 | { |
9e7b0091 | 296 | return SECTOR_SIZE * vg_free(vg); |
83f25cd1 DW |
297 | } |
298 | ||
7510963f | 299 | uint64_t lvm_vg_get_extent_size(const vg_t vg) |
83f25cd1 | 300 | { |
9e7b0091 | 301 | return SECTOR_SIZE * vg_extent_size(vg); |
83f25cd1 DW |
302 | } |
303 | ||
7510963f | 304 | uint64_t lvm_vg_get_extent_count(const vg_t vg) |
83f25cd1 DW |
305 | { |
306 | return vg_extent_count(vg); | |
307 | } | |
308 | ||
7510963f | 309 | uint64_t lvm_vg_get_free_extent_count(const vg_t vg) |
83f25cd1 DW |
310 | { |
311 | return vg_free_count(vg); | |
312 | } | |
313 | ||
7510963f | 314 | uint64_t lvm_vg_get_pv_count(const vg_t vg) |
83f25cd1 DW |
315 | { |
316 | return vg_pv_count(vg); | |
8c794666 DW |
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); | |
83f25cd1 DW |
327 | } |
328 | ||
298ec21e | 329 | const char *lvm_vg_get_uuid(const vg_t vg) |
f032ed74 | 330 | { |
254d672d | 331 | return vg_uuid_dup(vg); |
f032ed74 DW |
332 | } |
333 | ||
298ec21e | 334 | const char *lvm_vg_get_name(const vg_t vg) |
f032ed74 | 335 | { |
298ec21e | 336 | return dm_pool_strndup(vg->vgmem, (const char *)vg->name, NAME_LEN+1); |
f032ed74 | 337 | } |
122ccd0d | 338 | |
3c1febe0 DW |
339 | |
340 | struct lvm_property_value lvm_vg_get_property(const vg_t vg, const char *name) | |
341 | { | |
55429cde | 342 | return get_property(NULL, vg, NULL, NULL, NULL, name); |
3c1febe0 DW |
343 | } |
344 | ||
eeaf3ba7 PR |
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 | ||
122ccd0d DW |
351 | struct dm_list *lvm_list_vg_names(lvm_t libh) |
352 | { | |
38220f9f | 353 | return get_vgnames((struct cmd_context *)libh, 0); |
122ccd0d DW |
354 | } |
355 | ||
1efda0fb | 356 | struct dm_list *lvm_list_vg_uuids(lvm_t libh) |
122ccd0d | 357 | { |
38220f9f | 358 | return get_vgids((struct cmd_context *)libh, 0); |
122ccd0d | 359 | } |
fe63e644 | 360 | |
5e824754 DW |
361 | /* |
362 | * FIXME: Elaborate on when to use, side-effects, .cache file, etc | |
363 | */ | |
2572832e | 364 | int lvm_scan(lvm_t libh) |
fe63e644 | 365 | { |
f864285b DW |
366 | if (!lvmcache_label_scan((struct cmd_context *)libh, 2)) |
367 | return -1; | |
368 | return 0; | |
fe63e644 | 369 | } |