]> sourceware.org Git - lvm2.git/blob - liblvm/lvm_lv.c
Reinstate accidentally-deleted line.
[lvm2.git] / liblvm / lvm_lv.c
1 /*
2 * Copyright (C) 2008,2009 Red Hat, Inc. All rights reserved.
3 *
4 * This file is part of LVM2.
5 *
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.
9 *
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
13 */
14
15 #include "lib.h"
16 #include "metadata.h"
17 #include "lvm-string.h"
18 #include "defaults.h"
19 #include "segtype.h"
20 #include "locking.h"
21 #include "activate.h"
22 #include "lvm_misc.h"
23 #include "lvm2app.h"
24
25 static int _lv_check_handle(const lv_t lv, const int vg_writeable)
26 {
27 if (!lv || !lv->vg || vg_read_error(lv->vg))
28 return -1;
29 if (vg_writeable && !vg_check_write_mode(lv->vg))
30 return -1;
31 return 0;
32 }
33
34 /* FIXME: have lib/report/report.c _disp function call lv_size()? */
35 uint64_t lvm_lv_get_size(const lv_t lv)
36 {
37 return SECTOR_SIZE * lv_size(lv);
38 }
39
40 const char *lvm_lv_get_uuid(const lv_t lv)
41 {
42 return lv_uuid_dup(lv);
43 }
44
45 const char *lvm_lv_get_name(const lv_t lv)
46 {
47 return dm_pool_strndup(lv->vg->vgmem, (const char *)lv->name,
48 NAME_LEN+1);
49 }
50
51 struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name)
52 {
53 return get_property(NULL, NULL, lv, NULL, NULL, name);
54 }
55
56 struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg,
57 const char *name)
58 {
59 return get_property(NULL, NULL, NULL, lvseg, NULL, name);
60 }
61
62 uint64_t lvm_lv_is_active(const lv_t lv)
63 {
64 struct lvinfo info;
65 if (lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) &&
66 info.exists && info.live_table)
67 return 1;
68 return 0;
69 }
70
71 uint64_t lvm_lv_is_suspended(const lv_t lv)
72 {
73 struct lvinfo info;
74 if (lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) &&
75 info.exists && info.suspended)
76 return 1;
77 return 0;
78 }
79
80 int lvm_lv_add_tag(lv_t lv, const char *tag)
81 {
82 if (_lv_check_handle(lv, 1))
83 return -1;
84 if (!lv_change_tag(lv, tag, 1))
85 return -1;
86 return 0;
87 }
88
89
90 int lvm_lv_remove_tag(lv_t lv, const char *tag)
91 {
92 if (_lv_check_handle(lv, 1))
93 return -1;
94 if (!lv_change_tag(lv, tag, 0))
95 return -1;
96 return 0;
97 }
98
99
100 struct dm_list *lvm_lv_get_tags(const lv_t lv)
101 {
102 return tag_list_copy(lv->vg->vgmem, &lv->tags);
103 }
104
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,
108 uint64_t extents)
109 {
110 lp->zero = 1;
111 lp->major = -1;
112 lp->minor = -1;
113 lp->activate = CHANGE_AY;
114 lp->vg_name = vg->name;
115 lp->lv_name = lvname; /* FIXME: check this for safety */
116 lp->pvh = &vg->pvs;
117
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);
123 }
124
125 /* Set default for linear segment specific LV parameters */
126 static int _lv_set_default_linear_params(struct cmd_context *cmd,
127 struct lvcreate_params *lp)
128 {
129 if (!(lp->segtype = get_segtype_from_string(cmd, "striped"))) {
130 log_error(INTERNAL_ERROR "Segtype striped not found.");
131 return 0;
132 }
133
134 lp->stripes = 1;
135 lp->stripe_size = DEFAULT_STRIPESIZE * 2;
136
137 return 1;
138 }
139
140 /*
141 * FIXME: This function should probably not commit to disk but require calling
142 * lvm_vg_write. However, this appears to be non-trivial change until
143 * lv_create_single is refactored by segtype.
144 */
145 lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size)
146 {
147 struct lvcreate_params lp;
148 uint64_t extents;
149 struct lv_list *lvl;
150
151 if (vg_read_error(vg))
152 return NULL;
153 if (!vg_check_write_mode(vg))
154 return NULL;
155 memset(&lp, 0, sizeof(lp));
156 extents = extents_from_size(vg->cmd, size / SECTOR_SIZE,
157 vg->extent_size);
158 _lv_set_default_params(&lp, vg, name, extents);
159 if (!_lv_set_default_linear_params(vg->cmd, &lp))
160 return_NULL;
161 if (!lv_create_single(vg, &lp))
162 return NULL;
163 lvl = find_lv_in_vg(vg, name);
164 if (!lvl)
165 return NULL;
166 return (lv_t) lvl->lv;
167 }
168
169 /*
170 * FIXME: This function should probably not commit to disk but require calling
171 * lvm_vg_write.
172 */
173 int lvm_vg_remove_lv(lv_t lv)
174 {
175 if (!lv || !lv->vg || vg_read_error(lv->vg))
176 return -1;
177 if (!vg_check_write_mode(lv->vg))
178 return -1;
179 if (!lv_remove_single(lv->vg->cmd, lv, DONT_PROMPT))
180 return -1;
181 return 0;
182 }
183
184 int lvm_lv_activate(lv_t lv)
185 {
186 if (!lv || !lv->vg || vg_read_error(lv->vg) || !lv->vg->cmd)
187 return -1;
188
189 /* FIXME: handle pvmove stuff later */
190 if (lv->status & LOCKED) {
191 log_error("Unable to activate locked LV");
192 return -1;
193 }
194
195 /* FIXME: handle lvconvert stuff later */
196 if (lv->status & CONVERTING) {
197 log_error("Unable to activate LV with in-progress lvconvert");
198 return -1;
199 }
200
201 if (lv_is_origin(lv)) {
202 log_verbose("Activating logical volume \"%s\" "
203 "exclusively", lv->name);
204 if (!activate_lv_excl(lv->vg->cmd, lv)) {
205 log_error("Activate exclusive failed.");
206 return -1;
207 }
208 } else {
209 log_verbose("Activating logical volume \"%s\"",
210 lv->name);
211 if (!activate_lv(lv->vg->cmd, lv)) {
212 log_error("Activate failed.");
213 return -1;
214 }
215 }
216 return 0;
217 }
218
219 int lvm_lv_deactivate(lv_t lv)
220 {
221 if (!lv || !lv->vg || vg_read_error(lv->vg) || !lv->vg->cmd)
222 return -1;
223
224 log_verbose("Deactivating logical volume \"%s\"", lv->name);
225 if (!deactivate_lv(lv->vg->cmd, lv)) {
226 log_error("Deactivate failed.");
227 return -1;
228 }
229 return 0;
230 }
231
232 struct dm_list *lvm_lv_list_lvsegs(lv_t lv)
233 {
234 struct dm_list *list;
235 lvseg_list_t *lvseg;
236 struct lv_segment *lvl;
237
238 if (dm_list_empty(&lv->segments))
239 return NULL;
240
241 if (!(list = dm_pool_zalloc(lv->vg->vgmem, sizeof(*list)))) {
242 log_errno(ENOMEM, "Memory allocation fail for dm_list.");
243 return NULL;
244 }
245 dm_list_init(list);
246
247 dm_list_iterate_items(lvl, &lv->segments) {
248 if (!(lvseg = dm_pool_zalloc(lv->vg->vgmem, sizeof(*lvseg)))) {
249 log_errno(ENOMEM,
250 "Memory allocation fail for lvm_lvseg_list.");
251 return NULL;
252 }
253 lvseg->lvseg = lvl;
254 dm_list_add(list, &lvseg->list);
255 }
256 return list;
257 }
258
259 lv_t lvm_lv_from_name(vg_t vg, const char *name)
260 {
261 struct lv_list *lvl;
262
263 dm_list_iterate_items(lvl, &vg->lvs) {
264 if (!strcmp(name, lvl->lv->name))
265 return lvl->lv;
266 }
267 return NULL;
268 }
269
270 lv_t lvm_lv_from_uuid(vg_t vg, const char *uuid)
271 {
272 struct lv_list *lvl;
273 struct id id;
274
275 if (strlen(uuid) < ID_LEN) {
276 log_errno (EINVAL, "Invalid UUID string length");
277 return NULL;
278 }
279
280 if (!id_read_format(&id, uuid)) {
281 log_errno(EINVAL, "Invalid UUID format.");
282 return NULL;
283 }
284
285 dm_list_iterate_items(lvl, &vg->lvs) {
286 if (id_equal(&vg->id, &lvl->lv->lvid.id[0]) &&
287 id_equal(&id, &lvl->lv->lvid.id[1]))
288 return lvl->lv;
289 }
290 return NULL;
291 }
292 int lvm_lv_resize(const lv_t lv, uint64_t new_size)
293 {
294 /* FIXME: add lv resize code here */
295 log_error("NOT IMPLEMENTED YET");
296 return -1;
297 }
This page took 0.084009 seconds and 5 git commands to generate.