]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
o small bug in the format1 export code for snapshots.
[lvm2.git] / lib / activate / activate.c
CommitLineData
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>
fdc7af23 17#include <linux/kdev_t.h>
12137231 18
6d52fb46 19#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
b1713d28 20
fae0c576
AK
21int library_version(char *version, size_t size)
22{
23 if (!dm_get_library_version(version, size))
24 return 0;
25 return 1;
26}
27
fae0c576
AK
28int driver_version(char *version, size_t size)
29{
30 int r = 0;
31 struct dm_task *dmt;
32
33 log_very_verbose("Getting driver version");
34 if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
35 stack;
36 return 0;
37 }
38
39 if (!dm_task_run(dmt))
40 log_error("Failed to get driver version");
41
42 if (!dm_task_get_driver_version(dmt, version, size))
43 goto out;
44
45 r = 1;
46
47 out:
48 dm_task_destroy(dmt);
49
50 return r;
51}
52
6d52fb46 53static int _query(struct logical_volume *lv, int (*fn)(const char *))
37ed70b9 54{
6d52fb46 55 char buffer[128];
4a624ca0 56
6d52fb46 57 if (!build_dm_name(buffer, sizeof(buffer), "",
12137231
JT
58 lv->vg->name, lv->name)) {
59 stack;
6d52fb46 60 return -1;
12137231 61 }
4a624ca0 62
6d52fb46 63 return fn(buffer);
4a624ca0
AK
64}
65
a62ee8ad
AK
66
67/*
fdc7af23 68 * These three functions return the number of LVs in the state,
a62ee8ad
AK
69 * or -1 on error.
70 */
94b8220f 71int lv_active(struct logical_volume *lv)
2ba80b43 72{
6d52fb46 73 return _query(lv, device_active);
37ed70b9
JT
74}
75
2bc25b54
AK
76int lv_suspended(struct logical_volume *lv)
77{
6d52fb46 78 return _query(lv, device_suspended);
2bc25b54
AK
79}
80
94b8220f 81int lv_open_count(struct logical_volume *lv)
2ba80b43 82{
6d52fb46
JT
83 return _query(lv, device_open_count);
84}
85
a62ee8ad
AK
86
87/*
88 * Returns 1 if info structure populated, else 0 on failure.
89 */
6d52fb46
JT
90int lv_info(struct logical_volume *lv, struct dm_info *info)
91{
92 char buffer[128];
2ba80b43 93
6d52fb46
JT
94 if (!build_dm_name(buffer, sizeof(buffer), "",
95 lv->vg->name, lv->name)) {
2ba80b43 96 stack;
a62ee8ad 97 return 0;
2ba80b43
JT
98 }
99
6d52fb46 100 return device_info(buffer, info);
2ba80b43
JT
101}
102
fdc7af23
JT
103static inline int _read_only_lv(struct logical_volume *lv)
104{
105 return (lv->status & LVM_WRITE) && (lv->vg->status & LVM_WRITE);
106}
6c4ee296 107
6d52fb46
JT
108int lv_activate(struct logical_volume *lv)
109{
fdc7af23
JT
110 int r = 0;
111 struct dm_task *dmt;
6d52fb46 112 char buffer[128];
6c4ee296 113
6d52fb46
JT
114 if (test_mode()) {
115 _skip("Activation of '%s'.", lv->name);
116 return 0;
6c4ee296
JT
117 }
118
fdc7af23
JT
119 /*
120 * Decide what we're going to call this device.
121 */
6d52fb46
JT
122 if (!build_dm_name(buffer, sizeof(buffer), "",
123 lv->vg->name, lv->name)) {
124 stack;
125 return 0;
80f9662b
JT
126 }
127
fdc7af23
JT
128 /*
129 * Create a task.
130 */
131 if (!(dmt = setup_dm_task(buffer, DM_DEVICE_CREATE))) {
6d52fb46
JT
132 stack;
133 return 0;
134 }
a299e388 135
fdc7af23
JT
136 /*
137 * Populate it.
138 */
139 if (!device_populate_lv(dmt, lv)) {
80f9662b
JT
140 stack;
141 return 0;
142 }
143
fdc7af23
JT
144 /*
145 * Do we want a specific minor number ?
146 */
147 if (lv->minor >= 0) {
148 if (!dm_task_set_minor(dmt, MINOR(lv->minor))) {
149 log_error("Failed to set minor number for %s to %d "
150 "during activation.", lv->name, lv->minor);
151 goto out;
152 } else
153 log_very_verbose("Set minor number for %s to %d.",
154 lv->name, lv->minor);
155 }
156
157 /*
158 * Read only ?
159 */
160 if (!_read_only_lv(lv)) {
161 if (!dm_task_set_ro(dmt)) {
162 log_error("Failed to set %s read-only during "
163 "activation.", lv->name);
164 goto out;
165 } else
166 log_very_verbose("Activating %s read-only", lv->name);
167 }
168
169 /*
170 * Load this into the kernel.
171 */
172 if (!(r = dm_task_run(dmt))) {
173 log_err("Activation failed.");
174 goto out;
175 }
176
177 /*
178 * Create device nodes and symbolic links.
179 */
180 if (!fs_add_lv(lv, lv->minor))
181 stack;
182
183 out:
184 dm_task_destroy(dmt);
185 log_verbose("Logical volume %s%s activated", lv->name,
186 r == 1 ? "" : " not");
187 return r;
188}
189
190static int _reload(const char *name, struct logical_volume *lv)
191{
192 int r = 0;
193 struct dm_task *dmt;
194
195 /*
196 * Create a task.
197 */
198 if (!(dmt = setup_dm_task(name, DM_DEVICE_RELOAD))) {
199 stack;
200 return 0;
201 }
202
203 /*
204 * Populate it.
205 */
206 if (!device_populate_lv(dmt, lv)) {
207 stack;
208 return 0;
209 }
210
211 /*
212 * Load this into the kernel.
213 */
214 if (!(r = dm_task_run(dmt))) {
215 log_err("Activation failed.");
216 goto out;
217 }
218
219 /*
220 * Create device nodes and symbolic links.
221 */
222 if (!fs_add_lv(lv, lv->minor))
223 stack;
224
225 out:
226 dm_task_destroy(dmt);
227 log_verbose("Logical volume %s%s re-activated", lv->name,
228 r == 1 ? "" : " not");
229 return r;
80f9662b
JT
230}
231
6d52fb46 232int lv_reactivate(struct logical_volume *lv)
b1713d28 233{
6d52fb46
JT
234 int r;
235 char buffer[128];
e15559aa 236
6d52fb46
JT
237 if (test_mode()) {
238 _skip("Reactivation of '%s'.", lv->name);
ae2bb665
JT
239 return 0;
240 }
b1713d28 241
fdc7af23
JT
242 /*
243 * Decide what we're going to call this device.
244 */
6d52fb46
JT
245 if (!build_dm_name(buffer, sizeof(buffer), "",
246 lv->vg->name, lv->name)) {
247 stack;
248 return 0;
ae2bb665
JT
249 }
250
fdc7af23
JT
251 /*
252 * Suspend the device if it isn't already.
253 */
6d52fb46
JT
254 if (!device_suspended(buffer) && !device_suspend(buffer)) {
255 stack;
256 return 0;
12a6fcd3 257 }
2bc25b54 258
fdc7af23 259 r = _reload(buffer, lv);
2bc25b54 260
6d52fb46 261 if (!device_resume(buffer)) {
ae2bb665 262 stack;
6d52fb46
JT
263 return 0;
264 }
ae2bb665 265
ae2bb665 266 return r;
b1713d28 267}
a381c45a 268
6d52fb46 269int lv_deactivate(struct logical_volume *lv)
0a5e4a14 270{
6d52fb46 271 char buffer[128];
c2d72fd4 272
6d52fb46
JT
273 log_very_verbose("Deactivating %s", lv->name);
274 if (test_mode()) {
275 _skip("Deactivating '%s'.", lv->name);
276 return 0;
277 }
37ed70b9 278
6d52fb46
JT
279 if (!build_dm_name(buffer, sizeof(buffer), "",
280 lv->vg->name, lv->name)) {
281 stack;
282 return 0;
283 }
37ed70b9 284
6d52fb46 285 if (!device_deactivate(buffer)) {
37ed70b9
JT
286 stack;
287 return 0;
288 }
289
6d52fb46 290 fs_del_lv(lv);
37ed70b9 291
6d52fb46 292 return 1;
37ed70b9
JT
293}
294
4a624ca0
AK
295int lv_suspend(struct logical_volume *lv)
296{
6d52fb46 297 char buffer[128];
4a624ca0 298
6d52fb46
JT
299 log_very_verbose("Suspending %s", lv->name);
300 if (test_mode()) {
301 _skip("Suspending '%s'.", lv->name);
c2d72fd4 302 return 0;
6d52fb46 303 }
c2d72fd4 304
6d52fb46
JT
305 if (!build_dm_name(buffer, sizeof(buffer), "",
306 lv->vg->name, lv->name)) {
37ed70b9
JT
307 stack;
308 return 0;
309 }
0a5e4a14 310
6d52fb46 311 if (!device_suspend(buffer)) {
37ed70b9
JT
312 stack;
313 return 0;
314 }
0a5e4a14 315
6d52fb46 316 fs_del_lv(lv);
0a5e4a14 317
6d52fb46
JT
318 return 1;
319}
4a624ca0 320
6d52fb46 321int lv_rename(const char *old_name, struct logical_volume *lv)
ae2bb665 322{
6d52fb46
JT
323 int r = 0;
324 char new_name[PATH_MAX];
ab269099
JT
325 struct dm_task *dmt;
326
6d52fb46
JT
327 if (test_mode()) {
328 _skip("Rename '%s' to '%s'.", old_name, lv->name);
c2d72fd4 329 return 0;
6d52fb46 330 }
c2d72fd4 331
6d52fb46 332 if (!(dmt = setup_dm_task(old_name, DM_DEVICE_RENAME))) {
ae2bb665
JT
333 stack;
334 return 0;
335 }
336
6d52fb46
JT
337 if (!build_dm_name(new_name, sizeof(new_name), "",
338 lv->vg->name, lv->name)) {
ae2bb665 339 stack;
6d52fb46
JT
340 return 0;
341 }
ae2bb665 342
6d52fb46
JT
343 if (!dm_task_set_newname(dmt, new_name)) {
344 stack;
345 r = 0;
346 goto end;
347 }
f7a14956 348
6d52fb46
JT
349 if (!dm_task_run(dmt)) {
350 stack;
351 r = 0;
352 goto end;
353 }
354
355 fs_rename_lv(old_name, lv);
f7a14956 356
6d52fb46
JT
357 end:
358 dm_task_destroy(dmt);
ae2bb665
JT
359 return r;
360}
361
6d52fb46 362
37ed70b9
JT
363int activate_lvs_in_vg(struct volume_group *vg)
364{
365 struct list *lvh;
366 struct logical_volume *lv;
94b8220f 367 int count = 0;
37ed70b9
JT
368
369 list_iterate(lvh, &vg->lvs) {
f868d635 370 lv = list_item(lvh, struct lv_list)->lv;
94b8220f 371 count += (!lv_active(lv) && lv_activate(lv));
37ed70b9
JT
372 }
373
374 return count;
375}
376
ae2bb665
JT
377int lv_update_write_access(struct logical_volume *lv)
378{
2bc25b54
AK
379 struct dm_info info;
380
381 if (!lv_info(lv, &info)) {
382 stack;
383 return 0;
384 }
385
386 if (!info.exists || info.suspended)
387 /* Noop */
388 return 1;
389
390 return lv_reactivate(lv);
ae2bb665
JT
391}
392
a381c45a
AK
393int deactivate_lvs_in_vg(struct volume_group *vg)
394{
0a5e4a14 395 struct list *lvh;
37ed70b9 396 struct logical_volume *lv;
94b8220f 397 int count = 0;
37ed70b9
JT
398
399 list_iterate(lvh, &vg->lvs) {
f868d635 400 lv = list_item(lvh, struct lv_list)->lv;
94b8220f 401 count += ((lv_active(lv) == 1) && lv_deactivate(lv));
37ed70b9 402 }
0a5e4a14 403
37ed70b9 404 return count;
a381c45a 405}
f047219b
AK
406
407int lvs_in_vg_activated(struct volume_group *vg)
408{
37ed70b9
JT
409 struct list *lvh;
410 struct logical_volume *lv;
94b8220f 411 int count = 0;
37ed70b9
JT
412
413 list_iterate(lvh, &vg->lvs) {
f868d635 414 lv = list_item(lvh, struct lv_list)->lv;
94b8220f 415 count += (lv_active(lv) == 1);
37ed70b9
JT
416 }
417
418 return count;
f047219b 419}
2ba80b43
JT
420
421int lvs_in_vg_opened(struct volume_group *vg)
422{
423 struct list *lvh;
424 struct logical_volume *lv;
94b8220f 425 int count = 0;
2ba80b43
JT
426
427 list_iterate(lvh, &vg->lvs) {
f868d635 428 lv = list_item(lvh, struct lv_list)->lv;
94b8220f 429 count += (lv_open_count(lv) == 1);
2ba80b43
JT
430 }
431
432 return count;
433}
This page took 0.078215 seconds and 5 git commands to generate.