1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-28 04:23:49 +03:00

Compare commits

...

314 Commits

Author SHA1 Message Date
Alasdair G Kergon
d05d7d974c pre-release 2016-01-25 01:08:16 +00:00
Peter Rajnoha
bc8f8ac0fa tests: add pv-check-dev-size.sh 2016-01-22 14:16:00 +01:00
Peter Rajnoha
136fd8f2f6 conf: add metadata/check_pv_device_sizes 2016-01-22 14:16:00 +01:00
Peter Rajnoha
c0912af310 metadata: check PV dev size is not less than PV size 2016-01-22 14:16:00 +01:00
Peter Rajnoha
1f5dfb7369 lvmcache: invalidate all cached dev sizes if all VGs got unlocked 2016-01-22 14:16:00 +01:00
Peter Rajnoha
d090d6574e device: also cache device size
Add "size" and "size_seqno" to struct device to cache device's size
and also to control its lifetime - the cached value is valid as long
as the global _dev_size_seqno is equal to the device's size_seqno,
otherwise we need to get the size again and cache the new value.

This patch also adds new dev_size_seqno_inc() fn for the appropriate
parts of the code to increment current global value of _dev_size_seqno
and hence to cause all currently cached values for device sizes to
be invalidated.

The device size is now cached because we're planning to reuse this
information for further checks and we want to avoid checking it more
than necessary to save resources.
2016-01-22 14:13:34 +01:00
David Teigland
dc388e0c7a lvmlockd: remove noisy log_debug
The debug message appeared even when lvmlockd was not used,
and the lockd operation was simply being skipped.
2016-01-21 14:37:15 -06:00
Peter Rajnoha
55056c2d16 vgimportclone: fix VG name variable reference in error message after failed PV uuid change 2016-01-21 14:47:48 +01:00
Zdenek Kabelac
22810155a6 cleanup: add missing prototype
Commit 2304286f68
missed to add function prototype.
2016-01-21 13:29:08 +01:00
Zdenek Kabelac
347575df1d toollib: restore command break support
Fix regression caused by c9f021de0b.
This commit actually transfered real-action (e.g. device removal)
into the next loop which has however missed to check for break.
So add check for break also there.
2016-01-21 13:29:07 +01:00
Zdenek Kabelac
c701d9cc8c toollib: use cmd mempool for list
When creating a list in 'context of command' - use proper mempool.

