]> sourceware.org Git - lvm2.git/blame - lib/activate/activate.c
args: add --activate synonym for --available arg
[lvm2.git] / lib / activate / activate.c
CommitLineData
b1713d28 1/*
67cdbd7e 2 * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
a18dcfb5 3 * Copyright (C) 2004-2012 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"
d1e8046f 31#include "sharedlib.h"
12137231
JT
32
33#include <limits.h>
5986ec94 34#include <fcntl.h>
914c9723 35#include <unistd.h>
12137231 36
6d52fb46 37#define _skip(fmt, args...) log_very_verbose("Skipping: " fmt , ## args)
b1713d28 38
7d1552c9
AK
39int lvm1_present(struct cmd_context *cmd)
40{
900f5f81 41 static char path[PATH_MAX];
7d1552c9 42
0550c1b6 43 if (dm_snprintf(path, sizeof(path), "%s/lvm/global", cmd->proc_dir)
7d1552c9
AK
44 < 0) {
45 log_error("LVM1 proc global snprintf failed");
46 return 0;
47 }
48
49 if (path_exists(path))
50 return 1;
51 else
52 return 0;
53}
54
6c81ed26 55int list_segment_modules(struct dm_pool *mem, const struct lv_segment *seg,
2c44337b 56 struct dm_list *modules)
6c81ed26
AK
57{
58 unsigned int s;
59 struct lv_segment *seg2, *snap_seg;
2c44337b 60 struct dm_list *snh;
6c81ed26
AK
61
62 if (seg->segtype->ops->modules_needed &&
63 !seg->segtype->ops->modules_needed(mem, seg, modules)) {
64 log_error("module string allocation failed");
65 return 0;
66 }
67
68 if (lv_is_origin(seg->lv))
2c44337b 69 dm_list_iterate(snh, &seg->lv->snapshot_segs)
6c81ed26 70 if (!list_lv_modules(mem,
2c44337b 71 dm_list_struct_base(snh,
6c81ed26
AK
72 struct lv_segment,
73 origin_list)->cow,
74 modules))
75 return_0;
76
77 if (lv_is_cow(seg->lv)) {
78 snap_seg = find_cow(seg->lv);
79 if (snap_seg->segtype->ops->modules_needed &&
80 !snap_seg->segtype->ops->modules_needed(mem, snap_seg,
81 modules)) {
82 log_error("snap_seg module string allocation failed");
83 return 0;
84 }
85 }
86
87 for (s = 0; s < seg->area_count; s++) {
88 switch (seg_type(seg, s)) {
89 case AREA_LV:
90 seg2 = find_seg_by_le(seg_lv(seg, s), seg_le(seg, s));
91 if (seg2 && !list_segment_modules(mem, seg2, modules))
92 return_0;
93 break;
94 case AREA_PV:
95 case AREA_UNASSIGNED:
96 ;
97 }
98 }
99
100 return 1;
101}
102
103int list_lv_modules(struct dm_pool *mem, const struct logical_volume *lv,
2c44337b 104 struct dm_list *modules)
6c81ed26
AK
105{
106 struct lv_segment *seg;
107
2c44337b 108 dm_list_iterate_items(seg, &lv->segments)
6c81ed26
AK
109 if (!list_segment_modules(mem, seg, modules))
110 return_0;
111
112 return 1;
113}
114
199e490e
AK
115#ifndef DEVMAPPER_SUPPORT
116void set_activation(int act)
117{
f2046e0a
AK
118 static int warned = 0;
119
120 if (warned || !act)
121 return;
122
123 log_error("Compiled without libdevmapper support. "
124 "Can't enable activation.");
125
126 warned = 1;
199e490e
AK
127}
128int activation(void)
129{
130 return 0;
131}
132int library_version(char *version, size_t size)
133{
134 return 0;
135}
136int driver_version(char *version, size_t size)
137{
138 return 0;
139}
bbf83db1
AK
140int target_version(const char *target_name, uint32_t *maj,
141 uint32_t *min, uint32_t *patchlevel)
142{
143 return 0;
144}
ed82bfd2
AK
145int target_present(struct cmd_context *cmd, const char *target_name,
146 int use_modprobe)
d1f4953a
AK
147{
148 return 0;
149}
b1859936 150int lvm_dm_prefix_check(int major, int minor, const char *prefix)
07113bee
MB
151{
152 return 0;
153}
e8905d98 154int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
2d6fcbf6 155 struct lvinfo *info, int with_open_count, int with_read_ahead)
199e490e
AK
156{
157 return 0;
158}
e8905d98 159int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
a6b22cf3 160 struct lvinfo *info, int with_open_count, int with_read_ahead)
4bd9480d
AK
161{
162 return 0;
163}
b1859936
ZK
164int lv_check_not_in_use(struct cmd_context *cmd __attribute__((unused)),
165 struct logical_volume *lv, struct lvinfo *info)
166{
167 return 0;
168}
8191fe4f 169int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent)
199e490e
AK
170{
171 return 0;
172}
aec21154 173int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
8191fe4f 174 int wait, percent_t *percent, uint32_t *event_nr)
10b29b8d
AK
175{
176 return 0;
177}
b1859936
ZK
178int lv_raid_percent(const struct logical_volume *lv, percent_t *percent)
179{
180 return 0;
181}
182int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
183 percent_t *percent)
184{
185 return 0;
186}
187int lv_thin_percent(const struct logical_volume *lv, int mapped,
188 percent_t *percent)
189{
190 return 0;
191}
192int lv_thin_pool_transaction_id(const struct logical_volume *lv,
193 uint64_t *transaction_id)
194{
195 return 0;
196}
499a1616 197int lvs_in_vg_activated(const struct volume_group *vg)
199e490e
AK
198{
199 return 0;
200}
ab8b85fb 201int lvs_in_vg_opened(const struct volume_group *vg)
199e490e
AK
202{
203 return 0;
204}
2d6fcbf6 205/******
658b5812
AK
206int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
207{
208 return 1;
209}
2d6fcbf6 210*******/
b1859936 211int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive)
199e490e
AK
212{
213 return 1;
214}
ab8b85fb 215int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only)
658b5812
AK
216{
217 return 1;
218}
ab8b85fb 219int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
10d0d9c7 220 unsigned origin_only, unsigned exclusive, unsigned revert)
199e490e
AK
221{
222 return 1;
223}
224int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
225{
226 return 1;
227}
658b5812
AK
228int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
229 int *activate_lv)
230{
231 return 1;
232}
07d31831 233int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
199e490e
AK
234{
235 return 1;
236}
07d31831 237int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812
AK
238{
239 return 1;
240}
f7dd6d84
AK
241int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
242{
243 return 1;
244}
0ce83a83 245int pv_uses_vg(struct physical_volume *pv,
3e3d5d85 246 struct volume_group *vg)
352a99b9
AK
247{
248 return 0;
249}
2293567c
AK
250void activation_release(void)
251{
2293567c 252}
914c9723
AK
253void activation_exit(void)
254{
914c9723 255}
b19f0121 256
499a1616 257int lv_is_active(const struct logical_volume *lv)
ab8b85fb
ZK
258{
259 return 0;
260}
499a1616 261int lv_is_active_but_not_locally(const struct logical_volume *lv)
b19f0121
JEB
262{
263 return 0;
264}
499a1616 265int lv_is_active_exclusive(const struct logical_volume *lv)
b19f0121
JEB
266{
267 return 0;
268}
499a1616 269int lv_is_active_exclusive_locally(const struct logical_volume *lv)
ab8b85fb
ZK
270{
271 return 0;
272}
499a1616 273int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
ab8b85fb
ZK
274{
275 return 0;
276}
b19f0121 277
ab8b85fb
ZK
278int lv_check_transient(struct logical_volume *lv)
279{
280 return 1;
281}
282int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
b1859936 283 const struct lv_activate_opts *laopts, int monitor)
ab8b85fb
ZK
284{
285 return 1;
286}
b1859936
ZK
287/* fs.c */
288void fs_unlock(void)
289{
290}
291/* dev_manager.c */
499a1616 292#include "targets.h"
b1859936
ZK
293int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
294 struct dm_tree_node *node, uint32_t start_area,
295 uint32_t areas)
296{
297 return 0;
298}
299int device_is_usable(struct device *dev)
300{
301 return 0;
302}
303int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv,
304 const char *layer, const char *target_type)
305{
306 return 0;
307}
199e490e
AK
308#else /* DEVMAPPER_SUPPORT */
309
d1d9800e
AK
310static int _activation = 1;
311
8ef2b021 312void set_activation(int act)
d1d9800e 313{
8ef2b021 314 if (act == _activation)
d1d9800e
AK
315 return;
316
8ef2b021 317 _activation = act;
d1d9800e
AK
318 if (_activation)
319 log_verbose("Activation enabled. Device-mapper kernel "
320 "driver will be used.");
321 else
e7ddf416 322 log_warn("WARNING: Activation disabled. No device-mapper "
bfe2b548 323 "interaction will be attempted.");
d1d9800e
AK
324}
325
8ef2b021 326int activation(void)
d1d9800e
AK
327{
328 return _activation;
329}
330
a18dcfb5
AK
331static int _passes_volumes_filter(struct cmd_context *cmd,
332 struct logical_volume *lv,
333 const struct dm_config_node *cn,
334 const char *config_path)
de17d760 335{
e59e2f7c 336 const struct dm_config_value *cv;
760d1fac 337 const char *str;
900f5f81 338 static char path[PATH_MAX];
de17d760 339
a18dcfb5
AK
340 log_verbose("%s configuration setting defined: "
341 "Checking the list to match %s/%s",
342 config_path, lv->vg->name, lv->name);
fefa4323 343
f7e3a19f 344 for (cv = cn->v; cv; cv = cv->next) {
e59e2f7c 345 if (cv->type != DM_CFG_STRING) {
a18dcfb5
AK
346 log_error("Ignoring invalid string in config file %s",
347 config_path);
de17d760
AK
348 continue;
349 }
350 str = cv->v.str;
351 if (!*str) {
a18dcfb5
AK
352 log_error("Ignoring empty string in config file %s",
353 config_path);
de17d760
AK
354 continue;
355 }
356
f7e3a19f 357
de17d760
AK
358 /* Tag? */
359 if (*str == '@') {
360 str++;
361 if (!*str) {
362 log_error("Ignoring empty tag in config file "
a18dcfb5 363 "%s", config_path);
de17d760
AK
364 continue;
365 }
366 /* If any host tag matches any LV or VG tag, activate */
367 if (!strcmp(str, "*")) {
eb82bd05 368 if (str_list_match_list(&cmd->tags, &lv->tags, NULL)
de17d760 369 || str_list_match_list(&cmd->tags,
eb82bd05 370 &lv->vg->tags, NULL))
de17d760
AK
371 return 1;
372 else
373 continue;
374 }
375 /* If supplied tag matches LV or VG tag, activate */
376 if (str_list_match_item(&lv->tags, str) ||
377 str_list_match_item(&lv->vg->tags, str))
378 return 1;
379 else
380 continue;
381 }
13835b5f 382 if (!strchr(str, '/')) {
de17d760
AK
383 /* vgname supplied */
384 if (!strcmp(str, lv->vg->name))
385 return 1;
386 else
387 continue;
388 }
389 /* vgname/lvname */
0550c1b6 390 if (dm_snprintf(path, sizeof(path), "%s/%s", lv->vg->name,
de17d760 391 lv->name) < 0) {
0550c1b6 392 log_error("dm_snprintf error from %s/%s", lv->vg->name,
de17d760
AK
393 lv->name);
394 continue;
395 }
396 if (!strcmp(path, str))
397 return 1;
398 }
399
a18dcfb5
AK
400 log_verbose("No item supplied in %s configuration setting "
401 "matches %s/%s", config_path, lv->vg->name, lv->name);
fefa4323 402
de17d760
AK
403 return 0;
404}
405
a18dcfb5
AK
406static int _passes_activation_filter(struct cmd_context *cmd,
407 struct logical_volume *lv)
408{
409 const struct dm_config_node *cn;
410
411 if (!(cn = find_config_tree_node(cmd, "activation/volume_list"))) {
412 log_verbose("activation/volume_list configuration setting "
413 "not defined: Checking only host tags for %s/%s",
414 lv->vg->name, lv->name);
415
416 /* If no host tags defined, activate */
417 if (dm_list_empty(&cmd->tags))
418 return 1;
419
420 /* If any host tag matches any LV or VG tag, activate */
421 if (str_list_match_list(&cmd->tags, &lv->tags, NULL) ||
422 str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
423 return 1;
424
425 log_verbose("No host tag matches %s/%s",
426 lv->vg->name, lv->name);
427
428 /* Don't activate */
429 return 0;
430 }
431
432 return _passes_volumes_filter(cmd, lv, cn, "activation/volume_list");
433}
434
435static int _passes_readonly_filter(struct cmd_context *cmd,
436 struct logical_volume *lv)
437{
5d5c80ac 438 const struct dm_config_node *cn;
a18dcfb5
AK
439
440 if (!(cn = find_config_tree_node(cmd, "activation/read_only_volume_list")))
441 return 0;
442
443 return _passes_volumes_filter(cmd, lv, cn, "activation/read_only_volume_list");
444}
445
fae0c576
AK
446int library_version(char *version, size_t size)
447{
d1d9800e
AK
448 if (!activation())
449 return 0;
450
f894b4b1 451 return dm_get_library_version(version, size);
fae0c576
AK
452}
453
fae0c576
AK
454int driver_version(char *version, size_t size)
455{
d1d9800e
AK
456 if (!activation())
457 return 0;
458
fae0c576 459 log_very_verbose("Getting driver version");
fae0c576 460
f894b4b1 461 return dm_driver_version(version, size);
fae0c576
AK
462}
463
bbf83db1
AK
464int target_version(const char *target_name, uint32_t *maj,
465 uint32_t *min, uint32_t *patchlevel)
d1f4953a
AK
466{
467 int r = 0;
468 struct dm_task *dmt;
469 struct dm_versions *target, *last_target;
470
d1f4953a 471 log_very_verbose("Getting target version for %s", target_name);
5f4b2acf
AK
472 if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
473 return_0;
d1f4953a 474
2243718f
AK
475 if (activation_checks() && !dm_task_enable_checks(dmt))
476 goto_out;
477
d1f4953a
AK
478 if (!dm_task_run(dmt)) {
479 log_debug("Failed to get %s target version", target_name);
480 /* Assume this was because LIST_VERSIONS isn't supported */
209da6ef
ZK
481 *maj = 0;
482 *min = 0;
483 *patchlevel = 0;
484 r = 1;
485 goto out;
d1f4953a
AK
486 }
487
488 target = dm_task_get_versions(dmt);
489
490 do {
491 last_target = target;
492
493 if (!strcmp(target_name, target->name)) {
494 r = 1;
bbf83db1
AK
495 *maj = target->version[0];
496 *min = target->version[1];
497 *patchlevel = target->version[2];
d1f4953a
AK
498 goto out;
499 }
500
d40d166f 501 target = (struct dm_versions *)((char *) target + target->next);
d1f4953a
AK
502 } while (last_target != target);
503
504 out:
505 dm_task_destroy(dmt);
506
507 return r;
508}
509
a3390bb5 510int lvm_dm_prefix_check(int major, int minor, const char *prefix)
07113bee
MB
511{
512 struct dm_task *dmt;
513 const char *uuid;
514 int r;
515
516 if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
d1b36fbe 517 return_0;
07113bee
MB
518
519 if (!dm_task_set_minor(dmt, minor) ||
520 !dm_task_set_major(dmt, major) ||
521 !dm_task_run(dmt) ||
522 !(uuid = dm_task_get_uuid(dmt))) {
523 dm_task_destroy(dmt);
524 return 0;
525 }
526
527 r = strncasecmp(uuid, prefix, strlen(prefix));
528 dm_task_destroy(dmt);
529
d1b36fbe 530 return r ? 0 : 1;
07113bee
MB
531}
532
ed82bfd2 533int module_present(struct cmd_context *cmd, const char *target_name)
f894b4b1 534{
5619c629 535 int ret = 0;
03b49fe1 536#ifdef MODPROBE_CMD
f894b4b1 537 char module[128];
c8669f6b 538 const char *argv[3];
5619c629
MB
539
540 if (dm_snprintf(module, sizeof(module), "dm-%s", target_name) < 0) {
541 log_error("module_present module name too long: %s",
542 target_name);
543 return 0;
544 }
545
c8669f6b
ZK
546 argv[0] = MODPROBE_CMD;
547 argv[1] = module;
548 argv[2] = NULL;
549
b1b38215 550 ret = exec_cmd(cmd, argv, NULL, 0);
03b49fe1 551#endif
5619c629
MB
552 return ret;
553}
554
ed82bfd2
AK
555int target_present(struct cmd_context *cmd, const char *target_name,
556 int use_modprobe)
5619c629
MB
557{
558 uint32_t maj, min, patchlevel;
f894b4b1
AK
559
560 if (!activation())
561 return 0;
562
563#ifdef MODPROBE_CMD
5f4b2acf 564 if (use_modprobe) {
bbf83db1 565 if (target_version(target_name, &maj, &min, &patchlevel))
5f4b2acf 566 return 1;
f894b4b1 567
ed82bfd2 568 if (!module_present(cmd, target_name))
5f4b2acf 569 return_0;
f894b4b1
AK
570 }
571#endif
572
bbf83db1 573 return target_version(target_name, &maj, &min, &patchlevel);
f894b4b1
AK
574}
575
de6c9183
JT
576/*
577 * Returns 1 if info structure populated, else 0 on failure.
578 */
e8905d98 579int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
ab9663f3 580 struct lvinfo *info, int with_open_count, int with_read_ahead)
37ed70b9 581{
199e490e 582 struct dm_info dminfo;
e8905d98 583 const char *layer;
4a624ca0 584
d1d9800e
AK
585 if (!activation())
586 return 0;
56cab8cc
ZK
587 /*
588 * If open_count info is requested and we have to be sure our own udev
589 * transactions are finished
590 * For non-clustered locking type we are only interested for non-delete operation
591 * in progress - as only those could lead to opened files
592 */
593 if (with_open_count) {
594 if (locking_is_clustered())
595 sync_local_dev_names(cmd); /* Wait to have udev in sync */
f5f6dcbc 596 else if (fs_has_non_delete_ops())
56cab8cc
ZK
597 fs_unlock(); /* For non clustered - wait if there are non-delete ops */
598 }
d1d9800e 599
e8905d98
ZK
600 if (use_layer && lv_is_thin_pool(lv))
601 layer = "tpool";
602 else if (use_layer && lv_is_origin(lv))
603 layer = "real";
604 else
605 layer = NULL;
606
607 if (!dev_manager_info(lv->vg->cmd->mem, lv, layer, with_open_count,
ab9663f3 608 with_read_ahead, &dminfo, &info->read_ahead))
5f4b2acf 609 return_0;
4a624ca0 610
199e490e
AK
611 info->exists = dminfo.exists;
612 info->suspended = dminfo.suspended;
613 info->open_count = dminfo.open_count;
614 info->major = dminfo.major;
615 info->minor = dminfo.minor;
616 info->read_only = dminfo.read_only;
5f4b2acf
AK
617 info->live_table = dminfo.live_table;
618 info->inactive_table = dminfo.inactive_table;
199e490e 619
f894b4b1 620 return 1;
de6c9183 621}
a62ee8ad 622
e8905d98 623int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
a6b22cf3 624 struct lvinfo *info, int with_open_count, int with_read_ahead)
4bd9480d 625{
0548bcc2 626 int r;
4bd9480d
AK
627 struct logical_volume *lv;
628
7a593325 629 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
4bd9480d
AK
630 return 0;
631
e8905d98 632 r = lv_info(cmd, lv, use_layer, info, with_open_count, with_read_ahead);
077a6755 633 release_vg(lv->vg);
0548bcc2
MB
634
635 return r;
4bd9480d
AK
636}
637
125712be
PR
638int lv_check_not_in_use(struct cmd_context *cmd __attribute__((unused)),
639 struct logical_volume *lv, struct lvinfo *info)
640{
641 if (!info->exists)
642 return 1;
643
644 /* If sysfs is not used, use open_count information only. */
c3e5b497
PR
645 if (!*dm_sysfs_dir()) {
646 if (info->open_count) {
647 log_error("Logical volume %s/%s in use.",
648 lv->vg->name, lv->name);
649 return 0;
650 }
651
652 return 1;
653 }
125712be
PR
654
655 if (dm_device_has_holders(info->major, info->minor)) {
656 log_error("Logical volume %s/%s is used by another device.",
657 lv->vg->name, lv->name);
658 return 0;
659 }
660
661 if (dm_device_has_mounted_fs(info->major, info->minor)) {
662 log_error("Logical volume %s/%s contains a filesystem in use.",
663 lv->vg->name, lv->name);
664 return 0;
665 }
666
667 return 1;
668}
669
d345bf2c
PR
670/*
671 * Returns 1 if percent set, else 0 on failure.
672 */
673int lv_check_transient(struct logical_volume *lv)
674{
675 int r;
676 struct dev_manager *dm;
677
678 if (!activation())
679 return 0;
680
7df72b3c
AK
681 log_debug("Checking transient status for LV %s/%s", lv->vg->name, lv->name);
682
df390f17 683 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
d345bf2c
PR
684 return_0;
685
686 if (!(r = dev_manager_transient(dm, lv)))
687 stack;
688
689 dev_manager_destroy(dm);
690
691 return r;
692}
693
1951dba9
AL
694/*
695 * Returns 1 if percent set, else 0 on failure.
696 */
8191fe4f 697int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent)
1951dba9
AL
698{
699 int r;
700 struct dev_manager *dm;
701
d1d9800e
AK
702 if (!activation())
703 return 0;
704
7df72b3c
AK
705 log_debug("Checking snapshot percent for LV %s/%s", lv->vg->name, lv->name);
706
df390f17 707 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
5f4b2acf 708 return_0;
1951dba9 709
8191fe4f 710 if (!(r = dev_manager_snapshot_percent(dm, lv, percent)))
1951dba9 711 stack;
c826c0d1 712
1951dba9
AL
713 dev_manager_destroy(dm);
714
715 return r;
716}
717
10b29b8d 718/* FIXME Merge with snapshot_percent */
aec21154 719int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
8191fe4f 720 int wait, percent_t *percent, uint32_t *event_nr)
10b29b8d
AK
721{
722 int r;
723 struct dev_manager *dm;
b65b777d 724 struct lvinfo info;
10b29b8d 725
876003dc
AK
726 /* If mirrored LV is temporarily shrinked to 1 area (= linear),
727 * it should be considered in-sync. */
2c44337b 728 if (dm_list_size(&lv->segments) == 1 && first_seg(lv)->area_count == 1) {
8191fe4f 729 *percent = PERCENT_100;
876003dc
AK
730 return 1;
731 }
732
10b29b8d
AK
733 if (!activation())
734 return 0;
735
7df72b3c
AK
736 log_debug("Checking mirror percent for LV %s/%s", lv->vg->name, lv->name);
737
2d6fcbf6 738 if (!lv_info(cmd, lv, 0, &info, 0, 0))
5f4b2acf 739 return_0;
b65b777d
AK
740
741 if (!info.exists)
742 return 0;
743
df390f17 744 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
5f4b2acf 745 return_0;
10b29b8d 746
8191fe4f 747 if (!(r = dev_manager_mirror_percent(dm, lv, wait, percent, event_nr)))
10b29b8d
AK
748 stack;
749
750 dev_manager_destroy(dm);
751
752 return r;
753}
754
4aebd52c
JEB
755int lv_raid_percent(const struct logical_volume *lv, percent_t *percent)
756{
757 return lv_mirror_percent(lv->vg->cmd, lv, 0, percent, NULL);
758}
759
34507894 760/*
63368983 761 * Returns data or metadata percent usage, depends on metadata 0/1.
34507894
ZK
762 * Returns 1 if percent set, else 0 on failure.
763 */
63368983
ZK
764int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
765 percent_t *percent)
34507894
ZK
766{
767 int r;
768 struct dev_manager *dm;
769
770 if (!activation())
771 return 0;
772
63368983
ZK
773 log_debug("Checking thin %sdata percent for LV %s/%s",
774 (metadata) ? "meta" : "", lv->vg->name, lv->name);
34507894
ZK
775
776 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
777 return_0;
778
63368983 779 if (!(r = dev_manager_thin_pool_percent(dm, lv, metadata, percent)))
34507894
ZK
780 stack;
781
782 dev_manager_destroy(dm);
783
784 return r;
785}
786
76ee0899
ZK
787/*
788 * Returns 1 if percent set, else 0 on failure.
789 */
790int lv_thin_percent(const struct logical_volume *lv,
791 int mapped, percent_t *percent)
792{
793 int r;
794 struct dev_manager *dm;
795
796 if (!activation())
797 return 0;
798
799 log_debug("Checking thin percent for LV %s/%s",
800 lv->vg->name, lv->name);
801
802 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
803 return_0;
804
805 if (!(r = dev_manager_thin_percent(dm, lv, mapped, percent)))
806 stack;
807
808 dev_manager_destroy(dm);
809
810 return r;
811}
812
bdba904d
ZK
813/*
814 * Returns 1 if transaction_id set, else 0 on failure.
815 */
816int lv_thin_pool_transaction_id(const struct logical_volume *lv,
817 uint64_t *transaction_id)
818{
819 int r;
820 struct dev_manager *dm;
821 struct dm_status_thin_pool *status;
822
823 if (!activation())
824 return 0;
825
826 log_debug("Checking thin percent for LV %s/%s",
827 lv->vg->name, lv->name);
828
829 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
830 return_0;
831
832 if (!(r = dev_manager_thin_pool_status(dm, lv, &status)))
833 stack;
834 else
835 *transaction_id = status->transaction_id;
836
837 dev_manager_destroy(dm);
838
839 return r;
840}
841
499a1616 842static int _lv_active(struct cmd_context *cmd, const struct logical_volume *lv)
2ba80b43 843{
199e490e 844 struct lvinfo info;
2ba80b43 845
2d6fcbf6 846 if (!lv_info(cmd, lv, 0, &info, 0, 0)) {
2ba80b43 847 stack;
de6c9183 848 return -1;
2ba80b43
JT
849 }
850
de6c9183 851 return info.exists;
2ba80b43
JT
852}
853
f894b4b1 854static int _lv_open_count(struct cmd_context *cmd, struct logical_volume *lv)
5986ec94 855{
199e490e 856 struct lvinfo info;
5986ec94 857
2d6fcbf6 858 if (!lv_info(cmd, lv, 0, &info, 1, 0)) {
5986ec94 859 stack;
de6c9183 860 return -1;
5986ec94
JT
861 }
862
de6c9183 863 return info.open_count;
5986ec94
JT
864}
865
81beded3 866static int _lv_activate_lv(struct logical_volume *lv, struct lv_activate_opts *laopts)
b1713d28 867{
6d52fb46 868 int r;
de6c9183 869 struct dev_manager *dm;
b1713d28 870
df390f17 871 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, (lv->status & PVMOVE) ? 0 : 1)))
5f4b2acf 872 return_0;
ae2bb665 873
81beded3 874 if (!(r = dev_manager_activate(dm, lv, laopts)))
6d52fb46 875 stack;
ae2bb665 876
de6c9183 877 dev_manager_destroy(dm);
ae2bb665 878 return r;
b1713d28 879}
a381c45a 880
81beded3
ZK
881static int _lv_preload(struct logical_volume *lv, struct lv_activate_opts *laopts,
882 int *flush_required)
0a5e4a14 883{
a18dcfb5 884 int r = 0;
de6c9183 885 struct dev_manager *dm;
a18dcfb5
AK
886 int old_readonly = laopts->read_only;
887
888 laopts->read_only = _passes_readonly_filter(lv->vg->cmd, lv);
37ed70b9 889
df390f17 890 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, (lv->status & PVMOVE) ? 0 : 1)))
a18dcfb5 891 goto_out;
5f4b2acf 892
81beded3 893 if (!(r = dev_manager_preload(dm, lv, laopts, flush_required)))
6d52fb46 894 stack;
5f4b2acf
AK
895
896 dev_manager_destroy(dm);
a18dcfb5
AK
897
898 laopts->read_only = old_readonly;
899out:
5f4b2acf
AK
900 return r;
901}
902
903static int _lv_deactivate(struct logical_volume *lv)
904{
905 int r;
906 struct dev_manager *dm;
907
df390f17 908 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
5f4b2acf 909 return_0;
37ed70b9 910
de6c9183 911 if (!(r = dev_manager_deactivate(dm, lv)))
37ed70b9 912 stack;
37ed70b9 913
de6c9183
JT
914 dev_manager_destroy(dm);
915 return r;
37ed70b9
JT
916}
917
81beded3
ZK
918static int _lv_suspend_lv(struct logical_volume *lv, struct lv_activate_opts *laopts,
919 int lockfs, int flush_required)
4a624ca0 920{
20c5fcf7
AK
921 int r;
922 struct dev_manager *dm;
c2d72fd4 923
a18dcfb5
AK
924 laopts->read_only = _passes_readonly_filter(lv->vg->cmd, lv);
925
df390f17
AK
926 /*
927 * When we are asked to manipulate (normally suspend/resume) the PVMOVE
928 * device directly, we don't want to touch the devices that use it.
929 */
930 if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, (lv->status & PVMOVE) ? 0 : 1)))
5f4b2acf 931 return_0;
0a5e4a14 932
81beded3 933 if (!(r = dev_manager_suspend(dm, lv, laopts, lockfs, flush_required)))
37ed70b9 934 stack;
0a5e4a14 935
20c5fcf7
AK
936 dev_manager_destroy(dm);
937 return r;
6d52fb46 938}
4a624ca0 939
8c013da4 940/*
f75c11ed 941 * These two functions return the number of visible LVs in the state,
7df72b3c 942 * or -1 on error. FIXME Check this.
8c013da4 943 */
499a1616 944int lvs_in_vg_activated(const struct volume_group *vg)
f047219b 945{
60f13f01 946 struct lv_list *lvl;
94b8220f 947 int count = 0;
37ed70b9 948
d1d9800e
AK
949 if (!activation())
950 return 0;
951
7df72b3c 952 dm_list_iterate_items(lvl, &vg->lvs)
59d8429c 953 if (lv_is_visible(lvl->lv))
ab9663f3 954 count += (_lv_active(vg->cmd, lvl->lv) == 1);
7df72b3c
AK
955
956 log_debug("Counted %d active LVs in VG %s", count, vg->name);
37ed70b9
JT
957
958 return count;
f047219b 959}
2ba80b43 960
08c9ff43 961int lvs_in_vg_opened(const struct volume_group *vg)
2ba80b43 962{
08c9ff43 963 const struct lv_list *lvl;
94b8220f 964 int count = 0;
2ba80b43 965
d1d9800e
AK
966 if (!activation())
967 return 0;
968
7df72b3c 969 dm_list_iterate_items(lvl, &vg->lvs)
87371d48 970 if (lv_is_visible(lvl->lv))
f894b4b1 971 count += (_lv_open_count(vg->cmd, lvl->lv) > 0);
7df72b3c
AK
972
973 log_debug("Counted %d open LVs in VG %s", count, vg->name);
2ba80b43
JT
974
975 return count;
976}
413cc918 977
5ca6698f 978/*
27ff8813
JEB
979 * _lv_is_active
980 * @lv: logical volume being queried
981 * @locally: set if active locally (when provided)
982 * @exclusive: set if active exclusively (when provided)
983 *
5ca6698f 984 * Determine whether an LV is active locally or in a cluster.
27ff8813
JEB
985 * In addition to the return code which indicates whether or
986 * not the LV is active somewhere, two other values are set
987 * to yield more information about the status of the activation:
988 * return locally exclusively status
989 * ====== ======= =========== ======
990 * 0 0 0 not active
991 * 1 0 0 active remotely
992 * 1 0 1 exclusive remotely
993 * 1 1 0 active locally and possibly remotely
994 * 1 1 1 exclusive locally (or local && !cluster)
995 * The VG lock must be held to call this function.
996 *
997 * Returns: 0 or 1
5ca6698f 998 */
499a1616 999static int _lv_is_active(const struct logical_volume *lv,
27ff8813 1000 int *locally, int *exclusive)
5ca6698f 1001{
27ff8813
JEB
1002 int r, l, e; /* remote, local, and exclusive */
1003
1004 r = l = e = 0;
6ac30c94 1005
ab9663f3 1006 if (_lv_active(lv->vg->cmd, lv))
27ff8813 1007 l = 1;
5ca6698f 1008
27ff8813 1009 if (!vg_is_clustered(lv->vg)) {
f5bfc8b1
AK
1010 if (l)
1011 e = 1; /* exclusive by definition */
27ff8813
JEB
1012 goto out;
1013 }
1014
1015 /* Active locally, and the caller doesn't care about exclusive */
1016 if (l && !exclusive)
1017 goto out;
5ca6698f 1018
27ff8813
JEB
1019 if ((r = remote_lock_held(lv->lvid.s, &e)) >= 0)
1020 goto out;
6ac30c94
MB
1021
1022 /*
27ff8813
JEB
1023 * If lock query is not supported (due to interfacing with old
1024 * code), then we cannot evaluate exclusivity properly.
1025 *
1026 * Old users of this function will never be affected by this,
1027 * since they are only concerned about active vs. not active.
1028 * New users of this function who specifically ask for 'exclusive'
1029 * will be given an error message.
6ac30c94 1030 */
f5bfc8b1
AK
1031 log_error("Unable to determine exclusivity of %s", lv->name);
1032
1033 e = 0;
1034
1035 /*
1036 * We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
1037 * but it's unreliable.
1038 */
27ff8813 1039
27ff8813
JEB
1040out:
1041 if (locally)
1042 *locally = l;
1043 if (exclusive)
1044 *exclusive = e;
1045
1046 log_very_verbose("%s/%s is %sactive%s%s",
1047 lv->vg->name, lv->name,
1048 (r || l) ? "" : "not ",
1049 (exclusive && e) ? " exclusive" : "",
1050 e ? (l ? " locally" : " remotely") : "");
1051
1052 return r || l;
1053}
1054
499a1616 1055int lv_is_active(const struct logical_volume *lv)
27ff8813
JEB
1056{
1057 return _lv_is_active(lv, NULL, NULL);
1058}
1059
499a1616 1060int lv_is_active_but_not_locally(const struct logical_volume *lv)
27ff8813
JEB
1061{
1062 int l;
9e277b9e 1063 return _lv_is_active(lv, &l, NULL) && !l;
27ff8813 1064}
27ff8813 1065
499a1616 1066int lv_is_active_exclusive(const struct logical_volume *lv)
b19f0121
JEB
1067{
1068 int e;
1069
1070 return _lv_is_active(lv, NULL, &e) && e;
1071}
1072
499a1616 1073int lv_is_active_exclusive_locally(const struct logical_volume *lv)
27ff8813
JEB
1074{
1075 int l, e;
7df72b3c 1076
27ff8813
JEB
1077 return _lv_is_active(lv, &l, &e) && l && e;
1078}
1079
499a1616 1080int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
27ff8813
JEB
1081{
1082 int l, e;
7df72b3c 1083
27ff8813 1084 return _lv_is_active(lv, &l, &e) && !l && e;
5ca6698f
DW
1085}
1086
d1e8046f
AK
1087#ifdef DMEVENTD
1088static struct dm_event_handler *_create_dm_event_handler(struct cmd_context *cmd, const char *dmuuid, const char *dso,
1089 const int timeout, enum dm_event_mask mask)
1090{
1091 struct dm_event_handler *dmevh;
1092
1093 if (!(dmevh = dm_event_handler_create()))
1094 return_NULL;
1095
1096 if (dm_event_handler_set_dmeventd_path(dmevh, find_config_tree_str(cmd, "dmeventd/executable", NULL)))
1097 goto_bad;
1098
1099 if (dm_event_handler_set_dso(dmevh, dso))
1100 goto_bad;
1101
1102 if (dm_event_handler_set_uuid(dmevh, dmuuid))
1103 goto_bad;
1104
1105 dm_event_handler_set_timeout(dmevh, timeout);
1106 dm_event_handler_set_event_mask(dmevh, mask);
1107
1108 return dmevh;
1109
1110bad:
1111 dm_event_handler_destroy(dmevh);
1112 return NULL;
1113}
1114
1115char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath)
1116{
1117 char *path;
1118
1119 if (!(path = dm_pool_alloc(cmd->mem, PATH_MAX))) {
1120 log_error("Failed to allocate dmeventd library path.");
1121 return NULL;
1122 }
1123
1124 get_shared_library_path(cmd, libpath, path, PATH_MAX);
1125
1126 return path;
1127}
1128
2bc1d759
ZK
1129static char *_build_target_uuid(struct cmd_context *cmd, struct logical_volume *lv)
1130{
1131 const char *layer;
1132
1133 if (lv_is_thin_pool(lv))
1134 layer = "tpool"; /* Monitor "tpool" for the "thin pool". */
1135 else if (lv_is_origin(lv))
1136 layer = "real"; /* Monitor "real" for "snapshot-origin". */
1137 else
1138 layer = NULL;
1139
1140 return build_dm_uuid(cmd->mem, lv->lvid.s, layer);
1141}
1142
f92b4f94
AK
1143int target_registered_with_dmeventd(struct cmd_context *cmd, const char *dso,
1144 struct logical_volume *lv, int *pending)
d1e8046f
AK
1145{
1146 char *uuid;
1147 enum dm_event_mask evmask = 0;
1148 struct dm_event_handler *dmevh;
d1e8046f
AK
1149 *pending = 0;
1150
1151 if (!dso)
1152 return_0;
1153
2bc1d759 1154 if (!(uuid = _build_target_uuid(cmd, lv)))
d1e8046f
AK
1155 return_0;
1156
1157 if (!(dmevh = _create_dm_event_handler(cmd, uuid, dso, 0, DM_EVENT_ALL_ERRORS)))
1158 return_0;
1159
1160 if (dm_event_get_registered_device(dmevh, 0)) {
1161 dm_event_handler_destroy(dmevh);
1162 return 0;
1163 }
1164
1165 evmask = dm_event_handler_get_event_mask(dmevh);
1166 if (evmask & DM_EVENT_REGISTRATION_PENDING) {
1167 *pending = 1;
1168 evmask &= ~DM_EVENT_REGISTRATION_PENDING;
1169 }
1170
1171 dm_event_handler_destroy(dmevh);
1172
1173 return evmask;
1174}
1175
f92b4f94 1176int target_register_events(struct cmd_context *cmd, const char *dso, struct logical_volume *lv,
d1e8046f
AK
1177 int evmask __attribute__((unused)), int set, int timeout)
1178{
1179 char *uuid;
1180 struct dm_event_handler *dmevh;
1181 int r;
1182
1183 if (!dso)
1184 return_0;
1185
f92b4f94 1186 /* We always monitor the "real" device, never the "snapshot-origin" itself. */
2bc1d759 1187 if (!(uuid = _build_target_uuid(cmd, lv)))
d1e8046f
AK
1188 return_0;
1189
1190 if (!(dmevh = _create_dm_event_handler(cmd, uuid, dso, timeout,
1191 DM_EVENT_ALL_ERRORS | (timeout ? DM_EVENT_TIMEOUT : 0))))
1192 return_0;
1193
1194 r = set ? dm_event_register_handler(dmevh) : dm_event_unregister_handler(dmevh);
1195
1196 dm_event_handler_destroy(dmevh);
1197
1198 if (!r)
1199 return_0;
1200
1201 log_info("%s %s for events", set ? "Monitored" : "Unmonitored", uuid);
1202
1203 return 1;
1204}
1205
1206#endif
1207
3e3d5d85 1208/*
8a37910d
AK
1209 * Returns 0 if an attempt to (un)monitor the device failed.
1210 * Returns 1 otherwise.
3e3d5d85 1211 */
2d6fcbf6 1212int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
81beded3 1213 const struct lv_activate_opts *laopts, int monitor)
15d91f5a 1214{
ed09d7e3 1215#ifdef DMEVENTD
8a37910d
AK
1216 int i, pending = 0, monitored;
1217 int r = 1;
2c44337b 1218 struct dm_list *tmp, *snh, *snht;
15d91f5a 1219 struct lv_segment *seg;
7a369d37 1220 struct lv_segment *log_seg;
24f4552b 1221 int (*monitor_fn) (struct lv_segment *s, int e);
4e9083db 1222 uint32_t s;
81beded3 1223 static const struct lv_activate_opts zlaopts = { 0 };
2caa558e
ZK
1224 static const struct lv_activate_opts thinopts = { .skip_in_use = 1 };
1225 struct lvinfo info;
81beded3
ZK
1226
1227 if (!laopts)
1228 laopts = &zlaopts;
15d91f5a 1229
20db8ffc
AK
1230 /* skip dmeventd code altogether */
1231 if (dmeventd_monitor_mode() == DMEVENTD_MONITOR_IGNORE)
1232 return 1;
1233
8a37910d
AK
1234 /*
1235 * Nothing to do if dmeventd configured not to be used.
1236 */
1237 if (monitor && !dmeventd_monitor_mode())
3e3d5d85
AK
1238 return 1;
1239
2caa558e
ZK
1240 /*
1241 * Allow to unmonitor thin pool via explicit pool unmonitor
1242 * or unmonitor before the last thin pool user deactivation
1243 * Skip unmonitor, if invoked via unmonitor of thin volume
1244 * and there is another thin pool user (open_count > 1)
1245 */
1246 if (laopts->skip_in_use && lv_info(lv->vg->cmd, lv, 1, &info, 1, 0) &&
1247 (info.open_count != 1)) {
1248 log_debug("Skipping unmonitor of opened %s (open:%d)",
1249 lv->name, info.open_count);
1250 return 1;
1251 }
1252
67961c7c
PR
1253 /*
1254 * In case of a snapshot device, we monitor lv->snapshot->lv,
1255 * not the actual LV itself.
1256 */
c6168a14
ZK
1257 if (lv_is_cow(lv) && (laopts->no_merging || !lv_is_merging_cow(lv)))
1258 return monitor_dev_for_events(cmd, lv->snapshot->lv, NULL, monitor);
67961c7c
PR
1259
1260 /*
1261 * In case this LV is a snapshot origin, we instead monitor
f92b4f94
AK
1262 * each of its respective snapshots. The origin itself may
1263 * also need to be monitored if it is a mirror, for example.
67961c7c 1264 */
81beded3 1265 if (!laopts->origin_only && lv_is_origin(lv))
2c44337b
AK
1266 dm_list_iterate_safe(snh, snht, &lv->snapshot_segs)
1267 if (!monitor_dev_for_events(cmd, dm_list_struct_base(snh,
81beded3 1268 struct lv_segment, origin_list)->cow, NULL, monitor))
0c06de63 1269 r = 0;
67961c7c 1270
7a369d37
JEB
1271 /*
1272 * If the volume is mirrored and its log is also mirrored, monitor
1273 * the log volume as well.
1274 */
1275 if ((seg = first_seg(lv)) != NULL && seg->log_lv != NULL &&
1276 (log_seg = first_seg(seg->log_lv)) != NULL &&
1277 seg_is_mirrored(log_seg))
81beded3 1278 if (!monitor_dev_for_events(cmd, seg->log_lv, NULL, monitor))
7a369d37
JEB
1279 r = 0;
1280
2c44337b
AK
1281 dm_list_iterate(tmp, &lv->segments) {
1282 seg = dm_list_item(tmp, struct lv_segment);
15d91f5a 1283
4e9083db
AK
1284 /* Recurse for AREA_LV */
1285 for (s = 0; s < seg->area_count; s++) {
1286 if (seg_type(seg, s) != AREA_LV)
1287 continue;
81beded3 1288 if (!monitor_dev_for_events(cmd, seg_lv(seg, s), NULL,
4e9083db
AK
1289 monitor)) {
1290 log_error("Failed to %smonitor %s",
1291 monitor ? "" : "un",
1292 seg_lv(seg, s)->name);
1293 r = 0;
1294 }
1295 }
1296
2caa558e
ZK
1297 /*
1298 * If requested unmonitoring of thin volume, request test
1299 * if there is no other thin pool user
1300 *
1301 * FIXME: code here looks like _lv_postorder()
1302 */
1303 if (seg->pool_lv &&
1304 !monitor_dev_for_events(cmd, seg->pool_lv,
1305 (!monitor) ? &thinopts : NULL, monitor))
1306 r = 0;
1307
1308 if (seg->metadata_lv &&
1309 !monitor_dev_for_events(cmd, seg->metadata_lv, NULL, monitor))
1310 r = 0;
1311
8ef6eb30
AK
1312 if (!seg_monitored(seg) || (seg->status & PVMOVE))
1313 continue;
8a37910d
AK
1314
1315 monitor_fn = NULL;
ed09d7e3 1316
8ef6eb30 1317 /* Check monitoring status */
8a37910d
AK
1318 if (seg->segtype->ops->target_monitored)
1319 monitored = seg->segtype->ops->target_monitored(seg, &pending);
8ef6eb30
AK
1320 else
1321 continue; /* segtype doesn't support registration */
1322
1323 /*
1324 * FIXME: We should really try again if pending
1325 */
8a37910d 1326 monitored = (pending) ? 0 : monitored;
8ef6eb30 1327
8a37910d
AK
1328 if (monitor) {
1329 if (monitored)
8ef6eb30 1330 log_verbose("%s/%s already monitored.", lv->vg->name, lv->name);
8a37910d
AK
1331 else if (seg->segtype->ops->target_monitor_events)
1332 monitor_fn = seg->segtype->ops->target_monitor_events;
8ef6eb30 1333 } else {
8a37910d 1334 if (!monitored)
8ef6eb30 1335 log_verbose("%s/%s already not monitored.", lv->vg->name, lv->name);
8a37910d
AK
1336 else if (seg->segtype->ops->target_unmonitor_events)
1337 monitor_fn = seg->segtype->ops->target_unmonitor_events;
8ef6eb30 1338 }
15d91f5a 1339
8ef6eb30 1340 /* Do [un]monitor */
8a37910d 1341 if (!monitor_fn)
3e3d5d85 1342 continue;
e24e7130 1343
85a80e05
AK
1344 log_verbose("%sonitoring %s/%s%s", monitor ? "M" : "Not m", lv->vg->name, lv->name,
1345 test_mode() ? " [Test mode: skipping this]" : "");
1346
1347 /* FIXME Test mode should really continue a bit further. */
1348 if (test_mode())
1349 continue;
8a37910d 1350
3e3d5d85 1351 /* FIXME specify events */
57fc4cc0 1352 if (!monitor_fn(seg, 0)) {
8a37910d
AK
1353 log_error("%s/%s: %s segment monitoring function failed.",
1354 lv->vg->name, lv->name, seg->segtype->name);
1355 return 0;
e24e7130 1356 }
3e3d5d85 1357
8ef6eb30
AK
1358 /* Check [un]monitor results */
1359 /* Try a couple times if pending, but not forever... */
1360 for (i = 0; i < 10; i++) {
1361 pending = 0;
8a37910d 1362 monitored = seg->segtype->ops->target_monitored(seg, &pending);
8ef6eb30 1363 if (pending ||
8a37910d
AK
1364 (!monitored && monitor) ||
1365 (monitored && !monitor))
1366 log_very_verbose("%s/%s %smonitoring still pending: waiting...",
1367 lv->vg->name, lv->name, monitor ? "" : "un");
8ef6eb30
AK
1368 else
1369 break;
1370 sleep(1);
1371 }
1372
85a80e05
AK
1373 if (r)
1374 r = (monitored && monitor) || (!monitored && !monitor);
15d91f5a 1375 }
e6493477 1376
3e3d5d85
AK
1377 return r;
1378#else
15d91f5a 1379 return 1;
3e3d5d85 1380#endif
15d91f5a 1381}
15d91f5a 1382
0f2a4ca2
AK
1383struct detached_lv_data {
1384 struct logical_volume *lv_pre;
1385 struct lv_activate_opts *laopts;
1386 int *flush_required;
1387};
1388
1389static int _preload_detached_lv(struct cmd_context *cmd, struct logical_volume *lv, void *data)
1390{
1391 struct detached_lv_data *detached = data;
1392 struct lv_list *lvl_pre;
1393
1394 if ((lvl_pre = find_lv_in_vg(detached->lv_pre->vg, lv->name))) {
ee840ff1 1395 if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) && (!lv_is_cow(lv) || !lv_is_cow(lvl_pre->lv)) &&
0f2a4ca2
AK
1396 !_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
1397 return_0;
1398 }
1399
1400 return 1;
1401}
1402
658b5812 1403static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
81beded3 1404 struct lv_activate_opts *laopts, int error_if_not_suspended)
413cc918 1405{
df390f17
AK
1406 struct logical_volume *lv = NULL, *lv_pre = NULL, *pvmove_lv = NULL;
1407 struct lv_list *lvl_pre;
1408 struct seg_list *sl;
ee840ff1 1409 struct lv_segment *snap_seg;
199e490e 1410 struct lvinfo info;
eb91c4ee 1411 int r = 0, lockfs = 0, flush_required = 0;
0f2a4ca2 1412 struct detached_lv_data detached;
413cc918 1413
d1d9800e
AK
1414 if (!activation())
1415 return 1;
1416
8b888354 1417 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
095bbca6 1418 goto_out;
8b888354 1419
7a593325 1420 /* Use precommitted metadata if present */
8b888354 1421 if (!(lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
095bbca6 1422 goto_out;
413cc918 1423
2d6fcbf6 1424 /* Ignore origin_only unless LV is origin in both old and new metadata */
efc8ca10 1425 if (!lv_is_thin_volume(lv) && !(lv_is_origin(lv) && lv_is_origin(lv_pre)))
81beded3 1426 laopts->origin_only = 0;
2d6fcbf6 1427
20c5fcf7 1428 if (test_mode()) {
81beded3 1429 _skip("Suspending %s%s.", lv->name, laopts->origin_only ? " origin without snapshots" : "");
095bbca6
MB
1430 r = 1;
1431 goto out;
20c5fcf7
AK
1432 }
1433
81beded3 1434 if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
095bbca6 1435 goto_out;
41967a02 1436
095bbca6 1437 if (!info.exists || info.suspended) {
63ae0d14
MB
1438 if (!error_if_not_suspended) {
1439 r = 1;
1440 if (info.suspended)
df390f17 1441 critical_section_inc(cmd, "already suspended");
63ae0d14 1442 }
095bbca6
MB
1443 goto out;
1444 }
914c9723 1445
9249fb12
ZK
1446 if (!lv_read_replicator_vgs(lv))
1447 goto_out;
1448
c1fdeec9
MB
1449 lv_calculate_readahead(lv, NULL);
1450
df390f17 1451 /*
3a8eb387 1452 * Preload devices for the LV.
df390f17
AK
1453 * If the PVMOVE LV is being removed, it's only present in the old
1454 * metadata and not the new, so we must explicitly add the new
1455 * tables for all the changed LVs here, as the relationships
1456 * are not found by walking the new metadata.
1457 */
3a8eb387
AK
1458 if (!(lv_pre->status & LOCKED) &&
1459 (lv->status & LOCKED) &&
1460 (pvmove_lv = find_pvmove_lv_in_lv(lv))) {
1461 /* Preload all the LVs above the PVMOVE LV */
1462 dm_list_iterate_items(sl, &pvmove_lv->segs_using_this_lv) {
1463 if (!(lvl_pre = find_lv_in_vg(lv_pre->vg, sl->seg->lv->name))) {
ee840ff1 1464 log_error(INTERNAL_ERROR "LV %s missing from preload metadata", sl->seg->lv->name);
df390f17
AK
1465 goto out;
1466 }
81beded3 1467 if (!_lv_preload(lvl_pre->lv, laopts, &flush_required))
df390f17 1468 goto_out;
3a8eb387
AK
1469 }
1470 /* Now preload the PVMOVE LV itself */
1471 if (!(lvl_pre = find_lv_in_vg(lv_pre->vg, pvmove_lv->name))) {
ee840ff1 1472 log_error(INTERNAL_ERROR "LV %s missing from preload metadata", pvmove_lv->name);
3a8eb387
AK
1473 goto out;
1474 }
1475 if (!_lv_preload(lvl_pre->lv, laopts, &flush_required))
1476 goto_out;
1477 } else {
1478 if (!_lv_preload(lv_pre, laopts, &flush_required))
1479 /* FIXME Revert preloading */
1480 goto_out;
0f2a4ca2 1481
3a8eb387
AK
1482 /*
1483 * Search for existing LVs that have become detached and preload them.
1484 */
1485 detached.lv_pre = lv_pre;
1486 detached.laopts = laopts;
1487 detached.flush_required = &flush_required;
0f2a4ca2 1488
3a8eb387
AK
1489 if (!for_each_sub_lv(cmd, lv, &_preload_detached_lv, &detached))
1490 goto_out;
ee840ff1
AK
1491
1492 /*
1493 * Preload any snapshots that are being removed.
1494 */
1495 if (!laopts->origin_only && lv_is_origin(lv)) {
1496 dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs, origin_list) {
a73e9a6c
AK
1497 if (!(lvl_pre = find_lv_in_vg_by_lvid(lv_pre->vg, &snap_seg->cow->lvid))) {
1498 log_error(INTERNAL_ERROR "LV %s (%s) missing from preload metadata",
1499 snap_seg->cow->name, snap_seg->cow->lvid.id[1].uuid);
ee840ff1
AK
1500 goto out;
1501 }
1502 if (!lv_is_cow(lvl_pre->lv) &&
1503 !_lv_preload(lvl_pre->lv, laopts, &flush_required))
1504 goto_out;
1505 }
1506 }
5f4b2acf
AK
1507 }
1508
81beded3 1509 if (!monitor_dev_for_events(cmd, lv, laopts, 0))
e24e7130 1510 /* FIXME Consider aborting here */
ed09d7e3
AK
1511 stack;
1512
df390f17
AK
1513 critical_section_inc(cmd, "suspending");
1514 if (pvmove_lv)
1515 critical_section_inc(cmd, "suspending pvmove LV");
9cd3426d 1516
81beded3 1517 if (!laopts->origin_only &&
2d6fcbf6 1518 (lv_is_origin(lv_pre) || lv_is_cow(lv_pre)))
9cd3426d
AK
1519 lockfs = 1;
1520
2f99e5e3
ZK
1521 if (laopts->origin_only && lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
1522 lockfs = 1;
1523
df390f17
AK
1524 /*
1525 * Suspending an LV directly above a PVMOVE LV also
1526 * suspends other LVs using that same PVMOVE LV.
1527 * FIXME Remove this and delay the 'clear node' until
1528 * after the code knows whether there's a different
1529 * inactive table to load or not instead so lv_suspend
1530 * can be called separately for each LV safely.
1531 */
1532 if ((lv_pre->vg->status & PRECOMMITTED) &&
1533 (lv_pre->status & LOCKED) && find_pvmove_lv_in_lv(lv_pre)) {
81beded3 1534 if (!_lv_suspend_lv(lv_pre, laopts, lockfs, flush_required)) {
df390f17
AK
1535 critical_section_dec(cmd, "failed precommitted suspend");
1536 if (pvmove_lv)
1537 critical_section_dec(cmd, "failed precommitted suspend (pvmove)");
1538 goto_out;
1539 }
1540 } else {
1541 /* Normal suspend */
81beded3 1542 if (!_lv_suspend_lv(lv, laopts, lockfs, flush_required)) {
df390f17
AK
1543 critical_section_dec(cmd, "failed suspend");
1544 if (pvmove_lv)
1545 critical_section_dec(cmd, "failed suspend (pvmove)");
1546 goto_out;
1547 }
914c9723 1548 }
8c013da4 1549
095bbca6
MB
1550 r = 1;
1551out:
1552 if (lv_pre)
077a6755 1553 release_vg(lv_pre->vg);
9249fb12
ZK
1554 if (lv) {
1555 lv_release_replicator_vgs(lv);
077a6755 1556 release_vg(lv->vg);
9249fb12 1557 }
095bbca6
MB
1558
1559 return r;
413cc918
AK
1560}
1561
fd7d09e3
AK
1562/*
1563 * In a cluster, set exclusive to indicate that only one node is using the
1564 * device. Any preloaded tables may then use non-clustered targets.
1565 *
1566 * Returns success if the device is not active
1567 */
25d14105 1568int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive)
658b5812 1569{
25d14105
JEB
1570 struct lv_activate_opts laopts = {
1571 .origin_only = origin_only,
1572 .exclusive = exclusive
1573 };
81beded3
ZK
1574
1575 return _lv_suspend(cmd, lvid_s, &laopts, 0);
658b5812
AK
1576}
1577
2d6fcbf6
AK
1578/* No longer used */
1579/***********
658b5812
AK
1580int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
1581{
1582 return _lv_suspend(cmd, lvid_s, 1);
1583}
2d6fcbf6 1584***********/
658b5812
AK
1585
1586static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
81beded3 1587 struct lv_activate_opts *laopts, int error_if_not_active)
413cc918
AK
1588{
1589 struct logical_volume *lv;
199e490e 1590 struct lvinfo info;
095bbca6 1591 int r = 0;
2258242f 1592 int messages_only = 0;
413cc918 1593
d1d9800e
AK
1594 if (!activation())
1595 return 1;
1596
7a593325 1597 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
75b37a11 1598 goto_out;
413cc918 1599
2258242f
ZK
1600 if (lv_is_thin_pool(lv) && laopts->origin_only)
1601 messages_only = 1;
1602
2f99e5e3 1603 if (!lv_is_origin(lv) && !lv_is_thin_volume(lv))
81beded3 1604 laopts->origin_only = 0;
2d6fcbf6 1605
20c5fcf7 1606 if (test_mode()) {
10d0d9c7
AK
1607 _skip("Resuming %s%s%s.", lv->name, laopts->origin_only ? " without snapshots" : "",
1608 laopts->revert ? " (reverting)" : "");
095bbca6
MB
1609 r = 1;
1610 goto out;
20c5fcf7
AK
1611 }
1612
10d0d9c7 1613 log_debug("Resuming LV %s/%s%s%s%s.", lv->vg->name, lv->name,
7df72b3c 1614 error_if_not_active ? "" : " if active",
10d0d9c7
AK
1615 laopts->origin_only ? " without snapshots" : "",
1616 laopts->revert ? " (reverting)" : "");
7df72b3c 1617
81beded3 1618 if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
095bbca6 1619 goto_out;
41967a02 1620
2258242f 1621 if (!info.exists || !(info.suspended || messages_only)) {
4ec2ae86
ZK
1622 if (error_if_not_active)
1623 goto_out;
1624 r = 1;
df390f17
AK
1625 if (!info.suspended)
1626 critical_section_dec(cmd, "already resumed");
4ec2ae86 1627 goto out;
095bbca6 1628 }
914c9723 1629
a18dcfb5
AK
1630 laopts->read_only = _passes_readonly_filter(cmd, lv);
1631
81beded3 1632 if (!_lv_activate_lv(lv, laopts))
75b37a11 1633 goto_out;
914c9723 1634
df390f17 1635 critical_section_dec(cmd, "resumed");
413cc918 1636
81beded3 1637 if (!monitor_dev_for_events(cmd, lv, laopts, 1))
ed09d7e3 1638 stack;
15d91f5a 1639
095bbca6
MB
1640 r = 1;
1641out:
1642 if (lv)
077a6755 1643 release_vg(lv->vg);
095bbca6
MB
1644
1645 return r;
413cc918
AK
1646}
1647
fd7d09e3
AK
1648/*
1649 * In a cluster, set exclusive to indicate that only one node is using the
1650 * device. Any tables loaded may then use non-clustered targets.
1651 *
5c8b1486
ZK
1652 * @origin_only
1653 * @exclusive This parameter only has an affect in cluster-context.
1654 * It forces local target type to be used (instead of
1655 * cluster-aware type).
fd7d09e3
AK
1656 * Returns success if the device is not active
1657 */
c054e7cc 1658int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
fd7d09e3
AK
1659 unsigned origin_only, unsigned exclusive,
1660 unsigned revert)
658b5812 1661{
81beded3
ZK
1662 struct lv_activate_opts laopts = {
1663 .origin_only = origin_only,
10d0d9c7
AK
1664 .exclusive = exclusive,
1665 .revert = revert
81beded3
ZK
1666 };
1667
1668 return _lv_resume(cmd, lvid_s, &laopts, 0);
658b5812
AK
1669}
1670
2d6fcbf6 1671int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only)
658b5812 1672{
81beded3
ZK
1673 struct lv_activate_opts laopts = { .origin_only = origin_only, };
1674
1675 return _lv_resume(cmd, lvid_s, &laopts, 1);
658b5812
AK
1676}
1677
64a95010
AK
1678static int _lv_has_open_snapshots(struct logical_volume *lv)
1679{
1680 struct lv_segment *snap_seg;
1681 struct lvinfo info;
1682 int r = 0;
1683
1684 dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs, origin_list) {
2d6fcbf6 1685 if (!lv_info(lv->vg->cmd, snap_seg->cow, 0, &info, 1, 0)) {
64a95010
AK
1686 r = 1;
1687 continue;
1688 }
1689
1690 if (info.exists && info.open_count) {
1691 log_error("LV %s/%s has open snapshot %s: "
1692 "not deactivating", lv->vg->name, lv->name,
1693 snap_seg->cow->name);
1694 r = 1;
1695 }
1696 }
1697
1698 return r;
1699}
1700
be326a2f 1701int lv_deactivate(struct cmd_context *cmd, const char *lvid_s)
f4cbeaf0
AK
1702{
1703 struct logical_volume *lv;
199e490e 1704 struct lvinfo info;
095bbca6 1705 int r = 0;
f4cbeaf0 1706
d1d9800e
AK
1707 if (!activation())
1708 return 1;
1709
7a593325 1710 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
095bbca6 1711 goto out;
f4cbeaf0 1712
20c5fcf7
AK
1713 if (test_mode()) {
1714 _skip("Deactivating '%s'.", lv->name);
095bbca6
MB
1715 r = 1;
1716 goto out;
20c5fcf7
AK
1717 }
1718
7df72b3c
AK
1719 log_debug("Deactivating %s/%s.", lv->vg->name, lv->name);
1720
2d6fcbf6 1721 if (!lv_info(cmd, lv, 0, &info, 1, 0))
095bbca6 1722 goto_out;
41967a02 1723
095bbca6
MB
1724 if (!info.exists) {
1725 r = 1;
1726 goto out;
1727 }
f4cbeaf0 1728
64a95010 1729 if (lv_is_visible(lv)) {
125712be
PR
1730 if (!lv_check_not_in_use(cmd, lv, &info))
1731 goto_out;
1732
64a95010
AK
1733 if (lv_is_origin(lv) && _lv_has_open_snapshots(lv))
1734 goto_out;
0cf96f33
AK
1735 }
1736
9249fb12
ZK
1737 if (!lv_read_replicator_vgs(lv))
1738 goto_out;
1739
c1fdeec9
MB
1740 lv_calculate_readahead(lv, NULL);
1741
81beded3 1742 if (!monitor_dev_for_events(cmd, lv, NULL, 0))
ed09d7e3 1743 stack;
15d91f5a 1744
df390f17 1745 critical_section_inc(cmd, "deactivating");
914c9723 1746 r = _lv_deactivate(lv);
df390f17 1747 critical_section_dec(cmd, "deactivated");
914c9723 1748
401a40d9 1749 if (!lv_info(cmd, lv, 0, &info, 0, 0) || info.exists)
89a6cdfd 1750 r = 0;
095bbca6 1751out:
9249fb12
ZK
1752 if (lv) {
1753 lv_release_replicator_vgs(lv);
077a6755 1754 release_vg(lv->vg);
9249fb12 1755 }
095bbca6 1756
914c9723 1757 return r;
f4cbeaf0
AK
1758}
1759
658b5812
AK
1760/* Test if LV passes filter */
1761int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
1762 int *activate_lv)
1763{
1764 struct logical_volume *lv;
095bbca6 1765 int r = 0;
658b5812 1766
095bbca6
MB
1767 if (!activation()) {
1768 *activate_lv = 1;
1769 return 1;
1770 }
658b5812 1771
424dd43e 1772 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
095bbca6 1773 goto out;
658b5812
AK
1774
1775 if (!_passes_activation_filter(cmd, lv)) {
f7e3a19f
PR
1776 log_verbose("Not activating %s/%s since it does not pass "
1777 "activation filter.", lv->vg->name, lv->name);
658b5812 1778 *activate_lv = 0;
095bbca6
MB
1779 } else
1780 *activate_lv = 1;
1781 r = 1;
1782out:
1783 if (lv)
077a6755 1784 release_vg(lv->vg);
658b5812 1785
095bbca6 1786 return r;
658b5812
AK
1787}
1788
07d31831 1789static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
81beded3 1790 struct lv_activate_opts *laopts, int filter)
f4cbeaf0
AK
1791{
1792 struct logical_volume *lv;
199e490e 1793 struct lvinfo info;
095bbca6 1794 int r = 0;
f4cbeaf0 1795
d1d9800e
AK
1796 if (!activation())
1797 return 1;
1798
424dd43e 1799 if (!(lv = lv_from_lvid(cmd, lvid_s, 0)))
095bbca6 1800 goto out;
f4cbeaf0 1801
658b5812 1802 if (filter && !_passes_activation_filter(cmd, lv)) {
f7e3a19f
PR
1803 log_error("Not activating %s/%s since it does not pass "
1804 "activation filter.", lv->vg->name, lv->name);
095bbca6 1805 goto out;
de17d760
AK
1806 }
1807
cda35408 1808 if ((!lv->vg->cmd->partial_activation) && (lv->status & PARTIAL_LV)) {
8c5bcdab
AK
1809 log_error("Refusing activation of partial LV %s. Use --partial to override.",
1810 lv->name);
095bbca6 1811 goto_out;
8c5bcdab
AK
1812 }
1813
b4048242
PR
1814 if (lv_has_unknown_segments(lv)) {
1815 log_error("Refusing activation of LV %s containing "
1816 "an unrecognised segment.", lv->name);
1817 goto_out;
1818 }
1819
20c5fcf7
AK
1820 if (test_mode()) {
1821 _skip("Activating '%s'.", lv->name);
095bbca6
MB
1822 r = 1;
1823 goto out;
20c5fcf7
AK
1824 }
1825
a18dcfb5
AK
1826 if (filter)
1827 laopts->read_only = _passes_readonly_filter(cmd, lv);
1828
1829 log_debug("Activating %s/%s%s%s.", lv->vg->name, lv->name,
1830 laopts->exclusive ? " exclusively" : "",
1831 laopts->read_only ? " read-only" : "");
7df72b3c 1832
2d6fcbf6 1833 if (!lv_info(cmd, lv, 0, &info, 0, 0))
095bbca6 1834 goto_out;
8c013da4 1835
a18dcfb5
AK
1836 /*
1837 * Nothing to do?
1838 */
1839 if (info.exists && !info.suspended && info.live_table &&
1840 (info.read_only == read_only_lv(lv, laopts))) {
095bbca6
MB
1841 r = 1;
1842 goto out;
1843 }
f4cbeaf0 1844
9249fb12
ZK
1845 if (!lv_read_replicator_vgs(lv))
1846 goto_out;
1847
c1fdeec9
MB
1848 lv_calculate_readahead(lv, NULL);
1849
df390f17 1850 critical_section_inc(cmd, "activating");
81beded3 1851 if (!(r = _lv_activate_lv(lv, laopts)))
75b37a11 1852 stack;
df390f17 1853 critical_section_dec(cmd, "activated");
914c9723 1854
81beded3 1855 if (r && !monitor_dev_for_events(cmd, lv, laopts, 1))
ed09d7e3 1856 stack;
15d91f5a 1857
095bbca6 1858out:
9249fb12
ZK
1859 if (lv) {
1860 lv_release_replicator_vgs(lv);
077a6755 1861 release_vg(lv->vg);
9249fb12 1862 }
095bbca6 1863
914c9723 1864 return r;
f4cbeaf0 1865}
199e490e 1866
658b5812 1867/* Activate LV */
07d31831 1868int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812 1869{
81beded3
ZK
1870 struct lv_activate_opts laopts = { .exclusive = exclusive };
1871
1872 if (!_lv_activate(cmd, lvid_s, &laopts, 0))
75b37a11
AK
1873 return_0;
1874
1875 return 1;
658b5812
AK
1876}
1877
1878/* Activate LV only if it passes filter */
07d31831 1879int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive)
658b5812 1880{
81beded3
ZK
1881 struct lv_activate_opts laopts = { .exclusive = exclusive };
1882
1883 if (!_lv_activate(cmd, lvid_s, &laopts, 1))
75b37a11
AK
1884 return_0;
1885
1886 return 1;
658b5812
AK
1887}
1888
f7dd6d84
AK
1889int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv)
1890{
f7dd6d84
AK
1891 int r = 1;
1892
8b076648 1893 if (!lv) {
2262b320 1894 r = dm_mknodes(NULL);
8b076648
AK
1895 fs_unlock();
1896 return r;
1897 }
1898
ab9663f3
MB
1899 if (!activation())
1900 return 1;
f7dd6d84 1901
ab9663f3 1902 r = dev_manager_mknodes(lv);
f7dd6d84
AK
1903
1904 fs_unlock();
1905
1906 return r;
1907}
1908
352a99b9
AK
1909/*
1910 * Does PV use VG somewhere in its construction?
1911 * Returns 1 on failure.
1912 */
898e6f8e 1913int pv_uses_vg(struct physical_volume *pv,
3e3d5d85 1914 struct volume_group *vg)
352a99b9 1915{
dae08226 1916 if (!activation() || !pv->dev)
352a99b9
AK
1917 return 0;
1918
1919 if (!dm_is_dm_major(MAJOR(pv->dev->dev)))
1920 return 0;
1921
898e6f8e 1922 return dev_manager_device_uses_vg(pv->dev, vg);
352a99b9
AK
1923}
1924
2293567c
AK
1925void activation_release(void)
1926{
1927 dev_manager_release();
1928}
1929
914c9723
AK
1930void activation_exit(void)
1931{
1932 dev_manager_exit();
1933}
199e490e 1934#endif
This page took 0.359482 seconds and 5 git commands to generate.