4 * Copyright (C) 2008,2009 Red Hat, Inc. All rights reserved.
6 * This file is part of LVM2.
8 * This copyrighted material is made available to anyone wishing to use,
9 * modify, copy, or redistribute it subject to the terms and conditions
10 * of the GNU Lesser General Public License v.2.1.
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program; if not, write to the Free Software Foundation,
14 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 #include "toolcontext.h"
20 #include "metadata-exported.h"
23 #include "lvm-string.h"
30 vg_t
lvm_vg_create(lvm_t libh
, const char *vg_name
)
32 struct volume_group
*vg
;
34 vg
= vg_create((struct cmd_context
*)libh
, vg_name
);
35 /* FIXME: error handling is still TBD */
36 if (vg_read_error(vg
)) {
44 int lvm_vg_extend(vg_t vg
, const char *device
)
46 struct pvcreate_params pp
;
48 if (vg_read_error(vg
))
51 if (!vg_check_write_mode(vg
))
54 if (!lock_vol(vg
->cmd
, VG_ORPHANS
, LCK_VG_WRITE
)) {
55 log_error("Can't get lock for orphan PVs");
59 pvcreate_params_set_defaults(&pp
);
60 if (!vg_extend(vg
, 1, (char **) &device
, &pp
)) {
61 unlock_vg(vg
->cmd
, VG_ORPHANS
);
65 * FIXME: Either commit to disk, or keep holding VG_ORPHANS and
66 * release in lvm_vg_close().
68 unlock_vg(vg
->cmd
, VG_ORPHANS
);
72 int lvm_vg_reduce(vg_t vg
, const char *device
)
74 if (vg_read_error(vg
))
76 if (!vg_check_write_mode(vg
))
79 if (!vg_reduce(vg
, (char *)device
))
84 int lvm_vg_set_extent_size(vg_t vg
, uint32_t new_size
)
86 if (vg_read_error(vg
))
88 if (!vg_check_write_mode(vg
))
91 if (!vg_set_extent_size(vg
, new_size
))
96 int lvm_vg_write(vg_t vg
)
100 if (vg_read_error(vg
))
102 if (!vg_check_write_mode(vg
))
105 if (dm_list_empty(&vg
->pvs
)) {
111 if (! dm_list_empty(&vg
->removed_pvs
)) {
112 if (!lock_vol(vg
->cmd
, VG_ORPHANS
, LCK_VG_WRITE
)) {
113 log_error("Can't get lock for orphan PVs");
121 /* Store VG on disk(s) */
122 if (!vg_write(vg
) || !vg_commit(vg
))
125 if (! dm_list_empty(&vg
->removed_pvs
)) {
126 dm_list_iterate_items(pvl
, &vg
->removed_pvs
) {
127 pv_write_orphan(vg
->cmd
, pvl
->pv
);
128 /* FIXME: do pvremove / label_remove()? */
130 dm_list_init(&vg
->removed_pvs
);
131 unlock_vg(vg
->cmd
, VG_ORPHANS
);
137 int lvm_vg_close(vg_t vg
)
139 if (vg_read_error(vg
) == FAILED_LOCKING
)
142 unlock_and_release_vg(vg
->cmd
, vg
, vg
->name
);
146 int lvm_vg_remove(vg_t vg
)
148 if (vg_read_error(vg
))
150 if (!vg_check_write_mode(vg
))
153 if (!vg_remove_check(vg
))
159 vg_t
lvm_vg_open(lvm_t libh
, const char *vgname
, const char *mode
,
162 uint32_t internal_flags
= 0;
163 struct volume_group
*vg
;
165 if (!strncmp(mode
, "w", 1))
166 internal_flags
|= READ_FOR_UPDATE
;
167 else if (strncmp(mode
, "r", 1)) {
168 log_errno(EINVAL
, "Invalid VG open mode");
172 vg
= vg_read((struct cmd_context
*)libh
, vgname
, NULL
, internal_flags
);
173 if (vg_read_error(vg
)) {
174 /* FIXME: use log_errno either here in inside vg_read */
178 /* FIXME: combine this with locking ? */
179 vg
->open_mode
= mode
[0];
184 struct dm_list
*lvm_vg_list_pvs(vg_t vg
)
186 struct dm_list
*list
;
190 if (dm_list_empty(&vg
->pvs
))
193 if (!(list
= dm_pool_zalloc(vg
->vgmem
, sizeof(*list
)))) {
194 log_errno(ENOMEM
, "Memory allocation fail for dm_list.");
199 dm_list_iterate_items(pvl
, &vg
->pvs
) {
200 if (!(pvs
= dm_pool_zalloc(vg
->vgmem
, sizeof(*pvs
)))) {
202 "Memory allocation fail for lvm_pv_list.");
206 dm_list_add(list
, &pvs
->list
);
211 struct dm_list
*lvm_vg_list_lvs(vg_t vg
)
213 struct dm_list
*list
;
217 if (dm_list_empty(&vg
->lvs
))
220 if (!(list
= dm_pool_zalloc(vg
->vgmem
, sizeof(*list
)))) {
221 log_errno(ENOMEM
, "Memory allocation fail for dm_list.");
226 dm_list_iterate_items(lvl
, &vg
->lvs
) {
227 if (!(lvs
= dm_pool_zalloc(vg
->vgmem
, sizeof(*lvs
)))) {
229 "Memory allocation fail for lvm_lv_list.");
233 dm_list_add(list
, &lvs
->list
);
238 uint64_t lvm_vg_get_seqno(const vg_t vg
)
243 uint64_t lvm_vg_is_clustered(const vg_t vg
)
245 return vg_is_clustered(vg
);
248 uint64_t lvm_vg_is_exported(const vg_t vg
)
250 return vg_is_exported(vg
);
253 uint64_t lvm_vg_is_partial(const vg_t vg
)
255 return (vg_missing_pv_count(vg
) != 0);
258 /* FIXME: invalid handle? return INTMAX? */
259 uint64_t lvm_vg_get_size(const vg_t vg
)
264 uint64_t lvm_vg_get_free_size(const vg_t vg
)
269 uint64_t lvm_vg_get_extent_size(const vg_t vg
)
271 return vg_extent_size(vg
);
274 uint64_t lvm_vg_get_extent_count(const vg_t vg
)
276 return vg_extent_count(vg
);
279 uint64_t lvm_vg_get_free_extent_count(const vg_t vg
)
281 return vg_free_count(vg
);
284 uint64_t lvm_vg_get_pv_count(const vg_t vg
)
286 return vg_pv_count(vg
);
289 uint64_t lvm_vg_get_max_pv(const vg_t vg
)
291 return vg_max_pv(vg
);
294 uint64_t lvm_vg_get_max_lv(const vg_t vg
)
296 return vg_max_lv(vg
);
299 char *lvm_vg_get_uuid(const vg_t vg
)
301 char uuid
[64] __attribute((aligned(8)));
303 if (!id_write_format(&vg
->id
, uuid
, sizeof(uuid
))) {
304 log_error("Internal error converting uuid");
307 return strndup((const char *)uuid
, 64);
310 char *lvm_vg_get_name(const vg_t vg
)
314 name
= dm_malloc(NAME_LEN
+ 1);
315 strncpy(name
, (const char *)vg
->name
, NAME_LEN
);
316 name
[NAME_LEN
] = '\0';
321 * FIXME: These functions currently return hidden VGs. We should either filter
322 * these out and not return them in the list, or export something like
323 * is_orphan_vg and tell the caller to filter.
325 struct dm_list
*lvm_list_vg_names(lvm_t libh
)
327 return get_vgnames((struct cmd_context
*)libh
, 0);
330 struct dm_list
*lvm_list_vg_uuids(lvm_t libh
)
332 return get_vgids((struct cmd_context
*)libh
, 0);
336 * FIXME: Elaborate on when to use, side-effects, .cache file, etc
338 int lvm_scan(lvm_t libh
)
340 if (!lvmcache_label_scan((struct cmd_context
*)libh
, 2))