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