]>
Commit | Line | Data |
---|---|---|
d33f2e9f | 1 | /* |
67cdbd7e | 2 | * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved. |
6b3a4aac | 3 | * Copyright (C) 2004-2018 Red Hat, Inc. All rights reserved. |
d33f2e9f | 4 | * |
6606c3ae AK |
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 | |
be684599 | 9 | * of the GNU Lesser General Public License v.2.1. |
6606c3ae | 10 | * |
be684599 | 11 | * You should have received a copy of the GNU Lesser General Public License |
6606c3ae | 12 | * along with this program; if not, write to the Free Software Foundation, |
fcbef05a | 13 | * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
d33f2e9f JT |
14 | */ |
15 | ||
16 | #include "tools.h" | |
6b3a4aac ZK |
17 | #include "device_mapper/all.h" |
18 | #include "device_mapper/misc/dm-ioctl.h" | |
19 | ||
20 | /* | |
21 | * Check if there are any active volumes from restored vg_name. | |
22 | * We can prompt user, as such operation may make some serious | |
23 | * troubles later, when user will try to continue such devices. | |
24 | */ | |
25 | static int _check_all_dm_devices(const char *vg_name, unsigned *found) | |
26 | { | |
27 | struct dm_task *dmt; | |
28 | struct dm_names *names; | |
29 | char vgname_buf[DM_NAME_LEN * 2]; | |
30 | char *vgname, *lvname, *lvlayer; | |
31 | unsigned next = 0; | |
32 | int r = 1; | |
33 | ||
34 | if (!(dmt = dm_task_create(DM_DEVICE_LIST))) | |
35 | return_0; | |
36 | ||
37 | if (!dm_task_run(dmt)) { | |
38 | r = 0; | |
39 | goto_out; | |
40 | } | |
41 | ||
42 | if (!(names = dm_task_get_names(dmt))) { | |
43 | r = 0; | |
44 | goto_out; | |
45 | } | |
46 | ||
47 | if (!names->dev) { | |
48 | log_verbose("No devices found."); | |
49 | goto out; | |
50 | } | |
51 | ||
52 | do { | |
53 | /* TODO: Do we want to validate UUID LVM- prefix as well ? */ | |
54 | names = (struct dm_names *)((char *) names + next); | |
f9fefaaa | 55 | if (!_dm_strncpy(vgname_buf, names->name, sizeof(vgname_buf))) { |
6b3a4aac ZK |
56 | r = 0; |
57 | goto_out; | |
58 | } | |
59 | vgname = vgname_buf; | |
60 | if (!dm_split_lvm_name(NULL, NULL, &vgname, &lvname, &lvlayer)) { | |
61 | r = 0; | |
62 | goto_out; | |
63 | } | |
64 | if (strcmp(vgname, vg_name) == 0) { | |
65 | log_print("Volume group %s has active volume: %s.", vgname, lvname); | |
66 | (*found)++; | |
67 | } | |
68 | next = names->next; | |
69 | } while (next); | |
70 | ||
71 | out: | |
72 | dm_task_destroy(dmt); | |
73 | return r; | |
74 | } | |
d33f2e9f | 75 | |
60274aba | 76 | int vgcfgrestore(struct cmd_context *cmd, int argc, char **argv) |
d33f2e9f | 77 | { |
aec21154 | 78 | const char *vg_name = NULL; |
6b3a4aac | 79 | unsigned found = 0; |
6c269e63 | 80 | int ret; |
8ae908a0 | 81 | |
944cac93 BR |
82 | if (argc == 1) { |
83 | vg_name = skip_dev_dir(cmd, argv[0], NULL); | |
84 | if (!validate_name(vg_name)) { | |
8b111f28 | 85 | log_error("Volume group name \"%s\" is invalid.", vg_name); |
3ac7d2de | 86 | return EINVALID_CMD_LINE; |
944cac93 | 87 | } |
7e671e5d | 88 | } else if (!(arg_is_set(cmd, list_ARG) && arg_is_set(cmd, file_ARG))) { |
b8f47d5f | 89 | log_error("Please specify a *single* volume group to restore."); |
3ac7d2de | 90 | return EINVALID_CMD_LINE; |
d33f2e9f JT |
91 | } |
92 | ||
03888774 JT |
93 | /* |
94 | * FIXME: overloading the -l arg for now to display a | |
95 | * list of archive files for a particular vg | |
96 | */ | |
7e671e5d AK |
97 | if (arg_is_set(cmd, list_ARG)) { |
98 | if (!(arg_is_set(cmd,file_ARG) ? | |
651ff9b3 AK |
99 | archive_display_file(cmd, |
100 | arg_str_value(cmd, file_ARG, "")) : | |
b90450b8 ZK |
101 | archive_display(cmd, vg_name))) |
102 | return_ECMD_FAILED; | |
103 | ||
cfb7bfc7 | 104 | return ECMD_PROCESSED; |
03888774 JT |
105 | } |
106 | ||
5126ac7c ZK |
107 | if (!vg_name) { |
108 | log_error(INTERNAL_ERROR "VG name is not set."); | |
109 | return ECMD_FAILED; | |
110 | } else if (!_check_all_dm_devices(vg_name, &found)) { | |
6b3a4aac ZK |
111 | log_warn("WARNING: Failed to check for active volumes in volume group \"%s\".", vg_name); |
112 | } else if (found) { | |
113 | log_warn("WARNING: Found %u active volume(s) in volume group \"%s\".", | |
114 | found, vg_name); | |
115 | log_print("Restoring VG with active LVs, may cause mismatch with its metadata."); | |
116 | if (!arg_is_set(cmd, yes_ARG) && | |
117 | yes_no_prompt("Do you really want to proceed with restore of volume group \"%s\", " | |
118 | "while %u volume(s) are active? [y/n]: ", | |
119 | vg_name, found) == 'n') { | |
120 | log_error("Restore aborted."); | |
121 | return ECMD_FAILED; | |
122 | } | |
123 | } | |
124 | ||
8c87dda1 | 125 | if (!lock_global(cmd, "ex")) |
5a52dca9 | 126 | return ECMD_FAILED; |
5a52dca9 | 127 | |
9a8c36b8 DT |
128 | if (!lock_vol(cmd, vg_name, LCK_VG_WRITE, NULL)) { |
129 | log_error("Unable to lock volume group %s.", vg_name); | |
b85357cd DW |
130 | return ECMD_FAILED; |
131 | } | |
132 | ||
6620dc94 DT |
133 | clear_hint_file(cmd); |
134 | ||
92b4fcf5 DT |
135 | if (!lvmcache_label_scan(cmd)) { |
136 | unlock_vg(cmd, NULL, vg_name); | |
137 | return_ECMD_FAILED; | |
138 | } | |
748f29b4 | 139 | |
b4048242 PR |
140 | cmd->handles_unknown_segments = 1; |
141 | ||
7e671e5d | 142 | if (!(arg_is_set(cmd, file_ARG) ? |
8ae908a0 | 143 | backup_restore_from_file(cmd, vg_name, |
09b7ceea ZK |
144 | arg_str_value(cmd, file_ARG, ""), |
145 | arg_count(cmd, force_long_ARG)) : | |
146 | backup_restore(cmd, vg_name, arg_count(cmd, force_long_ARG)))) { | |
a7c45ddc | 147 | unlock_vg(cmd, NULL, vg_name); |
b8f47d5f | 148 | log_error("Restore failed."); |
6c269e63 | 149 | ret = ECMD_FAILED; |
117160b2 | 150 | goto out; |
d33f2e9f JT |
151 | } |
152 | ||
6c269e63 | 153 | ret = ECMD_PROCESSED; |
8b111f28 | 154 | log_print_unless_silent("Restored volume group %s.", vg_name); |
8ae908a0 | 155 | |
a7c45ddc | 156 | unlock_vg(cmd, NULL, vg_name); |
6ae22125 | 157 | out: |
6c269e63 | 158 | return ret; |
d33f2e9f | 159 | } |