]> sourceware.org Git - lvm2.git/blame - tools/vgmerge.c
Reinstate accidentally-deleted line.
[lvm2.git] / tools / vgmerge.c
CommitLineData
da4e57f2 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5a820745 3 * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
da4e57f2 4 *
6606c3ae 5 * This file is part of LVM2.
da4e57f2 6 *
6606c3ae
AK
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
be684599 9 * of the GNU Lesser General Public License v.2.1.
da4e57f2 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae
AK
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
da4e57f2
AK
14 */
15
16#include "tools.h"
17
7c86e390
DW
18static struct volume_group *_vgmerge_vg_read(struct cmd_context *cmd,
19 const char *vg_name)
af9ded78 20{
7c86e390
DW
21 struct volume_group *vg;
22 log_verbose("Checking for volume group \"%s\"", vg_name);
23 vg = vg_read_for_update(cmd, vg_name, NULL, 0);
24 if (vg_read_error(vg)) {
077a6755 25 release_vg(vg);
af9ded78
DW
26 return NULL;
27 }
7c86e390 28 return vg;
af9ded78
DW
29}
30
8ef2b021
AK
31static int _vgmerge_single(struct cmd_context *cmd, const char *vg_name_to,
32 const char *vg_name_from)
da4e57f2 33{
0adfbfd5 34 struct pv_list *pvl, *tpvl;
da4e57f2 35 struct volume_group *vg_to, *vg_from;
f2b7349e 36 struct lv_list *lvl1, *lvl2;
043b1362 37 int r = ECMD_FAILED;
115bc65b 38 int lock_vg_from_first = 0;
da4e57f2
AK
39
40 if (!strcmp(vg_name_to, vg_name_from)) {
08907484 41 log_error("Duplicate volume group name \"%s\"", vg_name_from);
da4e57f2
AK
42 return ECMD_FAILED;
43 }
44
3d9c2d86
DW
45 if (strcmp(vg_name_to, vg_name_from) > 0)
46 lock_vg_from_first = 1;
f53c6aa6 47
3d9c2d86
DW
48 if (lock_vg_from_first) {
49 vg_from = _vgmerge_vg_read(cmd, vg_name_from);
651ff9b3
AK
50 if (!vg_from) {
51 stack;
3d9c2d86 52 return ECMD_FAILED;
651ff9b3 53 }
3d9c2d86
DW
54 vg_to = _vgmerge_vg_read(cmd, vg_name_to);
55 if (!vg_to) {
651ff9b3 56 stack;
077a6755 57 unlock_and_release_vg(cmd, vg_from, vg_name_from);
3d9c2d86
DW
58 return ECMD_FAILED;
59 }
60 } else {
61 vg_to = _vgmerge_vg_read(cmd, vg_name_to);
651ff9b3
AK
62 if (!vg_to) {
63 stack;
3d9c2d86 64 return ECMD_FAILED;
651ff9b3 65 }
3d9c2d86
DW
66
67 vg_from = _vgmerge_vg_read(cmd, vg_name_from);
68 if (!vg_from) {
651ff9b3 69 stack;
077a6755 70 unlock_and_release_vg(cmd, vg_to, vg_name_to);
3d9c2d86
DW
71 return ECMD_FAILED;
72 }
7d0e6e80
AK
73 }
74
d865615e 75 if (!vgs_are_compatible(cmd, vg_from, vg_to))
c51b9fff 76 goto_bad;
352a99b9 77
da4e57f2
AK
78 /* FIXME List arg: vg_show_with_pv_and_lv(vg_to); */
79
614a4508 80 if (!archive(vg_from) || !archive(vg_to))
c51b9fff 81 goto_bad;
614a4508 82
de369215
ZK
83 if (!drop_cached_metadata(vg_from))
84 stack;
aa769723 85
da4e57f2 86 /* Merge volume groups */
0adfbfd5
DW
87 dm_list_iterate_items_safe(pvl, tpvl, &vg_from->pvs) {
88 del_pvl_from_vgs(vg_from, pvl);
89 add_pvl_to_vgs(vg_to, pvl);
90 pvl->pv->vg_name = dm_pool_strdup(cmd->mem, vg_to->name);
da4e57f2 91 }
da4e57f2 92
21ca3b12 93 /* Fix up LVIDs */
2c44337b 94 dm_list_iterate_items(lvl1, &vg_to->lvs) {
21ca3b12 95 union lvid *lvid1 = &lvl1->lv->lvid;
08f1ddea 96 char uuid[64] __attribute__((aligned(8)));
21ca3b12 97
2c44337b 98 dm_list_iterate_items(lvl2, &vg_from->lvs) {
21ca3b12
AK
99 union lvid *lvid2 = &lvl2->lv->lvid;
100
67cdbd7e 101 if (id_equal(&lvid1->id[1], &lvid2->id[1])) {
21ca3b12
AK
102 if (!id_create(&lvid2->id[1])) {
103 log_error("Failed to generate new "
104 "random LVID for %s",
105 lvl2->lv->name);
c51b9fff 106 goto bad;
21ca3b12 107 }
67cdbd7e 108 if (!id_write_format(&lvid2->id[1], uuid,
c51b9fff 109 sizeof(uuid)))
67cdbd7e 110 goto_bad;
21ca3b12
AK
111
112 log_verbose("Changed LVID for %s to %s",
113 lvl2->lv->name, uuid);
114 }
115 }
116 }
67cdbd7e 117
ebfe96ca
PR
118 dm_list_iterate_items(lvl1, &vg_from->lvs) {
119 lvl1->lv->vg = vg_to;
120 }
121
2c44337b
AK
122 while (!dm_list_empty(&vg_from->lvs)) {
123 struct dm_list *lvh = vg_from->lvs.n;
579944d3 124
2c44337b 125 dm_list_move(&vg_to->lvs, lvh);
da4e57f2 126 }
5a52dca9 127
f55a20eb
DW
128 while (!dm_list_empty(&vg_from->fid->metadata_areas_in_use)) {
129 struct dm_list *mdah = vg_from->fid->metadata_areas_in_use.n;
5a52dca9 130
f55a20eb 131 dm_list_move(&vg_to->fid->metadata_areas_in_use, mdah);
5a52dca9
AK
132 }
133
c6c031e4
DW
134 while (!dm_list_empty(&vg_from->fid->metadata_areas_ignored)) {
135 struct dm_list *mdah = vg_from->fid->metadata_areas_ignored.n;
136
137 dm_list_move(&vg_to->fid->metadata_areas_ignored, mdah);
138 }
139
da4e57f2
AK
140 vg_to->extent_count += vg_from->extent_count;
141 vg_to->free_count += vg_from->free_count;
142
143 /* store it on disks */
144 log_verbose("Writing out updated volume group");
c51b9fff
AK
145 if (!vg_write(vg_to) || !vg_commit(vg_to))
146 goto_bad;
da4e57f2
AK
147
148 /* FIXME Remove /dev/vgfrom */
149
197c3f2a 150 backup(vg_to);
08907484 151 log_print("Volume group \"%s\" successfully merged into \"%s\"",
da4e57f2 152 vg_from->name, vg_to->name);
043b1362
MB
153 r = ECMD_PROCESSED;
154bad:
91d865ca
ZK
155 /*
156 * Note: as vg_to is referencing moved elements from vg_from
077a6755 157 * the order of release_vg calls is mandatory.
91d865ca 158 */
077a6755
ZK
159 unlock_and_release_vg(cmd, vg_to, vg_name_to);
160 unlock_and_release_vg(cmd, vg_from, vg_name_from);
91d865ca 161
043b1362 162 return r;
da4e57f2 163}
5a52dca9
AK
164
165int vgmerge(struct cmd_context *cmd, int argc, char **argv)
166{
aec21154 167 const char *vg_name_to, *vg_name_from;
5a52dca9
AK
168 int opt = 0;
169 int ret = 0, ret_max = 0;
170
171 if (argc < 2) {
172 log_error("Please enter 2 or more volume groups to merge");
173 return EINVALID_CMD_LINE;
174 }
175
9397354a 176 vg_name_to = skip_dev_dir(cmd, argv[0], NULL);
5a52dca9
AK
177 argc--;
178 argv++;
179
180 for (; opt < argc; opt++) {
9397354a 181 vg_name_from = skip_dev_dir(cmd, argv[opt], NULL);
08c060cf
AK
182
183 ret = _vgmerge_single(cmd, vg_name_to, vg_name_from);
5a52dca9
AK
184 if (ret > ret_max)
185 ret_max = ret;
186 }
187
188 return ret_max;
189}
This page took 0.106065 seconds and 5 git commands to generate.