mirror of
git://sourceware.org/git/lvm2.git
synced 2025-12-28 04:23:49 +03:00
Compare commits
314 Commits
dev-mcsont
...
v2_02_141
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d05d7d974c | ||
|
|
bc8f8ac0fa | ||
|
|
136fd8f2f6 | ||
|
|
c0912af310 | ||
|
|
1f5dfb7369 | ||
|
|
d090d6574e | ||
|
|
dc388e0c7a | ||
|
|
55056c2d16 | ||
|
|
22810155a6 | ||
|
|
347575df1d | ||
|
|
c701d9cc8c | ||
|
|
fcbef05aae | ||
|
|
cc53a23d82 | ||
|
|
3e09f916b4 | ||
|
|
640c45d5a4 | ||
|
|
43b436398e | ||
|
|
21028a7903 | ||
|
|
7b5a8f61a7 | ||
|
|
b64703401d | ||
|
|
ca878a3426 | ||
|
|
178cbb580a | ||
|
|
4b9ae55a8d | ||
|
|
c99ca6f430 | ||
|
|
2da7525c83 | ||
|
|
509410bbbc | ||
|
|
2304286f68 | ||
|
|
c812c2dbc7 | ||
|
|
7f6a1e6bba | ||
|
|
2a4ef78c4a | ||
|
|
acf1e84e8c | ||
|
|
1341f83554 | ||
|
|
fccb1bb276 | ||
|
|
b160b73800 | ||
|
|
2ed324648e | ||
|
|
48f270970f | ||
|
|
6b3e402298 | ||
|
|
a3f484f812 | ||
|
|
6d7dc87cb3 | ||
|
|
5cd4d46f30 | ||
|
|
06346eab84 | ||
|
|
95ead96004 | ||
|
|
54b41dcd53 | ||
|
|
1ee6af344b | ||
|
|
7f62777041 | ||
|
|
0faa27d4f5 | ||
|
|
7559af2334 | ||
|
|
1752f5c31e | ||
|
|
e710bac03d | ||
|
|
b82d5ee092 | ||
|
|
6d09c8c2c4 | ||
|
|
88400b599e | ||
|
|
278c5509ee | ||
|
|
c9a813bff8 | ||
|
|
7d2b7f2bd8 | ||
|
|
2567d03e95 | ||
|
|
4310dfd4e1 | ||
|
|
ebcfd09ba9 | ||
|
|
753a496348 | ||
|
|
8857b22764 | ||
|
|
43897239b3 | ||
|
|
526297296f | ||
|
|
01228b692b | ||
|
|
9e9c757541 | ||
|
|
1b1f42b490 | ||
|
|
be1b1f3d89 | ||
|
|
63d59254d9 | ||
|
|
04d1a8a5e4 | ||
|
|
939d296525 | ||
|
|
9a81881965 | ||
|
|
1417ed304b | ||
|
|
d2d5c5e6c9 | ||
|
|
efab21b411 | ||
|
|
c66a83fdc3 | ||
|
|
84a9f750fe | ||
|
|
293abbb8d2 | ||
|
|
53b355a24b | ||
|
|
e168b5de75 | ||
|
|
7f74a99502 | ||
|
|
f1fe7af014 | ||
|
|
42fcbc1fd4 | ||
|
|
cdbf76b2f0 | ||
|
|
d50cd9d8d7 | ||
|
|
aae45a1f21 | ||
|
|
1bd83814ce | ||
|
|
9e336582f4 | ||
|
|
0c6946b4ce | ||
|
|
176b4aaebe | ||
|
|
1a3ee6402e | ||
|
|
d1e30ff0ba | ||
|
|
d09246a07d | ||
|
|
40701af969 | ||
|
|
d6cf83968c | ||
|
|
f03a21f5b8 | ||
|
|
a83d611a86 | ||
|
|
0dac4f09b4 | ||
|
|
04b82a8126 | ||
|
|
580c67486f | ||
|
|
8d11468ab2 | ||
|
|
4304a95dfd | ||
|
|
124b490fe6 | ||
|
|
796461a912 | ||
|
|
37bd35bc3d | ||
|
|
92e1422707 | ||
|
|
1be56e46c4 | ||
|
|
3e8126a66a | ||
|
|
4aa9e99a10 | ||
|
|
3e48354f2d | ||
|
|
07b9147ced | ||
|
|
7a4badc07f | ||
|
|
0688dbbc53 | ||
|
|
cd8e95d933 | ||
|
|
bf4b74c5eb | ||
|
|
dcb26b5f13 | ||
|
|
bdba4e7a93 | ||
|
|
dcd946e95a | ||
|
|
94dab390ef | ||
|
|
00bab9d9cd | ||
|
|
063b353b28 | ||
|
|
fedf15ffb0 | ||
|
|
748b8158b5 | ||
|
|
8b16efd17c | ||
|
|
45781161f4 | ||
|
|
c24d913c47 | ||
|
|
89418c1253 | ||
|
|
d2524315e6 | ||
|
|
e7978c5ab6 | ||
|
|
f40b3ba1e9 | ||
|
|
20acc66a23 | ||
|
|
20483ead5b | ||
|
|
c15c44a492 | ||
|
|
aec58c8620 | ||
|
|
3bbf89e9ec | ||
|
|
61573bd197 | ||
|
|
166adf0e1f | ||
|
|
67763a9bec | ||
|
|
5bbbd37f41 | ||
|
|
f7571eb287 | ||
|
|
ea74215fa1 | ||
|
|
3bcdf5d14b | ||
|
|
88cef47b18 | ||
|
|
1e43ec15ce | ||
|
|
aa4932674a | ||
|
|
4ff2583dc5 | ||
|
|
68e2ea11a3 | ||
|
|
86e7894ecc | ||
|
|
6336ef98d4 | ||
|
|
c717ea5fc0 | ||
|
|
fa87979004 | ||
|
|
46c8d6bb8a | ||
|
|
eb22f7c8f7 | ||
|
|
05ac836798 | ||
|
|
d3ca18e489 | ||
|
|
1f357532bb | ||
|
|
cd4d2cff97 | ||
|
|
b4a3aaf910 | ||
|
|
1fb8d746d6 | ||
|
|
ec647f1d43 | ||
|
|
4afe43e1a3 | ||
|
|
922fccc656 | ||
|
|
b7b59ad932 | ||
|
|
528695ec20 | ||
|
|
d582be43d4 | ||
|
|
1ea8afd3ca | ||
|
|
66c7fa4a44 | ||
|
|
4312b09635 | ||
|
|
d9faf85987 | ||
|
|
0285066e10 | ||
|
|
8d86c5db03 | ||
|
|
a220939d9e | ||
|
|
9243877ea1 | ||
|
|
5e50e5f0b4 | ||
|
|
6d6c233768 | ||
|
|
94c9453659 | ||
|
|
15be97d76b | ||
|
|
6ca5447e0c | ||
|
|
ddbf0075b1 | ||
|
|
fe64d3a2e2 | ||
|
|
c026846739 | ||
|
|
369bc264b0 | ||
|
|
da50f8bee6 | ||
|
|
795616a87b | ||
|
|
d1608345df | ||
|
|
6f002c29a5 | ||
|
|
2a23550cf3 | ||
|
|
0614c63579 | ||
|
|
0b2be60497 | ||
|
|
e2b00b0a89 | ||
|
|
0a2cadf6b8 | ||
|
|
7b11ef6de0 | ||
|
|
6167f5da10 | ||
|
|
83661c8f7f | ||
|
|
6e71d3fbde | ||
|
|
d8049dd17a | ||
|
|
011dd82050 | ||
|
|
121341e52c | ||
|
|
cad3568def | ||
|
|
51dfba002b | ||
|
|
931fede81b | ||
|
|
4d37db123d | ||
|
|
485d2ca945 | ||
|
|
d42cedae58 | ||
|
|
7d1c9e1d5a | ||
|
|
68c386cce7 | ||
|
|
4a984cabc4 | ||
|
|
920a281994 | ||
|
|
b6a45963e3 | ||
|
|
2a2487f02f | ||
|
|
5d4f5873a9 | ||
|
|
8ebf2b0611 | ||
|
|
0f4d96f1bd | ||
|
|
dccbc3b621 | ||
|
|
5a4676fea9 | ||
|
|
c3b292a4a9 | ||
|
|
193e7f5973 | ||
|
|
96d73dc6ea | ||
|
|
d4288c9bdf | ||
|
|
422c7474ca | ||
|
|
dd9a05b5ae | ||
|
|
376892ddf8 | ||
|
|
e31f4b76f4 | ||
|
|
d9295410e9 | ||
|
|
e425bce281 | ||
|
|
46193f4a59 | ||
|
|
970a428909 | ||
|
|
b2e13ac552 | ||
|
|
3089f5ab15 | ||
|
|
8d258c7df4 | ||
|
|
ea1814cea8 | ||
|
|
6dadebb1e4 | ||
|
|
1f2a42c7b7 | ||
|
|
70af08122e | ||
|
|
e0828e885b | ||
|
|
112c0592ad | ||
|
|
007be91e3d | ||
|
|
d74e1291cd | ||
|
|
0128770d6d | ||
|
|
43777b551d | ||
|
|
058725c721 | ||
|
|
1e729c47d2 | ||
|
|
b8779e706e | ||
|
|
f82e0210b7 | ||
|
|
6d0db97163 | ||
|
|
a45cc0fe14 | ||
|
|
59905100d1 | ||
|
|
fb59847a0f | ||
|
|
7ec61cd5b9 | ||
|
|
cd937efa77 | ||
|
|
d2d5191b78 | ||
|
|
a0cb92cbb1 | ||
|
|
6762eec88c | ||
|
|
45e749493c | ||
|
|
76b42901c0 | ||
|
|
b1215b7f8c | ||
|
|
d6767d753f | ||
|
|
c2d5cfbdb8 | ||
|
|
3db5ba08b1 | ||
|
|
6c331f3061 | ||
|
|
32762e2a9c | ||
|
|
e207ededd6 | ||
|
|
36ee367343 | ||
|
|
0b5a75c9af | ||
|
|
7103012754 | ||
|
|
ab4773671b | ||
|
|
e4c9b390ca | ||
|
|
84a9546869 | ||
|
|
5aae8de776 | ||
|
|
57c2a1ae8c | ||
|
|
846adadbcc | ||
|
|
22e19cb354 | ||
|
|
b1dab26be0 | ||
|
|
11151121aa | ||
|
|
c4c5635870 | ||
|
|
e262d5e596 | ||
|
|
9b9b5d0ea2 | ||
|
|
f6d2528f64 | ||
|
|
5ba219e87a | ||
|
|
04f76d9020 | ||
|
|
5c48ef993b | ||
|
|
2e04eee192 | ||
|
|
c542c18d2a | ||
|
|
07046e994f | ||
|
|
0c380c316c | ||
|
|
67b4761bc3 | ||
|
|
164d7e72bf | ||
|
|
4f8f8fcb52 | ||
|
|
856e11e11c | ||
|
|
fa1d730847 | ||
|
|
80c3fb786c | ||
|
|
3cadc1c87e | ||
|
|
84303dc17a | ||
|
|
f6c140e200 | ||
|
|
b1c4017743 | ||
|
|
18fd0bd20c | ||
|
|
b83a20b80a | ||
|
|
99def8f439 | ||
|
|
f66fe2c444 | ||
|
|
91bde0f4a1 | ||
|
|
297d6773af | ||
|
|
e90c5d2060 | ||
|
|
9df3069083 | ||
|
|
2c8d6f5c90 | ||
|
|
e1b111b02a | ||
|
|
8b857bfdc6 | ||
|
|
459b3db61e | ||
|
|
af6adec7cc | ||
|
|
a3f77ed4ba | ||
|
|
b9341e36f1 | ||
|
|
8096f2224c | ||
|
|
16780f6faa | ||
|
|
4103896ca0 | ||
|
|
d30105f471 | ||
|
|
19feda2c95 | ||
|
|
4e6377f5ba | ||
|
|
4b47ee5296 |
4
COPYING
4
COPYING
@@ -2,7 +2,7 @@
|
||||
Version 2, June 1991
|
||||
|
||||
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
|
||||
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
@@ -305,7 +305,7 @@ the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program; if not, write to the Free Software
|
||||
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -1 +1 @@
|
||||
1.02.111-git (2015-10-30)
|
||||
1.02.115-git (2016-01-25)
|
||||
|
||||
85
WHATS_NEW
85
WHATS_NEW
@@ -1,5 +1,88 @@
|
||||
Version 2.02.134 -
|
||||
Version 2.02.141 - 25th January 2016
|
||||
====================================
|
||||
Add metadata/check_pv_device_sizes switch to lvm.conf for device size checks.
|
||||
Warn if device size is less than corresponding PV size in metadata.
|
||||
Cache device sizes internally.
|
||||
Restore support for command breaking in process_each_lv_in_vg() (2.02.118).
|
||||
Use correct mempool when process_each_lv_in_vg() (2.02.118).
|
||||
Fix lvm.8 man to show again prohibited suffixes.
|
||||
Fix configure to set proper use_blkid_wiping if autodetected as disabled.
|
||||
Initialise udev in clvmd for use in device scanning. (2.02.116)
|
||||
Add seg_le_ranges report field for common format when displaying seg devices.
|
||||
Honour report/list_item_separator for seg_metadata_le_ranges report field.
|
||||
Don't mark hidden devs in -o devices,metadata_devices,seg_pe_ranges.(2.02.140)
|
||||
Change LV sizes in seg_pe_ranges report field to match underlying devices.
|
||||
Add kernel_cache_settings report field for cache LV settings used in kernel.
|
||||
|
||||
Version 2.02.140 - 16th January 2016
|
||||
====================================
|
||||
Fix lvm2app to return either 0 or 1 for lvm_vg_is_{clustered,exported}.
|
||||
Add kernel_discards report field to display thin pool discard used in kernel.
|
||||
Correct checking of target presence when driver access is disabled.
|
||||
Eval poolmetadatasize arg earlier in lvresize.
|
||||
Fix vgcfgrestore to respect allocatable attribute of PVs.
|
||||
Add report/mark_hidden_devices to lvm.conf.
|
||||
Use brackets consistently in report fields to mark hidden devices.
|
||||
Restore background polling processing during auto-activation (2.02.119).
|
||||
Fix invalid memory read when reporting cache LV policy_name (2.02.126).
|
||||
|
||||
Version 2.02.139 - 8th January 2016
|
||||
===================================
|
||||
Update lvmlockd with the new VG seqno before devices are suspended.
|
||||
Rework vgrename to use the common processing code in toollib.
|
||||
Make pvs show new devices on the system since the last .cache update.
|
||||
Document F,D and M thin pool health status chars for lv_attr in lvs man page.
|
||||
Also add lvm2-activation{-early,-net}.service systemd status for lvmdump -s.
|
||||
|
||||
Version 2.02.138 - 14th December 2015
|
||||
=====================================
|
||||
Support lvrename for hidden (used) cache pools.
|
||||
Fix lvrename for stacked cache pools.
|
||||
|
||||
Version 2.02.137 - 5th December 2015
|
||||
====================================
|
||||
Restore archiving before changing metadata in vgextend (2.02.117).
|
||||
Dropped internal usage of log_suppress(2).
|
||||
Cleaned logging code for buffer size usage.
|
||||
Added internal id_read_format_try() function to check and read valid UUID.
|
||||
Change lvcreate, lvrename, lvresize to use process_each_vg.
|
||||
Change process_each_vg to handle single VG as separate arg.
|
||||
Issue error if ambiguous VG name is supplied in most commands.
|
||||
Make process_each fns always work through full list of known VG names.
|
||||
Use dm_get_status_mirror() instead of individual parsers.
|
||||
Add mem pool arg for check_transient_status() target function.
|
||||
Avoid misleading error with -m is omitted with lvconvert to raid types.
|
||||
Add system_id to vginfo cache.
|
||||
|
||||
Version 2.02.136 - 28th November 2015
|
||||
=====================================
|
||||
Add new --sinceversion option for lvmconfig --type new.
|
||||
Fix inactive table loaded for wrapping thin-pool when resizing it.
|
||||
Extend the list of ignored libraries when locking memory.
|
||||
|
||||
Version 2.02.135 - 23rd November 2015
|
||||
=====================================
|
||||
Add a model file for Coverity.
|
||||
Show correct error message for unsupported yet cache pool repair.
|
||||
Allow lvconvert cache pools' data and metadata LV to raid.
|
||||
Fix reading of old metadata with missing cache policy or mode settings.
|
||||
Issue error if external_device_info_source=udev and udev db record incomplete.
|
||||
Update lvmetad duplicate VG name handling to use hash function extensions.
|
||||
Detect invalid vgrenames by vgid where the name is unchanged.
|
||||
Fix passing of 32bit values through daemons (mostly lvmlockd).
|
||||
Use local memory pool for whole alloc_handle manipulation.
|
||||
Add missing pointer validation after dm_get_next_target().
|
||||
Do not deref NULL pointer in debug message for _match_pv_tags().
|
||||
Drop unneeded stat() call when checking for sysfs file.
|
||||
Fix memory leak on error path of failing thin-pool percentage check.
|
||||
Add missing test for failing node allocation in lvmetad.
|
||||
Correct configure messages when enabling/disabling lvmlockd.
|
||||
|
||||
Version 2.02.134 - 9th November 2015
|
||||
====================================
|
||||
Refactor some lvmetad code and adjust some duplicate PV messages.
|
||||
No longer repair/wipe VG/PVs if inaccessible because foreign or shared.
|
||||
Pass correct data size to mirror log calc so log can be bigger than 1 extent.
|
||||
|
||||
Version 2.02.133 - 30th October 2015
|
||||
====================================
|
||||
|
||||
27
WHATS_NEW_DM
27
WHATS_NEW_DM
@@ -1,5 +1,30 @@
|
||||
Version 1.02.111 -
|
||||
Version 1.02.115 - 25th January 2016
|
||||
====================================
|
||||
Fix man page for dmsetup udevcreatecookie.
|
||||
|
||||
Version 1.02.114 - 14th December 2015
|
||||
=====================================
|
||||
Better support for dmsetup static linkage.
|
||||
Extend validity checks on dmeventd client socket.
|
||||
|
||||
Version 1.02.113 - 5th December 2015
|
||||
====================================
|
||||
Mirror plugin in dmeventd uses dm_get_status_mirror().
|
||||
Add dm_get_status_mirror() for parsing mirror status line.
|
||||
|
||||
Version 1.02.112 - 28th November 2015
|
||||
=====================================
|
||||
Show error message when trying to create unsupported raid type.
|
||||
Improve preloading sequence of an active thin-pool target.
|
||||
Drop extra space from cache target line to fix unneded table reloads.
|
||||
|
||||
Version 1.02.111 - 23rd November 2015
|
||||
=====================================
|
||||
Extend dm_hash to support multiple values with the same key.
|
||||
Add missing check for allocation inside dm_split_lvm_name().
|
||||
Test dm_task_get_message_response for !NULL in dm_stats_print_region().
|
||||
Add checks for failing dm_stats_create() in dmsetup.
|
||||
Add missing fifo close when failed to initialize client connection.
|
||||
|
||||
Version 1.02.110 - 30th October 2015
|
||||
====================================
|
||||
|
||||
4
aclocal.m4
vendored
4
aclocal.m4
vendored
@@ -15,7 +15,7 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun
|
||||
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
|
||||
# serial 1 (pkg-config-0.24)
|
||||
#
|
||||
# Copyright (c) 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
@@ -29,7 +29,7 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# As a special exception to the GNU General Public License, if you
|
||||
# distribute this file as part of a program that contains a
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -11,14 +11,22 @@
|
||||
# Refer to 'man lvm.conf' for further information about profiles and
|
||||
# general configuration file layout.
|
||||
#
|
||||
allocation {
|
||||
cache_mode="writethrough"
|
||||
cache_settings {
|
||||
}
|
||||
}
|
||||
|
||||
global {
|
||||
units="h"
|
||||
si_unit_consistency=1
|
||||
suffix=1
|
||||
lvdisplay_shows_full_device_path=0
|
||||
}
|
||||
|
||||
report {
|
||||
compact_output=0
|
||||
compact_output_cols=""
|
||||
aligned=1
|
||||
buffered=1
|
||||
headings=1
|
||||
@@ -28,6 +36,7 @@ report {
|
||||
quoted=1
|
||||
colums_as_rows=0
|
||||
binary_values_as_numeric=0
|
||||
time_format="%Y-%m-%d %T %z"
|
||||
devtypes_sort="devtype_name"
|
||||
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
|
||||
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
|
||||
@@ -46,4 +55,5 @@ report {
|
||||
pvsegs_sort="pv_name,pvseg_start"
|
||||
pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
|
||||
pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
|
||||
mark_hidden_devices=1
|
||||
}
|
||||
|
||||
@@ -1109,8 +1109,8 @@ activation {
|
||||
# @*
|
||||
# Selects an LV if a tag defined on the host is also set on the LV
|
||||
# or VG. See tags/hosttags. If any host tags exist but volume_list
|
||||
# is not defined, a default single-entry list containing '@*' is
|
||||
# assumed.
|
||||
# is not defined, a default single-entry list containing '@*'
|
||||
# is assumed.
|
||||
#
|
||||
# Example
|
||||
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
@@ -1146,11 +1146,11 @@ activation {
|
||||
# @*
|
||||
# Selects an LV if a tag defined on the host is also set on the LV
|
||||
# or VG. See tags/hosttags. If any host tags exist but volume_list
|
||||
# is not defined, a default single-entry list containing '@*' is
|
||||
# assumed.
|
||||
# is not defined, a default single-entry list containing '@*'
|
||||
# is assumed.
|
||||
#
|
||||
# Example
|
||||
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
# auto_activation_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
@@ -1172,11 +1172,11 @@ activation {
|
||||
# @*
|
||||
# Selects an LV if a tag defined on the host is also set on the LV
|
||||
# or VG. See tags/hosttags. If any host tags exist but volume_list
|
||||
# is not defined, a default single-entry list containing '@*' is
|
||||
# assumed.
|
||||
# is not defined, a default single-entry list containing '@*'
|
||||
# is assumed.
|
||||
#
|
||||
# Example
|
||||
# volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
# read_only_volume_list = [ "vg1", "vg2/lvol1", "@tag1", "@*" ]
|
||||
#
|
||||
# This configuration option does not have a default value defined.
|
||||
|
||||
@@ -1415,6 +1415,17 @@ activation {
|
||||
# This configuration section has an automatic default value.
|
||||
# metadata {
|
||||
|
||||
# Configuration option metadata/check_pv_device_sizes.
|
||||
# Check device sizes are not smaller than corresponding PV sizes.
|
||||
# If device size is less than corresponding PV size found in metadata,
|
||||
# there is always a risk of data loss. If this option is set, then LVM
|
||||
# issues a warning message each time it finds that the device size is
|
||||
# less than corresponding PV size. You should not disable this unless
|
||||
# you are absolutely sure about what you are doing!
|
||||
# This configuration option is advanced.
|
||||
# This configuration option has an automatic default value.
|
||||
# check_pv_device_sizes = 1
|
||||
|
||||
# Configuration option metadata/pvmetadatacopies.
|
||||
# Number of copies of metadata to store on each PV.
|
||||
# The --pvmetadatacopies option overrides this setting.
|
||||
@@ -1808,6 +1819,11 @@ activation {
|
||||
# See 'pvs --segments -o help' for the list of possible fields.
|
||||
# This configuration option has an automatic default value.
|
||||
# pvsegs_cols_verbose = "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
|
||||
|
||||
# Configuration option report/mark_hidden_devices.
|
||||
# Use brackets [] to mark hidden devices.
|
||||
# This configuration option has an automatic default value.
|
||||
# mark_hidden_devices = 1
|
||||
# }
|
||||
|
||||
# Configuration section dmeventd.
|
||||
|
||||
70
configure
vendored
70
configure
vendored
@@ -3130,7 +3130,6 @@ case "$host_os" in
|
||||
DEVMAPPER=yes
|
||||
LVMETAD=no
|
||||
LVMPOLLD=no
|
||||
LVMLOCKD=no
|
||||
LOCKDSANLOCK=no
|
||||
LOCKDDLM=no
|
||||
ODIRECT=yes
|
||||
@@ -11368,6 +11367,8 @@ $as_echo "$LVMPOLLD" >&6; }
|
||||
BUILD_LVMPOLLD=$LVMPOLLD
|
||||
|
||||
################################################################################
|
||||
BUILD_LVMLOCKD=no
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lockdsanlock" >&5
|
||||
$as_echo_n "checking whether to build lockdsanlock... " >&6; }
|
||||
# Check whether --enable-lockd-sanlock was given.
|
||||
@@ -11382,13 +11383,6 @@ BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
|
||||
|
||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
||||
|
||||
$as_echo "#define LOCKDSANLOCK_SUPPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_SANLOCK" >&5
|
||||
$as_echo_n "checking for LOCKD_SANLOCK... " >&6; }
|
||||
@@ -11459,6 +11453,9 @@ else
|
||||
$as_echo "yes" >&6; }
|
||||
HAVE_LOCKD_SANLOCK=yes
|
||||
fi
|
||||
|
||||
$as_echo "#define LOCKDSANLOCK_SUPPORT 1" >>confdefs.h
|
||||
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
@@ -11477,13 +11474,6 @@ BUILD_LOCKDDLM=$LOCKDDLM
|
||||
|
||||
if test "$BUILD_LOCKDDLM" = yes; then
|
||||
|
||||
$as_echo "#define LOCKDDLM_SUPPORT 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
if test "$BUILD_LOCKDDLM" = yes; then
|
||||
|
||||
pkg_failed=no
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LOCKD_DLM" >&5
|
||||
$as_echo_n "checking for LOCKD_DLM... " >&6; }
|
||||
@@ -11554,11 +11544,13 @@ else
|
||||
$as_echo "yes" >&6; }
|
||||
HAVE_LOCKD_DLM=yes
|
||||
fi
|
||||
|
||||
$as_echo "#define LOCKDDLM_SUPPORT 1" >>confdefs.h
|
||||
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build lvmlockd" >&5
|
||||
$as_echo_n "checking whether to build lvmlockd... " >&6; }
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_LVMLOCKD" >&5
|
||||
@@ -11799,7 +11791,7 @@ fi
|
||||
$as_echo "#define BLKID_WIPING_SUPPORT 1" >>confdefs.h
|
||||
|
||||
else
|
||||
DEFAULT_USE_BLKID_WIPING=1
|
||||
DEFAULT_USE_BLKID_WIPING=0
|
||||
fi
|
||||
else
|
||||
DEFAULT_USE_BLKID_WIPING=0
|
||||
@@ -12015,6 +12007,50 @@ fi
|
||||
|
||||
$as_echo "#define UDEV_SYNC_SUPPORT 1" >>confdefs.h
|
||||
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for udev_device_get_is_initialized in -ludev" >&5
|
||||
$as_echo_n "checking for udev_device_get_is_initialized in -ludev... " >&6; }
|
||||
if ${ac_cv_lib_udev_udev_device_get_is_initialized+:} false; then :
|
||||
$as_echo_n "(cached) " >&6
|
||||
else
|
||||
ac_check_lib_save_LIBS=$LIBS
|
||||
LIBS="-ludev $LIBS"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
/* Override any GCC internal prototype to avoid an error.
|
||||
Use char because int might match the return type of a GCC
|
||||
builtin and then its argument prototype would still apply. */
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
#endif
|
||||
char udev_device_get_is_initialized ();
|
||||
int
|
||||
main ()
|
||||
{
|
||||
return udev_device_get_is_initialized ();
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"; then :
|
||||
ac_cv_lib_udev_udev_device_get_is_initialized=yes
|
||||
else
|
||||
ac_cv_lib_udev_udev_device_get_is_initialized=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_udev_udev_device_get_is_initialized" >&5
|
||||
$as_echo "$ac_cv_lib_udev_udev_device_get_is_initialized" >&6; }
|
||||
if test "x$ac_cv_lib_udev_udev_device_get_is_initialized" = xyes; then :
|
||||
|
||||
$as_echo "#define HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED 1" >>confdefs.h
|
||||
|
||||
fi
|
||||
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
|
||||
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable installation of udev rules required for synchronisation" >&5
|
||||
|
||||
24
configure.in
24
configure.in
@@ -8,7 +8,7 @@
|
||||
##
|
||||
## You should have received a copy of the GNU General Public License
|
||||
## along with this program; if not, write to the Free Software Foundation,
|
||||
## Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
## Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
################################################################################
|
||||
|
||||
AC_PREREQ(2.61)
|
||||
@@ -39,7 +39,6 @@ case "$host_os" in
|
||||
DEVMAPPER=yes
|
||||
LVMETAD=no
|
||||
LVMPOLLD=no
|
||||
LVMLOCKD=no
|
||||
LOCKDSANLOCK=no
|
||||
LOCKDDLM=no
|
||||
ODIRECT=yes
|
||||
@@ -1145,6 +1144,8 @@ AC_MSG_RESULT($LVMPOLLD)
|
||||
BUILD_LVMPOLLD=$LVMPOLLD
|
||||
|
||||
################################################################################
|
||||
BUILD_LVMLOCKD=no
|
||||
|
||||
dnl -- Build lockdsanlock
|
||||
AC_MSG_CHECKING(whether to build lockdsanlock)
|
||||
AC_ARG_ENABLE(lockd-sanlock,
|
||||
@@ -1155,14 +1156,10 @@ AC_MSG_RESULT($LOCKDSANLOCK)
|
||||
|
||||
BUILD_LOCKDSANLOCK=$LOCKDSANLOCK
|
||||
|
||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
||||
AC_DEFINE([LOCKDSANLOCK_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd sanlock option.])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Look for sanlock libraries
|
||||
if test "$BUILD_LOCKDSANLOCK" = yes; then
|
||||
PKG_CHECK_MODULES(LOCKD_SANLOCK, libsanlock_client, [HAVE_LOCKD_SANLOCK=yes], $bailout)
|
||||
AC_DEFINE([LOCKDSANLOCK_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd sanlock option.])
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
@@ -1177,20 +1174,15 @@ AC_MSG_RESULT($LOCKDDLM)
|
||||
|
||||
BUILD_LOCKDDLM=$LOCKDDLM
|
||||
|
||||
if test "$BUILD_LOCKDDLM" = yes; then
|
||||
AC_DEFINE([LOCKDDLM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd dlm option.])
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Look for dlm libraries
|
||||
if test "$BUILD_LOCKDDLM" = yes; then
|
||||
PKG_CHECK_MODULES(LOCKD_DLM, libdlm, [HAVE_LOCKD_DLM=yes], $bailout)
|
||||
AC_DEFINE([LOCKDDLM_SUPPORT], 1, [Define to 1 to include code that uses lvmlockd dlm option.])
|
||||
BUILD_LVMLOCKD=yes
|
||||
fi
|
||||
|
||||
################################################################################
|
||||
dnl -- Build lvmlockd
|
||||
|
||||
AC_MSG_CHECKING(whether to build lvmlockd)
|
||||
AC_MSG_RESULT($BUILD_LVMLOCKD)
|
||||
|
||||
@@ -1299,7 +1291,7 @@ if test "$BLKID_WIPING" != no; then
|
||||
DEFAULT_USE_BLKID_WIPING=1
|
||||
AC_DEFINE([BLKID_WIPING_SUPPORT], 1, [Define to 1 to use libblkid detection of signatures when wiping.])
|
||||
else
|
||||
DEFAULT_USE_BLKID_WIPING=1
|
||||
DEFAULT_USE_BLKID_WIPING=0
|
||||
fi
|
||||
else
|
||||
DEFAULT_USE_BLKID_WIPING=0
|
||||
@@ -1342,6 +1334,10 @@ if test "$UDEV_SYNC" = yes; then
|
||||
pkg_config_init
|
||||
PKG_CHECK_MODULES(UDEV, libudev >= 143, [UDEV_PC="libudev"])
|
||||
AC_DEFINE([UDEV_SYNC_SUPPORT], 1, [Define to 1 to enable synchronisation with udev processing.])
|
||||
|
||||
AC_CHECK_LIB(udev, udev_device_get_is_initialized, AC_DEFINE([HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED], 1,
|
||||
[Define to 1 if udev_device_get_is_initialized is available.]))
|
||||
LIBS=$ac_check_lib_save_LIBS
|
||||
fi
|
||||
|
||||
dnl -- Enable udev rules
|
||||
|
||||
122
coverity/coverity_model.c
Normal file
122
coverity/coverity_model.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (C) 2015 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use,
|
||||
* modify, copy, or redistribute it subject to the terms and conditions
|
||||
* of the GNU General Public License v.2.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
* Coverity usage:
|
||||
*
|
||||
* translate model into xml
|
||||
* cov-make-library -of coverity_model.xml coverity_model.c
|
||||
*
|
||||
* compile (using outdir 'cov'):
|
||||
* cov-build --dir=cov make CC=gcc
|
||||
*
|
||||
* analyze (agressively, using 'cov')
|
||||
* cov-analyze --dir cov --wait-for-license --hfa --concurrency --enable-fnptr --enable-constraint-fpp --security --all --aggressiveness-level=high --field-offset-escape --user-model-file=coverity/coverity_model.xml
|
||||
*
|
||||
* generate html output (to 'html' from 'cov'):
|
||||
* cov-format-errors --dir cov --html-output html
|
||||
*/
|
||||
|
||||
struct lv_segment;
|
||||
struct logical_volume;
|
||||
|
||||
struct lv_segment *first_seg(const struct logical_volume *lv)
|
||||
{
|
||||
return ((struct lv_segment **)lv)[0];
|
||||
}
|
||||
|
||||
struct lv_segment *last_seg(const struct logical_volume *lv)
|
||||
{
|
||||
return ((struct lv_segment **)lv)[0];
|
||||
}
|
||||
|
||||
/* simple_memccpy() from glibc */
|
||||
void *memccpy(void *dest, const void *src, int c, size_t n)
|
||||
{
|
||||
const char *s = src;
|
||||
char *d = dest;
|
||||
|
||||
while (n-- > 0)
|
||||
if ((*d++ = *s++) == (char) c)
|
||||
return d;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* 2 lines bellow needs to be placed in coverity/config/user_nodefs.h
|
||||
* Not sure about any other way.
|
||||
* Without them, coverity shows warning since x86 system header files
|
||||
* are using inline assembly to reset fdset
|
||||
*/
|
||||
//#nodef FD_ZERO model_FD_ZERO
|
||||
//void model_FD_ZERO(void *fdset);
|
||||
|
||||
void model_FD_ZERO(void *fdset)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < 1024 / 8 / sizeof(long); ++i)
|
||||
((long*)fdset)[i] = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Added extra pointer check to not need these models,
|
||||
* for now just keep then in file
|
||||
*/
|
||||
|
||||
/*
|
||||
struct cmd_context;
|
||||
struct profile;
|
||||
|
||||
const char *find_config_tree_str(struct cmd_context *cmd, int id, struct profile *profile)
|
||||
{
|
||||
return "text";
|
||||
}
|
||||
|
||||
const char *find_config_tree_str_allow_empty(struct cmd_context *cmd, int id, struct profile *profile)
|
||||
{
|
||||
return "text";
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
* Until fixed coverity case# 00531860:
|
||||
* A FORWARD_NULL false positive on a recursive function call
|
||||
*
|
||||
* model also these functions:
|
||||
*/
|
||||
/*
|
||||
const struct dm_config_node;
|
||||
const struct dm_config_node *find_config_tree_array(struct cmd_context *cmd, int id, struct profile *profile)
|
||||
{
|
||||
const struct dm_config_node *cn;
|
||||
|
||||
return cn;
|
||||
}
|
||||
|
||||
const struct dm_config_node *find_config_tree_node(struct cmd_context *cmd, int id, struct profile *profile)
|
||||
{
|
||||
const struct dm_config_node *cn;
|
||||
|
||||
return cn;
|
||||
}
|
||||
|
||||
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile)
|
||||
{
|
||||
int b;
|
||||
|
||||
return b;
|
||||
}
|
||||
*/
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Definitions for CLVMD server and clients */
|
||||
@@ -76,8 +76,10 @@ static const char CLVMD_SOCKNAME[]= DEFAULT_RUN_DIR "/clvmd.sock";
|
||||
#define CLVMD_CMD_SYNC_NAMES 45
|
||||
|
||||
/* Used internally by some callers, but not part of the protocol.*/
|
||||
#define NODE_ALL "*"
|
||||
#define NODE_LOCAL "."
|
||||
#define NODE_REMOTE "^"
|
||||
#ifndef NODE_ALL
|
||||
# define NODE_ALL "*"
|
||||
# define NODE_LOCAL "."
|
||||
# define NODE_REMOTE "^"
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "clvmd-common.h"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -374,7 +374,7 @@ int main(int argc, char *argv[])
|
||||
/* Deal with command-line arguments */
|
||||
opterr = 0;
|
||||
optind = 0;
|
||||
while ((opt = getopt_long(argc, argv, "vVhfd:t:RST:CI:E:",
|
||||
while ((opt = getopt_long(argc, argv, "Vhfd:t:RST:CI:E:",
|
||||
longopts, NULL)) != -1) {
|
||||
switch (opt) {
|
||||
case 'h':
|
||||
@@ -604,7 +604,10 @@ int main(int argc, char *argv[])
|
||||
local_client_head.fd, &local_client_head, newfd->fd, newfd);
|
||||
|
||||
/* Don't let anyone else to do work until we are started */
|
||||
pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params);
|
||||
if (pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params)) {
|
||||
log_sys_error("pthread_create", "");
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Don't start until the LVM thread is ready */
|
||||
pthread_barrier_wait(&lvm_start_barrier);
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _CLVMD_H
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "clvmd-common.h"
|
||||
@@ -291,6 +291,7 @@ static int hold_lock(char *resource, int mode, int flags)
|
||||
}
|
||||
|
||||
lvi->lock_mode = mode;
|
||||
lvi->lock_id = 0;
|
||||
status = sync_lock(resource, mode, flags & ~LCKF_CONVERT, &lvi->lock_id);
|
||||
saved_errno = errno;
|
||||
if (status) {
|
||||
@@ -662,7 +663,8 @@ int do_refresh_cache(void)
|
||||
|
||||
init_full_scan_done(0);
|
||||
init_ignore_suspended_devices(1);
|
||||
lvmcache_label_scan(cmd, 2);
|
||||
lvmcache_force_next_label_scan();
|
||||
lvmcache_label_scan(cmd);
|
||||
dm_pool_empty(cmd->mem);
|
||||
|
||||
pthread_mutex_unlock(&lvm_lock);
|
||||
@@ -899,8 +901,12 @@ int init_clvm(struct dm_hash_table *excl_uuid)
|
||||
if (!get_initial_state(excl_uuid))
|
||||
log_error("Cannot load initial lock states.");
|
||||
|
||||
if (!udev_init_library_context())
|
||||
stack;
|
||||
|
||||
if (!(cmd = create_toolcontext(1, NULL, 0, 1, 1, 1))) {
|
||||
log_error("Failed to allocate command context");
|
||||
udev_fin_library_context();
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -927,6 +933,7 @@ void destroy_lvm(void)
|
||||
if (cmd) {
|
||||
memlock_dec_daemon(cmd);
|
||||
destroy_toolcontext(cmd);
|
||||
udev_fin_library_context();
|
||||
cmd = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* Functions in lvm-functions.c */
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* FIXME Remove duplicated functions from this file. */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "logging.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "logging.h"
|
||||
#include "cluster.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _LVM_CLOG_CLUSTER_H
|
||||
#define _LVM_CLOG_CLUSTER_H
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _LVM_CLOG_COMMON_H
|
||||
#define _LVM_CLOG_COMMON_H
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "logging.h"
|
||||
#include "functions.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _LVM_CLOG_FUNCTIONS_H
|
||||
#define _LVM_CLOG_FUNCTIONS_H
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "logging.h"
|
||||
#include "link_mon.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _LVM_CLOG_LINK_MON_H
|
||||
#define _LVM_CLOG_LINK_MON_H
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "logging.h"
|
||||
#include "common.h"
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _LVM_CLOG_LOCAL_H
|
||||
#define _LVM_CLOG_LOCAL_H
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "logging.h"
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_CLOG_LOGGING_H
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
@@ -408,7 +408,7 @@ static struct thread_status *_alloc_thread_status(const struct message_data *dat
|
||||
if (!(thread->device.uuid = dm_strdup(data->device_uuid)))
|
||||
goto_out;
|
||||
|
||||
/* Until real name resolved, use UUID */
|
||||
/* Until real name resolved, use UUID */
|
||||
if (!(thread->device.name = dm_strdup(data->device_uuid)))
|
||||
goto_out;
|
||||
|
||||
@@ -1355,78 +1355,89 @@ static int _get_timeout(struct message_data *message_data)
|
||||
return (msg->data && msg->size) ? 0 : -ENOMEM;
|
||||
}
|
||||
|
||||
/* Open fifos used for client communication. */
|
||||
static int _open_fifos(struct dm_event_fifos *fifos)
|
||||
static int _open_fifo(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
int fd = -1;
|
||||
|
||||
/*
|
||||
* FIXME Explicitly verify the code's requirement that path is secure:
|
||||
* - All parent directories owned by root without group/other write access unless sticky.
|
||||
*/
|
||||
|
||||
/* Create client fifo. */
|
||||
(void) dm_prepare_selinux_context(fifos->client_path, S_IFIFO);
|
||||
if ((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) {
|
||||
log_sys_error("client mkfifo", fifos->client_path);
|
||||
(void) dm_prepare_selinux_context(NULL, 0);
|
||||
goto fail;
|
||||
/* If path exists, only use it if it is root-owned fifo mode 0600 */
|
||||
if ((lstat(path, &st) < 0)) {
|
||||
if (errno != ENOENT) {
|
||||
log_sys_error("stat", path);
|
||||
return -1;
|
||||
}
|
||||
} else if (!S_ISFIFO(st.st_mode) || st.st_uid ||
|
||||
(st.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO))) {
|
||||
log_warn("WARNING: %s has wrong attributes: Replacing.", path);
|
||||
if (unlink(path)) {
|
||||
log_sys_error("unlink", path);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create server fifo. */
|
||||
(void) dm_prepare_selinux_context(fifos->server_path, S_IFIFO);
|
||||
if ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST) {
|
||||
log_sys_error("server mkfifo", fifos->server_path);
|
||||
/* Create fifo. */
|
||||
(void) dm_prepare_selinux_context(path, S_IFIFO);
|
||||
if ((mkfifo(path, 0600) == -1) && errno != EEXIST) {
|
||||
log_sys_error("mkfifo", path);
|
||||
(void) dm_prepare_selinux_context(NULL, 0);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
(void) dm_prepare_selinux_context(NULL, 0);
|
||||
|
||||
/* Warn about wrong permissions if applicable */
|
||||
if ((!stat(fifos->client_path, &st)) && (st.st_mode & 0777) != 0600)
|
||||
log_warn("WARNING: Fixing wrong permissions on %s: %s.\n",
|
||||
fifos->client_path, strerror(errno));
|
||||
|
||||
if ((!stat(fifos->server_path, &st)) && (st.st_mode & 0777) != 0600)
|
||||
log_warn("WARNING: Fixing wrong permissions on %s: %s.\n",
|
||||
fifos->server_path, strerror(errno));
|
||||
|
||||
/* If they were already there, make sure permissions are ok. */
|
||||
if (chmod(fifos->client_path, 0600)) {
|
||||
log_sys_error("chmod", fifos->client_path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (chmod(fifos->server_path, 0600)) {
|
||||
log_sys_error("chmod", fifos->server_path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Need to open read+write or we will block or fail */
|
||||
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
|
||||
log_sys_error("server open", fifos->server_path);
|
||||
if ((fd = open(path, O_RDWR)) < 0) {
|
||||
log_sys_error("open", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fcntl(fifos->server, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
log_sys_error("fcntl(FD_CLOEXEC)", fifos->server_path);
|
||||
/* Warn about wrong permissions if applicable */
|
||||
if (fstat(fd, &st)) {
|
||||
log_sys_error("fstat", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Need to open read+write for select() to work. */
|
||||
if ((fifos->client = open(fifos->client_path, O_RDWR)) < 0) {
|
||||
log_sys_error("client open", fifos->client_path);
|
||||
if (!S_ISFIFO(st.st_mode) || st.st_uid ||
|
||||
(st.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO))) {
|
||||
log_error("%s: fifo has incorrect attributes", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fcntl(fifos->client, F_SETFD, FD_CLOEXEC) < 0) {
|
||||
log_sys_error("fcntl(FD_CLOEXEC)", fifos->client_path);
|
||||
if (fcntl(fd, F_SETFD, FD_CLOEXEC)) {
|
||||
log_sys_error("fcntl(FD_CLOEXEC)", path);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return fd;
|
||||
|
||||
fail:
|
||||
if ((fd >= 0) && close(fd))
|
||||
log_sys_error("close", path);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Open fifos used for client communication. */
|
||||
static int _open_fifos(struct dm_event_fifos *fifos)
|
||||
{
|
||||
/* Create client fifo. */
|
||||
if ((fifos->client = _open_fifo(fifos->client_path)) < 0)
|
||||
goto fail;
|
||||
|
||||
/* Create server fifo. */
|
||||
if ((fifos->server = _open_fifo(fifos->server_path)) < 0)
|
||||
goto fail;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
if (fifos->server >= 0 && close(fifos->server))
|
||||
log_sys_error("server close", fifos->server_path);
|
||||
|
||||
fail:
|
||||
if (fifos->client >= 0 && close(fifos->client))
|
||||
log_sys_error("client close", fifos->client_path);
|
||||
log_sys_error("close", fifos->client_path);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1961,21 +1972,21 @@ static int _reinstate_registrations(struct dm_event_fifos *fifos)
|
||||
!(dev_name = strtok(NULL, _delim)) ||
|
||||
!(mask = strtok(NULL, _delim)) ||
|
||||
!(timeout = strtok(NULL, _delim))) {
|
||||
fprintf(stderr, _failed_parsing_msg);
|
||||
fputs(_failed_parsing_msg, stderr);
|
||||
continue;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
mask_value = strtoul(mask, &endp, 10);
|
||||
if (errno || !endp || *endp) {
|
||||
fprintf(stderr, _failed_parsing_msg);
|
||||
fputs(_failed_parsing_msg, stderr);
|
||||
continue;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
timeout_value = strtoul(timeout, &endp, 10);
|
||||
if (errno || !endp || *endp) {
|
||||
fprintf(stderr, _failed_parsing_msg);
|
||||
fputs(_failed_parsing_msg, stderr);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -2260,9 +2271,9 @@ int main(int argc, char *argv[])
|
||||
|
||||
log_notice("dmeventd shutting down.");
|
||||
|
||||
if (close(fifos.client))
|
||||
if (fifos.client >= 0 && close(fifos.client))
|
||||
log_sys_error("client close", fifos.client_path);
|
||||
if (close(fifos.server))
|
||||
if (fifos.server >= 0 && close(fifos.server))
|
||||
log_sys_error("server close", fifos.server_path);
|
||||
|
||||
if (_use_syslog)
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __DMEVENTD_DOT_H__
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "dm-logging.h"
|
||||
@@ -412,28 +412,55 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
|
||||
char default_dmeventd_path[] = DMEVENTD_PATH;
|
||||
char *args[] = { dmeventd_path ? : default_dmeventd_path, NULL };
|
||||
|
||||
if (stat(fifos->client_path, &statbuf))
|
||||
goto start_server;
|
||||
/*
|
||||
* FIXME Explicitly verify the code's requirement that client_path is secure:
|
||||
* - All parent directories owned by root without group/other write access unless sticky.
|
||||
*/
|
||||
|
||||
if (!S_ISFIFO(statbuf.st_mode)) {
|
||||
log_error("%s is not a fifo.", fifos->client_path);
|
||||
/* If client fifo path exists, only use it if it is root-owned fifo mode 0600 */
|
||||
if ((lstat(fifos->client_path, &statbuf) < 0)) {
|
||||
if (errno == ENOENT)
|
||||
/* Jump ahead if fifo does not already exist. */
|
||||
goto start_server;
|
||||
else {
|
||||
log_sys_error("stat", fifos->client_path);
|
||||
return 0;
|
||||
}
|
||||
} else if (!S_ISFIFO(statbuf.st_mode)) {
|
||||
log_error("%s must be a fifo.", fifos->client_path);
|
||||
return 0;
|
||||
} else if (statbuf.st_uid) {
|
||||
log_error("%s must be owned by uid 0.", fifos->client_path);
|
||||
return 0;
|
||||
} else if (statbuf.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO)) {
|
||||
log_error("%s must have mode 0600.", fifos->client_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Anyone listening? If not, errno will be ENXIO */
|
||||
fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
|
||||
if (fifos->client >= 0) {
|
||||
/* Should never happen if all the above checks passed. */
|
||||
if ((fstat(fifos->client, &statbuf) < 0) ||
|
||||
!S_ISFIFO(statbuf.st_mode) || statbuf.st_uid ||
|
||||
(statbuf.st_mode & (S_IEXEC | S_IRWXG | S_IRWXO))) {
|
||||
log_error("%s is no longer a secure root-owned fifo with mode 0600.", fifos->client_path);
|
||||
if (close(fifos->client))
|
||||
log_sys_debug("close", fifos->client_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* server is running and listening */
|
||||
if (close(fifos->client))
|
||||
log_sys_debug("close", fifos->client_path);
|
||||
return 1;
|
||||
} else if (errno != ENXIO) {
|
||||
} else if (errno != ENXIO && errno != ENOENT) {
|
||||
/* problem */
|
||||
log_sys_error("open", fifos->client_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
start_server:
|
||||
start_server:
|
||||
/* server is not running */
|
||||
|
||||
if ((args[0][0] == '/') && stat(args[0], &statbuf)) {
|
||||
@@ -587,8 +614,8 @@ static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_messag
|
||||
};
|
||||
|
||||
if (!_init_client(dmeventd_path, &fifos)) {
|
||||
stack;
|
||||
return -ESRCH;
|
||||
ret = -ESRCH;
|
||||
goto_out;
|
||||
}
|
||||
|
||||
ret = daemon_talk(&fifos, msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
|
||||
@@ -598,7 +625,7 @@ static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_messag
|
||||
|
||||
if (!ret)
|
||||
ret = daemon_talk(&fifos, msg, cmd, dso_name, dev_name, evmask, timeout);
|
||||
|
||||
out:
|
||||
/* what is the opposite of init? */
|
||||
fini_fifos(&fifos);
|
||||
|
||||
@@ -727,6 +754,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
|
||||
|
||||
uuid = dm_task_get_uuid(dmt);
|
||||
|
||||
/* FIXME Distinguish errors connecting to daemon */
|
||||
if (_do_event(next ? DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE :
|
||||
DM_EVENT_CMD_GET_REGISTERED_DEVICE, dmevh->dmeventd_path,
|
||||
&msg, dmevh->dso, uuid, dmevh->mask, 0)) {
|
||||
@@ -841,7 +869,7 @@ void dm_event_log(const char *subsys, int level, const char *file,
|
||||
static time_t start = 0;
|
||||
const char *indent = "";
|
||||
FILE *stream = stdout;
|
||||
int prio = -1;
|
||||
int prio;
|
||||
time_t now;
|
||||
|
||||
switch (level & ~(_LOG_STDERR | _LOG_ONCE)) {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -31,8 +31,9 @@ struct dso_state {
|
||||
|
||||
DM_EVENT_LOG_FN("mirr")
|
||||
|
||||
static int _process_status_code(const char status_code, const char *dev_name,
|
||||
const char *dev_type, int r)
|
||||
static void _process_status_code(dm_status_mirror_health_t health,
|
||||
uint32_t major, uint32_t minor,
|
||||
const char *dev_type, int *r)
|
||||
{
|
||||
/*
|
||||
* A => Alive - No failures
|
||||
@@ -42,90 +43,60 @@ static int _process_status_code(const char status_code, const char *dev_name,
|
||||
* R => Read - A read failure occurred, mirror data unaffected
|
||||
* U => Unclassified failure (bug)
|
||||
*/
|
||||
if (status_code == 'F') {
|
||||
log_error("%s device %s flush failed.", dev_type, dev_name);
|
||||
r = ME_FAILURE;
|
||||
} else if (status_code == 'S')
|
||||
log_error("%s device %s sync failed.", dev_type, dev_name);
|
||||
else if (status_code == 'R')
|
||||
log_error("%s device %s read failed.", dev_type, dev_name);
|
||||
else if (status_code != 'A') {
|
||||
log_error("%s device %s has failed (%c).",
|
||||
dev_type, dev_name, status_code);
|
||||
r = ME_FAILURE;
|
||||
switch (health) {
|
||||
case DM_STATUS_MIRROR_ALIVE:
|
||||
return;
|
||||
case DM_STATUS_MIRROR_FLUSH_FAILED:
|
||||
log_error("%s device %u:%u flush failed.",
|
||||
dev_type, major, minor);
|
||||
*r = ME_FAILURE;
|
||||
break;
|
||||
case DM_STATUS_MIRROR_SYNC_FAILED:
|
||||
log_error("%s device %u:%u sync failed.",
|
||||
dev_type, major, minor);
|
||||
break;
|
||||
case DM_STATUS_MIRROR_READ_FAILED:
|
||||
log_error("%s device %u:%u read failed.",
|
||||
dev_type, major, minor);
|
||||
break;
|
||||
default:
|
||||
log_error("%s device %u:%u has failed (%c).",
|
||||
dev_type, major, minor, (char)health);
|
||||
*r = ME_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _get_mirror_event(char *params)
|
||||
static int _get_mirror_event(struct dso_state *state, char *params)
|
||||
{
|
||||
int i, r = ME_INSYNC;
|
||||
char **args = NULL;
|
||||
char *dev_status_str;
|
||||
char *log_status_str;
|
||||
char *sync_str;
|
||||
char *p = NULL;
|
||||
int log_argc, num_devs;
|
||||
int r = ME_INSYNC;
|
||||
unsigned i;
|
||||
struct dm_status_mirror *ms;
|
||||
|
||||
/*
|
||||
* dm core parms: 0 409600 mirror
|
||||
* Mirror core parms: 2 253:4 253:5 400/400
|
||||
* New-style failure params: 1 AA
|
||||
* New-style log params: 3 cluster 253:3 A
|
||||
* or 3 disk 253:3 A
|
||||
* or 1 core
|
||||
*/
|
||||
|
||||
/* number of devices */
|
||||
if (!dm_split_words(params, 1, 0, &p))
|
||||
goto out_parse;
|
||||
|
||||
if (!(num_devs = atoi(p)) ||
|
||||
(num_devs > DEFAULT_MIRROR_MAX_IMAGES) || (num_devs < 0))
|
||||
goto out_parse;
|
||||
p += strlen(p) + 1;
|
||||
|
||||
/* devices names + "400/400" + "1 AA" + 1 or 3 log parms + NULL */
|
||||
args = dm_malloc((num_devs + 7) * sizeof(char *));
|
||||
if (!args || dm_split_words(p, num_devs + 7, 0, args) < num_devs + 5)
|
||||
goto out_parse;
|
||||
|
||||
/* FIXME: Code differs from lib/mirror/mirrored.c */
|
||||
dev_status_str = args[2 + num_devs];
|
||||
log_argc = atoi(args[3 + num_devs]);
|
||||
log_status_str = args[3 + num_devs + log_argc];
|
||||
sync_str = args[num_devs];
|
||||
if (!dm_get_status_mirror(state->mem, params, &ms))
|
||||
goto_out;
|
||||
|
||||
/* Check for bad mirror devices */
|
||||
for (i = 0; i < num_devs; i++)
|
||||
r = _process_status_code(dev_status_str[i], args[i],
|
||||
i ? "Secondary mirror" : "Primary mirror", r);
|
||||
for (i = 0; i < ms->dev_count; ++i)
|
||||
_process_status_code(ms->devs[i].health,
|
||||
ms->devs[i].major, ms->devs[i].minor,
|
||||
i ? "Secondary mirror" : "Primary mirror", &r);
|
||||
|
||||
/* Check for bad disk log device */
|
||||
if (log_argc > 1)
|
||||
r = _process_status_code(log_status_str[0],
|
||||
args[2 + num_devs + log_argc],
|
||||
"Log", r);
|
||||
for (i = 0; i < ms->log_count; ++i)
|
||||
_process_status_code(ms->logs[i].health,
|
||||
ms->logs[i].major, ms->logs[i].minor,
|
||||
"Log", &r);
|
||||
|
||||
if (r == ME_FAILURE)
|
||||
goto out;
|
||||
/* Ignore if not in-sync */
|
||||
if ((r == ME_INSYNC) && (ms->insync_regions != ms->total_regions))
|
||||
r = ME_IGNORE;
|
||||
|
||||
p = strstr(sync_str, "/");
|
||||
if (p) {
|
||||
p[0] = '\0';
|
||||
if (strcmp(sync_str, p+1))
|
||||
r = ME_IGNORE;
|
||||
p[0] = '/';
|
||||
} else
|
||||
goto out_parse;
|
||||
dm_pool_free(state->mem, ms);
|
||||
|
||||
out:
|
||||
dm_free(args);
|
||||
return r;
|
||||
|
||||
out_parse:
|
||||
dm_free(args);
|
||||
out:
|
||||
log_error("Unable to parse mirror status string.");
|
||||
|
||||
return ME_IGNORE;
|
||||
@@ -172,7 +143,7 @@ void process_event(struct dm_task *dmt,
|
||||
continue;
|
||||
}
|
||||
|
||||
switch(_get_mirror_event(params)) {
|
||||
switch(_get_mirror_event(state, params)) {
|
||||
case ME_INSYNC:
|
||||
/* FIXME: all we really know is that this
|
||||
_part_ of the device is in sync
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h" /* using here lvm log */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -77,7 +77,7 @@ int main(int argc, char **argv)
|
||||
val = atoi(argv[2]);
|
||||
|
||||
reply = daemon_send_simple(h, "set_global_info",
|
||||
"global_invalid = %d", val,
|
||||
"global_invalid = " FMTd64, (int64_t) val,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
print_reply(reply);
|
||||
@@ -106,21 +106,21 @@ int main(int argc, char **argv)
|
||||
reply = daemon_send_simple(h, "set_vg_info",
|
||||
"uuid = %s", uuid,
|
||||
"name = %s", name,
|
||||
"version = %d", ver,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
"version = " FMTd64, (int64_t) ver,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
} else if (uuid) {
|
||||
reply = daemon_send_simple(h, "set_vg_info",
|
||||
"uuid = %s", uuid,
|
||||
"version = %d", ver,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
"version = " FMTd64, (int64_t) ver,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
} else if (name) {
|
||||
reply = daemon_send_simple(h, "set_vg_info",
|
||||
"name = %s", name,
|
||||
"version = %d", ver,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
"version = " FMTd64, (int64_t) ver,
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
} else {
|
||||
printf("name or uuid required\n");
|
||||
return -1;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_LVMETAD_CLIENT_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#include "tool.h"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -18,7 +18,6 @@
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
@@ -456,7 +455,7 @@ static int do_able(const char *req_name)
|
||||
|
||||
reply = _lvmlockd_send(req_name,
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = %d", getpid(),
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", arg_vg_name,
|
||||
NULL);
|
||||
|
||||
@@ -487,7 +486,7 @@ static int do_stop_lockspaces(void)
|
||||
|
||||
reply = _lvmlockd_send("stop_all",
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = %d", getpid(),
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"opts = %s", opts[0] ? opts : "none",
|
||||
NULL);
|
||||
|
||||
@@ -522,7 +521,7 @@ static int do_kill(void)
|
||||
|
||||
reply = _lvmlockd_send("kill_vg",
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = %d", getpid(),
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", arg_vg_name,
|
||||
NULL);
|
||||
|
||||
@@ -568,7 +567,7 @@ static int do_drop(void)
|
||||
|
||||
reply = _lvmlockd_send("drop_vg",
|
||||
"cmd = %s", "lvmlockctl",
|
||||
"pid = %d", getpid(),
|
||||
"pid = " FMTd64, (int64_t) getpid(),
|
||||
"vg_name = %s", arg_vg_name,
|
||||
NULL);
|
||||
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
#include "daemon-io.h"
|
||||
#include "daemon-server.h"
|
||||
#include "daemon-log.h"
|
||||
#include "lvm-version.h"
|
||||
#include "lvmetad-client.h"
|
||||
#include "lvmlockd-client.h"
|
||||
@@ -742,24 +741,6 @@ static const char *op_str(int x)
|
||||
};
|
||||
}
|
||||
|
||||
static const char *mode_str(int x)
|
||||
{
|
||||
switch (x) {
|
||||
case LD_LK_IV:
|
||||
return "iv";
|
||||
case LD_LK_UN:
|
||||
return "un";
|
||||
case LD_LK_NL:
|
||||
return "nl";
|
||||
case LD_LK_SH:
|
||||
return "sh";
|
||||
case LD_LK_EX:
|
||||
return "ex";
|
||||
default:
|
||||
return ".";
|
||||
};
|
||||
}
|
||||
|
||||
int last_string_from_args(char *args_in, char *last)
|
||||
{
|
||||
const char *args = args_in;
|
||||
@@ -1021,6 +1002,43 @@ static void add_work_action(struct action *act)
|
||||
pthread_mutex_unlock(&worker_mutex);
|
||||
}
|
||||
|
||||
static daemon_reply send_lvmetad(const char *id, ...)
|
||||
{
|
||||
daemon_reply reply;
|
||||
va_list ap;
|
||||
int retries = 0;
|
||||
|
||||
va_start(ap, id);
|
||||
|
||||
/*
|
||||
* mutex is used because all threads share a single
|
||||
* lvmetad connection/handle.
|
||||
*/
|
||||
pthread_mutex_lock(&lvmetad_mutex);
|
||||
retry:
|
||||
reply = daemon_send_simple_v(lvmetad_handle, id, ap);
|
||||
|
||||
/* lvmetad may have been restarted */
|
||||
if ((reply.error == ECONNRESET) && (retries < 2)) {
|
||||
daemon_close(lvmetad_handle);
|
||||
lvmetad_connected = 0;
|
||||
|
||||
lvmetad_handle = lvmetad_open(NULL);
|
||||
if (lvmetad_handle.error || lvmetad_handle.socket_fd < 0) {
|
||||
log_error("lvmetad_open reconnect error %d", lvmetad_handle.error);
|
||||
} else {
|
||||
log_debug("lvmetad reconnected");
|
||||
lvmetad_connected = 1;
|
||||
}
|
||||
retries++;
|
||||
goto retry;
|
||||
}
|
||||
pthread_mutex_unlock(&lvmetad_mutex);
|
||||
|
||||
va_end(ap);
|
||||
return reply;
|
||||
}
|
||||
|
||||
static int res_lock(struct lockspace *ls, struct resource *r, struct action *act, int *retry)
|
||||
{
|
||||
struct lock *lk;
|
||||
@@ -1247,14 +1265,12 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
|
||||
else
|
||||
uuid = ls->vg_uuid;
|
||||
|
||||
pthread_mutex_lock(&lvmetad_mutex);
|
||||
reply = daemon_send_simple(lvmetad_handle, "set_vg_info",
|
||||
"token = %s", "skip",
|
||||
"uuid = %s", uuid,
|
||||
"name = %s", ls->vg_name,
|
||||
"version = %d", (int)new_version,
|
||||
NULL);
|
||||
pthread_mutex_unlock(&lvmetad_mutex);
|
||||
reply = send_lvmetad("set_vg_info",
|
||||
"token = %s", "skip",
|
||||
"uuid = %s", uuid,
|
||||
"name = %s", ls->vg_name,
|
||||
"version = " FMTd64, (int64_t)new_version,
|
||||
NULL);
|
||||
|
||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
|
||||
log_error("set_vg_info in lvmetad failed %d", reply.error);
|
||||
@@ -1267,12 +1283,10 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
|
||||
log_debug("S %s R %s res_lock set lvmetad global invalid",
|
||||
ls->name, r->name);
|
||||
|
||||
pthread_mutex_lock(&lvmetad_mutex);
|
||||
reply = daemon_send_simple(lvmetad_handle, "set_global_info",
|
||||
"token = %s", "skip",
|
||||
"global_invalid = %d", 1,
|
||||
NULL);
|
||||
pthread_mutex_unlock(&lvmetad_mutex);
|
||||
reply = send_lvmetad("set_global_info",
|
||||
"token = %s", "skip",
|
||||
"global_invalid = " FMTd64, INT64_C(1),
|
||||
NULL);
|
||||
|
||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
|
||||
log_error("set_global_info in lvmetad failed %d", reply.error);
|
||||
@@ -1333,7 +1347,7 @@ static int res_convert(struct lockspace *ls, struct resource *r,
|
||||
|
||||
r->last_client_id = act->client_id;
|
||||
|
||||
log_debug("S %s R %s res_convert cl %u mode %d", ls->name, r->name, act->client_id, act->mode);
|
||||
log_debug("S %s R %s res_convert cl %u mode %s", ls->name, r->name, act->client_id, mode_str(act->mode));
|
||||
|
||||
if (act->mode == LD_LK_EX && lk->mode == LD_LK_SH && r->sh_count > 1)
|
||||
return -EAGAIN;
|
||||
@@ -1347,12 +1361,16 @@ static int res_convert(struct lockspace *ls, struct resource *r,
|
||||
r->version++;
|
||||
lk->version = r->version;
|
||||
r_version = r->version;
|
||||
r->version_zero_valid = 0;
|
||||
|
||||
log_debug("S %s R %s res_convert r_version inc %u",
|
||||
ls->name, r->name, r_version);
|
||||
|
||||
} else if ((r->type == LD_RT_VG) && (r->mode == LD_LK_EX) && (lk->version > r->version)) {
|
||||
r->version = lk->version;
|
||||
r_version = r->version;
|
||||
r->version_zero_valid = 0;
|
||||
|
||||
log_debug("S %s R %s res_convert r_version new %u", ls->name, r->name, r_version);
|
||||
} else {
|
||||
r_version = 0;
|
||||
@@ -1547,8 +1565,23 @@ static int res_update(struct lockspace *ls, struct resource *r,
|
||||
|
||||
if (act->flags & LD_AF_NEXT_VERSION)
|
||||
lk->version = r->version + 1;
|
||||
else
|
||||
else {
|
||||
if (r->version >= act->version) {
|
||||
/*
|
||||
* This update is done from vg_write. If the metadata with
|
||||
* this seqno is not committed by vg_commit, then next
|
||||
* vg_write can use the same seqno, causing us to see no
|
||||
* increase in seqno here as expected.
|
||||
* FIXME: In this case, do something like setting the lvb
|
||||
* version to 0 to instead of the same seqno which will
|
||||
* force an invalidation on other hosts. The next change
|
||||
* will return to using the seqno again.
|
||||
*/
|
||||
log_error("S %s R %s res_update cl %u old version %u new version %u too small",
|
||||
ls->name, r->name, act->client_id, r->version, act->version);
|
||||
}
|
||||
lk->version = act->version;
|
||||
}
|
||||
|
||||
log_debug("S %s R %s res_update cl %u lk version to %u", ls->name, r->name, act->client_id, lk->version);
|
||||
|
||||
@@ -3030,6 +3063,7 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||||
int free_count = 0;
|
||||
int done;
|
||||
int stop;
|
||||
int perrno;
|
||||
|
||||
pthread_mutex_lock(&lockspaces_mutex);
|
||||
|
||||
@@ -3072,7 +3106,9 @@ static int for_each_lockspace(int do_stop, int do_free, int do_force)
|
||||
* thread touches the ls struct under lockspaces_mutex.
|
||||
*/
|
||||
if (done) {
|
||||
pthread_join(ls->thread, NULL);
|
||||
if ((perrno = pthread_join(ls->thread, NULL)))
|
||||
log_error("pthread_join error %d", perrno);
|
||||
|
||||
list_del(&ls->list);
|
||||
|
||||
/* FIXME: will free_vg ever not be set? */
|
||||
@@ -3592,12 +3628,15 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
strcat(result_flags, "NO_LOCKSPACES,");
|
||||
pthread_mutex_unlock(&lockspaces_mutex);
|
||||
|
||||
if (gl_use_sanlock && !gl_lsname_sanlock[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
else if (gl_use_dlm && !gl_lsname_dlm[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
else
|
||||
if (gl_use_sanlock) {
|
||||
if (!gl_lsname_sanlock[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
} else if (gl_use_dlm) {
|
||||
if (!gl_lsname_dlm[0])
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
} else {
|
||||
strcat(result_flags, "NO_GL_LS,");
|
||||
}
|
||||
}
|
||||
|
||||
if (act->flags & LD_AF_DUP_GL_LS)
|
||||
@@ -3626,9 +3665,9 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
act->result, vg_args ? vg_args : "", lv_args ? lv_args : "");
|
||||
|
||||
res = daemon_reply_simple("OK",
|
||||
"op = %d", act->op,
|
||||
"op_result = %d", act->result,
|
||||
"lm_result = %d", act->lm_rv,
|
||||
"op = " FMTd64, (int64_t)act->op,
|
||||
"op_result = " FMTd64, (int64_t) act->result,
|
||||
"lm_result = " FMTd64, (int64_t) act->lm_rv,
|
||||
"vg_lock_args = %s", vg_args,
|
||||
"lv_lock_args = %s", lv_args,
|
||||
"result_flags = %s", result_flags[0] ? result_flags : "none",
|
||||
@@ -3657,8 +3696,8 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
act->result, dump_len);
|
||||
|
||||
res = daemon_reply_simple("OK",
|
||||
"result = %d", act->result,
|
||||
"dump_len = %d", dump_len,
|
||||
"result = " FMTd64, (int64_t) act->result,
|
||||
"dump_len = " FMTd64, (int64_t) dump_len,
|
||||
NULL);
|
||||
} else {
|
||||
/*
|
||||
@@ -3671,10 +3710,10 @@ static int client_send_result(struct client *cl, struct action *act)
|
||||
act->result, (act->result == -ENOLS) ? "ENOLS" : "", result_flags);
|
||||
|
||||
res = daemon_reply_simple("OK",
|
||||
"op = %d", act->op,
|
||||
"op = " FMTd64, (int64_t) act->op,
|
||||
"lock_type = %s", lm_str(act->lm_type),
|
||||
"op_result = %d", act->result,
|
||||
"lm_result = %d", act->lm_rv,
|
||||
"op_result = " FMTd64, (int64_t) act->result,
|
||||
"lm_result = " FMTd64, (int64_t) act->lm_rv,
|
||||
"result_flags = %s", result_flags[0] ? result_flags : "none",
|
||||
NULL);
|
||||
}
|
||||
@@ -4401,9 +4440,9 @@ static void client_recv_action(struct client *cl)
|
||||
buffer_init(&res.buffer);
|
||||
|
||||
res = daemon_reply_simple("OK",
|
||||
"result = %d", result,
|
||||
"result = " FMTd64, (int64_t) result,
|
||||
"protocol = %s", lvmlockd_protocol,
|
||||
"version = %d", lvmlockd_protocol_version,
|
||||
"version = " FMTd64, (int64_t) lvmlockd_protocol_version,
|
||||
NULL);
|
||||
buffer_write(cl->fd, &res.buffer);
|
||||
buffer_destroy(&res.buffer);
|
||||
@@ -4742,15 +4781,11 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
|
||||
const char *lock_type;
|
||||
const char *lock_args;
|
||||
char find_str_path[PATH_MAX];
|
||||
int mutex_unlocked = 0;
|
||||
int rv = 0;
|
||||
|
||||
INIT_LIST_HEAD(&update_vgs);
|
||||
|
||||
pthread_mutex_lock(&lvmetad_mutex);
|
||||
reply = daemon_send_simple(lvmetad_handle, "vg_list",
|
||||
"token = %s", "skip",
|
||||
NULL);
|
||||
reply = send_lvmetad("vg_list", "token = %s", "skip", NULL);
|
||||
|
||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
||||
log_error("vg_list from lvmetad failed %d", reply.error);
|
||||
@@ -4787,10 +4822,10 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
|
||||
/* get vg_name and lock_type for each vg uuid entry in update_vgs */
|
||||
|
||||
list_for_each_entry(ls, &update_vgs, list) {
|
||||
reply = daemon_send_simple(lvmetad_handle, "vg_lookup",
|
||||
"token = %s", "skip",
|
||||
"uuid = %s", ls->vg_uuid,
|
||||
NULL);
|
||||
reply = send_lvmetad("vg_lookup",
|
||||
"token = %s", "skip",
|
||||
"uuid = %s", ls->vg_uuid,
|
||||
NULL);
|
||||
|
||||
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
|
||||
log_error("vg_lookup from lvmetad failed %d", reply.error);
|
||||
@@ -4879,8 +4914,6 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
|
||||
if (rv < 0)
|
||||
break;
|
||||
}
|
||||
pthread_mutex_unlock(&lvmetad_mutex);
|
||||
mutex_unlocked = 1;
|
||||
out:
|
||||
/* Return lockd VG's on the vg_lockd list. */
|
||||
|
||||
@@ -4893,9 +4926,6 @@ out:
|
||||
free(ls);
|
||||
}
|
||||
|
||||
if (!mutex_unlocked)
|
||||
pthread_mutex_unlock(&lvmetad_mutex);
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
@@ -5891,7 +5921,7 @@ static int main_loop(daemon_state *ds_arg)
|
||||
close_client_thread();
|
||||
closelog();
|
||||
daemon_close(lvmetad_handle);
|
||||
return 0;
|
||||
return 1; /* libdaemon uses 1 for success */
|
||||
}
|
||||
|
||||
static void usage(char *prog, FILE *file)
|
||||
@@ -5998,7 +6028,7 @@ int main(int argc, char *argv[])
|
||||
else if (lm == LD_LM_SANLOCK && lm_support_sanlock())
|
||||
gl_use_sanlock = 1;
|
||||
else {
|
||||
fprintf(stderr, "invalid gl-type option");
|
||||
fprintf(stderr, "invalid gl-type option\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "tool.h"
|
||||
|
||||
#include "daemon-server.h"
|
||||
#include "daemon-log.h"
|
||||
#include "xlate.h"
|
||||
|
||||
#include "lvmlockd-internal.h"
|
||||
@@ -26,7 +25,6 @@
|
||||
*/
|
||||
#include "libdlm.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
@@ -35,7 +33,6 @@
|
||||
#include <byteswap.h>
|
||||
#include <syslog.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
struct lm_dlm {
|
||||
dlm_lshandle_t *dh;
|
||||
@@ -166,6 +163,9 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls)
|
||||
struct lm_dlm *lmd;
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
goto skip_args;
|
||||
|
||||
memset(sys_clustername, 0, sizeof(sys_clustername));
|
||||
memset(arg_clustername, 0, sizeof(arg_clustername));
|
||||
|
||||
@@ -473,7 +473,11 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
log_debug("S %s R %s lock_dlm", ls->name, r->name);
|
||||
|
||||
if (daemon_test) {
|
||||
memset(vb_out, 0, sizeof(struct val_blk));
|
||||
if (rdd->vb) {
|
||||
vb_out->version = le16_to_cpu(rdd->vb->version);
|
||||
vb_out->flags = le16_to_cpu(rdd->vb->flags);
|
||||
vb_out->r_version = le32_to_cpu(rdd->vb->r_version);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -689,6 +693,9 @@ int lm_hosts_dlm(struct lockspace *ls, int notify)
|
||||
DIR *ls_dir;
|
||||
int count = 0;
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
memset(ls_nodes_path, 0, sizeof(ls_nodes_path));
|
||||
snprintf(ls_nodes_path, PATH_MAX-1, "%s/%s/nodes",
|
||||
DLM_LOCKSPACES_PATH, ls->name);
|
||||
@@ -757,6 +764,9 @@ int lm_is_running_dlm(void)
|
||||
char sys_clustername[MAX_ARGS+1];
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
return gl_use_dlm;
|
||||
|
||||
memset(sys_clustername, 0, sizeof(sys_clustername));
|
||||
|
||||
rv = read_cluster_name(sys_clustername);
|
||||
|
||||
@@ -351,6 +351,23 @@ int lockspaces_empty(void);
|
||||
int last_string_from_args(char *args_in, char *last);
|
||||
int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
|
||||
|
||||
static inline const char *mode_str(int x)
|
||||
{
|
||||
switch (x) {
|
||||
case LD_LK_IV:
|
||||
return "iv";
|
||||
case LD_LK_UN:
|
||||
return "un";
|
||||
case LD_LK_NL:
|
||||
return "nl";
|
||||
case LD_LK_SH:
|
||||
return "sh";
|
||||
case LD_LK_EX:
|
||||
return "ex";
|
||||
default:
|
||||
return ".";
|
||||
};
|
||||
}
|
||||
|
||||
#ifdef LOCKDDLM_SUPPORT
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@
|
||||
#include "tool.h"
|
||||
|
||||
#include "daemon-server.h"
|
||||
#include "daemon-log.h"
|
||||
#include "xlate.h"
|
||||
|
||||
#include "lvmlockd-internal.h"
|
||||
@@ -25,12 +24,10 @@
|
||||
#include "sanlock_admin.h"
|
||||
#include "sanlock_resource.h"
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stddef.h>
|
||||
#include <poll.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
/*
|
||||
-------------------------------------------------------------------------------
|
||||
@@ -205,9 +202,11 @@ int lm_data_size_sanlock(void)
|
||||
*/
|
||||
|
||||
#define LS_BEGIN 0
|
||||
#define GL_LOCK_BEGIN 65
|
||||
#define VG_LOCK_BEGIN 66
|
||||
#define LV_LOCK_BEGIN 67
|
||||
#define GL_LOCK_BEGIN UINT64_C(65)
|
||||
#define VG_LOCK_BEGIN UINT64_C(66)
|
||||
#define LV_LOCK_BEGIN UINT64_C(67)
|
||||
|
||||
static unsigned int daemon_test_lv_count;
|
||||
|
||||
static int lock_lv_name_from_args(char *vg_args, char *lock_lv_name)
|
||||
{
|
||||
@@ -341,6 +340,7 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
|
||||
if (daemon_test) {
|
||||
if (!gl_lsname_sanlock[0])
|
||||
strncpy(gl_lsname_sanlock, ls_name, MAX_NAME);
|
||||
snprintf(vg_args, MAX_ARGS, "%s:%s", lock_args_version, lock_lv_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -492,6 +492,15 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
|
||||
snprintf(lock_args_version, MAX_ARGS, "%u.%u.%u",
|
||||
LV_LOCK_ARGS_MAJOR, LV_LOCK_ARGS_MINOR, LV_LOCK_ARGS_PATCH);
|
||||
|
||||
if (daemon_test) {
|
||||
align_size = 1048576;
|
||||
snprintf(lv_args, MAX_ARGS, "%s:%llu",
|
||||
lock_args_version,
|
||||
(unsigned long long)((align_size * LV_LOCK_BEGIN) + (align_size * daemon_test_lv_count)));
|
||||
daemon_test_lv_count++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy(rd.rs.lockspace_name, ls_name, SANLK_NAME_LEN);
|
||||
rd.rs.num_disks = 1;
|
||||
snprintf(rd.rs.disks[0].path, SANLK_PATH_LEN-1, "/dev/mapper/%s-%s", vg_name, lock_lv_name);
|
||||
@@ -508,12 +517,6 @@ int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name,
|
||||
offset = align_size * LV_LOCK_BEGIN;
|
||||
rd.rs.disks[0].offset = offset;
|
||||
|
||||
if (daemon_test) {
|
||||
snprintf(lv_args, MAX_ARGS, "%s:%llu",
|
||||
lock_args_version, (unsigned long long)1111);
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
rd.rs.disks[0].offset = offset;
|
||||
|
||||
@@ -762,6 +765,9 @@ int lm_ex_disable_gl_sanlock(struct lockspace *ls)
|
||||
struct sanlk_resource **rs_args;
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
rs_args = malloc(2 * sizeof(struct sanlk_resource *));
|
||||
if (!rs_args)
|
||||
return -ENOMEM;
|
||||
@@ -831,6 +837,9 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable)
|
||||
else
|
||||
gl_name = R_NAME_GL_DISABLED;
|
||||
|
||||
if (daemon_test)
|
||||
goto out;
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
|
||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
@@ -846,7 +855,7 @@ int lm_able_gl_sanlock(struct lockspace *ls, int enable)
|
||||
ls->name, enable, rv, rd.rs.disks[0].path);
|
||||
return rv;
|
||||
}
|
||||
|
||||
out:
|
||||
log_debug("S %s able_gl %s", ls->name, gl_name);
|
||||
|
||||
ls->sanlock_gl_enabled = enable;
|
||||
@@ -867,6 +876,9 @@ static int gl_is_enabled(struct lockspace *ls, struct lm_sanlock *lms)
|
||||
uint64_t offset;
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
return 1;
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
|
||||
strncpy(rd.rs.lockspace_name, ls->name, SANLK_NAME_LEN);
|
||||
@@ -925,8 +937,10 @@ int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
|
||||
uint64_t offset;
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
if (daemon_test) {
|
||||
*free_offset = (1048576 * LV_LOCK_BEGIN) + (1048576 * (daemon_test_lv_count + 1));
|
||||
return 0;
|
||||
}
|
||||
|
||||
memset(&rd, 0, sizeof(rd));
|
||||
|
||||
@@ -1175,6 +1189,11 @@ int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
int rv;
|
||||
|
||||
if (daemon_test) {
|
||||
sleep(2);
|
||||
goto out;
|
||||
}
|
||||
|
||||
rv = sanlock_add_lockspace_timeout(&lms->ss, 0, sanlock_io_timeout);
|
||||
if (rv == -EEXIST && adopt) {
|
||||
/* We could alternatively just skip the sanlock call for adopt. */
|
||||
@@ -1243,10 +1262,10 @@ int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
|
||||
ls->name, rv, lms->ss.host_id_disk.path);
|
||||
}
|
||||
}
|
||||
out:
|
||||
|
||||
if (close(lms->sock))
|
||||
log_error("failed to close sanlock daemon socket connection");
|
||||
|
||||
out:
|
||||
free(lms);
|
||||
ls->lm_data = NULL;
|
||||
|
||||
@@ -1305,6 +1324,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
|
||||
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
|
||||
struct sanlk_resource *rs;
|
||||
struct sanlk_options opt;
|
||||
uint64_t lock_lv_offset;
|
||||
uint32_t flags = 0;
|
||||
struct val_blk vb;
|
||||
@@ -1378,12 +1398,16 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
|
||||
rs->flags |= SANLK_RES_PERSISTENT;
|
||||
|
||||
log_debug("S %s R %s lock_san acquire %s:%llu",
|
||||
ls->name, r->name, rs->disks[0].path,
|
||||
log_debug("S %s R %s lock_san %s at %s:%llu",
|
||||
ls->name, r->name, mode_str(ld_mode), rs->disks[0].path,
|
||||
(unsigned long long)rs->disks[0].offset);
|
||||
|
||||
if (daemon_test) {
|
||||
memset(vb_out, 0, sizeof(struct val_blk));
|
||||
if (rds->vb) {
|
||||
vb_out->version = le16_to_cpu(rds->vb->version);
|
||||
vb_out->flags = le16_to_cpu(rds->vb->flags);
|
||||
vb_out->r_version = le32_to_cpu(rds->vb->r_version);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1401,7 +1425,10 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
|
||||
flags |= SANLK_ACQUIRE_OWNER_NOWAIT;
|
||||
#endif
|
||||
|
||||
rv = sanlock_acquire(lms->sock, -1, flags, 1, &rs, NULL);
|
||||
memset(&opt, 0, sizeof(opt));
|
||||
sprintf(opt.owner_name, "%s", "lvmlockd");
|
||||
|
||||
rv = sanlock_acquire(lms->sock, -1, flags, 1, &rs, &opt);
|
||||
|
||||
if (rv == -EAGAIN) {
|
||||
/*
|
||||
@@ -1561,7 +1588,8 @@ int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
|
||||
uint32_t flags = 0;
|
||||
int rv;
|
||||
|
||||
log_debug("S %s R %s convert_san", ls->name, r->name);
|
||||
log_debug("S %s R %s convert_san %s to %s",
|
||||
ls->name, r->name, mode_str(r->mode), mode_str(ld_mode));
|
||||
|
||||
if (daemon_test)
|
||||
goto rs_flag;
|
||||
@@ -1665,11 +1693,18 @@ int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
|
||||
struct val_blk vb;
|
||||
int rv;
|
||||
|
||||
log_debug("S %s R %s unlock_san r_version %u flags %x",
|
||||
ls->name, r->name, r_version, lmu_flags);
|
||||
log_debug("S %s R %s unlock_san %s r_version %u flags %x",
|
||||
ls->name, r->name, mode_str(r->mode), r_version, lmu_flags);
|
||||
|
||||
if (daemon_test)
|
||||
if (daemon_test) {
|
||||
if (rds->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||
if (!rds->vb->version)
|
||||
rds->vb->version = cpu_to_le16(VAL_BLK_VERSION);
|
||||
if (r_version)
|
||||
rds->vb->r_version = cpu_to_le32(r_version);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rds->vb && r_version && (r->mode == LD_LK_EX)) {
|
||||
if (!rds->vb->version) {
|
||||
@@ -1719,6 +1754,9 @@ int lm_hosts_sanlock(struct lockspace *ls, int notify)
|
||||
int found_others = 0;
|
||||
int i, rv;
|
||||
|
||||
if (daemon_test)
|
||||
return 0;
|
||||
|
||||
rv = sanlock_get_hosts(ls->name, 0, &hss, &hss_count, 0);
|
||||
if (rv < 0) {
|
||||
log_error("S %s hosts_san get_hosts error %d", ls->name, rv);
|
||||
@@ -1818,6 +1856,9 @@ int lm_is_running_sanlock(void)
|
||||
uint32_t daemon_proto;
|
||||
int rv;
|
||||
|
||||
if (daemon_test)
|
||||
return gl_use_sanlock;
|
||||
|
||||
rv = sanlock_version(0, &daemon_version, &daemon_proto);
|
||||
if (rv < 0)
|
||||
return 0;
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lvmpolld-common.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_LVMPOLLD_CMD_UTILS_H
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lvmpolld-common.h"
|
||||
@@ -539,7 +539,7 @@ static response progress_info(client_handle h, struct lvmpolld_state *ls, reques
|
||||
if (st.polling_finished)
|
||||
r = daemon_reply_simple(LVMPD_RESP_FINISHED,
|
||||
"reason = %s", st.cmd_state.signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE,
|
||||
LVMPD_PARM_VALUE " = %d", (int64_t)(st.cmd_state.signal ?: st.cmd_state.retcode),
|
||||
LVMPD_PARM_VALUE " = " FMTd64, (int64_t)(st.cmd_state.signal ?: st.cmd_state.retcode),
|
||||
NULL);
|
||||
else
|
||||
r = daemon_reply_simple(LVMPD_RESP_IN_PROGRESS, NULL);
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lvmpolld-common.h"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_LVMPOLLD_PROTOCOL_H
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_TOOL_POLLING_OPS_H
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lvm2cmd.h"
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
@top_srcdir@/daemons/clvmd/clvm.h
|
||||
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
|
||||
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
|
||||
@top_srcdir@/daemons/lvmlockd/lvmlockd-client.h
|
||||
@top_srcdir@/daemons/lvmpolld/lvmpolld-protocol.h
|
||||
@top_srcdir@/daemons/lvmpolld/polling_ops.h
|
||||
@top_srcdir@/daemons/lvmlockd/lvmlockd-client.h
|
||||
@top_srcdir@/liblvm/lvm2app.h
|
||||
@top_srcdir@/lib/activate/activate.h
|
||||
@top_srcdir@/lib/activate/targets.h
|
||||
@top_srcdir@/lib/cache/lvmcache.h
|
||||
@top_srcdir@/lib/cache/lvmetad.h
|
||||
@top_srcdir@/lib/locking/lvmlockd.h
|
||||
@top_srcdir@/lib/commands/toolcontext.h
|
||||
@top_srcdir@/lib/config/config.h
|
||||
@top_srcdir@/lib/config/config_settings.h
|
||||
@@ -19,8 +17,8 @@
|
||||
@top_srcdir@/lib/device/dev-cache.h
|
||||
@top_srcdir@/lib/device/dev-ext-udev-constants.h
|
||||
@top_srcdir@/lib/device/dev-type.h
|
||||
@top_srcdir@/lib/device/device.h
|
||||
@top_srcdir@/lib/device/device-types.h
|
||||
@top_srcdir@/lib/device/device.h
|
||||
@top_srcdir@/lib/display/display.h
|
||||
@top_srcdir@/lib/filters/filter.h
|
||||
@top_srcdir@/lib/format1/format1.h
|
||||
@@ -31,20 +29,19 @@
|
||||
@top_srcdir@/lib/format_text/text_import.h
|
||||
@top_srcdir@/lib/label/label.h
|
||||
@top_srcdir@/lib/locking/locking.h
|
||||
@top_srcdir@/lib/locking/lvmlockd.h
|
||||
@top_srcdir@/lib/log/log.h
|
||||
@top_srcdir@/lib/log/lvm-logging.h
|
||||
@top_srcdir@/lib/lvmpolld/lvmpolld-client.h
|
||||
@top_srcdir@/lib/lvmpolld/polldaemon.h
|
||||
@top_srcdir@/lib/metadata/lv.h
|
||||
@top_srcdir@/lib/metadata/lv_alloc.h
|
||||
@top_srcdir@/lib/metadata/metadata.h
|
||||
@top_srcdir@/lib/metadata/metadata-exported.h
|
||||
@top_srcdir@/lib/metadata/metadata.h
|
||||
@top_srcdir@/lib/metadata/pv.h
|
||||
@top_srcdir@/lib/metadata/pv_alloc.h
|
||||
@top_srcdir@/lib/metadata/segtype.h
|
||||
@top_srcdir@/lib/metadata/vg.h
|
||||
@top_srcdir@/lib/mm/memlock.h
|
||||
@top_srcdir@/lib/mm/xlate.h
|
||||
@top_srcdir@/lib/misc/crc.h
|
||||
@top_srcdir@/lib/misc/intl.h
|
||||
@top_srcdir@/lib/misc/last-path-component.h
|
||||
@@ -53,25 +50,28 @@
|
||||
@top_srcdir@/lib/misc/lvm-file.h
|
||||
@top_srcdir@/lib/misc/lvm-flock.h
|
||||
@top_srcdir@/lib/misc/lvm-globals.h
|
||||
@top_srcdir@/lib/misc/lvm-percent.h
|
||||
@top_srcdir@/lib/misc/lvm-signal.h
|
||||
@top_srcdir@/lib/misc/lvm-string.h
|
||||
@top_srcdir@/lib/misc/lvm-percent.h
|
||||
@top_srcdir@/lib/misc/lvm-wrappers.h
|
||||
@top_srcdir@/lib/misc/sharedlib.h
|
||||
@top_srcdir@/lib/misc/util.h
|
||||
@top_srcdir@/lib/mm/memlock.h
|
||||
@top_srcdir@/lib/mm/xlate.h
|
||||
@top_srcdir@/lib/properties/prop_common.h
|
||||
@top_srcdir@/lib/report/properties.h
|
||||
@top_srcdir@/lib/report/report.h
|
||||
@top_srcdir@/lib/uuid/uuid.h
|
||||
@top_srcdir@/libdaemon/client/config-util.h
|
||||
@top_srcdir@/libdaemon/client/daemon-client.h
|
||||
@top_srcdir@/libdaemon/client/daemon-io.h
|
||||
@top_srcdir@/libdaemon/client/config-util.h
|
||||
@top_srcdir@/libdm/libdevmapper.h
|
||||
@top_srcdir@/libdm/misc/dm-ioctl.h
|
||||
@top_srcdir@/libdm/misc/dm-logging.h
|
||||
@top_srcdir@/libdm/misc/dm-log-userspace.h
|
||||
@top_srcdir@/libdm/misc/dm-logging.h
|
||||
@top_srcdir@/libdm/misc/dmlib.h
|
||||
@top_srcdir@/libdm/misc/kdev_t.h
|
||||
@top_srcdir@/liblvm/lvm2app.h
|
||||
@top_srcdir@/po/pogen.h
|
||||
@top_srcdir@/tools/lvm2cmd.h
|
||||
@top_srcdir@/tools/tool.h
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -258,6 +258,9 @@
|
||||
/* Define to 1 if you have the <libintl.h> header file. */
|
||||
#undef HAVE_LIBINTL_H
|
||||
|
||||
/* Define to 1 if udev_device_get_is_initialized is available. */
|
||||
#undef HAVE_LIBUDEV_UDEV_DEVICE_GET_IS_INITIALIZED
|
||||
|
||||
/* Define to 1 if you have the <limits.h> header file. */
|
||||
#undef HAVE_LIMITS_H
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_VERSION_H
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -118,8 +118,8 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
|
||||
|
||||
config_def_get_path(config_path, sizeof(config_path), cfg_id);
|
||||
log_verbose("%s configuration setting defined: "
|
||||
"Checking the list to match %s/%s",
|
||||
config_path, lv->vg->name, lv->name);
|
||||
"Checking the list to match %s.",
|
||||
config_path, display_lvname(lv));
|
||||
|
||||
for (cv = cn->v; cv; cv = cv->next) {
|
||||
if (cv->type == DM_CFG_EMPTY_ARRAY)
|
||||
@@ -170,8 +170,8 @@ static int _lv_passes_volumes_filter(struct cmd_context *cmd, const struct logic
|
||||
}
|
||||
|
||||
out:
|
||||
log_verbose("No item supplied in %s configuration setting "
|
||||
"matches %s/%s", config_path, lv->vg->name, lv->name);
|
||||
log_verbose("No item supplied in %s configuration setting matches %s.",
|
||||
config_path, display_lvname(lv));
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -333,7 +333,7 @@ int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
|
||||
}
|
||||
*******/
|
||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
||||
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
|
||||
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
@@ -389,6 +389,10 @@ int lv_is_active_locally(const struct logical_volume *lv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_is_active_remotely(const struct logical_volume *lv)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
int lv_is_active_but_not_locally(const struct logical_volume *lv)
|
||||
{
|
||||
return 0;
|
||||
@@ -469,8 +473,8 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
||||
|
||||
if (!(cn = find_config_tree_array(cmd, activation_volume_list_CFG, NULL))) {
|
||||
log_verbose("activation/volume_list configuration setting "
|
||||
"not defined: Checking only host tags for %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
"not defined: Checking only host tags for %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
/* If no host tags defined, activate */
|
||||
if (dm_list_empty(&cmd->tags))
|
||||
@@ -481,8 +485,7 @@ static int _passes_activation_filter(struct cmd_context *cmd,
|
||||
str_list_match_list(&cmd->tags, &lv->vg->tags, NULL))
|
||||
return 1;
|
||||
|
||||
log_verbose("No host tag matches %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_verbose("No host tag matches %s", display_lvname(lv));
|
||||
|
||||
/* Don't activate */
|
||||
return 0;
|
||||
@@ -771,14 +774,14 @@ int lv_check_not_in_use(const struct logical_volume *lv)
|
||||
/* If sysfs is not used, use open_count information only. */
|
||||
if (dm_sysfs_dir()) {
|
||||
if (dm_device_has_holders(info.major, info.minor)) {
|
||||
log_error("Logical volume %s/%s is used by another device.",
|
||||
lv->vg->name, lv->name);
|
||||
log_error("Logical volume %s is used by another device.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dm_device_has_mounted_fs(info.major, info.minor)) {
|
||||
log_error("Logical volume %s/%s contains a filesystem in use.",
|
||||
lv->vg->name, lv->name);
|
||||
log_error("Logical volume %s contains a filesystem in use.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -786,14 +789,14 @@ int lv_check_not_in_use(const struct logical_volume *lv)
|
||||
open_count_check_retries = retry_deactivation() ? OPEN_COUNT_CHECK_RETRIES : 1;
|
||||
while (info.open_count > 0 && open_count_check_retries--) {
|
||||
if (!open_count_check_retries) {
|
||||
log_error("Logical volume %s/%s in use.",
|
||||
lv->vg->name, lv->name);
|
||||
log_error("Logical volume %s in use.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
usleep(OPEN_COUNT_CHECK_USLEEP_DELAY);
|
||||
log_debug_activation("Retrying open_count check for %s/%s.",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Retrying open_count check for %s.",
|
||||
display_lvname(lv));
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, &info, 1, 0)) {
|
||||
stack; /* device dissappeared? */
|
||||
break;
|
||||
@@ -814,7 +817,8 @@ int lv_check_transient(struct logical_volume *lv)
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking transient status for LV %s/%s", lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking transient status for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -838,7 +842,8 @@ int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent)
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking snapshot percent for LV %s/%s", lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking snapshot percent for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -868,7 +873,8 @@ int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
|
||||
if (!lv_info(cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking mirror percent for LV %s/%s", lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking mirror percent for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -897,8 +903,8 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health)
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking raid device health for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking raid device health for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -925,8 +931,8 @@ int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt)
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking raid mismatch count for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking raid mismatch count for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -953,8 +959,8 @@ int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action)
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking raid sync_action for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking raid sync_action for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -990,12 +996,12 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
(lv_is_raid(seg_lv(first_seg(lv), 0)) ||
|
||||
lv_is_raid(first_seg(lv)->metadata_lv))) {
|
||||
log_error("Thin pool data or metadata volume "
|
||||
"must be specified. (E.g. \"%s/%s_tdata\")",
|
||||
lv->vg->name, lv->name);
|
||||
"must be specified. (E.g. \"%s_tdata\")",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
log_error("%s/%s must be a RAID logical volume to"
|
||||
" perform this action.", lv->vg->name, lv->name);
|
||||
log_error("%s must be a RAID logical volume to perform this action.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1008,8 +1014,8 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
return_0;
|
||||
|
||||
if (!(r = dev_manager_raid_status(dm, lv, &status))) {
|
||||
log_error("Failed to retrieve status of %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_error("Failed to retrieve status of %s.",
|
||||
display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1036,8 +1042,8 @@ int lv_raid_message(const struct logical_volume *lv, const char *msg)
|
||||
goto out;
|
||||
}
|
||||
if (strcmp(status->sync_action, "idle")) {
|
||||
log_error("%s/%s state is currently \"%s\". Unable to switch to \"%s\".",
|
||||
lv->vg->name, lv->name, status->sync_action, msg);
|
||||
log_error("%s state is currently \"%s\". Unable to switch to \"%s\".",
|
||||
display_lvname(lv), status->sync_action, msg);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1101,8 +1107,8 @@ int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
|
||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking thin %sdata percent for LV %s/%s",
|
||||
(metadata) ? "meta" : "", lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking thin %sdata percent for LV %s.",
|
||||
(metadata) ? "meta" : "", display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -1127,8 +1133,8 @@ int lv_thin_percent(const struct logical_volume *lv,
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking thin percent for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking thin percent for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -1154,8 +1160,8 @@ int lv_thin_pool_transaction_id(const struct logical_volume *lv,
|
||||
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking thin percent for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking thin percent for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -1178,8 +1184,8 @@ int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id)
|
||||
if (!lv_info(lv->vg->cmd, lv, 0, NULL, 0, 0))
|
||||
return 0;
|
||||
|
||||
log_debug_activation("Checking device id for LV %s/%s",
|
||||
lv->vg->name, lv->name);
|
||||
log_debug_activation("Checking device id for LV %s.",
|
||||
display_lvname(lv));
|
||||
|
||||
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
|
||||
return_0;
|
||||
@@ -1332,12 +1338,14 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
||||
* _lv_is_active
|
||||
* @lv: logical volume being queried
|
||||
* @locally: set if active locally (when provided)
|
||||
* @remotely: set if active remotely (when provided)
|
||||
* @exclusive: set if active exclusively (when provided)
|
||||
*
|
||||
* Determine whether an LV is active locally or in a cluster.
|
||||
* In addition to the return code which indicates whether or
|
||||
* not the LV is active somewhere, two other values are set
|
||||
* to yield more information about the status of the activation:
|
||||
*
|
||||
* return locally exclusively status
|
||||
* ====== ======= =========== ======
|
||||
* 0 0 0 not active
|
||||
@@ -1350,9 +1358,10 @@ int lvs_in_vg_opened(const struct volume_group *vg)
|
||||
* Returns: 0 or 1
|
||||
*/
|
||||
static int _lv_is_active(const struct logical_volume *lv,
|
||||
int *locally, int *exclusive)
|
||||
int *locally, int *remotely, int *exclusive)
|
||||
{
|
||||
int r, l, e; /* remote, local, and exclusive */
|
||||
int skip_cluster_query = 0;
|
||||
|
||||
r = l = e = 0;
|
||||
|
||||
@@ -1365,11 +1374,14 @@ static int _lv_is_active(const struct logical_volume *lv,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Active locally, and the caller doesn't care about exclusive */
|
||||
if (l && !exclusive)
|
||||
/* Active locally, and the caller doesn't care about exclusive or remotely */
|
||||
if (l && !exclusive && !remotely)
|
||||
skip_cluster_query = 1;
|
||||
|
||||
if (skip_cluster_query)
|
||||
goto out;
|
||||
|
||||
if ((r = remote_lock_held(lv->lvid.s, &e)) >= 0)
|
||||
if ((r = cluster_lock_held(lv->lvid.s, "", &e)) >= 0)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
@@ -1381,10 +1393,13 @@ static int _lv_is_active(const struct logical_volume *lv,
|
||||
* New users of this function who specifically ask for 'exclusive'
|
||||
* will be given an error message.
|
||||
*/
|
||||
log_error("Unable to determine exclusivity of %s", lv->name);
|
||||
log_error("Unable to determine exclusivity of %s.", display_lvname(lv));
|
||||
|
||||
e = 0;
|
||||
|
||||
/* Also set remotely as a precaution, as we don't know */
|
||||
r = 1;
|
||||
|
||||
/*
|
||||
* We used to attempt activate_lv_excl_local(lv->vg->cmd, lv) here,
|
||||
* but it's unreliable.
|
||||
@@ -1395,53 +1410,65 @@ out:
|
||||
*locally = l;
|
||||
if (exclusive)
|
||||
*exclusive = e;
|
||||
if (remotely)
|
||||
*remotely = r;
|
||||
|
||||
log_very_verbose("%s/%s is %sactive%s%s",
|
||||
lv->vg->name, lv->name,
|
||||
log_very_verbose("%s is %sactive%s%s%s%s",
|
||||
display_lvname(lv),
|
||||
(r || l) ? "" : "not ",
|
||||
(exclusive && e) ? " exclusive" : "",
|
||||
e ? (l ? " locally" : " remotely") : "");
|
||||
l ? " locally" : "",
|
||||
(!skip_cluster_query && l && r) ? " and" : "",
|
||||
(!skip_cluster_query && r) ? " remotely" : "");
|
||||
|
||||
return r || l;
|
||||
}
|
||||
|
||||
int lv_is_active(const struct logical_volume *lv)
|
||||
{
|
||||
return _lv_is_active(lv, NULL, NULL);
|
||||
return _lv_is_active(lv, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
int lv_is_active_locally(const struct logical_volume *lv)
|
||||
{
|
||||
int l;
|
||||
|
||||
return _lv_is_active(lv, &l, NULL) && l;
|
||||
return _lv_is_active(lv, &l, NULL, NULL) && l;
|
||||
}
|
||||
|
||||
int lv_is_active_remotely(const struct logical_volume *lv)
|
||||
{
|
||||
int r;
|
||||
|
||||
return _lv_is_active(lv, NULL, &r, NULL) && r;
|
||||
}
|
||||
|
||||
int lv_is_active_but_not_locally(const struct logical_volume *lv)
|
||||
{
|
||||
int l;
|
||||
return _lv_is_active(lv, &l, NULL) && !l;
|
||||
|
||||
return _lv_is_active(lv, &l, NULL, NULL) && !l;
|
||||
}
|
||||
|
||||
int lv_is_active_exclusive(const struct logical_volume *lv)
|
||||
{
|
||||
int e;
|
||||
|
||||
return _lv_is_active(lv, NULL, &e) && e;
|
||||
return _lv_is_active(lv, NULL, NULL, &e) && e;
|
||||
}
|
||||
|
||||
int lv_is_active_exclusive_locally(const struct logical_volume *lv)
|
||||
{
|
||||
int l, e;
|
||||
|
||||
return _lv_is_active(lv, &l, &e) && l && e;
|
||||
return _lv_is_active(lv, &l, NULL, &e) && l && e;
|
||||
}
|
||||
|
||||
int lv_is_active_exclusive_remotely(const struct logical_volume *lv)
|
||||
{
|
||||
int l, e;
|
||||
|
||||
return _lv_is_active(lv, &l, &e) && !l && e;
|
||||
return _lv_is_active(lv, &l, NULL, &e) && !l && e;
|
||||
}
|
||||
|
||||
#ifdef DMEVENTD
|
||||
@@ -1606,14 +1633,14 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
if (laopts->skip_in_use && lv_is_thin_pool(lv) &&
|
||||
lv_info(lv->vg->cmd, lv, 1, &info, 1, 0) && (info.open_count > 1)) {
|
||||
log_debug_activation("Skipping unmonitor of opened %s (open:%d)",
|
||||
lv->name, info.open_count);
|
||||
display_lvname(lv), info.open_count);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Do not monitor snapshot that already covers origin */
|
||||
if (monitor && lv_is_cow_covering_origin(lv)) {
|
||||
log_debug_activation("Skipping monitor of snapshot larger "
|
||||
"then origin %s.", lv->name);
|
||||
"then origin %s.", display_lvname(lv));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1661,7 +1688,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
monitor)) {
|
||||
log_error("Failed to %smonitor %s",
|
||||
monitor ? "" : "un",
|
||||
seg_lv(seg, s)->name);
|
||||
display_lvname(seg_lv(seg, s)));
|
||||
r = 0;
|
||||
}
|
||||
}
|
||||
@@ -1698,12 +1725,12 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
|
||||
if (monitor) {
|
||||
if (monitored)
|
||||
log_verbose("%s/%s already monitored.", lv->vg->name, lv->name);
|
||||
log_verbose("%s already monitored.", display_lvname(lv));
|
||||
else if (seg->segtype->ops->target_monitor_events)
|
||||
monitor_fn = seg->segtype->ops->target_monitor_events;
|
||||
} else {
|
||||
if (!monitored)
|
||||
log_verbose("%s/%s already not monitored.", lv->vg->name, lv->name);
|
||||
log_verbose("%s already not monitored.", display_lvname(lv));
|
||||
else if (seg->segtype->ops->target_unmonitor_events)
|
||||
monitor_fn = seg->segtype->ops->target_unmonitor_events;
|
||||
}
|
||||
@@ -1712,7 +1739,7 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
if (!monitor_fn)
|
||||
continue;
|
||||
|
||||
log_verbose("%sonitoring %s/%s%s", monitor ? "M" : "Not m", lv->vg->name, lv->name,
|
||||
log_verbose("%sonitoring %s%s", monitor ? "M" : "Not m", display_lvname(lv),
|
||||
test_mode() ? " [Test mode: skipping this]" : "");
|
||||
|
||||
/* FIXME Test mode should really continue a bit further. */
|
||||
@@ -1721,8 +1748,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
|
||||
/* FIXME specify events */
|
||||
if (!monitor_fn(seg, 0)) {
|
||||
log_error("%s/%s: %s segment monitoring function failed.",
|
||||
lv->vg->name, lv->name, seg->segtype->name);
|
||||
log_error("%s: %s segment monitoring function failed.",
|
||||
display_lvname(lv), seg->segtype->name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1734,8 +1761,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
if (pending ||
|
||||
(!monitored && monitor) ||
|
||||
(monitored && !monitor))
|
||||
log_very_verbose("%s/%s %smonitoring still pending: waiting...",
|
||||
lv->vg->name, lv->name, monitor ? "" : "un");
|
||||
log_very_verbose("%s %smonitoring still pending: waiting...",
|
||||
display_lvname(lv), monitor ? "" : "un");
|
||||
else
|
||||
break;
|
||||
usleep(10000 * i);
|
||||
@@ -1746,8 +1773,8 @@ int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume
|
||||
}
|
||||
|
||||
if (!r && !error_message_produced())
|
||||
log_error("%sonitoring %s/%s failed.", monitor ? "M" : "Not m",
|
||||
lv->vg->name, lv->name);
|
||||
log_error("%sonitoring %s failed.", monitor ? "M" : "Not m",
|
||||
display_lvname(lv));
|
||||
return r;
|
||||
#else
|
||||
return 1;
|
||||
@@ -1763,25 +1790,28 @@ struct detached_lv_data {
|
||||
static int _preload_detached_lv(struct logical_volume *lv, void *data)
|
||||
{
|
||||
struct detached_lv_data *detached = data;
|
||||
struct lv_list *lvl_pre;
|
||||
struct logical_volume *lv_pre;
|
||||
|
||||
/* Check and preload removed raid image leg or metadata */
|
||||
if (lv_is_raid_image(lv)) {
|
||||
if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
||||
!lv_is_raid_image(lvl_pre->lv) && lv_is_active(lv) &&
|
||||
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
|
||||
if ((lv_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
||||
!lv_is_raid_image(lv_pre) && lv_is_active(lv) &&
|
||||
!_lv_preload(lv_pre, detached->laopts, detached->flush_required))
|
||||
return_0;
|
||||
} else if (lv_is_raid_metadata(lv)) {
|
||||
if ((lvl_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
||||
!lv_is_raid_metadata(lvl_pre->lv) && lv_is_active(lv) &&
|
||||
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
|
||||
if ((lv_pre = find_lv_in_vg_by_lvid(detached->lv_pre->vg, &lv->lvid)) &&
|
||||
!lv_is_raid_metadata(lv_pre) && lv_is_active(lv) &&
|
||||
!_lv_preload(lv_pre, detached->laopts, detached->flush_required))
|
||||
return_0;
|
||||
}
|
||||
|
||||
if ((lvl_pre = find_lv_in_vg(detached->lv_pre->vg, lv->name))) {
|
||||
if (lv_is_visible(lvl_pre->lv) && lv_is_active(lv) &&
|
||||
(!lv_is_cow(lv) || !lv_is_cow(lvl_pre->lv)) &&
|
||||
!_lv_preload(lvl_pre->lv, detached->laopts, detached->flush_required))
|
||||
/* FIXME: condition here should be far more limiting to really
|
||||
* detect detached LVs */
|
||||
if ((lv_pre = find_lv(detached->lv_pre->vg, lv->name))) {
|
||||
if (lv_is_visible(lv_pre) && lv_is_active(lv) &&
|
||||
!lv_is_pool(lv) &&
|
||||
(!lv_is_cow(lv) || !lv_is_cow(lv_pre)) &&
|
||||
!_lv_preload(lv_pre, detached->laopts, detached->flush_required))
|
||||
return_0;
|
||||
}
|
||||
|
||||
@@ -1790,12 +1820,12 @@ static int _preload_detached_lv(struct logical_volume *lv, void *data)
|
||||
|
||||
static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lv_activate_opts *laopts, int error_if_not_suspended,
|
||||
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
|
||||
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||
{
|
||||
const struct logical_volume *pvmove_lv = NULL;
|
||||
const struct logical_volume *ondisk_lv_to_free = NULL;
|
||||
const struct logical_volume *incore_lv_to_free = NULL;
|
||||
struct lv_list *lvl_pre;
|
||||
const struct logical_volume *lv_to_free = NULL;
|
||||
const struct logical_volume *lv_pre_to_free = NULL;
|
||||
struct logical_volume *lv_pre_tmp;
|
||||
struct seg_list *sl;
|
||||
struct lv_segment *snap_seg;
|
||||
struct lvinfo info;
|
||||
@@ -1805,27 +1835,28 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (!activation())
|
||||
return 1;
|
||||
|
||||
if (!ondisk_lv && !(ondisk_lv_to_free = ondisk_lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
/* lv comes from committed metadata */
|
||||
if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
goto_out;
|
||||
|
||||
/* Use precommitted metadata if present */
|
||||
if (!incore_lv && !(incore_lv_to_free = incore_lv = lv_from_lvid(cmd, lvid_s, 1)))
|
||||
if (!lv_pre && !(lv_pre_to_free = lv_pre = lv_from_lvid(cmd, lvid_s, 1)))
|
||||
goto_out;
|
||||
|
||||
/* Ignore origin_only unless LV is origin in both old and new metadata */
|
||||
/* or LV is thin or thin pool volume */
|
||||
if (!lv_is_thin_volume(ondisk_lv) && !lv_is_thin_pool(ondisk_lv) &&
|
||||
!(lv_is_origin(ondisk_lv) && lv_is_origin(incore_lv)))
|
||||
if (!lv_is_thin_volume(lv) && !lv_is_thin_pool(lv) &&
|
||||
!(lv_is_origin(lv) && lv_is_origin(lv_pre)))
|
||||
laopts->origin_only = 0;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Suspending %s%s.", ondisk_lv->name,
|
||||
_skip("Suspending %s%s.", display_lvname(lv),
|
||||
laopts->origin_only ? " origin without snapshots" : "");
|
||||
r = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!lv_info(cmd, ondisk_lv, laopts->origin_only, &info, 0, 0))
|
||||
if (!lv_info(cmd, lv, laopts->origin_only, &info, 0, 0))
|
||||
goto_out;
|
||||
|
||||
if (!info.exists || info.suspended) {
|
||||
@@ -1837,10 +1868,10 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!lv_read_replicator_vgs(ondisk_lv))
|
||||
if (!lv_read_replicator_vgs(lv))
|
||||
goto_out;
|
||||
|
||||
lv_calculate_readahead(ondisk_lv, NULL);
|
||||
lv_calculate_readahead(lv, NULL);
|
||||
|
||||
/*
|
||||
* Preload devices for the LV.
|
||||
@@ -1849,58 +1880,60 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
* tables for all the changed LVs here, as the relationships
|
||||
* are not found by walking the new metadata.
|
||||
*/
|
||||
if (!lv_is_locked(incore_lv) &&
|
||||
lv_is_locked(ondisk_lv) &&
|
||||
(pvmove_lv = find_pvmove_lv_in_lv(ondisk_lv))) {
|
||||
if (lv_is_locked(lv) && !lv_is_locked(lv_pre) &&
|
||||
(pvmove_lv = find_pvmove_lv_in_lv(lv))) {
|
||||
/* Preload all the LVs above the PVMOVE LV */
|
||||
dm_list_iterate_items(sl, &pvmove_lv->segs_using_this_lv) {
|
||||
if (!(lvl_pre = find_lv_in_vg(incore_lv->vg, sl->seg->lv->name))) {
|
||||
log_error(INTERNAL_ERROR "LV %s missing from preload metadata", sl->seg->lv->name);
|
||||
if (!(lv_pre_tmp = find_lv(lv_pre->vg, sl->seg->lv->name))) {
|
||||
log_error(INTERNAL_ERROR "LV %s missing from preload metadata.",
|
||||
display_lvname(sl->seg->lv));
|
||||
goto out;
|
||||
}
|
||||
if (!_lv_preload(lvl_pre->lv, laopts, &flush_required))
|
||||
if (!_lv_preload(lv_pre_tmp, laopts, &flush_required))
|
||||
goto_out;
|
||||
}
|
||||
/* Now preload the PVMOVE LV itself */
|
||||
if (!(lvl_pre = find_lv_in_vg(incore_lv->vg, pvmove_lv->name))) {
|
||||
log_error(INTERNAL_ERROR "LV %s missing from preload metadata", pvmove_lv->name);
|
||||
if (!(lv_pre_tmp = find_lv(lv_pre->vg, pvmove_lv->name))) {
|
||||
log_error(INTERNAL_ERROR "LV %s missing from preload metadata.",
|
||||
display_lvname(pvmove_lv));
|
||||
goto out;
|
||||
}
|
||||
if (!_lv_preload(lvl_pre->lv, laopts, &flush_required))
|
||||
if (!_lv_preload(lv_pre_tmp, laopts, &flush_required))
|
||||
goto_out;
|
||||
} else {
|
||||
if (!_lv_preload(incore_lv, laopts, &flush_required))
|
||||
if (!_lv_preload(lv_pre, laopts, &flush_required))
|
||||
/* FIXME Revert preloading */
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* Search for existing LVs that have become detached and preload them.
|
||||
*/
|
||||
detached.lv_pre = incore_lv;
|
||||
detached.lv_pre = lv_pre;
|
||||
detached.laopts = laopts;
|
||||
detached.flush_required = &flush_required;
|
||||
|
||||
if (!for_each_sub_lv((struct logical_volume *)ondisk_lv, &_preload_detached_lv, &detached))
|
||||
if (!for_each_sub_lv((struct logical_volume *)lv, &_preload_detached_lv, &detached))
|
||||
goto_out;
|
||||
|
||||
/*
|
||||
* Preload any snapshots that are being removed.
|
||||
*/
|
||||
if (!laopts->origin_only && lv_is_origin(ondisk_lv)) {
|
||||
dm_list_iterate_items_gen(snap_seg, &ondisk_lv->snapshot_segs, origin_list) {
|
||||
if (!(lvl_pre = find_lv_in_vg_by_lvid(incore_lv->vg, &snap_seg->cow->lvid))) {
|
||||
log_error(INTERNAL_ERROR "LV %s (%s) missing from preload metadata",
|
||||
snap_seg->cow->name, snap_seg->cow->lvid.id[1].uuid);
|
||||
if (!laopts->origin_only && lv_is_origin(lv)) {
|
||||
dm_list_iterate_items_gen(snap_seg, &lv->snapshot_segs, origin_list) {
|
||||
if (!(lv_pre_tmp = find_lv_in_vg_by_lvid(lv_pre->vg, &snap_seg->cow->lvid))) {
|
||||
log_error(INTERNAL_ERROR "LV %s (%s) missing from preload metadata.",
|
||||
display_lvname(snap_seg->cow),
|
||||
snap_seg->cow->lvid.id[1].uuid);
|
||||
goto out;
|
||||
}
|
||||
if (!lv_is_cow(lvl_pre->lv) &&
|
||||
!_lv_preload(lvl_pre->lv, laopts, &flush_required))
|
||||
if (!lv_is_cow(lv_pre_tmp) &&
|
||||
!_lv_preload(lv_pre_tmp, laopts, &flush_required))
|
||||
goto_out;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!monitor_dev_for_events(cmd, ondisk_lv, laopts, 0))
|
||||
if (!monitor_dev_for_events(cmd, lv, laopts, 0))
|
||||
/* FIXME Consider aborting here */
|
||||
stack;
|
||||
|
||||
@@ -1909,14 +1942,14 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
critical_section_inc(cmd, "suspending pvmove LV");
|
||||
|
||||
if (!laopts->origin_only &&
|
||||
(lv_is_origin(incore_lv) || lv_is_cow(incore_lv)))
|
||||
(lv_is_origin(lv_pre) || lv_is_cow(lv_pre)))
|
||||
lockfs = 1;
|
||||
|
||||
/* Converting non-thin LV to thin external origin ? */
|
||||
if (!lv_is_thin_volume(ondisk_lv) && lv_is_thin_volume(incore_lv))
|
||||
if (!lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
|
||||
lockfs = 1; /* Sync before conversion */
|
||||
|
||||
if (laopts->origin_only && lv_is_thin_volume(ondisk_lv) && lv_is_thin_volume(incore_lv))
|
||||
if (laopts->origin_only && lv_is_thin_volume(lv) && lv_is_thin_volume(lv_pre))
|
||||
lockfs = 1;
|
||||
|
||||
/*
|
||||
@@ -1927,9 +1960,9 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
* inactive table to load or not instead so lv_suspend
|
||||
* can be called separately for each LV safely.
|
||||
*/
|
||||
if ((incore_lv->vg->status & PRECOMMITTED) &&
|
||||
lv_is_locked(incore_lv) && find_pvmove_lv_in_lv(incore_lv)) {
|
||||
if (!_lv_suspend_lv(incore_lv, laopts, lockfs, flush_required)) {
|
||||
if ((lv_pre->vg->status & PRECOMMITTED) &&
|
||||
lv_is_locked(lv_pre) && find_pvmove_lv_in_lv(lv_pre)) {
|
||||
if (!_lv_suspend_lv(lv_pre, laopts, lockfs, flush_required)) {
|
||||
critical_section_dec(cmd, "failed precommitted suspend");
|
||||
if (pvmove_lv)
|
||||
critical_section_dec(cmd, "failed precommitted suspend (pvmove)");
|
||||
@@ -1937,7 +1970,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
}
|
||||
} else {
|
||||
/* Normal suspend */
|
||||
if (!_lv_suspend_lv(ondisk_lv, laopts, lockfs, flush_required)) {
|
||||
if (!_lv_suspend_lv(lv, laopts, lockfs, flush_required)) {
|
||||
critical_section_dec(cmd, "failed suspend");
|
||||
if (pvmove_lv)
|
||||
critical_section_dec(cmd, "failed suspend (pvmove)");
|
||||
@@ -1947,11 +1980,11 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
|
||||
|
||||
r = 1;
|
||||
out:
|
||||
if (incore_lv_to_free)
|
||||
release_vg(incore_lv_to_free->vg);
|
||||
if (ondisk_lv_to_free) {
|
||||
lv_release_replicator_vgs(ondisk_lv_to_free);
|
||||
release_vg(ondisk_lv_to_free->vg);
|
||||
if (lv_pre_to_free)
|
||||
release_vg(lv_pre_to_free->vg);
|
||||
if (lv_to_free) {
|
||||
lv_release_replicator_vgs(lv_to_free);
|
||||
release_vg(lv_to_free->vg);
|
||||
}
|
||||
|
||||
return r;
|
||||
@@ -1964,23 +1997,16 @@ out:
|
||||
* Returns success if the device is not active
|
||||
*/
|
||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
||||
const struct logical_volume *ondisk_lv, const struct logical_volume *incore_lv)
|
||||
const struct logical_volume *lv, const struct logical_volume *lv_pre)
|
||||
{
|
||||
struct lv_activate_opts laopts = {
|
||||
.origin_only = origin_only,
|
||||
.exclusive = exclusive
|
||||
};
|
||||
|
||||
return _lv_suspend(cmd, lvid_s, &laopts, 0, ondisk_lv, incore_lv);
|
||||
return _lv_suspend(cmd, lvid_s, &laopts, 0, lv, lv_pre);
|
||||
}
|
||||
|
||||
/* No longer used */
|
||||
/***********
|
||||
int lv_suspend(struct cmd_context *cmd, const char *lvid_s)
|
||||
{
|
||||
return _lv_suspend(cmd, lvid_s, 1);
|
||||
}
|
||||
***********/
|
||||
|
||||
static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
struct lv_activate_opts *laopts, int error_if_not_active,
|
||||
@@ -2000,13 +2026,14 @@ static int _lv_resume(struct cmd_context *cmd, const char *lvid_s,
|
||||
laopts->origin_only = 0;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Resuming %s%s%s.", lv->name, laopts->origin_only ? " without snapshots" : "",
|
||||
_skip("Resuming %s%s%s.", display_lvname(lv),
|
||||
laopts->origin_only ? " without snapshots" : "",
|
||||
laopts->revert ? " (reverting)" : "");
|
||||
r = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_debug_activation("Resuming LV %s/%s%s%s%s.", lv->vg->name, lv->name,
|
||||
log_debug_activation("Resuming LV %s%s%s%s.", display_lvname(lv),
|
||||
error_if_not_active ? "" : " if active",
|
||||
laopts->origin_only ?
|
||||
(lv_is_thin_pool(lv) ? " pool only" :
|
||||
@@ -2084,8 +2111,8 @@ static int _lv_has_open_snapshots(const struct logical_volume *lv)
|
||||
r++;
|
||||
|
||||
if (r)
|
||||
log_error("LV %s/%s has open %d snapshot(s), not deactivating.",
|
||||
lv->vg->name, lv->name, r);
|
||||
log_error("LV %s has open %d snapshot(s), not deactivating.",
|
||||
display_lvname(lv), r);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -2105,12 +2132,12 @@ int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logi
|
||||
goto out;
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Deactivating '%s'.", lv->name);
|
||||
_skip("Deactivating %s.", display_lvname(lv));
|
||||
r = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
log_debug_activation("Deactivating %s/%s.", lv->vg->name, lv->name);
|
||||
log_debug_activation("Deactivating %s.", display_lvname(lv));
|
||||
|
||||
if (!lv_info(cmd, lv, 0, &info, 0, 0))
|
||||
goto_out;
|
||||
@@ -2179,11 +2206,11 @@ int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
|
||||
}
|
||||
|
||||
if (!lv && !(lv_to_free = lv = lv_from_lvid(cmd, lvid_s, 0)))
|
||||
goto out;
|
||||
goto_out;
|
||||
|
||||
if (!_passes_activation_filter(cmd, lv)) {
|
||||
log_verbose("Not activating %s/%s since it does not pass "
|
||||
"activation filter.", lv->vg->name, lv->name);
|
||||
log_verbose("Not activating %s since it does not pass "
|
||||
"activation filter.", display_lvname(lv));
|
||||
*activate_lv = 0;
|
||||
} else
|
||||
*activate_lv = 1;
|
||||
@@ -2210,8 +2237,8 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
goto out;
|
||||
|
||||
if (filter && !_passes_activation_filter(cmd, lv)) {
|
||||
log_verbose("Not activating %s/%s since it does not pass "
|
||||
"activation filter.", lv->vg->name, lv->name);
|
||||
log_verbose("Not activating %s since it does not pass "
|
||||
"activation filter.", display_lvname(lv));
|
||||
r = 1;
|
||||
goto out;
|
||||
}
|
||||
@@ -2234,7 +2261,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
|
||||
if (lv_has_unknown_segments(lv)) {
|
||||
log_error("Refusing activation of LV %s containing "
|
||||
"an unrecognised segment.", lv->name);
|
||||
"an unrecognised segment.", display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -2249,7 +2276,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
}
|
||||
|
||||
if (test_mode()) {
|
||||
_skip("Activating '%s'.", lv->name);
|
||||
_skip("Activating %s.", display_lvname(lv));
|
||||
r = 1;
|
||||
goto out;
|
||||
}
|
||||
@@ -2257,7 +2284,7 @@ static int _lv_activate(struct cmd_context *cmd, const char *lvid_s,
|
||||
if (filter)
|
||||
laopts->read_only = _passes_readonly_filter(cmd, lv);
|
||||
|
||||
log_debug_activation("Activating %s/%s%s%s%s%s.", lv->vg->name, lv->name,
|
||||
log_debug_activation("Activating %s%s%s%s%s.", display_lvname(lv),
|
||||
laopts->exclusive ? " exclusively" : "",
|
||||
laopts->read_only ? " read-only" : "",
|
||||
laopts->noscan ? " noscan" : "",
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef LVM_ACTIVATE_H
|
||||
@@ -106,7 +106,7 @@ void activation_exit(void);
|
||||
|
||||
/* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
|
||||
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
|
||||
const struct logical_volume *lv_ondisk, const struct logical_volume *lv_incore);
|
||||
const struct logical_volume *lv, const struct logical_volume *lv_pre);
|
||||
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, const struct logical_volume *lv);
|
||||
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
|
||||
unsigned origin_only, unsigned exclusive, unsigned revert, const struct logical_volume *lv);
|
||||
@@ -189,6 +189,7 @@ int lvs_in_vg_opened(const struct volume_group *vg);
|
||||
|
||||
int lv_is_active(const struct logical_volume *lv);
|
||||
int lv_is_active_locally(const struct logical_volume *lv);
|
||||
int lv_is_active_remotely(const struct logical_volume *lv);
|
||||
int lv_is_active_but_not_locally(const struct logical_volume *lv);
|
||||
int lv_is_active_exclusive(const struct logical_volume *lv);
|
||||
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
* Copyright (C) 2002-2004 Sistina Software, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
|
||||
* Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file is part of LVM2.
|
||||
*
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -66,7 +66,7 @@ struct dev_manager {
|
||||
unsigned track_pending_delete;
|
||||
unsigned track_pvmove_deps;
|
||||
|
||||
char *vg_name;
|
||||
const char *vg_name;
|
||||
};
|
||||
|
||||
struct lv_layer {
|
||||
@@ -246,79 +246,6 @@ static int _info_run(info_type_t type, const char *name, const char *dlid,
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* _parse_mirror_status
|
||||
* @mirror_status_string
|
||||
* @image_health: return for allocated copy of image health characters
|
||||
* @log_device: return for 'dev_t' of log device
|
||||
* @log_health: NULL if corelog, otherwise dm_malloc'ed log health char which
|
||||
* the caller must free
|
||||
*
|
||||
* This function takes the mirror status string, breaks it up and returns
|
||||
* its components. For now, we only return the health characters. This
|
||||
* is an internal function. If there are more things we want to return
|
||||
* later, we can do that then.
|
||||
*
|
||||
* Returns: 1 on success, 0 on failure
|
||||
*/
|
||||
static int _parse_mirror_status(char *mirror_status_str,
|
||||
char **images_health,
|
||||
dev_t *log_dev, char **log_health)
|
||||
{
|
||||
int major, minor;
|
||||
char *p = NULL;
|
||||
char **args, **log_args;
|
||||
unsigned num_devs, log_argc;
|
||||
|
||||
*images_health = NULL;
|
||||
*log_health = NULL;
|
||||
*log_dev = 0;
|
||||
|
||||
if (!dm_split_words(mirror_status_str, 1, 0, &p) ||
|
||||
!(num_devs = (unsigned) atoi(p)))
|
||||
/* On errors, we must assume the mirror is to be avoided */
|
||||
return_0;
|
||||
|
||||
p += strlen(p) + 1;
|
||||
args = alloca((num_devs + 5) * sizeof(char *));
|
||||
|
||||
if ((unsigned)dm_split_words(p, num_devs + 4, 0, args) < num_devs + 4)
|
||||
return_0;
|
||||
|
||||
log_argc = (unsigned) atoi(args[3 + num_devs]);
|
||||
log_args = alloca(log_argc * sizeof(char *));
|
||||
|
||||
if ((unsigned)dm_split_words(args[3 + num_devs] + strlen(args[3 + num_devs]) + 1,
|
||||
log_argc, 0, log_args) < log_argc)
|
||||
return_0;
|
||||
|
||||
if (!strcmp(log_args[0], "disk")) {
|
||||
if (!(*log_health = dm_strdup(log_args[2]))) {
|
||||
log_error("Allocation of log string failed.");
|
||||
return 0;
|
||||
}
|
||||
if (sscanf(log_args[1], "%d:%d", &major, &minor) != 2) {
|
||||
log_error("Failed to parse log's device number from %s.", log_args[1]);
|
||||
goto out;
|
||||
}
|
||||
*log_dev = MKDEV((dev_t)major, minor);
|
||||
}
|
||||
|
||||
if (!(*images_health = dm_strdup(args[2 + num_devs]))) {
|
||||
log_error("Allocation of images string failed.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
out:
|
||||
dm_free(*log_health);
|
||||
*log_health = NULL;
|
||||
*log_dev = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* ignore_blocked_mirror_devices
|
||||
* @dev
|
||||
@@ -349,51 +276,53 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
||||
uint64_t start, uint64_t length,
|
||||
char *mirror_status_str)
|
||||
{
|
||||
struct dm_pool *mem;
|
||||
struct dm_status_mirror *sm;
|
||||
unsigned i, check_for_blocking = 0;
|
||||
dev_t log_dev;
|
||||
char *images_health, *log_health;
|
||||
uint64_t s,l;
|
||||
char *p, *params, *target_type = NULL;
|
||||
void *next = NULL;
|
||||
struct dm_task *dmt = NULL;
|
||||
int r = 0;
|
||||
struct device *tmp_dev;
|
||||
char buf[16];
|
||||
|
||||
if (!_parse_mirror_status(mirror_status_str,
|
||||
&images_health, &log_dev, &log_health))
|
||||
if (!(mem = dm_pool_create("blocked_mirrors", 128)))
|
||||
return_0;
|
||||
|
||||
for (i = 0; images_health[i]; i++)
|
||||
if (images_health[i] != 'A') {
|
||||
if (!dm_get_status_mirror(mem, mirror_status_str, &sm))
|
||||
goto_out;
|
||||
|
||||
for (i = 0; i < sm->dev_count; ++i)
|
||||
if (sm->devs[i].health != DM_STATUS_MIRROR_ALIVE) {
|
||||
log_debug_activation("%s: Mirror image %d marked as failed",
|
||||
dev_name(dev), i);
|
||||
check_for_blocking = 1;
|
||||
}
|
||||
|
||||
if (!check_for_blocking && log_dev) {
|
||||
if (log_health[0] != 'A') {
|
||||
if (!check_for_blocking && sm->log_count) {
|
||||
if (sm->logs[0].health != DM_STATUS_MIRROR_ALIVE) {
|
||||
log_debug_activation("%s: Mirror log device marked as failed",
|
||||
dev_name(dev));
|
||||
check_for_blocking = 1;
|
||||
} else {
|
||||
struct device *tmp_dev;
|
||||
char buf[16];
|
||||
|
||||
if (dm_snprintf(buf, sizeof(buf), "%d:%d",
|
||||
(int)MAJOR(log_dev),
|
||||
(int)MINOR(log_dev)) < 0)
|
||||
if (dm_snprintf(buf, sizeof(buf), "%u:%u",
|
||||
sm->logs[0].major, sm->logs[0].minor) < 0)
|
||||
goto_out;
|
||||
|
||||
if (!(tmp_dev = dev_create_file(buf, NULL, NULL, 0)))
|
||||
goto_out;
|
||||
|
||||
tmp_dev->dev = log_dev;
|
||||
tmp_dev->dev = MKDEV((dev_t)sm->logs[0].major, sm->logs[0].minor);
|
||||
if (device_is_usable(tmp_dev, (struct dev_usable_check_params)
|
||||
{ .check_empty = 1,
|
||||
.check_blocked = 1,
|
||||
.check_suspended = ignore_suspended_devices(),
|
||||
.check_error_target = 1,
|
||||
.check_reserved = 0 }))
|
||||
goto_out;
|
||||
goto out; /* safe to use */
|
||||
stack;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,8 +369,8 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
|
||||
out:
|
||||
if (dmt)
|
||||
dm_task_destroy(dmt);
|
||||
dm_free(log_health);
|
||||
dm_free(images_health);
|
||||
|
||||
dm_pool_destroy(mem);
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -498,14 +427,14 @@ static int _ignore_suspended_snapshot_component(struct device *dev)
|
||||
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||
if (!strcmp(target_type, "snapshot")) {
|
||||
if (sscanf(params, "%d:%d %d:%d", &major1, &minor1, &major2, &minor2) != 4) {
|
||||
if (!target_type || !strcmp(target_type, "snapshot")) {
|
||||
if (!params || sscanf(params, "%d:%d %d:%d", &major1, &minor1, &major2, &minor2) != 4) {
|
||||
log_error("Incorrect snapshot table found");
|
||||
goto_out;
|
||||
}
|
||||
r = r || _device_is_suspended(major1, minor1) || _device_is_suspended(major2, minor2);
|
||||
} else if (!strcmp(target_type, "snapshot-origin")) {
|
||||
if (sscanf(params, "%d:%d", &major1, &minor1) != 2) {
|
||||
if (!params || sscanf(params, "%d:%d", &major1, &minor1) != 2) {
|
||||
log_error("Incorrect snapshot-origin table found");
|
||||
goto_out;
|
||||
}
|
||||
@@ -545,7 +474,7 @@ static int _ignore_unusable_thins(struct device *dev)
|
||||
goto out;
|
||||
}
|
||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||
if (sscanf(params, "%d:%d", &minor, &major) != 2) {
|
||||
if (!params || sscanf(params, "%d:%d", &minor, &major) != 2) {
|
||||
log_error("Failed to get thin-pool major:minor for thin device %d:%d.",
|
||||
(int)MAJOR(dev->dev), (int)MINOR(dev->dev));
|
||||
goto out;
|
||||
@@ -567,7 +496,7 @@ static int _ignore_unusable_thins(struct device *dev)
|
||||
|
||||
dm_get_next_target(dmt, next, &start, &length, &target_type, ¶ms);
|
||||
if (!dm_get_status_thin_pool(mem, params, &status))
|
||||
return_0;
|
||||
goto_out;
|
||||
|
||||
if (status->read_only || status->out_of_data_space) {
|
||||
log_warn("WARNING: %s: Thin's thin-pool needs inspection.",
|
||||
@@ -794,15 +723,12 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
char *dlid, *name;
|
||||
int r;
|
||||
|
||||
if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, layer))) {
|
||||
log_error("name build failed for %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, layer)))
|
||||
return_0;
|
||||
|
||||
if (!(dlid = build_dm_uuid(mem, lv, layer))) {
|
||||
log_error("dlid build failed for %s", name);
|
||||
r = 0;
|
||||
goto out;
|
||||
goto_out;
|
||||
}
|
||||
|
||||
log_debug_activation("Getting device info for %s [%s]", name, dlid);
|
||||
@@ -823,16 +749,15 @@ static const struct dm_info *_cached_dm_info(struct dm_pool *mem,
|
||||
const struct dm_tree_node *dnode;
|
||||
const struct dm_info *dinfo = NULL;
|
||||
|
||||
if (!(dlid = build_dm_uuid(mem, lv, layer))) {
|
||||
log_error("Failed to build dlid for %s.", lv->name);
|
||||
return NULL;
|
||||
}
|
||||
if (!(dlid = build_dm_uuid(mem, lv, layer)))
|
||||
return_NULL;
|
||||
|
||||
if (!(dnode = dm_tree_find_node_by_uuid(dtree, dlid)))
|
||||
goto_out;
|
||||
|
||||
if (!(dinfo = dm_tree_node_get_info(dnode))) {
|
||||
log_error("Failed to get info from tree node for %s.", lv->name);
|
||||
log_error("Failed to get info from tree node for %s.",
|
||||
display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -844,83 +769,6 @@ out:
|
||||
return dinfo;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* FIXME Interface must cope with multiple targets */
|
||||
static int _status_run(const char *name, const char *uuid,
|
||||
unsigned long long *s, unsigned long long *l,
|
||||
char **t, uint32_t t_size, char **p, uint32_t p_size)
|
||||
{
|
||||
int r = 0;
|
||||
struct dm_task *dmt;
|
||||
struct dm_info info;
|
||||
void *next = NULL;
|
||||
uint64_t start, length;
|
||||
char *type = NULL;
|
||||
char *params = NULL;
|
||||
|
||||
if (!(dmt = _setup_task(name, uuid, 0, DM_DEVICE_STATUS, 0, 0, 0)))
|
||||
return_0;
|
||||
|
||||
if (!dm_task_run(dmt))
|
||||
goto_out;
|
||||
|
||||
if (!dm_task_get_info(dmt, &info) || !info.exists)
|
||||
goto_out;
|
||||
|
||||
do {
|
||||
next = dm_get_next_target(dmt, next, &start, &length,
|
||||
&type, ¶ms);
|
||||
if (type) {
|
||||
*s = start;
|
||||
*l = length;
|
||||
/* Make sure things are null terminated */
|
||||
strncpy(*t, type, t_size);
|
||||
(*t)[t_size - 1] = '\0';
|
||||
strncpy(*p, params, p_size);
|
||||
(*p)[p_size - 1] = '\0';
|
||||
|
||||
r = 1;
|
||||
/* FIXME Cope with multiple targets! */
|
||||
break;
|
||||
}
|
||||
|
||||
} while (next);
|
||||
|
||||
out:
|
||||
dm_task_destroy(dmt);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int _status(const char *name, const char *uuid,
|
||||
unsigned long long *start, unsigned long long *length,
|
||||
char **type, uint32_t type_size, char **params,
|
||||
uint32_t param_size) __attribute__ ((unused));
|
||||
|
||||
static int _status(const char *name, const char *uuid,
|
||||
unsigned long long *start, unsigned long long *length,
|
||||
char **type, uint32_t type_size, char **params,
|
||||
uint32_t param_size)
|
||||
{
|
||||
if (uuid && *uuid) {
|
||||
if (_status_run(NULL, uuid, start, length, type,
|
||||
type_size, params, param_size) &&
|
||||
*params)
|
||||
return 1;
|
||||
else if (_status_run(NULL, uuid + sizeof(UUID_PREFIX) - 1, start,
|
||||
length, type, type_size, params,
|
||||
param_size) &&
|
||||
*params)
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (name && _status_run(name, NULL, start, length, type, type_size,
|
||||
params, param_size))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
|
||||
const char *layer, const char *target_type)
|
||||
{
|
||||
@@ -1065,7 +913,8 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
if (lv) {
|
||||
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
||||
log_error("Number of segments in active LV %s "
|
||||
"does not match metadata", lv->name);
|
||||
"does not match metadata.",
|
||||
display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
seg = dm_list_item(segh, struct lv_segment);
|
||||
@@ -1105,7 +954,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
|
||||
|
||||
if (lv && dm_list_next(&lv->segments, segh)) {
|
||||
log_error("Number of segments in active LV %s does not "
|
||||
"match metadata", lv->name);
|
||||
"match metadata.", display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1180,7 +1029,7 @@ int dev_manager_transient(struct dev_manager *dm, const struct logical_volume *l
|
||||
|
||||
if (!(segh = dm_list_next(&lv->segments, segh))) {
|
||||
log_error("Number of segments in active LV %s "
|
||||
"does not match metadata", lv->name);
|
||||
"does not match metadata.", display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
seg = dm_list_item(segh, struct lv_segment);
|
||||
@@ -1194,14 +1043,14 @@ int dev_manager_transient(struct dev_manager *dm, const struct logical_volume *l
|
||||
}
|
||||
|
||||
if (seg->segtype->ops->check_transient_status &&
|
||||
!seg->segtype->ops->check_transient_status(seg, params))
|
||||
!seg->segtype->ops->check_transient_status(dm->mem, seg, params))
|
||||
goto_out;
|
||||
|
||||
} while (next);
|
||||
|
||||
if (dm_list_next(&lv->segments, segh)) {
|
||||
log_error("Number of segments in active LV %s does not "
|
||||
"match metadata", lv->name);
|
||||
"match metadata.", display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1230,9 +1079,7 @@ struct dev_manager *dev_manager_create(struct cmd_context *cmd,
|
||||
|
||||
dm->cmd = cmd;
|
||||
dm->mem = mem;
|
||||
|
||||
if (!(dm->vg_name = dm_pool_strdup(dm->mem, vg_name)))
|
||||
goto_bad;
|
||||
dm->vg_name = vg_name;
|
||||
|
||||
/*
|
||||
* When we manipulate (normally suspend/resume) the PVMOVE
|
||||
@@ -1335,10 +1182,8 @@ int dev_manager_mirror_percent(struct dev_manager *dm,
|
||||
if (!(name = dm_build_dm_name(dm->mem, lv->vg->name, lv->name, layer)))
|
||||
return_0;
|
||||
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer))) {
|
||||
log_error("dlid build failed for %s", lv->name);
|
||||
return 0;
|
||||
}
|
||||
if (!(dlid = build_dm_uuid(dm->mem, lv, layer)))
|
||||
return_0;
|
||||
|
||||
log_debug_activation("Getting device %s status percentage for %s",
|
||||
target_type, name);
|
||||
@@ -1404,20 +1249,20 @@ int dev_manager_raid_message(struct dev_manager *dm,
|
||||
const char *layer = lv_layer(lv);
|
||||
|
||||
if (!lv_is_raid(lv)) {
|
||||
log_error(INTERNAL_ERROR "%s/%s is not a RAID logical volume",
|
||||
lv->vg->name, lv->name);
|
||||
log_error(INTERNAL_ERROR "%s is not a RAID logical volume",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* These are the supported RAID messages for dm-raid v1.5.0 */
|
||||
if (!strcmp(msg, "idle") &&
|
||||
!strcmp(msg, "frozen") &&
|
||||
!strcmp(msg, "resync") &&
|
||||
!strcmp(msg, "recover") &&
|
||||
!strcmp(msg, "check") &&
|
||||
!strcmp(msg, "repair") &&
|
||||
!strcmp(msg, "reshape")) {
|
||||
log_error("Unknown RAID message: %s", msg);
|
||||
if (strcmp(msg, "idle") &&
|
||||
strcmp(msg, "frozen") &&
|
||||
strcmp(msg, "resync") &&
|
||||
strcmp(msg, "recover") &&
|
||||
strcmp(msg, "check") &&
|
||||
strcmp(msg, "repair") &&
|
||||
strcmp(msg, "reshape")) {
|
||||
log_error(INTERNAL_ERROR "Unknown RAID message: %s", msg);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1499,66 +1344,6 @@ out:
|
||||
return r;
|
||||
}
|
||||
|
||||
//FIXME: Can we get rid of this crap below?
|
||||
#if 0
|
||||
log_very_verbose("%s %s", sus ? "Suspending" : "Resuming", name);
|
||||
|
||||
log_verbose("Loading %s", dl->name);
|
||||
log_very_verbose("Activating %s read-only", dl->name);
|
||||
log_very_verbose("Activated %s %s %03u:%03u", dl->name,
|
||||
dl->dlid, dl->info.major, dl->info.minor);
|
||||
|
||||
if (_get_flag(dl, VISIBLE))
|
||||
log_verbose("Removing %s", dl->name);
|
||||
else
|
||||
log_very_verbose("Removing %s", dl->name);
|
||||
|
||||
log_debug_activation("Adding target: %" PRIu64 " %" PRIu64 " %s %s",
|
||||
extent_size * seg->le, extent_size * seg->len, target, params);
|
||||
|
||||
log_debug_activation("Adding target: 0 %" PRIu64 " snapshot-origin %s",
|
||||
dl->lv->size, params);
|
||||
log_debug_activation("Adding target: 0 %" PRIu64 " snapshot %s", size, params);
|
||||
log_debug_activation("Getting device info for %s", dl->name);
|
||||
|
||||
/* Rename? */
|
||||
if ((suffix = strrchr(dl->dlid + sizeof(UUID_PREFIX) - 1, '-')))
|
||||
suffix++;
|
||||
new_name = dm_build_dm_name(dm->mem, dm->vg_name, dl->lv->name,
|
||||
suffix);
|
||||
|
||||
static int _belong_to_vg(const char *vgname, const char *name)
|
||||
{
|
||||
const char *v = vgname, *n = name;
|
||||
|
||||
while (*v) {
|
||||
if ((*v != *n) || (*v == '-' && *(++n) != '-'))
|
||||
return 0;
|
||||
v++, n++;
|
||||
}
|
||||
|
||||
if (*n == '-' && *(n + 1) != '-')
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(snap_seg = find_snapshot(lv)))
|
||||
return 1;
|
||||
|
||||
old_origin = snap_seg->origin;
|
||||
|
||||
/* Was this the last active snapshot with this origin? */
|
||||
dm_list_iterate_items(lvl, active_head) {
|
||||
active = lvl->lv;
|
||||
if ((snap_seg = find_snapshot(active)) &&
|
||||
snap_seg->origin == old_origin) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int dev_manager_thin_pool_status(struct dev_manager *dm,
|
||||
const struct logical_volume *lv,
|
||||
struct dm_status_thin_pool **status,
|
||||
@@ -1674,17 +1459,20 @@ int dev_manager_thin_device_id(struct dev_manager *dm,
|
||||
|
||||
if (dm_get_next_target(dmt, NULL, &start, &length,
|
||||
&target_type, ¶ms)) {
|
||||
log_error("More then one table line found for %s.", lv->name);
|
||||
log_error("More then one table line found for %s.",
|
||||
display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (strcmp(target_type, "thin")) {
|
||||
log_error("Unexpected target type %s found for thin %s.", target_type, lv->name);
|
||||
if (!target_type || strcmp(target_type, "thin")) {
|
||||
log_error("Unexpected target type %s found for thin %s.",
|
||||
target_type, display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (sscanf(params, "%*u:%*u %u", device_id) != 1) {
|
||||
log_error("Cannot parse table like parameters %s for %s.", params, lv->name);
|
||||
if (!params || sscanf(params, "%*u:%*u %u", device_id) != 1) {
|
||||
log_error("Cannot parse table like parameters %s for %s.",
|
||||
params, display_lvname(lv));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1705,7 +1493,7 @@ static int _dev_manager_lv_mknodes(const struct logical_volume *lv)
|
||||
char *name;
|
||||
|
||||
if (!(name = dm_build_dm_name(lv->vg->cmd->mem, lv->vg->name,
|
||||
lv->name, NULL)))
|
||||
lv->name, NULL)))
|
||||
return_0;
|
||||
|
||||
return fs_add_lv(lv, name);
|
||||
@@ -1884,7 +1672,8 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
log_error("Volume %s (%" PRIu32 ":%" PRIu32")"
|
||||
" differs from already active device "
|
||||
"(%" PRIu32 ":%" PRIu32")",
|
||||
lv->name, lv->major, lv->minor, info.major, info.minor);
|
||||
display_lvname(lv), lv->major, lv->minor,
|
||||
info.major, info.minor);
|
||||
return 0;
|
||||
}
|
||||
if (!info.exists && _info_by_dev(lv->major, lv->minor, &info2) &&
|
||||
@@ -1904,7 +1693,8 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
}
|
||||
|
||||
if (info.exists && dm->track_pending_delete) {
|
||||
log_debug_activation("Tracking pending delete for %s (%s).", lv->name, dlid);
|
||||
log_debug_activation("Tracking pending delete for %s (%s).",
|
||||
display_lvname(lv), dlid);
|
||||
if (!str_list_add(dm->mem, &dm->pending_delete, dlid))
|
||||
return_0;
|
||||
}
|
||||
@@ -2311,7 +2101,8 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
return_0;
|
||||
if (seg->pool_lv &&
|
||||
(lv_is_cache_pool(seg->pool_lv) || !dm->skip_external_lv) &&
|
||||
!_add_lv_to_dtree(dm, dtree, seg->pool_lv, 1)) /* stack */
|
||||
/* When activating and not origin_only detect linear 'overlay' over pool */
|
||||
!_add_lv_to_dtree(dm, dtree, seg->pool_lv, dm->activation ? origin_only : 1))
|
||||
return_0;
|
||||
|
||||
for (s = 0; s < seg->area_count; s++) {
|
||||
@@ -2339,7 +2130,8 @@ static struct dm_tree *_create_partial_dtree(struct dev_manager *dm, const struc
|
||||
struct dm_tree *dtree;
|
||||
|
||||
if (!(dtree = dm_tree_create())) {
|
||||
log_debug_activation("Partial dtree creation failed for %s.", lv->name);
|
||||
log_debug_activation("Partial dtree creation failed for %s.",
|
||||
display_lvname(lv));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2383,7 +2175,7 @@ static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
return_NULL;
|
||||
|
||||
if (!(name = dm_build_dm_name(dm->mem, seg->lv->vg->name,
|
||||
seg->lv->name, errid)))
|
||||
seg->lv->name, errid)))
|
||||
return_NULL;
|
||||
|
||||
log_debug_activation("Getting device info for %s [%s]", name, dlid);
|
||||
@@ -2456,7 +2248,8 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
if (!seg->lv->vg->cmd->degraded_activation ||
|
||||
!lv_is_raid_type(seg->lv)) {
|
||||
log_error("Aborting. LV %s is now incomplete "
|
||||
"and '--activationmode partial' was not specified.", seg->lv->name);
|
||||
"and '--activationmode partial' was not specified.",
|
||||
display_lvname(seg->lv));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2507,7 +2300,7 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
return_0;
|
||||
} else {
|
||||
log_error(INTERNAL_ERROR "Unassigned area found in LV %s.",
|
||||
seg->lv->name);
|
||||
display_lvname(seg->lv));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2515,8 +2308,8 @@ int add_areas_line(struct dev_manager *dm, struct lv_segment *seg,
|
||||
if (num_error_areas) {
|
||||
/* Thins currently do not support partial activation */
|
||||
if (lv_is_thin_type(seg->lv)) {
|
||||
log_error("Cannot activate %s%s: pool incomplete.",
|
||||
seg->lv->vg->name, seg->lv->name);
|
||||
log_error("Cannot activate %s: pool incomplete.",
|
||||
display_lvname(seg->lv));
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2566,7 +2359,8 @@ static int _add_snapshot_merge_target_to_dtree(struct dev_manager *dm,
|
||||
struct lv_segment *merging_snap_seg = find_snapshot(lv);
|
||||
|
||||
if (!lv_is_merging_origin(lv)) {
|
||||
log_error(INTERNAL_ERROR "LV %s is not merging snapshot.", lv->name);
|
||||
log_error(INTERNAL_ERROR "LV %s is not merging snapshot.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2598,7 +2392,8 @@ static int _add_snapshot_target_to_dtree(struct dev_manager *dm,
|
||||
uint64_t size;
|
||||
|
||||
if (!(snap_seg = find_snapshot(lv))) {
|
||||
log_error("Couldn't find snapshot for '%s'.", lv->name);
|
||||
log_error("Couldn't find snapshot for '%s'.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2723,8 +2518,8 @@ static int _add_new_external_lv_to_dtree(struct dev_manager *dm,
|
||||
*/
|
||||
dm->skip_external_lv = 1;
|
||||
|
||||
log_debug_activation("Adding external origin lv %s and all active users.",
|
||||
external_lv->name);
|
||||
log_debug_activation("Adding external origin LV %s and all active users.",
|
||||
display_lvname(external_lv));
|
||||
|
||||
if (!_add_new_lv_to_dtree(dm, dtree, external_lv, laopts,
|
||||
lv_layer(external_lv)))
|
||||
@@ -2735,7 +2530,6 @@ static int _add_new_external_lv_to_dtree(struct dev_manager *dm,
|
||||
* needed because of conversion of thin which could have been
|
||||
* also an old-snapshot to external origin.
|
||||
*/
|
||||
//if (lv_is_origin(external_lv))
|
||||
dm_list_iterate_items(sl, &external_lv->segs_using_this_lv)
|
||||
if ((sl->seg->external_lv == external_lv) &&
|
||||
/* Add only active layered devices (also avoids loop) */
|
||||
@@ -2745,8 +2539,9 @@ static int _add_new_external_lv_to_dtree(struct dev_manager *dm,
|
||||
laopts, lv_layer(sl->seg->lv)))
|
||||
return_0;
|
||||
|
||||
log_debug_activation("Finished adding external origin lv %s and all active users.",
|
||||
external_lv->name);
|
||||
log_debug_activation("Finished adding external origin LV %s and all active users.",
|
||||
display_lvname(external_lv));
|
||||
|
||||
dm->skip_external_lv = 0;
|
||||
|
||||
return 1;
|
||||
@@ -2773,14 +2568,14 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
segtype->name);
|
||||
|
||||
log_debug_activation("Checking kernel supports %s segment type for %s%s%s",
|
||||
target_name, seg->lv->name,
|
||||
target_name, display_lvname(seg->lv),
|
||||
layer ? "-" : "", layer ? : "");
|
||||
|
||||
if (segtype->ops->target_present &&
|
||||
!segtype->ops->target_present(seg_present->lv->vg->cmd,
|
||||
seg_present, NULL)) {
|
||||
log_error("Can't process LV %s: %s target support missing "
|
||||
"from kernel?", seg->lv->name, target_name);
|
||||
"from kernel?", display_lvname(seg->lv), target_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2827,7 +2622,7 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
if (dm->track_pending_delete) {
|
||||
/* Replace target and all its used devs with error mapping */
|
||||
log_debug_activation("Using error for pending delete %s.",
|
||||
seg->lv->name);
|
||||
display_lvname(seg->lv));
|
||||
if (!dm_tree_node_add_error_target(dnode, (uint64_t)seg->lv->vg->extent_size * seg->len))
|
||||
return_0;
|
||||
} else if (!_add_target_to_dtree(dm, dnode, seg, laopts))
|
||||
@@ -2836,59 +2631,6 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
static int _set_udev_flags_for_children(struct dev_manager *dm,
|
||||
struct volume_group *vg,
|
||||
struct dm_tree_node *dnode)
|
||||
{
|
||||
char *p;
|
||||
const char *uuid;
|
||||
void *handle = NULL;
|
||||
struct dm_tree_node *child;
|
||||
const struct dm_info *info;
|
||||
struct lv_list *lvl;
|
||||
|
||||
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
|
||||
/* Ignore root node */
|
||||
if (!(info = dm_tree_node_get_info(child)) || !info->exists)
|
||||
continue;
|
||||
|
||||
if (!(uuid = dm_tree_node_get_uuid(child))) {
|
||||
log_error(INTERNAL_ERROR
|
||||
"Failed to get uuid for %" PRIu32 ":%" PRIu32,
|
||||
info->major, info->minor);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Ignore non-LVM devices */
|
||||
if (!(p = strstr(uuid, UUID_PREFIX)))
|
||||
continue;
|
||||
p += strlen(UUID_PREFIX);
|
||||
|
||||
/* Ignore LVs that belong to different VGs (due to stacking) */
|
||||
if (strncmp(p, (char *)vg->id.uuid, ID_LEN))
|
||||
continue;
|
||||
|
||||
/* Ignore LVM devices with 'layer' suffixes */
|
||||
if (strrchr(p, '-'))
|
||||
continue;
|
||||
|
||||
if (!(lvl = find_lv_in_vg_by_lvid(vg, (const union lvid *)p))) {
|
||||
log_error(INTERNAL_ERROR
|
||||
"%s (%" PRIu32 ":%" PRIu32 ") not found in VG",
|
||||
dm_tree_node_get_name(child),
|
||||
info->major, info->minor);
|
||||
return 0;
|
||||
}
|
||||
|
||||
dm_tree_node_set_udev_flags(child,
|
||||
_get_udev_flags(dm, lvl->lv, NULL, 0, 0));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
const struct logical_volume *lv, struct lv_activate_opts *laopts,
|
||||
const char *layer)
|
||||
@@ -2961,7 +2703,7 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
|
||||
if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) {
|
||||
log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.",
|
||||
lv->name, layer);
|
||||
display_lvname(lv), layer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3074,12 +2816,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
|
||||
if (!_add_new_lv_to_dtree(dm, dtree, sl->seg->lv, laopts, NULL))
|
||||
return_0;
|
||||
|
||||
#if 0
|
||||
/* Should not be needed, will be removed */
|
||||
if (!_set_udev_flags_for_children(dm, lv->vg, dnode))
|
||||
return_0;
|
||||
#endif
|
||||
|
||||
dm->track_pending_delete = save_pending_delete; /* restore */
|
||||
|
||||
return 1;
|
||||
@@ -3237,7 +2973,8 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
/* Some LV can be used for top level tree */
|
||||
/* TODO: add more.... */
|
||||
if (lv_is_cache_pool(lv) && !dm_list_empty(&lv->segs_using_this_lv)) {
|
||||
log_error(INTERNAL_ERROR "Cannot create tree for %s.", lv->name);
|
||||
log_error(INTERNAL_ERROR "Cannot create tree for %s.",
|
||||
display_lvname(lv));
|
||||
return 0;
|
||||
}
|
||||
/* Some targets may build bigger tree for activation */
|
||||
@@ -3273,7 +3010,8 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
if (!dm_tree_deactivate_children(root, dlid, DLID_SIZE))
|
||||
goto_out;
|
||||
if (!_remove_lv_symlinks(dm, root))
|
||||
log_warn("Failed to remove all device symlinks associated with %s.", lv->name);
|
||||
log_warn("Failed to remove all device symlinks associated with %s.",
|
||||
display_lvname(lv));
|
||||
break;
|
||||
case SUSPEND:
|
||||
dm_tree_skip_lockfs(root);
|
||||
@@ -3310,7 +3048,8 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
|
||||
if (!dm_tree_activate_children(root, dlid, DLID_SIZE))
|
||||
goto_out;
|
||||
if (!_create_lv_symlinks(dm, root))
|
||||
log_warn("Failed to create symlinks for %s.", lv->name);
|
||||
log_warn("Failed to create symlinks for %s.",
|
||||
display_lvname(lv));
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_DEV_MANAGER_H
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_FS_H
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_TARGETS_H
|
||||
|
||||
194
lib/cache/lvmcache.c
vendored
194
lib/cache/lvmcache.c
vendored
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -56,6 +56,7 @@ struct lvmcache_vginfo {
|
||||
char _padding[7];
|
||||
struct lvmcache_vginfo *next; /* Another VG with same name? */
|
||||
char *creation_host;
|
||||
char *system_id;
|
||||
char *lock_type;
|
||||
uint32_t mda_checksum;
|
||||
size_t mda_size;
|
||||
@@ -81,6 +82,7 @@ static int _has_scanned = 0;
|
||||
static int _vgs_locked = 0;
|
||||
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
|
||||
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
|
||||
static int _suppress_lock_ordering = 0;
|
||||
|
||||
int lvmcache_init(void)
|
||||
{
|
||||
@@ -330,7 +332,7 @@ void lvmcache_commit_metadata(const char *vgname)
|
||||
|
||||
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
|
||||
{
|
||||
if (lvmcache_vgname_is_locked(VG_GLOBAL) && !vg_write_lock_held())
|
||||
if (lvmcache_vgname_is_locked(VG_GLOBAL))
|
||||
return;
|
||||
|
||||
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
|
||||
@@ -370,6 +372,11 @@ static int _vgname_order_correct(const char *vgname1, const char *vgname2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void lvmcache_lock_ordering(int enable)
|
||||
{
|
||||
_suppress_lock_ordering = !enable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Ensure VG locks are acquired in alphabetical order.
|
||||
*/
|
||||
@@ -378,6 +385,9 @@ int lvmcache_verify_lock_order(const char *vgname)
|
||||
struct dm_hash_node *n;
|
||||
const char *vgname2;
|
||||
|
||||
if (_suppress_lock_ordering)
|
||||
return 1;
|
||||
|
||||
if (!_lock_hash)
|
||||
return_0;
|
||||
|
||||
@@ -442,8 +452,10 @@ void lvmcache_unlock_vgname(const char *vgname)
|
||||
dm_hash_remove(_lock_hash, vgname);
|
||||
|
||||
/* FIXME Do this per-VG */
|
||||
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked)
|
||||
if (strcmp(vgname, VG_GLOBAL) && !--_vgs_locked) {
|
||||
dev_close_all();
|
||||
dev_size_seqno_inc(); /* invalidate all cached dev sizes */
|
||||
}
|
||||
}
|
||||
|
||||
int lvmcache_vgs_locked(void)
|
||||
@@ -613,6 +625,23 @@ const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid)
|
||||
return vgname;
|
||||
}
|
||||
|
||||
const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgname)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
|
||||
return_NULL;
|
||||
|
||||
if (!vginfo->next)
|
||||
return dm_pool_strdup(cmd->mem, vginfo->vgid);
|
||||
|
||||
/*
|
||||
* There are multiple VGs with this name to choose from.
|
||||
* Return an error because we don't know which VG is intended.
|
||||
*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _info_is_valid(struct lvmcache_info *info)
|
||||
{
|
||||
if (info->status & CACHE_INVALID)
|
||||
@@ -725,12 +754,30 @@ static int _scan_invalid(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
/*
|
||||
* lvmcache_label_scan() remembers that it has already
|
||||
* been called, and will not scan labels if it's called
|
||||
* again. (It will rescan "INVALID" devices if called again.)
|
||||
*
|
||||
* To force lvmcache_label_scan() to rescan labels on all devices,
|
||||
* call lvmcache_force_next_label_scan() before calling
|
||||
* lvmcache_label_scan().
|
||||
*/
|
||||
|
||||
static int _force_label_scan;
|
||||
|
||||
void lvmcache_force_next_label_scan(void)
|
||||
{
|
||||
_force_label_scan = 1;
|
||||
}
|
||||
|
||||
int lvmcache_label_scan(struct cmd_context *cmd)
|
||||
{
|
||||
struct label *label;
|
||||
struct dev_iter *iter;
|
||||
struct device *dev;
|
||||
struct format_type *fmt;
|
||||
int dev_count = 0;
|
||||
|
||||
int r = 0;
|
||||
|
||||
@@ -748,24 +795,30 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (_has_scanned && !full_scan) {
|
||||
if (_has_scanned && !_force_label_scan) {
|
||||
r = _scan_invalid();
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (full_scan == 2 && (cmd->full_filter && !cmd->full_filter->use_count) && !refresh_filters(cmd))
|
||||
if (_force_label_scan && (cmd->full_filter && !cmd->full_filter->use_count) && !refresh_filters(cmd))
|
||||
goto_out;
|
||||
|
||||
if (!cmd->full_filter || !(iter = dev_iter_create(cmd->full_filter, (full_scan == 2) ? 1 : 0))) {
|
||||
if (!cmd->full_filter || !(iter = dev_iter_create(cmd->full_filter, _force_label_scan))) {
|
||||
log_error("dev_iter creation failed");
|
||||
goto out;
|
||||
}
|
||||
|
||||
while ((dev = dev_iter_get(iter)))
|
||||
log_very_verbose("Scanning device labels");
|
||||
|
||||
while ((dev = dev_iter_get(iter))) {
|
||||
(void) label_read(dev, &label, UINT64_C(0));
|
||||
dev_count++;
|
||||
}
|
||||
|
||||
dev_iter_destroy(iter);
|
||||
|
||||
log_very_verbose("Scanned %d device labels", dev_count);
|
||||
|
||||
_has_scanned = 1;
|
||||
|
||||
/* Perform any format-specific scanning e.g. text files */
|
||||
@@ -778,7 +831,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
* If we are a long-lived process, write out the updated persistent
|
||||
* device cache for the benefit of short-lived processes.
|
||||
*/
|
||||
if (full_scan == 2 && cmd->is_long_lived &&
|
||||
if (_force_label_scan && cmd->is_long_lived &&
|
||||
cmd->dump_filter && cmd->full_filter && cmd->full_filter->dump &&
|
||||
!cmd->full_filter->dump(cmd->full_filter, 0))
|
||||
stack;
|
||||
@@ -787,6 +840,7 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
|
||||
|
||||
out:
|
||||
_scanning_in_progress = 0;
|
||||
_force_label_scan = 0;
|
||||
|
||||
return r;
|
||||
}
|
||||
@@ -912,7 +966,7 @@ int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
|
||||
struct vgnameid_list *vgnl;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
lvmcache_label_scan(cmd);
|
||||
|
||||
dm_list_iterate_items(vginfo, &_vginfos) {
|
||||
if (!include_internal && is_orphan_vg(vginfo->vgname))
|
||||
@@ -944,7 +998,7 @@ struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
// TODO plug into lvmetad here automagically?
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
lvmcache_label_scan(cmd);
|
||||
|
||||
if (!(vgids = str_list_create(cmd->mem))) {
|
||||
log_error("vgids list allocation failed");
|
||||
@@ -971,7 +1025,7 @@ struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
|
||||
struct dm_list *vgnames;
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
lvmcache_label_scan(cmd);
|
||||
|
||||
if (!(vgnames = str_list_create(cmd->mem))) {
|
||||
log_errno(ENOMEM, "vgnames list allocation failed");
|
||||
@@ -1053,7 +1107,7 @@ struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct i
|
||||
if (dev)
|
||||
return dev;
|
||||
|
||||
lvmcache_label_scan(cmd, 0);
|
||||
lvmcache_label_scan(cmd);
|
||||
|
||||
/* Try again */
|
||||
dev = _device_from_pvid(pvid, label_sector);
|
||||
@@ -1063,7 +1117,8 @@ struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct i
|
||||
if (critical_section() || (scan_done_once && *scan_done_once))
|
||||
return NULL;
|
||||
|
||||
lvmcache_label_scan(cmd, 2);
|
||||
lvmcache_force_next_label_scan();
|
||||
lvmcache_label_scan(cmd);
|
||||
if (scan_done_once)
|
||||
*scan_done_once = 1;
|
||||
|
||||
@@ -1241,6 +1296,15 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
||||
return_0;
|
||||
|
||||
/*
|
||||
* vginfo is kept for each VG with the same name.
|
||||
* They are saved with the vginfo->next list.
|
||||
* These checks just decide the ordering of
|
||||
* that list.
|
||||
*
|
||||
* FIXME: it should no longer matter what order
|
||||
* the vginfo's are kept in, so we can probably
|
||||
* remove these comparisons and reordering entirely.
|
||||
*
|
||||
* If Primary not exported, new exported => keep
|
||||
* Else Primary exported, new not exported => change
|
||||
* Else Primary has hostname for this machine => keep
|
||||
@@ -1250,38 +1314,42 @@ static int _insert_vginfo(struct lvmcache_vginfo *new_vginfo, const char *vgid,
|
||||
*/
|
||||
if (!(primary_vginfo->status & EXPORTED_VG) &&
|
||||
(vgstatus & EXPORTED_VG))
|
||||
log_warn("WARNING: Duplicate VG name %s: "
|
||||
"Existing %s takes precedence over "
|
||||
"exported %s", new_vginfo->vgname,
|
||||
uuid_primary, uuid_new);
|
||||
log_verbose("Cache: Duplicate VG name %s: "
|
||||
"Existing %s takes precedence over "
|
||||
"exported %s", new_vginfo->vgname,
|
||||
uuid_primary, uuid_new);
|
||||
else if ((primary_vginfo->status & EXPORTED_VG) &&
|
||||
!(vgstatus & EXPORTED_VG)) {
|
||||
log_warn("WARNING: Duplicate VG name %s: "
|
||||
"%s takes precedence over exported %s",
|
||||
new_vginfo->vgname, uuid_new,
|
||||
uuid_primary);
|
||||
log_verbose("Cache: Duplicate VG name %s: "
|
||||
"%s takes precedence over exported %s",
|
||||
new_vginfo->vgname, uuid_new,
|
||||
uuid_primary);
|
||||
use_new = 1;
|
||||
} else if (primary_vginfo->creation_host &&
|
||||
!strcmp(primary_vginfo->creation_host,
|
||||
primary_vginfo->fmt->cmd->hostname))
|
||||
log_warn("WARNING: Duplicate VG name %s: "
|
||||
"Existing %s (created here) takes precedence "
|
||||
"over %s", new_vginfo->vgname, uuid_primary,
|
||||
uuid_new);
|
||||
log_verbose("Cache: Duplicate VG name %s: "
|
||||
"Existing %s (created here) takes precedence "
|
||||
"over %s", new_vginfo->vgname, uuid_primary,
|
||||
uuid_new);
|
||||
else if (!primary_vginfo->creation_host && creation_host) {
|
||||
log_warn("WARNING: Duplicate VG name %s: "
|
||||
"%s (with creation_host) takes precedence over %s",
|
||||
new_vginfo->vgname, uuid_new,
|
||||
uuid_primary);
|
||||
log_verbose("Cache: Duplicate VG name %s: "
|
||||
"%s (with creation_host) takes precedence over %s",
|
||||
new_vginfo->vgname, uuid_new,
|
||||
uuid_primary);
|
||||
use_new = 1;
|
||||
} else if (creation_host &&
|
||||
!strcmp(creation_host,
|
||||
primary_vginfo->fmt->cmd->hostname)) {
|
||||
log_warn("WARNING: Duplicate VG name %s: "
|
||||
"%s (created here) takes precedence over %s",
|
||||
new_vginfo->vgname, uuid_new,
|
||||
uuid_primary);
|
||||
log_verbose("Cache: Duplicate VG name %s: "
|
||||
"%s (created here) takes precedence over %s",
|
||||
new_vginfo->vgname, uuid_new,
|
||||
uuid_primary);
|
||||
use_new = 1;
|
||||
} else {
|
||||
log_verbose("Cache: Duplicate VG name %s: "
|
||||
"Prefer existing %s vs new %s",
|
||||
new_vginfo->vgname, uuid_primary, uuid_new);
|
||||
}
|
||||
|
||||
if (!use_new) {
|
||||
@@ -1448,7 +1516,8 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
|
||||
}
|
||||
|
||||
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
|
||||
const char *creation_host, const char *lock_type)
|
||||
const char *creation_host, const char *lock_type,
|
||||
const char *system_id)
|
||||
{
|
||||
if (!info || !info->vginfo)
|
||||
return 1;
|
||||
@@ -1482,20 +1551,41 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
|
||||
set_lock_type:
|
||||
|
||||
if (!lock_type)
|
||||
goto out;
|
||||
goto set_system_id;
|
||||
|
||||
if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
|
||||
goto out;
|
||||
goto set_system_id;
|
||||
|
||||
if (info->vginfo->lock_type)
|
||||
dm_free(info->vginfo->lock_type);
|
||||
|
||||
if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
|
||||
log_error("cache creation host alloc failed for %s",
|
||||
lock_type);
|
||||
log_error("cache lock_type alloc failed for %s", lock_type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug_cache("lvmcache: %s: VG %s: Set lock_type to %s.",
|
||||
dev_name(info->dev), info->vginfo->vgname, lock_type);
|
||||
|
||||
set_system_id:
|
||||
|
||||
if (!system_id)
|
||||
goto out;
|
||||
|
||||
if (info->vginfo->system_id && !strcmp(system_id, info->vginfo->system_id))
|
||||
goto out;
|
||||
|
||||
if (info->vginfo->system_id)
|
||||
dm_free(info->vginfo->system_id);
|
||||
|
||||
if (!(info->vginfo->system_id = dm_strdup(system_id))) {
|
||||
log_error("cache system_id alloc failed for %s", system_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
log_debug_cache("lvmcache: %s: VG %s: Set system_id to %s.",
|
||||
dev_name(info->dev), info->vginfo->vgname, system_id);
|
||||
|
||||
out:
|
||||
return 1;
|
||||
}
|
||||
@@ -1561,7 +1651,7 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vg
|
||||
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
|
||||
vgsummary->creation_host, info->fmt) ||
|
||||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
|
||||
!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type) ||
|
||||
!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type, vgsummary->system_id) ||
|
||||
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
|
||||
return_0;
|
||||
|
||||
@@ -1577,6 +1667,7 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
|
||||
.vgname = vg->name,
|
||||
.vgstatus = vg->status,
|
||||
.vgid = vg->id,
|
||||
.system_id = vg->system_id,
|
||||
.lock_type = vg->lock_type
|
||||
};
|
||||
|
||||
@@ -1784,9 +1875,9 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
* been chosen during a previous populating of
|
||||
* lvmcache, so just use the existing preferences.
|
||||
*/
|
||||
log_verbose("Found duplicate PV %s: using existing dev %s",
|
||||
pvid_s,
|
||||
dev_name(existing->dev));
|
||||
log_warn("Found duplicate PV %s: using existing dev %s",
|
||||
pvid_s,
|
||||
dev_name(existing->dev));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -2065,7 +2156,8 @@ int lvmcache_populate_pv_fields(struct lvmcache_info *info,
|
||||
|
||||
/* Perform full scan (just the first time) and try again */
|
||||
if (!scan_label_only && !critical_section() && !full_scan_done()) {
|
||||
lvmcache_label_scan(info->fmt->cmd, 2);
|
||||
lvmcache_force_next_label_scan();
|
||||
lvmcache_label_scan(info->fmt->cmd);
|
||||
|
||||
if (_get_pv_if_in_vg(info, pv))
|
||||
return 1;
|
||||
@@ -2378,3 +2470,17 @@ void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
|
||||
}
|
||||
}
|
||||
|
||||
int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
||||
{
|
||||
struct lvmcache_vginfo *vginfo;
|
||||
int ret = 0;
|
||||
|
||||
if (lvmetad_active())
|
||||
return lvmetad_vg_is_foreign(cmd, vgname, vgid);
|
||||
|
||||
if ((vginfo = lvmcache_vginfo_from_vgid(vgid)))
|
||||
ret = !is_system_id_allowed(cmd, vginfo->system_id);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
18
lib/cache/lvmcache.h
vendored
18
lib/cache/lvmcache.h
vendored
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_CACHE_H
|
||||
@@ -55,6 +55,7 @@ struct lvmcache_vgsummary {
|
||||
struct id vgid;
|
||||
uint64_t vgstatus;
|
||||
char *creation_host;
|
||||
const char *system_id;
|
||||
const char *lock_type;
|
||||
uint32_t mda_checksum;
|
||||
size_t mda_size;
|
||||
@@ -65,9 +66,14 @@ void lvmcache_allow_reads_with_lvmetad(void);
|
||||
|
||||
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
|
||||
|
||||
/* Set full_scan to 1 to reread every filtered device label or
|
||||
* 2 to rescan /dev for new devices */
|
||||
int lvmcache_label_scan(struct cmd_context *cmd, int full_scan);
|
||||
/*
|
||||
* lvmcache_label_scan() will scan labels the first time it's
|
||||
* called, but not on subsequent calls, unless
|
||||
* lvmcache_force_next_label_scan() is called first
|
||||
* to force the next lvmcache_label_scan() to scan again.
|
||||
*/
|
||||
void lvmcache_force_next_label_scan(void);
|
||||
int lvmcache_label_scan(struct cmd_context *cmd);
|
||||
|
||||
/* Add/delete a device */
|
||||
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
|
||||
@@ -98,6 +104,7 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgname(const char *vgname,
|
||||
struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid);
|
||||
struct lvmcache_info *lvmcache_info_from_pvid(const char *pvid, int valid_only);
|
||||
const char *lvmcache_vgname_from_vgid(struct dm_pool *mem, const char *vgid);
|
||||
const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgname);
|
||||
struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct id *pvid,
|
||||
unsigned *scan_done_once, uint64_t *label_sector);
|
||||
const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
|
||||
@@ -193,5 +200,8 @@ int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
|
||||
void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
|
||||
unsigned *pv_max_name_len, unsigned *vg_max_name_len);
|
||||
|
||||
int lvmcache_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||
|
||||
void lvmcache_lock_ordering(int enable);
|
||||
|
||||
#endif
|
||||
|
||||
104
lib/cache/lvmetad.c
vendored
104
lib/cache/lvmetad.c
vendored
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -316,6 +316,15 @@ static int _lvmetad_handle_reply(daemon_reply reply, const char *action, const c
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Multiple VGs with the same name were found. */
|
||||
if (found && !strcmp(daemon_reply_str(reply, "response", ""), "multiple")) {
|
||||
log_very_verbose("Request to %s %s%sin lvmetad found multiple matching objects.",
|
||||
action, object, *object ? " " : "");
|
||||
if (found)
|
||||
*found = 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
log_error("Request to %s %s%sin lvmetad gave response %s. Reason: %s",
|
||||
action, object, *object ? " " : "",
|
||||
daemon_reply_str(reply, "response", "<missing>"),
|
||||
@@ -439,6 +448,14 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
|
||||
|
||||
while (alt_device) {
|
||||
dev_alternate = dev_cache_get_by_devt(alt_device->v.i, cmd->filter);
|
||||
|
||||
log_verbose("PV on device %s (%d:%d %d) is also on device %s (%d:%d %d) %s",
|
||||
dev_name(dev),
|
||||
(int)MAJOR(devt), (int)MINOR(devt), (int)devt,
|
||||
dev_alternate ? dev_name(dev_alternate) : "unknown",
|
||||
(int)MAJOR(alt_device->v.i), (int)MINOR(alt_device->v.i), (int)alt_device->v.i,
|
||||
pvid_txt);
|
||||
|
||||
if (dev_alternate) {
|
||||
if ((info_alternate = lvmcache_add(fmt->labeller, (const char *)&pvid, dev_alternate,
|
||||
vgname, (const char *)&vgid, 0))) {
|
||||
@@ -446,9 +463,6 @@ static int _pv_populate_lvmcache(struct cmd_context *cmd,
|
||||
info = info_alternate;
|
||||
lvmcache_get_label(info)->dev = dev_alternate;
|
||||
}
|
||||
} else {
|
||||
log_warn("Duplicate of PV %s dev %s exists on unknown device %"PRId64 ":%" PRId64,
|
||||
pvid_txt, dev_name(dev), MAJOR(alt_device->v.i), MINOR(alt_device->v.i));
|
||||
}
|
||||
alt_device = alt_device->next;
|
||||
}
|
||||
@@ -506,22 +520,39 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
|
||||
if (vgid) {
|
||||
if (!id_write_format((const struct id*)vgid, uuid, sizeof(uuid)))
|
||||
return_NULL;
|
||||
log_debug_lvmetad("Asking lvmetad for VG %s (%s)", uuid, vgname ? : "name unknown");
|
||||
}
|
||||
|
||||
if (vgid && vgname) {
|
||||
log_debug_lvmetad("Asking lvmetad for VG %s %s", uuid, vgname);
|
||||
reply = _lvmetad_send("vg_lookup",
|
||||
"uuid = %s", uuid,
|
||||
"name = %s", vgname,
|
||||
NULL);
|
||||
diag_name = uuid;
|
||||
|
||||
} else if (vgid) {
|
||||
log_debug_lvmetad("Asking lvmetad for VG vgid %s", uuid);
|
||||
reply = _lvmetad_send("vg_lookup", "uuid = %s", uuid, NULL);
|
||||
diag_name = uuid;
|
||||
} else {
|
||||
if (!vgname) {
|
||||
log_error(INTERNAL_ERROR "VG name required (VGID not available)");
|
||||
reply = _lvmetad_send("vg_lookup", "name = %s", "MISSING", NULL);
|
||||
goto out;
|
||||
}
|
||||
|
||||
} else if (vgname) {
|
||||
log_debug_lvmetad("Asking lvmetad for VG %s", vgname);
|
||||
reply = _lvmetad_send("vg_lookup", "name = %s", vgname, NULL);
|
||||
diag_name = vgname;
|
||||
|
||||
} else {
|
||||
log_error(INTERNAL_ERROR "VG name required (VGID not available)");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (_lvmetad_handle_reply(reply, "lookup VG", diag_name, &found) && found) {
|
||||
|
||||
if ((found == 2) && vgname) {
|
||||
log_error("Multiple VGs found with the same name: %s.", vgname);
|
||||
log_error("See the --select option with VG UUID (vg_uuid).");
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (!(top = dm_config_find_node(reply.cft->root, "metadata"))) {
|
||||
log_error(INTERNAL_ERROR "metadata config node not found.");
|
||||
goto out;
|
||||
@@ -1167,16 +1198,17 @@ struct _lvmetad_pvscan_baton {
|
||||
static int _lvmetad_pvscan_single(struct metadata_area *mda, void *baton)
|
||||
{
|
||||
struct _lvmetad_pvscan_baton *b = baton;
|
||||
struct volume_group *this;
|
||||
struct volume_group *vg;
|
||||
|
||||
if (!(this = mda_is_ignored(mda) ? NULL : mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1)))
|
||||
if (mda_is_ignored(mda) ||
|
||||
!(vg = mda->ops->vg_read(b->fid, "", mda, NULL, NULL, 1)))
|
||||
return 1;
|
||||
|
||||
/* FIXME Also ensure contents match etc. */
|
||||
if (!b->vg || this->seqno > b->vg->seqno)
|
||||
b->vg = this;
|
||||
if (!b->vg || vg->seqno > b->vg->seqno)
|
||||
b->vg = vg;
|
||||
else if (b->vg)
|
||||
release_vg(this);
|
||||
release_vg(vg);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -1305,6 +1337,7 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
|
||||
struct _lvmetad_pvscan_baton baton;
|
||||
/* Create a dummy instance. */
|
||||
struct format_instance_ctx fic = { .type = 0 };
|
||||
struct metadata_area *mda;
|
||||
|
||||
if (!lvmetad_active()) {
|
||||
log_error("Cannot proceed since lvmetad is not active.");
|
||||
@@ -1348,8 +1381,12 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
|
||||
* Note that the single_device parameter also gets ignored and this code
|
||||
* can scan further devices.
|
||||
*/
|
||||
if (!baton.vg && !(baton.fid->fmt->features & FMT_MDAS))
|
||||
baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, NULL, NULL, 1);
|
||||
if (!baton.vg && !(baton.fid->fmt->features & FMT_MDAS)) {
|
||||
/* This code seems to be unreachable */
|
||||
if ((mda = (struct metadata_area *)dm_list_first(&baton.fid->metadata_areas_in_use)))
|
||||
baton.vg = mda->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info),
|
||||
mda, NULL, NULL, 1);
|
||||
}
|
||||
|
||||
if (!baton.vg)
|
||||
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
|
||||
@@ -1725,7 +1762,8 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
||||
* Update the local lvmetad cache so it correctly reflects any
|
||||
* changes made on remote hosts.
|
||||
*/
|
||||
lvmetad_pvscan_all_devs(cmd, NULL);
|
||||
if (!lvmetad_pvscan_all_devs(cmd, NULL))
|
||||
stack; /* FIXME: Anything more on this error path ? */
|
||||
|
||||
/*
|
||||
* Clear the global_invalid flag in lvmetad.
|
||||
@@ -1735,7 +1773,7 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
||||
*/
|
||||
reply = daemon_send_simple(_lvmetad, "set_global_info",
|
||||
"token = %s", "skip",
|
||||
"global_invalid = %d", 0,
|
||||
"global_invalid = " FMTd64, INT64_C(0),
|
||||
NULL);
|
||||
if (reply.error)
|
||||
log_error("lvmetad_validate_global_cache set_global_info error %d", reply.error);
|
||||
@@ -1770,3 +1808,29 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force)
|
||||
_update_changed_pvs_in_udev(cmd, &pvc_before, &pvc_after);
|
||||
}
|
||||
}
|
||||
|
||||
int lvmetad_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid)
|
||||
{
|
||||
daemon_reply reply;
|
||||
struct dm_config_node *top;
|
||||
const char *system_id = NULL;
|
||||
char uuid[64];
|
||||
int ret;
|
||||
|
||||
if (!id_write_format((const struct id*)vgid, uuid, sizeof(uuid)))
|
||||
return_0;
|
||||
|
||||
reply = _lvmetad_send("vg_lookup",
|
||||
"uuid = %s", uuid,
|
||||
"name = %s", vgname,
|
||||
NULL);
|
||||
|
||||
if ((top = dm_config_find_node(reply.cft->root, "metadata")))
|
||||
system_id = dm_config_find_str(top, "metadata/system_id", NULL);
|
||||
|
||||
ret = !is_system_id_allowed(cmd, system_id);
|
||||
|
||||
daemon_reply_destroy(reply);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
5
lib/cache/lvmetad.h
vendored
5
lib/cache/lvmetad.h
vendored
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_METAD_H
|
||||
@@ -169,6 +169,8 @@ int lvmetad_pvscan_foreign_vgs(struct cmd_context *cmd, activation_handler handl
|
||||
int lvmetad_vg_clear_outdated_pvs(struct volume_group *vg);
|
||||
void lvmetad_validate_global_cache(struct cmd_context *cmd, int force);
|
||||
|
||||
int lvmetad_vg_is_foreign(struct cmd_context *cmd, const char *vgname, const char *vgid);
|
||||
|
||||
# else /* LVMETAD_SUPPORT */
|
||||
|
||||
# define lvmetad_init(cmd) do { } while (0)
|
||||
@@ -197,6 +199,7 @@ void lvmetad_validate_global_cache(struct cmd_context *cmd, int force);
|
||||
# define lvmetad_pvscan_foreign_vgs(cmd, handler) (0)
|
||||
# define lvmetad_vg_clear_outdated_pvs(vg) (1)
|
||||
# define lvmetad_validate_global_cache(cmd, force) do { } while (0)
|
||||
# define lvmetad_vg_is_foreign(cmd, vgname, vgid) (0)
|
||||
|
||||
# endif /* LVMETAD_SUPPORT */
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
srcdir = @srcdir@
|
||||
top_srcdir = @top_srcdir@
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -34,6 +34,32 @@ static unsigned _feature_mask;
|
||||
log_error(t " segment %s of logical volume %s.", ## p, \
|
||||
dm_config_parent_name(sn), seg->lv->name), 0;
|
||||
|
||||
/*
|
||||
* When older metadata are loaded without newer settings,
|
||||
* set then to default settings (the one that could have been
|
||||
* used implicitely at that time).
|
||||
*
|
||||
* Needs both segments cache and cache_pool to be loaded.
|
||||
*/
|
||||
static int _fix_missing_defaults(struct lv_segment *cpool_seg)
|
||||
{
|
||||
if (!cpool_seg->policy_name) {
|
||||
cpool_seg->policy_name = "mq";
|
||||
log_verbose("Cache is missing cache policy, using %s.",
|
||||
cpool_seg->policy_name);
|
||||
}
|
||||
|
||||
if (!cache_mode_is_set(cpool_seg)) {
|
||||
if (!cache_set_mode(cpool_seg, "writethrough")) {
|
||||
log_error(INTERNAL_ERROR "Failed to writethrough cache mode.");
|
||||
return 0;
|
||||
}
|
||||
log_verbose("Cache is missing cache mode, using %s.",
|
||||
get_cache_mode_name(cpool_seg));
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int _cache_pool_text_import(struct lv_segment *seg,
|
||||
const struct dm_config_node *sn,
|
||||
@@ -115,6 +141,10 @@ static int _cache_pool_text_import(struct lv_segment *seg,
|
||||
if (!attach_pool_metadata_lv(seg, meta_lv))
|
||||
return_0;
|
||||
|
||||
if (!dm_list_empty(&seg->lv->segs_using_this_lv) &&
|
||||
!_fix_missing_defaults(seg))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -194,20 +224,22 @@ static int _target_present(struct cmd_context *cmd,
|
||||
const struct dm_config_value *cv;
|
||||
const char *str;
|
||||
|
||||
if (!activation())
|
||||
return 0;
|
||||
|
||||
if (!_cache_checked) {
|
||||
_cache_present = target_present(cmd, "cache", 1);
|
||||
|
||||
if (!target_version("cache", &maj, &min, &patchlevel)) {
|
||||
log_error("Failed to determine version of cache kernel module");
|
||||
return 0;
|
||||
}
|
||||
|
||||
_cache_checked = 1;
|
||||
|
||||
if (!(_cache_present = target_present(cmd, "cache", 1)))
|
||||
return 0;
|
||||
|
||||
if (!target_version("cache", &maj, &min, &patchlevel))
|
||||
return_0;
|
||||
|
||||
if ((maj < 1) ||
|
||||
((maj == 1) && (min < 3))) {
|
||||
_cache_present = 0;
|
||||
log_error("The cache kernel module is version %u.%u.%u. "
|
||||
log_warn("WARNING: The cache kernel module is version %u.%u.%u. "
|
||||
"Version 1.3.0+ is required.",
|
||||
maj, min, patchlevel);
|
||||
return 0;
|
||||
@@ -319,6 +351,10 @@ static int _cache_text_import(struct lv_segment *seg,
|
||||
if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
|
||||
return_0;
|
||||
|
||||
if (!dm_list_empty(&pool_lv->segments) &&
|
||||
!_fix_missing_defaults(first_seg(pool_lv)))
|
||||
return_0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "lib.h"
|
||||
@@ -478,6 +478,7 @@ int process_profilable_config(struct cmd_context *cmd)
|
||||
|
||||
cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
|
||||
cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
|
||||
cmd->report_mark_hidden_devices = find_config_tree_bool(cmd, report_mark_hidden_devices_CFG, NULL);
|
||||
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
|
||||
cmd->report_list_item_separator = find_config_tree_str(cmd, report_list_item_separator_CFG, NULL);
|
||||
if (!(cmd->time_format = _set_time_format(cmd)))
|
||||
@@ -561,9 +562,9 @@ static int _process_config(struct cmd_context *cmd)
|
||||
#endif
|
||||
|
||||
dev_ext_info_src = find_config_tree_str(cmd, devices_external_device_info_source_CFG, NULL);
|
||||
if (!strcmp(dev_ext_info_src, "none"))
|
||||
if (dev_ext_info_src && !strcmp(dev_ext_info_src, "none"))
|
||||
init_external_device_info_source(DEV_EXT_NONE);
|
||||
else if (!strcmp(dev_ext_info_src, "udev"))
|
||||
else if (dev_ext_info_src && !strcmp(dev_ext_info_src, "udev"))
|
||||
init_external_device_info_source(DEV_EXT_UDEV);
|
||||
else {
|
||||
log_error("Invalid external device info source specification.");
|
||||
@@ -669,6 +670,8 @@ static int _process_config(struct cmd_context *cmd)
|
||||
/* LVM stores sizes internally in units of 512-byte sectors. */
|
||||
init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));
|
||||
|
||||
cmd->check_pv_dev_sizes = find_config_tree_bool(cmd, metadata_check_pv_device_sizes_CFG, NULL);
|
||||
|
||||
if (!process_profilable_config(cmd))
|
||||
return_0;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _LVM_TOOLCONTEXT_H
|
||||
@@ -113,6 +113,7 @@ struct cmd_context {
|
||||
* Switches.
|
||||
*/
|
||||
unsigned is_long_lived:1; /* optimises persistent_filter handling */
|
||||
unsigned check_pv_dev_sizes:1;
|
||||
unsigned handles_missing_pvs:1;
|
||||
unsigned handles_unknown_segments:1;
|
||||
unsigned use_linear_target:1;
|
||||
@@ -121,6 +122,7 @@ struct cmd_context {
|
||||
unsigned auto_set_activation_skip:1;
|
||||
unsigned si_unit_consistency:1;
|
||||
unsigned report_binary_values_as_numeric:1;
|
||||
unsigned report_mark_hidden_devices:1;
|
||||
unsigned metadata_read_only:1;
|
||||
unsigned ignore_clustered_vgs:1;
|
||||
unsigned threaded:1; /* set if running within a thread e.g. clvmd */
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user