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