vg->vgmem is mempool related to VG metadata - and can be eventually
locked read-only when VG struct is shared.
2016-01-21 13:28:28 +01:00
Zdenek Kabelac
fcbef05aae doc: change fsf address
Hmm rpmlint suggest fsf is using a different address these days,
so lets keep it up-to-date
2016-01-21 12:11:37 +01:00
Zdenek Kabelac
cc53a23d82 cleanup: join if/else 2016-01-21 12:11:37 +01:00
Zdenek Kabelac
3e09f916b4 man: show hidden pieces
W: manual-page-warning /usr/share/man/man8/lvm.8.gz 491: warning: macro `_cdata',' not defined

rpmlint actually notices we had few hidden word in man page.
the line cannot start with apostrophe as it has then a different
meaning.
2016-01-21 12:11:35 +01:00
Zdenek Kabelac
640c45d5a4 man: dmsetup
Typo in CMD_UDEVCREATECOOKIE macro name noticed by rpmlint.
2016-01-21 12:10:26 +01:00
Peter Rajnoha
43b436398e configure: fix configure to set proper use_blkid_wiping if autodetected as disabled
If not using explicit --enable-blkid-wiping/--disable-blkid-wiping
configure option, the configure script tries to enable/disable blkid
wiping feature automatically based on blkid library version found.

The script incorrectly set default value for lvm.conf's
allocation/use_blkid_wiping" setting to "1" (enabled) if proper
blkid library version was not found or the version found was less
than the minimum required. It should be set to "0" in this case.
2016-01-21 10:01:34 +01:00
Zdenek Kabelac
21028a7903 cleanup: reformat sentence about max sizes
The extent size must fits all blocks in 4294967295 sectors
(in 512b units) this is 1/2 KiB less then 2TiB.

So while previous statement 'suggested' 2TiB is still acceptable value,
make it clear it's not.

As now we support any multiples of 128KB as extent size -
values like 2047G will still 'flow-in' otherwise the largest power-of-2
supported value is 1TiB.

With 1TiB user needs 8388608 extents for 8EiB device.
(FYI such device is already unusable with todays glibc-2.22.90-27)

4GiB extent size is currently the smallest extent size which allows
a user to create 8EiB devices (with 2GiB  it's less then 8EiB).

TODO: lvm2 may possibly print amount of 'lost/unused space' on a PV,
since using such ridiculously sized extent size may result in huge
space being left unaccessible.
2016-01-20 13:44:47 +01:00
Zdenek Kabelac
7b5a8f61a7 cleanup: drop extra cmd passed arg
Use vg->cmd when needed cmd struct.
2016-01-20 13:44:47 +01:00
Zdenek Kabelac
b64703401d cleanup: relocate size assign
Directly set thin-pool size when thin data LV size changes.
2016-01-20 13:44:47 +01:00
Zdenek Kabelac
ca878a3426 cleanup: adjust once 2016-01-20 13:44:47 +01:00
Zdenek Kabelac
178cbb580a cleanup: update check function
Use display_lvname().
Use lv_is_lockd_sanlock_lv().
Order  'error' checks ahead of 'ignore' ones.
2016-01-20 13:44:47 +01:00
Zdenek Kabelac
4b9ae55a8d cleanup: shuffle check of threshold
Check first threshold and then policy_amount.
2016-01-20 13:44:47 +01:00
Zdenek Kabelac
c99ca6f430 cleanup: use log_print
Using log_print for ignoring message instead of log_warn.
Add some missing '.'.
2016-01-20 13:44:47 +01:00
Alasdair G Kergon
2da7525c83 activation: remote node check doesn't work yet 2016-01-20 02:54:11 +00:00
Alasdair G Kergon
509410bbbc clvmd: Initialise udev.
Since commit 2fc126b00d, the library
code requires udev to be initialised for device scanning and
clvmd can fail to find VGs if devices/external_device_info_source
is set to "udev".
2016-01-20 00:58:09 +00:00
Alasdair G Kergon
2304286f68 activation: Add lv_is_active_remotely. 2016-01-19 22:01:59 +00:00
Alasdair G Kergon
c812c2dbc7 locking: Add node parameter to query_resource. 2016-01-19 21:42:22 +00:00
Peter Rajnoha
7f6a1e6bba man: mention GPT id for LVM in pvcreate man page 2016-01-19 15:28:44 +01:00
Peter Rajnoha
2a4ef78c4a report: fix off-by-one error when reporting LV segment's metadata device extent count
Commit a3f484f812 used "-1" two times by
mistake for the extent count when reporting seg_metadata_le_ranges.
2016-01-19 14:44:06 +01:00
Peter Rajnoha
acf1e84e8c report: add note about seg_pe_ranges and seg_le_ranges in -o help 2016-01-19 14:30:21 +01:00
Peter Rajnoha
1341f83554 report: add seg_le_ranges report field 2016-01-19 14:30:21 +01:00
Peter Rajnoha
fccb1bb276 report: make devices, metadata_devices, seg_pe_ranges and seg_metadata_le_ranges fields consistent
There are two basic groups of fields for LV segment device reporting:
  - related to LV segment's devices: devices and seg_pe_ranges
  - related to LV segment's metadata devices: metadata_devices and seg_metadata_le_ranges

The devices and metadata_devices report devices in this format:
    "device_name(extent_start)"

The seg_pe_ranges and seg_metadata_le_ranges report devices in
this format:
    "device_name:extent_start-extent_end"

This patch reverts partly what commit 7f74a99502
(v 2.02.140) introduced in this area - it added [] for
hidden devices to mark them for all four fields mentioned above.

We won't be marking hidden devices in devices and metadata_devices
fields.

The seg_metadata_le_ranges field will have hidden devices marked -
it's new enough that we don't need to care about compatibility much
yet.

The seg_pe_ranges is old enough that we shouldn't be changing this
one - so we're reverting to not marking hidden devices here.
Instead, there's going to be a new field "seg_le_ranges" which
is going to replace the seg_pe_ranges and it will mark hidden devices -
this is going to be introduced in a patch later.

So in the end we'll end up with:

   (LV segment's devices)
   devices field with "device_name(extent_start)" format, not marking hidden devices
   seg_pe_ranges field with "device_name:extent_start-extent_end" format, not marking hidden devices (deprecated, new seg_le_ranges should be used instead for standardized format)
   seg_le_ranges field with "device_name:extent_start-extent_end" format, marking hidden devices

   (LV segment's metadata devices)
   metadata_devices field with "device_name:extent_start-extent_end" format, not marking hidden devices
   seg_metadata_le_ranges field with "device_name:extent_start-extent_end" format, marking hidden devices

Also, both seg_le_ranges and seg_metadata_le_ranges will honour the
report/list_item_separator setting which can be used to configure
the delimiter used for list items.

So, to sum it up, we will recommend using the new seg_le_ranges and
seg_metadata_le_ranges fields because they display devices with
standard extent range format, they can mark hidden devices and they
honour the report/list_item_separator setting.

We'll be keeping devices,seg_pe_ranges and metadata_devices fields
for compatibility.
2016-01-19 14:30:20 +01:00
Peter Rajnoha
b160b73800 report: change _format_pvsegs to return list instead of plain string, change associated report fields from STR to STR_LIST
The associated devices,metadata_devices,seg_pe_ranges and
seg_metadata_le_ranges are reported as genuine string lists now.
This allows for using the items separately in -S|--select
(so searching for subsets etc.) and also it allows for
configuring the separator using report/list_item_separator
which may be useful in scripts (however, we'll enable this
only for seg_le_metadata_ranges and not for devices,seg_pe_ranges
and seg_metadata_devices for compatibility reasons - see following
patch).
2016-01-19 14:17:41 +01:00
Peter Rajnoha
2ed324648e refactor: add 'delimiter' variable for non-default delimiter when reporting string list 2016-01-19 11:50:52 +01:00
David Teigland
48f270970f lvconvert: disallow test mode in shared VG
until test mode can be checked in all the necessary
locations related to lvmlockd to prevent making
actual changes.
2016-01-18 16:53:14 -06:00
David Teigland
6b3e402298 toollib: add comment about missing device
Add a comment in _process_pvs_in_vg() to document the
place where there have been problems with processing
PVs twice.

For a while we had a hacky workaround here where we'd
skip processing a PV if its device wasn't found in
all_devices (and !is_missing_pv since we want to
process PVs with missing devices.).  That workaround
was removed in commit 5cd4d46f because it was no
longer needed.

The workaround had originally been needed to prevent
a device from being processed twice when the PV had
no MDAs -- it would be processed once in its real VG
and then the workaround would prevent it from being
processed a second time in the orphan VG.

Wrongly appearing as an orphan likely happened because
lvmcache would consider the no-MDA PV an orphan unless
the real VG holding that PV was also in lvmcache.
This issue is also mentioned in pvchange where holding
the global lock allows VGs to remain in lvmcache so
PVs with 0 mdas are not considered orphans.

The workaround in _process_pvs_in_vg() was originally
intended for reporting commands, not for pvchange.
But, it was accidentally helping pvchange also because
the method described by the pvchange global lock
comment had been subverted by commit 80f4b4b8.
Commit 80f4b4b8 was found to be unnecessary, and was
reverted in commit e710bac0.  This restored the
intended global lock lvmcache effect to pvchange, and
it no longer relied on the workaround in toollib.
2016-01-18 16:09:22 -06:00
Alasdair G Kergon
a3f484f812 report: Fix seg_pe_ranges LV sizes.
When reporting on LVs, take the end of the range from the size of the
underlying (hidden) LV rather than the logical size of the current
segment (that PVs use).
2016-01-18 22:04:43 +00:00
David Teigland
6d7dc87cb3 pvmove: use toollib
Previously, pvmove used the function find_pv_in_vg() which did the
equivalent of process_each_pv() by doing:

  find_pv_by_name() -> get_pvs() ->

  get_pvs_internal() -> _get_pvs() -> get_vgids() ->

  /* equivalent to process_each_pv */
  dm_list_iterate_items(vgids)
    vg = vg_read_internal()
    dm_list_iterate_items(&vg->pvs)

With the found 'pv', it would do vg_read() on pv_vg_name(pv),
and then do the actual pvmove processing.

This commit simplifies by using process_each_pv() and putting
the actual pvmove processing into the "single" function.
This eliminates both find_pv_by_name() and the vg_read().
The processing code that followed vg_read remains the same.

The return code for the pvmove command is not based on the
process_each_pv return code, but is based on the success/fail
conditions in the existing code.
2016-01-18 14:48:30 -06:00
David Teigland
5cd4d46f30 Revert "Revert "process_each_pv: remove unnecessary workaround""
This reverts commit 6d09c8c2c4.

Try again to remove the workaround.
2016-01-18 09:36:55 -06:00
David Teigland
06346eab84 lvmlockd: cosemtic improvements to logging
Also pass our name to sanlock so it appears in
the sanlock status output.
2016-01-18 09:35:21 -06:00
David Teigland
95ead96004 lvmlockd: fix lvb validation for conversion
Make the lvb validation rules for convert match
those for unlock (even though it would be very
unlikely or impossible for convert to deal with
zero lvb.)
2016-01-18 09:35:20 -06:00
David Teigland
54b41dcd53 pvchange, pvresize: fix lockd_gl() usage
When an orphan PV is changed/resized, the
lvmlockd global lock is converted from sh
to ex. If the command is changing two
orphan PVs, the conversion to ex should
be done only once.
2016-01-18 09:35:06 -06:00
Peter Rajnoha
1ee6af344b report: add kernel_cache_settings field
Existing cache_settings field displays the settings which are
saved in metadata. Add new kernel_cache_settings fields to display
the settings which are currently used by kernel, including fields
for which default values are used.

This way users have complete view of the set of cache settings
supported (and which they can set) and their values which are used
at the moment by kernel.

For example:

$  lvs -o name,cache_policy,cache_settings,kernel_cache_settings vg
  LV      Cache Policy Cache Settings                               KCache Settings
  cached1 mq    migration_threshold=1024,write_promote_adjustment=2 migration_threshold=1024,random_threshold=4,sequential_threshold=512,discard_promote_adjustment=1,read_promote_adjustment=4,write_promote_adjustment=2
  cached2 smq   migration_threshold=1024                            migration_threshold=1024
  cached3 smq   migration_threshold=2048
2016-01-18 14:42:29 +01:00
Alasdair G Kergon
7f62777041 post-release 2016-01-16 02:12:10 +00:00
Alasdair G Kergon
0faa27d4f5 pre-release 2016-01-16 02:11:21 +00:00
Peter Rajnoha
7559af2334 lvm2app: fix lvm2app to return either 0 or 1 for lvm_vg_is_{clustered,exported}
Fix lvm2app to return either 0 or 1 for lvm_vg_is_{clustered,exported},
including internal functions pvseg_is_allocated and vg_is_resizeable
which are not yet exposed in lvm2app but make them consistent with the
rest.
2016-01-15 14:42:18 +01:00
David Teigland
1752f5c31e lvmlockd: fixes for test mode
Get the test mode working (lvmlockd running with no
lock manager).
2016-01-14 16:01:29 -06:00
David Teigland
e710bac03d Revert "lvmcache: skip drop when vg_write lock is not held"
This reverts e28e22b9e1
The problem that that commit was fixing (pytest failure)
no longer appears with the current code, so the commit is
not needed.

That commit is a problem for pvchange, because it prevents
lvmcache from retaining VG metadata even while the global
lock is held.  pvchange holds the global lock to ensure
that VG metadata is kept in lvmcache throughout processing.
If the cache is not kept, a PV with zero MDAs will appear
first in its actual VG and then appear again in the orphan VG.
It wrongly appears a second time in the orphan VG only if
the actual VG is dropped from lvmcache.
2016-01-14 13:34:36 -06:00
Peter Rajnoha
b82d5ee092 report: add kernel_discards report field to display thin pool discard used in kernel
Thin pool discard mode set in metadata can be different from the one
actually used if any device underneath does not support that mode. Add
kernel_discard report field to make it possible to see this difference.
2016-01-14 16:54:12 +01:00
David Teigland
6d09c8c2c4 Revert "process_each_pv: remove unnecessary workaround"
This reverts commit be1b1f3d89.
2016-01-14 09:12:57 -06:00
Zdenek Kabelac
88400b599e lvmanip: fix last commit and drop else
In last commit when removing if() branch
this 'else' now has to be dropped.
2016-01-14 11:55:47 +01:00
Zdenek Kabelac
278c5509ee cleanup: order ac members 2016-01-14 11:34:05 +01:00
Zdenek Kabelac
c9a813bff8 cleanup: spaces 2016-01-14 11:34:05 +01:00
Zdenek Kabelac
7d2b7f2bd8 cleanup: replace log_warn 2016-01-14 11:34:05 +01:00
Zdenek Kabelac
2567d03e95 cleanup: explicit prohibition for virtual segs
Internal _alloc_init() is only called from allocate_extents(),
which already does prevent usage of virtual segments.

So mark as internal error early and do not process it any further.
2016-01-14 11:34:05 +01:00
Zdenek Kabelac
4310dfd4e1 cleanup: simplier formula 2016-01-14 11:34:05 +01:00
Zdenek Kabelac
ebcfd09ba9 cleanup: more readable check 2016-01-14 11:34:05 +01:00
Zdenek Kabelac
753a496348 snapshot: relocate alloc_snapshot_seg
Move alloc_snapshot_seg to snapshot_manip and make it local static.
2016-01-14 11:34:05 +01:00
Zdenek Kabelac
8857b22764 segtype: check for activation
Before setting static variable with check passed state,
detect if we are allowed to talk to driver.
2016-01-14 11:34:05 +01:00
Zdenek Kabelac
43897239b3 lvresize: check for poolmetadatasize arg earlier
Since we check for poolmetadatasize, we need to detect it before
actual test.
2016-01-14 11:34:04 +01:00
Zdenek Kabelac
526297296f lvmanip: add lv_is_snapshot
Add new test for  lv_is_snapshot().
Also move few other bitchecks into same place as remaining bit tests.

TODO: drop lv_is_merging_origin() and keep using lv_is_merging().
2016-01-14 11:34:04 +01:00
Alasdair G Kergon
01228b692b vgcfgrestore: Retain allocatable PV attribute.
pvchange -xn was getting lost.
All PVs were set to allocatable again after restore.

Moved setting ALLOCATABLE_PV outside pv_setup().
2016-01-14 00:46:45 +00:00
David Teigland
9e9c757541 vgchange: fix lockd_gl results
The wrong error value was being checked from lockd_gl()
in two cases.

Clarify the use of lockd_gl() in the lock-start case.
2016-01-13 16:40:02 -06:00
David Teigland
1b1f42b490 lvmlockd: fix exit code
libdaemon uses 1 for success
2016-01-13 16:40:02 -06:00
David Teigland
be1b1f3d89 process_each_pv: remove unnecessary workaround
The problem addressed by this workaround no longer
seems to exist, so remove it.  PVs with no mdas
no longer appear in both their actual VG and in
the orphan VG.
2016-01-13 10:46:04 -06:00
Peter Rajnoha
63d59254d9 lv: fix check for NULL origin_lv in _do_lv_origin_dup, cleanup _do_lvconvert_lv_dup 2016-01-13 17:11:05 +01:00
Peter Rajnoha
04d1a8a5e4 cleanup: rename 'invisible devices' to 'hidden devices' 2016-01-13 16:43:25 +01:00
Peter Rajnoha
939d296525 conf: fix 'the volume list' vs 'volume list' and '@*' 2016-01-13 15:47:26 +01:00
Peter Rajnoha
9a81881965 cleanup: rename 'invisible devices' to 'hidden devices' 2016-01-13 15:37:15 +01:00
Peter Rajnoha
1417ed304b cleanup: rename 'invisible devices' to 'hidden devices' 2016-01-13 15:22:46 +01:00
Peter Rajnoha
d2d5c5e6c9 WHATS_NEW: reports and invisible devices 2016-01-13 14:45:49 +01:00
Peter Rajnoha
efab21b411 test: add report-invisible.sh test 2016-01-13 14:37:09 +01:00
Peter Rajnoha
c66a83fdc3 tests: update tests to deal with invisible devices consistently 2016-01-13 13:55:24 +01:00
Peter Rajnoha
84a9f750fe cleanup: cleanup lv.h and put fns into categories for better readability 2016-01-13 12:17:00 +01:00
Peter Rajnoha
293abbb8d2 conf: update command_profile_template.profile.in 2016-01-13 12:16:58 +01:00
Peter Rajnoha
53b355a24b conf: regenerate 2016-01-13 12:01:55 +01:00
Peter Rajnoha
e168b5de75 conf: add report/mark_invisible_devices 2016-01-13 12:01:10 +01:00
Peter Rajnoha
7f74a99502 lv: use brackets for invisible devices when formatting device segments
Include brackets for the name if the dev is invisible.
This change applies to all callers of _format_pvsegs fn:
  - lvseg_devices (the "lvs -o devices")
  - lvseg_metadata_devices (the "lvs -o metadata_devices)
  - lvseg_seg_pe_ranges (the "lvs -o seg_pe_ranges")
  - lvseg_seg_metadata_le_ranges (the "lvs -o seg_metadata_le_ranges")
2016-01-13 11:20:04 +01:00
Peter Rajnoha
f1fe7af014 lv: add common lv_pool_lv fn for use in report and dup, use brackets for invisible devices
The common lv_pool_lv fn avoids code duplication and also
the reporting part now uses _lvname_disp and _uuid_disp to display
name and uuid respectively, including brackets for the name if the
dev is invisible.
2016-01-13 11:20:01 +01:00
Peter Rajnoha
42fcbc1fd4 lv: add common lv_metadata_lv fn for use in report and dup, use brackets for invisible devices
The common lv_metadata_lv fn avoids code duplication and also
the reporting part now uses _lvname_disp and _uuid_disp to display
name and uuid respectively, including brackets for the name if the
dev is invisible.
2016-01-13 11:19:58 +01:00
Peter Rajnoha
cdbf76b2f0 lv: add common lv_data_lv fn for use in report and dup, use brackets for invisible devices
The common lv_data_lv fn avoids code duplication and also
the reporting part now uses _lvname_disp and _uuid_disp to display
name and uuid respectively, including brackets for the name if the
dev is invisible.
2016-01-13 11:19:55 +01:00
Peter Rajnoha
d50cd9d8d7 lv: add common lv_mirror_log_lv for use in report and dup, use brackets for invisible devices
The common lv_mirror_log_lv fn avoids code duplication and also
the reporting part now uses _lvname_disp and _uuid_disp to display
name and uuid respectively, including brackets for the name if the
dev is invisible.
2016-01-13 11:19:51 +01:00
Peter Rajnoha
aae45a1f21 lv: add common lv_origin_lv fn for use in report and dup, use brackets for invisible devices
The common lv_origin_lv fn avoids code duplication and also
the reporting part now uses _lvname_disp and _uuid_disp to display
name and uuid respectively, including brackets for the name if the
dev is invisible.
2016-01-13 11:19:45 +01:00
Peter Rajnoha
1bd83814ce lv: add common lv_convert_lv fn for use in report and dup, use brackets for invisible devices
The common lv_convert_lv fn avoids code duplication and also
the reporting part now uses _lvname_disp and _uuid_disp to display
name and uuid respectively, including brackets for the name if the
dev is invisible.
2016-01-13 11:16:37 +01:00
David Teigland
9e336582f4 man lvmlockd: mention pvmove restriction 2016-01-12 12:01:53 -06:00
David Teigland
0c6946b4ce pvmove: disallow moving PVs under sanlock leases
Fail with an error message if pvmove tries to move PVs
under the lvmlock LV.
2016-01-12 11:53:33 -06:00
Peter Rajnoha
176b4aaebe report: use proper string reference in _string_disp call for _cache_policy_disp fn 2016-01-12 16:14:23 +01:00
Ondrej Kozina
1a3ee6402e test: conditional skip of auto-activation bg polling test
if dm-snapshot-merge target not present skip whole test
2016-01-12 13:32:23 +01:00
Ondrej Kozina
d1e30ff0ba vgchange: drop redundant check
check for background polling option is performed from
within vgchange_background_polling routine as well.
2016-01-12 11:41:41 +01:00
Ondrej Kozina
d09246a07d test: add test for autoactivation regression
add test for a regression fixed in
40701af969
2016-01-12 11:40:43 +01:00
Ondrej Kozina
40701af969 pvscan: restore polling in autoactivation handler
This commit fixes regression in auto-activation code introduced
in commit: c26d81d6e6.

- resolves rhbz1295562
2016-01-12 11:40:43 +01:00
Peter Rajnoha
d6cf83968c report: use brackets to signify LVs which are not visible when reporting lv_parent
Use common _lvname_disp to report lv_parent. The _lvname_disp
takes care of properly marking LVs which are not visible - such
LVs are always enclosed in brackets when reported within any
other field.

For example, thin pool over RAID.

Before:

$ lvs -a -o name,lv_parent,data_lv,metadata_lv vg
  LV                          Parent           Data               Meta
  cache_pool                                   [cache_pool_tdata] [cache_pool_tmeta]
  [cache_pool_tdata]          cache_pool
  [cache_pool_tdata_rimage_0] cache_pool_tdata
  [cache_pool_tdata_rimage_1] cache_pool_tdata
  [cache_pool_tdata_rmeta_0]  cache_pool_tdata
  [cache_pool_tdata_rmeta_1]  cache_pool_tdata
  [cache_pool_tmeta]          cache_pool
  [cache_pool_tmeta_rimage_0] cache_pool_tmeta
  [cache_pool_tmeta_rimage_1] cache_pool_tmeta
  [cache_pool_tmeta_rmeta_0]  cache_pool_tmeta
  [cache_pool_tmeta_rmeta_1]  cache_pool_tmeta
  [lvol0_pmspare]

With this patch applied:

$ lvs -a -o name,lv_parent,data_lv,metadata_lv vg
  LV                          Parent             Data               Meta
  cache_pool                                     [cache_pool_tdata] [cache_pool_tmeta]
  [cache_pool_tdata]          cache_pool
  [cache_pool_tdata_rimage_0] [cache_pool_tdata]
  [cache_pool_tdata_rimage_1] [cache_pool_tdata]
  [cache_pool_tdata_rmeta_0]  [cache_pool_tdata]
  [cache_pool_tdata_rmeta_1]  [cache_pool_tdata]
  [cache_pool_tmeta]          cache_pool
  [cache_pool_tmeta_rimage_0] [cache_pool_tmeta]
  [cache_pool_tmeta_rimage_1] [cache_pool_tmeta]
  [cache_pool_tmeta_rmeta_0]  [cache_pool_tmeta]
  [cache_pool_tmeta_rmeta_1]  [cache_pool_tmeta]
  [lvol0_pmspare]
2016-01-11 15:34:35 +01:00
Peter Rajnoha
f03a21f5b8 cleanup: use _field_set_value and _string_disp consistently in report.c
Do not mix dm_report_field_set_value and _field_set_value and
use single function call throughout for clarity. The same applies
for dm_report_field_string and _string_disp.
2016-01-11 15:01:42 +01:00
Peter Rajnoha
a83d611a86 report: fix invalid memory read when reporting cache LV policy name
Fix regression caused by commit c2d4330f27
which removed the dm_pool_strdup for the cache policy name in
_cache_policy_disp report function.

This regression was hit with buffered reporting only (which is
used by default). The reason is that for buffered reporting, we're
iterating over LVs in VG (process_each_lv) while gathering
all the information that is needed for the report. In this case,
the LV's cache policy name has not been duped, but only the pointer
to the original VG buffer was stored. When the LV iteration finished,
the VG buffer was freed and any report to output called later
(dm_report_output call) accessed already freed VG data.

This didn't appear if unbuffered reporting was used (--unbuffered)
because in this case, the data were reported to output as
soon as they were processed, hence it was reported to output
before the VG data was freed.
2016-01-11 12:51:08 +01:00
Alasdair G Kergon
0dac4f09b4 post-release 2016-01-08 18:51:08 +00:00
Alasdair G Kergon
04b82a8126 pre-release 2016-01-08 18:46:41 +00:00
David Teigland
580c67486f document commits since last release 2016-01-08 09:53:58 -06:00
Peter Rajnoha
8d11468ab2 man: lvs: document F,D and M thin pool health status chars for lv_attr in lvs man page 2016-01-08 15:47:01 +01:00
Peter Rajnoha
4304a95dfd lvmdump: also add lvm2-activation{-early,-net}.service systemd status for lvmdump -s
The lvm2-activation{-early,-net}.service systemd unit statuses were missing
in dump gathered by lvmdump -s. These are quite important when debugging
scenarios with systemd environment and where lvmetad is not used.
2016-01-04 15:12:25 +01:00
David Teigland
124b490fe6 lvmlockd: update VG lock version earlier
Have commands send lvmlockd the update message
in vg_write instead of vg_commit, so that it's
not done while LVs are suspended.  If the vg_write
is not committed, and the seqno sent to lvmlockd
is not used, then lvmlockd can detect this when
the next update uses the same seqno.
2015-12-15 16:14:49 -06:00
David Teigland
796461a912 vgrename: use process_each_vg
Use process_each_vg() to lock and read the old VG,
and then call the main vgrename code.

When real VG names are used (not a UUID in place of the
old name), the command still pre-locks the new name
(when strcmp wants it locked first), before calling
process_each_vg on the old name.

In the case where the old name is replaced with a UUID,
process_each_vg now translates that UUID into the real
VG name, which it locks and reads.  In this case, we
cannot do pre-locking to maintain lock ordering because
the old name is unknown.  So, in this case the strcmp
based lock ordering is suppressed and the old name is
always locked first.  This opens a remote chance for
lock ordering conflict between racing vgrenames between
two names where one or both commands use the UUID.
2015-12-14 14:26:47 -06:00
Alasdair G Kergon
37bd35bc3d pvscan: Remove duplicate filter wipe.
Also always clear the internal lvmcache after rescanning, and
reinstate a test for --trustcache so that 'pvs --trustcache'
(for example) avoids rescanning.
2015-12-14 20:14:59 +00:00
David Teigland
92e1422707 process_each_pv: do full scan earlier to find new devices
Before commit c1f246fedf,
_get_all_devices() did a full device scan before
get_vgnameids() was called.  The full scan in
_get_all_devices() is from calling dev_iter_create(f, 1).
The '1' arg forces a full scan.

By doing a full scan in _get_all_devices(), new devices
were added to dev-cache before get_vgnameids() began
scanning labels.  So, labels would be read from new devices.
(e.g. by the first 'pvs' command after the new device appeared.)

After that commit, _get_all_devices() was called
after get_vgnameids() was finished scanning labels.
So, new devices would be missed while scanning labels.
When _get_all_devices() saw the new devices (after
labels were scanned), those devices were added to
the .cache file.  This meant that the second 'pvs'
command would see the devices because they would be
in .cache.

Now, the full device scan is factored out of
_get_all_devices() and called by itself at the
start of the command so that new devices will
be known before get_vgnameids() scans labels.
2015-12-14 10:02:29 -06:00
Alasdair G Kergon
1be56e46c4 post-release 2015-12-14 12:25:48 +00:00
Alasdair G Kergon
3e8126a66a pre-release 2015-12-14 12:24:21 +00:00
David Teigland
4aa9e99a10 Change messages from verbose to debug
These messages about outdated PVs should not
be verbose because they always appear, even
when there are no outdated PVs.
2015-12-11 15:28:46 -06:00
Zdenek Kabelac
3e48354f2d cleanup: add missing WHATS_NEW 2015-12-11 20:15:57 +01:00
Zdenek Kabelac
07b9147ced tests: check lvrename of stacked cache pool 2015-12-11 20:15:57 +01:00
Riku Voipio
7a4badc07f fix static linking
Static linking fails currently, as -lm and -lpthread are missing:

gcc -O2  -fPIC -O2  -L../libdm -L../lib -L../libdaemon/client -static
-L../libdm/ioctl \
      -o dmsetup.static dmsetup.o -ldevmapper    -lrt
../libdm/ioctl/libdevmapper.a(libdm-stats.o): In function
`dm_stats_create_region':
libdm-stats.c:(.text+0x2d69): undefined reference to `log10'
libdm-stats.c:(.text+0x2d6e): undefined reference to `lround'
../libdm/ioctl/libdevmapper.a(pool.o): In function `dm_pool_create':
pool.c:(.text+0x134): undefined reference to `pthread_mutex_lock'
pool.c:(.text+0x14f): undefined reference to `pthread_mutex_unlock'

Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
2015-12-11 20:15:51 +01:00
Zdenek Kabelac
0688dbbc53 tests: fix logging
Actually  file redirection must be before stderr redir.
2015-12-10 21:01:24 +01:00
Zdenek Kabelac
cd8e95d933 lvrename: always allow to rename pools
Since we mark cache-pool as 'hidden/private' while it is in-use,
we may still allow user to change it's name.

It should not cause any harm and user may prefer better naming
for a cache-pool in use.
2015-12-10 21:01:24 +01:00
Zdenek Kabelac
bf4b74c5eb cache: support stacked rename
Preserve skip_pool flag when running for_each_sub_lv() so
lvrename continues to work when thin-pool is using cached
data LV.
2015-12-10 21:01:24 +01:00
David Teigland
dcb26b5f13 lvmlockd: reconnect to lvmetad if it's restarted
If lvmetad is restarted after lvmlockd has connected
to it, then lvmlockd should reconnect.
2015-12-10 10:50:19 -06:00
David Teigland
bdba4e7a93 lvrename: move the lvmlockd LV lock
The function it was in is used for various
internal renaming of hidden LVs where a lock
from lvmlockd does not apply.
2015-12-09 11:59:49 -06:00
Alasdair G Kergon
dcd946e95a dmeventd: Don't trust fifo with wrong attrs.
If an existing fifo has the wrong attributes it cannot be trusted
so we must unlink it and recreate it correctly.
(Replaces 2c8d6f5c90: if the other end of
the fifo already got opened while its mode was insecure, delaying the
chmod isn't going to make any difference!)
2015-12-08 01:48:17 +00:00
Alasdair G Kergon
94dab390ef dmeventd: Extend checks on client socket.
Reinstate and extend checks removed by e1b111b02a.

The code has always assumed that only root has access to the directory
containing the fifos and that they are under the complete control of
dmeventd code.  If anything is found not to be as expected, then open()
should certainly not be attempted!
2015-12-08 00:59:39 +00:00
Alasdair G Kergon
00bab9d9cd post-release 2015-12-05 15:36:22 +00:00
Alasdair G Kergon
063b353b28 pre-release 2015-12-05 15:33:19 +00:00
Zdenek Kabelac
fedf15ffb0 tests: extend test 2015-12-04 22:10:30 +01:00
Zdenek Kabelac
748b8158b5 archiver: fix reporting for check_current_backup
It's getting a bit more complex here.

Basic idea behind is - check_current_backup() should not
log error when a user is using a read-only filesystem,
so e.g.  vgscan  will not report any error when it tries
to take missing backup.

We still have cases when error could be reported though,
e.g. the backup this would be a symbolic link, but these
are rather misconfiguration and unexpected case.
2015-12-04 22:10:30 +01:00
Zdenek Kabelac
8b16efd17c debug: correct stack tracing
Here the 'goto' is correct path, as  !device_is_usable
is traceable with <backtrace>.

Keep the 'stack' for unusable device.
2015-12-04 22:10:30 +01:00
Zdenek Kabelac
45781161f4 libdm: add some doc for mirror status
Comment content of struct for mirror status.
2015-12-04 22:10:30 +01:00
Alasdair G Kergon
c24d913c47 lvconvert: Reinstate raid merge after splitmirror.
After commit 46c8d6bb8a
(lvconvert: Improve message for raid without -m)
2015-12-03 17:40:10 +00:00
Zdenek Kabelac
89418c1253 tests: check read-only backup archive 2015-12-03 18:17:45 +01:00
Zdenek Kabelac
d2524315e6 vgextend: reinstantiate archiving
Since commit f5d06efbab we lost archiving.
Restore it now with process_each_vg.
2015-12-03 18:17:45 +01:00
Zdenek Kabelac
e7978c5ab6 cleanup: drop log_suppress(2) usage
No longer need to use  log_suppress(2) instance so dropped.
2015-12-03 18:02:34 +01:00
Zdenek Kabelac
f40b3ba1e9 archiver: inital change toward proper logging
We have to modes of  'archive()' usage -
1. compulsory - fail stops command and user may try '-An' option
to do a command.

2. non-compulsory - some fails in archiving are ignorable (i.e.
read-only filesystem where archive dir is located).

Those 2 cases needs to be properly handle - i.e. the non-compulsory
logging should not be tampering  error logging message production.

So more work here is needed
2015-12-03 18:01:45 +01:00
Zdenek Kabelac
20acc66a23 log: use full buffer size for printf
Pass full buffer size to printf() function - no reason to make
buffer 1 char smaller.

Also rename locn buffer to message buffer directly since it's
not used for anything else.

TODO: we may use same buffer also for 'buf[]' since there is
no collision - so may safe 1K on stack usage.
2015-12-03 18:01:42 +01:00
Zdenek Kabelac
20483ead5b cleanup: use try_id_read_format
Better then using log_suppress in this case.
2015-12-03 18:00:54 +01:00
Zdenek Kabelac
c15c44a492 uuid: add id_read_format_try
Provide id_read_format() functionality without log_error
when ID is not valid one - it will just return 0.

Does not need to use log_suppress() then.
2015-12-03 18:00:38 +01:00
Alasdair G Kergon
aec58c8620 lvconvert: Reinstate mirror to raid conversions.
Reinstate conversions from mirror to raid stopped
by commit 46c8d6bb8a
(lvconvert: Improve message for raid without -m).
2015-12-03 14:40:14 +00:00
David Teigland
3bbf89e9ec man lvm: add section about unique VG names 2015-12-02 10:37:25 -06:00
David Teigland
61573bd197 toollib: only interpret vgname arg as uuid for vgrename
In general, --select should be used to specify a VG by UUID,
but vgrename already allows a uuid to be substituted for
the name, so continue to allow it in that case.
2015-12-01 15:50:14 -06:00
David Teigland
166adf0e1f toollib: allow VG UUID to be used in place of VG name
If the VG arg from the command line does not match the
name of any known VGs, then check if the arg looks like
a UUID.  If it's a valid UUID, then compare it to the
UUID of known VGs.  If it matches the UUID of a known VG,
then process that VG.
2015-12-01 12:08:24 -06:00
David Teigland
67763a9bec lvresize: use process_each_vg
No functional change.
2015-12-01 11:01:26 -06:00
David Teigland
5bbbd37f41 lvrename: use process_each_vg
No functional change.
2015-12-01 09:54:33 -06:00
David Teigland
f7571eb287 lvcreate: use process_each_vg
No functional change.
2015-12-01 09:36:52 -06:00
David Teigland
ea74215fa1 vgextend: pass single vgname as process_each_vg arg
Pass the single vgname as a new process_each_vg arg
instead of setting a cmd flag to tell process_each_vg
to take only the first vgname arg from argv.

Other commands with different argv formats will be
able to use it this way.
2015-12-01 09:36:45 -06:00
David Teigland
3bcdf5d14b lvmcache: change duplicate VG name warnings to verbose
When two different VGs with the same name exist,
they are both stored in lvmcache using the vginfo->next
list.  Previously, the code would print warnings (sometimes)
when adding VGs to this list.  Now the duplicate VG names
are handled by higher level code, so this list no longer
needs to print warnings about duplicate VG names being found.
2015-12-01 09:30:23 -06:00
David Teigland
88cef47b18 vg_read: look up vgid from name
After recent changes to process_each, vg_read() is usually
given both the vgname and vgid for the intended VG.

However, in some cases vg_read() is given a vgid with
no vgname, or is given a vgname with no vgid.

When given a vgid with no vgname, vg_read() uses lvmcache
to look up the vgname using the vgid.  If the vgname is
not found, vg_read() fails.

When given a vgname with no vgid, vg_read() should also
use lvmcache to look up the vgid using the vgname.
If the vgid is not found, vg_read() fails.

If the lvmcache lookup finds multiple vgids for the
vgname, then the lookup fails, causing vg_read() to fail
because the intended VG is uncertain.

Usually, both vgname and vgid for the intended VG are passed
to vg_read(), which means the lvmcache translations
between vgname and vgid are not done.
2015-12-01 09:18:48 -06:00
David Teigland
1e43ec15ce toollib: remove unused function 2015-12-01 09:10:01 -06:00
David Teigland
aa4932674a process_each: resolve duplicate VG names
If two different VGs with the same name exist on the system,
a command that just specifies that ambiguous name will fail
with a new error:

$ vgs -o name,uuid
  ...
  foo qyUS65-vn32-TuKs-a8yF-wfeQ-7DkF-Fds0uf
  foo vfhKCP-mpc7-KLLL-Uh08-4xPG-zLNR-4cnxJX

$ lvs foo
  Multiple VGs found with the same name: foo
  Use the --select option with VG UUID (vg_uuid).

$ vgremove foo
  Multiple VGs found with the same name: foo
  Use the --select option with VG UUID (vg_uuid).

$ lvs -S vg_uuid=qyUS65-vn32-TuKs-a8yF-wfeQ-7DkF-Fds0uf
  lv1 foo ...

This is implemented for process_each_vg/lv, and works
with or without lvmetad.  It does not work for commands
that do not use process_each.

This change includes one exception to the behavior shown
above.  If one of the VGs is foreign, and the other is not,
then the command assumes that the intended VG is the local
one and uses it.
2015-12-01 09:09:55 -06:00
David Teigland
4ff2583dc5 process_each: always use list of vgnames on system
This makes process_each_vg/lv always use the list of
vgnames on the system.  When specific VGs are named on
the command line, the corresponding entries from
vgnameids_on_system are moved to vgnameids_to_process.

Previously, when specific VGs were named on the command
line, the vgnameids_on_system list was not created, and
vgnameids_to_process was created from the arg_vgnames
list (which is only names, without vgids).

Now, vgnameids_on_system is always created, and entries
are moved from that list to vgnameids_to_process -- either
some (when arg_vgnames specifies only some), or all (when
the command is processing all VGs, or needs to look at
all VGs for checking tags/selection).

This change adds one new lvmetad lookup (vg_list) to a
command that specifies VG names.  It adds no new work
for other commands, e.g. non-lvmetad commands, or
commands that look at all VGs.

When using lvmetad, 'lvs foo' previously sent one
request to lvmetad: 'vg_lookup foo'.
Now, 'lvs foo' sends two requests to lvmetad:
'vg_list' and 'vg_lookup foo <uuid>'.

(The lookup can now always include the uuid in the request
because the initial vg_list contains name/vgid pairs.)
2015-12-01 09:09:49 -06:00
Zdenek Kabelac
68e2ea11a3 mirror: fix condition
Recent patch tested wrong condition for error
2015-12-01 13:59:20 +01:00
Zdenek Kabelac
86e7894ecc cleanup: use dm_get_status_mirror
Use libdm function to parse mirror status report.
2015-12-01 13:03:16 +01:00
Zdenek Kabelac
6336ef98d4 lib: pass mem pool to check_transient_status
check_transient_status() may need to allocate some memory,
so pass in already existing mem pool.
2015-12-01 13:01:28 +01:00
Zdenek Kabelac
c717ea5fc0 tests: unit test for mirror status 2015-12-01 13:00:52 +01:00
Zdenek Kabelac
fa87979004 libdm: introduce dm_get_status_mirror
Add missing function to parse mirror status.
2015-12-01 13:00:43 +01:00
Alasdair G Kergon
46c8d6bb8a lvconvert: Improve message for raid without -m. 2015-11-30 22:36:05 +00:00
David Teigland
eb22f7c8f7 lvmcache: new function to check if VG is foreign
When not using lvmetad, this uses the system_id field in
the cached vginfo structs that are populated during a scan.

When using lvmetad, this requests the VG from lvmetad, and
checks the system_id field in the returned metadata.
2015-11-30 11:54:56 -06:00
David Teigland
05ac836798 system_id: refactor check for allowed system_id
Refactor the code that checks for an allowable system_id
so that it can be used from other places.
2015-11-30 11:46:55 -06:00
David Teigland
d3ca18e489 lvmcache: include system_id in vginfo cache
Save system_id just like creation_host and lock_type
strings in vginfo cache.
2015-11-30 11:32:17 -06:00
David Teigland
1f357532bb lvmetad: include both vgid and vgname in lookup request
When the command already knows both the vgid and vgname,
it should send both to lvmetad for a more exact request,
and it can save lvmetad the work of a name lookup.
2015-11-30 10:57:30 -06:00
Alasdair G Kergon
cd4d2cff97 post-release 2015-11-28 01:29:00 +00:00
Alasdair G Kergon
b4a3aaf910 pre-release 2015-11-28 01:25:53 +00:00
Zdenek Kabelac
1fb8d746d6 tests: make unit testing usable again
Make unit tests usable/compilable with newer header files.
Add 'initial' dmlist_t  for list tests.
More will come...
2015-11-27 11:22:21 +01:00
Zdenek Kabelac
ec647f1d43 cleanup: clean gcc shadow declaration of version warning 2015-11-26 21:52:22 +01:00
Zdenek Kabelac
4afe43e1a3 debug: show LV name where dlid creation failed 2015-11-26 21:52:05 +01:00
Zdenek Kabelac
922fccc656 cleanup: using display_lvname
Use for showing vgname/lvname in messages.
No functional change.
2015-11-26 09:27:37 +01:00
Zdenek Kabelac
b7b59ad932 cleanup: remove unused code
Remove long outstand unused code lines, which were already
been obsoleted by other code.

Statuses and snapshot tree creation is already handled differently.

Also drop some 'extra' log_error() and use only stack;
since error has already been reported.
2015-11-26 09:27:37 +01:00
Zdenek Kabelac
528695ec20 cleanup: avoid allocation for vg_name
Since we do not use dev_manager in a way we would have destroyed VG
content while  in-use - we could safely keep just pointer.
So dropping strdup.

Also it seems we actually no longer use vg_name for anything
so it may possibly go away completely unless it would be useful
for debugging...
2015-11-26 09:27:37 +01:00
Zdenek Kabelac
d582be43d4 libdm: const raid params and error for unsupported type
Accept const struct with raid params (No API change).
Also add extra error message when raid type is unsupported.
2015-11-26 09:27:04 +01:00
Peter Rajnoha
1ea8afd3ca lvmconfig: add --sinceversion for --type new
Just for convenience to display all new configuration settings
introduced since given version (before, there was only --atversion
to display settings introduced in concrete version).

For example:
	$ lvmconfig --type new --sinceversion 2.2.120
	allocation {
		# cache_mode="writethrough"
		# cache_settings {
		# }
	}
	global {
		use_lvmlockd=0
		# lvmlockd_lock_retries=3
		# sanlock_lv_extend=256
		use_lvmpolld=1
	}
	activation {
	}
	# report {
		# compact_output_cols=""
		# time_format="%Y-%m-%d %T %z"
	# }
	local {
		# host_id=0
	}
2015-11-25 14:12:12 +01:00
Zdenek Kabelac
66c7fa4a44 cleanup: rename lv_ondisk to lv_committed
Patch has no functional change.
2015-11-25 11:39:26 +01:00
Zdenek Kabelac
4312b09635 cleanup: change ondisk committed
Patch has no functional change.
2015-11-25 11:39:26 +01:00
Zdenek Kabelac
d9faf85987 cleanup: rename vg_ondisk to vg_committed
Unifying terminology.

Since all the metadata in-use are ALWAYS on disk - switch
to terminology  committed and precommitted.

Patch has no functional change inside.
2015-11-25 11:11:21 +01:00
Zdenek Kabelac
0285066e10 thin: fix previous update of partial tree building
We do want to preserve 'active' thin-pool,
so add this 'fake' layer only when activating.

TODO:  think how to use thin-pool without fake LV layer.
2015-11-24 23:24:11 +01:00
Zdenek Kabelac
8d86c5db03 tests: improve teardown
Do not try to execute vgremove, when test has left suspended devices.
2015-11-24 11:29:28 +01:00
Zdenek Kabelac
a220939d9e tests: data correctness after thin-pool resize 2015-11-24 11:29:27 +01:00
Zdenek Kabelac
9243877ea1 cleanup: use display_lvname
Switch debug msg to use display_lvname.
Link to VG early, so we have access to VG from LV.
2015-11-23 23:42:59 +01:00
Zdenek Kabelac
5e50e5f0b4 thin: skip detach preload from pools
lv preload for detached LVs started to be used also
for various other types which just happens to pass through
weak if() condition.

TODO: find here better solution to rather explicitly check
for types we really need to preload.
2015-11-23 23:42:59 +01:00
Zdenek Kabelac
6d6c233768 cleanup: move towards using direct LV pointers
We do not won't to 'expose'  internals of VG struct.
ATM we use lists to keep all LVs - we may want to switch
to better struct for quicker 'search'.

Since we do not need 'lists' but always actual LV,
switch find_lv_in_vg_by_lvid() to return LV,
and replaces some use case of  find_lv_in_vg()
with 'better' working find_lv() which already
returns LV.
2015-11-23 23:42:59 +01:00
Zdenek Kabelac
94c9453659 thin: work with active thin-pool
When 'lvextend -L+XX vg/thinpool'  do not leave inactive table
loaded for 'wrapping' LV on top of resized thin-pool
(ATM we use linear  LV for this with same size as thin-pool).
2015-11-23 23:41:36 +01:00
Zdenek Kabelac
15be97d76b memlock: add more libs on ignore list
Udev recently start to 'link-in' major amount of useless libs.
(Seem to be faulty 'systemd' link-in all issue)
Anyway - avoid locking those libs in RAM.
2015-11-23 23:39:01 +01:00
Zdenek Kabelac
6ca5447e0c libdm: enhance thin-pool preload
When preloading thin-pool device node for already
existing/running thin-pool do not resume such thin-pool.

This allows to properly schedule commit point for metadata,
when thin-pool data or metadata volume is resized.
2015-11-23 23:34:46 +01:00
Zdenek Kabelac
ddbf0075b1 libdm: drop extra space from cache target line
Extra space between 'cache' target and metadata device caused
string comparation being not equal and thus always causing
table reload even when uneeded.
2015-11-23 23:33:37 +01:00
David Teigland
fe64d3a2e2 man lvmcache: include chunk size 2015-11-23 11:57:41 -06:00
Alasdair G Kergon
c026846739 post-release 2015-11-23 03:40:34 +00:00
Alasdair G Kergon
369bc264b0 pre-release 2015-11-23 03:37:54 +00:00
Zdenek Kabelac
da50f8bee6 tests: more cache conversion checks 2015-11-19 14:40:49 +01:00
Zdenek Kabelac
795616a87b cache: lvconvert repairs only thin pools
Avoid internal error message where thin pool repair code tries to
fix cache pool - was catched later in code stack, so rather
catch this early and make the repair function exlusive
to thin pools.

So far we have no code for repairing cache pools
(other then the automatic during activation/deactivation).
2015-11-19 14:40:24 +01:00
Zdenek Kabelac
d1608345df cache: enable raid conversion for _cdata and _cmeta
Since thin-pool supports convertion of data and metadata LV,
enable the same for cache data and metadata LV.
2015-11-19 14:38:36 +01:00
Marian Csontos
6f002c29a5 tests: stacktrace on skip if message is empty 2015-11-19 12:18:33 +01:00
Marian Csontos
2a23550cf3 tests: add missing --skip option and S env.variable 2015-11-19 12:00:59 +01:00
Zdenek Kabelac
0614c63579 cleanup: cast resulting value explicitely 2015-11-19 11:59:19 +01:00
Zdenek Kabelac
0b2be60497 cleanup: add stack traces 2015-11-18 22:17:26 +01:00
Zdenek Kabelac
e2b00b0a89 cleanup: use display_lvname in pmspare
Just switch to use display_lvname().
Also squeeze possibly failing strncpy into INTERNAL_ERROR
as lvname always should fit.
2015-11-18 22:17:26 +01:00
Peter Rajnoha
0a2cadf6b8 libdm: report: consolidate use of string list selection structures 2015-11-18 10:54:09 +01:00
David Teigland
7b11ef6de0 tests: update lvmcache-exercise
To handle multiple VGs with the same name.
Simply using the VG name is ambiguous, and
lvmetad requires the VG uuid be used to
specify which one is meant.
2015-11-17 12:12:17 -06:00
Zdenek Kabelac
6167f5da10 coverity: trying different model
Model reseting of given set, but it still makes
FD_SET to think it's accessing uninitialized value.

Maybe model also FD_SET.
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
83661c8f7f cleanup: use embeded list
Skip pointer and put list into selection_str_list.
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
6e71d3fbde cleanup: more readable code
Simplify if() expression.
Rename 'this' to 'vg'..
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
d8049dd17a cleanup: add some test for NULL
Coverity here is a bit 'blind' here and cannot resolve which
code paths are actually able to hit this code path.
(It's using 'statistic' to resolve all possible paths,
and it's not scanning 'individual' code paths.)

This just cleans warns and add 'cheap' tests.
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
011dd82050 cleanup: do not call vg_read with NULL mda
Use 'mda' instead of NULL to quite Coverity warn.
However this code seems to be actually not even possible to hit.
With proper analysis it may possibly be dropped from code to
simplify logic.
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
121341e52c cleanup: unify NULL custom check
Unify testing of NULL custom pointer.
Resolve 'factor' only in required if() branch.
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
cad3568def raid: drop unneeded NULL test
Skip testing target_pvs for NULL, we already
dereference it in many other places.
If check would ever be needed - it needs to be
in front of _raid_extract_images().
2015-11-17 19:01:25 +01:00
Zdenek Kabelac
51dfba002b libdm: update error message
Correcting error message.
2015-11-17 19:01:25 +01:00
David Teigland
931fede81b hash: change name of new lookup function 2015-11-17 11:59:44 -06:00
David Teigland
4d37db123d lvmetad: improve error message for VGs with same name 2015-11-17 10:35:42 -06:00
David Teigland
485d2ca945 lvmetad: different style for hash functions
In lookup, return a count of entries with the
same key rather than the value from a second
entry with the same key.

Using some slightly different names.
2015-11-17 10:27:16 -06:00
David Teigland
d42cedae58 lvmetad: add error explaining duplicate VG names
When a VG name lookup fails because the name matches
multiple VGs, return an explanatory error.
2015-11-16 16:25:49 -06:00
David Teigland
7d1c9e1d5a lvmetad: fix some error logging
For some errors old_meta may not be set, so
check before logging it.
2015-11-16 15:13:26 -06:00
David Teigland
68c386cce7 lvmetad: use lookup_withval in another location
Simply use lookup_withval right away rather than doing a
standard lookup, checking for the wrong mapping, then
repeating with lookup_withval to get the right mapping.
2015-11-16 15:13:22 -06:00
David Teigland
4a984cabc4 lvmetad: remove unneeded FIXME
This case is now handled correctly.
2015-11-16 13:44:57 -06:00
David Teigland
920a281994 hash: add comment about multiple values 2015-11-16 11:02:25 -06:00
Zdenek Kabelac
b6a45963e3 libdm: fix check of pointer
Ahhh being blind here - wanted to check the pointer before dereference
not a dereferenced one.
2015-11-16 13:10:24 +01:00
Zdenek Kabelac
2a2487f02f libdm: better error reporting from dm_split_lvm_name
Report errors from all error paths correctly.
Validate passed args before dereferencing them.
2015-11-16 13:09:53 +01:00
Zdenek Kabelac
5d4f5873a9 coverity: model FD_ZERO
Coverity is not able to understand assembly language in
system's header file, so provide model for such macro.

Note: to really see model in-use: #nodef FD_ZERO model_FD_ZERO
need to go to coverity/config/user_nodefs.h
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
8ebf2b0611 debug: lvconvert add missing display_lvname
Add missing display_lvname in _lvconvert_merge_thin_snapshot().

Also when we detect missing origin, report Internal error,
which would likely be the primary fault here
(and avoid dereft of NULL origin as noticed by Coverity).
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
0f4d96f1bd cleanup: just alphabetically sort links 2015-11-16 01:16:11 +01:00
Zdenek Kabelac
dccbc3b621 cleanup: simplify dev_cache_exit
Just set whole _cache struct into unitialized state just
like with lib init start usage.
Lists are initialized with dev_cache_init().
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
5a4676fea9 cleanup: add _free on error path
Just like with failing allocation above also _free(dev).

TODO: rework this to always use mempool and drop unneeded
comlexity we have in this function.
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
c3b292a4a9 format-text: ensure no division by zero
Coverity likes here to be 100% sure no division by zero is possible.
Add check for alignment !=0 which is made on other code paths here.
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
193e7f5973 config: check vdef pointer before dereference
Coverity notices we check for v_def != NULL elsewhere, so it thinks
it may be possibly NULL also here.
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
96d73dc6ea libdm: check for passed custom time value
Coverity reports custom should be checked before derefernce.
2015-11-16 01:16:11 +01:00
Zdenek Kabelac
d4288c9bdf libdm: check for null from pool strdup
Unlikely to happen, but Coverity shown we may have possible
derefer NULL pointer.
2015-11-16 01:16:09 +01:00
Zdenek Kabelac
422c7474ca libdm: check if passed return pointer is not NULL
Coverity: before storing return value, check passed space will
not dereference NULL pointer.
2015-11-16 01:15:04 +01:00
Stéphane Aulery
dd9a05b5ae man: improve cmirrord.8 manpage
- Keywords in bold
- Add syslog and signal ref.
- Sort see also sections

Signed-off-by: Stéphane Aulery <saulery@free.fr>
2015-11-16 01:15:03 +01:00
Stéphane Aulery
376892ddf8 clvmd: remove -v option from getopt
-V is documented, not -v.

Signed-off-by: Stéphane Aulery <saulery@free.fr>
2015-11-16 01:15:03 +01:00
Zdenek Kabelac
e31f4b76f4 cache: handle older metadata format
When reading older lvm2 metadata for cache-pool - we now handle more
extended syntax - basically we want to enter most setting when
actually creating cached LV.

For this new validation code has been added. However older metadata
without new settings set is now found as invalid.

Fix it by adding default settings for  cache policy  mq
and cache mode  writethrough.
2015-11-16 01:12:57 +01:00
David Teigland
d9295410e9 lvmetad: change the new hash to take data len
If the data len is passed into the hash table
and saved there, then the hash table internals
do not need to assume that the data value is
a string at any point.
2015-11-13 16:54:22 -06:00
David Teigland
e425bce281 tests: allow lvmetad tests with duplicate VG names 2015-11-13 15:09:26 -06:00
David Teigland
46193f4a59 lvmetad: handle duplicate VG names
New hash table functions are added that allow for
multiple entries with the same key.  Use of the
vgname_to_vgid hash table is converted to these
new functions since there are multiple entries
in vgname_to_vgid that have the same key (vgname).

When multiple VGs with the same name exist, commands
that reference only a VG name will fail saying the
VG could not be found (that error message could be
improved.)  Any command that works with the select
option can access one of the VGs with -S vg_uuid=X.
vgrename is a special case that allows the first VG
name arg to be replaced by a uuid, which also works.

(The existing hash table implementation is not well
suited for handling this case, but it works ok with
the new extensions.  Changing lvmetad to use its own
custom hash tables may be preferable at some point.)
2015-11-13 14:56:35 -06:00
Alasdair G Kergon
970a428909 pvmove: Remove unused find_pvmove_lv_from_pvname. 2015-11-13 18:06:08 +00:00
Zdenek Kabelac
b2e13ac552 coverity: add few internal errors
Mark impossible paths with internal errors.
Also replace 'strcmp() with more readable seg_is...()
2015-11-13 11:18:27 +01:00
Zdenek Kabelac
3089f5ab15 coverity: model some function
Reduce number of false-positives and model functions in a way
Coverity is able to understand it.
2015-11-13 11:18:27 +01:00
Zdenek Kabelac
8d258c7df4 coverity: hint
Here Coverity cannot see the pointer cannot be NULL in this
code path - opened coverity case #00531860.

We could make a model to avoid seeing related reports,
but then we loose coverage for modeled function.

So decided to add minor hint for this case.
2015-11-13 11:18:27 +01:00
Zdenek Kabelac
ea1814cea8 tests: without delay_dev skip some checks
When delay_dev is missing these tests are just racy.
2015-11-13 11:17:07 +01:00
Zdenek Kabelac
6dadebb1e4 cleanup: better error message
Use display_lvname.
2015-11-13 11:17:06 +01:00
Zdenek Kabelac
1f2a42c7b7 cleanup: check LVs in one statement
Use a single statement to check all LVs we want to
deref via  get_only_segment_using_this_lv().
2015-11-13 11:17:06 +01:00
Zdenek Kabelac
70af08122e cleanup: missing check for PV2
Patch missed also check this pointer dereference.
2015-11-13 11:17:06 +01:00
Zdenek Kabelac
e0828e885b cleanup: drop unneded check for mem
Revert missed to drop this extra check.
2015-11-13 11:17:06 +01:00
Zdenek Kabelac
112c0592ad debug: put stack on error path
At least check result and trace it.
However we may need better error reaction in this case.
2015-11-13 11:17:06 +01:00
Zdenek Kabelac
007be91e3d raid: ensure area_count is at least 2
Enusure we will not divide by 0.
2015-11-13 11:17:06 +01:00
Zdenek Kabelac
d74e1291cd libdm: put in secure check
Coverity complains about NULL deref - while this cannot currently
happen, put in secure INTERNAL_ERROR.
2015-11-13 11:17:05 +01:00
Zdenek Kabelac
0128770d6d reporter: add missing stack trace
Use goto_out on error paths.
2015-11-13 11:17:05 +01:00
David Teigland
43777b551d lvmetad: tail chasing to shut up coverity 2015-11-12 09:35:41 -06:00
Zdenek Kabelac
058725c721 dmeventd: fix check for failing open.
Recent change 2c8d6f5c90
actually droped restart when the reason of failing open is missing
device completely - check for ENOENT now as another reason
to start new dmeventd server  (when there is no systemd to maintain it).
2015-11-11 19:54:55 +01:00
Peter Rajnoha
1e729c47d2 str_list: do not support str lists without mempools
Do not support str lists without mempools. Instead, create temporary
mempool where necessary (currently only _get_report_options fn).
2015-11-11 16:09:52 +01:00
Peter Rajnoha
b8779e706e configure: check for udev_device_get_is_initialized is available
The udev_device_get_is_initialized is available since libudev version
165. Older versions are still used somewhere (e.g. RHEL6). So better
check for this fn and use it only if it's available.
2015-11-11 15:15:50 +01:00
Peter Rajnoha
f82e0210b7 dev-ext: issue error if external_device_info_source=udev and udev db record incomplete
Udev db records are marked as not initialized (incomplete) on timeout.
Issue an error message whenever LVM finds such records so users are
aware that something's going wrong with udev db.

This is important in case we use devices/external_device_info_source="udev"
where udev database records are used to do various filtering decisions.

For example:

udev log of timed out worker:

Nov 11 13:02:25 raw.virt systemd-udevd[607]: seq 1997 '/devices/virtual/block/dm-2' is taking a long time
Nov 11 13:04:25 raw.virt systemd-udevd[607]: seq 1997 '/devices/virtual/block/dm-2' killed
Nov 11 13:04:25 raw.virt systemd-udevd[607]: worker [11221] terminated by signal 9 (Killed)
Nov 11 13:04:25 raw.virt systemd-udevd[607]: worker [11221] failed while handling '/devices/virtual/block/dm-2'
...

LVM also issues error message visibly if incomplete udev db record is found,
devices/external_device_info_source="udev" is set:

$ pvs
  Udev database has incomplete information about device /dev/dm-2.
  Failed to get external handle for device /dev/dm-2 [udev].
  ...
2015-11-11 13:14:07 +01:00
Zdenek Kabelac
6d0db97163 libdm: reorder error path
Coverity noticed recent fix of an error path missed to
release 'dmt' - reoder code to ensure 'dmt' is released.
2015-11-10 21:41:47 +01:00
Zdenek Kabelac
a45cc0fe14 raid: fix the string compare
Coverity noticed this condition is always false and the error
path could never be visited.

So check for all mismatches of supported messages
and actually mark log_error as internal error.
2015-11-10 21:40:28 +01:00
Alasdair G Kergon
59905100d1 coverity: Add placeholder modelling file. 2015-11-10 01:37:11 +00:00
Zdenek Kabelac
fb59847a0f libdm: replace assign with increment
Coverity didn't liked assign with && expression, so use trick.
It does not complain against this prefix incremenent operation.
2015-11-09 22:51:48 +01:00
David Teigland
7ec61cd5b9 vgrename: check if new and old names match
When the first arg is a UUID and vgrename translates
that UUID to a current VG name, the old and new VG
names are not being checked for equality.  If they
are equal, it produces an internal error rather than
a proper error.
2015-11-09 13:23:59 -06:00
David Teigland
cd937efa77 lvmetad: change recent cleanups
with better alternatives.
2015-11-09 12:18:43 -06:00
David Teigland
d2d5191b78 lvmlockd: reverse some unnecessary checking
These are unnecessary or not useful.
2015-11-09 12:18:43 -06:00
Zdenek Kabelac
a0cb92cbb1 tests: handle missing delay_dev
Try to run as much of test which could run without delay_dev.
2015-11-09 19:07:53 +01:00
David Teigland
6762eec88c lvmlockd: fix the NO_GL_LS condition
indicating when no global lockspace exists.
2015-11-09 11:33:16 -06:00
Zdenek Kabelac
45e749493c cleanup: ensuring string is not NULL
Coverity cannot see the string cannot be NULL so make it explicit.
2015-11-09 17:04:10 +01:00
Zdenek Kabelac
76b42901c0 cache: ensure there is no NULL str
Coverity is not smart enough to detect this case could never happen.
2015-11-09 17:04:10 +01:00
Zdenek Kabelac
b1215b7f8c lvmlockd: enforce 64bit arithmetic
Coverity suggest to stay on the 'safe' side and widen operators early
so 64bit offset is made from 64bit arithmentic.
2015-11-09 17:04:10 +01:00
Zdenek Kabelac
d6767d753f lvmlockd: add missing error checks
Detect error from function and report them.
2015-11-09 17:04:10 +01:00
Zdenek Kabelac
c2d5cfbdb8 cleanup: use _ for local function 2015-11-09 17:04:10 +01:00
Zdenek Kabelac
3db5ba08b1 cleanup: drop unneded headers
Coverity notices they are not really needed.
2015-11-09 17:04:10 +01:00
Zdenek Kabelac
6c331f3061 dmsetup: one missed dms 2015-11-09 17:04:10 +01:00
Zdenek Kabelac
32762e2a9c libdaemon: fix passing 32bit values for %d
Since %d is now prohibited for its great confusion,
replace it with  FMTd64 and correctly converted int64_t
parameter.
2015-11-09 17:04:10 +01:00
David Teigland
e207ededd6 lvmlockd: shut up warnings 2015-11-09 10:00:04 -06:00
Zdenek Kabelac
36ee367343 libdaemon: prohibit use of %d for 64bit numbres
Do not let pass %d and print internal error when found one.
Require all users to use  FMTd64 - it's seriously confusing.
2015-11-09 14:03:25 +01:00
Zdenek Kabelac
0b5a75c9af lvmetad: restore use of FMTd64
daemon_reply_simple() eats just 64bit numbers - so make it explicit.
2015-11-09 14:02:27 +01:00
Zdenek Kabelac
7103012754 tests: update test to check for race better
Use  delay_dev to slow down mirror sync so we could more
easily check for race and proper reject of parallel mirror
leg addition/reduction.

Also expose fail in mirror allocation of parallel leg.
2015-11-09 12:21:17 +01:00
Zdenek Kabelac
ab4773671b tests: do not skip test when delay is missing
Rather then skipping whole test - just do not use it.

Failing tests that have required delay need to deal with reality
and shell either check for HAVE_DM_DELAY and skip portion
of test or using should when needed.
2015-11-09 12:21:17 +01:00
Zdenek Kabelac
e4c9b390ca cleanup: update comment 2015-11-09 12:21:17 +01:00
Zdenek Kabelac
84a9546869 dmsetup: cleanup warn for older compilers
Older gcc somehow thinks there is a path of using
subcommand uninitilized.

So make it more obvious there is no such one.
2015-11-09 12:21:17 +01:00
Zdenek Kabelac
5aae8de776 lvmetad: maintain seqno as int
Keep seqno as 32bit value.
Also use '_' prefix for local _update_metadata.
2015-11-09 12:21:17 +01:00
Zdenek Kabelac
57c2a1ae8c raid: mark intententional copy and paste
Coverity: add this extra comment, to let Coverity know this
slightly changed copy&paste code is intentional.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
846adadbcc cleanup: use code in place
Pass const strings to printf(),
and use  struct names directly instead of creating unused vars on stack.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
22e19cb354 cleanup: reoder rstatus init
In all error paths always initialize *rstatus.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
b1dab26be0 cleanup: coverity quiet
While through all codepaths we never 'read' lock_id unless LCKF_CONVERT,
coverity cannot decrypt this.

As since it's usually better to pass in 'well-defined' data structures
preset lock_id to 0.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
11151121aa cleanup: use fputs for plain strings
Use fputs() when printing plain string,
easier then fprintf which needs to parse it.

Also check fd before close is >= 0 -
it is - but coverity fail to see it, so eliminate
this false-positive warning.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
c4c5635870 cleanup: drop unneeded assign
prio is always assigned later.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
e262d5e596 cleanup: keep using enum typedef
Using enum instead of unsigned.
2015-11-09 10:22:52 +01:00
Zdenek Kabelac
9b9b5d0ea2 cleanup: use 64bit multiply for print 2015-11-09 10:22:52 +01:00
Zdenek Kabelac
f6d2528f64 cleanup: drop unneeded header file 2015-11-09 10:22:51 +01:00
Zdenek Kabelac
5ba219e87a cleanup: use display_lvname 2015-11-09 10:22:51 +01:00
Zdenek Kabelac
04f76d9020 cleanup: use NAME_LEN
Let's have instant check for max name len when creating
subLV name.
2015-11-09 10:22:51 +01:00
Zdenek Kabelac
5c48ef993b cleanup: use NAME_LEN buffer instead of alloca
Drop alloca and use NAME_LEN size to get implicit check
for max len of LV name.
2015-11-09 10:22:51 +01:00
Zdenek Kabelac
2e04eee192 cleanup: do not test alloca for NULL
alloca() never returns NULL.
In case stack is out-of-range the behaviour is undefined.
2015-11-09 10:22:51 +01:00
Zdenek Kabelac
c542c18d2a cleanup: drop unneded assign
Coverity doesn't really like to see subcommand being assigned NULL,
so drop it.
2015-11-09 10:22:51 +01:00
Zdenek Kabelac
07046e994f alloc: use own mem pool for alloc_handle
Keep alloc_handle's data in a single mempool and do not
spread them into vgmem pool.
2015-11-09 10:22:49 +01:00
Zdenek Kabelac
0c380c316c cleanup: relocate error capture
Capture internal error before allocation anything.
2015-11-09 10:21:09 +01:00
Zdenek Kabelac
67b4761bc3 toollib: add missing check for lvmcache_init()
Coverity notices lvmcache_init() may fail so check and
error out in case of failure.
2015-11-09 10:19:20 +01:00
Zdenek Kabelac
164d7e72bf devmanager: validate target params
Coverity: ensure we do not read through NULL pointers for
target_type and params.
2015-11-09 10:19:20 +01:00
Zdenek Kabelac
4f8f8fcb52 report: add extra pointer check
Coverity was seeing possible trouble with NULL pointer dereference.
So ensure it may never happen.
2015-11-09 10:19:20 +01:00
Zdenek Kabelac
856e11e11c lv_manip: do not deref NULL for debug message
Coverity: when 'pv2' would be passed as NULL, do not try to
deref it in debug message.
2015-11-09 10:19:20 +01:00
Zdenek Kabelac
fa1d730847 dev-type: fix TOCTOU order
Doing 'stat' checking first and later opening is racy.
And since we do not really care about any 'status' info
here and we read 'sysfs' here - just drop whole 'stat()'
call and directly handle error from failing 'fopen()'.
2015-11-09 10:19:20 +01:00
Zdenek Kabelac
80c3fb786c thin: fix error path mem leak
Coverity: when parsing of thin-pool status would have failed,
it could have leaked memory pool and dmt struct.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
3cadc1c87e libdm: add test for dm_task_get_message_response()
Coverity notices dm_task_get_message_response() result should be
checked for NULL which should not be passed to dm_pool_strdup().
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
84303dc17a libdm: exlicitly check for NULL
Coverity: another explict check for NULL, where coverity fails to
see it.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
f6c140e200 libdm: ensure vars are initialized
Coverity found potential error path, where code could
have used some unset variables.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
b1c4017743 libdm: add missing error path check
Coverity: do not continue with section cloning when root node
would a NULL.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
18fd0bd20c lvconvert: add extra check for existance of pointer
Coverity here is not fully-in-picture - but please it
with validation of pointer which currently cannot be null,
since we always return at least empty string.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
b83a20b80a lvmetad: validate mda is not NULL
Coverity: make it explicitely obvious metadata area is not NULL.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
99def8f439 lvmetad: check for pointers not NULL
Check for  arg_vgid_lookup and arg_name_lookup not being NULL.
Drop checking arg_vgid and arg_name for NULL since they
are already dereference earlier - thus mostly must be NOT NULL.

(If that would be possible larger rework of this function would be
required).
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
f66fe2c444 lvmetad: require meta_lookup
Coverity: do not call update_pvid_to_vgid() with
meta_lookup == NULL since it is dereferencing it.
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
91bde0f4a1 lvmetad: check for allocation fail
Coverity: missing check for root != NULL as this pointer is
later dereferenced in add_last_node().
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
297d6773af dmsetup: add missing checks for dm_stats_create() ret value
Coverity likes to see a check for dms not being NULL, so
add those missing ones...
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
e90c5d2060 dmsetup: check for NULL from dm_task_get_ioctl_timestamp
Coverity: ensure NULL is not passed to dm_timestamp_delta().
2015-11-09 10:19:19 +01:00
Zdenek Kabelac
9df3069083 clvmd: check for pthread_create status
Coverity: likes to see checked function result.
2015-11-09 10:19:18 +01:00
Zdenek Kabelac
2c8d6f5c90 dmeventd: open fifo in one function
Put calls related to fifo opening into a single function.

Fix  Time-Of-Check-Time-Of-Use and use fstat()
and fchmod() on already opened fd instead of
checking first path and then risking to open something
different.
2015-11-09 10:18:53 +01:00
Zdenek Kabelac
e1b111b02a dmeventd: reorder tou 2015-11-09 10:00:33 +01:00
Zdenek Kabelac
8b857bfdc6 libdevmapper-event: fix fifo leak on error path
Coverity: when _init_client() fails, client fifo could have
been already openned and needs to be closed on error path.
2015-11-09 10:00:13 +01:00
Zdenek Kabelac
459b3db61e configure: report whether to build lvmlockd
Report configured status for build with lvmlockd.
2015-11-09 09:58:27 +01:00
Alasdair G Kergon
af6adec7cc post-release 2015-11-09 01:48:57 +00:00
Alasdair G Kergon
a3f77ed4ba pre-release 2015-11-09 01:45:22 +00:00
David Teigland
b9341e36f1 test: disable duplicate VG name test for lvmetad
Until we decide how duplicate VG names should be
handled by lvmetad, and implement that.
2015-11-06 15:58:22 -06:00
Alasdair G Kergon
8096f2224c mirror: Fix log size calc when more than 1 extent.
Currently the code creates the log separately after allocating space for
the data and as no data allocation is needed this second time,
total_extents ends up holding zero so use new_extents directly instead.
2015-11-05 23:40:47 +00:00
David Teigland
16780f6faa vg_read: skip repair and wipe for foreign and shared VGs
When reading a foreign VG we cannot write it, since
it belongs to another host.  When reading a shared VG
we cannot write it because we may not have an ex lock.
(Or we may be reading the shared VG while not using
lvmlockd in which case it's like reading a foreign VG.)

Add the same checks for wiping outdated PVs.  We may
read a foreign or shared VG, or see the PVs, while
another host is part way through writing a new version
of the VG to the PVs.  This might cause us to think
some of the PVs are outdated.  We do not want to
write another host's PVs, especially when we may
wrongly conclude they are outdated.
2015-11-03 13:42:21 -06:00
David Teigland
4103896ca0 lvmcache: change log_verbose to log_warn
Without this, some cases miss printing a
warning for duplicate PVs.
2015-11-03 13:37:31 -06:00
David Teigland
d30105f471 lvmetad: log duplicate PVs returned from lvmetad
When the command gets a list of alternate devices
from lvmetad, log each one directly.  This is not
the same as the warnings when adding lvmcache,
which are related to which duplicate is preferred.
2015-11-03 13:35:51 -06:00
David Teigland
19feda2c95 tests: skip duplicate vg names test with lvmetad
If two PVs have different VGs with the same name
(different uuids), one of the VGs is ignored by
lvmetad.  A FIXME exists in lvmetad to find a
better response.
2015-11-03 13:25:35 -06:00
David Teigland
4e6377f5ba lvmetad: refactor and document
update_metadata and pv_found update the cached metadata;
these are both reworked to improve the code, organize it
by each possible state and transition, make it much more
clear what's changing, add more error checking and
handling, and add comments.

The state and content of the cache (hash tables) does not
change (apart from some things that didn't work before),
and the communication to/from commands does not change.
The implementation and organization of the code making
the state changes does change significantly.

One detail related to the content of the cache does change:
different hash tables do not reference the same memory any more;
the target values in each hash table are allocated and freed
individually.
2015-11-03 13:18:27 -06:00
David Teigland
4b47ee5296 config: fix copy error in examples
The same example was copied without
changing the variable name.
2015-11-03 11:07:27 -06:00
719 changed files with 7500 additions and 3853 deletions

View File

@@ -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.

View File

@@ -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@

View File

@@ -1 +1 @@
2.02.134(2)-git (2015-10-30)
2.02.141(2)-git (2016-01-25)

View File

@@ -1 +1 @@
1.02.111-git (2015-10-30)
1.02.115-git (2016-01-25)

View File

@@ -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
====================================

View File

@@ -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
View File

@@ -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

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View File

@@ -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
}

View File

@@ -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
View File

@@ -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

View File

@@ -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
View 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;
}
*/

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View File

@@ -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

View File

@@ -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
*/
/*

View File

@@ -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
*/
/*

View File

@@ -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
*/
/*

View File

@@ -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
*/
/*

View File

@@ -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
*/
/*

View File

@@ -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
*/
/*

View File

@@ -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"

View File

@@ -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);

View File

@@ -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

View File

@@ -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;
}
}

View File

@@ -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 */

View File

@@ -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. */

View 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
*/

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View File

@@ -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"

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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@

View File

@@ -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)

View File

@@ -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__

View File

@@ -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)) {

View File

@@ -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
*/
/*

View File

@@ -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@

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View File

@@ -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"

View File

@@ -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
*/
/*

View File

@@ -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@

View File

@@ -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

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View File

@@ -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"

View File

@@ -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@

View File

@@ -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"

View 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
srcdir = @srcdir@
top_srcdir = @top_srcdir@

View File

@@ -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 */

View File

@@ -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@

View File

@@ -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;

View File

@@ -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

View 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
*/
#include "tool.h"

View File

@@ -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@

View File

@@ -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);

View File

@@ -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;

View File

@@ -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);

View File

@@ -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

View File

@@ -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;

View File

@@ -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@

View File

@@ -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"

View File

@@ -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

View File

@@ -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
*/
/*

View File

@@ -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);

View File

@@ -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"

View File

@@ -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

View File

@@ -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

View File

@@ -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

View 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
*/
#include "lvm2cmd.h"

View File

@@ -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

View File

@@ -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@

View File

@@ -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

View File

@@ -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

View File

@@ -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@

View File

@@ -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" : "",

View File

@@ -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);

View File

@@ -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, &params);
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, &params);
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, &params);
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, &params);
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, &params)) {
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;

View File

@@ -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

View File

@@ -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"

View File

@@ -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

View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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
View File

@@ -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 */

View File

@@ -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@

View File

@@ -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;
}

View File

@@ -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;

View File

@@ -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