]>
Commit | Line | Data |
---|---|---|
f032ed74 DW |
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" | |
254d672d | 16 | #include "metadata.h" |
f032ed74 | 17 | #include "lvm-string.h" |
7a35a9f5 DW |
18 | #include "defaults.h" |
19 | #include "segtype.h" | |
63b186b6 | 20 | #include "locking.h" |
2642ef55 | 21 | #include "activate.h" |
a6ca9ac0 | 22 | #include "lvm_misc.h" |
8961b1d5 | 23 | #include "lvm2app.h" |
63b186b6 | 24 | |
a6ca9ac0 DW |
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 | ||
83f25cd1 | 34 | /* FIXME: have lib/report/report.c _disp function call lv_size()? */ |
5d370b1b | 35 | uint64_t lvm_lv_get_size(const lv_t lv) |
83f25cd1 | 36 | { |
9e7b0091 | 37 | return SECTOR_SIZE * lv_size(lv); |
83f25cd1 DW |
38 | } |
39 | ||
298ec21e | 40 | const char *lvm_lv_get_uuid(const lv_t lv) |
f032ed74 | 41 | { |
254d672d | 42 | return lv_uuid_dup(lv); |
f032ed74 DW |
43 | } |
44 | ||
298ec21e | 45 | const char *lvm_lv_get_name(const lv_t lv) |
f032ed74 | 46 | { |
298ec21e DW |
47 | return dm_pool_strndup(lv->vg->vgmem, (const char *)lv->name, |
48 | NAME_LEN+1); | |
f032ed74 DW |
49 | } |
50 | ||
dd68ee88 DW |
51 | struct lvm_property_value lvm_lv_get_property(const lv_t lv, const char *name) |
52 | { | |
55429cde | 53 | return get_property(NULL, NULL, lv, NULL, NULL, name); |
5de70620 PR |
54 | } |
55 | ||
56 | struct lvm_property_value lvm_lvseg_get_property(const lvseg_t lvseg, | |
57 | const char *name) | |
58 | { | |
55429cde | 59 | return get_property(NULL, NULL, NULL, lvseg, NULL, name); |
dd68ee88 DW |
60 | } |
61 | ||
5d370b1b | 62 | uint64_t lvm_lv_is_active(const lv_t lv) |
2642ef55 DW |
63 | { |
64 | struct lvinfo info; | |
401a40d9 | 65 | if (lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) && |
2642ef55 DW |
66 | info.exists && info.live_table) |
67 | return 1; | |
68 | return 0; | |
69 | } | |
70 | ||
5d370b1b | 71 | uint64_t lvm_lv_is_suspended(const lv_t lv) |
2642ef55 DW |
72 | { |
73 | struct lvinfo info; | |
401a40d9 | 74 | if (lv_info(lv->vg->cmd, lv, 0, &info, 0, 0) && |
2642ef55 DW |
75 | info.exists && info.suspended) |
76 | return 1; | |
77 | return 0; | |
78 | } | |
79 | ||
a6ca9ac0 DW |
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 | ||
7a35a9f5 DW |
105 | /* Set defaults for non-segment specific LV parameters */ |
106 | static void _lv_set_default_params(struct lvcreate_params *lp, | |
7510963f | 107 | vg_t vg, const char *lvname, |
7a35a9f5 DW |
108 | uint64_t extents) |
109 | { | |
110 | lp->zero = 1; | |
111 | lp->major = -1; | |
112 | lp->minor = -1; | |
453cdee5 | 113 | lp->activate = CHANGE_AY; |
7a35a9f5 DW |
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; | |
f8452d8c | 122 | dm_list_init(&lp->tags); |
7a35a9f5 DW |
123 | } |
124 | ||
125 | /* Set default for linear segment specific LV parameters */ | |
73e62cdc | 126 | static int _lv_set_default_linear_params(struct cmd_context *cmd, |
7a35a9f5 DW |
127 | struct lvcreate_params *lp) |
128 | { | |
73e62cdc ZK |
129 | if (!(lp->segtype = get_segtype_from_string(cmd, "striped"))) { |
130 | log_error(INTERNAL_ERROR "Segtype striped not found."); | |
131 | return 0; | |
132 | } | |
133 | ||
7a35a9f5 DW |
134 | lp->stripes = 1; |
135 | lp->stripe_size = DEFAULT_STRIPESIZE * 2; | |
73e62cdc ZK |
136 | |
137 | return 1; | |
7a35a9f5 DW |
138 | } |
139 | ||
88e3ced7 DW |
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 | */ | |
5d370b1b | 145 | lv_t lvm_vg_create_lv_linear(vg_t vg, const char *name, uint64_t size) |
7a35a9f5 DW |
146 | { |
147 | struct lvcreate_params lp; | |
148 | uint64_t extents; | |
149 | struct lv_list *lvl; | |
150 | ||
7a35a9f5 DW |
151 | if (vg_read_error(vg)) |
152 | return NULL; | |
afcd9399 DW |
153 | if (!vg_check_write_mode(vg)) |
154 | return NULL; | |
7a35a9f5 | 155 | memset(&lp, 0, sizeof(lp)); |
9e7b0091 AK |
156 | extents = extents_from_size(vg->cmd, size / SECTOR_SIZE, |
157 | vg->extent_size); | |
7a35a9f5 | 158 | _lv_set_default_params(&lp, vg, name, extents); |
73e62cdc ZK |
159 | if (!_lv_set_default_linear_params(vg->cmd, &lp)) |
160 | return_NULL; | |
7a35a9f5 DW |
161 | if (!lv_create_single(vg, &lp)) |
162 | return NULL; | |
163 | lvl = find_lv_in_vg(vg, name); | |
164 | if (!lvl) | |
165 | return NULL; | |
5d370b1b | 166 | return (lv_t) lvl->lv; |
7a35a9f5 DW |
167 | } |
168 | ||
88e3ced7 DW |
169 | /* |
170 | * FIXME: This function should probably not commit to disk but require calling | |
171 | * lvm_vg_write. | |
172 | */ | |
5d370b1b | 173 | int lvm_vg_remove_lv(lv_t lv) |
8bcb9683 DW |
174 | { |
175 | if (!lv || !lv->vg || vg_read_error(lv->vg)) | |
f864285b | 176 | return -1; |
afcd9399 DW |
177 | if (!vg_check_write_mode(lv->vg)) |
178 | return -1; | |
f864285b DW |
179 | if (!lv_remove_single(lv->vg->cmd, lv, DONT_PROMPT)) |
180 | return -1; | |
181 | return 0; | |
8bcb9683 | 182 | } |
63b186b6 | 183 | |
5d370b1b | 184 | int lvm_lv_activate(lv_t lv) |
63b186b6 DW |
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) { | |
df621aa3 | 191 | log_error("Unable to activate locked LV"); |
63b186b6 DW |
192 | return -1; |
193 | } | |
194 | ||
195 | /* FIXME: handle lvconvert stuff later */ | |
196 | if (lv->status & CONVERTING) { | |
df621aa3 | 197 | log_error("Unable to activate LV with in-progress lvconvert"); |
63b186b6 DW |
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)) { | |
df621aa3 | 205 | log_error("Activate exclusive failed."); |
63b186b6 DW |
206 | return -1; |
207 | } | |
208 | } else { | |
209 | log_verbose("Activating logical volume \"%s\"", | |
210 | lv->name); | |
211 | if (!activate_lv(lv->vg->cmd, lv)) { | |
df621aa3 | 212 | log_error("Activate failed."); |
63b186b6 DW |
213 | return -1; |
214 | } | |
215 | } | |
216 | return 0; | |
217 | } | |
218 | ||
5d370b1b | 219 | int lvm_lv_deactivate(lv_t lv) |
63b186b6 DW |
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)) { | |
df621aa3 | 226 | log_error("Deactivate failed."); |
63b186b6 DW |
227 | return -1; |
228 | } | |
229 | return 0; | |
230 | } | |
ee7e183f | 231 | |
ecc51116 PR |
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 | ||
14b0c96b PR |
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 | ||
5219fe3c PR |
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 | } | |
eae8784a ZK |
279 | |
280 | if (!id_read_format(&id, uuid)) { | |
281 | log_errno(EINVAL, "Invalid UUID format."); | |
282 | return NULL; | |
5219fe3c | 283 | } |
eae8784a | 284 | |
5219fe3c PR |
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 | } | |
5d370b1b | 292 | int lvm_lv_resize(const lv_t lv, uint64_t new_size) |
ee7e183f DW |
293 | { |
294 | /* FIXME: add lv resize code here */ | |
df621aa3 | 295 | log_error("NOT IMPLEMENTED YET"); |
ee7e183f DW |
296 | return -1; |
297 | } |