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
20 #include "toolcontext.h"
24 char *lvseg_tags_dup(const struct lv_segment *seg)
26 return tags_format_and_copy(seg->lv->vg->vgmem, &seg->tags);
29 char *lvseg_segtype_dup(const struct lv_segment *seg)
31 if (seg->area_count == 1) {
32 return (char *)"linear";
35 return dm_pool_strdup(seg->lv->vg->vgmem, seg->segtype->ops->name(seg));
38 uint64_t lvseg_chunksize(const struct lv_segment *seg)
42 if (lv_is_cow(seg->lv))
43 size = (uint64_t) find_cow(seg->lv)->chunk_size;
49 uint64_t lvseg_start(const struct lv_segment *seg)
51 return (uint64_t) seg->le * seg->lv->vg->extent_size;
54 uint64_t lvseg_size(const struct lv_segment *seg)
56 return (uint64_t) seg->len * seg->lv->vg->extent_size;
59 uint32_t lv_kernel_read_ahead(const struct logical_volume *lv)
63 if (!lv_info(lv->vg->cmd, lv, 0, &info, 0, 1) || !info.exists)
65 return info.read_ahead;
68 char *lv_origin_dup(struct dm_pool *mem, const struct logical_volume *lv)
71 return lv_name_dup(mem, origin_from_cow(lv));
75 char *lv_name_dup(struct dm_pool *mem, const struct logical_volume *lv)
77 return dm_pool_strdup(mem, lv->name);
80 char *lv_modules_dup(struct dm_pool *mem, const struct logical_volume *lv)
82 struct dm_list *modules;
84 if (!(modules = str_list_create(mem))) {
85 log_error("modules str_list allocation failed");
89 if (!list_lv_modules(mem, lv, modules))
91 return tags_format_and_copy(mem, modules);
94 char *lv_mirror_log_dup(struct dm_pool *mem, const struct logical_volume *lv)
96 struct lv_segment *seg;
98 dm_list_iterate_items(seg, &lv->segments) {
99 if (!seg_is_mirrored(seg) || !seg->log_lv)
101 return dm_pool_strdup(mem, seg->log_lv->name);
106 int lv_kernel_minor(const struct logical_volume *lv)
110 if (lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) && info.exists)
115 int lv_kernel_major(const struct logical_volume *lv)
118 if (lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) && info.exists)
123 char *lv_convert_lv_dup(struct dm_pool *mem, const struct logical_volume *lv)
125 struct lv_segment *seg;
127 if (lv->status & (CONVERTING|MIRRORED)) {
130 /* Temporary mirror is always area_num == 0 */
131 if (seg_type(seg, 0) == AREA_LV &&
132 is_temporary_mirror_layer(seg_lv(seg, 0)))
133 return dm_pool_strdup(mem, seg_lv(seg, 0)->name);
138 char *lv_move_pv_dup(struct dm_pool *mem, const struct logical_volume *lv)
140 struct lv_segment *seg;
142 dm_list_iterate_items(seg, &lv->segments) {
143 if (seg->status & PVMOVE)
144 return dm_pool_strdup(mem, dev_name(seg_dev(seg, 0)));
149 uint64_t lv_origin_size(const struct logical_volume *lv)
152 return (uint64_t) find_cow(lv)->len * lv->vg->extent_size;
153 if (lv_is_origin(lv))
158 char *lv_path_dup(struct dm_pool *mem, const struct logical_volume *lv)
163 len = strlen(lv->vg->cmd->dev_dir) + strlen(lv->vg->name) +
164 strlen(lv->name) + 2;
166 if (!(repstr = dm_pool_zalloc(mem, len))) {
167 log_error("dm_pool_alloc failed");
171 if (dm_snprintf(repstr, len, "%s%s/%s",
172 lv->vg->cmd->dev_dir, lv->vg->name, lv->name) < 0) {
173 log_error("lvpath snprintf failed");
179 char *lv_uuid_dup(const struct logical_volume *lv)
181 return id_format_and_copy(lv->vg->vgmem, &lv->lvid.id[1]);
184 char *lv_tags_dup(const struct logical_volume *lv)
186 return tags_format_and_copy(lv->vg->vgmem, &lv->tags);
189 uint64_t lv_size(const struct logical_volume *lv)
194 static int _lv_mimage_in_sync(const struct logical_volume *lv)
197 struct lv_segment *mirror_seg = find_mirror_seg(first_seg(lv));
199 if (!(lv->status & MIRROR_IMAGE) || !mirror_seg)
202 if (!lv_mirror_percent(lv->vg->cmd, mirror_seg->lv, 0, &percent,
206 return (percent == PERCENT_100) ? 1 : 0;
209 char *lv_attr_dup(struct dm_pool *mem, const struct logical_volume *lv)
211 percent_t snap_percent;
215 if (!(repstr = dm_pool_zalloc(mem, 7))) {
216 log_error("dm_pool_alloc failed");
220 /* Blank if this is a "free space" LV. */
224 if (lv->status & PVMOVE)
226 else if (lv->status & CONVERTING)
228 else if (lv->status & VIRTUAL)
230 /* Origin takes precedence over Mirror */
231 else if (lv_is_origin(lv)) {
232 repstr[0] = (lv_is_merging_origin(lv)) ? 'O' : 'o';
234 else if (lv->status & MIRRORED) {
235 repstr[0] = (lv->status & MIRROR_NOTSYNCED) ? 'M' : 'm';
236 }else if (lv->status & MIRROR_IMAGE)
237 repstr[0] = (_lv_mimage_in_sync(lv)) ? 'i' : 'I';
238 else if (lv->status & MIRROR_LOG)
240 else if (lv_is_cow(lv)) {
241 repstr[0] = (lv_is_merging_cow(lv)) ? 'S' : 's';
245 if (lv->status & PVMOVE)
247 else if (lv->status & LVM_WRITE)
249 else if (lv->status & LVM_READ)
254 repstr[2] = alloc_policy_char(lv->alloc);
256 if (lv->status & LOCKED)
257 repstr[2] = toupper(repstr[2]);
259 repstr[3] = (lv->status & FIXED_MINOR) ? 'm' : '-';
261 if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) && info.exists) {
263 repstr[4] = 's'; /* Suspended */
264 else if (info.live_table)
265 repstr[4] = 'a'; /* Active */
266 else if (info.inactive_table)
267 repstr[4] = 'i'; /* Inactive with table */
269 repstr[4] = 'd'; /* Inactive without table */
271 /* Snapshot dropped? */
272 if (info.live_table && lv_is_cow(lv) &&
273 (!lv_snapshot_percent(lv, &snap_percent) ||
274 snap_percent == PERCENT_INVALID)) {
275 repstr[0] = toupper(repstr[0]);
277 repstr[4] = 'S'; /* Susp Inv snapshot */
279 repstr[4] = 'I'; /* Invalid snapshot */
282 repstr[5] = (info.open_count) ? 'o' : '-';