2 * Copyright (C) 2008,2009 Red Hat, Inc. All rights reserved.
4 * This file is part of LVM2.
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.
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
17 #include "lvm-string.h"
25 static int _lv_check_handle(const lv_t lv, const int vg_writeable)
27 if (!lv || !lv->vg || vg_read_error(lv->vg))
29 if (vg_writeable && !vg_check_write_mode(lv->vg))
34 /* FIXME: have lib/report/report.c _disp function call lv_size()? */
35 uint64_t lvm_lv_get_size(const lv_t lv)
37 return SECTOR_SIZE * lv_size(lv);
40 const char *lvm_lv_get_uuid(const lv_t lv)
42 return lv_uuid_dup(lv);
45 const char *lvm_lv_get_name(const lv_t lv)
47 return dm_pool_strndup(lv->vg->vgmem, (const char *)lv->name,
51 struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name)
53 return get_property(NULL, NULL, lv, NULL, NULL, name);
56 struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg,
59 return get_property(NULL, NULL, NULL, lvseg, NULL, name);
62 uint64_t lvm_lv_is_active(const lv_t lv)
65 if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) &&
66 info.exists && info.live_table)
71 uint64_t lvm_lv_is_suspended(const lv_t lv)
74 if (lv_info(lv->vg->cmd, lv, 0, &info, 1, 0) &&
75 info.exists && info.suspended)
80 int lvm_lv_add_tag(lv_t lv, const char *tag)
82 if (_lv_check_handle(lv, 1))
84 if (!lv_change_tag(lv, tag, 1))
90 int lvm_lv_remove_tag(lv_t lv, const char *tag)
92 if (_lv_check_handle(lv, 1))
94 if (!lv_change_tag(lv, tag, 0))
100 struct dm_list *lvm_lv_get_tags(const lv_t lv)
102 return tag_list_copy(lv->vg->vgmem, &lv->tags);
105 /* Set defaults for non-segment specific LV parameters */
106 static void _lv_set_default_params(struct lvcreate_params *lp,
107 vg_t vg, const char *lvname,
113 lp->activation_monitoring = DEFAULT_DMEVENTD_MONITOR;
114 lp->vg_name = vg->name;
115 lp->lv_name = lvname; /* FIXME: check this for safety */
118 lp->extents = extents;
119 lp->permission = LVM_READ | LVM_WRITE;
120 lp->read_ahead = DM_READ_AHEAD_NONE;
121 lp->alloc = ALLOC_INHERIT;
122 dm_list_init(&lp->tags);
125 /* Set default for linear segment specific LV parameters */
126 static void _lv_set_default_linear_params(struct cmd_context *cmd,
127 struct lvcreate_params *lp)
129 lp->segtype = get_segtype_from_string(cmd, "striped");
131 lp->stripe_size = DEFAULT_STRIPESIZE * 2;
135 * FIXME: This function should probably not commit to disk but require calling
136 * lvm_vg_write. However, this appears to be non-trivial change until
137 * lv_create_single is refactored by segtype.
139 lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size)
141 struct lvcreate_params lp;
145 if (vg_read_error(vg))
147 if (!vg_check_write_mode(vg))
149 memset(&lp, 0, sizeof(lp));
150 extents = extents_from_size(vg->cmd, size / SECTOR_SIZE,
152 _lv_set_default_params(&lp, vg, name, extents);
153 _lv_set_default_linear_params(vg->cmd, &lp);
154 if (!lv_create_single(vg, &lp))
156 lvl = find_lv_in_vg(vg, name);
159 return (lv_t) lvl->lv;
163 * FIXME: This function should probably not commit to disk but require calling
166 int lvm_vg_remove_lv(lv_t lv)
168 if (!lv || !lv->vg || vg_read_error(lv->vg))
170 if (!vg_check_write_mode(lv->vg))
172 if (!lv_remove_single(lv->vg->cmd, lv, DONT_PROMPT))
177 int lvm_lv_activate(lv_t lv)
179 if (!lv || !lv->vg || vg_read_error(lv->vg) || !lv->vg->cmd)
182 /* FIXME: handle pvmove stuff later */
183 if (lv->status & LOCKED) {
184 log_error("Unable to activate locked LV");
188 /* FIXME: handle lvconvert stuff later */
189 if (lv->status & CONVERTING) {
190 log_error("Unable to activate LV with in-progress lvconvert");
194 if (lv_is_origin(lv)) {
195 log_verbose("Activating logical volume \"%s\" "
196 "exclusively", lv->name);
197 if (!activate_lv_excl(lv->vg->cmd, lv)) {
198 log_error("Activate exclusive failed.");
202 log_verbose("Activating logical volume \"%s\"",
204 if (!activate_lv(lv->vg->cmd, lv)) {
205 log_error("Activate failed.");
212 int lvm_lv_deactivate(lv_t lv)
214 if (!lv || !lv->vg || vg_read_error(lv->vg) || !lv->vg->cmd)
217 log_verbose("Deactivating logical volume \"%s\"", lv->name);
218 if (!deactivate_lv(lv->vg->cmd, lv)) {
219 log_error("Deactivate failed.");
225 struct dm_list *lvm_lv_list_lvsegs(lv_t lv)
227 struct dm_list *list;
229 struct lv_segment *lvl;
231 if (dm_list_empty(&lv->segments))
234 if (!(list = dm_pool_zalloc(lv->vg->vgmem, sizeof(*list)))) {
235 log_errno(ENOMEM, "Memory allocation fail for dm_list.");
240 dm_list_iterate_items(lvl, &lv->segments) {
241 if (!(lvseg = dm_pool_zalloc(lv->vg->vgmem, sizeof(*lvseg)))) {
243 "Memory allocation fail for lvm_lvseg_list.");
247 dm_list_add(list, &lvseg->list);
252 lv_t lvm_lv_from_name(vg_t vg, const char *name)
256 dm_list_iterate_items(lvl, &vg->lvs) {
257 if (!strcmp(name, lvl->lv->name))
263 lv_t lvm_lv_from_uuid(vg_t vg, const char *uuid)
268 if (strlen(uuid) < ID_LEN) {
269 log_errno (EINVAL, "Invalid UUID string length");
272 if (strlen(uuid) >= ID_LEN) {
273 if (!id_read_format(&id, uuid)) {
274 log_errno(EINVAL, "Invalid UUID format");
278 dm_list_iterate_items(lvl, &vg->lvs) {
279 if (id_equal(&vg->id, &lvl->lv->lvid.id[0]) &&
280 id_equal(&id, &lvl->lv->lvid.id[1]))
285 int lvm_lv_resize(const lv_t lv, uint64_t new_size)
287 /* FIXME: add lv resize code here */
288 log_error("NOT IMPLEMENTED YET");