2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3 * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
5 * This file is part of LVM2.
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.
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
21 char *vg_fmt_dup(const struct volume_group *vg)
23 if (!vg->fid || !vg->fid->fmt)
25 return dm_pool_strdup(vg->vgmem, vg->fid->fmt->name);
28 char *vg_name_dup(const struct volume_group *vg)
30 return dm_pool_strdup(vg->vgmem, vg->name);
33 char *vg_system_id_dup(const struct volume_group *vg)
35 return dm_pool_strdup(vg->vgmem, vg->system_id);
38 char *vg_uuid_dup(const struct volume_group *vg)
40 return id_format_and_copy(vg->vgmem, &vg->id);
43 char *vg_tags_dup(const struct volume_group *vg)
45 return tags_format_and_copy(vg->vgmem, &vg->tags);
48 uint32_t vg_seqno(const struct volume_group *vg)
53 uint64_t vg_status(const struct volume_group *vg)
58 uint64_t vg_size(const struct volume_group *vg)
60 return (uint64_t) vg->extent_count * vg->extent_size;
63 uint64_t vg_free(const struct volume_group *vg)
65 return (uint64_t) vg->free_count * vg->extent_size;
68 uint64_t vg_extent_size(const struct volume_group *vg)
70 return (uint64_t) vg->extent_size;
73 uint64_t vg_extent_count(const struct volume_group *vg)
75 return (uint64_t) vg->extent_count;
78 uint64_t vg_free_count(const struct volume_group *vg)
80 return (uint64_t) vg->free_count;
83 uint64_t vg_pv_count(const struct volume_group *vg)
85 return (uint64_t) vg->pv_count;
88 uint64_t vg_max_pv(const struct volume_group *vg)
90 return (uint64_t) vg->max_pv;
93 uint64_t vg_max_lv(const struct volume_group *vg)
95 return (uint64_t) vg->max_lv;
98 unsigned snapshot_count(const struct volume_group *vg)
101 unsigned num_snapshots = 0;
103 dm_list_iterate_items(lvl, &vg->lvs)
104 if (lv_is_cow(lvl->lv))
107 return num_snapshots;
110 unsigned vg_visible_lvs(const struct volume_group *vg)
113 unsigned lv_count = 0;
115 dm_list_iterate_items(lvl, &vg->lvs) {
116 if (lv_is_visible(lvl->lv))
123 uint32_t vg_mda_count(const struct volume_group *vg)
125 return dm_list_size(&vg->fid->metadata_areas_in_use) +
126 dm_list_size(&vg->fid->metadata_areas_ignored);
129 uint32_t vg_mda_used_count(const struct volume_group *vg)
131 uint32_t used_count = 0;
132 struct metadata_area *mda;
135 * Ignored mdas could be on either list - the reason being the state
136 * may have changed from ignored to un-ignored and we need to write
139 dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use)
140 if (!mda_is_ignored(mda))
146 uint32_t vg_mda_copies(const struct volume_group *vg)
148 return vg->mda_copies;
151 uint64_t vg_mda_size(const struct volume_group *vg)
153 return find_min_mda_size(&vg->fid->metadata_areas_in_use);
156 uint64_t vg_mda_free(const struct volume_group *vg)
158 uint64_t freespace = UINT64_MAX, mda_free;
159 struct metadata_area *mda;
161 dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
162 if (!mda->ops->mda_free_sectors)
164 mda_free = mda->ops->mda_free_sectors(mda);
165 if (mda_free < freespace)
166 freespace = mda_free;
169 if (freespace == UINT64_MAX)
170 freespace = UINT64_C(0);
174 int vg_set_mda_copies(struct volume_group *vg, uint32_t mda_copies)
176 vg->mda_copies = mda_copies;
178 /* FIXME Use log_verbose when this is due to specific cmdline request. */
179 log_debug("Setting mda_copies to %"PRIu32" for VG %s",
180 mda_copies, vg->name);
185 static int _recalc_extents(uint32_t *extents, const char *desc1,
186 const char *desc2, uint32_t old_size,
189 uint64_t size = (uint64_t) old_size * (*extents);
191 if (size % new_size) {
192 log_error("New size %" PRIu64 " for %s%s not an exact number "
193 "of new extents.", size, desc1, desc2);
199 if (size > UINT32_MAX) {
200 log_error("New extent count %" PRIu64 " for %s%s exceeds "
201 "32 bits.", size, desc1, desc2);
205 *extents = (uint32_t) size;
210 int vg_set_extent_size(struct volume_group *vg, uint32_t new_size)
212 uint32_t old_size = vg->extent_size;
215 struct physical_volume *pv;
216 struct logical_volume *lv;
217 struct lv_segment *seg;
218 struct pv_segment *pvseg;
221 if (!vg_is_resizeable(vg)) {
222 log_error("Volume group \"%s\" must be resizeable "
223 "to change PE size", vg->name);
228 log_error("Physical extent size may not be zero");
232 if (new_size == vg->extent_size)
235 if (new_size & (new_size - 1)) {
236 log_error("Physical extent size must be a power of 2.");
240 if (new_size > vg->extent_size) {
241 if ((uint64_t) vg_size(vg) % new_size) {
242 /* FIXME Adjust used PV sizes instead */
243 log_error("New extent size is not a perfect fit");
248 vg->extent_size = new_size;
250 if (vg->fid->fmt->ops->vg_setup &&
251 !vg->fid->fmt->ops->vg_setup(vg->fid, vg))
254 if (!_recalc_extents(&vg->extent_count, vg->name, "", old_size,
258 if (!_recalc_extents(&vg->free_count, vg->name, " free space",
263 dm_list_iterate_items(pvl, &vg->pvs) {
266 pv->pe_size = new_size;
267 if (!_recalc_extents(&pv->pe_count, pv_dev_name(pv), "",
271 if (!_recalc_extents(&pv->pe_alloc_count, pv_dev_name(pv),
272 " allocated space", old_size, new_size))
275 /* foreach free PV Segment */
276 dm_list_iterate_items(pvseg, &pv->segments) {
277 if (pvseg_is_allocated(pvseg))
280 if (!_recalc_extents(&pvseg->pe, pv_dev_name(pv),
281 " PV segment start", old_size,
284 if (!_recalc_extents(&pvseg->len, pv_dev_name(pv),
285 " PV segment length", old_size,
292 dm_list_iterate_items(lvl, &vg->lvs) {
295 if (!_recalc_extents(&lv->le_count, lv->name, "", old_size,
299 dm_list_iterate_items(seg, &lv->segments) {
300 if (!_recalc_extents(&seg->le, lv->name,
301 " segment start", old_size,
305 if (!_recalc_extents(&seg->len, lv->name,
306 " segment length", old_size,
310 if (!_recalc_extents(&seg->area_len, lv->name,
311 " area length", old_size,
315 if (!_recalc_extents(&seg->extents_copied, lv->name,
316 " extents moved", old_size,
321 for (s = 0; s < seg->area_count; s++) {
322 switch (seg_type(seg, s)) {
327 " pvseg start", old_size,
331 (&seg_pvseg(seg, s)->len,
333 " pvseg length", old_size,
339 (&seg_le(seg, s), lv->name,
340 " area start", old_size,
344 case AREA_UNASSIGNED:
345 log_error("Unassigned area %u found in "
357 int vg_set_max_lv(struct volume_group *vg, uint32_t max_lv)
359 if (!vg_is_resizeable(vg)) {
360 log_error("Volume group \"%s\" must be resizeable "
361 "to change MaxLogicalVolume", vg->name);
365 if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
368 else if (max_lv > 255) {
369 log_error("MaxLogicalVolume limit is 255");
374 if (max_lv && max_lv < vg_visible_lvs(vg)) {
375 log_error("MaxLogicalVolume is less than the current number "
376 "%d of LVs for %s", vg_visible_lvs(vg),
385 int vg_set_max_pv(struct volume_group *vg, uint32_t max_pv)
387 if (!vg_is_resizeable(vg)) {
388 log_error("Volume group \"%s\" must be resizeable "
389 "to change MaxPhysicalVolumes", vg->name);
393 if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
396 else if (max_pv > 255) {
397 log_error("MaxPhysicalVolume limit is 255");
402 if (max_pv && max_pv < vg->pv_count) {
403 log_error("MaxPhysicalVolumes is less than the current number "
404 "%d of PVs for \"%s\"", vg->pv_count,
412 int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc)
414 if (alloc == ALLOC_INHERIT) {
415 log_error("Volume Group allocation policy cannot inherit "
420 if (alloc == vg->alloc)
427 int vg_set_clustered(struct volume_group *vg, int clustered)
432 * We do not currently support switching the cluster attribute
433 * on active mirrors or snapshots.
435 dm_list_iterate_items(lvl, &vg->lvs) {
436 if (lv_is_mirrored(lvl->lv) && lv_is_active(lvl->lv)) {
437 log_error("Mirror logical volumes must be inactive "
438 "when changing the cluster attribute.");
443 if (lv_is_origin(lvl->lv) || lv_is_cow(lvl->lv)) {
444 log_error("Volume group %s contains snapshots "
445 "that are not yet supported.",
451 if ((lv_is_origin(lvl->lv) || lv_is_cow(lvl->lv)) &&
452 lv_is_active(lvl->lv)) {
453 log_error("Snapshot logical volumes must be inactive "
454 "when changing the cluster attribute.");
460 vg->status |= CLUSTERED;
462 vg->status &= ~CLUSTERED;
466 char *vg_attr_dup(struct dm_pool *mem, const struct volume_group *vg)
470 if (!(repstr = dm_pool_zalloc(mem, 7))) {
471 log_error("dm_pool_alloc failed");
475 repstr[0] = (vg->status & LVM_WRITE) ? 'w' : 'r';
476 repstr[1] = (vg_is_resizeable(vg)) ? 'z' : '-';
477 repstr[2] = (vg_is_exported(vg)) ? 'x' : '-';
478 repstr[3] = (vg_missing_pv_count(vg)) ? 'p' : '-';
479 repstr[4] = alloc_policy_char(vg->alloc);
480 repstr[5] = (vg_is_clustered(vg)) ? 'c' : '-';