]>
Commit | Line | Data |
---|---|---|
b1713d28 JT |
1 | /* |
2 | * Copyright (C) 2001 Sistina Software (UK) Limited. | |
3 | * | |
1b9fcf48 | 4 | * This file is released under the LGPL. |
b1713d28 JT |
5 | */ |
6 | ||
a381c45a | 7 | #include "metadata.h" |
b1713d28 | 8 | #include "activate.h" |
6d52fb46 | 9 | #include "ll-activate.h" |
78125be9 | 10 | #include "display.h" |
f047219b | 11 | #include "log.h" |
f7a14956 | 12 | #include "fs.h" |
41b2fd5f | 13 | #include "lvm-string.h" |
12137231 JT |
14 | #include "names.h" |
15 | ||
16 | #include <limits.h> | |
17 | ||
6d52fb46 | 18 | #define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args) |
b1713d28 | 19 | |
fae0c576 AK |
20 | int library_version(char *version, size_t size) |
21 | { | |
22 | if (!dm_get_library_version(version, size)) | |
23 | return 0; | |
24 | return 1; | |
25 | } | |
26 | ||
fae0c576 AK |
27 | int driver_version(char *version, size_t size) |
28 | { | |
29 | int r = 0; | |
30 | struct dm_task *dmt; | |
31 | ||
32 | log_very_verbose("Getting driver version"); | |
33 | if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) { | |
34 | stack; | |
35 | return 0; | |
36 | } | |
37 | ||
38 | if (!dm_task_run(dmt)) | |
39 | log_error("Failed to get driver version"); | |
40 | ||
41 | if (!dm_task_get_driver_version(dmt, version, size)) | |
42 | goto out; | |
43 | ||
44 | r = 1; | |
45 | ||
46 | out: | |
47 | dm_task_destroy(dmt); | |
48 | ||
49 | return r; | |
50 | } | |
51 | ||
6d52fb46 | 52 | static int _query(struct logical_volume *lv, int (*fn)(const char *)) |
37ed70b9 | 53 | { |
6d52fb46 | 54 | char buffer[128]; |
4a624ca0 | 55 | |
6d52fb46 | 56 | if (!build_dm_name(buffer, sizeof(buffer), "", |
12137231 JT |
57 | lv->vg->name, lv->name)) { |
58 | stack; | |
6d52fb46 | 59 | return -1; |
12137231 | 60 | } |
4a624ca0 | 61 | |
6d52fb46 | 62 | return fn(buffer); |
4a624ca0 AK |
63 | } |
64 | ||
94b8220f | 65 | int lv_active(struct logical_volume *lv) |
2ba80b43 | 66 | { |
6d52fb46 | 67 | return _query(lv, device_active); |
37ed70b9 JT |
68 | } |
69 | ||
2bc25b54 AK |
70 | int lv_suspended(struct logical_volume *lv) |
71 | { | |
6d52fb46 | 72 | return _query(lv, device_suspended); |
2bc25b54 AK |
73 | } |
74 | ||
94b8220f | 75 | int lv_open_count(struct logical_volume *lv) |
2ba80b43 | 76 | { |
6d52fb46 JT |
77 | return _query(lv, device_open_count); |
78 | } | |
79 | ||
80 | int lv_info(struct logical_volume *lv, struct dm_info *info) | |
81 | { | |
82 | char buffer[128]; | |
2ba80b43 | 83 | |
6d52fb46 JT |
84 | if (!build_dm_name(buffer, sizeof(buffer), "", |
85 | lv->vg->name, lv->name)) { | |
2ba80b43 | 86 | stack; |
6d52fb46 | 87 | return -1; |
2ba80b43 JT |
88 | } |
89 | ||
6d52fb46 | 90 | return device_info(buffer, info); |
2ba80b43 JT |
91 | } |
92 | ||
6c4ee296 | 93 | |
6d52fb46 JT |
94 | int lv_activate(struct logical_volume *lv) |
95 | { | |
96 | char buffer[128]; | |
6c4ee296 | 97 | |
6d52fb46 JT |
98 | if (test_mode()) { |
99 | _skip("Activation of '%s'.", lv->name); | |
100 | return 0; | |
6c4ee296 JT |
101 | } |
102 | ||
6d52fb46 JT |
103 | if (!build_dm_name(buffer, sizeof(buffer), "", |
104 | lv->vg->name, lv->name)) { | |
105 | stack; | |
106 | return 0; | |
80f9662b JT |
107 | } |
108 | ||
6d52fb46 JT |
109 | if (!device_create_lv(buffer, lv, lv->minor)) { |
110 | stack; | |
111 | return 0; | |
112 | } | |
a299e388 | 113 | |
6d52fb46 | 114 | if (!fs_add_lv(lv, lv->minor)) { |
80f9662b JT |
115 | stack; |
116 | return 0; | |
117 | } | |
118 | ||
80f9662b JT |
119 | return 1; |
120 | } | |
121 | ||
6d52fb46 | 122 | int lv_reactivate(struct logical_volume *lv) |
b1713d28 | 123 | { |
6d52fb46 JT |
124 | int r; |
125 | char buffer[128]; | |
e15559aa | 126 | |
6d52fb46 JT |
127 | if (test_mode()) { |
128 | _skip("Reactivation of '%s'.", lv->name); | |
ae2bb665 JT |
129 | return 0; |
130 | } | |
b1713d28 | 131 | |
6d52fb46 JT |
132 | if (!build_dm_name(buffer, sizeof(buffer), "", |
133 | lv->vg->name, lv->name)) { | |
134 | stack; | |
135 | return 0; | |
ae2bb665 JT |
136 | } |
137 | ||
6d52fb46 JT |
138 | if (!device_suspended(buffer) && !device_suspend(buffer)) { |
139 | stack; | |
140 | return 0; | |
12a6fcd3 | 141 | } |
2bc25b54 | 142 | |
6d52fb46 | 143 | r = device_reload_lv(buffer, lv); |
2bc25b54 | 144 | |
6d52fb46 | 145 | if (!device_resume(buffer)) { |
ae2bb665 | 146 | stack; |
6d52fb46 JT |
147 | return 0; |
148 | } | |
ae2bb665 | 149 | |
ae2bb665 | 150 | return r; |
b1713d28 | 151 | } |
a381c45a | 152 | |
6d52fb46 | 153 | int lv_deactivate(struct logical_volume *lv) |
0a5e4a14 | 154 | { |
6d52fb46 | 155 | char buffer[128]; |
c2d72fd4 | 156 | |
6d52fb46 JT |
157 | log_very_verbose("Deactivating %s", lv->name); |
158 | if (test_mode()) { | |
159 | _skip("Deactivating '%s'.", lv->name); | |
160 | return 0; | |
161 | } | |
37ed70b9 | 162 | |
6d52fb46 JT |
163 | if (!build_dm_name(buffer, sizeof(buffer), "", |
164 | lv->vg->name, lv->name)) { | |
165 | stack; | |
166 | return 0; | |
167 | } | |
37ed70b9 | 168 | |
6d52fb46 | 169 | if (!device_deactivate(buffer)) { |
37ed70b9 JT |
170 | stack; |
171 | return 0; | |
172 | } | |
173 | ||
6d52fb46 | 174 | fs_del_lv(lv); |
37ed70b9 | 175 | |
6d52fb46 | 176 | return 1; |
37ed70b9 JT |
177 | } |
178 | ||
4a624ca0 AK |
179 | int lv_suspend(struct logical_volume *lv) |
180 | { | |
6d52fb46 | 181 | char buffer[128]; |
4a624ca0 | 182 | |
6d52fb46 JT |
183 | log_very_verbose("Suspending %s", lv->name); |
184 | if (test_mode()) { | |
185 | _skip("Suspending '%s'.", lv->name); | |
c2d72fd4 | 186 | return 0; |
6d52fb46 | 187 | } |
c2d72fd4 | 188 | |
6d52fb46 JT |
189 | if (!build_dm_name(buffer, sizeof(buffer), "", |
190 | lv->vg->name, lv->name)) { | |
37ed70b9 JT |
191 | stack; |
192 | return 0; | |
193 | } | |
0a5e4a14 | 194 | |
6d52fb46 | 195 | if (!device_suspend(buffer)) { |
37ed70b9 JT |
196 | stack; |
197 | return 0; | |
198 | } | |
0a5e4a14 | 199 | |
6d52fb46 | 200 | fs_del_lv(lv); |
0a5e4a14 | 201 | |
6d52fb46 JT |
202 | return 1; |
203 | } | |
4a624ca0 | 204 | |
6d52fb46 | 205 | int lv_rename(const char *old_name, struct logical_volume *lv) |
ae2bb665 | 206 | { |
6d52fb46 JT |
207 | int r = 0; |
208 | char new_name[PATH_MAX]; | |
ab269099 JT |
209 | struct dm_task *dmt; |
210 | ||
6d52fb46 JT |
211 | if (test_mode()) { |
212 | _skip("Rename '%s' to '%s'.", old_name, lv->name); | |
c2d72fd4 | 213 | return 0; |
6d52fb46 | 214 | } |
c2d72fd4 | 215 | |
6d52fb46 | 216 | if (!(dmt = setup_dm_task(old_name, DM_DEVICE_RENAME))) { |
ae2bb665 JT |
217 | stack; |
218 | return 0; | |
219 | } | |
220 | ||
6d52fb46 JT |
221 | if (!build_dm_name(new_name, sizeof(new_name), "", |
222 | lv->vg->name, lv->name)) { | |
ae2bb665 | 223 | stack; |
6d52fb46 JT |
224 | return 0; |
225 | } | |
ae2bb665 | 226 | |
6d52fb46 JT |
227 | if (!dm_task_set_newname(dmt, new_name)) { |
228 | stack; | |
229 | r = 0; | |
230 | goto end; | |
231 | } | |
f7a14956 | 232 | |
6d52fb46 JT |
233 | if (!dm_task_run(dmt)) { |
234 | stack; | |
235 | r = 0; | |
236 | goto end; | |
237 | } | |
238 | ||
239 | fs_rename_lv(old_name, lv); | |
f7a14956 | 240 | |
6d52fb46 JT |
241 | end: |
242 | dm_task_destroy(dmt); | |
ae2bb665 JT |
243 | return r; |
244 | } | |
245 | ||
6d52fb46 | 246 | |
37ed70b9 JT |
247 | int activate_lvs_in_vg(struct volume_group *vg) |
248 | { | |
249 | struct list *lvh; | |
250 | struct logical_volume *lv; | |
94b8220f | 251 | int count = 0; |
37ed70b9 JT |
252 | |
253 | list_iterate(lvh, &vg->lvs) { | |
f868d635 | 254 | lv = list_item(lvh, struct lv_list)->lv; |
94b8220f | 255 | count += (!lv_active(lv) && lv_activate(lv)); |
37ed70b9 JT |
256 | } |
257 | ||
258 | return count; | |
259 | } | |
260 | ||
ae2bb665 JT |
261 | int lv_update_write_access(struct logical_volume *lv) |
262 | { | |
2bc25b54 AK |
263 | struct dm_info info; |
264 | ||
265 | if (!lv_info(lv, &info)) { | |
266 | stack; | |
267 | return 0; | |
268 | } | |
269 | ||
270 | if (!info.exists || info.suspended) | |
271 | /* Noop */ | |
272 | return 1; | |
273 | ||
274 | return lv_reactivate(lv); | |
ae2bb665 JT |
275 | } |
276 | ||
a381c45a AK |
277 | int deactivate_lvs_in_vg(struct volume_group *vg) |
278 | { | |
0a5e4a14 | 279 | struct list *lvh; |
37ed70b9 | 280 | struct logical_volume *lv; |
94b8220f | 281 | int count = 0; |
37ed70b9 JT |
282 | |
283 | list_iterate(lvh, &vg->lvs) { | |
f868d635 | 284 | lv = list_item(lvh, struct lv_list)->lv; |
94b8220f | 285 | count += ((lv_active(lv) == 1) && lv_deactivate(lv)); |
37ed70b9 | 286 | } |
0a5e4a14 | 287 | |
37ed70b9 | 288 | return count; |
a381c45a | 289 | } |
f047219b AK |
290 | |
291 | int lvs_in_vg_activated(struct volume_group *vg) | |
292 | { | |
37ed70b9 JT |
293 | struct list *lvh; |
294 | struct logical_volume *lv; | |
94b8220f | 295 | int count = 0; |
37ed70b9 JT |
296 | |
297 | list_iterate(lvh, &vg->lvs) { | |
f868d635 | 298 | lv = list_item(lvh, struct lv_list)->lv; |
94b8220f | 299 | count += (lv_active(lv) == 1); |
37ed70b9 JT |
300 | } |
301 | ||
302 | return count; | |
f047219b | 303 | } |
2ba80b43 JT |
304 | |
305 | int lvs_in_vg_opened(struct volume_group *vg) | |
306 | { | |
307 | struct list *lvh; | |
308 | struct logical_volume *lv; | |
94b8220f | 309 | int count = 0; |
2ba80b43 JT |
310 | |
311 | list_iterate(lvh, &vg->lvs) { | |
f868d635 | 312 | lv = list_item(lvh, struct lv_list)->lv; |
94b8220f | 313 | count += (lv_open_count(lv) == 1); |
2ba80b43 JT |
314 | } |
315 | ||
316 | return count; | |
317 | } |