import source from lvm2 2.02.79
[external/device-mapper.git] / lib / metadata / vg.c
1 /*
2  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3  * Copyright (C) 2004-2010 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 "display.h"
19 #include "activate.h"
20
21 char *vg_fmt_dup(const struct volume_group *vg)
22 {
23         if (!vg->fid || !vg->fid->fmt)
24                 return NULL;
25         return dm_pool_strdup(vg->vgmem, vg->fid->fmt->name);
26 }
27
28 char *vg_name_dup(const struct volume_group *vg)
29 {
30         return dm_pool_strdup(vg->vgmem, vg->name);
31 }
32
33 char *vg_system_id_dup(const struct volume_group *vg)
34 {
35         return dm_pool_strdup(vg->vgmem, vg->system_id);
36 }
37
38 char *vg_uuid_dup(const struct volume_group *vg)
39 {
40         return id_format_and_copy(vg->vgmem, &vg->id);
41 }
42
43 char *vg_tags_dup(const struct volume_group *vg)
44 {
45         return tags_format_and_copy(vg->vgmem, &vg->tags);
46 }
47
48 uint32_t vg_seqno(const struct volume_group *vg)
49 {
50         return vg->seqno;
51 }
52
53 uint64_t vg_status(const struct volume_group *vg)
54 {
55         return vg->status;
56 }
57
58 uint64_t vg_size(const struct volume_group *vg)
59 {
60         return (uint64_t) vg->extent_count * vg->extent_size;
61 }
62
63 uint64_t vg_free(const struct volume_group *vg)
64 {
65         return (uint64_t) vg->free_count * vg->extent_size;
66 }
67
68 uint64_t vg_extent_size(const struct volume_group *vg)
69 {
70         return (uint64_t) vg->extent_size;
71 }
72
73 uint64_t vg_extent_count(const struct volume_group *vg)
74 {
75         return (uint64_t) vg->extent_count;
76 }
77
78 uint64_t vg_free_count(const struct volume_group *vg)
79 {
80         return (uint64_t) vg->free_count;
81 }
82
83 uint64_t vg_pv_count(const struct volume_group *vg)
84 {
85         return (uint64_t) vg->pv_count;
86 }
87
88 uint64_t vg_max_pv(const struct volume_group *vg)
89 {
90         return (uint64_t) vg->max_pv;
91 }
92
93 uint64_t vg_max_lv(const struct volume_group *vg)
94 {
95         return (uint64_t) vg->max_lv;
96 }
97
98 unsigned snapshot_count(const struct volume_group *vg)
99 {
100         struct lv_list *lvl;
101         unsigned num_snapshots = 0;
102
103         dm_list_iterate_items(lvl, &vg->lvs)
104                 if (lv_is_cow(lvl->lv))
105                         num_snapshots++;
106
107         return num_snapshots;
108 }
109
110 unsigned vg_visible_lvs(const struct volume_group *vg)
111 {
112         struct lv_list *lvl;
113         unsigned lv_count = 0;
114
115         dm_list_iterate_items(lvl, &vg->lvs) {
116                 if (lv_is_visible(lvl->lv))
117                         lv_count++;
118         }
119
120         return lv_count;
121 }
122
123 uint32_t vg_mda_count(const struct volume_group *vg)
124 {
125         return dm_list_size(&vg->fid->metadata_areas_in_use) +
126                 dm_list_size(&vg->fid->metadata_areas_ignored);
127 }
128
129 uint32_t vg_mda_used_count(const struct volume_group *vg)
130 {
131        uint32_t used_count = 0;
132        struct metadata_area *mda;
133
134         /*
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
137          * the state to disk.
138          */
139        dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use)
140                if (!mda_is_ignored(mda))
141                        used_count++;
142
143        return used_count;
144 }
145
146 uint32_t vg_mda_copies(const struct volume_group *vg)
147 {
148         return vg->mda_copies;
149 }
150
151 uint64_t vg_mda_size(const struct volume_group *vg)
152 {
153         return find_min_mda_size(&vg->fid->metadata_areas_in_use);
154 }
155
156 uint64_t vg_mda_free(const struct volume_group *vg)
157 {
158         uint64_t freespace = UINT64_MAX, mda_free;
159         struct metadata_area *mda;
160
161         dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {
162                 if (!mda->ops->mda_free_sectors)
163                         continue;
164                 mda_free = mda->ops->mda_free_sectors(mda);
165                 if (mda_free < freespace)
166                         freespace = mda_free;
167         }
168
169         if (freespace == UINT64_MAX)
170                 freespace = UINT64_C(0);
171         return freespace;
172 }
173
174 int vg_set_mda_copies(struct volume_group *vg, uint32_t mda_copies)
175 {
176         vg->mda_copies = mda_copies;
177
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);
181
182         return 1;
183 }
184
185 static int _recalc_extents(uint32_t *extents, const char *desc1,
186                            const char *desc2, uint32_t old_size,
187                            uint32_t new_size)
188 {
189         uint64_t size = (uint64_t) old_size * (*extents);
190
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);
194                 return 0;
195         }
196
197         size /= new_size;
198
199         if (size > UINT32_MAX) {
200                 log_error("New extent count %" PRIu64 " for %s%s exceeds "
201                           "32 bits.", size, desc1, desc2);
202                 return 0;
203         }
204
205         *extents = (uint32_t) size;
206
207         return 1;
208 }
209
210 int vg_set_extent_size(struct volume_group *vg, uint32_t new_size)
211 {
212         uint32_t old_size = vg->extent_size;
213         struct pv_list *pvl;
214         struct lv_list *lvl;
215         struct physical_volume *pv;
216         struct logical_volume *lv;
217         struct lv_segment *seg;
218         struct pv_segment *pvseg;
219         uint32_t s;
220
221         if (!vg_is_resizeable(vg)) {
222                 log_error("Volume group \"%s\" must be resizeable "
223                           "to change PE size", vg->name);
224                 return 0;
225         }
226
227         if (!new_size) {
228                 log_error("Physical extent size may not be zero");
229                 return 0;
230         }
231
232         if (new_size == vg->extent_size)
233                 return 1;
234
235         if (new_size & (new_size - 1)) {
236                 log_error("Physical extent size must be a power of 2.");
237                 return 0;
238         }
239
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");
244                         return 0;
245                 }
246         }
247
248         vg->extent_size = new_size;
249
250         if (vg->fid->fmt->ops->vg_setup &&
251             !vg->fid->fmt->ops->vg_setup(vg->fid, vg))
252                 return_0;
253
254         if (!_recalc_extents(&vg->extent_count, vg->name, "", old_size,
255                              new_size))
256                 return_0;
257
258         if (!_recalc_extents(&vg->free_count, vg->name, " free space",
259                              old_size, new_size))
260                 return_0;
261
262         /* foreach PV */
263         dm_list_iterate_items(pvl, &vg->pvs) {
264                 pv = pvl->pv;
265
266                 pv->pe_size = new_size;
267                 if (!_recalc_extents(&pv->pe_count, pv_dev_name(pv), "",
268                                      old_size, new_size))
269                         return_0;
270
271                 if (!_recalc_extents(&pv->pe_alloc_count, pv_dev_name(pv),
272                                      " allocated space", old_size, new_size))
273                         return_0;
274
275                 /* foreach free PV Segment */
276                 dm_list_iterate_items(pvseg, &pv->segments) {
277                         if (pvseg_is_allocated(pvseg))
278                                 continue;
279
280                         if (!_recalc_extents(&pvseg->pe, pv_dev_name(pv),
281                                              " PV segment start", old_size,
282                                              new_size))
283                                 return_0;
284                         if (!_recalc_extents(&pvseg->len, pv_dev_name(pv),
285                                              " PV segment length", old_size,
286                                              new_size))
287                                 return_0;
288                 }
289         }
290
291         /* foreach LV */
292         dm_list_iterate_items(lvl, &vg->lvs) {
293                 lv = lvl->lv;
294
295                 if (!_recalc_extents(&lv->le_count, lv->name, "", old_size,
296                                      new_size))
297                         return_0;
298
299                 dm_list_iterate_items(seg, &lv->segments) {
300                         if (!_recalc_extents(&seg->le, lv->name,
301                                              " segment start", old_size,
302                                              new_size))
303                                 return_0;
304
305                         if (!_recalc_extents(&seg->len, lv->name,
306                                              " segment length", old_size,
307                                              new_size))
308                                 return_0;
309
310                         if (!_recalc_extents(&seg->area_len, lv->name,
311                                              " area length", old_size,
312                                              new_size))
313                                 return_0;
314
315                         if (!_recalc_extents(&seg->extents_copied, lv->name,
316                                              " extents moved", old_size,
317                                              new_size))
318                                 return_0;
319
320                         /* foreach area */
321                         for (s = 0; s < seg->area_count; s++) {
322                                 switch (seg_type(seg, s)) {
323                                 case AREA_PV:
324                                         if (!_recalc_extents
325                                             (&seg_pe(seg, s),
326                                              lv->name,
327                                              " pvseg start", old_size,
328                                              new_size))
329                                                 return_0;
330                                         if (!_recalc_extents
331                                             (&seg_pvseg(seg, s)->len,
332                                              lv->name,
333                                              " pvseg length", old_size,
334                                              new_size))
335                                                 return_0;
336                                         break;
337                                 case AREA_LV:
338                                         if (!_recalc_extents
339                                             (&seg_le(seg, s), lv->name,
340                                              " area start", old_size,
341                                              new_size))
342                                                 return_0;
343                                         break;
344                                 case AREA_UNASSIGNED:
345                                         log_error("Unassigned area %u found in "
346                                                   "segment", s);
347                                         return 0;
348                                 }
349                         }
350                 }
351
352         }
353
354         return 1;
355 }
356
357 int vg_set_max_lv(struct volume_group *vg, uint32_t max_lv)
358 {
359         if (!vg_is_resizeable(vg)) {
360                 log_error("Volume group \"%s\" must be resizeable "
361                           "to change MaxLogicalVolume", vg->name);
362                 return 0;
363         }
364
365         if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
366                 if (!max_lv)
367                         max_lv = 255;
368                 else if (max_lv > 255) {
369                         log_error("MaxLogicalVolume limit is 255");
370                         return 0;
371                 }
372         }
373
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),
377                           vg->name);
378                 return 0;
379         }
380         vg->max_lv = max_lv;
381
382         return 1;
383 }
384
385 int vg_set_max_pv(struct volume_group *vg, uint32_t max_pv)
386 {
387         if (!vg_is_resizeable(vg)) {
388                 log_error("Volume group \"%s\" must be resizeable "
389                           "to change MaxPhysicalVolumes", vg->name);
390                 return 0;
391         }
392
393         if (!(vg->fid->fmt->features & FMT_UNLIMITED_VOLS)) {
394                 if (!max_pv)
395                         max_pv = 255;
396                 else if (max_pv > 255) {
397                         log_error("MaxPhysicalVolume limit is 255");
398                         return 0;
399                 }
400         }
401
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,
405                           vg->name);
406                 return 0;
407         }
408         vg->max_pv = max_pv;
409         return 1;
410 }
411
412 int vg_set_alloc_policy(struct volume_group *vg, alloc_policy_t alloc)
413 {
414         if (alloc == ALLOC_INHERIT) {
415                 log_error("Volume Group allocation policy cannot inherit "
416                           "from anything");
417                 return 0;
418         }
419
420         if (alloc == vg->alloc)
421                 return 1;
422
423         vg->alloc = alloc;
424         return 1;
425 }
426
427 int vg_set_clustered(struct volume_group *vg, int clustered)
428 {
429         struct lv_list *lvl;
430
431         /*
432          * We do not currently support switching the cluster attribute
433          * on active mirrors or snapshots.
434          */
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.");
439                         return 0;
440                 }
441
442                 if (clustered) {
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.",
446                                           vg->name);
447                                 return 0;
448                         }
449                 }
450
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.");
455                         return 0;
456                 }
457         }
458
459         if (clustered)
460                 vg->status |= CLUSTERED;
461         else
462                 vg->status &= ~CLUSTERED;
463         return 1;
464 }
465
466 char *vg_attr_dup(struct dm_pool *mem, const struct volume_group *vg)
467 {
468         char *repstr;
469
470         if (!(repstr = dm_pool_zalloc(mem, 7))) {
471                 log_error("dm_pool_alloc failed");
472                 return NULL;
473         }
474
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' : '-';
481         return repstr;
482 }