lvconvert.c revision 1.1 1 1.1 haad /* $NetBSD: lvconvert.c,v 1.1 2008/12/22 00:19:01 haad Exp $ */
2 1.1 haad
3 1.1 haad /*
4 1.1 haad * Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
5 1.1 haad *
6 1.1 haad * This file is part of LVM2.
7 1.1 haad *
8 1.1 haad * This copyrighted material is made available to anyone wishing to use,
9 1.1 haad * modify, copy, or redistribute it subject to the terms and conditions
10 1.1 haad * of the GNU Lesser General Public License v.2.1.
11 1.1 haad *
12 1.1 haad * You should have received a copy of the GNU Lesser General Public License
13 1.1 haad * along with this program; if not, write to the Free Software Foundation,
14 1.1 haad * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
15 1.1 haad */
16 1.1 haad
17 1.1 haad #include "tools.h"
18 1.1 haad #include "polldaemon.h"
19 1.1 haad #include "lv_alloc.h"
20 1.1 haad
21 1.1 haad struct lvconvert_params {
22 1.1 haad int snapshot;
23 1.1 haad int zero;
24 1.1 haad
25 1.1 haad const char *origin;
26 1.1 haad const char *lv_name;
27 1.1 haad const char *lv_name_full;
28 1.1 haad const char *vg_name;
29 1.1 haad int wait_completion;
30 1.1 haad int need_polling;
31 1.1 haad
32 1.1 haad uint32_t chunk_size;
33 1.1 haad uint32_t region_size;
34 1.1 haad
35 1.1 haad uint32_t mirrors;
36 1.1 haad sign_t mirrors_sign;
37 1.1 haad
38 1.1 haad struct segment_type *segtype;
39 1.1 haad
40 1.1 haad alloc_policy_t alloc;
41 1.1 haad
42 1.1 haad int pv_count;
43 1.1 haad char **pvs;
44 1.1 haad struct dm_list *pvh;
45 1.1 haad };
46 1.1 haad
47 1.1 haad static int _lvconvert_name_params(struct lvconvert_params *lp,
48 1.1 haad struct cmd_context *cmd,
49 1.1 haad int *pargc, char ***pargv)
50 1.1 haad {
51 1.1 haad char *ptr;
52 1.1 haad const char *vg_name = NULL;
53 1.1 haad
54 1.1 haad if (lp->snapshot) {
55 1.1 haad if (!*pargc) {
56 1.1 haad log_error("Please specify a logical volume to act as "
57 1.1 haad "the snapshot origin.");
58 1.1 haad return 0;
59 1.1 haad }
60 1.1 haad
61 1.1 haad lp->origin = *pargv[0];
62 1.1 haad (*pargv)++, (*pargc)--;
63 1.1 haad if (!(lp->vg_name = extract_vgname(cmd, lp->origin))) {
64 1.1 haad log_error("The origin name should include the "
65 1.1 haad "volume group.");
66 1.1 haad return 0;
67 1.1 haad }
68 1.1 haad
69 1.1 haad /* Strip the volume group from the origin */
70 1.1 haad if ((ptr = strrchr(lp->origin, (int) '/')))
71 1.1 haad lp->origin = ptr + 1;
72 1.1 haad }
73 1.1 haad
74 1.1 haad if (!*pargc) {
75 1.1 haad log_error("Please provide logical volume path");
76 1.1 haad return 0;
77 1.1 haad }
78 1.1 haad
79 1.1 haad lp->lv_name = lp->lv_name_full = (*pargv)[0];
80 1.1 haad (*pargv)++, (*pargc)--;
81 1.1 haad
82 1.1 haad if (strchr(lp->lv_name_full, '/') &&
83 1.1 haad (vg_name = extract_vgname(cmd, lp->lv_name_full)) &&
84 1.1 haad lp->vg_name && strcmp(vg_name, lp->vg_name)) {
85 1.1 haad log_error("Please use a single volume group name "
86 1.1 haad "(\"%s\" or \"%s\")", vg_name, lp->vg_name);
87 1.1 haad return 0;
88 1.1 haad }
89 1.1 haad
90 1.1 haad if (!lp->vg_name)
91 1.1 haad lp->vg_name = vg_name;
92 1.1 haad
93 1.1 haad if (!validate_name(lp->vg_name)) {
94 1.1 haad log_error("Please provide a valid volume group name");
95 1.1 haad return 0;
96 1.1 haad }
97 1.1 haad
98 1.1 haad if ((ptr = strrchr(lp->lv_name_full, '/')))
99 1.1 haad lp->lv_name = ptr + 1;
100 1.1 haad
101 1.1 haad if (!apply_lvname_restrictions(lp->lv_name))
102 1.1 haad return_0;
103 1.1 haad
104 1.1 haad return 1;
105 1.1 haad }
106 1.1 haad
107 1.1 haad static int _read_params(struct lvconvert_params *lp, struct cmd_context *cmd,
108 1.1 haad int argc, char **argv)
109 1.1 haad {
110 1.1 haad int region_size;
111 1.1 haad int pagesize = lvm_getpagesize();
112 1.1 haad
113 1.1 haad memset(lp, 0, sizeof(*lp));
114 1.1 haad
115 1.1 haad if (arg_count(cmd, snapshot_ARG) &&
116 1.1 haad (arg_count(cmd, mirrorlog_ARG) || arg_count(cmd, mirrors_ARG))) {
117 1.1 haad log_error("--snapshots argument cannot be mixed "
118 1.1 haad "with --mirrors or --log");
119 1.1 haad return 0;
120 1.1 haad }
121 1.1 haad
122 1.1 haad if (!arg_count(cmd, background_ARG))
123 1.1 haad lp->wait_completion = 1;
124 1.1 haad
125 1.1 haad if (arg_count(cmd, snapshot_ARG))
126 1.1 haad lp->snapshot = 1;
127 1.1 haad
128 1.1 haad if (arg_count(cmd, mirrors_ARG)) {
129 1.1 haad lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0);
130 1.1 haad lp->mirrors_sign = arg_sign_value(cmd, mirrors_ARG, 0);
131 1.1 haad }
132 1.1 haad
133 1.1 haad lp->alloc = ALLOC_INHERIT;
134 1.1 haad if (arg_count(cmd, alloc_ARG))
135 1.1 haad lp->alloc = arg_uint_value(cmd, alloc_ARG, lp->alloc);
136 1.1 haad
137 1.1 haad if (lp->snapshot) {
138 1.1 haad if (arg_count(cmd, regionsize_ARG)) {
139 1.1 haad log_error("--regionsize is only available with mirrors");
140 1.1 haad return 0;
141 1.1 haad }
142 1.1 haad
143 1.1 haad if (arg_sign_value(cmd, chunksize_ARG, 0) == SIGN_MINUS) {
144 1.1 haad log_error("Negative chunk size is invalid");
145 1.1 haad return 0;
146 1.1 haad }
147 1.1 haad lp->chunk_size = arg_uint_value(cmd, chunksize_ARG, 8);
148 1.1 haad if (lp->chunk_size < 8 || lp->chunk_size > 1024 ||
149 1.1 haad (lp->chunk_size & (lp->chunk_size - 1))) {
150 1.1 haad log_error("Chunk size must be a power of 2 in the "
151 1.1 haad "range 4K to 512K");
152 1.1 haad return 0;
153 1.1 haad }
154 1.1 haad log_verbose("Setting chunksize to %d sectors.", lp->chunk_size);
155 1.1 haad
156 1.1 haad if (!(lp->segtype = get_segtype_from_string(cmd, "snapshot")))
157 1.1 haad return_0;
158 1.1 haad
159 1.1 haad lp->zero = strcmp(arg_str_value(cmd, zero_ARG,
160 1.1 haad (lp->segtype->flags &
161 1.1 haad SEG_CANNOT_BE_ZEROED) ?
162 1.1 haad "n" : "y"), "n");
163 1.1 haad
164 1.1 haad } else { /* Mirrors */
165 1.1 haad if (arg_count(cmd, chunksize_ARG)) {
166 1.1 haad log_error("--chunksize is only available with "
167 1.1 haad "snapshots");
168 1.1 haad return 0;
169 1.1 haad }
170 1.1 haad
171 1.1 haad if (arg_count(cmd, zero_ARG)) {
172 1.1 haad log_error("--zero is only available with snapshots");
173 1.1 haad return 0;
174 1.1 haad }
175 1.1 haad
176 1.1 haad /*
177 1.1 haad * --regionsize is only valid if converting an LV into a mirror.
178 1.1 haad * Checked when we know the state of the LV being converted.
179 1.1 haad */
180 1.1 haad
181 1.1 haad if (arg_count(cmd, regionsize_ARG)) {
182 1.1 haad if (arg_sign_value(cmd, regionsize_ARG, 0) ==
183 1.1 haad SIGN_MINUS) {
184 1.1 haad log_error("Negative regionsize is invalid");
185 1.1 haad return 0;
186 1.1 haad }
187 1.1 haad lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
188 1.1 haad } else {
189 1.1 haad region_size = 2 * find_config_tree_int(cmd,
190 1.1 haad "activation/mirror_region_size",
191 1.1 haad DEFAULT_MIRROR_REGION_SIZE);
192 1.1 haad if (region_size < 0) {
193 1.1 haad log_error("Negative regionsize in "
194 1.1 haad "configuration file is invalid");
195 1.1 haad return 0;
196 1.1 haad }
197 1.1 haad lp->region_size = region_size;
198 1.1 haad }
199 1.1 haad
200 1.1 haad if (lp->region_size % (pagesize >> SECTOR_SHIFT)) {
201 1.1 haad log_error("Region size (%" PRIu32 ") must be "
202 1.1 haad "a multiple of machine memory "
203 1.1 haad "page size (%d)",
204 1.1 haad lp->region_size, pagesize >> SECTOR_SHIFT);
205 1.1 haad return 0;
206 1.1 haad }
207 1.1 haad
208 1.1 haad if (lp->region_size & (lp->region_size - 1)) {
209 1.1 haad log_error("Region size (%" PRIu32
210 1.1 haad ") must be a power of 2", lp->region_size);
211 1.1 haad return 0;
212 1.1 haad }
213 1.1 haad
214 1.1 haad if (!lp->region_size) {
215 1.1 haad log_error("Non-zero region size must be supplied.");
216 1.1 haad return 0;
217 1.1 haad }
218 1.1 haad
219 1.1 haad if (!(lp->segtype = get_segtype_from_string(cmd, "mirror")))
220 1.1 haad return_0;
221 1.1 haad }
222 1.1 haad
223 1.1 haad if (activation() && lp->segtype->ops->target_present &&
224 1.1 haad !lp->segtype->ops->target_present(NULL, NULL)) {
225 1.1 haad log_error("%s: Required device-mapper target(s) not "
226 1.1 haad "detected in your kernel", lp->segtype->name);
227 1.1 haad return 0;
228 1.1 haad }
229 1.1 haad
230 1.1 haad if (!_lvconvert_name_params(lp, cmd, &argc, &argv))
231 1.1 haad return_0;
232 1.1 haad
233 1.1 haad lp->pv_count = argc;
234 1.1 haad lp->pvs = argv;
235 1.1 haad
236 1.1 haad return 1;
237 1.1 haad }
238 1.1 haad
239 1.1 haad
240 1.1 haad static struct volume_group *_get_lvconvert_vg(struct cmd_context *cmd,
241 1.1 haad const char *lv_name)
242 1.1 haad {
243 1.1 haad dev_close_all();
244 1.1 haad
245 1.1 haad return vg_lock_and_read(cmd, extract_vgname(cmd, lv_name),
246 1.1 haad NULL, LCK_VG_WRITE,
247 1.1 haad CLUSTERED | EXPORTED_VG | LVM_WRITE,
248 1.1 haad CORRECT_INCONSISTENT | FAIL_INCONSISTENT);
249 1.1 haad }
250 1.1 haad
251 1.1 haad static struct logical_volume *_get_lvconvert_lv(struct cmd_context *cmd __attribute((unused)),
252 1.1 haad struct volume_group *vg,
253 1.1 haad const char *name,
254 1.1 haad uint32_t lv_type __attribute((unused)))
255 1.1 haad {
256 1.1 haad return find_lv(vg, name);
257 1.1 haad }
258 1.1 haad
259 1.1 haad static int _update_lvconvert_mirror(struct cmd_context *cmd __attribute((unused)),
260 1.1 haad struct volume_group *vg __attribute((unused)),
261 1.1 haad struct logical_volume *lv __attribute((unused)),
262 1.1 haad struct dm_list *lvs_changed __attribute((unused)),
263 1.1 haad unsigned flags __attribute((unused)))
264 1.1 haad {
265 1.1 haad /* lvconvert mirror doesn't require periodical metadata update */
266 1.1 haad return 1;
267 1.1 haad }
268 1.1 haad
269 1.1 haad static int _finish_lvconvert_mirror(struct cmd_context *cmd,
270 1.1 haad struct volume_group *vg,
271 1.1 haad struct logical_volume *lv,
272 1.1 haad struct dm_list *lvs_changed __attribute((unused)))
273 1.1 haad {
274 1.1 haad if (!collapse_mirrored_lv(lv)) {
275 1.1 haad log_error("Failed to remove temporary sync layer.");
276 1.1 haad return 0;
277 1.1 haad }
278 1.1 haad
279 1.1 haad lv->status &= ~CONVERTING;
280 1.1 haad
281 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
282 1.1 haad
283 1.1 haad if (!vg_write(vg))
284 1.1 haad return_0;
285 1.1 haad
286 1.1 haad backup(vg);
287 1.1 haad
288 1.1 haad if (!suspend_lv(cmd, lv)) {
289 1.1 haad log_error("Failed to lock %s", lv->name);
290 1.1 haad vg_revert(vg);
291 1.1 haad return 0;
292 1.1 haad }
293 1.1 haad
294 1.1 haad if (!vg_commit(vg)) {
295 1.1 haad resume_lv(cmd, lv);
296 1.1 haad return 0;
297 1.1 haad }
298 1.1 haad
299 1.1 haad log_very_verbose("Updating \"%s\" in kernel", lv->name);
300 1.1 haad
301 1.1 haad if (!resume_lv(cmd, lv)) {
302 1.1 haad log_error("Problem reactivating %s", lv->name);
303 1.1 haad return 0;
304 1.1 haad }
305 1.1 haad
306 1.1 haad log_print("Logical volume %s converted.", lv->name);
307 1.1 haad
308 1.1 haad return 1;
309 1.1 haad }
310 1.1 haad
311 1.1 haad static struct poll_functions _lvconvert_mirror_fns = {
312 1.1 haad .get_copy_vg = _get_lvconvert_vg,
313 1.1 haad .get_copy_lv = _get_lvconvert_lv,
314 1.1 haad .update_metadata = _update_lvconvert_mirror,
315 1.1 haad .finish_copy = _finish_lvconvert_mirror,
316 1.1 haad };
317 1.1 haad
318 1.1 haad int lvconvert_poll(struct cmd_context *cmd, const char *lv_name,
319 1.1 haad unsigned background)
320 1.1 haad {
321 1.1 haad return poll_daemon(cmd, lv_name, background, 0, &_lvconvert_mirror_fns,
322 1.1 haad "Converted");
323 1.1 haad }
324 1.1 haad
325 1.1 haad static int _insert_lvconvert_layer(struct cmd_context *cmd,
326 1.1 haad struct logical_volume *lv)
327 1.1 haad {
328 1.1 haad char *format, *layer_name;
329 1.1 haad size_t len;
330 1.1 haad int i;
331 1.1 haad
332 1.1 haad /*
333 1.1 haad * We would like to give the same number for this layer
334 1.1 haad * and the newly added mimage.
335 1.1 haad * However, LV name of newly added mimage is determined *after*
336 1.1 haad * the LV name of this layer is determined.
337 1.1 haad *
338 1.1 haad * So, use generate_lv_name() to generate mimage name first
339 1.1 haad * and take the number from it.
340 1.1 haad */
341 1.1 haad
342 1.1 haad len = strlen(lv->name) + 32;
343 1.1 haad if (!(format = alloca(len)) ||
344 1.1 haad !(layer_name = alloca(len)) ||
345 1.1 haad dm_snprintf(format, len, "%s_mimage_%%d", lv->name) < 0) {
346 1.1 haad log_error("lvconvert: layer name allocation failed.");
347 1.1 haad return 0;
348 1.1 haad }
349 1.1 haad
350 1.1 haad if (!generate_lv_name(lv->vg, format, layer_name, len) ||
351 1.1 haad sscanf(layer_name, format, &i) != 1) {
352 1.1 haad log_error("lvconvert: layer name generation failed.");
353 1.1 haad return 0;
354 1.1 haad }
355 1.1 haad
356 1.1 haad if (dm_snprintf(layer_name, len, MIRROR_SYNC_LAYER "_%d", i) < 0) {
357 1.1 haad log_error("layer name allocation failed.");
358 1.1 haad return 0;
359 1.1 haad }
360 1.1 haad
361 1.1 haad if (!insert_layer_for_lv(cmd, lv, 0, layer_name)) {
362 1.1 haad log_error("Failed to insert resync layer");
363 1.1 haad return 0;
364 1.1 haad }
365 1.1 haad
366 1.1 haad return 1;
367 1.1 haad }
368 1.1 haad
369 1.1 haad /* walk down the stacked mirror LV to the original mirror LV */
370 1.1 haad static struct logical_volume *_original_lv(struct logical_volume *lv)
371 1.1 haad {
372 1.1 haad struct logical_volume *next_lv = lv, *tmp_lv;
373 1.1 haad
374 1.1 haad while ((tmp_lv = find_temporary_mirror(next_lv)))
375 1.1 haad next_lv = tmp_lv;
376 1.1 haad
377 1.1 haad return next_lv;
378 1.1 haad }
379 1.1 haad
380 1.1 haad static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * lv,
381 1.1 haad struct lvconvert_params *lp)
382 1.1 haad {
383 1.1 haad struct lv_segment *seg;
384 1.1 haad uint32_t existing_mirrors;
385 1.1 haad const char *mirrorlog;
386 1.1 haad unsigned corelog = 0;
387 1.1 haad struct logical_volume *original_lv;
388 1.1 haad
389 1.1 haad seg = first_seg(lv);
390 1.1 haad existing_mirrors = lv_mirror_count(lv);
391 1.1 haad
392 1.1 haad /* If called with no argument, try collapsing the resync layers */
393 1.1 haad if (!arg_count(cmd, mirrors_ARG) && !arg_count(cmd, mirrorlog_ARG) &&
394 1.1 haad !arg_count(cmd, corelog_ARG) && !arg_count(cmd, regionsize_ARG)) {
395 1.1 haad lp->need_polling = 1;
396 1.1 haad return 1;
397 1.1 haad }
398 1.1 haad
399 1.1 haad /*
400 1.1 haad * Adjust required number of mirrors
401 1.1 haad *
402 1.1 haad * We check mirrors_ARG again to see if it
403 1.1 haad * was supplied. If not, they want the mirror
404 1.1 haad * count to remain the same. They may be changing
405 1.1 haad * the logging type.
406 1.1 haad */
407 1.1 haad if (!arg_count(cmd, mirrors_ARG))
408 1.1 haad lp->mirrors = existing_mirrors;
409 1.1 haad else if (lp->mirrors_sign == SIGN_PLUS)
410 1.1 haad lp->mirrors = existing_mirrors + lp->mirrors;
411 1.1 haad else if (lp->mirrors_sign == SIGN_MINUS)
412 1.1 haad lp->mirrors = existing_mirrors - lp->mirrors;
413 1.1 haad else
414 1.1 haad lp->mirrors += 1;
415 1.1 haad
416 1.1 haad /*
417 1.1 haad * Did the user try to subtract more legs than available?
418 1.1 haad */
419 1.1 haad if (lp->mirrors < 1) {
420 1.1 haad log_error("Logical volume %s only has %" PRIu32 " mirrors.",
421 1.1 haad lv->name, existing_mirrors);
422 1.1 haad return 0;
423 1.1 haad }
424 1.1 haad
425 1.1 haad /*
426 1.1 haad * Adjust log type
427 1.1 haad */
428 1.1 haad if (arg_count(cmd, corelog_ARG))
429 1.1 haad corelog = 1;
430 1.1 haad
431 1.1 haad mirrorlog = arg_str_value(cmd, mirrorlog_ARG,
432 1.1 haad corelog ? "core" : DEFAULT_MIRRORLOG);
433 1.1 haad if (!strcmp("disk", mirrorlog)) {
434 1.1 haad if (corelog) {
435 1.1 haad log_error("--mirrorlog disk and --corelog "
436 1.1 haad "are incompatible");
437 1.1 haad return 0;
438 1.1 haad }
439 1.1 haad corelog = 0;
440 1.1 haad } else if (!strcmp("core", mirrorlog))
441 1.1 haad corelog = 1;
442 1.1 haad else {
443 1.1 haad log_error("Unknown mirrorlog type: %s", mirrorlog);
444 1.1 haad return 0;
445 1.1 haad }
446 1.1 haad
447 1.1 haad log_verbose("Setting logging type to %s", mirrorlog);
448 1.1 haad
449 1.1 haad /*
450 1.1 haad * Region size must not change on existing mirrors
451 1.1 haad */
452 1.1 haad if (arg_count(cmd, regionsize_ARG) && (lv->status & MIRRORED) &&
453 1.1 haad (lp->region_size != seg->region_size)) {
454 1.1 haad log_error("Mirror log region size cannot be changed on "
455 1.1 haad "an existing mirror.");
456 1.1 haad return 0;
457 1.1 haad }
458 1.1 haad
459 1.1 haad /*
460 1.1 haad * Converting from mirror to linear
461 1.1 haad */
462 1.1 haad if ((lp->mirrors == 1)) {
463 1.1 haad if (!(lv->status & MIRRORED)) {
464 1.1 haad log_error("Logical volume %s is already not mirrored.",
465 1.1 haad lv->name);
466 1.1 haad return 1;
467 1.1 haad }
468 1.1 haad
469 1.1 haad if (!lv_remove_mirrors(cmd, lv, existing_mirrors - 1, 1,
470 1.1 haad lp->pv_count ? lp->pvh : NULL, 0))
471 1.1 haad return_0;
472 1.1 haad goto commit_changes;
473 1.1 haad }
474 1.1 haad
475 1.1 haad /*
476 1.1 haad * Converting from linear to mirror
477 1.1 haad */
478 1.1 haad if (!(lv->status & MIRRORED)) {
479 1.1 haad /* FIXME Share code with lvcreate */
480 1.1 haad
481 1.1 haad /* FIXME Why is this restriction here? Fix it! */
482 1.1 haad dm_list_iterate_items(seg, &lv->segments) {
483 1.1 haad if (seg_is_striped(seg) && seg->area_count > 1) {
484 1.1 haad log_error("Mirrors of striped volumes are not yet supported.");
485 1.1 haad return 0;
486 1.1 haad }
487 1.1 haad }
488 1.1 haad
489 1.1 haad if (!lv_add_mirrors(cmd, lv, lp->mirrors - 1, 1,
490 1.1 haad adjusted_mirror_region_size(
491 1.1 haad lv->vg->extent_size,
492 1.1 haad lv->le_count,
493 1.1 haad lp->region_size),
494 1.1 haad corelog ? 0U : 1U, lp->pvh, lp->alloc,
495 1.1 haad MIRROR_BY_LV))
496 1.1 haad return_0;
497 1.1 haad if (lp->wait_completion)
498 1.1 haad lp->need_polling = 1;
499 1.1 haad goto commit_changes;
500 1.1 haad }
501 1.1 haad
502 1.1 haad /*
503 1.1 haad * Converting from mirror to mirror with different leg count,
504 1.1 haad * or different log type.
505 1.1 haad */
506 1.1 haad if (dm_list_size(&lv->segments) != 1) {
507 1.1 haad log_error("Logical volume %s has multiple "
508 1.1 haad "mirror segments.", lv->name);
509 1.1 haad return 0;
510 1.1 haad }
511 1.1 haad
512 1.1 haad if (lp->mirrors == existing_mirrors) {
513 1.1 haad /*
514 1.1 haad * Convert Mirror log type
515 1.1 haad */
516 1.1 haad original_lv = _original_lv(lv);
517 1.1 haad if (!first_seg(original_lv)->log_lv && !corelog) {
518 1.1 haad if (!add_mirror_log(cmd, original_lv, 1,
519 1.1 haad adjusted_mirror_region_size(
520 1.1 haad lv->vg->extent_size,
521 1.1 haad lv->le_count,
522 1.1 haad lp->region_size),
523 1.1 haad lp->pvh, lp->alloc))
524 1.1 haad return_0;
525 1.1 haad } else if (first_seg(original_lv)->log_lv && corelog) {
526 1.1 haad if (!remove_mirror_log(cmd, original_lv,
527 1.1 haad lp->pv_count ? lp->pvh : NULL))
528 1.1 haad return_0;
529 1.1 haad } else {
530 1.1 haad /* No change */
531 1.1 haad log_error("Logical volume %s already has %"
532 1.1 haad PRIu32 " mirror(s).", lv->name,
533 1.1 haad lp->mirrors - 1);
534 1.1 haad if (lv->status & CONVERTING)
535 1.1 haad lp->need_polling = 1;
536 1.1 haad return 1;
537 1.1 haad }
538 1.1 haad } else if (lp->mirrors > existing_mirrors) {
539 1.1 haad if (lv->status & MIRROR_NOTSYNCED) {
540 1.1 haad log_error("Not adding mirror to mirrored LV "
541 1.1 haad "without initial resync");
542 1.1 haad return 0;
543 1.1 haad }
544 1.1 haad /*
545 1.1 haad * Log addition/removal should be done before the layer
546 1.1 haad * insertion to make the end result consistent with
547 1.1 haad * linear-to-mirror conversion.
548 1.1 haad */
549 1.1 haad original_lv = _original_lv(lv);
550 1.1 haad if (!first_seg(original_lv)->log_lv && !corelog) {
551 1.1 haad if (!add_mirror_log(cmd, original_lv, 1,
552 1.1 haad adjusted_mirror_region_size(
553 1.1 haad lv->vg->extent_size,
554 1.1 haad lv->le_count,
555 1.1 haad lp->region_size),
556 1.1 haad lp->pvh, lp->alloc))
557 1.1 haad return_0;
558 1.1 haad } else if (first_seg(original_lv)->log_lv && corelog) {
559 1.1 haad if (!remove_mirror_log(cmd, original_lv,
560 1.1 haad lp->pv_count ? lp->pvh : NULL))
561 1.1 haad return_0;
562 1.1 haad }
563 1.1 haad /* Insert a temporary layer for syncing,
564 1.1 haad * only if the original lv is using disk log. */
565 1.1 haad if (seg->log_lv && !_insert_lvconvert_layer(cmd, lv)) {
566 1.1 haad log_error("Failed to insert resync layer");
567 1.1 haad return 0;
568 1.1 haad }
569 1.1 haad /* FIXME: can't have multiple mlogs. force corelog. */
570 1.1 haad if (!lv_add_mirrors(cmd, lv, lp->mirrors - existing_mirrors, 1,
571 1.1 haad adjusted_mirror_region_size(
572 1.1 haad lv->vg->extent_size,
573 1.1 haad lv->le_count,
574 1.1 haad lp->region_size),
575 1.1 haad 0U, lp->pvh, lp->alloc,
576 1.1 haad MIRROR_BY_LV))
577 1.1 haad return_0;
578 1.1 haad lv->status |= CONVERTING;
579 1.1 haad lp->need_polling = 1;
580 1.1 haad } else {
581 1.1 haad /* Reduce number of mirrors */
582 1.1 haad if (!lv_remove_mirrors(cmd, lv, existing_mirrors - lp->mirrors,
583 1.1 haad corelog ? 1U : 0U,
584 1.1 haad lp->pv_count ? lp->pvh : NULL, 0))
585 1.1 haad return_0;
586 1.1 haad }
587 1.1 haad
588 1.1 haad commit_changes:
589 1.1 haad log_very_verbose("Updating logical volume \"%s\" on disk(s)", lv->name);
590 1.1 haad
591 1.1 haad if (!vg_write(lv->vg))
592 1.1 haad return_0;
593 1.1 haad
594 1.1 haad backup(lv->vg);
595 1.1 haad
596 1.1 haad if (!suspend_lv(cmd, lv)) {
597 1.1 haad log_error("Failed to lock %s", lv->name);
598 1.1 haad vg_revert(lv->vg);
599 1.1 haad return 0;
600 1.1 haad }
601 1.1 haad
602 1.1 haad if (!vg_commit(lv->vg)) {
603 1.1 haad resume_lv(cmd, lv);
604 1.1 haad return 0;
605 1.1 haad }
606 1.1 haad
607 1.1 haad log_very_verbose("Updating \"%s\" in kernel", lv->name);
608 1.1 haad
609 1.1 haad if (!resume_lv(cmd, lv)) {
610 1.1 haad log_error("Problem reactivating %s", lv->name);
611 1.1 haad return 0;
612 1.1 haad }
613 1.1 haad
614 1.1 haad if (!lp->need_polling)
615 1.1 haad log_print("Logical volume %s converted.", lv->name);
616 1.1 haad
617 1.1 haad return 1;
618 1.1 haad }
619 1.1 haad
620 1.1 haad static int lvconvert_snapshot(struct cmd_context *cmd,
621 1.1 haad struct logical_volume *lv,
622 1.1 haad struct lvconvert_params *lp)
623 1.1 haad {
624 1.1 haad struct logical_volume *org;
625 1.1 haad
626 1.1 haad if (!(org = find_lv(lv->vg, lp->origin))) {
627 1.1 haad log_error("Couldn't find origin volume '%s'.", lp->origin);
628 1.1 haad return 0;
629 1.1 haad }
630 1.1 haad
631 1.1 haad if (org == lv) {
632 1.1 haad log_error("Unable to use \"%s\" as both snapshot and origin.",
633 1.1 haad lv->name);
634 1.1 haad return 0;
635 1.1 haad }
636 1.1 haad
637 1.1 haad if (org->status & (LOCKED|PVMOVE|MIRRORED) || lv_is_cow(org)) {
638 1.1 haad log_error("Unable to create a snapshot of a %s LV.",
639 1.1 haad org->status & LOCKED ? "locked" :
640 1.1 haad org->status & PVMOVE ? "pvmove" :
641 1.1 haad org->status & MIRRORED ? "mirrored" :
642 1.1 haad "snapshot");
643 1.1 haad return 0;
644 1.1 haad }
645 1.1 haad
646 1.1 haad if (!lp->zero || !(lv->status & LVM_WRITE))
647 1.1 haad log_warn("WARNING: \"%s\" not zeroed", lv->name);
648 1.1 haad else if (!set_lv(cmd, lv, UINT64_C(0), 0)) {
649 1.1 haad log_error("Aborting. Failed to wipe snapshot "
650 1.1 haad "exception store.");
651 1.1 haad return 0;
652 1.1 haad }
653 1.1 haad
654 1.1 haad if (!deactivate_lv(cmd, lv)) {
655 1.1 haad log_error("Couldn't deactivate LV %s.", lv->name);
656 1.1 haad return 0;
657 1.1 haad }
658 1.1 haad
659 1.1 haad if (!vg_add_snapshot(NULL, org, lv, NULL, org->le_count,
660 1.1 haad lp->chunk_size)) {
661 1.1 haad log_error("Couldn't create snapshot.");
662 1.1 haad return 0;
663 1.1 haad }
664 1.1 haad
665 1.1 haad /* store vg on disk(s) */
666 1.1 haad if (!vg_write(lv->vg))
667 1.1 haad return_0;
668 1.1 haad
669 1.1 haad backup(lv->vg);
670 1.1 haad
671 1.1 haad if (!suspend_lv(cmd, org)) {
672 1.1 haad log_error("Failed to suspend origin %s", org->name);
673 1.1 haad vg_revert(lv->vg);
674 1.1 haad return 0;
675 1.1 haad }
676 1.1 haad
677 1.1 haad if (!vg_commit(lv->vg))
678 1.1 haad return_0;
679 1.1 haad
680 1.1 haad if (!resume_lv(cmd, org)) {
681 1.1 haad log_error("Problem reactivating origin %s", org->name);
682 1.1 haad return 0;
683 1.1 haad }
684 1.1 haad
685 1.1 haad log_print("Logical volume %s converted to snapshot.", lv->name);
686 1.1 haad
687 1.1 haad return 1;
688 1.1 haad }
689 1.1 haad
690 1.1 haad static int lvconvert_single(struct cmd_context *cmd, struct logical_volume *lv,
691 1.1 haad void *handle)
692 1.1 haad {
693 1.1 haad struct lvconvert_params *lp = handle;
694 1.1 haad
695 1.1 haad if (lv->status & LOCKED) {
696 1.1 haad log_error("Cannot convert locked LV %s", lv->name);
697 1.1 haad return ECMD_FAILED;
698 1.1 haad }
699 1.1 haad
700 1.1 haad if (lv_is_origin(lv)) {
701 1.1 haad log_error("Can't convert logical volume \"%s\" under snapshot",
702 1.1 haad lv->name);
703 1.1 haad return ECMD_FAILED;
704 1.1 haad }
705 1.1 haad
706 1.1 haad if (lv_is_cow(lv)) {
707 1.1 haad log_error("Can't convert snapshot logical volume \"%s\"",
708 1.1 haad lv->name);
709 1.1 haad return ECMD_FAILED;
710 1.1 haad }
711 1.1 haad
712 1.1 haad if (lv->status & PVMOVE) {
713 1.1 haad log_error("Unable to convert pvmove LV %s", lv->name);
714 1.1 haad return ECMD_FAILED;
715 1.1 haad }
716 1.1 haad
717 1.1 haad if (lp->snapshot) {
718 1.1 haad if (lv->status & MIRRORED) {
719 1.1 haad log_error("Unable to convert mirrored LV \"%s\" into a snapshot.", lv->name);
720 1.1 haad return ECMD_FAILED;
721 1.1 haad }
722 1.1 haad if (!archive(lv->vg))
723 1.1 haad return ECMD_FAILED;
724 1.1 haad if (!lvconvert_snapshot(cmd, lv, lp))
725 1.1 haad return ECMD_FAILED;
726 1.1 haad } else if (arg_count(cmd, mirrors_ARG) || (lv->status & MIRRORED)) {
727 1.1 haad if (!archive(lv->vg))
728 1.1 haad return ECMD_FAILED;
729 1.1 haad if (!lvconvert_mirrors(cmd, lv, lp))
730 1.1 haad return ECMD_FAILED;
731 1.1 haad }
732 1.1 haad
733 1.1 haad return ECMD_PROCESSED;
734 1.1 haad }
735 1.1 haad
736 1.1 haad int lvconvert(struct cmd_context * cmd, int argc, char **argv)
737 1.1 haad {
738 1.1 haad struct volume_group *vg;
739 1.1 haad struct lv_list *lvl;
740 1.1 haad struct lvconvert_params lp;
741 1.1 haad int ret = ECMD_FAILED;
742 1.1 haad struct lvinfo info;
743 1.1 haad
744 1.1 haad if (!_read_params(&lp, cmd, argc, argv)) {
745 1.1 haad stack;
746 1.1 haad return EINVALID_CMD_LINE;
747 1.1 haad }
748 1.1 haad
749 1.1 haad log_verbose("Checking for existing volume group \"%s\"", lp.vg_name);
750 1.1 haad
751 1.1 haad if (!(vg = vg_lock_and_read(cmd, lp.vg_name, NULL, LCK_VG_WRITE,
752 1.1 haad CLUSTERED | EXPORTED_VG | LVM_WRITE,
753 1.1 haad CORRECT_INCONSISTENT)))
754 1.1 haad return ECMD_FAILED;
755 1.1 haad
756 1.1 haad if (!(lvl = find_lv_in_vg(vg, lp.lv_name))) {
757 1.1 haad log_error("Logical volume \"%s\" not found in "
758 1.1 haad "volume group \"%s\"", lp.lv_name, lp.vg_name);
759 1.1 haad goto bad;
760 1.1 haad }
761 1.1 haad
762 1.1 haad if (lp.pv_count) {
763 1.1 haad if (!(lp.pvh = create_pv_list(cmd->mem, vg, lp.pv_count,
764 1.1 haad lp.pvs, 0)))
765 1.1 haad goto_bad;
766 1.1 haad } else
767 1.1 haad lp.pvh = &vg->pvs;
768 1.1 haad
769 1.1 haad ret = lvconvert_single(cmd, lvl->lv, &lp);
770 1.1 haad
771 1.1 haad bad:
772 1.1 haad unlock_vg(cmd, lp.vg_name);
773 1.1 haad
774 1.1 haad if (ret == ECMD_PROCESSED && lp.need_polling) {
775 1.1 haad if (!lv_info(cmd, lvl->lv, &info, 1, 0) || !info.exists) {
776 1.1 haad log_print("Conversion starts after activation");
777 1.1 haad return ret;
778 1.1 haad }
779 1.1 haad ret = lvconvert_poll(cmd, lp.lv_name_full,
780 1.1 haad lp.wait_completion ? 0 : 1U);
781 1.1 haad }
782 1.1 haad
783 1.1 haad return ret;
784 1.1 haad }
785