]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
Fix lvreduce pv extents calculations.
[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
d1d9800e 7#include "lib.h"
a381c45a 8#include "metadata.h"
b1713d28 9#include "activate.h"
914c9723 10#include "memlock.h"
78125be9 11#include "display.h"
f7a14956 12#include "fs.h"
41b2fd5f 13#include "lvm-string.h"
413cc918
AK
14#include "pool.h"
15#include "toolcontext.h"
de6c9183 16#include "dev_manager.h"
de17d760 17#include "str_list.h"
12137231
JT
18
19#include <limits.h>
5986ec94 20#include <fcntl.h>
914c9723 21#include <unistd.h>
12137231 22
6d52fb46 23#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
b1713d28 24
199e490e
AK
25#ifndef DEVMAPPER_SUPPORT
26void set_activation(int act)
27{
28 if (act)
29 log_error("Compiled without libdevmapper support. "
30 "Can't enable activation.");
31}
32int activation(void)
33{
34 return 0;
35}
36int library_version(char *version, size_t size)
37{
38 return 0;
39}
40int driver_version(char *version, size_t size)
41{
42 return 0;
43}
44int lv_info(const struct logical_volume *lv, struct lvinfo *info)
45{
46 return 0;
47}
48int lv_snapshot_percent(struct logical_volume *lv, float *percent)
49{
50 return 0;
51}
914c9723
AK
52int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
53 uint32_t *event_nr)
10b29b8d
AK
54{
55 return 0;
56}
199e490e
AK
57int lvs_in_vg_activated(struct volume_group *vg)
58{
59 return 0;
60}
61int lvs_in_vg_opened(struct volume_group *vg)
62{
63 return 0;
64}
658b5812
AK
65int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
66{
67 return 1;
68}
199e490e
AK
69int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
70{
71 return 1;
72}
658b5812
AK
73int lv_resume(struct cmd_context *cmd, const char *lvid_s)
74{
75 return 1;
76}
199e490e
AK
77int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
78{
79 return 1;
80}
81int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
82{
83 return 1;
84}
658b5812
AK
85int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
86 int *activate_lv)
87{
88 return 1;
89}
199e490e
AK
90int lv_activate(struct cmd_context *cmd, const char *lvid_s)
91{
92 return 1;
93}
658b5812
AK
94int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
95{
96 return 1;
97}
f7dd6d84
AK
98
99int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
100{
101 return 1;
102}
103
914c9723
AK
104void activation_exit(void)
105{
106 return;
107}
199e490e
AK
108
109#else /* DEVMAPPER_SUPPORT */
110
d1d9800e
AK
111static int _activation = 1;
112
8ef2b021 113void set_activation(int act)
d1d9800e 114{
8ef2b021 115 if (act == _activation)
d1d9800e
AK
116 return;
117
8ef2b021 118 _activation = act;
d1d9800e
AK
119 if (_activation)
120 log_verbose("Activation enabled. Device-mapper kernel "
121 "driver will be used.");
122 else
123 log_verbose("Activation disabled. No device-mapper "
124 "interaction will be attempted.");
125}
126
8ef2b021 127int activation(void)
d1d9800e
AK
128{
129 return _activation;
130}
131
de17d760
AK
132static int _passes_activation_filter(struct cmd_context *cmd,
133 struct logical_volume *lv)
134{
135 struct config_node *cn;
136 struct config_value *cv;
137 char *str;
138 char path[PATH_MAX];
139
814643d8 140 if (!(cn = find_config_node(cmd->cft->root, "activation/volume_list"))) {
de17d760
AK
141 /* If no hosts tags defined, activate */
142 if (list_empty(&cmd->tags))
143 return 1;
144
145 /* If any host tag matches any LV or VG tag, activate */
146 if (str_list_match_list(&cmd->tags, &lv->tags) ||
147 str_list_match_list(&cmd->tags, &lv->vg->tags))
148 return 1;
149
150 /* Don't activate */
151 return 0;
152 }
153
154 for (cv = cn->v; cv; cv = cv->next) {
155 if (cv->type != CFG_STRING) {
156 log_error("Ignoring invalid string in config file "
157 "activation/volume_list");
158 continue;
159 }
160 str = cv->v.str;
161 if (!*str) {
162 log_error("Ignoring empty string in config file "
163 "activation/volume_list");
164 continue;
165 }
166
167 /* Tag? */
168 if (*str == '@') {
169 str++;
170 if (!*str) {
171 log_error("Ignoring empty tag in config file "
172 "activation/volume_list");
173 continue;
174 }
175 /* If any host tag matches any LV or VG tag, activate */
176 if (!strcmp(str, "*")) {
177 if (str_list_match_list(&cmd->tags, &lv->tags)
178 || str_list_match_list(&cmd->tags,
179 &lv->vg->tags))
180 return 1;
181 else
182 continue;
183 }
184 /* If supplied tag matches LV or VG tag, activate */
185 if (str_list_match_item(&lv->tags, str) ||
186 str_list_match_item(&lv->vg->tags, str))
187 return 1;
188 else
189 continue;
190 }
191 if (!index(str, '/')) {
192 /* vgname supplied */
193 if (!strcmp(str, lv->vg->name))
194 return 1;
195 else
196 continue;
197 }
198 /* vgname/lvname */
199 if (lvm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
200 lv->name) < 0) {
201 log_error("lvm_snprintf error from %s/%s", lv->vg->name,
202 lv->name);
203 continue;
204 }
205 if (!strcmp(path, str))
206 return 1;
207 }
208
209 return 0;
210}
211
fae0c576
AK
212int library_version(char *version, size_t size)
213{
d1d9800e
AK
214 if (!activation())
215 return 0;
216
fae0c576
AK
217 if (!dm_get_library_version(version, size))
218 return 0;
219 return 1;
220}
221
fae0c576
AK
222int driver_version(char *version, size_t size)
223{
224 int r = 0;
225 struct dm_task *dmt;
226
d1d9800e
AK
227 if (!activation())
228 return 0;
229
fae0c576
AK
230 log_very_verbose("Getting driver version");
231 if (!(dmt = dm_task_create(DM_DEVICE_VERSION))) {
232 stack;
233 return 0;
234 }
235
236 if (!dm_task_run(dmt))
237 log_error("Failed to get driver version");
238
239 if (!dm_task_get_driver_version(dmt, version, size))
240 goto out;
241
242 r = 1;
243
2ed2a724 244 out:
fae0c576
AK
245 dm_task_destroy(dmt);
246
247 return r;
248}
249
de6c9183
JT
250/*
251 * Returns 1 if info structure populated, else 0 on failure.
252 */
8c0388e4
AK
253static int _lv_info(const struct logical_volume *lv, int mknodes,
254 struct lvinfo *info)
37ed70b9 255{
de6c9183
JT
256 int r;
257 struct dev_manager *dm;
199e490e 258 struct dm_info dminfo;
4a624ca0 259
d1d9800e
AK
260 if (!activation())
261 return 0;
262
814643d8 263 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
12137231 264 stack;
de6c9183 265 return 0;
12137231 266 }
4a624ca0 267
8c0388e4 268 if (!(r = dev_manager_info(dm, lv, mknodes, &dminfo)))
de6c9183 269 stack;
4a624ca0 270
199e490e
AK
271 info->exists = dminfo.exists;
272 info->suspended = dminfo.suspended;
273 info->open_count = dminfo.open_count;
274 info->major = dminfo.major;
275 info->minor = dminfo.minor;
276 info->read_only = dminfo.read_only;
277
de6c9183
JT
278 dev_manager_destroy(dm);
279 return r;
280}
a62ee8ad 281
8c0388e4
AK
282int lv_info(const struct logical_volume *lv, struct lvinfo *info)
283{
284 return _lv_info(lv, 0, info);
285}
286
1951dba9
AL
287/*
288 * Returns 1 if percent set, else 0 on failure.
289 */
c826c0d1 290int lv_snapshot_percent(struct logical_volume *lv, float *percent)
1951dba9
AL
291{
292 int r;
293 struct dev_manager *dm;
294
d1d9800e
AK
295 if (!activation())
296 return 0;
297
814643d8 298 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
1951dba9
AL
299 stack;
300 return 0;
301 }
302
c826c0d1 303 if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
1951dba9 304 stack;
c826c0d1 305
1951dba9
AL
306 dev_manager_destroy(dm);
307
308 return r;
309}
310
10b29b8d
AK
311/* FIXME Merge with snapshot_percent */
312int lv_mirror_percent(struct logical_volume *lv, int wait, float *percent,
313 uint32_t *event_nr)
314{
315 int r;
316 struct dev_manager *dm;
317
318 if (!activation())
319 return 0;
320
814643d8 321 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
10b29b8d
AK
322 stack;
323 return 0;
324 }
325
326 if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
327 stack;
328
329 dev_manager_destroy(dm);
330
331 return r;
332}
333
41967a02 334static int _lv_active(struct logical_volume *lv)
2ba80b43 335{
199e490e 336 struct lvinfo info;
2ba80b43 337
de6c9183 338 if (!lv_info(lv, &info)) {
2ba80b43 339 stack;
de6c9183 340 return -1;
2ba80b43
JT
341 }
342
de6c9183 343 return info.exists;
2ba80b43
JT
344}
345
41967a02 346static int _lv_open_count(struct logical_volume *lv)
5986ec94 347{
199e490e 348 struct lvinfo info;
5986ec94 349
de6c9183 350 if (!lv_info(lv, &info)) {
5986ec94 351 stack;
de6c9183 352 return -1;
5986ec94
JT
353 }
354
de6c9183 355 return info.open_count;
5986ec94
JT
356}
357
8c013da4 358/* FIXME Need to detect and handle an lv rename */
658b5812 359static int _lv_activate_lv(struct logical_volume *lv)
b1713d28 360{
6d52fb46 361 int r;
de6c9183 362 struct dev_manager *dm;
b1713d28 363
814643d8 364 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
6d52fb46
JT
365 stack;
366 return 0;
ae2bb665
JT
367 }
368
0fe3a2c5 369 if (!(r = dev_manager_activate(dm, lv)))
6d52fb46 370 stack;
ae2bb665 371
de6c9183 372 dev_manager_destroy(dm);
ae2bb665 373 return r;
b1713d28 374}
a381c45a 375
be326a2f 376static int _lv_deactivate(struct logical_volume *lv)
0a5e4a14 377{
de6c9183
JT
378 int r;
379 struct dev_manager *dm;
37ed70b9 380
814643d8 381 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
6d52fb46
JT
382 stack;
383 return 0;
384 }
37ed70b9 385
de6c9183 386 if (!(r = dev_manager_deactivate(dm, lv)))
37ed70b9 387 stack;
37ed70b9 388
de6c9183
JT
389 dev_manager_destroy(dm);
390 return r;
37ed70b9
JT
391}
392
658b5812 393static int _lv_suspend_lv(struct logical_volume *lv)
4a624ca0 394{
20c5fcf7
AK
395 int r;
396 struct dev_manager *dm;
c2d72fd4 397
814643d8 398 if (!(dm = dev_manager_create(lv->vg->name, lv->vg->cmd->cft))) {
37ed70b9
JT
399 stack;
400 return 0;
401 }
0a5e4a14 402
20c5fcf7 403 if (!(r = dev_manager_suspend(dm, lv)))
37ed70b9 404 stack;
0a5e4a14 405
20c5fcf7
AK
406 dev_manager_destroy(dm);
407 return r;
6d52fb46 408}
4a624ca0 409
8c013da4
AK
410/*
411 * These two functions return the number of LVs in the state,
412 * or -1 on error.
413 */
f047219b
AK
414int lvs_in_vg_activated(struct volume_group *vg)
415{
37ed70b9
JT
416 struct list *lvh;
417 struct logical_volume *lv;
94b8220f 418 int count = 0;
37ed70b9 419
d1d9800e
AK
420 if (!activation())
421 return 0;
422
37ed70b9 423 list_iterate(lvh, &vg->lvs) {
f868d635 424 lv = list_item(lvh, struct lv_list)->lv;
41967a02 425 count += (_lv_active(lv) == 1);
37ed70b9
JT
426 }
427
428 return count;
f047219b 429}
2ba80b43
JT
430
431int lvs_in_vg_opened(struct volume_group *vg)
432{
433 struct list *lvh;
434 struct logical_volume *lv;
94b8220f 435 int count = 0;
2ba80b43 436
d1d9800e
AK
437 if (!activation())
438 return 0;
439
2ba80b43 440 list_iterate(lvh, &vg->lvs) {
f868d635 441 lv = list_item(lvh, struct lv_list)->lv;
41967a02 442 count += (_lv_open_count(lv) == 1);
2ba80b43
JT
443 }
444
445 return count;
446}
413cc918 447
658b5812
AK
448static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
449 int error_if_not_suspended)
413cc918
AK
450{
451 struct logical_volume *lv;
199e490e 452 struct lvinfo info;
413cc918 453
d1d9800e
AK
454 if (!activation())
455 return 1;
456
457 if (!(lv = lv_from_lvid(cmd, lvid_s)))
413cc918
AK
458 return 0;
459
20c5fcf7
AK
460 if (test_mode()) {
461 _skip("Suspending '%s'.", lv->name);
711f7fc6 462 return 1;
20c5fcf7
AK
463 }
464
2ed2a724
AK
465 if (!lv_info(lv, &info)) {
466 stack;
467 return 0;
468 }
41967a02 469
914c9723 470 if (!info.exists || info.suspended)
658b5812 471 return error_if_not_suspended ? 0 : 1;
914c9723
AK
472
473 memlock_inc();
658b5812 474 if (!_lv_suspend_lv(lv)) {
914c9723
AK
475 memlock_dec();
476 fs_unlock();
477 return 0;
478 }
8c013da4 479
413cc918
AK
480 return 1;
481}
482
658b5812
AK
483/* Returns success if the device is not active */
484int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
485{
486 return _lv_suspend(cmd, lvid_s, 0);
487}
488
489int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
490{
491 return _lv_suspend(cmd, lvid_s, 1);
492}
493
494static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
495 int error_if_not_active)
413cc918
AK
496{
497 struct logical_volume *lv;
199e490e 498 struct lvinfo info;
413cc918 499
d1d9800e
AK
500 if (!activation())
501 return 1;
502
503 if (!(lv = lv_from_lvid(cmd, lvid_s)))
413cc918
AK
504 return 0;
505
20c5fcf7
AK
506 if (test_mode()) {
507 _skip("Resuming '%s'.", lv->name);
711f7fc6 508 return 1;
20c5fcf7
AK
509 }
510
2ed2a724
AK
511 if (!lv_info(lv, &info)) {
512 stack;
513 return 0;
514 }
41967a02 515
914c9723 516 if (!info.exists || !info.suspended)
658b5812 517 return error_if_not_active ? 0 : 1;
914c9723 518
658b5812 519 if (!_lv_activate_lv(lv))
914c9723
AK
520 return 0;
521
522 memlock_dec();
523 fs_unlock();
413cc918
AK
524
525 return 1;
526}
527
658b5812
AK
528/* Returns success if the device is not active */
529int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
530{
531 return _lv_resume(cmd, lvid_s, 0);
532}
533
534int lv_resume(struct cmd_context *cmd, const char *lvid_s)
535{
536 return _lv_resume(cmd, lvid_s, 1);
537}
538
be326a2f 539int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
f4cbeaf0
AK
540{
541 struct logical_volume *lv;
199e490e 542 struct lvinfo info;
914c9723 543 int r;
f4cbeaf0 544
d1d9800e
AK
545 if (!activation())
546 return 1;
547
548 if (!(lv = lv_from_lvid(cmd, lvid_s)))
f4cbeaf0
AK
549 return 0;
550
20c5fcf7
AK
551 if (test_mode()) {
552 _skip("Deactivating '%s'.", lv->name);
711f7fc6 553 return 1;
20c5fcf7
AK
554 }
555
2ed2a724
AK
556 if (!lv_info(lv, &info)) {
557 stack;
558 return 0;
559 }
41967a02 560
914c9723
AK
561 if (!info.exists)
562 return 1;
f4cbeaf0 563
0cf96f33
AK
564 if (info.open_count) {
565 log_error("LV %s/%s in use: not removing", lv->vg->name,
566 lv->name);
567 return 0;
568 }
569
914c9723
AK
570 memlock_inc();
571 r = _lv_deactivate(lv);
572 memlock_dec();
573 fs_unlock();
574
575 return r;
f4cbeaf0
AK
576}
577
658b5812
AK
578/* Test if LV passes filter */
579int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
580 int *activate_lv)
581{
582 struct logical_volume *lv;
583
584 if (!activation())
585 goto activate;
586
587 if (!(lv = lv_from_lvid(cmd, lvid_s)))
588 return 0;
589
590 if (!_passes_activation_filter(cmd, lv)) {
591 log_verbose("Not activating %s/%s due to config file settings",
592 lv->vg->name, lv->name);
593 *activate_lv = 0;
594 return 1;
595 }
596
597 activate:
598 *activate_lv = 1;
599 return 1;
600}
601
602static int _lv_activate(struct cmd_context *cmd, const char *lvid_s, int filter)
f4cbeaf0
AK
603{
604 struct logical_volume *lv;
199e490e 605 struct lvinfo info;
914c9723 606 int r;
f4cbeaf0 607
d1d9800e
AK
608 if (!activation())
609 return 1;
610
611 if (!(lv = lv_from_lvid(cmd, lvid_s)))
f4cbeaf0
AK
612 return 0;
613
658b5812 614 if (filter && !_passes_activation_filter(cmd, lv)) {
de17d760
AK
615 log_verbose("Not activating %s/%s due to config file settings",
616 lv->vg->name, lv->name);
617 return 0;
618 }
619
20c5fcf7
AK
620 if (test_mode()) {
621 _skip("Activating '%s'.", lv->name);
711f7fc6 622 return 1;
20c5fcf7
AK
623 }
624
2ed2a724
AK
625 if (!lv_info(lv, &info)) {
626 stack;
627 return 0;
628 }
8c013da4 629
914c9723
AK
630 if (info.exists && !info.suspended)
631 return 1;
f4cbeaf0 632
914c9723 633 memlock_inc();
658b5812 634 r = _lv_activate_lv(lv);
914c9723
AK
635 memlock_dec();
636 fs_unlock();
637
638 return r;
f4cbeaf0 639}
199e490e 640
658b5812
AK
641/* Activate LV */
642int lv_activate(struct cmd_context *cmd, const char *lvid_s)
643{
644 return _lv_activate(cmd, lvid_s, 0);
645}
646
647/* Activate LV only if it passes filter */
648int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s)
649{
650 return _lv_activate(cmd, lvid_s, 1);
651}
652
f7dd6d84
AK
653int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
654{
655 struct lvinfo info;
656 int r = 1;
657
8c0388e4 658 if (!_lv_info(lv, 1, &info)) {
f7dd6d84
AK
659 stack;
660 return 0;
661 }
662
663 if (info.exists)
664 r = dev_manager_mknodes(lv);
665 else
666 r = dev_manager_rmnodes(lv);
667
668 fs_unlock();
669
670 return r;
671}
672
914c9723
AK
673void activation_exit(void)
674{
675 dev_manager_exit();
676}
199e490e 677#endif
This page took 0.129818 seconds and 5 git commands to generate.