]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
install conditionally fsadm.8 manpage
[lvm2.git] / lib / activate / activate.c
CommitLineData
b1713d28 1/*
6606c3ae 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
be684599 3 * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
b1713d28 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
AK
12 * along with this program; if not, write to the Free Software Foundation,
13 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
b1713d28
JT
14 */
15
d1d9800e 16#include "lib.h"
a381c45a 17#include "metadata.h"
b1713d28 18#include "activate.h"
914c9723 19#include "memlock.h"
78125be9 20#include "display.h"
f7a14956 21#include "fs.h"
f894b4b1 22#include "lvm-exec.h"
7d1552c9 23#include "lvm-file.h"
41b2fd5f 24#include "lvm-string.h"
413cc918 25#include "toolcontext.h"
de6c9183 26#include "dev_manager.h"
de17d760 27#include "str_list.h"
4922197a 28#include "config.h"
352a99b9 29#include "filter.h"
15d91f5a 30#include "segtype.h"
12137231
JT
31
32#include <limits.h>
5986ec94 33#include <fcntl.h>
914c9723 34#include <unistd.h>
12137231 35
6d52fb46 36#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
b1713d28 37
7d1552c9
AK
38int lvm1_present(struct cmd_context *cmd)
39{
40 char path[PATH_MAX];
41
0550c1b6 42 if (dm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
7d1552c9
AK
43 < 0) {
44 log_error("LVM1 proc global snprintf failed");
45 return 0;
46 }
47
48 if (path_exists(path))
49 return 1;
50 else
51 return 0;
52}
53
6c81ed26
AK
54int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
55 struct list *modules)
56{
57 unsigned int s;
58 struct lv_segment *seg2, *snap_seg;
59 struct list *snh;
60
61 if (seg->segtype->ops->modules_needed &&
62 !seg->segtype->ops->modules_needed(mem, seg, modules)) {
63 log_error("module string allocation failed");
64 return 0;
65 }
66
67 if (lv_is_origin(seg->lv))
68 list_iterate(snh, &seg->lv->snapshot_segs)
69 if (!list_lv_modules(mem,
70 list_struct_base(snh,
71 struct lv_segment,
72 origin_list)->cow,
73 modules))
74 return_0;
75
76 if (lv_is_cow(seg->lv)) {
77 snap_seg = find_cow(seg->lv);
78 if (snap_seg->segtype->ops->modules_needed &&
79 !snap_seg->segtype->ops->modules_needed(mem, snap_seg,
80 modules)) {
81 log_error("snap_seg module string allocation failed");
82 return 0;
83 }
84 }
85
86 for (s = 0; s < seg->area_count; s++) {
87 switch (seg_type(seg, s)) {
88 case AREA_LV:
89 seg2 = find_seg_by_le(seg_lv(seg, s), seg_le(seg, s));
90 if (seg2 && !list_segment_modules(mem, seg2, modules))
91 return_0;
92 break;
93 case AREA_PV:
94 case AREA_UNASSIGNED:
95 ;
96 }
97 }
98
99 return 1;
100}
101
102int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
103 struct list *modules)
104{
105 struct lv_segment *seg;
106
107 list_iterate_items(seg, &lv->segments)
108 if (!list_segment_modules(mem, seg, modules))
109 return_0;
110
111 return 1;
112}
113
199e490e
AK
114#ifndef DEVMAPPER_SUPPORT
115void set_activation(int act)
116{
f2046e0a
AK
117 static int warned = 0;
118
119 if (warned || !act)
120 return;
121
122 log_error("Compiled without libdevmapper support. "
123 "Can't enable activation.");
124
125 warned = 1;
199e490e
AK
126}
127int activation(void)
128{
129 return 0;
130}
131int library_version(char *version, size_t size)
132{
133 return 0;
134}
135int driver_version(char *version, size_t size)
136{
137 return 0;
138}
bbf83db1
AK
139int target_version(const char *target_name, uint32_t *maj,
140 uint32_t *min, uint32_t *patchlevel)
141{
142 return 0;
143}
0ce83a83 144int target_present(const char *target_name, int use_modprobe)
d1f4953a
AK
145{
146 return 0;
147}
f894b4b1 148int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
a6b22cf3 149 int with_open_count, int with_read_ahead)
199e490e
AK
150{
151 return 0;
152}
4bd9480d 153int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
a6b22cf3 154 struct lvinfo *info, int with_open_count, int with_read_ahead)
4bd9480d
AK
155{
156 return 0;
157}
472ac5bd 158int lv_snapshot_percent(const struct logical_volume *lv, float *percent)
199e490e
AK
159{
160 return 0;
161}
472ac5bd
AK
162int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
163 int wait, float *percent, uint32_t *event_nr)
10b29b8d
AK
164{
165 return 0;
166}
199e490e
AK
167int lvs_in_vg_activated(struct volume_group *vg)
168{
169 return 0;
170}
1bf5aae9 171int lvs_in_vg_activated_by_uuid_only(struct volume_group *vg)
b45c9f49
AK
172{
173 return 0;
174}
199e490e
AK
175int lvs_in_vg_opened(struct volume_group *vg)
176{
177 return 0;
178}
658b5812
AK
179int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
180{
181 return 1;
182}
199e490e
AK
183int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
184{
185 return 1;
186}
658b5812
AK
187int lv_resume(struct cmd_context *cmd, const char *lvid_s)
188{
189 return 1;
190}
199e490e
AK
191int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
192{
193 return 1;
194}
195int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
196{
197 return 1;
198}
658b5812
AK
199int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
200 int *activate_lv)
201{
202 return 1;
203}
07d31831 204int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
199e490e
AK
205{
206 return 1;
207}
07d31831 208int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812
AK
209{
210 return 1;
211}
f7dd6d84
AK
212
213int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
214{
215 return 1;
216}
217
0ce83a83 218int pv_uses_vg(struct physical_volume *pv,
3e3d5d85 219 struct volume_group *vg)
352a99b9
AK
220{
221 return 0;
222}
223
2293567c
AK
224void activation_release(void)
225{
226 return;
227}
228
914c9723
AK
229void activation_exit(void)
230{
231 return;
232}
199e490e
AK
233
234#else /* DEVMAPPER_SUPPORT */
235
d1d9800e
AK
236static int _activation = 1;
237
8ef2b021 238void set_activation(int act)
d1d9800e 239{
8ef2b021 240 if (act == _activation)
d1d9800e
AK
241 return;
242
8ef2b021 243 _activation = act;
d1d9800e
AK
244 if (_activation)
245 log_verbose("Activation enabled. Device-mapper kernel "
246 "driver will be used.");
247 else
e7ddf416 248 log_warn("WARNING: Activation disabled. No device-mapper "
bfe2b548 249 "interaction will be attempted.");
d1d9800e
AK
250}
251
8ef2b021 252int activation(void)
d1d9800e
AK
253{
254 return _activation;
255}
256
de17d760
AK
257static int _passes_activation_filter(struct cmd_context *cmd,
258 struct logical_volume *lv)
259{
25579907 260 const struct config_node *cn;
de17d760
AK
261 struct config_value *cv;
262 char *str;
263 char path[PATH_MAX];
264
2293567c 265 if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
25579907 266 /* If no host tags defined, activate */
de17d760
AK
267 if (list_empty(&cmd->tags))
268 return 1;
269
270 /* If any host tag matches any LV or VG tag, activate */
271 if (str_list_match_list(&cmd->tags, &lv->tags) ||
272 str_list_match_list(&cmd->tags, &lv->vg->tags))
273 return 1;
274
275 /* Don't activate */
276 return 0;
277 }
278
279 for (cv = cn->v; cv; cv = cv->next) {
280 if (cv->type != CFG_STRING) {
281 log_error("Ignoring invalid string in config file "
282 "activation/volume_list");
283 continue;
284 }
285 str = cv->v.str;
286 if (!*str) {
287 log_error("Ignoring empty string in config file "
288 "activation/volume_list");
289 continue;
290 }
291
292 /* Tag? */
293 if (*str == '@') {
294 str++;
295 if (!*str) {
296 log_error("Ignoring empty tag in config file "
297 "activation/volume_list");
298 continue;
299 }
300 /* If any host tag matches any LV or VG tag, activate */
301 if (!strcmp(str, "*")) {
302 if (str_list_match_list(&cmd->tags, &lv->tags)
303 || str_list_match_list(&cmd->tags,
304 &lv->vg->tags))
305 return 1;
306 else
307 continue;
308 }
309 /* If supplied tag matches LV or VG tag, activate */
310 if (str_list_match_item(&lv->tags, str) ||
311 str_list_match_item(&lv->vg->tags, str))
312 return 1;
313 else
314 continue;
315 }
13835b5f 316 if (!strchr(str, '/')) {
de17d760
AK
317 /* vgname supplied */
318 if (!strcmp(str, lv->vg->name))
319 return 1;
320 else
321 continue;
322 }
323 /* vgname/lvname */
0550c1b6 324 if (dm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
de17d760 325 lv->name) < 0) {
0550c1b6 326 log_error("dm_snprintf error from %s/%s", lv->vg->name,
de17d760
AK
327 lv->name);
328 continue;
329 }
330 if (!strcmp(path, str))
331 return 1;
332 }
333
334 return 0;
335}
336
fae0c576
AK
337int library_version(char *version, size_t size)
338{
d1d9800e
AK
339 if (!activation())
340 return 0;
341
f894b4b1 342 return dm_get_library_version(version, size);
fae0c576
AK
343}
344
fae0c576
AK
345int driver_version(char *version, size_t size)
346{
d1d9800e
AK
347 if (!activation())
348 return 0;
349
fae0c576 350 log_very_verbose("Getting driver version");
fae0c576 351
f894b4b1 352 return dm_driver_version(version, size);
fae0c576
AK
353}
354
bbf83db1
AK
355int target_version(const char *target_name, uint32_t *maj,
356 uint32_t *min, uint32_t *patchlevel)
d1f4953a
AK
357{
358 int r = 0;
359 struct dm_task *dmt;
360 struct dm_versions *target, *last_target;
361
d1f4953a 362 log_very_verbose("Getting target version for %s", target_name);
5f4b2acf
AK
363 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
364 return_0;
d1f4953a
AK
365
366 if (!dm_task_run(dmt)) {
367 log_debug("Failed to get %s target version", target_name);
368 /* Assume this was because LIST_VERSIONS isn't supported */
369 return 1;
370 }
371
372 target = dm_task_get_versions(dmt);
373
374 do {
375 last_target = target;
376
377 if (!strcmp(target_name, target->name)) {
378 r = 1;
bbf83db1
AK
379 *maj = target->version[0];
380 *min = target->version[1];
381 *patchlevel = target->version[2];
d1f4953a
AK
382 goto out;
383 }
384
385 target = (void *) target + target->next;
386 } while (last_target != target);
387
388 out:
389 dm_task_destroy(dmt);
390
391 return r;
392}
393
5f4b2acf 394int target_present(const char *target_name, int use_modprobe)
f894b4b1 395{
bbf83db1 396 uint32_t maj, min, patchlevel;
03b49fe1 397#ifdef MODPROBE_CMD
f894b4b1 398 char module[128];
03b49fe1 399#endif
f894b4b1
AK
400
401 if (!activation())
402 return 0;
403
404#ifdef MODPROBE_CMD
5f4b2acf 405 if (use_modprobe) {
bbf83db1 406 if (target_version(target_name, &maj, &min, &patchlevel))
5f4b2acf 407 return 1;
f894b4b1 408
0550c1b6 409 if (dm_snprintf(module, sizeof(module), "dm-%s", target_name)
5f4b2acf
AK
410 < 0) {
411 log_error("target_present module name too long: %s",
412 target_name);
413 return 0;
414 }
f894b4b1 415
5f4b2acf
AK
416 if (!exec_cmd(MODPROBE_CMD, module, "", ""))
417 return_0;
f894b4b1
AK
418 }
419#endif
420
bbf83db1 421 return target_version(target_name, &maj, &min, &patchlevel);
f894b4b1
AK
422}
423
de6c9183
JT
424/*
425 * Returns 1 if info structure populated, else 0 on failure.
426 */
f894b4b1 427static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int with_mknodes,
a6b22cf3 428 struct lvinfo *info, int with_open_count, int with_read_ahead, unsigned by_uuid_only)
37ed70b9 429{
199e490e 430 struct dm_info dminfo;
b45c9f49 431 char *name = NULL;
4a624ca0 432
d1d9800e
AK
433 if (!activation())
434 return 0;
435
b45c9f49
AK
436 if (!by_uuid_only &&
437 !(name = build_dm_name(cmd->mem, lv->vg->name, lv->name, NULL)))
5f4b2acf 438 return_0;
4a624ca0 439
f894b4b1 440 log_debug("Getting device info for %s", name);
03b49fe1 441 if (!dev_manager_info(lv->vg->cmd->mem, name, lv, with_mknodes,
a6b22cf3
AK
442 with_open_count, with_read_ahead, &dminfo,
443 &info->read_ahead)) {
b45c9f49
AK
444 if (name)
445 dm_pool_free(cmd->mem, name);
5f4b2acf 446 return_0;
f894b4b1 447 }
4a624ca0 448
199e490e
AK
449 info->exists = dminfo.exists;
450 info->suspended = dminfo.suspended;
451 info->open_count = dminfo.open_count;
452 info->major = dminfo.major;
453 info->minor = dminfo.minor;
454 info->read_only = dminfo.read_only;
5f4b2acf
AK
455 info->live_table = dminfo.live_table;
456 info->inactive_table = dminfo.inactive_table;
199e490e 457
b45c9f49
AK
458 if (name)
459 dm_pool_free(cmd->mem, name);
460
f894b4b1 461 return 1;
de6c9183 462}
a62ee8ad 463
f894b4b1 464int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, struct lvinfo *info,
a6b22cf3 465 int with_open_count, int with_read_ahead)
8c0388e4 466{
a6b22cf3 467 return _lv_info(cmd, lv, 0, info, with_open_count, with_read_ahead, 0);
8c0388e4
AK
468}
469
4bd9480d 470int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s,
a6b22cf3 471 struct lvinfo *info, int with_open_count, int with_read_ahead)
4bd9480d
AK
472{
473 struct logical_volume *lv;
474
7a593325 475 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
4bd9480d
AK
476 return 0;
477
a6b22cf3 478 return _lv_info(cmd, lv, 0, info, with_open_count, with_read_ahead, 0);
4bd9480d
AK
479}
480
1951dba9
AL
481/*
482 * Returns 1 if percent set, else 0 on failure.
483 */
472ac5bd 484int lv_snapshot_percent(const struct logical_volume *lv, float *percent)
1951dba9
AL
485{
486 int r;
487 struct dev_manager *dm;
488
d1d9800e
AK
489 if (!activation())
490 return 0;
491
5f4b2acf
AK
492 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
493 return_0;
1951dba9 494
c826c0d1 495 if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
1951dba9 496 stack;
c826c0d1 497
1951dba9
AL
498 dev_manager_destroy(dm);
499
500 return r;
501}
502
10b29b8d 503/* FIXME Merge with snapshot_percent */
472ac5bd
AK
504int lv_mirror_percent(struct cmd_context *cmd, struct logical_volume *lv,
505 int wait, float *percent, uint32_t *event_nr)
10b29b8d
AK
506{
507 int r;
508 struct dev_manager *dm;
b65b777d 509 struct lvinfo info;
10b29b8d
AK
510
511 if (!activation())
512 return 0;
513
a6b22cf3 514 if (!lv_info(cmd, lv, &info, 0, 0))
5f4b2acf 515 return_0;
b65b777d
AK
516
517 if (!info.exists)
518 return 0;
519
5f4b2acf
AK
520 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
521 return_0;
10b29b8d
AK
522
523 if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
524 stack;
525
526 dev_manager_destroy(dm);
527
528 return r;
529}
530
b45c9f49
AK
531static int _lv_active(struct cmd_context *cmd, struct logical_volume *lv,
532 unsigned by_uuid_only)
2ba80b43 533{
199e490e 534 struct lvinfo info;
2ba80b43 535
a6b22cf3 536 if (!_lv_info(cmd, lv, 0, &info, 0, 0, by_uuid_only)) {
2ba80b43 537 stack;
de6c9183 538 return -1;
2ba80b43
JT
539 }
540
de6c9183 541 return info.exists;
2ba80b43
JT
542}
543
f894b4b1 544static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
5986ec94 545{
199e490e 546 struct lvinfo info;
5986ec94 547
a6b22cf3 548 if (!lv_info(cmd, lv, &info, 1, 0)) {
5986ec94 549 stack;
de6c9183 550 return -1;
5986ec94
JT
551 }
552
de6c9183 553 return info.open_count;
5986ec94
JT
554}
555
658b5812 556static int _lv_activate_lv(struct logical_volume *lv)
b1713d28 557{
6d52fb46 558 int r;
de6c9183 559 struct dev_manager *dm;
b1713d28 560
5f4b2acf
AK
561 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
562 return_0;
ae2bb665 563
0fe3a2c5 564 if (!(r = dev_manager_activate(dm, lv)))
6d52fb46 565 stack;
ae2bb665 566
de6c9183 567 dev_manager_destroy(dm);
ae2bb665 568 return r;
b1713d28 569}
a381c45a 570
5f4b2acf 571static int _lv_preload(struct logical_volume *lv)
0a5e4a14 572{
de6c9183
JT
573 int r;
574 struct dev_manager *dm;
37ed70b9 575
5f4b2acf
AK
576 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
577 return_0;
578
579 if (!(r = dev_manager_preload(dm, lv)))
6d52fb46 580 stack;
5f4b2acf
AK
581
582 dev_manager_destroy(dm);
583 return r;
584}
585
586static int _lv_deactivate(struct logical_volume *lv)
587{
588 int r;
589 struct dev_manager *dm;
590
591 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
592 return_0;
37ed70b9 593
de6c9183 594 if (!(r = dev_manager_deactivate(dm, lv)))
37ed70b9 595 stack;
37ed70b9 596
de6c9183
JT
597 dev_manager_destroy(dm);
598 return r;
37ed70b9
JT
599}
600
9cd3426d 601static int _lv_suspend_lv(struct logical_volume *lv, int lockfs)
4a624ca0 602{
20c5fcf7
AK
603 int r;
604 struct dev_manager *dm;
c2d72fd4 605
5f4b2acf
AK
606 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name)))
607 return_0;
0a5e4a14 608
9cd3426d 609 if (!(r = dev_manager_suspend(dm, lv, lockfs)))
37ed70b9 610 stack;
0a5e4a14 611
20c5fcf7
AK
612 dev_manager_destroy(dm);
613 return r;
6d52fb46 614}
4a624ca0 615
8c013da4 616/*
f75c11ed 617 * These two functions return the number of visible LVs in the state,
8c013da4
AK
618 * or -1 on error.
619 */
b45c9f49 620static int _lvs_in_vg_activated(struct volume_group *vg, unsigned by_uuid_only)
f047219b 621{
60f13f01 622 struct lv_list *lvl;
94b8220f 623 int count = 0;
37ed70b9 624
d1d9800e
AK
625 if (!activation())
626 return 0;
627
60f13f01
AK
628 list_iterate_items(lvl, &vg->lvs) {
629 if (lvl->lv->status & VISIBLE_LV)
b45c9f49 630 count += (_lv_active(vg->cmd, lvl->lv, by_uuid_only) == 1);
37ed70b9
JT
631 }
632
633 return count;
f047219b 634}
2ba80b43 635
b45c9f49
AK
636int lvs_in_vg_activated_by_uuid_only(struct volume_group *vg)
637{
638 return _lvs_in_vg_activated(vg, 1);
639}
640
641int lvs_in_vg_activated(struct volume_group *vg)
642{
643 return _lvs_in_vg_activated(vg, 0);
644}
645
08c9ff43 646int lvs_in_vg_opened(const struct volume_group *vg)
2ba80b43 647{
08c9ff43 648 const struct lv_list *lvl;
94b8220f 649 int count = 0;
2ba80b43 650
d1d9800e
AK
651 if (!activation())
652 return 0;
653
60f13f01
AK
654 list_iterate_items(lvl, &vg->lvs) {
655 if (lvl->lv->status & VISIBLE_LV)
f894b4b1 656 count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
2ba80b43
JT
657 }
658
659 return count;
660}
413cc918 661
3e3d5d85 662/*
8a37910d
AK
663 * Returns 0 if an attempt to (un)monitor the device failed.
664 * Returns 1 otherwise.
3e3d5d85 665 */
8a37910d
AK
666int monitor_dev_for_events(struct cmd_context *cmd,
667 struct logical_volume *lv, int monitor)
15d91f5a 668{
ed09d7e3 669#ifdef DMEVENTD
8a37910d
AK
670 int i, pending = 0, monitored;
671 int r = 1;
15d91f5a
AK
672 struct list *tmp;
673 struct lv_segment *seg;
24f4552b 674 int (*monitor_fn) (struct lv_segment *s, int e);
15d91f5a 675
20db8ffc
AK
676 /* skip dmeventd code altogether */
677 if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
678 return 1;
679
8a37910d
AK
680 /*
681 * Nothing to do if dmeventd configured not to be used.
682 */
683 if (monitor && !dmeventd_monitor_mode())
3e3d5d85
AK
684 return 1;
685
15d91f5a
AK
686 list_iterate(tmp, &lv->segments) {
687 seg = list_item(tmp, struct lv_segment);
688
8ef6eb30
AK
689 if (!seg_monitored(seg) || (seg->status & PVMOVE))
690 continue;
8a37910d
AK
691
692 monitor_fn = NULL;
ed09d7e3 693
8ef6eb30 694 /* Check monitoring status */
8a37910d
AK
695 if (seg->segtype->ops->target_monitored)
696 monitored = seg->segtype->ops->target_monitored(seg, &pending);
8ef6eb30
AK
697 else
698 continue; /* segtype doesn't support registration */
699
700 /*
701 * FIXME: We should really try again if pending
702 */
8a37910d 703 monitored = (pending) ? 0 : monitored;
8ef6eb30 704
8a37910d
AK
705 if (monitor) {
706 if (monitored)
8ef6eb30 707 log_verbose("%s/%s already monitored.", lv->vg->name, lv->name);
8a37910d
AK
708 else if (seg->segtype->ops->target_monitor_events)
709 monitor_fn = seg->segtype->ops->target_monitor_events;
8ef6eb30 710 } else {
8a37910d 711 if (!monitored)
8ef6eb30 712 log_verbose("%s/%s already not monitored.", lv->vg->name, lv->name);
8a37910d
AK
713 else if (seg->segtype->ops->target_unmonitor_events)
714 monitor_fn = seg->segtype->ops->target_unmonitor_events;
8ef6eb30 715 }
15d91f5a 716
8ef6eb30 717 /* Do [un]monitor */
8a37910d 718 if (!monitor_fn)
3e3d5d85 719 continue;
e24e7130 720
8a37910d
AK
721 log_verbose("%sonitoring %s/%s", monitor ? "M" : "Not m", lv->vg->name, lv->name);
722
3e3d5d85 723 /* FIXME specify events */
57fc4cc0 724 if (!monitor_fn(seg, 0)) {
8a37910d
AK
725 log_error("%s/%s: %s segment monitoring function failed.",
726 lv->vg->name, lv->name, seg->segtype->name);
727 return 0;
e24e7130 728 }
3e3d5d85 729
8ef6eb30
AK
730 /* Check [un]monitor results */
731 /* Try a couple times if pending, but not forever... */
732 for (i = 0; i < 10; i++) {
733 pending = 0;
8a37910d 734 monitored = seg->segtype->ops->target_monitored(seg, &pending);
8ef6eb30 735 if (pending ||
8a37910d
AK
736 (!monitored && monitor) ||
737 (monitored && !monitor))
738 log_very_verbose("%s/%s %smonitoring still pending: waiting...",
739 lv->vg->name, lv->name, monitor ? "" : "un");
8ef6eb30
AK
740 else
741 break;
742 sleep(1);
743 }
744
8a37910d 745 r = (monitored && monitor) || (!monitored && !monitor);
15d91f5a 746 }
e6493477 747
3e3d5d85
AK
748 return r;
749#else
15d91f5a 750 return 1;
3e3d5d85 751#endif
15d91f5a 752}
15d91f5a 753
658b5812
AK
754static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
755 int error_if_not_suspended)
413cc918 756{
8b888354 757 struct logical_volume *lv, *lv_pre;
199e490e 758 struct lvinfo info;
9cd3426d 759 int lockfs = 0;
413cc918 760
d1d9800e
AK
761 if (!activation())
762 return 1;
763
8b888354 764 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
e408d62e 765 return_0;
8b888354 766
7a593325 767 /* Use precommitted metadata if present */
8b888354 768 if (!(lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
e408d62e 769 return_0;
413cc918 770
20c5fcf7
AK
771 if (test_mode()) {
772 _skip("Suspending '%s'.", lv->name);
711f7fc6 773 return 1;
20c5fcf7
AK
774 }
775
a6b22cf3 776 if (!lv_info(cmd, lv, &info, 0, 0))
5f4b2acf 777 return_0;
41967a02 778
914c9723 779 if (!info.exists || info.suspended)
658b5812 780 return error_if_not_suspended ? 0 : 1;
914c9723 781
5f4b2acf 782 /* If VG was precommitted, preload devices for the LV */
8b888354
AK
783 if ((lv_pre->vg->status & PRECOMMITTED)) {
784 if (!_lv_preload(lv_pre)) {
5f4b2acf
AK
785 /* FIXME Revert preloading */
786 return_0;
787 }
788 }
789
8a37910d 790 if (!monitor_dev_for_events(cmd, lv, 0))
e24e7130 791 /* FIXME Consider aborting here */
ed09d7e3
AK
792 stack;
793
914c9723 794 memlock_inc();
9cd3426d
AK
795
796 if (lv_is_origin(lv_pre) || lv_is_cow(lv_pre))
797 lockfs = 1;
798
799 if (!_lv_suspend_lv(lv, lockfs)) {
914c9723
AK
800 memlock_dec();
801 fs_unlock();
802 return 0;
803 }
8c013da4 804
413cc918
AK
805 return 1;
806}
807
658b5812
AK
808/* Returns success if the device is not active */
809int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s)
810{
811 return _lv_suspend(cmd, lvid_s, 0);
812}
813
814int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
815{
816 return _lv_suspend(cmd, lvid_s, 1);
817}
818
819static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
820 int error_if_not_active)
413cc918
AK
821{
822 struct logical_volume *lv;
199e490e 823 struct lvinfo info;
413cc918 824
d1d9800e
AK
825 if (!activation())
826 return 1;
827
7a593325 828 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
413cc918
AK
829 return 0;
830
20c5fcf7
AK
831 if (test_mode()) {
832 _skip("Resuming '%s'.", lv->name);
711f7fc6 833 return 1;
20c5fcf7
AK
834 }
835
a6b22cf3 836 if (!lv_info(cmd, lv, &info, 0, 0))
5f4b2acf 837 return_0;
41967a02 838
914c9723 839 if (!info.exists || !info.suspended)
658b5812 840 return error_if_not_active ? 0 : 1;
914c9723 841
658b5812 842 if (!_lv_activate_lv(lv))
914c9723
AK
843 return 0;
844
845 memlock_dec();
846 fs_unlock();
413cc918 847
8a37910d 848 if (!monitor_dev_for_events(cmd, lv, 1))
ed09d7e3 849 stack;
15d91f5a 850
413cc918
AK
851 return 1;
852}
853
658b5812
AK
854/* Returns success if the device is not active */
855int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s)
856{
857 return _lv_resume(cmd, lvid_s, 0);
858}
859
860int lv_resume(struct cmd_context *cmd, const char *lvid_s)
861{
862 return _lv_resume(cmd, lvid_s, 1);
863}
864
be326a2f 865int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
f4cbeaf0
AK
866{
867 struct logical_volume *lv;
199e490e 868 struct lvinfo info;
914c9723 869 int r;
f4cbeaf0 870
d1d9800e
AK
871 if (!activation())
872 return 1;
873
7a593325 874 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
f4cbeaf0
AK
875 return 0;
876
20c5fcf7
AK
877 if (test_mode()) {
878 _skip("Deactivating '%s'.", lv->name);
711f7fc6 879 return 1;
20c5fcf7
AK
880 }
881
a6b22cf3 882 if (!lv_info(cmd, lv, &info, 1, 0))
5f4b2acf 883 return_0;
41967a02 884
914c9723
AK
885 if (!info.exists)
886 return 1;
f4cbeaf0 887
c1f50521 888 if (info.open_count && (lv->status & VISIBLE_LV)) {
5f4b2acf 889 log_error("LV %s/%s in use: not deactivating", lv->vg->name,
0cf96f33
AK
890 lv->name);
891 return 0;
892 }
893
8a37910d 894 if (!monitor_dev_for_events(cmd, lv, 0))
ed09d7e3 895 stack;
15d91f5a 896
914c9723
AK
897 memlock_inc();
898 r = _lv_deactivate(lv);
899 memlock_dec();
900 fs_unlock();
901
902 return r;
f4cbeaf0
AK
903}
904
658b5812
AK
905/* Test if LV passes filter */
906int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
907 int *activate_lv)
908{
909 struct logical_volume *lv;
910
911 if (!activation())
912 goto activate;
913
7a593325 914 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
658b5812
AK
915 return 0;
916
917 if (!_passes_activation_filter(cmd, lv)) {
918 log_verbose("Not activating %s/%s due to config file settings",
919 lv->vg->name, lv->name);
920 *activate_lv = 0;
921 return 1;
922 }
923
924 activate:
925 *activate_lv = 1;
926 return 1;
927}
928
07d31831
AK
929static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
930 int exclusive, int filter)
f4cbeaf0
AK
931{
932 struct logical_volume *lv;
199e490e 933 struct lvinfo info;
914c9723 934 int r;
f4cbeaf0 935
d1d9800e
AK
936 if (!activation())
937 return 1;
938
7a593325 939 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
f4cbeaf0
AK
940 return 0;
941
658b5812 942 if (filter && !_passes_activation_filter(cmd, lv)) {
de17d760
AK
943 log_verbose("Not activating %s/%s due to config file settings",
944 lv->vg->name, lv->name);
945 return 0;
946 }
947
20c5fcf7
AK
948 if (test_mode()) {
949 _skip("Activating '%s'.", lv->name);
711f7fc6 950 return 1;
20c5fcf7
AK
951 }
952
a6b22cf3 953 if (!lv_info(cmd, lv, &info, 0, 0))
5f4b2acf 954 return_0;
8c013da4 955
5f4b2acf 956 if (info.exists && !info.suspended && info.live_table)
914c9723 957 return 1;
f4cbeaf0 958
07d31831
AK
959 if (exclusive)
960 lv->status |= ACTIVATE_EXCL;
961
914c9723 962 memlock_inc();
658b5812 963 r = _lv_activate_lv(lv);
914c9723
AK
964 memlock_dec();
965 fs_unlock();
966
5efd97f1 967 if (r && !monitor_dev_for_events(cmd, lv, 1))
ed09d7e3 968 stack;
15d91f5a 969
914c9723 970 return r;
f4cbeaf0 971}
199e490e 972
658b5812 973/* Activate LV */
07d31831 974int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812 975{
07d31831 976 return _lv_activate(cmd, lvid_s, exclusive, 0);
658b5812
AK
977}
978
979/* Activate LV only if it passes filter */
07d31831 980int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812 981{
07d31831 982 return _lv_activate(cmd, lvid_s, exclusive, 1);
658b5812
AK
983}
984
f7dd6d84
AK
985int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
986{
987 struct lvinfo info;
988 int r = 1;
989
8b076648 990 if (!lv) {
2262b320 991 r = dm_mknodes(NULL);
8b076648
AK
992 fs_unlock();
993 return r;
994 }
995
a6b22cf3 996 if (!_lv_info(cmd, lv, 1, &info, 0, 0, 0))
5f4b2acf 997 return_0;
f7dd6d84
AK
998
999 if (info.exists)
f09fe0ad 1000 r = dev_manager_lv_mknodes(lv);
f7dd6d84 1001 else
f09fe0ad 1002 r = dev_manager_lv_rmnodes(lv);
f7dd6d84
AK
1003
1004 fs_unlock();
1005
1006 return r;
1007}
1008
352a99b9
AK
1009/*
1010 * Does PV use VG somewhere in its construction?
1011 * Returns 1 on failure.
1012 */
898e6f8e 1013int pv_uses_vg(struct physical_volume *pv,
3e3d5d85 1014 struct volume_group *vg)
352a99b9 1015{
352a99b9
AK
1016 if (!activation())
1017 return 0;
1018
1019 if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
1020 return 0;
1021
898e6f8e 1022 return dev_manager_device_uses_vg(pv->dev, vg);
352a99b9
AK
1023}
1024
2293567c
AK
1025void activation_release(void)
1026{
1027 dev_manager_release();
1028}
1029
914c9723
AK
1030void activation_exit(void)
1031{
1032 dev_manager_exit();
1033}
199e490e 1034#endif
This page took 0.183553 seconds and 5 git commands to generate.