Tizen 2.1 base
[external/device-mapper.git] / tools / vgsplit.c
1 /*
2  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3  * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
4  *
5  * This file is part of LVM2.
6  *
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.
10  *
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
14  */
15
16 #include "tools.h"
17
18 /* FIXME Why not (lv->vg == vg) ? */
19 static int _lv_is_in_vg(struct volume_group *vg, struct logical_volume *lv)
20 {
21         struct lv_list *lvl;
22
23         dm_list_iterate_items(lvl, &vg->lvs)
24                 if (lv == lvl->lv)
25                          return 1;
26
27         return 0;
28 }
29
30 static int _move_one_lv(struct volume_group *vg_from,
31                          struct volume_group *vg_to,
32                          struct dm_list *lvh)
33 {
34         struct logical_volume *lv = dm_list_item(lvh, struct lv_list)->lv;
35
36         dm_list_move(&vg_to->lvs, lvh);
37         lv->vg = vg_to;
38
39         if (lv_is_active(lv)) {
40                 log_error("Logical volume \"%s\" must be inactive", lv->name);
41                 return 0;
42         }
43
44         return 1;
45 }
46
47 static int _move_lvs(struct volume_group *vg_from, struct volume_group *vg_to)
48 {
49         struct dm_list *lvh, *lvht;
50         struct logical_volume *lv;
51         struct lv_segment *seg;
52         struct physical_volume *pv;
53         struct volume_group *vg_with;
54         unsigned s;
55
56         dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
57                 lv = dm_list_item(lvh, struct lv_list)->lv;
58
59                 if ((lv->status & SNAPSHOT))
60                         continue;
61
62                 if ((lv->status & MIRRORED))
63                         continue;
64
65                 /* Ensure all the PVs used by this LV remain in the same */
66                 /* VG as each other */
67                 vg_with = NULL;
68                 dm_list_iterate_items(seg, &lv->segments) {
69                         for (s = 0; s < seg->area_count; s++) {
70                                 /* FIXME Check AREA_LV too */
71                                 if (seg_type(seg, s) != AREA_PV)
72                                         continue;
73
74                                 pv = seg_pv(seg, s);
75                                 if (vg_with) {
76                                         if (!pv_is_in_vg(vg_with, pv)) {
77                                                 log_error("Can't split Logical "
78                                                           "Volume %s between "
79                                                           "two Volume Groups",
80                                                           lv->name);
81                                                 return 0;
82                                         }
83                                         continue;
84                                 }
85
86                                 if (pv_is_in_vg(vg_from, pv)) {
87                                         vg_with = vg_from;
88                                         continue;
89                                 }
90                                 if (pv_is_in_vg(vg_to, pv)) {
91                                         vg_with = vg_to;
92                                         continue;
93                                 }
94                                 log_error("Physical Volume %s not found",
95                                           pv_dev_name(pv));
96                                 return 0;
97                         }
98
99                 }
100
101                 if (vg_with == vg_from)
102                         continue;
103
104                 /* Move this LV */
105                 if (!_move_one_lv(vg_from, vg_to, lvh))
106                         return_0;
107         }
108
109         /* FIXME Ensure no LVs contain segs pointing at LVs in the other VG */
110
111         return 1;
112 }
113
114 /*
115  * Move the hidden / internal "snapshotN" LVs.from 'vg_from' to 'vg_to'.
116  */
117 static int _move_snapshots(struct volume_group *vg_from,
118                            struct volume_group *vg_to)
119 {
120         struct dm_list *lvh, *lvht;
121         struct logical_volume *lv;
122         struct lv_segment *seg;
123         int cow_from = 0;
124         int origin_from = 0;
125
126         dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
127                 lv = dm_list_item(lvh, struct lv_list)->lv;
128
129                 if (!(lv->status & SNAPSHOT))
130                         continue;
131
132                 dm_list_iterate_items(seg, &lv->segments) {
133                         cow_from = _lv_is_in_vg(vg_from, seg->cow);
134                         origin_from = _lv_is_in_vg(vg_from, seg->origin);
135
136                         if (cow_from && origin_from)
137                                 continue;
138                         if ((!cow_from && origin_from) ||
139                              (cow_from && !origin_from)) {
140                                 log_error("Can't split snapshot %s between"
141                                           " two Volume Groups", seg->cow->name);
142                                 return 0;
143                         }
144
145                         /*
146                          * At this point, the cow and origin should already be
147                          * in vg_to.
148                          */
149                         if (_lv_is_in_vg(vg_to, seg->cow) &&
150                             _lv_is_in_vg(vg_to, seg->origin)) {
151                                 if (!_move_one_lv(vg_from, vg_to, lvh))
152                                         return_0;
153                         }
154                 }
155
156         }
157
158         return 1;
159 }
160
161 static int _move_mirrors(struct volume_group *vg_from,
162                          struct volume_group *vg_to)
163 {
164         struct dm_list *lvh, *lvht;
165         struct logical_volume *lv;
166         struct lv_segment *seg;
167         unsigned s, seg_in, log_in;
168
169         dm_list_iterate_safe(lvh, lvht, &vg_from->lvs) {
170                 lv = dm_list_item(lvh, struct lv_list)->lv;
171
172                 if (!(lv->status & MIRRORED))
173                         continue;
174
175                 seg = first_seg(lv);
176
177                 seg_in = 0;
178                 for (s = 0; s < seg->area_count; s++)
179                         if (_lv_is_in_vg(vg_to, seg_lv(seg, s)))
180                             seg_in++;
181
182                 log_in = (!seg->log_lv || _lv_is_in_vg(vg_to, seg->log_lv));
183
184                 if ((seg_in && seg_in < seg->area_count) ||
185                     (seg_in && seg->log_lv && !log_in) ||
186                     (!seg_in && seg->log_lv && log_in)) {
187                         log_error("Can't split mirror %s between "
188                                   "two Volume Groups", lv->name);
189                         return 0;
190                 }
191
192                 if (seg_in == seg->area_count && log_in) {
193                         if (!_move_one_lv(vg_from, vg_to, lvh))
194                                 return_0;
195                 }
196         }
197
198         return 1;
199 }
200
201 /*
202  * Create or open the destination of the vgsplit operation.
203  * Returns
204  * - non-NULL: VG handle w/VG lock held
205  * - NULL: no VG lock held
206  */
207 static struct volume_group *_vgsplit_to(struct cmd_context *cmd,
208                                         const char *vg_name_to,
209                                         int *existing_vg)
210 {
211         struct volume_group *vg_to = NULL;
212
213         log_verbose("Checking for new volume group \"%s\"", vg_name_to);
214         /*
215          * First try to create a new VG.  If we cannot create it,
216          * and we get FAILED_EXIST (we will not be holding a lock),
217          * a VG must already exist with this name.  We then try to
218          * read the existing VG - the vgsplit will be into an existing VG.
219          *
220          * Otherwise, if the lock was successful, it must be the case that
221          * we obtained a WRITE lock and could not find the vgname in the
222          * system.  Thus, the split will be into a new VG.
223          */
224         vg_to = vg_create(cmd, vg_name_to);
225         if (vg_read_error(vg_to) == FAILED_LOCKING) {
226                 log_error("Can't get lock for %s", vg_name_to);
227                 free_vg(vg_to);
228                 return NULL;
229         }
230         if (vg_read_error(vg_to) == FAILED_EXIST) {
231                 *existing_vg = 1;
232                 free_vg(vg_to);
233                 vg_to = vg_read_for_update(cmd, vg_name_to, NULL, 0);
234
235                 if (vg_read_error(vg_to)) {
236                         free_vg(vg_to);
237                         stack;
238                         return NULL;
239                 }
240
241         } else if (vg_read_error(vg_to) == SUCCESS) {
242                 *existing_vg = 0;
243         }
244         return vg_to;
245 }
246
247 /*
248  * Open the source of the vgsplit operation.
249  * Returns
250  * - non-NULL: VG handle w/VG lock held
251  * - NULL: no VG lock held
252  */
253 static struct volume_group *_vgsplit_from(struct cmd_context *cmd,
254                                           const char *vg_name_from)
255 {
256         struct volume_group *vg_from;
257
258         log_verbose("Checking for volume group \"%s\"", vg_name_from);
259
260         vg_from = vg_read_for_update(cmd, vg_name_from, NULL, 0);
261         if (vg_read_error(vg_from)) {
262                 free_vg(vg_from);
263                 return NULL;
264         }
265         return vg_from;
266 }
267
268 /*
269  * Has the user given an option related to a new vg as the split destination?
270  */
271 static int new_vg_option_specified(struct cmd_context *cmd)
272 {
273         return(arg_count(cmd, clustered_ARG) ||
274                arg_count(cmd, alloc_ARG) ||
275                arg_count(cmd, maxphysicalvolumes_ARG) ||
276                arg_count(cmd, maxlogicalvolumes_ARG) ||
277                arg_count(cmd, vgmetadatacopies_ARG));
278 }
279
280 int vgsplit(struct cmd_context *cmd, int argc, char **argv)
281 {
282         struct vgcreate_params vp_new;
283         struct vgcreate_params vp_def;
284         char *vg_name_from, *vg_name_to;
285         struct volume_group *vg_to = NULL, *vg_from = NULL;
286         int opt;
287         int existing_vg = 0;
288         int r = ECMD_FAILED;
289         const char *lv_name;
290         int lock_vg_from_first = 1;
291
292         if ((arg_count(cmd, name_ARG) + argc) < 3) {
293                 log_error("Existing VG, new VG and either physical volumes "
294                           "or logical volume required.");
295                 return EINVALID_CMD_LINE;
296         }
297
298         if (arg_count(cmd, name_ARG) && (argc > 2)) {
299                 log_error("A logical volume name cannot be given with "
300                           "physical volumes.");
301                 return ECMD_FAILED;
302         }
303
304         if (arg_count(cmd, name_ARG))
305                 lv_name = arg_value(cmd, name_ARG);
306         else
307                 lv_name = NULL;
308
309         vg_name_from = skip_dev_dir(cmd, argv[0], NULL);
310         vg_name_to = skip_dev_dir(cmd, argv[1], NULL);
311         argc -= 2;
312         argv += 2;
313
314         if (!strcmp(vg_name_to, vg_name_from)) {
315                 log_error("Duplicate volume group name \"%s\"", vg_name_from);
316                 return ECMD_FAILED;
317         }
318
319         if (strcmp(vg_name_to, vg_name_from) < 0)
320                 lock_vg_from_first = 0;
321
322         if (lock_vg_from_first) {
323                 vg_from = _vgsplit_from(cmd, vg_name_from);
324                 if (!vg_from) {
325                         stack;
326                         return ECMD_FAILED;
327                 }
328                 /*
329                  * Set metadata format of original VG.
330                  * NOTE: We must set the format before calling vg_create()
331                  * since vg_create() calls the per-format constructor.
332                  */
333                 cmd->fmt = vg_from->fid->fmt;
334
335                 vg_to = _vgsplit_to(cmd, vg_name_to, &existing_vg);
336                 if (!vg_to) {
337                         unlock_and_free_vg(cmd, vg_from, vg_name_from);
338                         stack;
339                         return ECMD_FAILED;
340                 }
341         } else {
342                 vg_to = _vgsplit_to(cmd, vg_name_to, &existing_vg);
343                 if (!vg_to) {
344                         stack;
345                         return ECMD_FAILED;
346                 }
347                 vg_from = _vgsplit_from(cmd, vg_name_from);
348                 if (!vg_from) {
349                         unlock_and_free_vg(cmd, vg_to, vg_name_to);
350                         stack;
351                         return ECMD_FAILED;
352                 }
353
354                 if (cmd->fmt != vg_from->fid->fmt) {
355                         /* In this case we don't know the vg_from->fid->fmt */
356                         log_error("Unable to set new VG metadata type based on "
357                                   "source VG format - use -M option.");
358                         goto bad;
359                 }
360         }
361
362         if (existing_vg) {
363                 if (new_vg_option_specified(cmd)) {
364                         log_error("Volume group \"%s\" exists, but new VG "
365                                     "option specified", vg_name_to);
366                         goto bad;
367                 }
368                 if (!vgs_are_compatible(cmd, vg_from,vg_to))
369                         goto_bad;
370         } else {
371                 vgcreate_params_set_defaults(&vp_def, vg_from);
372                 vp_def.vg_name = vg_name_to;
373                 if (vgcreate_params_set_from_args(cmd, &vp_new, &vp_def)) {
374                         r = EINVALID_CMD_LINE;
375                         goto_bad;
376                 }
377
378                 if (vgcreate_params_validate(cmd, &vp_new)) {
379                         r = EINVALID_CMD_LINE;
380                         goto_bad;
381                 }
382
383                 if (!vg_set_extent_size(vg_to, vp_new.extent_size) ||
384                     !vg_set_max_lv(vg_to, vp_new.max_lv) ||
385                     !vg_set_max_pv(vg_to, vp_new.max_pv) ||
386                     !vg_set_alloc_policy(vg_to, vp_new.alloc) ||
387                     !vg_set_clustered(vg_to, vp_new.clustered) ||
388                     !vg_set_mda_copies(vg_to, vp_new.vgmetadatacopies))
389                         goto_bad;
390         }
391
392         /* Archive vg_from before changing it */
393         if (!archive(vg_from))
394                 goto_bad;
395
396         /* Move PVs across to new structure */
397         for (opt = 0; opt < argc; opt++) {
398                 unescape_colons_and_at_signs(argv[opt], NULL, NULL);
399                 if (!move_pv(vg_from, vg_to, argv[opt]))
400                         goto_bad;
401         }
402
403         /* If an LV given on the cmdline, move used_by PVs */
404         if (lv_name && !move_pvs_used_by_lv(vg_from, vg_to, lv_name))
405                 goto_bad;
406
407         /* Move required LVs across, checking consistency */
408         if (!(_move_lvs(vg_from, vg_to)))
409                 goto_bad;
410
411         /* FIXME Separate the 'move' from the 'validation' to fix dev stacks */
412         /* Move required mirrors across */
413         if (!(_move_mirrors(vg_from, vg_to)))
414                 goto_bad;
415
416         /* Move required snapshots across */
417         if (!(_move_snapshots(vg_from, vg_to)))
418                 goto_bad;
419
420         /* Split metadata areas and check if both vgs have at least one area */
421         if (!(vg_split_mdas(cmd, vg_from, vg_to)) && vg_from->pv_count) {
422                 log_error("Cannot split: Nowhere to store metadata for new Volume Group");
423                 goto bad;
424         }
425
426         /* Set proper name for all PVs in new VG */
427         if (!vg_rename(cmd, vg_to, vg_name_to))
428                 goto_bad;
429
430         /* store it on disks */
431         log_verbose("Writing out updated volume groups");
432
433         /*
434          * First, write out the new VG as EXPORTED.  We do this first in case
435          * there is a crash - we will still have the new VG information, in an
436          * exported state.  Recovery after this point would be removal of the
437          * new VG and redoing the vgsplit.
438          * FIXME: recover automatically or instruct the user?
439          */
440         vg_to->status |= EXPORTED_VG;
441
442         if (!archive(vg_to))
443                 goto_bad;
444
445         if (!vg_write(vg_to) || !vg_commit(vg_to))
446                 goto_bad;
447
448         backup(vg_to);
449
450         /*
451          * Next, write out the updated old VG.  If we crash after this point,
452          * recovery is a vgimport on the new VG.
453          * FIXME: recover automatically or instruct the user?
454          */
455         if (vg_from->pv_count) {
456                 if (!vg_write(vg_from) || !vg_commit(vg_from))
457                         goto_bad;
458
459                 backup(vg_from);
460         }
461
462         /*
463          * Finally, remove the EXPORTED flag from the new VG and write it out.
464          */
465         if (!test_mode()) {
466                 free_vg(vg_to);
467                 vg_to = vg_read_for_update(cmd, vg_name_to, NULL,
468                                            READ_ALLOW_EXPORTED);
469                 if (vg_read_error(vg_to)) {
470                         log_error("Volume group \"%s\" became inconsistent: "
471                                   "please fix manually", vg_name_to);
472                         goto bad;
473                 }
474         }
475
476         vg_to->status &= ~EXPORTED_VG;
477
478         if (!vg_write(vg_to) || !vg_commit(vg_to))
479                 goto_bad;
480
481         backup(vg_to);
482
483         log_print("%s volume group \"%s\" successfully split from \"%s\"",
484                   existing_vg ? "Existing" : "New",
485                   vg_to->name, vg_from->name);
486
487         r = ECMD_PROCESSED;
488
489 bad:
490         if (lock_vg_from_first) {
491                 unlock_and_free_vg(cmd, vg_to, vg_name_to);
492                 unlock_and_free_vg(cmd, vg_from, vg_name_from);
493         } else {
494                 unlock_and_free_vg(cmd, vg_from, vg_name_from);
495                 unlock_and_free_vg(cmd, vg_to, vg_name_to);
496         }
497         return r;
498 }