1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-09-28 09:44:18 +03:00

Compare commits

...

99 Commits

Author SHA1 Message Date
Alasdair G Kergon
a729b1aa29 pre-release 2015-09-15 13:17:50 +01:00
Alasdair G Kergon
548c09acfc man: Add all_man Makefile target.
Use 'make all_man' to generate all man pages (regardless of
configuration options) or 'make install_all_man' to install them.
2015-09-15 13:14:16 +01:00
David Teigland
2ce8ee0214 vgcreate: initialize new PVs only in first vg_write
When a command does a sequence of
vg_write + vg_commit + vg_write + vg_commit,

initialization of non-PV devices happens during the
first vg_write, and does not need to be repeated by
the second vg_write.

When creating a lockd VG, this sequence occurs because
the VG is first created, then the lockd data is created,
then the lockd data is then written to the VG metadata.
2015-09-14 13:22:22 -05:00
Zdenek Kabelac
cee9ed2244 tests: early check for snapshot-merge 2015-09-14 20:18:54 +02:00
Zdenek Kabelac
e7e15631dd tests: lvextend of full thin pool 2015-09-14 20:18:54 +02:00
Zdenek Kabelac
ffeeb5c1e7 thin: show message on error path
Add missing log_error and show proper reason for failure
when autoextend is set to 0.

Add missing log_error when checked LV is not locally active.
2015-09-14 20:18:54 +02:00
Zdenek Kabelac
c356991fa8 libdm: no validate for pool without messages
Avoid validation of free space in pool, when no messages are passed.

Patch a3c7e326c3 add new check for
pool overload - but this check should not be made if there are
no messages and transaction_id is still within 'bounds' (bigger by 1).
2015-09-14 20:18:54 +02:00
Zdenek Kabelac
e42ee69988 vgimporeclone: use correct cache dir path
Commit 00b36ef06a had a typo
and missed '{' for shell variable, thus command used slightly
different 'tmp' dir name for cache dir (with extra '}').

Such change was unnoticed until a recent fix in persistent
filter, lvm2 missed to update cache file when --config
was specified.

The result was, /tmp dir was accumulating snap.XXXXX} dirs when
running vgimportclose  script.
2015-09-14 09:31:26 +02:00
Zdenek Kabelac
226e7d7b3c tests: wait for sync before deactivation
On slower machine/disk, sync may block udev from reading and may prevent
deactivation.
2015-09-11 21:52:27 +02:00
Zdenek Kabelac
cd2e4310b3 tests: new thin tests 2015-09-11 21:52:27 +02:00
Zdenek Kabelac
fd3d795b93 makefiles: distclean missing files 2015-09-11 21:52:27 +02:00
Zdenek Kabelac
729b035edd pool: validate pool_metadata has proper suffix 2015-09-11 21:52:27 +02:00
Zdenek Kabelac
fda853b573 thin: improve swapping of identifiers
Since we may want to swap names when LVs are complex types, we cannot
avoid doing full renames on both LV stacks.
Temporarily use 'pvmove_tmeta' as unused name to prevent validation troubles.
2015-09-11 21:51:11 +02:00
Zdenek Kabelac
280a6275ce thin: lvconvert use passed PVs for _pmspare
When PVs are given on 'lvconvert' respect them when converting
volume to thin-pool and allocating i.e. _pmspare.
2015-09-11 21:48:19 +02:00
Zdenek Kabelac
95b5d24f43 configure: relocate configure.h
Commit 9403edbb93 move location of
configure.h and lvm-version.h.

Let's try even better place then /conf dir which should be left
for user configurable files.

Put these files right into include dir.
2015-09-11 21:46:35 +02:00
Zdenek Kabelac
19443035a6 configure: correct message 2015-09-11 21:46:34 +02:00
David Teigland
8b8103efef man lvmlockd: move and update text about vgremove
The requirement to stop VGs before vgremove applies
to both sanlock and dlm VGs.
2015-09-11 14:34:22 -05:00
David Teigland
6bc3d72a65 lvmlockd: prevent vgremove of dlm VG while lockspace is used
This applies the same rule/logic to dlm VGs that has always
existed for sanlock VGs.  Allowing a dlm VG to be removed
while its lockspace was still running on other hosts largely
worked, but there were difficult problems if another VG with
the same name was recreated.  Forcing the VG lockspace to
be stopped, gives both sanlock and dlm VGs the same behavior.
2015-09-11 14:12:13 -05:00
David Teigland
854a559a49 lvmlockd: remove shortcut for lockspace thread cleanup
This shortcut was added for an odd case that I do not
believe is relevant any more.  Having an alternate
path for lockspace thread cleanup is a complication
that could lead to problems.
2015-09-11 13:20:20 -05:00
David Teigland
18dfbbb150 lvmlockd: optimize dlm global lockspace creation
Set a flag indicating that the dlm global lockspace
exists to avoid going through the entire process of
trying to add it before finding it exists.
2015-09-11 13:20:01 -05:00
David Teigland
0a26c20b88 lockd: fix rescanning VG metadata
The code was expecting the wrong return value from
compare_config, which returns 0 when equal.

This is a problem for a lockd VG using multiple PVs
when the VG needs to be rescanned.
2015-09-11 13:10:48 -05:00
Zdenek Kabelac
0889cff5d5 spec: upgrade
Upgrade spec rules to be in touch with recent code.
Provide services and proper postin/preun/postun scriplets.
2015-09-10 17:28:47 +02:00
Zdenek Kabelac
9b8c876293 tests: remove only existing loops
If loop device meanwhile dissapered, skip 'losetup -d' call.
2015-09-10 17:28:47 +02:00
Zdenek Kabelac
e94ab01940 tests: fix check lv_not_exist
Use 'not' to set proper 'expected return status'
so we do not 'leak' debug logs printed for failing case.
2015-09-10 17:28:47 +02:00
Zdenek Kabelac
54c982081f tests: check cache stripe and raid behavior
Somehow raid tests landed in plain cache - separte them out
so they properly check for  have_raid.

Check we do not support strip option with cache-pool creation.
2015-09-10 17:28:47 +02:00
Zdenek Kabelac
a631fa20d0 cache: disallow stripes/size for cache pool
ATM allocation can't handle stripping and cache pool allocation.
It's not yet even clear what should be actually result.
Until resolved, disable this option (it's been coredumping
inside allocation anyway).
2015-09-10 17:28:15 +02:00
Zdenek Kabelac
5911fa1d91 cache: warn if caching causes troubles
Certain stacks of cached LVs may have unexpected consequences.
So add a warning function called when LV is cached to detect
such caces and WARN user about them - the best we could do ATM.
2015-09-10 17:27:30 +02:00
Zdenek Kabelac
e1edb5676e lib: when moving segtypes, move LV bits
When we insert layer we also move status flag-bits for certain LV types,
so internal volume_group structure remains consistent.
(Perhaps it's misuse of 'insert_layer' function and we should have
another similar function for this.)

Basically we aim to maintain the same state as after reading fresh
metadata out of volume group.

Currently we when i.e. cache  'raid' LV - this should transfer 'raidLV' flag
to  _corigin LV and cache is no longer a raid.

TODO: bits for stacked devices needs more exact rules.
2015-09-10 17:25:28 +02:00
David Teigland
3670f095c7 lvmlockd: check all variations of lvb values
The dlm will often lose the lvb content, so we need to
check quite a few possibilities for lvb values that
were not being checked before.

Refactoring was required to pass the entire lvb value
back to the core code instead of the single value.

The only functional change should be detecting new
lvb states where metadata is now invalidated where
it wasn't before.
2015-09-10 09:47:26 -05:00
David Teigland
f11d690967 lvmlockd: flag for internal actions
When an action is created by lvmlockd for itself,
there is no client to send the result to.  Add
the NO_CLIENT flag to the action to skip sending
the result to a client.
2015-09-10 09:47:26 -05:00
David Teigland
15ae237d2c lvmlockd: rename ADOPT_CLIENT_ID
to INTERNAL_CLIENT_ID since it will be
used for more than adopting locks.
2015-09-10 09:47:26 -05:00
David Teigland
36d16fed1f lockd: add start_init arg to lockd_start_vg
Add a new arg to lockd_start_vg() that indicates
it is being called for a new lockd VG, so that
lvmlockd knows the lockspace being started is new.
(Will be used by a following commit.)
2015-09-10 09:47:26 -05:00
David Teigland
30e489db5e vgchange: lock-stop only needs shared lock
lock-stop is one of the vgchange options that
doesn't change the VG so we can override the
default ex lock and use sh.
2015-09-10 09:47:26 -05:00
Peter Rajnoha
2296999cf6 dev-cache: ignore persistent cache if configuration changed
Commit f6473baffc introduced a new
cmd->initialized variable to keep info about which parts of the
cmd_context have been initialized.

A part of this patch was also a change in refresh_filters fn
which checks for cmd->initialized.filters variable and it does
the filter refresh *only* if the filter has already been initialized
before otherwise it's a NOOP (before, the refresh_filters also
initialized filters as a side effect in case it had not been
initialized before which was not quite correct).

However, the commit f6473baffc
did not handle the case in which configuration changes
either via --config argument or when configuration file changed
and its timestamp was higher than the timestamp of the persistent
cache file - the /etc/lvm/cache/.cache.

This patch fixes this issue and it causes the init_filters fn
in lvm_run_command fn to be called with proper value of
"load_persistent_cache" switch even if the configuration changes,
hence causing the persistent cache file to be ignored in this
case.
2015-09-10 16:13:39 +02:00
David Teigland
d323acdfec man lvmlockd: fix typo 2015-09-09 15:43:28 -05:00
David Teigland
81b0e9de7c man lvmlockd: mention device used for first vgcreate 2015-09-09 15:21:10 -05:00
Zdenek Kabelac
587fd6a0e4 tests: ensure dd flushed all data before exit 2015-09-08 15:41:34 +02:00
Zdenek Kabelac
6cb7f21e38 tests: better check for compiled version
Use install /lib files to check for expected version.
2015-09-08 15:41:34 +02:00
Zdenek Kabelac
8ff43c3705 makefiles: ensure no old .h are left
Ensure make clean  cleans any left-over file from their previous
location so they are not in conflict with new ones.

Also hide error message when .commands file is not present.
2015-09-08 15:41:33 +02:00
Peter Rajnoha
026db90621 WHATS_NEW: commit b77497cbd8 2015-09-08 15:37:23 +02:00
Peter Rajnoha
b77497cbd8 filters: make sure regex filter is evaluated before any filter that needs disk access
The regex filter (controlled by devices/filter lvm.conf setting) was
evaluated as the very last filter. However, this is not optimal when
it comes to restricting disk access - users define devices/filter
as well as devices/global_filter to avoid this.

The devices/global_filter is already positioned at the beginning of the
filter chain. We need to do the same for devices/filter.

Filter chains before this patch:

  A: when lvmetad is not used:
       persistent_filter -> sysfs_filter -> global_regex_filter ->
       type_filter -> usable->filter -> mpath_component_filter ->
       partition_filter -> md_component_filter -> fw_raid_filter ->
       regex_filter

  B: when lvmetad is used:

    B1: to update lvmetad:
      sysfs_filter -> global_regex_filter -> type_filter ->
      usable_filter -> mpath_component_filter -> partition_filter ->
      md_component_filter -> fw_raid_filter

    B2: to retrieve info from lvmetad:
      persistent_filter -> usable_filter -> regex_filter

From the chain list above we can see that particularly in case when
lvmetad is not used, the regex filter is the very last one that is
processed. If lvmetad is used, it doesn't matter much as there's
the global_regex_filter which is used instead when updating lvmetad
and when retrieving info from lvmetad, putting regex_filter in front
of usable_filter wouldn't change much since usabled_filter is not
reading disks directly.

This patch puts the regex filter to the front even in case lvmetad
is not used, hence reinstating the state as it was before commit
a7be3b12df (which moved the regex_filter
position in the chain). Still, the arguments for the commit
a7be3b12df still apply and they're
still satisfied since component filters (MD, mpath...) are evaluated
first just before updating lvmetad.

So with this patch, we end up with:

  A: when lvmetad is not used:
       persistent_filter -> sysfs_filter -> global_regex_filter ->
       regex_filter -> type_filter -> usable->filter ->
       mpath_component_filter -> partition_filter ->
       md_component_filter -> fw_raid_filter

  B: when lvmetad is used:

    B1: to update lvmetad:
      sysfs_filter -> global_regex_filter -> type_filter ->
      usable_filter -> mpath_component_filter -> partition_filter ->
      md_component_filter -> fw_raid_filter

    B2: to retrieve info from lvmetad:
      persistent_filter -> regex_filter -> usable_filter

This way, specifying the regex_filter in non-lvmetad case causes
the devices to be filtered based on regex first before processing
any other filters which can access disks (like md_component_filter).

This patch also streamlines the code for better readability.
2015-09-08 15:28:10 +02:00
Zdenek Kabelac
596ec5c74b tests: skip raid testing on 4.[1,2] fc24 kernels
Hopefull 4.3 will be fixed and test will be updated to let
raid test running again.

Meanwhile using md-raid may effectively kill kernel,
so leave at least other tests running.
2015-09-08 12:12:38 +02:00
Zdenek Kabelac
0ec64370b2 specs: install lvmlockctl only when built
Move install line into proper section.
2015-09-07 23:27:50 +02:00
Bryn M. Reeves
d7f45ebca5 libdm: clean up stats local variable use 2015-09-07 20:14:53 +01:00
Bryn M. Reeves
daa94eb792 libdm: fix display of nsec suffixes in histogram strings 2015-09-07 20:14:53 +01:00
Bryn M. Reeves
5f990473e4 libdm: clean up _build_histogram_arg()
Split up _build_histogram_arg() into separate functions to allocate
and fill the histogram arg string and remove nested local variable
declarations from the parent function.
2015-09-07 19:30:03 +01:00
Bryn M. Reeves
4bc7a86f3a libdm: only free the first histogram explicitly (Coverity)
Coverity flags a user-after-free in _stats_histograms_destroy():

>>>     Calling "dm_pool_free" frees pointer "mem->chunk" which has
>>>     already been freed.

This should not be possible since the histograms are destroyed in
reverse order of allocation:

 203         for (n = _nr_areas_region(region) - 1; n; n--)
 204                 if (region->counters[n].histogram)
 205                         dm_pool_free(mem, region->counters[n].histogram);

It appears that Coverity is unaware that pool->chunk is updated
during the call to dm_pool_free() and valgrind flags no errors in
this function when called with multiple allocated histograms.

Since there is no actual need to free the histograms individually
in this way simplify the code and just free the first allocated
object (which will also free all later allocated histograms in a
single call).
2015-09-07 17:53:56 +01:00
Zdenek Kabelac
ffbf12504d cleanup: assign seg_name once 2015-09-07 17:44:08 +02:00
Zdenek Kabelac
330cad1567 specs: package lvmlockctl man page 2015-09-07 17:44:08 +02:00
Zdenek Kabelac
fa4d2ec241 tests: update install rules
Enhnace 'make install' rules for test suite (used for rpm packaging).
Install lvmlockd conf files.
Compile runner with correct CXXFLAGS.
2015-09-07 17:44:08 +02:00
Zdenek Kabelac
acfc56957c makefiles: do not generate tags for everyone
Create tags file only on request (make tags).
Also clean file with 'make clean'.
2015-09-07 17:44:04 +02:00
Zdenek Kabelac
3ba431e79e makefiles: deps depends on header links
Put include/.symlinks_created as a prerequisite for dep calc.
Otherwise if these are not generated and user enters tests subdir and
runs 'make' he just gets endless loop of dep calculation.
2015-09-07 17:43:27 +02:00
Zdenek Kabelac
d62448cb45 configure: regenerate 2015-09-07 17:43:27 +02:00
Zdenek Kabelac
1999e368f1 configure: simpler version reading
Avoid calling 'cat' when 'read' could handle it.

Also drop DM_LIB_VERSION from AC_SUBST as it's not used anywhere
in .in file.
2015-09-07 17:43:27 +02:00
Zdenek Kabelac
fc4f0d3fce configure: support --disable-dependency-tracking
One-time build may enjoy little speedup of build when dependencies are not
calculated.
2015-09-07 17:43:11 +02:00
Zdenek Kabelac
9403edbb93 configure: relocate generated headers
Relocate generated configure.h and lvm-version.h outside
of compilable .c source tree.

The reason is behind - when compiling in builddir != srcdir
the generated file in lib/misc/configure.h was used for all compiled
source file except ones located in lib/misc dir - those would have used
configure.h file located in this dir - if there have existed one (i.e.
from some other build)

This problem was only visible, when srcdir == buildir was used before
trying to use  srcdri != builddir  (as configure.h appeared then in
srcdir).
2015-09-07 17:40:58 +02:00
Bryn M. Reeves
ab1b54c3e3 libdm: fix dm_stats leak in dm_stats_create()
The histogram changes adds a new error path to dm_stats_create().
Make sure that the dm_stats handle is properly destroyed if we fail
to create the histogram pool and check for failures setting the
program_id.
2015-09-07 12:08:34 +01:00
Bryn M. Reeves
0f5933ecc1 libdm: handle pool errors in dm_histogram_to_string() 2015-09-07 12:01:20 +01:00
Bryn M. Reeves
e75b4bc2df libdm: check dm_pool_begin_object() return value. 2015-09-07 11:52:54 +01:00
Bryn M. Reeves
36b09fd147 libdm: add missing error handling in _stats_parse_histogram()
Since we are growing an object in the histogram pool the return
value of dm_pool_grow_object() must be checked and error paths need
to abandon the object before returning.
2015-09-07 11:44:53 +01:00
Bryn M. Reeves
a26523330e dmsetup: fix bounds leak in _do_stats_create_regions()
If we fail to create the DM_DEVICE_TABLE dm_task destroy the bounds
object before returning.
2015-09-07 11:14:28 +01:00
Alasdair G Kergon
2a022e9e6e post-release 2015-09-05 23:58:40 +01:00
Alasdair G Kergon
fb12308416 style: Standardise some error paths. 2015-09-05 23:56:30 +01:00
Alasdair G Kergon
f5a3b05c7a pre-release 2015-09-05 23:46:22 +01:00
Bryn M. Reeves
f868624f85 WHATS_NEW_DM: fix histogram entries for 1.02.107
The histogram entries were under the wrong version (1.02.106). Fix
that and describe the library changes in more detail.
2015-09-04 19:53:10 +01:00
David Teigland
10ccbc5efa lvmlockd: don't stop lockspace for EREMOVED
Undo the part of the recent EREMOVED change which
automatically stopped the lockspace for a remotely
removed VG.  It didn't always work (would not work
when lvb content was rebuilt in the dlm).  This will
be handled better when the lvb content is controlled
more strictly.
2015-09-04 13:41:38 -05:00
David Teigland
43d6b5b375 man lvmlockd: add section about first sanlock VG
Add a section specifically about creating the first
sanlock VG.
2015-09-04 13:01:03 -05:00
David Teigland
869c0bdeb8 man lvmlockctl: add man page 2015-09-04 11:05:13 -05:00
David Teigland
c71af0895d lvmlockctl: update command descriptions and add logging
The one line descriptions will match the man page.

Add a syslog entry when enabling/disabling the global lock
to help debugging.
2015-09-04 11:05:13 -05:00
David Teigland
b00ee99a21 man lvmlockd: explain the use of lvmlockctl kill 2015-09-04 11:05:13 -05:00
Peter Rajnoha
55c13f3de4 dev-cache: fix use of uninitialized device status if reading outdated .cache record
As part of fix that came with cf700151eb,
I forgot to add the check whether the result of stat was successful or
not. This bug caused uninitialized buffer to be used for entries
from .cache file which are no longer valid.

This bug may have caused these uninitialized values to be used further,
for example (see the unreal (2567,590944) representing major:minor
pair):

$ pvs
  /dev/abc: stat failed: No such file or directory
  Path /dev/abc no longer valid for device(2567,590944)
  PV               VG   Fmt  Attr PSize   PFree
  /dev/mapper/test      lvm2 ---  104.00m 104.00m
  /dev/vda2        rhel lvm2 a--    9.51g      0
2015-09-04 18:00:29 +02:00
David Teigland
9694854082 vgchange: improve error message about changing lock type 2015-09-04 09:53:33 -05:00
Bryn M. Reeves
cdca2782d2 libdm: fix uninitialized variable warnings on older gcc
Older versions of gcc aren't able to track the assignments of
local variables as well as the latest versions leading to spurious
warnings like:

libdm-stats.c:2183: warning: "len" may be used uninitialized in this
function
libdm-stats.c:2177: warning: "minwidth" may be used uninitialized in
this function

Both of these variables are in fact assigned in all possible paths
through the function and later compilers do not produce these
warnings.

There's no reason to not initialize these variables though and
it makes the function slightly easier to follow.

Also fix one use of 'unsigned' for a nr_bins value.
2015-09-04 11:46:48 +01:00
Bryn M. Reeves
cebbb0feaf dmstats: replace histogram command with switch
Replace the histogram stats subcommand with a --histogram switch
to enable histogram related fields for both list and report output.

To avoid overloading the existing --histogram rename it to --bounds:
this is also a better description of the option.
2015-09-03 23:39:11 +01:00
David Teigland
6240a7639d lvmlockd: fixes for starting dlm global lockspace
Remove the optimization/shortcut for starting the dlm global
lockspace when it was already running.

Reenable automatically starting the dlm global lockspace
when a command attempts to use it and it's not yet started.
This had become disabled at some point.
2015-09-03 16:47:54 -05:00
David Teigland
9e8b3d4a98 lockd: check for unlock failure in all cases
This suppresses an unwanted error message.
2015-09-03 16:47:54 -05:00
David Teigland
c27015368b lvmlockd: improve log messages for adding dlm global lockspace 2015-09-03 16:47:54 -05:00
Zdenek Kabelac
5da497d0a8 tests: update thin test
Use slightly better values
2015-09-03 23:34:37 +02:00
Zdenek Kabelac
dc261f17e9 tests: use conv=fdatasync
Should be slightly better to flushed before dd exits
instead of using direct IO.
2015-09-03 23:34:37 +02:00
Zdenek Kabelac
ee8200f1c6 cleanup: use just 2 decimal digits 2015-09-03 23:34:37 +02:00
Zdenek Kabelac
0a389691dc cleanup: avoid printing -0.00
Nice trick to not print -0.00 for some percent values.
2015-09-03 23:34:37 +02:00
Zdenek Kabelac
32d6ca9196 cleanup: show error message
Add error message on error path.
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
20e317cf92 lvcreate: restore missed --monitor
Fix regression from d13239b054.
This patch reorganized whole command option parsing, however
it has lost support to accept --monitor arg.
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
2b9843c20b dmeventd: reorder mempool allocation
Since lvm2_init() effectively detects memory leaks
allocate mempool after this initialization
(so it's not reported as leak).
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
872ea3b987 thin: do not flush when quering for thin percent
Since we may easily get blocked when checking for percentage
of thin-pool - do not flush and just show current values.
This avoids holding VG locked when pool is overfilled.
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
df110bccbe thin: validate mapped size of thin volume
Never show we map more then 100% for a volume.
But show warning when there could be some consistency problems.
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
a01eb9c451 thin: detect unusable thins
Try to detect thin-pool which my block lvm2 command from furher
processing (i.e. lvextend).

Check if pool is read-only or out-of-space and in this case thins
will skipped from being scanned (so user may miss some PVs located
on thin volumes).
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
81a9da8f61 filters: swap device_is_usable test
Fix regression introduced with commit:
2fc126b00d

This commit has moved  pv_min_size() test in front
of device_is_usable(). However pv_min_size needs to open device,
so it may have actually get blocked.

So restore the original order and first validate
dm device to be usable for open.

It's worth to note that such check is not 'race-free',
but it usually eliminates 99.99% of problems ;).
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
a3c7e326c3 libdm: relocate parsing of thin-pool status
Use single routine for parsing status.

Internally we do not need to allocate pool memory for
passed struct.
2015-09-03 23:34:36 +02:00
Zdenek Kabelac
5ce334923f configure: better parsing of cache_check version
Properly read also version string like  0.5.5-1.fc24
and read just first 3 digits split by '.'

Also remove one extra  $HAVE_REALTIME.
2015-09-03 23:34:36 +02:00
Bryn M. Reeves
49b5022993 dmstats: support --noheadings for histogram fields 2015-09-03 22:04:11 +01:00
Bryn M. Reeves
84d88cb2cf dmstats: add --notimesuffix switch
Add a switch to disable the printing of time unit suffixes in
histogram bounds descriptions.
2015-09-03 22:04:10 +01:00
Bryn M. Reeves
f09e4f7b10 libdm: allow formatting histogram strings with no whitespace
Allow dm_histogram_to_string() to format histogram strings with
no whitespace by passing a width value less than zero.
2015-09-03 22:04:10 +01:00
David Teigland
0a73a5012a vgrename: add missing trace on error path 2015-09-03 10:38:16 -05:00
David Teigland
96dc03b337 lockd: vgrename fixes
If busy locks in lvmlockd prevent vgrename, use the
correct error exit path, and print a user-friendly
error message.
2015-09-03 10:21:44 -05:00
Peter Rajnoha
d1d00fdeec dev-cache: append (major:minor) to debug messages about adding device or its alias to cache
device/dev-cache.c:350         /dev/sda: Added to device cache (8:0)
device/dev-cache.c:346         /dev/disk/by-id/lvm-pv-uuid-5nPovF-EWp4-vBwd-ylCJ-9Y0B-yzHQ-ek1li2: Aliased to /dev/sda in device cache (8:0)
...
2015-09-03 14:36:15 +02:00
Peter Rajnoha
00b610e542 filters: do not print [none:nil] as external device info's [source:handler] if "none" source is used
Print [source:handler] in filters' debug messages only if external
device info source other than "none" is used.

$ lvmconfig --type full devices/external_device_info_source
external_device_info_source="none

Before this patch (from the -vvvv log):

filters/filter-usable.c:47         /dev/mapper/test: Skipping: Too small to hold a PV [none:(nil)]
filters/filter-md.c:33         /dev/sdb: Skipping md component device [none:(nil)]
filters/filter-partitioned.c:25         /dev/vda: Skipping: Partition table signature found [none:(nil)]

With this patch applied:

filters/filter-usable.c:44         /dev/mapper/test: Skipping: Too small to hold a PV
filters/filter-md.c:35         /dev/sdb: Skipping md component device
filters/filter-partitioned.c:27         /dev/vda: Skipping: Partition table signature found
2015-09-03 14:19:48 +02:00
Peter Rajnoha
fc35b6988d libdm: pkgconfig: fix devmapper.pc to not reference nonexistent rt.pc file
librt doesn't have a pkgconfig file so use Libs.private: -lrt instead
to declare the dependency directly.

The same applies for -lm which is also used and which hasn't been
defined in the devmapper.pc file yet.
2015-09-03 09:28:42 +02:00
Bryn M. Reeves
b86bd3b074 man: fix typo in dmstats.8.in 2015-09-02 23:01:46 +01:00
85 changed files with 2225 additions and 1187 deletions

View File

@@ -131,6 +131,9 @@ rpm: dist
generate: conf.generate
$(MAKE) -C conf generate
all_man:
$(MAKE) -C man all_man
install_system_dirs:
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_SYS_DIR)
$(INSTALL_ROOT_DIR) $(DESTDIR)$(DEFAULT_ARCHIVE_DIR)
@@ -150,8 +153,8 @@ install_systemd_generators:
install_systemd_units:
$(MAKE) -C scripts install_systemd_units
install_full_man:
$(MAKE) -C man install_full_man
install_all_man:
$(MAKE) -C man install_all_man
ifeq ("@PYTHON_BINDINGS@", "yes")
install_python_bindings:
@@ -229,10 +232,9 @@ endif
ifneq ($(shell which ctags),)
.PHONY: tags
all: tags
tags:
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags | head -1)" || $(RM) tags
test -z "$(shell find $(top_srcdir) -type f -name '*.[ch]' -newer tags 2>/dev/null | head -1)" || $(RM) tags
test -f tags || find $(top_srcdir) -maxdepth 4 -type f -name '*.[ch]' -exec ctags -a '{}' +
DISTCLEAN_TARGETS += tags
CLEAN_TARGETS += tags
endif

View File

@@ -1 +1 @@
2.02.130(2)-git (2015-08-26)
2.02.131(2)-git (2015-09-15)

View File

@@ -1 +1 @@
1.02.107-git (2015-08-26)
1.02.108-git (2015-09-15)

View File

@@ -1,5 +1,26 @@
Version 2.02.130 -
===================================
Version 2.02.131 - 15th September 2015
======================================
Rename 'make install_full_man' to install_all_man and add all_man target.
Fix vgimportclone cache_dir path name (2.02.115).
Swapping of LV identifiers handles more complex LVs.
Use passed list of PVS when allocating space in lvconvert --thinpool.
Disallow usage of --stripe and --stripesize when creating cache pool.
Warn user when caching raid or thin pool data LV.
When layering LV, move LV flags with segments.
Ignore persistent cache if configuration changed. (2.02.127)
Fix devices/filter to be applied before disk-accessing filters. (2.02.112)
Make tags only when requested via 'make tags'.
Configure supports --disable-dependency-tracking for one-time builds.
Fix usage of configure.h when building in srcdir != builddir.
Version 2.02.130 - 5th September 2015
=====================================
Fix use of uninitialized device status if reading outdated .cache record.
Restore support for --monitor option in lvcreate (2.02.112).
Read thin-pool data and metadata percent without flush.
Detect blocked thin-pool and avoid scanning their thin volumes.
Check if dm device is usable before checking its size (2.02.116).
Extend parsing of cache_check version in configure.
Make lvpoll error messages visible in lvmpolld's stderr and in syslog.
Add 'make install_full_man' to install all man pages regardless of config.

View File

@@ -1,13 +1,24 @@
Version 1.02.107 -
===================================
Version 1.02.108 - 15th September 2015
======================================
Do not check for full thin pool when activating without messages (1.02.107).
Version 1.02.107 - 5th September 2015
=====================================
Parse thin-pool status with one single routine internally.
Add --histogram to select default histogram fields for list and report.
Add report fields for displaying latency histogram configuration and data.
Add dmstats --bounds to specify histogram boundaries for a new region.
Add dm_histogram_to_string() to format histogram data in string form.
Add public methods to libdm to access numerical histogram config and data.
Parse and store histogram data in dm_stats_list() and dm_stats_populate().
Add an argument to specify histogram bounds to dm_stats_create_region().
Add dm_histogram_bounds_from_{string,uint64_t}() to parse histogram bounds.
Add dm_histogram handle type to represent a latency histogram and its bounds.
Fix devmapper.pc pkgconfig file to not reference non-existent rt.pc file.
Reinstate dm_task_get_info@Base to libdevmapper exports. (1.02.106)
Version 1.02.106 - 26th August 2015
===================================
Add basic report fields for displaying latency histogram data.
Add dmstats --histogram to specify histogram boundaries for a region.
Add public methods to libdm-stats to access numerical histogram data.
Add the ability to parse histogram data into numeric form to libdm-stats.
Add 'precise' column to statistics reports.
Add --precise switch to 'dmstats create' to request nanosecond counters.
Add precise argument to dm_stats_create_region().

2
conf/.gitignore vendored
View File

@@ -2,3 +2,5 @@ command_profile_template.profile
example.conf
lvmlocal.conf
metadata_profile_template.profile
configure.h
lvm-version.h

42
configure vendored
View File

@@ -643,6 +643,7 @@ LVMETAD_PIDFILE
DMEVENTD_PIDFILE
WRITE_INSTALL
VALGRIND_POOL
USE_TRACKING
UDEV_HAS_BUILTIN_BLKID
UDEV_RULE_EXEC_DETECTION
UDEV_SYSTEMD_BACKGROUND_JOBS
@@ -659,7 +660,7 @@ SELINUX_PC
SELINUX_LIBS
REPLICATORS
READLINE_LIBS
RT_PC
RT_LIB
RAID
PYTHON_LIBDIRS
PYTHON_INCDIRS
@@ -693,7 +694,6 @@ BLKDEACTIVATE
FSADM
ELDFLAGS
DM_LIB_PATCHLEVEL
DM_LIB_VERSION
DMEVENTD_PATH
DMEVENTD
DL_LIBS
@@ -876,6 +876,7 @@ SHELL'
ac_subst_files=''
ac_user_opts='
enable_option_checking
enable_dependency_tracking
enable_static_link
with_user
with_group
@@ -1634,6 +1635,8 @@ Optional Features:
--disable-option-checking ignore unrecognized --enable/--with options
--disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no)
--enable-FEATURE[=ARG] include FEATURE [ARG=yes]
--disable-dependency-tracking
speeds up one-time build.
--enable-static_link use this to link the tools to their libraries
statically (default is dynamic linking
--enable-lvm1_fallback use this to fall back and use LVM1 binaries if
@@ -2966,7 +2969,7 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
ac_config_headers="$ac_config_headers lib/misc/configure.h"
ac_config_headers="$ac_config_headers include/configure.h"
################################################################################
@@ -7632,6 +7635,19 @@ done
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to enable dependency tracking" >&5
$as_echo_n "checking whether to enable dependency tracking... " >&6; }
# Check whether --enable-dependency-tracking was given.
if test "${enable_dependency_tracking+set}" = set; then :
enableval=$enable_dependency_tracking; USE_TRACKING=$enableval
else
USE_TRACKING=yes
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $USE_TRACKING" >&5
$as_echo "$USE_TRACKING" >&6; }
################################################################################
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use static linking" >&5
$as_echo_n "checking whether to use static linking... " >&6; }
@@ -8816,7 +8832,7 @@ $as_echo "$as_me: WARNING: cache_check not found in path $PATH" >&2;}
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
read -r CACHE_CHECK_VSN < conftest.tmp
IFS=. read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH < conftest.tmp
IFS=.- read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH LEFTOVER < conftest.tmp
rm -f conftest.tmp
# Require version >= 0.5.4 for --clear-needs-check-flag
@@ -12847,13 +12863,11 @@ fi
$as_echo "#define HAVE_REALTIME 1" >>confdefs.h
LIBS="-lrt $LIBS"
RT_PC="librt"
RT_LIB="-lrt"
else
{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Disabling realtime clock" >&5
$as_echo "$as_me: WARNING: Disabling realtime clock" >&2;}
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $HAVE_REALTIME" >&5
$as_echo "$HAVE_REALTIME" >&6; }
fi
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for struct stat has st_ctim." >&5
@@ -14028,18 +14042,18 @@ test "$interface" != ioctl && as_fn_error $? "--with-interface=ioctl required. f
$as_echo "$interface" >&6; }
################################################################################
DM_LIB_VERSION="\"`cat "$srcdir"/VERSION_DM 2>/dev/null || echo Unknown`\""
read DM_LIB_VERSION < "$srcdir"/VERSION_DM 2>/dev/null || DM_LIB_VERSION=Unknown
cat >>confdefs.h <<_ACEOF
#define DM_LIB_VERSION $DM_LIB_VERSION
#define DM_LIB_VERSION "$DM_LIB_VERSION"
_ACEOF
DM_LIB_PATCHLEVEL=`cat "$srcdir"/VERSION_DM | $AWK -F '[-. ]' '{printf "%s.%s.%s",$1,$2,$3}'`
LVM_VERSION="\"`cat "$srcdir"/VERSION 2>/dev/null || echo Unknown`\""
read VER < "$srcdir"/VERSION 2>/dev/null || VER=Unknown
VER=`cat "$srcdir"/VERSION`
LVM_VERSION=\"$VER\"
LVM_RELEASE_DATE="\"`echo $VER | $SED 's/.* (//;s/).*//'`\""
VER=`echo "$VER" | $AWK '{print $1}'`
LVM_RELEASE="\"`echo "$VER" | $AWK -F '-' '{print $2}'`\""
@@ -14198,7 +14212,7 @@ LVM_LIBAPI=`echo "$VER" | $AWK -F '[()]' '{print $2}'`
################################################################################
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile lib/misc/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
ac_config_files="$ac_config_files Makefile make.tmpl daemons/Makefile daemons/clvmd/Makefile daemons/cmirrord/Makefile daemons/dmeventd/Makefile daemons/dmeventd/libdevmapper-event.pc daemons/dmeventd/plugins/Makefile daemons/dmeventd/plugins/lvm2/Makefile daemons/dmeventd/plugins/raid/Makefile daemons/dmeventd/plugins/mirror/Makefile daemons/dmeventd/plugins/snapshot/Makefile daemons/dmeventd/plugins/thin/Makefile daemons/lvmetad/Makefile daemons/lvmpolld/Makefile daemons/lvmlockd/Makefile conf/Makefile conf/example.conf conf/lvmlocal.conf conf/command_profile_template.profile conf/metadata_profile_template.profile include/.symlinks include/Makefile lib/Makefile lib/format1/Makefile lib/format_pool/Makefile lib/locking/Makefile lib/mirror/Makefile lib/replicator/Makefile include/lvm-version.h lib/raid/Makefile lib/snapshot/Makefile lib/thin/Makefile lib/cache_segtype/Makefile libdaemon/Makefile libdaemon/client/Makefile libdaemon/server/Makefile libdm/Makefile libdm/libdevmapper.pc liblvm/Makefile liblvm/liblvm2app.pc man/Makefile po/Makefile python/Makefile python/setup.py scripts/blkdeactivate.sh scripts/blk_availability_init_red_hat scripts/blk_availability_systemd_red_hat.service scripts/clvmd_init_red_hat scripts/cmirrord_init_red_hat scripts/dm_event_systemd_red_hat.service scripts/dm_event_systemd_red_hat.socket scripts/lvm2_cluster_activation_red_hat.sh scripts/lvm2_cluster_activation_systemd_red_hat.service scripts/lvm2_clvmd_systemd_red_hat.service scripts/lvm2_cmirrord_systemd_red_hat.service scripts/lvm2_lvmetad_init_red_hat scripts/lvm2_lvmetad_systemd_red_hat.service scripts/lvm2_lvmetad_systemd_red_hat.socket scripts/lvm2_lvmpolld_init_red_hat scripts/lvm2_lvmpolld_systemd_red_hat.service scripts/lvm2_lvmpolld_systemd_red_hat.socket scripts/lvm2_lvmlockd_systemd_red_hat.service scripts/lvm2_lvmlocking_systemd_red_hat.service scripts/lvm2_monitoring_init_red_hat scripts/lvm2_monitoring_systemd_red_hat.service scripts/lvm2_pvscan_systemd_red_hat@.service scripts/lvm2_tmpfiles_red_hat.conf scripts/Makefile test/Makefile test/api/Makefile test/unit/Makefile tools/Makefile udev/Makefile unit-tests/datastruct/Makefile unit-tests/regex/Makefile unit-tests/mm/Makefile"
cat >confcache <<\_ACEOF
# This file is a shell script that caches the results of configure
@@ -14892,7 +14906,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
for ac_config_target in $ac_config_targets
do
case $ac_config_target in
"lib/misc/configure.h") CONFIG_HEADERS="$CONFIG_HEADERS lib/misc/configure.h" ;;
"include/configure.h") CONFIG_HEADERS="$CONFIG_HEADERS include/configure.h" ;;
"Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
"make.tmpl") CONFIG_FILES="$CONFIG_FILES make.tmpl" ;;
"daemons/Makefile") CONFIG_FILES="$CONFIG_FILES daemons/Makefile" ;;
@@ -14922,7 +14936,7 @@ do
"lib/locking/Makefile") CONFIG_FILES="$CONFIG_FILES lib/locking/Makefile" ;;
"lib/mirror/Makefile") CONFIG_FILES="$CONFIG_FILES lib/mirror/Makefile" ;;
"lib/replicator/Makefile") CONFIG_FILES="$CONFIG_FILES lib/replicator/Makefile" ;;
"lib/misc/lvm-version.h") CONFIG_FILES="$CONFIG_FILES lib/misc/lvm-version.h" ;;
"include/lvm-version.h") CONFIG_FILES="$CONFIG_FILES include/lvm-version.h" ;;
"lib/raid/Makefile") CONFIG_FILES="$CONFIG_FILES lib/raid/Makefile" ;;
"lib/snapshot/Makefile") CONFIG_FILES="$CONFIG_FILES lib/snapshot/Makefile" ;;
"lib/thin/Makefile") CONFIG_FILES="$CONFIG_FILES lib/thin/Makefile" ;;

View File

@@ -16,7 +16,7 @@ AC_PREREQ(2.61)
dnl -- Process this file with autoconf to produce a configure script.
AC_INIT
AC_CONFIG_SRCDIR([lib/device/dev-cache.h])
AC_CONFIG_HEADERS([lib/misc/configure.h])
AC_CONFIG_HEADERS([include/configure.h])
################################################################################
dnl -- Setup the directory where autoconf has auxilary files
@@ -155,6 +155,15 @@ AC_FUNC_STAT
AC_FUNC_STRTOD
AC_FUNC_VPRINTF
################################################################################
dnl -- Disable dependency tracking
AC_MSG_CHECKING(whether to enable dependency tracking)
AC_ARG_ENABLE(dependency-tracking,
AC_HELP_STRING([--disable-dependency-tracking],
[speeds up one-time build.]),
USE_TRACKING=$enableval, USE_TRACKING=yes)
AC_MSG_RESULT($USE_TRACKING)
################################################################################
dnl -- Enables statically-linked tools
AC_MSG_CHECKING(whether to use static linking)
@@ -586,7 +595,7 @@ case "$CACHE" in
if test "$CACHE_CHECK_NEEDS_CHECK" = yes; then
$CACHE_CHECK_CMD -V 2>/dev/null >conftest.tmp
read -r CACHE_CHECK_VSN < conftest.tmp
IFS=. read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH < conftest.tmp
IFS=.- read -r CACHE_CHECK_VSN_MAJOR CACHE_CHECK_VSN_MINOR CACHE_CHECK_VSN_PATCH LEFTOVER < conftest.tmp
rm -f conftest.tmp
# Require version >= 0.5.4 for --clear-needs-check-flag
@@ -1581,11 +1590,10 @@ if test "$REALTIME" = yes; then
if test "$HAVE_REALTIME" = yes; then
AC_DEFINE([HAVE_REALTIME], 1, [Define to 1 to include support for realtime clock.])
LIBS="-lrt $LIBS"
RT_PC="librt"
RT_LIB="-lrt"
else
AC_MSG_WARN(Disabling realtime clock)
fi
AC_MSG_RESULT($HAVE_REALTIME)
fi
dnl Check if the system has struct stat st_ctim.
@@ -1880,14 +1888,14 @@ test "$interface" != ioctl && AC_MSG_ERROR([--with-interface=ioctl required. fs
AC_MSG_RESULT($interface)
################################################################################
DM_LIB_VERSION="\"`cat "$srcdir"/VERSION_DM 2>/dev/null || echo Unknown`\""
AC_DEFINE_UNQUOTED(DM_LIB_VERSION, $DM_LIB_VERSION, [Library version])
read DM_LIB_VERSION < "$srcdir"/VERSION_DM 2>/dev/null || DM_LIB_VERSION=Unknown
AC_DEFINE_UNQUOTED(DM_LIB_VERSION, "$DM_LIB_VERSION", [Library version])
DM_LIB_PATCHLEVEL=`cat "$srcdir"/VERSION_DM | $AWK -F '[[-. ]]' '{printf "%s.%s.%s",$1,$2,$3}'`
LVM_VERSION="\"`cat "$srcdir"/VERSION 2>/dev/null || echo Unknown`\""
read VER < "$srcdir"/VERSION 2>/dev/null || VER=Unknown
VER=`cat "$srcdir"/VERSION`
LVM_VERSION=\"$VER\"
LVM_RELEASE_DATE="\"`echo $VER | $SED 's/.* (//;s/).*//'`\""
VER=`echo "$VER" | $AWK '{print $1}'`
LVM_RELEASE="\"`echo "$VER" | $AWK -F '-' '{print $2}'`\""
@@ -1955,7 +1963,6 @@ AC_SUBST(DLM_LIBS)
AC_SUBST(DL_LIBS)
AC_SUBST(DMEVENTD)
AC_SUBST(DMEVENTD_PATH)
AC_SUBST(DM_LIB_VERSION)
AC_SUBST(DM_LIB_PATCHLEVEL)
AC_SUBST(ELDFLAGS)
AC_SUBST(FSADM)
@@ -1995,7 +2002,7 @@ AC_SUBST(PYTHON_LIBDIRS)
AC_SUBST(QUORUM_CFLAGS)
AC_SUBST(QUORUM_LIBS)
AC_SUBST(RAID)
AC_SUBST(RT_PC)
AC_SUBST(RT_LIB)
AC_SUBST(READLINE_LIBS)
AC_SUBST(REPLICATORS)
AC_SUBST(SACKPT_CFLAGS)
@@ -2024,6 +2031,7 @@ AC_SUBST(UDEV_SYNC)
AC_SUBST(UDEV_SYSTEMD_BACKGROUND_JOBS)
AC_SUBST(UDEV_RULE_EXEC_DETECTION)
AC_SUBST(UDEV_HAS_BUILTIN_BLKID)
AC_SUBST(USE_TRACKING)
AC_SUBST(VALGRIND_POOL)
AC_SUBST(WRITE_INSTALL)
AC_SUBST(DMEVENTD_PIDFILE)
@@ -2078,7 +2086,7 @@ lib/format_pool/Makefile
lib/locking/Makefile
lib/mirror/Makefile
lib/replicator/Makefile
lib/misc/lvm-version.h
include/lvm-version.h
lib/raid/Makefile
lib/snapshot/Makefile
lib/thin/Makefile

View File

@@ -1445,7 +1445,7 @@ static int disk_status_info(struct log_c *lc, struct dm_ulog_request *rq)
char *data = (char *)rq->data;
struct stat statbuf;
if(fstat(lc->disk_fd, &statbuf)) {
if (fstat(lc->disk_fd, &statbuf)) {
rq->error = -errno;
return -errno;
}
@@ -1508,7 +1508,7 @@ static int disk_status_table(struct log_c *lc, struct dm_ulog_request *rq)
char *data = (char *)rq->data;
struct stat statbuf;
if(fstat(lc->disk_fd, &statbuf)) {
if (fstat(lc->disk_fd, &statbuf)) {
rq->error = -errno;
return -errno;
}

View File

@@ -94,21 +94,22 @@ int dmeventd_lvm2_init(void)
pthread_mutex_lock(&_register_mutex);
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024)))
goto out;
if (!_lvm_handle) {
if (!getenv("LVM_LOG_FILE_EPOCH"))
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
if (!(_lvm_handle = lvm2_init()))
goto out;
/*
* Need some space for allocations. 1024 should be more
* than enough for what we need (device mapper name splitting)
*/
if (!_mem_pool && !(_mem_pool = dm_pool_create("mirror_dso", 1024))) {
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
goto out;
}
lvm2_disable_dmeventd_monitoring(_lvm_handle);
/* FIXME Temporary: move to dmeventd core */
lvm2_run(_lvm_handle, "_memlock_inc");

View File

@@ -45,6 +45,8 @@ lvmetactl: lvmetactl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmetactl.o $(LVMLIBS)
CLEAN_TARGETS += lvmetactl.o
# TODO: No idea. No idea how to test either.
#ifneq ("$(CFLOW_CMD)", "")
#CFLOW_SOURCES = $(addprefix $(srcdir)/, $(SOURCES))

View File

@@ -578,7 +578,7 @@ static void mark_outdated_pv(lvmetad_state *s, const char *vgid, const char *pvi
!(cft_vgid = make_text_node(outdated_pvs, "vgid", dm_pool_strdup(outdated_pvs->mem, vgid),
outdated_pvs->root, NULL)))
abort();
if(!dm_hash_insert(s->vgid_to_outdated_pvs, cft_vgid->v->v.str, outdated_pvs))
if (!dm_hash_insert(s->vgid_to_outdated_pvs, cft_vgid->v->v.str, outdated_pvs))
abort();
DEBUGLOG(s, "created outdated_pvs list for VG %s", vgid);
}

View File

@@ -599,14 +599,14 @@ static void print_usage(void)
printf(" Wait option for other commands.\n");
printf("--force | -f 0|1>\n");
printf(" Force option for other commands.\n");
printf("--kill | -k <vg_name>\n");
printf(" Kill access to the vg when sanlock cannot renew lease.\n");
printf("--drop | -r <vg_name>\n");
printf(" Clear locks for the vg after it has been killed and is no longer used.\n");
printf("--gl-enable <vg_name>\n");
printf(" Tell lvmlockd to enable the global lock in a sanlock vg.\n");
printf("--gl-disable <vg_name>\n");
printf(" Tell lvmlockd to disable the global lock in a sanlock vg.\n");
printf("--kill | -k <vgname>\n");
printf(" Kill access to the VG when sanlock cannot renew lease.\n");
printf("--drop | -r <vgname>\n");
printf(" Clear locks for the VG when it is unused after kill (-k).\n");
printf("--gl-enable | -E <vgname>\n");
printf(" Tell lvmlockd to enable the global lock in a sanlock VG.\n");
printf("--gl-disable | -D <vgname>\n");
printf(" Tell lvmlockd to disable the global lock in a sanlock VG.\n");
printf("--stop-lockspaces | -S\n");
printf(" Stop all lockspaces.\n");
}
@@ -731,11 +731,13 @@ int main(int argc, char **argv)
}
if (gl_enable) {
syslog(LOG_INFO, "Enabling global lock in VG %s.", arg_vg_name);
rv = do_able("enable_gl");
goto out;
}
if (gl_disable) {
syslog(LOG_INFO, "Disabling global lock in VG %s.", arg_vg_name);
rv = do_able("disable_gl");
goto out;
}

View File

@@ -197,11 +197,11 @@ static pthread_mutex_t client_mutex;
static pthread_cond_t client_cond;
static struct list_head client_list; /* connected clients */
static struct list_head client_results; /* actions to send back to clients */
static uint32_t client_ids; /* 0 and ADOPT_CLIENT_ID are skipped */
static uint32_t client_ids; /* 0 and INTERNAL_CLIENT_ID are skipped */
static int client_stop; /* stop the thread */
static int client_work; /* a client on client_list has work to do */
#define ADOPT_CLIENT_ID 0xFFFFFFFF /* special client_id for adopt actions */
#define INTERNAL_CLIENT_ID 0xFFFFFFFF /* special client_id for internal actions */
static struct list_head adopt_results; /* special start actions from adopt_locks() */
/*
@@ -735,6 +735,8 @@ static const char *op_str(int x)
return "dump_log";
case LD_OP_DUMP_INFO:
return "dump_info";
case LD_OP_BUSY:
return "busy";
default:
return "op_unknown";
};
@@ -873,14 +875,14 @@ static int lm_rem_lockspace(struct lockspace *ls, struct action *act, int free_v
}
static int lm_lock(struct lockspace *ls, struct resource *r, int mode, struct action *act,
uint32_t *r_version, int *retry, int adopt)
struct val_blk *vb_out, int *retry, int adopt)
{
int rv;
if (ls->lm_type == LD_LM_DLM)
rv = lm_lock_dlm(ls, r, mode, r_version, adopt);
rv = lm_lock_dlm(ls, r, mode, vb_out, adopt);
else if (ls->lm_type == LD_LM_SANLOCK)
rv = lm_lock_sanlock(ls, r, mode, r_version, retry, adopt);
rv = lm_lock_sanlock(ls, r, mode, vb_out, retry, adopt);
else
return -1;
@@ -926,7 +928,7 @@ static int lm_unlock(struct lockspace *ls, struct resource *r, struct action *ac
static int lm_hosts(struct lockspace *ls, int notify)
{
if (ls->lm_type == LD_LM_DLM)
return 0;
return lm_hosts_dlm(ls, notify);
else if (ls->lm_type == LD_LM_SANLOCK)
return lm_hosts_sanlock(ls, notify);
return -1;
@@ -959,6 +961,13 @@ static int lm_find_free_lock(struct lockspace *ls, uint64_t *free_offset)
static void add_client_result(struct action *act)
{
if (act->flags & LD_AF_NO_CLIENT) {
log_debug("internal action done op %s mode %s result %d vg %s",
op_str(act->op), mode_str(act->mode), act->result, act->vg_name);
free_action(act);
return;
}
pthread_mutex_lock(&client_mutex);
if (act->flags & LD_AF_ADOPT)
list_add_tail(&act->list, &adopt_results);
@@ -1015,8 +1024,12 @@ static void add_work_action(struct action *act)
static int res_lock(struct lockspace *ls, struct resource *r, struct action *act, int *retry)
{
struct lock *lk;
uint32_t r_version = 0;
int rv;
struct val_blk vb;
uint32_t new_version = 0;
int inval_meta;
int rv = 0;
memset(&vb, 0, sizeof(vb));
if (r->type == LD_RT_LV)
log_debug("S %s R %s res_lock mode %s (%s)", ls->name, r->name, mode_str(act->mode), act->lv_name);
@@ -1029,114 +1042,245 @@ static int res_lock(struct lockspace *ls, struct resource *r, struct action *act
if (r->type == LD_RT_LV && act->lv_args[0])
memcpy(r->lv_args, act->lv_args, MAX_ARGS);
rv = lm_lock(ls, r, act->mode, act, &r_version, retry, act->flags & LD_AF_ADOPT);
if (rv == -EAGAIN)
return rv;
if (rv < 0) {
log_error("S %s R %s res_lock lm error %d", ls->name, r->name, rv);
return rv;
}
rv = lm_lock(ls, r, act->mode, act, &vb, retry, act->flags & LD_AF_ADOPT);
log_debug("S %s R %s res_lock lm done r_version %u",
ls->name, r->name, r_version);
if (r->use_vb)
log_debug("S %s R %s res_lock %d read vb %x %x %u",
ls->name, r->name, rv, vb.version, vb.flags, vb.r_version);
else
log_debug("S %s R %s res_lock %d", ls->name, r->name, rv);
if (rv < 0)
return rv;
if (sanlock_gl_dup && ls->sanlock_gl_enabled)
act->flags |= LD_AF_DUP_GL_LS;
/* lm_lock() reads new r_version */
/*
* Check new lvb values to decide if lvmetad cache should
* be invalidated. When we need to invalidate the lvmetad
* cache, but don't have a usable r_version from the lvb,
* send lvmetad new_version 0 which causes it to invalidate
* the VG metdata without comparing against the currently
* cached VG seqno.
*/
if ((r_version != r->version) || (!r->version && !r->version_zero_valid)) {
inval_meta = 0;
if (!r->use_vb) {
/* LV locks don't use an lvb. */
} else if (vb.version && ((vb.version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
log_error("S %s R %s res_lock invalid val_blk version %x flags %x r_version %u",
ls->name, r->name, vb.version, vb.flags, vb.r_version);
inval_meta = 1;
new_version = 0;
rv = -EINVAL;
} else if (vb.r_version && (vb.r_version == r->version)) {
/*
* r_version only increases, so if it goes down, it means the
* dlm lvb became invalid (happens during recovery if the
* resource master leaves).
* Common case when the version hasn't changed.
* Do nothing.
*/
if (r_version < r->version) {
log_debug("S %s R %s res_lock lvb invalid r_version %u prev %u",
ls->name, r->name, r_version, r->version);
} else if (r->version && vb.r_version && (vb.r_version > r->version)) {
/*
* Common case when the version has changed. Another host
* has changed the data protected by the lock since we last
* acquired it, and increased r_version so we know that our
* cache is invalid.
*/
log_debug("S %s R %s res_lock got version %u our %u",
ls->name, r->name, vb.r_version, r->version);
r->version = vb.r_version;
new_version = vb.r_version;
r->version_zero_valid = 0;
inval_meta = 1;
} else if (r->version_zero_valid && !vb.r_version) {
/*
* The lvb is in a persistent zero state, which will end
* once someone uses the lock and writes a new lvb value.
* Do nothing.
*/
log_debug("S %s R %s res_lock version_zero_valid still zero", ls->name, r->name);
} else if (r->version_zero_valid && vb.r_version) {
/*
* Someone has written to the lvb after it was in a
* persistent zero state. Begin tracking normal
* non-zero changes. We may or may not have known
* about a previous non-zero version (in r->version).
* If we did, it means the lvb content was lost and
* has now been reinitialized.
*
* If the new reinitialized value is less than the
* previous non-zero value in r->version, then something
* unusual has happened. For a VG lock, it probably
* means the VG was removed and recreated. Invalidate
* our cache and begin using the new VG version. For
* a GL lock, another host may have reinitialized a
* lost/zero lvb with a value less than we'd seen
* before. Invalidate the cache, and begin using
* the lower version (or continue using our old
* larger version?)
*/
if (r->version && (r->version >= vb.r_version)) {
log_debug("S %s R %s res_lock version_zero_valid got version %u less than our %u",
ls->name, r->name, vb.r_version, r->version);
new_version = 0;
} else {
log_debug("S %s R %s res_lock version_zero_valid got version %u our %u",
ls->name, r->name, vb.r_version, r->version);
new_version = vb.r_version;
}
r->version = vb.r_version;
r->version_zero_valid = 0;
inval_meta = 1;
} else if (!r->version && vb.r_version) {
/*
* New r_version of the lock: means that another
* host has changed data protected by this lock
* since the last time we acquired it. We
* should invalidate any local cache of the data
* protected by this lock and reread it from disk.
* The first time we've acquired the lock and seen the lvb.
*/
r->version = r_version;
log_debug("S %s R %s res_lock initial version %u", ls->name, r->name, vb.r_version);
r->version = vb.r_version;
inval_meta = 1;
new_version = vb.r_version;
r->version_zero_valid = 0;
} else if (!r->version && !vb.r_version) {
/*
* When a new global lock is enabled in a new vg,
* it will have version zero, and the first time
* we use it we need to validate the global cache
* since we don't have any version history to know
* the state of the cache. The version could remain
* zero for a long time if no global state is changed
* to cause the GL version to be incremented to 1.
* The lock may have never been used to change something.
* (e.g. a new sanlock GL?)
*/
log_debug("S %s R %s res_lock all versions zero", ls->name, r->name);
if (!r->version_zero_valid) {
inval_meta = 1;
new_version = 0;
}
r->version_zero_valid = 1;
} else if (r->version && !vb.r_version) {
/*
* r is vglk: tell lvmetad to set the vg invalid
* flag, and provide the new r_version. If lvmetad finds
* that its cached vg has seqno less than the value
* we send here, it will set the vg invalid flag.
* lvm commands that read the vg from lvmetad, will
* see the invalid flag returned, will reread the
* vg from disk, update the lvmetad copy, and go on.
* The lvb content has been lost or never been initialized.
* It can be lost during dlm recovery when the master node
* is removed.
*
* r is global: tell lvmetad to set the global invalid
* flag. When commands see this flag returned from lvmetad,
* they will reread metadata from disk, update the lvmetad
* caches, and tell lvmetad to set global invalid to 0.
* If we're the next to write the lvb, reinitialze it to the
* new VG seqno, or a new GL counter larger than was seen by
* any hosts before (how to estimate that?)
*
* If we see non-zero values before we next write to it, use
* those values.
*
* While the lvb values remain zero, the data for the lock
* is unchanged and we don't need to invalidate metadata.
*/
if ((ls->lm_type == LD_LM_DLM) && !vb.version && !vb.flags)
log_debug("S %s R %s res_lock all lvb content is blank",
ls->name, r->name);
log_debug("S %s R %s res_lock our version %u got vb %x %x %u",
ls->name, r->name, r->version, vb.version, vb.flags, vb.r_version);
r->version_zero_valid = 1;
inval_meta = 1;
new_version = 0;
if ((r->type == LD_RT_VG) && lvmetad_connected) {
daemon_reply reply;
char *uuid;
} else if (r->version && vb.r_version && (vb.r_version < r->version)) {
/*
* The lvb value has gone backwards, which shouldn't generally happen,
* but could when the dlm lvb is lost and reinitialized, or the VG
* is removed and recreated.
*
* If this is a VG lock, it probably means the VG has been removed
* and recreated while we had the dlm lockspace running.
* FIXME: how does the cache validation and replacement in lvmetad
* work in this case?
*/
log_debug("S %s R %s res_lock got version %u less than our version %u",
ls->name, r->name, vb.r_version, r->version);
r->version = vb.r_version;
inval_meta = 1;
new_version = 0;
r->version_zero_valid = 0;
} else {
log_debug("S %s R %s res_lock undefined vb condition vzv %d our version %u vb %x %x %u",
ls->name, r->name, r->version_zero_valid, r->version,
vb.version, vb.flags, vb.r_version);
}
log_debug("S %s R %s res_lock set lvmetad vg version %u",
ls->name, r->name, r_version);
if (vb.version && vb.r_version && (vb.flags & VBF_REMOVED)) {
/* Should we set ls->thread_stop = 1 ? */
log_debug("S %s R %s res_lock vb flag REMOVED",
ls->name, r->name);
rv = -EREMOVED;
}
if (!lvmetad_connected && inval_meta)
log_debug("S %s R %s res_lock no lvmetad connection to invalidate",
ls->name, r->name);
/*
* r is vglk: tell lvmetad to set the vg invalid
* flag, and provide the new r_version. If lvmetad finds
* that its cached vg has seqno less than the value
* we send here, it will set the vg invalid flag.
* lvm commands that read the vg from lvmetad, will
* see the invalid flag returned, will reread the
* vg from disk, update the lvmetad copy, and go on.
*
* r is global: tell lvmetad to set the global invalid
* flag. When commands see this flag returned from lvmetad,
* they will reread metadata from disk, update the lvmetad
* caches, and tell lvmetad to set global invalid to 0.
*/
if (lvmetad_connected && inval_meta && (r->type == LD_RT_VG)) {
daemon_reply reply;
char *uuid;
log_debug("S %s R %s res_lock set lvmetad vg version %u",
ls->name, r->name, new_version);
if (!ls->vg_uuid[0] || !strcmp(ls->vg_uuid, "none"))
uuid = (char *)"none";
else
uuid = ls->vg_uuid;
if (!ls->vg_uuid[0] || !strcmp(ls->vg_uuid, "none"))
uuid = (char *)"none";
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)r_version,
NULL);
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);
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
log_error("set_vg_info in lvmetad failed %d", reply.error);
daemon_reply_destroy(reply);
}
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
log_error("set_vg_info in lvmetad failed %d", reply.error);
daemon_reply_destroy(reply);
}
if ((r->type == LD_RT_GL) && lvmetad_connected) {
daemon_reply reply;
if (lvmetad_connected && inval_meta && (r->type == LD_RT_GL)) {
daemon_reply reply;
log_debug("S %s R %s res_lock set lvmetad global invalid",
ls->name, r->name);
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",
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);
pthread_mutex_unlock(&lvmetad_mutex);
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
log_error("set_global_info in lvmetad failed %d", reply.error);
daemon_reply_destroy(reply);
}
if (reply.error || strcmp(daemon_reply_str(reply, "response", ""), "OK"))
log_error("set_global_info in lvmetad failed %d", reply.error);
daemon_reply_destroy(reply);
}
/*
* Record the new lock state.
*/
r->mode = act->mode;
add_lk:
@@ -1156,7 +1300,7 @@ add_lk:
list_add_tail(&lk->list, &r->locks);
return 0;
return rv;
}
static int res_convert(struct lockspace *ls, struct resource *r,
@@ -1313,12 +1457,14 @@ do_unlock:
r->version++;
lk->version = r->version;
r_version = r->version;
r->version_zero_valid = 0;
log_debug("S %s R %s res_unlock 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_unlock r_version new %u",
ls->name, r->name, r_version);
@@ -1763,7 +1909,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
list_del(&act->list);
add_client_result(act);
}
if (rv == -EUNATCH || rv == -EREMOVED)
if (rv == -EUNATCH)
goto r_free;
}
}
@@ -1796,7 +1942,7 @@ static void res_process(struct lockspace *ls, struct resource *r,
list_del(&act->list);
add_client_result(act);
}
if (rv == -EUNATCH || rv == -EREMOVED)
if (rv == -EUNATCH)
goto r_free;
break;
}
@@ -1817,9 +1963,6 @@ r_free:
lm_rem_resource(ls, r);
list_del(&r->list);
free_resource(r);
if (rv == -EREMOVED)
ls->thread_stop = 1;
}
#define LOCKS_EXIST_ANY 1
@@ -1963,15 +2106,18 @@ static struct resource *find_resource_act(struct lockspace *ls,
return NULL;
r->type = act->rt;
r->mode = LD_LK_UN;
if (r->type == LD_RT_GL)
if (r->type == LD_RT_GL) {
strncpy(r->name, R_NAME_GL, MAX_NAME);
else if (r->type == LD_RT_VG)
r->use_vb = 1;
} else if (r->type == LD_RT_VG) {
strncpy(r->name, R_NAME_VG, MAX_NAME);
else if (r->type == LD_RT_LV)
r->use_vb = 1;
} else if (r->type == LD_RT_LV) {
strncpy(r->name, act->lv_uuid, MAX_NAME);
r->use_vb = 0;
}
list_add_tail(&r->list, &ls->resources);
@@ -2220,6 +2366,18 @@ static void *lockspace_thread_main(void *arg_in)
break;
}
if (act->op == LD_OP_BUSY && act->rt == LD_RT_VG) {
log_debug("S %s checking if lockspace is busy", ls->name);
rv = lm_hosts(ls, 0);
if (rv)
act->result = -EBUSY;
else
act->result = 0;
list_del(&act->list);
add_client_result(act);
continue;
}
if (act->op == LD_OP_RENAME_BEFORE && act->rt == LD_RT_VG) {
/* vgrename */
log_debug("S %s checking for lockspace hosts", ls->name);
@@ -2402,11 +2560,10 @@ out_act:
ls->thread_done = 1;
ls->free_vg = free_vg;
ls->drop_vg = drop_vg;
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
global_dlm_lockspace_exists = 0;
pthread_mutex_unlock(&lockspaces_mutex);
if (gl_use_dlm && !strcmp(ls->name, gl_lsname_dlm))
dlm_gl_lockspace_running = 0;
/* worker_thread will join this thread, and free the ls */
pthread_mutex_lock(&worker_mutex);
worker_wake = 1;
@@ -2501,14 +2658,10 @@ static int add_lockspace_thread(const char *ls_name,
{
struct lockspace *ls, *ls2;
struct resource *r;
uint32_t version = 0;
int rv;
if (act)
version = act->version;
log_debug("add_lockspace_thread %s %s version %u",
lm_str(lm_type), ls_name, version);
lm_str(lm_type), ls_name, act ? act->version : 0);
if (!(ls = alloc_lockspace()))
return -ENOMEM;
@@ -2538,17 +2691,20 @@ static int add_lockspace_thread(const char *ls_name,
r->type = LD_RT_VG;
r->mode = LD_LK_UN;
r->version = version;
r->use_vb = 1;
strncpy(r->name, R_NAME_VG, MAX_NAME);
list_add_tail(&r->list, &ls->resources);
pthread_mutex_lock(&lockspaces_mutex);
ls2 = find_lockspace_name(ls->name);
if (ls2) {
if (ls2->thread_stop)
if (ls2->thread_stop) {
log_debug("add_lockspace_thread %s exists and stopping", ls->name);
rv = -EAGAIN;
else
} else {
log_debug("add_lockspace_thread %s exists", ls->name);
rv = -EEXIST;
}
pthread_mutex_unlock(&lockspaces_mutex);
free_resource(r);
free(ls);
@@ -2562,11 +2718,14 @@ static int add_lockspace_thread(const char *ls_name,
if (act)
list_add(&act->list, &ls->actions);
if (ls->lm_type == LD_LM_DLM && !strcmp(ls->name, gl_lsname_dlm))
global_dlm_lockspace_exists = 1;
list_add_tail(&ls->list, &lockspaces);
pthread_mutex_unlock(&lockspaces_mutex);
rv = pthread_create(&ls->thread, NULL, lockspace_thread_main, ls);
if (rv < 0) {
log_error("add_lockspace_thread %s pthread error %d %d", ls->name, rv, errno);
pthread_mutex_lock(&lockspaces_mutex);
list_del(&ls->list);
pthread_mutex_unlock(&lockspaces_mutex);
@@ -2588,22 +2747,24 @@ static int add_dlm_global_lockspace(struct action *act)
{
int rv;
if (dlm_gl_lockspace_running)
return -EEXIST;
dlm_gl_lockspace_running = 1;
if (global_dlm_lockspace_exists)
return 0;
/*
* There's a short period after which a previous gl lockspace thread
* has set dlm_gl_lockspace_running = 0, but before its ls struct has
* been deleted, during which this add_lockspace_thread() can fail with
* -EAGAIN.
* FIXME: if the dlm global lockspace is started without a global
* lock request, insert an internal gl sh lock request?
*/
rv = add_lockspace_thread(gl_lsname_dlm, NULL, NULL, LD_LM_DLM, NULL, act);
if (rv < 0) {
log_error("add_dlm_global_lockspace add_lockspace_thread %d", rv);
dlm_gl_lockspace_running = 0;
}
if (rv < 0)
log_debug("add_dlm_global_lockspace add_lockspace_thread %d", rv);
/*
* EAGAIN may be returned for a short period because
* global_dlm_lockspace_exists is set to 0 before the
* ls is removed from the lockspaces list by the
* worker_thread.
*/
return rv;
}
@@ -2685,20 +2846,16 @@ static int add_lockspace(struct action *act)
}
if (act->rt == LD_RT_VG) {
if (gl_use_dlm) {
rv = add_dlm_global_lockspace(NULL);
if (rv < 0 && rv != -EEXIST)
return rv;
}
if (gl_use_dlm)
add_dlm_global_lockspace(NULL);
vg_ls_name(act->vg_name, ls_name);
rv = add_lockspace_thread(ls_name, act->vg_name, act->vg_uuid,
act->lm_type, act->vg_args,
act);
if (rv)
log_error("add_lockspace %s add_lockspace_thread %d", ls_name, rv);
log_debug("add_lockspace %s add_lockspace_thread %d", ls_name, rv);
return rv;
}
@@ -3535,15 +3692,27 @@ static int add_lock_action(struct action *act)
memset(ls_name, 0, sizeof(ls_name));
/* Determine which lockspace this action is for, and set ls_name. */
/*
* Determine which lockspace this action is for, and set ls_name.
*/
if (act->rt == LD_RT_GL && gl_use_sanlock &&
(act->op == LD_OP_ENABLE || act->op == LD_OP_DISABLE))
vg_ls_name(act->vg_name, ls_name);
else if (act->rt == LD_RT_GL)
gl_ls_name(ls_name);
else
if (act->rt == LD_RT_GL) {
/* Global lock is requested */
if (gl_use_sanlock && (act->op == LD_OP_ENABLE || act->op == LD_OP_DISABLE)) {
vg_ls_name(act->vg_name, ls_name);
} else {
if (!gl_use_dlm && !gl_use_sanlock) {
if (lm_is_running_dlm())
gl_use_dlm = 1;
else if (lm_is_running_sanlock())
gl_use_sanlock = 1;
}
gl_ls_name(ls_name);
}
} else {
/* VG lock is requested */
vg_ls_name(act->vg_name, ls_name);
}
retry:
pthread_mutex_lock(&lockspaces_mutex);
@@ -3552,35 +3721,43 @@ static int add_lock_action(struct action *act)
pthread_mutex_unlock(&lockspaces_mutex);
if (!ls) {
if (act->op == LD_OP_UPDATE && act->rt == LD_RT_VG) {
log_debug("lockspace not found ignored for vg update");
log_debug("lockspace \"%s\" not found ignored for vg update", ls_name);
return -ENOLS;
} else if (act->flags & LD_AF_SEARCH_LS) {
/* fail if we've already tried searching for the ls */
log_debug("lockspace search repeated %s", ls_name);
/*
* Fail if we've already tried searching for the lockspace.
*/
log_debug("lockspace \"%s\" not found after search", ls_name);
return -ENOLS;
} else if (act->op == LD_OP_LOCK && act->rt == LD_RT_GL && gl_use_sanlock) {
/* gl may have been enabled in an existing vg */
log_debug("gl lockspace not found check sanlock vgs");
/*
* The sanlock global lock may have been enabled in an existing VG,
* so search existing VGs for an enabled global lock.
*/
log_debug("lockspace \"%s\" not found for sanlock gl, searching...", ls_name);
act->flags |= LD_AF_SEARCH_LS;
add_work_action(act);
return 0;
} else if (act->op == LD_OP_LOCK && act->rt == LD_RT_GL && gl_use_dlm) {
log_debug("gl lockspace not found add dlm global");
} else if (act->op == LD_OP_LOCK && act->rt == LD_RT_GL && act->mode != LD_LK_UN && gl_use_dlm) {
/*
* Automatically start the dlm global lockspace when
* a command tries to acquire the global lock.
*/
log_debug("lockspace \"%s\" not found for dlm gl, adding...", ls_name);
act->flags |= LD_AF_SEARCH_LS;
act->flags |= LD_AF_WAIT_STARTING;
add_dlm_global_lockspace(NULL);
gl_ls_name(ls_name);
goto retry;
} else if (act->op == LD_OP_LOCK && act->mode == LD_LK_UN) {
log_debug("lockspace not found ignored for unlock");
log_debug("lockspace \"%s\" not found for unlock ignored", ls_name);
return -ENOLS;
} else {
log_debug("lockspace not found %s", ls_name);
log_debug("lockspace \"%s\" not found", ls_name);
return -ENOLS;
}
}
@@ -3597,17 +3774,6 @@ static int add_lock_action(struct action *act)
}
pthread_mutex_lock(&ls->mutex);
if (ls->thread_stop && ls->thread_done) {
log_debug("lockspace is done finish cleanup %s", ls_name);
pthread_join(ls->thread, NULL);
list_del(&ls->list);
pthread_mutex_unlock(&ls->mutex);
free_ls_resources(ls);
free(ls);
pthread_mutex_unlock(&lockspaces_mutex);
goto retry;
}
if (ls->thread_stop) {
pthread_mutex_unlock(&ls->mutex);
pthread_mutex_unlock(&lockspaces_mutex);
@@ -3673,6 +3839,11 @@ static int str_to_op_rt(const char *req_name, int *op, int *rt)
*rt = LD_RT_VG;
return 0;
}
if (!strcmp(req_name, "busy_vg")) {
*op = LD_OP_BUSY;
*rt = LD_RT_VG;
return 0;
}
if (!strcmp(req_name, "free_lv")) {
*op = LD_OP_FREE;
*rt = LD_RT_LV;
@@ -4325,6 +4496,7 @@ static void client_recv_action(struct client *cl)
case LD_OP_FIND_FREE_LOCK:
case LD_OP_KILL_VG:
case LD_OP_DROP_VG:
case LD_OP_BUSY:
rv = add_lock_action(act);
break;
default:
@@ -4621,6 +4793,7 @@ static int get_lockd_vgs(struct list_head *vg_lockd)
goto next;
}
r->use_vb = 0;
r->type = LD_RT_LV;
strncpy(r->name, lv_uuid, MAX_NAME);
if (lock_args)
@@ -5041,7 +5214,7 @@ static void adopt_locks(void)
act->flags = (LD_AF_ADOPT | LD_AF_WAIT);
act->rt = LD_RT_GL;
act->lm_type = LD_LM_DLM;
act->client_id = ADOPT_CLIENT_ID;
act->client_id = INTERNAL_CLIENT_ID;
add_dlm_global_lockspace(act);
count_start++;
}
@@ -5053,7 +5226,7 @@ static void adopt_locks(void)
act->flags = (LD_AF_ADOPT | LD_AF_WAIT);
act->rt = LD_RT_VG;
act->lm_type = ls->lm_type;
act->client_id = ADOPT_CLIENT_ID;
act->client_id = INTERNAL_CLIENT_ID;
strncpy(act->vg_name, ls->vg_name, MAX_NAME);
memcpy(act->vg_uuid, ls->vg_uuid, 64);
memcpy(act->vg_args, ls->vg_args, MAX_ARGS);
@@ -5145,7 +5318,7 @@ static void adopt_locks(void)
act->rt = LD_RT_LV;
act->mode = LD_LK_EX;
act->flags = (LD_AF_ADOPT | LD_AF_PERSISTENT);
act->client_id = ADOPT_CLIENT_ID;
act->client_id = INTERNAL_CLIENT_ID;
act->lm_type = ls->lm_type;
strncpy(act->vg_name, ls->vg_name, MAX_NAME);
strncpy(act->lv_uuid, r->name, MAX_NAME);
@@ -5173,7 +5346,7 @@ static void adopt_locks(void)
act->rt = LD_RT_VG;
act->mode = LD_LK_SH;
act->flags = LD_AF_ADOPT;
act->client_id = ADOPT_CLIENT_ID;
act->client_id = INTERNAL_CLIENT_ID;
act->lm_type = ls->lm_type;
strncpy(act->vg_name, ls->vg_name, MAX_NAME);
@@ -5199,7 +5372,7 @@ static void adopt_locks(void)
act->rt = LD_RT_GL;
act->mode = LD_LK_SH;
act->flags = LD_AF_ADOPT;
act->client_id = ADOPT_CLIENT_ID;
act->client_id = INTERNAL_CLIENT_ID;
act->lm_type = (gl_use_sanlock ? LD_LM_SANLOCK : LD_LM_DLM);
log_debug("adopt lock for gl");
@@ -5438,7 +5611,7 @@ static void process_listener(int poll_fd)
pthread_mutex_lock(&client_mutex);
client_ids++;
if (client_ids == ADOPT_CLIENT_ID)
if (client_ids == INTERNAL_CLIENT_ID)
client_ids++;
if (!client_ids)
client_ids++;

View File

@@ -343,7 +343,7 @@ static int to_dlm_mode(int ld_mode)
}
static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version)
struct val_blk *vb_out)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
@@ -352,7 +352,7 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
int mode;
int rv;
*r_version = 0;
memset(vb_out, 0, sizeof(struct val_blk));
if (!r->lm_init) {
rv = lm_add_resource_dlm(ls, r, 0);
@@ -431,15 +431,13 @@ static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
*/
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version, int adopt)
struct val_blk *vb_out, int adopt)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
struct dlm_lksb *lksb;
struct val_blk vb;
uint32_t flags = 0;
uint16_t vb_version;
uint16_t vb_flags;
int mode;
int rv;
@@ -447,7 +445,7 @@ int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
/* When adopting, we don't follow the normal method
of acquiring a NL lock then converting it to the
desired mode. */
return lm_adopt_dlm(ls, r, ld_mode, r_version);
return lm_adopt_dlm(ls, r, ld_mode, vb_out);
}
if (!r->lm_init) {
@@ -475,7 +473,7 @@ 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) {
*r_version = 0;
memset(vb_out, 0, sizeof(struct val_blk));
return 0;
}
@@ -513,35 +511,22 @@ lockrv:
if (lksb->sb_flags & DLM_SBF_VALNOTVALID) {
log_debug("S %s R %s lock_dlm VALNOTVALID", ls->name, r->name);
memset(rdd->vb, 0, sizeof(struct val_blk));
*r_version = 0;
memset(vb_out, 0, sizeof(struct val_blk));
goto out;
}
/*
* 'vb' contains disk endian values, not host endian.
* It is copied directly to rdd->vb which is also kept
* in disk endian form.
* vb_out is returned to the caller in host endian form.
*/
memcpy(&vb, lksb->sb_lvbptr, sizeof(struct val_blk));
vb_version = le16_to_cpu(vb.version);
vb_flags = le16_to_cpu(vb.flags);
memcpy(rdd->vb, &vb, sizeof(vb));
if (vb_version && ((vb_version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
log_error("S %s R %s lock_dlm ignore vb_version %x",
ls->name, r->name, vb_version);
*r_version = 0;
free(rdd->vb);
rdd->vb = NULL;
lksb->sb_lvbptr = NULL;
goto out;
}
*r_version = le32_to_cpu(vb.r_version);
memcpy(rdd->vb, &vb, sizeof(vb)); /* rdd->vb saved as le */
log_debug("S %s R %s lock_dlm get r_version %u flags %x",
ls->name, r->name, *r_version, vb_flags);
if (vb_flags & VBF_REMOVED) {
log_debug("S %s R %s lock_dlm VG has been removed",
ls->name, r->name);
return -EREMOVED;
}
vb_out->version = le16_to_cpu(vb.version);
vb_out->flags = le16_to_cpu(vb.flags);
vb_out->r_version = le32_to_cpu(vb.r_version);
}
out:
return 0;
@@ -602,12 +587,12 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
struct dlm_lksb *lksb = &rdd->lksb;
struct val_blk vb_prev;
struct val_blk vb_next;
uint32_t flags = 0;
int new_vb = 0;
int rv;
log_debug("S %s R %s unlock_dlm r_version %u flags %x",
ls->name, r->name, r_version, lmu_flags);
/*
* Do not set PERSISTENT, because we don't need an orphan
* NL lock to protect anything.
@@ -616,22 +601,45 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
flags |= LKF_CONVERT;
if (rdd->vb && (r->mode == LD_LK_EX)) {
if (!rdd->vb->version) {
/* first time vb has been written */
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
/* vb_prev and vb_next are in disk endian form */
memcpy(&vb_prev, rdd->vb, sizeof(struct val_blk));
memcpy(&vb_next, rdd->vb, sizeof(struct val_blk));
if (!vb_prev.version) {
vb_next.version = cpu_to_le16(VAL_BLK_VERSION);
new_vb = 1;
}
if (r_version)
rdd->vb->r_version = cpu_to_le32(r_version);
if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG))
rdd->vb->flags = cpu_to_le16(VBF_REMOVED);
if ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG)) {
vb_next.flags = cpu_to_le16(VBF_REMOVED);
new_vb = 1;
}
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
if (r_version) {
vb_next.r_version = cpu_to_le32(r_version);
new_vb = 1;
}
log_debug("S %s R %s unlock_dlm set r_version %u",
ls->name, r->name, r_version);
if (new_vb) {
memcpy(rdd->vb, &vb_next, sizeof(struct val_blk));
memcpy(lksb->sb_lvbptr, &vb_next, sizeof(struct val_blk));
log_debug("S %s R %s unlock_dlm vb old %x %x %u new %x %x %u",
ls->name, r->name,
le16_to_cpu(vb_prev.version),
le16_to_cpu(vb_prev.flags),
le32_to_cpu(vb_prev.r_version),
le16_to_cpu(vb_next.version),
le16_to_cpu(vb_next.flags),
le32_to_cpu(vb_next.r_version));
} else {
log_debug("S %s R %s unlock_dlm vb unchanged", ls->name, r->name);
}
flags |= LKF_VALBLK;
} else {
log_debug("S %s R %s unlock_dlm", ls->name, r->name);
}
if (daemon_test)
@@ -654,6 +662,62 @@ int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
#define DLM_LOCKSPACES_PATH "/sys/kernel/config/dlm/cluster/spaces"
/*
* FIXME: this should be implemented differently.
* It's not nice to use an aspect of the dlm clustering
* implementation, which could change. It would be
* better to do something like use a special lock in the
* lockspace that was held PR by all nodes, and then an
* EX request on it could check if it's started (and
* possibly also notify others to stop it automatically).
* Or, possibly an enhancement to libdlm that would give
* info about lockspace members.
*
* (We could let the VG be removed while others still
* have the lockspace running, which largely works, but
* introduces problems if another VG with the same name is
* recreated while others still have the lockspace running
* for the previous VG. We'd also want a way to clean up
* the stale lockspaces on the others eventually.)
*/
int lm_hosts_dlm(struct lockspace *ls, int notify)
{
static const char closedir_err_msg[] = "lm_hosts_dlm: closedir failed";
char ls_nodes_path[PATH_MAX];
struct dirent *de;
DIR *ls_dir;
int count = 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);
if (!(ls_dir = opendir(ls_nodes_path)))
return -ECONNREFUSED;
while ((de = readdir(ls_dir))) {
if (de->d_name[0] == '.')
continue;
count++;
}
if (closedir(ls_dir))
log_error(closedir_err_msg);
if (!count) {
log_error("lm_hosts_dlm found no nodes in %s", ls_nodes_path);
return 0;
}
/*
* Assume that a count of one node represents ourself,
* and any value over one represents other nodes.
*/
return count - 1;
}
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
{
static const char closedir_err_msg[] = "lm_get_lockspace_dlm: closedir failed";
@@ -700,3 +764,4 @@ int lm_is_running_dlm(void)
return 0;
return 1;
}

View File

@@ -52,6 +52,7 @@ enum {
LD_OP_FIND_FREE_LOCK,
LD_OP_KILL_VG,
LD_OP_DROP_VG,
LD_OP_BUSY,
};
/* resource types */
@@ -89,7 +90,7 @@ struct client {
};
#define LD_AF_PERSISTENT 0x00000001
#define LD_AF_UNUSED 0x00000002 /* use me */
#define LD_AF_NO_CLIENT 0x00000002
#define LD_AF_UNLOCK_CANCEL 0x00000004
#define LD_AF_NEXT_VERSION 0x00000008
#define LD_AF_WAIT 0x00000010
@@ -143,9 +144,9 @@ struct resource {
unsigned int lm_init : 1; /* lm_data is initialized */
unsigned int adopt : 1; /* temp flag in remove_inactive_lvs */
unsigned int version_zero_valid : 1;
unsigned int use_vb : 1;
struct list_head locks;
struct list_head actions;
struct val_blk *vb;
char lv_args[MAX_ARGS+1];
char lm_data[0]; /* lock manager specific data */
};
@@ -313,14 +314,12 @@ static inline int list_empty(const struct list_head *head)
* or when disable_gl matches.
*/
EXTERN int dlm_gl_lockspace_running;
EXTERN int gl_type_static;
EXTERN int gl_use_dlm;
EXTERN int gl_use_sanlock;
EXTERN pthread_mutex_t gl_type_mutex;
EXTERN char gl_lsname_dlm[MAX_NAME+1];
EXTERN char gl_lsname_sanlock[MAX_NAME+1];
EXTERN int global_dlm_lockspace_exists;
EXTERN int daemon_test; /* run as much as possible without a live lock manager */
EXTERN int daemon_debug;
@@ -357,7 +356,7 @@ int lm_prepare_lockspace_dlm(struct lockspace *ls);
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt);
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg);
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version, int adopt);
struct val_blk *vb_out, int adopt);
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
@@ -366,6 +365,7 @@ int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r);
int lm_get_lockspaces_dlm(struct list_head *ls_rejoin);
int lm_data_size_dlm(void);
int lm_is_running_dlm(void);
int lm_hosts_dlm(struct lockspace *ls, int notify);
static inline int lm_support_dlm(void)
{
@@ -395,7 +395,7 @@ static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
}
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version, int adopt)
struct val_blk *vb_out, int adopt)
{
return -1;
}
@@ -437,6 +437,11 @@ static inline int lm_support_dlm(void)
return 0;
}
static inline int lm_hosts_dlm(struct lockspace *ls, int notify)
{
return 0;
}
#endif /* dlm support */
#ifdef LOCKDSANLOCK_SUPPORT
@@ -449,7 +454,7 @@ int lm_prepare_lockspace_sanlock(struct lockspace *ls);
int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt);
int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg);
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version, int *retry, int adopt);
struct val_blk *vb_out, int *retry, int adopt);
int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version);
int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
@@ -507,7 +512,7 @@ static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
}
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version, int *retry, int adopt)
struct val_blk *vb_out, int *retry, int adopt)
{
return -1;
}

View File

@@ -1300,7 +1300,7 @@ int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
}
int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
uint32_t *r_version, int *retry, int adopt)
struct val_blk *vb_out, int *retry, int adopt)
{
struct lm_sanlock *lms = (struct lm_sanlock *)ls->lm_data;
struct rd_sanlock *rds = (struct rd_sanlock *)r->lm_data;
@@ -1308,7 +1308,6 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
uint64_t lock_lv_offset;
uint32_t flags = 0;
struct val_blk vb;
uint16_t vb_version;
int added = 0;
int rv;
@@ -1384,7 +1383,7 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
(unsigned long long)rs->disks[0].offset);
if (daemon_test) {
*r_version = 0;
memset(vb_out, 0, sizeof(struct val_blk));
return 0;
}
@@ -1501,26 +1500,23 @@ int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
rv = sanlock_get_lvb(0, rs, (char *)&vb, sizeof(vb));
if (rv < 0) {
log_error("S %s R %s lock_san get_lvb error %d", ls->name, r->name, rv);
*r_version = 0;
memset(rds->vb, 0, sizeof(struct val_blk));
memset(vb_out, 0, sizeof(struct val_blk));
goto out;
}
vb_version = le16_to_cpu(vb.version);
/*
* 'vb' contains disk endian values, not host endian.
* It is copied directly to rrs->vb which is also kept
* in disk endian form.
* vb_out is returned to the caller in host endian form.
*/
if (vb_version && ((vb_version & 0xFF00) > (VAL_BLK_VERSION & 0xFF00))) {
log_error("S %s R %s lock_san ignore vb_version %x",
ls->name, r->name, vb_version);
*r_version = 0;
free(rds->vb);
rds->vb = NULL;
goto out;
}
memcpy(rds->vb, &vb, sizeof(vb));
*r_version = le32_to_cpu(vb.r_version);
memcpy(rds->vb, &vb, sizeof(vb)); /* rds->vb saved as le */
log_debug("S %s R %s lock_san get r_version %u",
ls->name, r->name, *r_version);
vb_out->version = le16_to_cpu(vb.version);
vb_out->flags = le16_to_cpu(vb.flags);
vb_out->r_version = le32_to_cpu(vb.r_version);
}
out:
return rv;

View File

@@ -45,7 +45,6 @@
@top_srcdir@/lib/metadata/vg.h
@top_srcdir@/lib/mm/memlock.h
@top_srcdir@/lib/mm/xlate.h
@top_builddir@/lib/misc/configure.h
@top_srcdir@/lib/misc/crc.h
@top_srcdir@/lib/misc/intl.h
@top_srcdir@/lib/misc/last-path-component.h
@@ -56,7 +55,6 @@
@top_srcdir@/lib/misc/lvm-globals.h
@top_srcdir@/lib/misc/lvm-signal.h
@top_srcdir@/lib/misc/lvm-string.h
@top_builddir@/lib/misc/lvm-version.h
@top_srcdir@/lib/misc/lvm-percent.h
@top_srcdir@/lib/misc/lvm-wrappers.h
@top_srcdir@/lib/misc/sharedlib.h

View File

@@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -35,5 +35,5 @@ device-mapper: all
cflow: all
DISTCLEAN_TARGETS += .symlinks
DISTCLEAN_TARGETS += .symlinks configure.h lvm-version.h
CLEAN_TARGETS += $(LINKS) .include_symlinks .symlinks_created

View File

@@ -1,4 +1,4 @@
/* lib/misc/configure.h.in. Generated from configure.in by autoheader. */
/* include/configure.h.in. Generated from configure.in by autoheader. */
/* Define to 1 to use libblkid detection of signatures when wiping. */
#undef BLKID_WIPING_SUPPORT

View File

@@ -230,4 +230,4 @@ CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS) $(VALGRIND_CFLAGS)
$(SUBDIRS): $(LIB_STATIC)
DISTCLEAN_TARGETS += misc/configure.h misc/lvm-version.h
CLEAN_TARGETS += misc/configure.h misc/lvm-version.h

View File

@@ -518,6 +518,73 @@ out:
return r;
}
static int _ignore_unusable_thins(struct device *dev)
{
/* TODO make function for thin testing */
struct dm_pool *mem;
struct dm_status_thin_pool *status;
struct dm_task *dmt = NULL;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
int minor, major;
int r = 0;
if (!(mem = dm_pool_create("unusable_thins", 128)))
return_0;
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
goto_out;
if (!dm_task_no_open_count(dmt))
goto_out;
if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
goto_out;
if (!dm_task_run(dmt)) {
log_error("Failed to get state of mapped device.");
goto out;
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (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;
}
dm_task_destroy(dmt);
if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
goto_out;
if (!dm_task_no_flush(dmt))
log_warn("Can't set no_flush.");
if (!dm_task_no_open_count(dmt))
goto_out;
if (!dm_task_set_major_minor(dmt, minor, major, 1))
goto_out;
if (!dm_task_run(dmt)) {
log_error("Failed to get state of mapped device.");
goto out;
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!dm_get_status_thin_pool(mem, params, &status))
return_0;
if (status->read_only || status->out_of_data_space) {
log_warn("WARNING: %s: Thin's thin-pool needs inspection.",
dev_name(dev));
goto out;
}
r = 1;
out:
if (dmt)
dm_task_destroy(dmt);
dm_pool_destroy(mem);
return r;
}
/*
* device_is_usable
* @dev
@@ -646,6 +713,13 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check)
goto out;
}
/* TODO: extend check struct ? */
if (target_type && !strcmp(target_type, "thin") &&
!_ignore_unusable_thins(dev)) {
log_debug_activation("%s: %s device %s not usable.", dev_name(dev), target_type, name);
goto out;
}
if (target_type && strcmp(target_type, "error"))
only_error_target = 0;
} while (next);
@@ -971,6 +1045,11 @@ static int _percent_run(struct dev_manager *dm, const char *name,
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, 0, 0, 0)))
return_0;
/* No freeze on overfilled thin-pool, read existing slightly outdated data */
if (lv && lv_is_thin_pool(lv) &&
!dm_task_no_flush(dmt))
log_warn("Can't set no_flush flag."); /* Non fatal */
if (!dm_task_run(dmt))
goto_out;
@@ -1038,7 +1117,7 @@ static int _percent_run(struct dev_manager *dm, const char *name,
goto_out;
}
log_debug_activation("LV percent: %f", dm_percent_to_float(*overall_percent));
log_debug_activation("LV percent: %.2f", dm_percent_to_float(*overall_percent));
r = 1;
out:

2
lib/cache/lvmetad.c vendored
View File

@@ -1174,7 +1174,7 @@ static struct volume_group *lvmetad_pvscan_vg(struct cmd_context *cmd, struct vo
if (!vgmeta_ret) {
vgmeta_ret = vgmeta;
} else {
if (!compare_config(vgmeta_ret->root, vgmeta->root)) {
if (compare_config(vgmeta_ret->root, vgmeta->root)) {
log_error("VG metadata comparison failed");
dm_config_destroy(vgmeta);
dm_config_destroy(vgmeta_ret);

View File

@@ -1069,7 +1069,7 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
nr_filt++;
}
/* regex filter. Optional. */
/* global regex filter. Optional. */
if ((cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
log_error("Failed to create global regex device filter");
@@ -1078,6 +1078,17 @@ static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
nr_filt++;
}
/* regex filter. Optional. */
if (!lvmetad_used()) {
if ((cn = find_config_tree_node(cmd, devices_filter_CFG, NULL))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
log_error("Failed to create regex device filter");
goto bad;
}
nr_filt++;
}
}
/* device type filter. Required. */
if (!(filters[nr_filt] = lvm_type_filter_create(cmd->dev_types))) {
log_error("Failed to create lvm type filter");
@@ -1145,26 +1156,24 @@ bad:
* md component filter -> fw raid filter
*
* - cmd->filter - the filter chain used for lvmetad responses:
* persistent filter -> usable device filter(FILTER_MODE_POST_LVMETAD) ->
* regex filter
* persistent filter -> regex_filter -> usable device filter(FILTER_MODE_POST_LVMETAD)
*
* - cmd->full_filter - the filter chain used for all the remaining situations:
* lvmetad_filter -> filter
* cmd->lvmetad_filter -> cmd->filter
*
* If lvmetad isnot used, there's just one filter chain:
* If lvmetad is not used, there's just one filter chain:
*
* - cmd->filter == cmd->full_filter:
* persistent filter -> regex filter -> sysfs filter ->
* global regex filter -> type filter ->
* usable device filter(FILTER_MODE_NO_LVMETAD) ->
* mpath component filter -> partitioned filter ->
* md component filter -> fw raid filter
* persistent filter -> sysfs filter -> global regex filter ->
* regex_filter -> type filter -> usable device filter(FILTER_MODE_NO_LVMETAD) ->
* mpath component filter -> partitioned filter -> md component filter -> fw raid filter
*
*/
int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
{
const char *dev_cache;
struct dev_filter *filter = NULL, *filter_components[2] = {0};
int nr_filt;
struct stat st;
const struct dm_config_node *cn;
struct timespec ts, cts;
@@ -1193,26 +1202,26 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
*/
/* filter component 0 */
if (lvmetad_used()) {
if (!(filter_components[0] = usable_filter_create(cmd->dev_types, FILTER_MODE_POST_LVMETAD))) {
nr_filt = 0;
if ((cn = find_config_tree_array(cmd, devices_filter_CFG, NULL))) {
if (!(filter_components[nr_filt] = regex_filter_create(cn->v))) {
log_verbose("Failed to create regex device filter.");
goto bad;
}
nr_filt++;
}
if (!(filter_components[nr_filt] = usable_filter_create(cmd->dev_types, FILTER_MODE_POST_LVMETAD))) {
log_verbose("Failed to create usable device filter.");
goto bad;
}
nr_filt++;
if (!(filter = composite_filter_create(nr_filt, 0, filter_components)))
goto_bad;
} else {
filter_components[0] = cmd->lvmetad_filter;
filter = cmd->lvmetad_filter;
cmd->lvmetad_filter = NULL;
}
/* filter component 1 */
if ((cn = find_config_tree_array(cmd, devices_filter_CFG, NULL))) {
if (!(filter_components[1] = regex_filter_create(cn->v)))
goto_bad;
/* we have two filter components - create composite filter */
if (!(filter = composite_filter_create(2, 0, filter_components)))
goto_bad;
} else
/* we have only one filter component - no need to create composite filter */
filter = filter_components[0];
if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
goto_bad;
@@ -1224,9 +1233,12 @@ int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
cmd->filter = filter;
if (lvmetad_used()) {
filter_components[0] = cmd->lvmetad_filter;
filter_components[1] = cmd->filter;
if (!(cmd->full_filter = composite_filter_create(2, 0, filter_components)))
nr_filt = 0;
filter_components[nr_filt] = cmd->lvmetad_filter;
nr_filt++;
filter_components[nr_filt] = cmd->filter;
nr_filt++;
if (!(cmd->full_filter = composite_filter_create(nr_filt, 0, filter_components)))
goto_bad;
} else
cmd->full_filter = filter;

View File

@@ -341,11 +341,13 @@ static int _add_alias(struct device *dev, const char *path)
if (!dm_list_empty(&dev->aliases)) {
oldpath = dm_list_item(dev->aliases.n, struct dm_str_list)->str;
prefer_old = _compare_paths(path, oldpath);
log_debug_devs("%s: Aliased to %s in device cache%s",
path, oldpath, prefer_old ? "" : " (preferred name)");
log_debug_devs("%s: Aliased to %s in device cache%s (%d:%d)",
path, oldpath, prefer_old ? "" : " (preferred name)",
(int) MAJOR(dev->dev), (int) MINOR(dev->dev));
} else
log_debug_devs("%s: Added to device cache", path);
log_debug_devs("%s: Added to device cache (%d:%d)", path,
(int) MAJOR(dev->dev), (int) MINOR(dev->dev));
if (prefer_old)
dm_list_add(&dev->aliases, &sl->list);
@@ -946,6 +948,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
{
struct stat buf;
struct device *d = (struct device *) dm_hash_lookup(_cache.names, name);
int info_available = 0;
if (d && (d->flags & DEV_REGULAR))
return d;
@@ -956,7 +959,8 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
dm_hash_remove(_cache.names, name);
log_sys_very_verbose("stat", name);
d = NULL;
}
} else
info_available = 1;
if (d && (buf.st_rdev != d->dev)) {
dm_hash_remove(_cache.names, name);
@@ -964,7 +968,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
}
if (!d) {
_insert(name, &buf, 0, obtain_device_list_from_udev());
_insert(name, info_available ? &buf : NULL, 0, obtain_device_list_from_udev());
d = (struct device *) dm_hash_lookup(_cache.names, name);
if (!d) {
_full_scan(0);

View File

@@ -61,6 +61,8 @@ static int _dev_is_fwraid(struct device *dev)
return 0;
}
#define MSG_SKIPPING "%s: Skipping firmware RAID component device"
static int _ignore_fwraid(struct dev_filter *f __attribute__((unused)),
struct device *dev)
{
@@ -72,8 +74,11 @@ static int _ignore_fwraid(struct dev_filter *f __attribute__((unused)),
ret = _dev_is_fwraid(dev);
if (ret == 1) {
log_debug_devs("%s: Skipping firmware RAID component device [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
return 0;
}

View File

@@ -18,6 +18,8 @@
#ifdef __linux__
#define MSG_SKIPPING "%s: Skipping md component device"
static int _ignore_md(struct dev_filter *f __attribute__((unused)),
struct device *dev)
{
@@ -29,8 +31,11 @@ static int _ignore_md(struct dev_filter *f __attribute__((unused)),
ret = dev_is_md(dev, NULL);
if (ret == 1) {
log_debug_devs("%s: Skipping md component device [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
return 0;
}

View File

@@ -244,11 +244,16 @@ static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
return 0;
}
#define MSG_SKIPPING "%s: Skipping mpath component device"
static int _ignore_mpath(struct dev_filter *f, struct device *dev)
{
if (_dev_is_mpath(f, dev) == 1) {
log_debug_devs("%s: Skipping mpath component device [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
return 0;
}

View File

@@ -16,13 +16,18 @@
#include "lib.h"
#include "filter.h"
#define MSG_SKIPPING "%s: Skipping: Partition table signature found"
static int _passes_partitioned_filter(struct dev_filter *f, struct device *dev)
{
struct dev_types *dt = (struct dev_types *) f->private;
if (dev_is_partitioned(dt, dev)) {
log_debug_devs("%s: Skipping: Partition table signature found [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));
else
log_debug_devs(MSG_SKIPPING " [%s:%p]", dev_name(dev),
dev_ext_name(dev), dev->ext.handle);
return 0;
}

View File

@@ -29,22 +29,19 @@ static int _native_check_pv_min_size(struct device *dev)
/* Check it's accessible */
if (!dev_open_readonly_quiet(dev)) {
log_debug_devs("%s: Skipping: open failed [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
log_debug_devs("%s: Skipping: open failed", dev_name(dev));
return 0;
}
/* Check it's not too small */
if (!dev_get_size(dev, &size)) {
log_debug_devs("%s: Skipping: dev_get_size failed [%s:%p]",
dev_name(dev), dev_ext_name(dev), dev->ext.handle);
log_debug_devs("%s: Skipping: dev_get_size failed", dev_name(dev));
goto out;
}
if (size < pv_min_size()) {
log_debug_devs("%s: Skipping: %s [%s:%p]", dev_name(dev),
_too_small_to_hold_pv_msg,
dev_ext_name(dev), dev->ext.handle);
log_debug_devs("%s: Skipping: %s", dev_name(dev),
_too_small_to_hold_pv_msg);
goto out;
}
@@ -115,26 +112,11 @@ static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
{
filter_mode_t mode = *((filter_mode_t *) f->private);
struct dev_usable_check_params ucp = {0};
int r;
/* check if the device is not too small to hold a PV */
switch (mode) {
case FILTER_MODE_NO_LVMETAD:
/* fall through */
case FILTER_MODE_PRE_LVMETAD:
if (!_check_pv_min_size(dev))
return 0;
break;
case FILTER_MODE_POST_LVMETAD:
/* nothing to do here */
break;
}
int r = 1;
/* further checks are done on dm devices only */
if (!dm_is_dm_major(MAJOR(dev->dev)))
return 1;
switch (mode) {
if (dm_is_dm_major(MAJOR(dev->dev))) {
switch (mode) {
case FILTER_MODE_NO_LVMETAD:
ucp.check_empty = 1;
ucp.check_blocked = 1;
@@ -163,10 +145,25 @@ static int _passes_usable_filter(struct dev_filter *f, struct device *dev)
ucp.check_error_target = 0;
ucp.check_reserved = 0;
break;
}
if (!(r = device_is_usable(dev, ucp)))
log_debug_devs("%s: Skipping unusable device.", dev_name(dev));
}
if (!(r = device_is_usable(dev, ucp)))
log_debug_devs("%s: Skipping unusable device", dev_name(dev));
if (r) {
/* check if the device is not too small to hold a PV */
switch (mode) {
case FILTER_MODE_NO_LVMETAD:
/* fall through */
case FILTER_MODE_PRE_LVMETAD:
r = _check_pv_min_size(dev);
break;
case FILTER_MODE_POST_LVMETAD:
/* nothing to do here */
break;
}
}
return r;
}

View File

@@ -698,15 +698,6 @@ static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
if (!_lvmlockd_connected)
return 0;
/*
* For the dlm, free_vg means unlock the ex VG lock,
* and include an indication in the lvb that the VG
* has been removed. Then, leave the lockspace.
* If another host tries to acquire the VG lock, it
* will see that the VG has been removed by looking
* at the lvb value.
*/
reply = _lockd_send("free_vg",
"pid = %d", getpid(),
"vg_name = %s", vg->name,
@@ -730,6 +721,50 @@ static int _free_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
/* called before vg_remove on disk */
static int _busy_vg_dlm(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
uint32_t lockd_flags = 0;
int result;
int ret;
if (!_use_lvmlockd)
return 0;
if (!_lvmlockd_connected)
return 0;
/*
* Check that other hosts do not have the VG lockspace started.
*/
reply = _lockd_send("busy_vg",
"pid = %d", getpid(),
"vg_name = %s", vg->name,
"vg_lock_type = %s", vg->lock_type,
"vg_lock_args = %s", vg->lock_args,
NULL);
if (!_lockd_result(reply, &result, &lockd_flags)) {
ret = 0;
} else {
ret = (result < 0) ? 0 : 1;
}
if (result == -EBUSY) {
log_error("Lockspace for \"%s\" not stopped on other hosts", vg->name);
goto out;
}
if (!ret)
log_error("_busy_vg_dlm lvmlockd result %d", result);
out:
daemon_reply_destroy(reply);
return ret;
}
/* called before vg_remove on disk */
static int _free_vg_sanlock(struct cmd_context *cmd, struct volume_group *vg)
{
daemon_reply reply;
@@ -881,8 +916,10 @@ int lockd_free_vg_before(struct cmd_context *cmd, struct volume_group *vg,
switch (lock_type_num) {
case LOCK_TYPE_NONE:
case LOCK_TYPE_CLVM:
case LOCK_TYPE_DLM:
return 1;
case LOCK_TYPE_DLM:
/* returning an error will prevent vg_remove() */
return _busy_vg_dlm(cmd, vg);
case LOCK_TYPE_SANLOCK:
/* returning an error will prevent vg_remove() */
return _free_vg_sanlock(cmd, vg);
@@ -921,9 +958,13 @@ void lockd_free_vg_final(struct cmd_context *cmd, struct volume_group *vg)
* for starting the lockspace. To use the vg after starting
* the lockspace, follow the standard method which is:
* lock the vg, read/use/write the vg, unlock the vg.
*
* start_init is 1 when the VG is being started after the
* command has done lockd_init_vg(). This tells lvmlockd
* that the VG lockspace being started is new.
*/
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init)
{
char uuid[64] __attribute__((aligned(8)));
daemon_reply reply;
@@ -945,8 +986,8 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
return 0;
}
log_debug("lockd start VG %s lock_type %s",
vg->name, vg->lock_type ? vg->lock_type : "empty");
log_debug("lockd start VG %s lock_type %s init %d",
vg->name, vg->lock_type ? vg->lock_type : "empty", start_init);
if (!id_write_format(&vg->id, uuid, sizeof(uuid)))
return_0;
@@ -973,6 +1014,7 @@ int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
"vg_uuid = %s", uuid[0] ? uuid : "none",
"version = %d", (int64_t)vg->seqno,
"host_id = %d", host_id,
"opts = %s", start_init ? "start_init" : "none",
NULL);
if (!_lockd_result(reply, &result, NULL)) {
@@ -1454,6 +1496,10 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
}
}
if (!strcmp(mode, "un"))
return 1;
/*
* ENOLS: no lockspace was found with a global lock.
* The VG with the global lock may not be visible or started yet,
@@ -1473,10 +1519,6 @@ int lockd_gl(struct cmd_context *cmd, const char *def_mode, uint32_t flags)
result == -ESTARTING ||
result == -EVGKILLED ||
result == -ELOCKIO) {
if (!strcmp(mode, "un"))
return 1;
/*
* If an ex global lock fails, then the command fails.
*/
@@ -2423,6 +2465,12 @@ int lockd_rename_vg_before(struct cmd_context *cmd, struct volume_group *vg)
}
daemon_reply_destroy(reply);
/* Other hosts have not stopped the lockspace. */
if (result == -EBUSY) {
log_error("Lockspace for \"%s\" not stopped on other hosts", vg->name);
return 0;
}
if (!ret) {
log_error("lockd_rename_vg_before lvmlockd result %d", result);
@@ -2455,7 +2503,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
* Depending on the problem that caused the rename to
* fail, it may make sense to not restart the VG here.
*/
if (!lockd_start_vg(cmd, vg))
if (!lockd_start_vg(cmd, vg, 0))
log_error("Failed to restart VG %s lockspace.", vg->name);
return 1;
}
@@ -2495,7 +2543,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
}
}
if (!lockd_start_vg(cmd, vg))
if (!lockd_start_vg(cmd, vg, 1))
log_error("Failed to start VG %s lockspace.", vg->name);
return 1;

View File

@@ -62,7 +62,7 @@ int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_group *vg, int
/* start and stop the lockspace for a vg */
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg);
int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init);
int lockd_stop_vg(struct cmd_context *cmd, struct volume_group *vg);
int lockd_start_wait(struct cmd_context *cmd);
@@ -147,7 +147,7 @@ static inline int lockd_rename_vg_final(struct cmd_context *cmd, struct volume_g
return 1;
}
static inline int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg)
static inline int lockd_start_vg(struct cmd_context *cmd, struct volume_group *vg, int start_init)
{
return 0;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright (C) 2014 Red Hat, Inc. All rights reserved.
* Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -101,6 +101,23 @@ int cache_set_mode(struct lv_segment *seg, const char *str)
return 1;
}
/*
* At least warn a user if certain cache stacks may present some problems
*/
void cache_check_for_warns(const struct lv_segment *seg)
{
struct logical_volume *origin_lv = seg_lv(seg, 0);
if (lv_is_raid(origin_lv) &&
first_seg(seg->pool_lv)->feature_flags & DM_CACHE_FEATURE_WRITEBACK)
log_warn("WARNING: Data redundancy is lost with writeback "
"caching of raid logical volume!");
if (lv_is_thin_pool_data(seg->lv))
log_warn("WARNING: Cached thin pool's data cannot be currently "
"resized and require manual uncache before resize!");
}
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,

View File

@@ -251,16 +251,18 @@ static int _lv_layout_and_role_raid(struct dm_pool *mem,
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID]))
goto_bad;
if (!strcmp(first_seg(lv)->segtype->name, SEG_TYPE_NAME_RAID1)) {
seg_name = first_seg(lv)->segtype->name;
if (!strcmp(seg_name, SEG_TYPE_NAME_RAID1)) {
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID1]))
goto_bad;
} else if (!strcmp(first_seg(lv)->segtype->name, SEG_TYPE_NAME_RAID10)) {
} else if (!strcmp(seg_name, SEG_TYPE_NAME_RAID10)) {
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID10]))
goto_bad;
} else if (!strcmp(first_seg(lv)->segtype->name, SEG_TYPE_NAME_RAID4)) {
} else if (!strcmp(seg_name, SEG_TYPE_NAME_RAID4)) {
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID4]))
goto_bad;
} else if (!strncmp(seg_name = first_seg(lv)->segtype->name, SEG_TYPE_NAME_RAID5, strlen(SEG_TYPE_NAME_RAID5))) {
} else if (!strncmp(seg_name, SEG_TYPE_NAME_RAID5, strlen(SEG_TYPE_NAME_RAID5))) {
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID5]))
goto_bad;
@@ -277,7 +279,7 @@ static int _lv_layout_and_role_raid(struct dm_pool *mem,
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID5_RS]))
goto_bad;
}
} else if (!strncmp(seg_name = first_seg(lv)->segtype->name, SEG_TYPE_NAME_RAID6, strlen(SEG_TYPE_NAME_RAID6))) {
} else if (!strncmp(seg_name, SEG_TYPE_NAME_RAID6, strlen(SEG_TYPE_NAME_RAID6))) {
if (!str_list_add_no_dup_check(mem, layout, _lv_type_names[LV_TYPE_RAID6]))
goto_bad;
@@ -4403,8 +4405,11 @@ static int _adjust_policy_params(struct cmd_context *cmd,
policy_amount =
find_config_tree_int(cmd, activation_thin_pool_autoextend_percent_CFG,
lv_config_profile(lv));
if (!policy_amount && policy_threshold < DM_PERCENT_100)
return 0;
if (!policy_amount && policy_threshold < DM_PERCENT_100) {
log_error("Can't extend thin pool %s, autoextend is set to 0%%.",
display_lvname(lv));
return 0;
}
} else {
policy_threshold =
find_config_tree_int(cmd, activation_snapshot_autoextend_threshold_CFG, NULL) * DM_PERCENT_1;
@@ -4415,6 +4420,12 @@ static int _adjust_policy_params(struct cmd_context *cmd,
if (policy_threshold >= DM_PERCENT_100)
return 1; /* nothing to do */
if (!lv_is_active_locally(lv)) {
log_error("Can't read state of locally inactive LV %s.",
display_lvname(lv));
return 0;
}
if (lv_is_thin_pool(lv)) {
if (!lv_thin_pool_percent(lv, 1, &percent))
return_0;
@@ -6252,6 +6263,7 @@ int move_lv_segments(struct logical_volume *lv_to,
struct logical_volume *lv_from,
uint64_t set_status, uint64_t reset_status)
{
const uint64_t MOVE_BITS = (RAID | MIRROR | THIN_VOLUME);
struct lv_segment *seg;
dm_list_iterate_items(seg, &lv_to->segments)
@@ -6269,6 +6281,16 @@ int move_lv_segments(struct logical_volume *lv_to,
seg->status |= set_status;
}
/*
* Move LV status bits for selected types with their segments
* i.e. when inserting layer to cache LV, we move raid segments
* to a new place, thus 'raid' LV property now belongs to this LV.
*
* Bits should match to those which appears after read from disk.
*/
lv_to->status |= lv_from->status & MOVE_BITS;
lv_from->status &= ~MOVE_BITS;
lv_to->le_count = lv_from->le_count;
lv_to->size = lv_from->size;
@@ -7503,6 +7525,8 @@ static struct logical_volume *_lv_create_an_lv(struct volume_group *vg,
if (!cache_set_policy(first_seg(lv), lp->policy_name, lp->policy_settings))
return_NULL; /* revert? */
cache_check_for_warns(first_seg(lv));
if (!lv_update_and_reload(lv)) {
/* FIXME Do a better revert */
log_error("Aborting. Manual intervention required.");

View File

@@ -119,12 +119,24 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
inc_error_count;
}
if (lv_is_pool_metadata(lv) &&
(!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->metadata_lv != lv)) {
log_error("LV %s: segment 1 pool metadata LV does not point back to same LV",
lv->name);
inc_error_count;
if (lv_is_pool_metadata(lv)) {
if (!(seg2 = first_seg(lv)) || !(seg2 = find_pool_seg(seg2)) ||
seg2->metadata_lv != lv) {
log_error("LV %s: segment 1 pool metadata LV does not point back to same LV",
lv->name);
inc_error_count;
}
if (lv_is_thin_pool_metadata(lv) &&
!strstr(lv->name, "_tmeta")) {
log_error("LV %s: thin pool metadata LV does not use _tmeta",
lv->name);
inc_error_count;
} else if (lv_is_cache_pool_metadata(lv) &&
!strstr(lv->name, "_cmeta")) {
log_error("LV %s: cache pool metadata LV does not use _cmeta",
lv->name);
inc_error_count;
}
}
}

View File

@@ -1158,6 +1158,7 @@ int cache_mode_is_set(const struct lv_segment *seg);
int cache_set_mode(struct lv_segment *cache_seg, const char *str);
int cache_set_policy(struct lv_segment *cache_seg, const char *name,
const struct dm_config_tree *settings);
void cache_check_for_warns(const struct lv_segment *seg);
int update_cache_pool_params(const struct segment_type *segtype,
struct volume_group *vg, unsigned attr,
int passed_args, uint32_t pool_data_extents,

View File

@@ -319,10 +319,11 @@ static struct pv_list *_copy_pvl(struct dm_pool *pvmem, struct pv_list *pvl_from
if (!(pvl_to->pv = dm_pool_alloc(pvmem, sizeof(*pvl_to->pv))))
goto_bad;
if(!_copy_pv(pvmem, pvl_to->pv, pvl_from->pv))
if (!_copy_pv(pvmem, pvl_to->pv, pvl_from->pv))
goto_bad;
return pvl_to;
bad:
dm_pool_free(pvmem, pvl_to);
return NULL;
@@ -3010,7 +3011,7 @@ out:
int vg_write(struct volume_group *vg)
{
struct dm_list *mdah;
struct pv_to_create *pv_to_create;
struct pv_to_create *pv_to_create, *pv_to_create_safe;
struct metadata_area *mda;
struct lv_list *lvl;
int revert = 0, wrote = 0;
@@ -3066,10 +3067,11 @@ int vg_write(struct volume_group *vg)
memlock_unlock(vg->cmd);
vg->seqno++;
dm_list_iterate_items(pv_to_create, &vg->pvs_to_create) {
dm_list_iterate_items_safe(pv_to_create, pv_to_create_safe, &vg->pvs_to_create) {
if (!_pvcreate_write(vg->cmd, pv_to_create))
return 0;
}
dm_list_del(&pv_to_create->list);
}
/* Write to each copy of the metadata area */
dm_list_iterate_items(mda, &vg->fid->metadata_areas_in_use) {

View File

@@ -397,8 +397,10 @@ static struct logical_volume *_alloc_image_component(struct logical_volume *lv,
}
if (dm_snprintf(img_name, sizeof(img_name), "%s_%s_%%d",
(alt_base_name) ? : lv->name, type_suffix) < 0)
return_0;
(alt_base_name) ? : lv->name, type_suffix) < 0) {
log_error("Component name for raid %s is too long.", lv->name);
return 0;
}
status = LVM_READ | LVM_WRITE | LV_REBUILD | type;
if (!(tmp_lv = lv_create_empty(img_name, NULL, status, ALLOC_INHERIT, lv->vg))) {

2
lib/misc/.gitignore vendored
View File

@@ -1,2 +0,0 @@
configure.h
lvm-version.h

View File

@@ -620,6 +620,15 @@ static int _thin_target_percent(void **target_state __attribute__((unused)),
/* Pool allocates whole chunk so round-up to nearest one */
csize = first_seg(seg->pool_lv)->chunk_size;
csize = ((seg->lv->size + csize - 1) / csize) * csize;
if (s->mapped_sectors > csize) {
log_warn("WARNING: LV %s maps %s while the size is only %s.",
display_lvname(seg->lv),
display_size(cmd, s->mapped_sectors),
display_size(cmd, csize));
/* Don't show nonsense numbers like i.e. 1000% full */
s->mapped_sectors = csize;
}
*percent = dm_make_percent(s->mapped_sectors, csize);
*total_denominator += csize;
} else {

View File

@@ -2826,8 +2826,8 @@ uint64_t dm_histogram_get_sum(const struct dm_histogram *dmh);
/*
* Histogram formatting flags.
*/
#define DM_HISTOGRAM_VALUES 0x1
#define DM_HISTOGRAM_SUFFIX 0x2
#define DM_HISTOGRAM_SUFFIX 0x1
#define DM_HISTOGRAM_VALUES 0x2
#define DM_HISTOGRAM_PERCENT 0X4
#define DM_HISTOGRAM_BOUNDS_LOWER 0x10
#define DM_HISTOGRAM_BOUNDS_UPPER 0x20
@@ -2840,6 +2840,12 @@ uint64_t dm_histogram_get_sum(const struct dm_histogram *dmh);
* The bin argument selects the bin to format. If this argument is less
* than zero all bins will be included in the resulting string.
*
* width specifies a minimum width for the field in characters; if it is
* zero the width will be determined automatically based on the options
* selected for formatting. A value less than zero disables field width
* control: bin boundaries and values will be output with a minimum
* amount of whitespace.
*
* flags is a collection of flag arguments that control the string format:
*
* DM_HISTOGRAM_VALUES - Include bin values in the string.

View File

@@ -8,4 +8,5 @@ Description: device-mapper library
Version: @DM_LIB_PATCHLEVEL@
Cflags: -I${includedir}
Libs: -L${libdir} -ldevmapper
Requires.private: @SELINUX_PC@ @UDEV_PC@ @RT_PC@
Requires.private: @SELINUX_PC@ @UDEV_PC@
Libs.private: -lm @RT_LIB@

View File

@@ -1427,7 +1427,50 @@ static int _suspend_node(const char *name, uint32_t major, uint32_t minor,
return r;
}
static int _thin_pool_status_transaction_id(struct dm_tree_node *dnode, uint64_t *transaction_id)
static int _thin_pool_parse_status(const char *params,
struct dm_status_thin_pool *s)
{
int pos;
if (!params) {
log_error("Failed to parse invalid thin params.");
return 0;
}
/* FIXME: add support for held metadata root */
if (sscanf(params, FMTu64 " " FMTu64 "/" FMTu64 " " FMTu64 "/" FMTu64 "%n",
&s->transaction_id,
&s->used_metadata_blocks,
&s->total_metadata_blocks,
&s->used_data_blocks,
&s->total_data_blocks, &pos) < 5) {
log_error("Failed to parse thin pool params: %s.", params);
return 0;
}
/* New status flags */
if (strstr(params + pos, "no_discard_passdown"))
s->discards = DM_THIN_DISCARDS_NO_PASSDOWN;
else if (strstr(params + pos, "ignore_discard"))
s->discards = DM_THIN_DISCARDS_IGNORE;
else /* default discard_passdown */
s->discards = DM_THIN_DISCARDS_PASSDOWN;
if (strstr(params + pos, "ro "))
s->read_only = 1;
else if (strstr(params + pos, "fail"))
s->fail = 1;
else if (strstr(params + pos, "out_of_data_space"))
s->out_of_data_space = 1;
if (strstr(params + pos, "error_if_no_space"))
s->error_if_no_space = 1;
return 1;
}
static int _thin_pool_get_status(struct dm_tree_node *dnode,
struct dm_status_thin_pool *s)
{
struct dm_task *dmt;
int r = 0;
@@ -1458,14 +1501,12 @@ static int _thin_pool_status_transaction_id(struct dm_tree_node *dnode, uint64_t
goto out;
}
if (!params || (sscanf(params, FMTu64, transaction_id) != 1)) {
log_error("Failed to parse transaction_id from %s.", params);
goto out;
}
if (!_thin_pool_parse_status(params, s))
goto_out;
log_debug_activation("Found transaction id %" PRIu64 " for thin pool %s "
"with status line: %s.",
*transaction_id, _node_name(dnode), params);
s->transaction_id, _node_name(dnode), params);
r = 1;
out:
@@ -1553,7 +1594,7 @@ static int _node_send_messages(struct dm_tree_node *dnode,
{
struct load_segment *seg;
struct thin_message *tmsg;
uint64_t trans_id;
struct dm_status_thin_pool stp = { 0 };
const char *uuid;
int have_messages;
@@ -1572,39 +1613,39 @@ static int _node_send_messages(struct dm_tree_node *dnode,
return 1;
}
if (!_thin_pool_status_transaction_id(dnode, &trans_id))
if (!_thin_pool_get_status(dnode, &stp))
return_0;
have_messages = !dm_list_empty(&seg->thin_messages) ? 1 : 0;
if (trans_id == seg->transaction_id) {
if (stp.transaction_id == seg->transaction_id) {
dnode->props.send_messages = 0; /* messages already committed */
if (have_messages)
log_debug_activation("Thin pool %s transaction_id matches %"
PRIu64 ", skipping messages.",
_node_name(dnode), trans_id);
_node_name(dnode), stp.transaction_id);
return 1;
}
/* Error if there are no stacked messages or id mismatches */
if ((trans_id + 1) != seg->transaction_id) {
if ((stp.transaction_id + 1) != seg->transaction_id) {
log_error("Thin pool %s transaction_id is %" PRIu64 ", while expected %" PRIu64 ".",
_node_name(dnode), trans_id, seg->transaction_id - have_messages);
_node_name(dnode), stp.transaction_id, seg->transaction_id - have_messages);
return 0;
}
if (!send)
if (!have_messages || !send)
return 1; /* transaction_id is matching */
dm_list_iterate_items(tmsg, &seg->thin_messages) {
if (!(_thin_pool_node_message(dnode, tmsg)))
return_0;
if (tmsg->message.type == DM_THIN_MESSAGE_SET_TRANSACTION_ID) {
if (!_thin_pool_status_transaction_id(dnode, &trans_id))
if (!_thin_pool_get_status(dnode, &stp))
return_0;
if (trans_id != tmsg->message.u.m_set_transaction_id.new_id) {
if (stp.transaction_id != tmsg->message.u.m_set_transaction_id.new_id) {
log_error("Thin pool %s transaction_id is %" PRIu64
" and does not match expected %" PRIu64 ".",
_node_name(dnode), trans_id,
_node_name(dnode), stp.transaction_id,
tmsg->message.u.m_set_transaction_id.new_id);
return 0;
}
@@ -4003,48 +4044,17 @@ int dm_get_status_thin_pool(struct dm_pool *mem, const char *params,
struct dm_status_thin_pool **status)
{
struct dm_status_thin_pool *s;
int pos;
if (!params) {
log_error("Failed to parse invalid thin pool params.");
return 0;
}
if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_thin_pool)))) {
log_error("Failed to allocate thin_pool status structure.");
return 0;
}
/* FIXME: add support for held metadata root */
if (sscanf(params, FMTu64 " " FMTu64 "/" FMTu64 " " FMTu64 "/" FMTu64 "%n",
&s->transaction_id,
&s->used_metadata_blocks,
&s->total_metadata_blocks,
&s->used_data_blocks,
&s->total_data_blocks, &pos) < 5) {
if (!_thin_pool_parse_status(params, s)) {
dm_pool_free(mem, s);
log_error("Failed to parse thin pool params: %s.", params);
return 0;
return_0;
}
/* New status flags */
if (strstr(params + pos, "no_discard_passdown"))
s->discards = DM_THIN_DISCARDS_NO_PASSDOWN;
else if (strstr(params + pos, "ignore_discard"))
s->discards = DM_THIN_DISCARDS_IGNORE;
else /* default discard_passdown */
s->discards = DM_THIN_DISCARDS_PASSDOWN;
if (strstr(params + pos, "ro "))
s->read_only = 1;
else if (strstr(params + pos, "fail"))
s->fail = 1;
else if (strstr(params + pos, "out_of_data_space"))
s->out_of_data_space = 1;
if (strstr(params + pos, "error_if_no_space"))
s->error_if_no_space = 1;
*status = s;
return 1;
@@ -4055,11 +4065,6 @@ int dm_get_status_thin(struct dm_pool *mem, const char *params,
{
struct dm_status_thin *s;
if (!params) {
log_error("Failed to parse invalid thin params.");
return 0;
}
if (!(s = dm_pool_zalloc(mem, sizeof(struct dm_status_thin)))) {
log_error("Failed to allocate thin status structure.");
return 0;

View File

@@ -119,8 +119,8 @@ int dm_create_lockfile(const char *lockfile)
char buffer[50];
int retries = 0;
if((fd = open(lockfile, O_CREAT | O_WRONLY,
(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
if ((fd = open(lockfile, O_CREAT | O_WRONLY,
(S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH))) < 0) {
log_error("Cannot open lockfile [%s], error was [%s]",
lockfile, strerror(errno));
return 0;

View File

@@ -2309,7 +2309,8 @@ static const char *_get_reserved(struct dm_report *rh, unsigned type,
float dm_percent_to_float(dm_percent_t percent)
{
return (float) percent / DM_PERCENT_1;
/* Add 0.f to prevent returning -0.00 */
return (float) percent / DM_PERCENT_1 + 0.f;
}
dm_percent_t dm_make_percent(uint64_t numerator, uint64_t denominator)
@@ -4194,7 +4195,7 @@ static void _destroy_rows(struct dm_report *rh)
* pool allocation this will also free all subsequently allocated
* rows from the report and any associated string data.
*/
if(rh->first_row)
if (rh->first_row)
dm_pool_free(rh->mem, rh->first_row);
rh->first_row = NULL;
dm_list_init(&rh->rows);

File diff suppressed because it is too large Load Diff

View File

@@ -155,9 +155,8 @@ static struct dm_list *_lvm_list_pvs(lvm_t libh)
} else {
dm_list_init(&rc->pvslist);
dm_list_init(&rc->vgslist);
if( !get_pvs_perserve_vg(cmd, &rc->pvslist, &rc->vgslist) ) {
return NULL;
}
if (!get_pvs_perserve_vg(cmd, &rc->pvslist, &rc->vgslist))
return_NULL;
/*
* If we have no PVs we still need to have access to cmd

View File

@@ -275,7 +275,7 @@ POTFILES = $(SOURCES:%.c=%.pot)
.PHONY: all pofile distclean clean cleandir cflow device-mapper
.PHONY: install install_cluster install_device-mapper install_lvm2
.PHONY: install_lib_shared install_dm_plugin install_lvm2_plugin
.PHONY: install_ocf install_systemd_generators install_full_man help
.PHONY: install_ocf install_systemd_generators install_all_man all_man man help
.PHONY: python_bindings install_python_bindings
.PHONY: $(SUBDIRS) $(SUBDIRS.install) $(SUBDIRS.clean) $(SUBDIRS.distclean)
.PHONY: $(SUBDIRS.pofile) $(SUBDIRS.install_cluster) $(SUBDIRS.cflow)
@@ -448,7 +448,7 @@ $(LIB_STATIC): $(OBJECTS)
$(RM) $@
$(AR) rs $@ $(OBJECTS)
%.d: %.c
%.d: %.c $(INC_LNS)
$(MKDIR_P) $(dir $@); \
set -e; \
FILE=`echo $@ | sed 's/\\//\\\\\\//g;s/\\.d//g'`; \
@@ -511,6 +511,7 @@ else
) > $@
endif
ifeq ("@USE_TRACKING@","yes")
ifeq (,$(findstring $(MAKECMDGOALS),cscope.out cflow clean distclean lcov \
help check check_local check_cluster check_lvmetad check_lvmpolld))
ifdef SOURCES
@@ -520,3 +521,4 @@ ifeq (,$(findstring $(MAKECMDGOALS),cscope.out cflow clean distclean lcov \
-include $(SOURCES2:.c=.d)
endif
endif
endif

View File

@@ -21,7 +21,7 @@ BLKDEACTIVATEMAN = blkdeactivate.8
DMEVENTDMAN = dmeventd.8
LVMETADMAN = lvmetad.8
LVMPOLLDMAN = lvmpolld.8
LVMLOCKDMAN = lvmlockd.8
LVMLOCKDMAN = lvmlockd.8 lvmlockctl.8
CLVMDMAN = clvmd.8
CMIRRORDMAN = cmirrord.8
LVMCACHEMAN = lvmcache.7
@@ -42,7 +42,15 @@ MAN8DM=dmsetup.8 dmstats.8
MAN8CLUSTER=
MAN8SYSTEMD_GENERATORS=lvm2-activation-generator.8
ifeq ($(MAKECMDGOALS),install_full_man)
ifeq ($(MAKECMDGOALS),all_man)
MAN_ALL="yes"
endif
ifeq ($(MAKECMDGOALS),install_all_man)
MAN_ALL="yes"
endif
ifeq ($(MAN_ALL),"yes")
MAN8+=$(FSADMMAN) $(LVMETADMAN) $(LVMPOLLDMAN) $(LVMLOCKDMAN)
MAN8DM+=$(BLKDEACTIVATEMAN) $(DMEVENTDMAN)
MAN8CLUSTER+=$(CLVMDMAN) $(CMIRRORDMAN)
@@ -109,6 +117,8 @@ device-mapper: $(MAN8DM)
man: $(MAN5) $(MAN7) $(MAN8) $(MAN8CLUSTER) $(MAN8SYSTEMD_GENERATORS)
all_man: man
$(MAN5) $(MAN7) $(MAN8) $(MAN8DM) $(MAN8CLUSTER): Makefile
Makefile: Makefile.in
@@ -150,4 +160,4 @@ install_systemd_generators: $(MAN8SYSTEMD_GENERATORS)
install: install_lvm2 install_device-mapper install_cluster
install_full_man: install install_systemd_generators
install_all_man: install install_systemd_generators

View File

@@ -1,4 +1,4 @@
eTH DMSTATS 8 "Jul 25 2015" "Linux" "MAINTENANCE COMMANDS"
.TH DMSTATS 8 "Jul 25 2015" "Linux" "MAINTENANCE COMMANDS"
.SH NAME
dmstats \(em device-mapper statistics management
.SH SYNOPSIS
@@ -32,8 +32,8 @@ dmstats \(em device-mapper statistics management
.IR nr_areas ]
.RB |[ \-\-areasize
.IR area_size ]]
.RB [ \-\-histogram
.IR boundaries ]
.RB [ \-\-bounds
.IR histogram_boundaries ]
.RB [ \-\-precise ]
.RB [[ \-\-start
.IR start_sector ]
@@ -58,37 +58,16 @@ dmstats \(em device-mapper statistics management
.B dmstats help
.RB [ \-c | \-C | \-\-columns ]
.br
.B dmstats histogram
.RI [ device_name ]
.RB [ \-\-interval
.IR seconds ]
.RB [ \-\-count
.IR count ]
.RB [ \-\-units
.IR units ]
.RB [ \-\-allprograms ]
.RB [ \-\-programid
.IR id ]
.RB [ \-\-relative ]
.RB [ \-\-regionid
.IR id ]
.RB [ \-O | \-\-sort
.IR sort_fields ]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-\-units
.IR units ]
.RB [ \-\-nosuffix ]
.br
.B dmstats list
.RI [ device_name ]
.RB [ \-\-allprograms
.RB | \-\-programid
.IR id ]
.RB [ \-\-histogram ]
.RB [ \-\-units
.IR units ]
.RB [ \-\-nosuffix ]
.RB [ \-\-nosuffix ]
.RB [ \-\-notimesuffix ]
.RB [ \-v | \-\-verbose \ [ \-v | \-\-verbose ]
.br
.B dmstats print
@@ -109,6 +88,7 @@ dmstats \(em device-mapper statistics management
.IR count ]
.RB [ \-\-units
.IR units ]
.RB [ \-\-histogram ]
.RB [ \-\-allprograms ]
.RB [ \-\-programid
.IR id ]
@@ -121,6 +101,7 @@ dmstats \(em device-mapper statistics management
.RB [ \-\-units
.IR units ]
.RB [ \-\-nosuffix ]
.RB [ \-\-notimesuffix ]
.br
.ad b
.SH DESCRIPTION
@@ -178,13 +159,17 @@ When printing statistics counters, also atomically reset them to zero.
Specify the iteration count for repeating reports. If the count
argument is zero reports will continue to repeat until interrupted.
.TP
.B \-\-histogram \fIboundaries
.B \-\-bounds \fIhistogram_boundaries
Specify the boundaries of a latency histogram to be tracked for the
region as a comma separated list of latency values. Latency values are
given in nanoseconds. An optional unit suffix of ns, us, ms, or s may be
given after each value to specify units of nanoseconds, microseconds,
miliseconds or seconds respectively.
.TP
.B \-\-histogram
When used with the \fBreport\fP and \fBlist\fP commands select default
fields that emphasize latency histogram data.
.TP
.B \-\-interval \fIseconds
Specify the interval in seconds between successive iterations for
repeating reports. If \-\-interval is specified but \-\-count is not,
@@ -206,6 +191,10 @@ Specify the minor number.
Suppress the suffix on output sizes. Use with \fB\-\-units\fP
(except h and H) if processing the output.
.TP
.B \-\-notimesuffix
Suppress the suffix on output time values. Histogram boundary values
will be reported in units of nanoseconds.
.TP
.BR \-o | \-\-options
Specify which report fields to display.
.TP
@@ -283,8 +272,8 @@ regions (with the exception of in-flight IO counters).
.IR nr_areas ]
.RB [ \-\-areasize
.IR area_size ]
.RB [ \-\-histogram
.IR boundaries ]
.RB [ --bounds
.IR histogram_boundaries ]
.RB [ \-\-precise ]
.RB [[ \-\-start
.IR start_sector ]
@@ -308,7 +297,7 @@ device-mapper device's table.
If the \fB\-\-precise\fP option is used the command will attempt to
create a region using nanosecond precision counters.
If \fB\-\-histogram\fP is given a latency histogram will be tracked for
If \fB--bounds\fP is given a latency histogram will be tracked for
the new region. The boundaries of the histogram bins are given as a
comma separated list of latency values. There is an implicit lower bound
of zero on the first bin and an implicit upper bound of infinity (or the
@@ -363,40 +352,9 @@ Outputs a summary of the commands available, optionally including
the list of report fields.
.br
.TP
.B histogram
.RB [ \-\-allprograms ]
.RB [ \-\-interval
.IR seconds ]
.RB [ \-\-count
.IR count ]
.RB [ \-\-units
.IR unit ]
.RB [ \-\-relative ]
.RB [ \-\-regionid
.IR id ]
.RB [ \-\-programid
.IR id ]
.RB [ \-O | \-\-sort
.IR sort_fields ]
.RB [ \-S | \-\-select
.IR Selection ]
.RB [ \-\-units
.IR units ]
.br
Start a report for the specified region or for all present regions that
emphasizes latency histograms in the default field options. If the count
argument is specified, the report will repeat at a fixed interval set by
the \fB\-\-interval\fP option. The default interval is one second.
If the \fB\-\-allprograms\fP switch is given, all regions will be
listed, regardless of region program ID values.
If \fB\-\-relative\fP is given the default histogram field displays the
relative histogram instead of absolute counts.
.br
.TP
.B list
.RI [ device_name ]
.RB [ \-\-histogram ]
.RB [ \-\-allprograms ]
.RB [ \-\-programid
.RB [ \-v | \-\-verbose \ [ \-v | \-\-verbose ]]
@@ -408,6 +366,9 @@ regardless of region program ID values.
If \fB\-v\fP or \fB\-\-verbose\fP is given the report will include
a row of information for each area contained in each region displayed.
If \fB\-\-histogram\fP is given the report will include the bin count
and latency boundary values for any configured histograms.
.br
.TP
.B print
@@ -450,6 +411,13 @@ one second.
If the \fB\-\-allprograms\fP switch is given, all regions will be
listed, regardless of region program ID values.
If \fB\-\-histogram\fP is given the report will include the histogram
values and latency boundaries.
If \fB\-\-relative\fP is used the default histogram field displays
bin values as a percentage of the total number of I/Os.
.br
.SH REGIONS AND AREAS
The device-mapper statistics facility allows separate performance

102
man/lvmlockctl.8.in Normal file
View File

@@ -0,0 +1,102 @@
.TH "LVMLOCKCTL" "8" "LVM TOOLS #VERSION#" "Red Hat, Inc" "\""
.SH NAME
lvmlockctl \(em Control for lvmlockd
.SH DESCRIPTION
This command interacts with
.BR lvmlockd (8).
.SH OPTIONS
lvmlockctl [options]
.B \-\-help | \-h
Show this help information.
.B \-\-quit | \-q
Tell lvmlockd to quit.
.B \-\-info | \-i
Print lock state information from lvmlockd.
.B \-\-dump | \-d
Print log buffer from lvmlockd.
.B \-\-wait | \-w 0|1
Wait option for other commands.
.B \-\-force | \-f 0|1
Force option for other commands.
.B \-\-kill | \-k
.I vgname
Kill access to the VG when sanlock cannot renew lease.
.B \-\-drop | \-r
.I vgname
Clear locks for the VG when it is unused after kill (-k).
.B \-\-gl\-enable | \-E
.I vgname
Tell lvmlockd to enable the global lock in a sanlock VG.
.B \-\-gl\-disable | \-D
.I vgname
Tell lvmlockd to disable the global lock in a sanlock VG.
.B \-\-stop\-lockspaces | \-S
Stop all lockspaces.
.SH USAGE
.SS info
This collects and displays lock state from lvmlockd. The display is
primitive, incomplete and will change in future version. To print the raw
lock state from lvmlockd, combine this option with --dump|-d.
.SS dump
This collects the circular log buffer of debug statements from lvmlockd
and prints it.
.SS kill
This is run by sanlock when it loses access to the storage holding leases
for a VG. It currently emits a syslog message stating that the VG must
be immediately deactivated. In the future it may automatically attempt to
forcibly deactivate the VG. For more, see
.BR lvmlockd (8).
.SS drop
This should only be run after a VG has been successfully deactivated
following an lvmlockctl \-\-kill command. It clears the stale lockspace
from lvmlockd. In the future, this may become automatic along with an
automatic handling of \-\-kill. For more, see
.BR lvmlockd (8).
.SS gl\-enable
This enables the global lock in a sanlock VG. This is necessary if the VG
that previously held the global lock is removed. For more, see
.BR lvmlockd (8).
.SS gl\-disable
This disables the global lock in a sanlock VG. This is necessary if the
global lock has mistakenly been enabled in more than one VG. The global
lock should be disabled in all but one sanlock VG. For more, see
.BR lvmlockd (8).
.SS stop\-lockspaces
This tells lvmlockd to stop all lockspaces. It can be useful to stop
lockspaces for VGs that the vgchange \-\-lock\-stop comand can no longer
see, or to stop the dlm global lockspace which is not directly stopped by
the vgchange command. The wait and force options can be used with this
command.

View File

@@ -298,6 +298,39 @@ LVM commands request locks from clvmd to use the VG.
.P
.SS creating the first sanlock VG
Creating the first sanlock VG is not protected by locking and requires
special attention. This is because sanlock locks exist within the VG, so
they are not available until the VG exists. The first sanlock VG will
contain the "global lock".
.IP \[bu] 2
The first vgcreate command needs to be given the path to a device that has
not yet been initialized with pvcreate. The pvcreate initialization will
be done by vgcreate. This is because the pvcreate command requires the
global lock, which will not be available until after the first sanlock VG
is created.
.IP \[bu] 2
While running vgcreate for the first sanlock VG, ensure that the device
being used is not used by another LVM command. Allocation of shared
devices is usually protected by the global lock, but this cannot be done
for the first sanlock VG which will hold the global lock.
.IP \[bu] 2
While running vgcreate for the first sanlock VG, ensure that the VG name
being used is not used by another LVM command. Uniqueness of VG names is
usually ensured by the global lock.
.IP \[bu] 2
Because the first sanlock VG will contain the global lock, this VG needs
to be accessible to all hosts that will use sanlock shared VGs. All hosts
will need to use the global lock from the first sanlock VG.
See below for more information about managing the sanlock global lock.
.SS using lockd VGs
There are some special considerations when using lockd VGs.
@@ -319,6 +352,10 @@ be displayed with 'vgs \-o+locktype,lockargs'.
lockd VGs need to be "started" and "stopped", unlike other types of VGs.
See the following section for a full description of starting and stopping.
vgremove of a lockd VG will fail if other hosts have the VG started.
Run vgchange \-\-lock-stop <vgname> on all other hosts before vgremove.
(It may take several seconds before vgremove recognizes that all hosts
have stopped a sanlock VG.)
.SS starting and stopping VGs
@@ -479,9 +516,7 @@ global/lvmlockd_lock_retries before failing. If a request for an LV lock
fails due to a lock conflict, the command fails immediately.
.SS sanlock global lock
There are some special cases related to the global lock in sanlock VGs.
.SS managing the global lock in sanlock VGs
The global lock exists in one of the sanlock VGs. The first sanlock VG
created will contain the global lock. Subsequent sanlock VGs will each
@@ -526,17 +561,10 @@ A small sanlock VG dedicated to holding the global lock can avoid the case
where the GL lock must be manually enabled after a vgremove.
.SS sanlock VG usage
There are some special cases related to using a sanlock VG.
vgremove of a sanlock VG will fail if other hosts have the VG started.
Run vgchange \-\-lock-stop <vgname> on all other hosts before vgremove.
(It may take several seconds before vgremove recognizes that all hosts
have stopped.)
.SS internal lvmlock LV
A sanlock VG contains a hidden LV called "lvmlock" that holds the sanlock
locks. vgreduce cannot yet remove the PV holding the lvmlockd LV. To
locks. vgreduce cannot yet remove the PV holding the lvmlock LV. To
remove this PV, change the VG lock type to "none", run vgreduce, then
change the VG lock type back to "sanlock".
@@ -590,13 +618,20 @@ the dlm/corosync recovery process is complete.
.B sanlock lease storage failure
If a host loses access to the device holding a VG's locks, sanlock cannot
renew its lease for the VG's locks. After some time, the lease will
expire, and locks held by the host can be acquired by other hosts.
If the PV under a sanlock VG's lvmlock LV is disconnected, unresponsive or
too slow, sanlock cannot renew the lease for the VG's locks. After some
time, the lease will expire, and locks that the host owns in the VG can be
acquired by other hosts. The VG must be forcibly deactivated on the host
with the expiring lease before other hosts can acquire its locks.
If no LVs are active in the VG, the lockspace with an expiring lease will
be shut down, and errors will be reported when trying to use the VG. Use
the lvmlockctl \-\-drop command to clear the stale lockspace from
When the sanlock daemon detects that the lease storage is lost, it runs
the command lvmlockctl \-\-kill <vgname>. This command emits a syslog
message stating that lease storage is lost for the VG and LVs must be
immediately deactivated.
If no LVs are active in the VG, then the lockspace with an expiring lease
will be removed, and errors will be reported when trying to use the VG.
Use the lvmlockctl \-\-drop command to clear the stale lockspace from
lvmlockd.
If the VG has active LVs when the lock storage is lost, the LVs must be
@@ -607,9 +642,12 @@ about 40 seconds, sanlock will reset the host using the local watchdog.
The machine reset is effectively a severe form of "deactivating" LVs
before they can be activated on other hosts. The reset is considered a
better alternative than having LVs used by multiple hosts at once, which
could easily damage or destroy their content. A future enhancement may
automatically attempt to forcibly deactivate LVs before the lockspace
lease expires.
could easily damage or destroy their content.
In the future, the lvmlockctl kill command may automatically attempt to
forcibly deactivate LVs before the sanlock lease expires. Until then, the
user must notice the syslog message and manually deactivate the VG before
sanlock resets the machine.
.B sanlock daemon failure

View File

@@ -151,6 +151,7 @@ DISTCLEAN_TARGETS += \
lvm2_clvmd_systemd_red_hat.service \
lvm2_cmirrord_systemd_red_hat.service \
lvm2_lvmetad_init_red_hat \
lvm2_lvmpolld_init_red_hat \
lvm2_lvmetad_systemd_red_hat.service \
lvm2_lvmetad_systemd_red_hat.socket \
lvm2_lvmpolld_systemd_red_hat.service \

View File

@@ -1,7 +1,7 @@
#!/bin/bash
# Copyright (C) 2009 Chris Procter All rights reserved.
# Copyright (C) 2009 Red Hat, Inc. All rights reserved.
# Copyright (C) 2009-2015 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@@ -239,7 +239,7 @@ LVMCONF=${TMP_LVM_SYSTEM_DIR}/lvm.conf
CMD_CONFIG_LINE="devices { \
scan = [ \"${TMP_LVM_SYSTEM_DIR}\" ] \
cache_dir = \"$TMP_LVM_SYSTEM_DIR}/cache\"
cache_dir = \"${TMP_LVM_SYSTEM_DIR}/cache\"
global_filter = [ \"a|.*|\" ] \
${FILTER}
} \

View File

@@ -42,6 +42,7 @@ make install DESTDIR=$RPM_BUILD_ROOT
make install_system_dirs DESTDIR=$RPM_BUILD_ROOT
%if %{enable_systemd}
make install_systemd_units DESTDIR=$RPM_BUILD_ROOT
make install_systemd_generators DESTDIR=$RPM_BUILD_ROOT
make install_tmpfiles_configuration DESTDIR=$RPM_BUILD_ROOT
%else
make install_initscripts DESTDIR=$RPM_BUILD_ROOT

View File

@@ -4,6 +4,7 @@
%global _default_locking_dir /run/lock/lvm
%global _udevbasedir %{_prefix}/lib/udev
%global _udevdir %{_udevbasedir}/rules.d
%global _tmpfilesdir %{_prefix}/lib/tmpfiles.d
%if !0%{?fedora}
%global fedora 0
@@ -34,7 +35,7 @@
%define daemon_reload \
%if %{enable_systemd} \
/bin/systemctl daemon-reload > /dev/null 2>&1 || : \
systemctl daemon-reload > /dev/null 2>&1 || : \
%endif \
: \
%{nil}
@@ -42,9 +43,11 @@
%define enable(s:t:) \
%if %{have_service %{-s*}} \
%if %{enable_systemd} \
/bin/systemctl enable lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
if [ $1 = 1 ]; then \
systemctl preset lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
fi \
%else \
/sbin/chkconfig --add lvm2-%{-s*} \
/sbin/chkconfig --add lvm2-%{-s*} \
%endif \
%endif \
: \
@@ -53,13 +56,18 @@
%define disable(s:t:) \
%if %{have_service %{-s*}} \
%if %{enable_systemd} \
/bin/systemctl --no-reload disable lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
/bin/systemctl stop lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
%if %{-t*} == socket \
/bin/systemctl stop lvm2-%{-s*}.service > /dev/null 2>&1 || : \
%endif \
if [ $1 = 0 ]; then \
systemctl --no-reload disable lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
%if %{-t*} == socket \
systemctl --no-reload disable lvm2-%{-s*}.service > /dev/null 2>&1 || : \
%endif \
systemctl stop lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
%if %{-t*} == socket \
systemctl stop lvm2-%{-s*}.service > /dev/null 2>&1 || : \
%endif \
fi \
%else \
/sbin/chkconfig --del lvm2-%{-s*} \
/sbin/chkconfig --del lvm2-%{-s*} \
%endif \
%endif \
: \
@@ -67,7 +75,9 @@
%define try_restart(s:t:) \
%if %{have_service %{-s*}} && %{enable_systemd} \
/bin/systemctl try-restart lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
if [ $1 = 1 ]; then \
systemctl try-restart lvm2-%{-s*}.%{-t*} > /dev/null 2>&1 || : \
fi \
%endif \
: \
: \
%{nil}

View File

@@ -1,23 +1,34 @@
### MAIN PACKAGE (lvm2)
%post
/sbin/ldconfig
%daemon_reload
%enable -s monitor -t service
%if %{have_service lvmetad}
%enable -s lvmetad -t socket
%endif
%if %{have_service lvmpolld}
%enable -s lvmpolld -t socket
%endif
%preun
if [ "$1" = 0 ]; then
%disable -s monitor -t service
%if %{have_service lvmpolld}
%disable -s lvmpolld -t socket
%endif
%if %{have_service lvmetad}
%disable -s lvmetad -t socket
fi
%endif
%disable -s monitor -t service
%postun
%daemon_reload
if [ $1 -ge 1 ]; then
%try_restart -s monitor -t service
%if %{have_service lvmetad}
%try_restart -s lvmetad -t service
%endif
%if %{have_service lvmpolld}
%try_restart -s lvmpolld -t service
%endif
if [ $1 = 0 ]; then
%daemon_reload
fi
%triggerun -- %{name} < 2.02.86-2
@@ -31,6 +42,7 @@ fi
%defattr(-,root,root,-)
%doc COPYING COPYING.LIB INSTALL README VERSION WHATS_NEW
%doc doc/lvm_fault_handling.txt
%{_sbindir}/blkdeactivate
%{_sbindir}/fsadm
%{_sbindir}/lvchange
%{_sbindir}/lvconvert
@@ -39,6 +51,8 @@ fi
%{_sbindir}/lvextend
%{_sbindir}/lvm
%{_sbindir}/lvmchange
%{_sbindir}/lvmconf
%{_sbindir}/lvmconfig
%{_sbindir}/lvmdiskscan
%{_sbindir}/lvmdump
%{_sbindir}/lvmsadc
@@ -77,32 +91,28 @@ fi
%{_sbindir}/vgs
%{_sbindir}/vgscan
%{_sbindir}/vgsplit
%{_sbindir}/lvmconfig
%{_sbindir}/lvmconf
%{_sbindir}/blkdeactivate
%if %{have_service lvmetad}
%{_sbindir}/lvmetad
%endif
%if %{have_service lvmpolld}
%{_sbindir}/lvmpolld
%endif
%if %{have_with cache}
%{_mandir}/man7/lvmcache.7.gz
%endif
%if %{have_with thin}
%{_mandir}/man7/lvmthin.7.gz
%endif
%{_mandir}/man7/lvmsystemid.7.gz
%{_mandir}/man5/lvm.conf.5.gz
%{_mandir}/man7/lvmsystemid.7.gz
%{_mandir}/man8/blkdeactivate.8.gz
%{_mandir}/man8/fsadm.8.gz
%{_mandir}/man8/lvchange.8.gz
%{_mandir}/man8/lvconvert.8.gz
%{_mandir}/man8/lvcreate.8.gz
%{_mandir}/man8/lvdisplay.8.gz
%{_mandir}/man8/lvextend.8.gz
%{_mandir}/man8/lvm-config.8.gz
%{_mandir}/man8/lvm-dumpconfig.8.gz
%{_mandir}/man8/lvm.8.gz
%{_mandir}/man8/lvm2-activation-generator.8.gz
%{_mandir}/man8/lvmchange.8.gz
%{_mandir}/man8/lvmconf.8.gz
%{_mandir}/man8/lvmconfig.8.gz
%{_mandir}/man8/lvmdiskscan.8.gz
%{_mandir}/man8/lvmdump.8.gz
%{_mandir}/man8/lvmsadc.8.gz
@@ -141,10 +151,16 @@ fi
%{_mandir}/man8/vgs.8.gz
%{_mandir}/man8/vgscan.8.gz
%{_mandir}/man8/vgsplit.8.gz
%{_mandir}/man8/blkdeactivate.8.gz
%{_mandir}/man8/lvm-dumpconfig.8.gz
%{_mandir}/man8/lvm-config.8.gz
%{_mandir}/man8/lvmconfig.8.gz
%if %{have_with cache}
%{_mandir}/man7/lvmcache.7.gz
%endif
%if %{have_with thin}
%{_mandir}/man7/lvmthin.7.gz
%endif
%if %{have_service lvmpolld}
%{_mandir}/man8/lvmpolld.8.gz
%{_mandir}/man8/lvm-lvpoll.8.gz
%endif
%if %{enable_udev}
%{_udevdir}/11-dm-lvm.rules
%if %{have_service lvmetad}
@@ -152,14 +168,11 @@ fi
%{_udevdir}/69-dm-lvm-metad.rules
%endif
%endif
%if %{have_service lvmpolld}
%{_mandir}/man8/lvmpolld.8.gz
%{_mandir}/man8/lvm-lvpoll.8.gz
%endif
%dir %{_sysconfdir}/lvm
%ghost %{_sysconfdir}/lvm/cache/.cache
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvm.conf
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvmlocal.conf
%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvm.conf
%attr(644, -, -) %config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/lvmlocal.conf
%dir %{_sysconfdir}/lvm/profile
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/command_profile_template.profile
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/metadata_profile_template.profile
%config(noreplace) %verify(not md5 mtime size) %{_sysconfdir}/lvm/profile/thin-generic.profile
@@ -169,23 +182,25 @@ fi
%dir %{_sysconfdir}/lvm/backup
%dir %{_sysconfdir}/lvm/cache
%dir %{_sysconfdir}/lvm/archive
%dir %{_default_run_dir}
%ghost %dir %{_default_locking_dir}
%ghost %dir %{_default_run_dir}
%if %{enable_systemd}
%config(noreplace) %{_prefix}/lib/tmpfiles.d/%{name}.conf
%{_tmpfilesdir}/%{name}.conf
%{_unitdir}/blk-availability.service
%{_unitdir}/lvm2-monitor.service
%attr(555, -, -) %{_prefix}/lib/systemd/system-generators/lvm2-activation-generator
%if %{have_service lvmetad}
%{_unitdir}/lvm2-lvmetad.socket
%{_unitdir}/lvm2-lvmetad.service
%{_unitdir}/lvm2-pvscan@.service
%{_unitdir}/blk-availability.service
%endif
%if %{have_service lvmpolld}
%{_unitdir}/lvm2-lvmpolld.service
%{_unitdir}/lvm2-lvmpolld.socket
%endif
%else
%{_sysconfdir}/rc.d/init.d/lvm2-monitor
%{_sysconfdir}/rc.d/init.d/blk-availability
%{_sysconfdir}/rc.d/init.d/lvm2-monitor
%if %{have_service lvmetad}
%{_sysconfdir}/rc.d/init.d/lvm2-lvmetad
%endif
@@ -272,18 +287,24 @@ Requires(postun): systemd-units
LVM commands use lvmlockd to coordinate access to shared storage.
%post lockd
%systemd_post lvm2-lvmlockd.service lvm2-lvmlocking.service
%daemon_reload
%enable -s lvmlockd -t service
%enable -s lvmlocking -t service
%preun lockd
%systemd_preun lvm2-lvmlockd.service lvm2-lvmlocking.service
%disable -s lvmlocking -t service
%disable -s lvmlockd -t service
%postun lockd
%systemd_postun lvm2-lvmlockd.service lvm2-lvmlocking.service
if [ $1 = 0 ]; then
%daemon_reload
fi
%files lockd
%{_sbindir}/lvmlockd
%{_sbindir}/lvmlockctl
%{_mandir}/man8/lvmlockd.8.gz
%{_mandir}/man8/lvmlockctl.8.gz
%dir %{_default_locking_dir}
%{_unitdir}/lvm2-lvmlockd.service
%{_unitdir}/lvm2-lvmlocking.service
@@ -310,18 +331,29 @@ Requires(preun): lvm2 >= 2.02
Extensions to LVM2 to support clusters.
%post cluster
/sbin/chkconfig --add clvmd
if [ "$1" -gt "1" ] ; then
/usr/sbin/clvmd -S >/dev/null 2>&1 || :
%daemon_reload
%enable -s clvmd -t service
%if %{have_service clvmd}
if [ $1 = 2 ]; then
if [ -e %{_default_pid_dir}/clvmd.pid ]; then
%{_sbindir}/clvmd -S >/dev/null 2>&1 || :
fi
fi
%endif
%preun cluster
if [ "$1" = 0 ]; then
/sbin/chkconfig --del clvmd
# lvmconf may no longer exist if lvm2 is being removed in the same rpm run
%disable -s clvmd -t service
%if %{have_service clvmd}
if [ $1 = 0 ]; then
# lvmconf may no longer exist if lvm2 is being removed in the same rpm run
if test -x /sbin/lvmconf; then /sbin/lvmconf --disable-cluster; fi
fi
%endif
%postun cluster
if [ $1 = 0 ]; then
%daemon_reload
fi
%files cluster
%defattr(-,root,root,-)
@@ -354,11 +386,16 @@ Requires: device-mapper >= %{device_mapper_version}-%{release}
Daemon providing device-mapper-based mirrors in a shared-storage cluster.
%post -n cmirror
/sbin/chkconfig --add cmirrord
%daemon_reload
%enable -s cmirrord -t service
%preun -n cmirror
if [ "$1" = 0 ]; then
/sbin/chkconfig --del cmirrord
%disable -s cmirrord -t service
%postun -n cmirror
%try_restart -s cmirrord -t service
if [ $1 = 0 ]; then
%daemon_reload
fi
%files -n cmirror
@@ -467,26 +504,26 @@ This package contains the dmeventd daemon for monitoring the state
of device-mapper devices.
%post -n device-mapper-event
%daemon_reload
%if %{enable_systemd}
/bin/systemctl daemon-reload > /dev/null 2>&1 || :
/bin/systemctl enable dm-event.socket > /dev/null 2>&1 || :
systemctl preset dm-event.socket > /dev/null 2>&1 || :
%endif
if [ -e %{_default_pid_dir}/dmeventd.pid ]; then
%{_sbindir}/dmeventd -R || echo "Failed to restart dmeventd daemon. Please, try manual restart."
fi
%preun -n device-mapper-event
%if %{enable_systemd}
if [ "$1" = 0 ]; then
/bin/systemctl --no-reload disable dm-event.service dm-event.socket > /dev/null 2>&1 || :
/bin/systemctl stop dm-event.service dm-event.socket> /dev/null 2>&1 || :
if [ $1 = 0 ]; then
systemctl --no-reload disable dm-event.service dm-event.socket > /dev/null 2>&1 || :
systemctl stop dm-event.service dm-event.socket> /dev/null 2>&1 || :
fi
%endif
%postun -n device-mapper-event
%if %{enable_systemd}
/bin/systemctl daemon-reload > /dev/null 2>&1 || :
if [ $1 -ge 1 ]; then
/bin/systemctl reload dm-event.service > /dev/null 2>&1 || :
if [ $1 = 0 ]; then
%daemon_reload
fi
%endif
%files -n device-mapper-event
%defattr(-,root,root,-)

View File

@@ -4,14 +4,31 @@
# Defaults (rawhide)...
%global enable_profiling 0
%global enable_testsuite 0
%global enable_testsuite 1
%global enable_udev 1
%global enable_systemd 1
%global enable_cmirror 1
#%global enable_lvmlockd 0
%global enable_lvmlockd 1
%global enable_lvmetad 1
%global enable_lvmpolld 1
#%global enable_lockd_dlm 0
#%global enable_lockd_sanlock 0
%if %{enable_udev}
%service lvmetad 1
%service lvmpolld 1
%endif
########################################################
# Normally clustering is maintained via resource agents
#
# enable service only if you know what you are doing
#
%if %{enable_cmirror}
#service clvmd 1
#service cmirrord 1
%endif
%global buildreq_cluster corosync-devel >= 1.99.9-1, dlm-devel >= 3.99.1-1
%global req_cluster corosync >= 1.99.9-1, dlm >= 3.99.2-1
%with clvmd corosync
@@ -26,9 +43,6 @@
%global buildreq_udev systemd-devel
%global req_udev udev >= 181-1
%service lvmetad 1
%service lvmpolld 1
%if %{fedora} >= 22 || %{rhel} >= 7
%service lvmlockd 1

View File

@@ -30,6 +30,7 @@ LVM_TEST_RESULTS ?= results
SUBDIRS = api unit
SOURCES = lib/not.c lib/harness.c
CXXSOURCES = lib/runner.cpp
CXXFLAGS += $(EXTRA_EXEC_CFLAGS)
include $(top_builddir)/make.tmpl
@@ -171,41 +172,53 @@ DATADIR = $(datadir)/lvm2-testsuite
EXECDIR = $(libexecdir)/lvm2-testsuite
LIB_FLAVOURS = \
lib/flavour-ndev-cluster-lvmpolld\
lib/flavour-ndev-cluster\
lib/flavour-ndev-lvmetad-lvmpolld\
lib/flavour-ndev-lvmetad\
lib/flavour-ndev-lvmpolld\
lib/flavour-ndev-vanilla\
lib/flavour-udev-cluster-lvmpolld\
lib/flavour-udev-cluster\
lib/flavour-udev-lvmetad-lvmpolld\
lib/flavour-udev-lvmetad\
lib/flavour-udev-lvmpolld\
lib/flavour-udev-lvmlockd-sanlock\
lib/flavour-udev-lvmlockd-dlm\
lib/flavour-udev-vanilla
flavour-ndev-cluster-lvmpolld\
flavour-ndev-cluster\
flavour-ndev-lvmetad-lvmpolld\
flavour-ndev-lvmetad\
flavour-ndev-lvmpolld\
flavour-ndev-vanilla\
flavour-udev-cluster-lvmpolld\
flavour-udev-cluster\
flavour-udev-lvmetad-lvmpolld\
flavour-udev-lvmetad\
flavour-udev-lvmpolld\
flavour-udev-lvmlockd-sanlock\
flavour-udev-lvmlockd-dlm\
flavour-udev-vanilla
LIB_LOCAL = lib/paths lib/runner
LIB_EXEC = lib/not lib/invalid lib/fail lib/should
LIB_SHARED = lib/check lib/aux lib/inittest lib/utils lib/get lib/lvm-wrapper
LIB_LVMLOCKD_CONF = \
test-corosync-conf \
test-dlm-conf \
test-sanlock-conf
install: .tests-stamp lib/paths-installed
LIB_LOCAL = paths runner
LIB_NOT = not
LIB_LINK_NOT = invalid fail should
LIB_SHARED = check aux inittest utils get lvm-wrapper
install: .tests-stamp lib/paths-installed lib/version-expected
@echo $(srcdir)
@echo $(LIB_FLAVOURS)
$(INSTALL_DIR) $(DATADIR)/{shell,api,lib}
$(INSTALL_DATA) shell/*.sh $(DATADIR)/shell/
$(INSTALL_DATA) api/*.sh $(DATADIR)/api/
$(INSTALL_PROGRAM) api/*.{t,py} $(DATADIR)/api/
$(INSTALL_DIR) $(DATADIR)/{shell,api,lib} $(EXECDIR)
$(INSTALL_DATA) shell/*.sh $(DATADIR)/shell
$(INSTALL_DATA) api/*.sh $(DATADIR)/api
$(INSTALL_PROGRAM) api/*.{t,py} $(DATADIR)/api
$(INSTALL_DATA) lib/paths-installed $(DATADIR)/lib/paths
$(INSTALL_DATA) $(LIB_FLAVOURS) $(DATADIR)/lib/
for i in cache-mq cache-smq thin-performance ; do \
$(INSTALL_DATA) $(abs_top_srcdir)/conf/$$i.profile $(DATADIR)/lib/$$i.profile; done
$(INSTALL_SCRIPT) $(LIB_SHARED) $(DATADIR)/lib/
for i in $(CMDS); do (cd $(DATADIR)/lib && $(LN_S) -f lvm-wrapper $$i); done
$(INSTALL_DIR) $(EXECDIR)
$(INSTALL_PROGRAM) $(LIB_EXEC) $(EXECDIR)
cd lib && $(INSTALL_DATA) \
$(LIB_FLAVOURS) \
$(LIB_LVMLOCKD_CONF) \
version-expected $(DATADIR)/lib
@for i in cache-mq cache-smq thin-performance ; do \
echo "$(INSTALL_DATA) $(abs_top_srcdir)/conf/$$i.profile $(DATADIR)/lib"; \
$(INSTALL_DATA) $(abs_top_srcdir)/conf/$$i.profile $(DATADIR)/lib; done
cd lib && $(INSTALL_SCRIPT) $(LIB_SHARED) $(DATADIR)/lib
@cd $(DATADIR)/lib && for i in $(CMDS); do \
echo "$(LN_S) -f lvm-wrapper $$i"; \
$(LN_S) -f lvm-wrapper $$i; done
$(INSTALL_PROGRAM) lib/$(LIB_NOT) $(EXECDIR)
@cd $(EXECDIR) && for i in $(LIB_LINK_NOT); do \
echo "$(LN_S) -f not $$i"; \
$(LN_S) -f not $$i; done
$(INSTALL_PROGRAM) -D lib/runner $(bindir)/lvm2-testsuite
lib/should: lib/not
@@ -218,10 +231,12 @@ lib/fail: lib/not
$(LN_S) -f not lib/fail
lib/runner: lib/runner.o .lib-dir-stamp
$(CXX) $(LDFLAGS) -o $@ $<
$(CXX) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) -o $@ $<
lib/runner.o: $(wildcard $(srcdir)/lib/*.h)
CFLAGS_runner.o += $(EXTRA_EXEC_CFLAGS)
lib/%: lib/%.o .lib-dir-stamp
$(CC) $(LDFLAGS) -o $@ $<
@@ -268,10 +283,13 @@ lib/paths: lib/paths-common
echo 'abs_builddir="$(abs_builddir)"' >> $@-t
mv $@-t $@
CMDS = lvm $(shell cat $(top_builddir)/tools/.commands)
LIB = $(LIB_SHARED) $(LIB_LOCAL) $(LIB_EXEC) $(LIB_FLAVOURS)
lib/version-expected: $(top_srcdir)/VERSION .lib-dir-stamp
cut -f 1 -d ' ' <$< >$@
.tests-stamp: $(ALL) $(LIB) $(SUBDIRS)
CMDS = lvm $(shell cat $(top_builddir)/tools/.commands 2>/dev/null)
LIB = $(addprefix lib/, $(LIB_SHARED) $(LIB_LOCAL) $(LIB_NOT) $(LIB_LINK_NOT) $(LIB_FLAVOURS))
.tests-stamp: $(ALL) $(LIB) $(SUBDIRS) lib/version-expected
@if test "$(srcdir)" != . ; then \
echo "Linking tests to builddir."; \
$(MKDIR_P) shell; \
@@ -285,27 +303,26 @@ LIB = $(LIB_SHARED) $(LIB_LOCAL) $(LIB_EXEC) $(LIB_FLAVOURS)
.lib-dir-stamp:
$(MKDIR_P) lib
for i in $(CMDS); do $(LN_S) -f lvm-wrapper lib/$$i; done
$(LN_S) -f $(abs_top_builddir)/tools/dmsetup lib/dmsetup
$(LN_S) -f $(abs_top_builddir)/daemons/clvmd/clvmd lib/clvmd
$(LN_S) -f $(abs_top_builddir)/daemons/dmeventd/dmeventd lib/dmeventd
$(LN_S) -f $(abs_top_builddir)/daemons/lvmetad/lvmetad lib/lvmetad
$(LN_S) -f $(abs_top_builddir)/daemons/lvmpolld/lvmpolld lib/lvmpolld
$(LN_S) -f $(abs_top_srcdir)/scripts/vgimportclone.sh lib/vgimportclone
for i in daemons/clvmd/clvmd daemons/dmeventd/dmeventd \
tools/dmsetup daemons/lvmetad/lvmetad \
daemons/lvmpolld/lvmpolld ; do \
$(LN_S) -f $(abs_top_builddir)/$$i lib/; done
$(LN_S) -f $(abs_top_srcdir)/conf/thin-performance.profile lib/
$(LN_S) -f $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
$(LN_S) -f $(abs_top_srcdir)/conf/thin-performance.profile lib/thin-performance.profile
$(LN_S) -f $(abs_top_srcdir)/scripts/vgimportclone.sh lib/vgimportclone
test "$(srcdir)" = . || for i in $(LIB_LVMLOCKD_CONF); do \
$(LN_S) -f $(abs_top_srcdir)/test/lib/$$i lib/; done
touch $@
CLEAN_DIRS += $(LVM_TEST_RESULTS)
ifneq (.,$(firstword $(srcdir)))
CLEAN_TARGETS += $(RUN_BASE)
CLEAN_TARGETS += $(RUN_BASE) $(addprefix lib/,$(LIB_LVMLOCKD_CONF))
endif
CLEAN_TARGETS += .lib-dir-stamp .tests-stamp $(LIB) $(addprefix lib/,$(CMDS)) \
lib/clvmd lib/dmeventd lib/dmsetup lib/lvmetad lib/fsadm lib/vgimportclone \
lib/thin-performance.profile lib/harness \
lib/paths-installed lib/paths-installed-t \
lib/paths-common lib/paths-common-t \
lib/lvmpolld
CLEAN_TARGETS += .lib-dir-stamp .tests-stamp $(LIB) $(addprefix lib/,\
$(CMDS) clvmd dmeventd dmsetup lvmetad lvmpolld \
harness thin-performance.profile fsadm vgimportclone version-expected \
paths-installed paths-installed-t paths-common paths-common-t)
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@

View File

@@ -253,7 +253,7 @@ teardown_devs() {
test ${#stray_loops[@]} -eq 0 || {
teardown_devs_prefixed "$COMMON_PREFIX" 1
echo "Removing stray loop devices containing $COMMON_PREFIX: ${stray_loops[@]}"
for i in "${stray_loops[@]}" ; do losetup -d $i ; done
for i in "${stray_loops[@]}" ; do test ! -f $i || losetup -d $i ; done
# Leave test when udev processed all removed devices
udev_wait
}
@@ -1108,6 +1108,14 @@ have_raid() {
return 1;
}
target_at_least dm-raid "$@"
# some kernels have broken mdraid bitmaps, don't use them!
# may oops kernel, we know for sure all FC24 are currently broken
# in general any 4.1, 4.2 is likely useless unless patched
# hopefully 4.3 will be patched
case "$(uname -r)" in
4.[123].*fc24*) return 1 ;;
esac
}
have_cache() {

View File

@@ -268,8 +268,7 @@ lv_not_exists() {
else
while [ $# -gt 1 ]; do
shift
lvl $vg/$1 &>/dev/null || continue
die "$vg/$1 expected to not exist but it does!"
not lvl $vg/$1 &>/dev/null || die "$vg/$1 expected to not exist but it does!"
done
fi
rm -f debug.log

View File

@@ -15,15 +15,10 @@ test -e LOCAL_LVMPOLLD && skip
lvm version
test -n "$abs_top_builddir" || skip
v=$abs_top_builddir/lib/misc/lvm-version.h
sed -n "/#define LVM_VERSION ./s///p" "$v" | sed "s/ .*//" > expected
lvm pvmove --version|sed -n "1s/.*: *\([0-9][^ ]*\) .*/\1/p" > actual
lvm pvmove --version|sed -n "1s/.*: *\([0-9][^ ]*\) .*/\1/p" | tee version
# ensure they are the same
diff -u actual expected
diff -u version lib/version-expected
# ensure we can create devices (uses dmsetup, etc)
aux prepare_devs 5

View File

@@ -24,7 +24,7 @@ aux prepare_vg 5 80
# Bug 1095843
# lvcreate RAID1 origin, lvcreate cache-pool, and lvconvert to cache
lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
lvcreate --type raid1 -m 1 --nosync -l 2 -n $lv1 $vg
lvcreate --type cache-pool -l 1 -n ${lv1}_cachepool $vg
lvconvert --cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
@@ -33,17 +33,19 @@ lvremove -f $vg
# lvcreate RAID1 origin, lvcreate RAID1 cache-pool, and lvconvert to cache
lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
lvcreate --type raid1 -m 1 -l 2 -n ${lv1}_cachepool $vg
lvcreate --type raid1 -m 1 --nosync -l 2 -n $lv1 $vg
lvcreate --type raid1 -m 1 --nosync -l 2 -n ${lv1}_cachepool $vg
#should lvs -a $vg/${lv1}_cdata_rimage_0 # ensure images are properly renamed
lvconvert --yes --type cache --cachepool $vg/${lv1}_cachepool $vg/$lv1
lvconvert --yes --type cache --cachemode writeback --cachepool $vg/${lv1}_cachepool $vg/$lv1 2>&1 | tee out
grep "WARNING: Data redundancy is lost" out
check lv_exists $vg/${lv1}_corig_rimage_0 # ensure images are properly renamed
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
lvremove -f $vg
lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
lvcreate -n cpool --type cache $vg/corigin -l 10
lvcreate -n corigin -m 1 --type raid1 --nosync -l 10 $vg
lvcreate -n cpool --type cache $vg/corigin --cachemode writeback -l 10 2>&1 | tee out
grep "WARNING: Data redundancy is lost" out
lvconvert --splitmirrors 1 --name split $vg/corigin "$dev1"
lvremove -f $vg

View File

@@ -0,0 +1,58 @@
#!/bin/sh
# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Test repairing of broken thin pool on raid
. lib/inittest
test -e LOCAL_LVMPOLLD && skip
aux have_thin 1 0 0 || skip
aux have_raid 1 4 0 || skip
#
# Main
#
aux prepare_vg 4
lvcreate --type raid1 -L1 -n pool $vg
lvcreate --type raid1 -L2 -n meta $vg
# raid _tdata & _tmeta
lvconvert -y --thinpool $vg/pool --poolmetadata $vg/meta
lvcreate -V1G $vg/pool
# Pool has to be inactive (ATM) for repair
fail lvconvert -y --repair $vg/pool "$dev3"
lvchange -an $vg
check lv_field $vg/pool_tmeta lv_role "private,thin,pool,metadata"
lvconvert -y --repair $vg/pool "$dev3"
lvs -a -o+devices,seg_pe_ranges,role,layout $vg
check lv_field $vg/pool_meta0 lv_role "public"
check lv_field $vg/pool_meta0 lv_layout "raid,raid1"
check lv_field $vg/pool_tmeta lv_layout "linear"
check lv_on $vg pool_tmeta "$dev1"
# Hmm name is generated in order
SPARE=$(lvs --noheadings -a --select "name=~_pmspare" -o name $vg)
SPARE=${SPARE##*[}
SPARE=${SPARE%%]*}
check lv_on $vg $SPARE "$dev3"
lvchange -ay $vg
vgremove -ff $vg

View File

@@ -0,0 +1,34 @@
#!/bin/sh
# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
# Exercise creation of cache and raids
. lib/inittest
test -e LOCAL_LVMPOLLD && skip
aux have_cache 1 3 0 || skip
aux have_raid 1 0 0 || skip
# FIXME: parallel cache metadata allocator is crashing when used value 8000!
aux prepare_vg 5 80000
aux lvmconf 'global/cache_disabled_features = [ "policy_smq" ]'
# Bug 1110026 & Bug 1095843
# Create RAID1 origin, then cache pool and cache
lvcreate -aey -l 2 --type raid1 -m1 -n $lv2 $vg
lvcreate --cache -l 1 $vg/$lv2
check lv_exists $vg/${lv2}_corig_rimage_0 # ensure images are properly renamed
check active $vg ${lv2}_corig
dmsetup table ${vg}-$lv2 | grep cache # ensure it is loaded in kernel
vgremove -ff $vg

View File

@@ -36,6 +36,8 @@ invalid lvcreate -H -l 1 --name $lv1 $vg
invalid lvcreate -l 1 --cache $vg
# Only cached volume could be created
invalid lvcreate -l 1 --type cache $vg
# Striping is not supported with cache-pool creation
invalid lvcreate -l 1 -i 2 --type cache-pool $vg
# Fails as it needs to see VG content
fail lvcreate -l 1 --type cache --cachepool $vg/pool1
fail lvcreate -l 1 --type cache --cachepool pool2 $vg
@@ -142,13 +144,6 @@ lvcreate -aey -l 2 -n $lv1 $vg
lvcreate --type cache -l 1 $vg/$lv1
dmsetup table ${vg}-$lv1 | grep cache # ensure it is loaded in kernel
# Bug 1110026 & Bug 1095843
# Create RAID1 origin, then cache pool and cache
lvcreate -aey -l 2 --type raid1 -m1 -n $lv2 $vg
lvcreate --cache -l 1 $vg/$lv2
check lv_exists $vg/${lv2}_corig_rimage_0 # ensure images are properly renamed
dmsetup table ${vg}-$lv2 | grep cache # ensure it is loaded in kernel
lvremove -f $vg
@@ -168,6 +163,8 @@ lvremove -f $vg
# writeable origin and 'default' => writable cache + origin
lvcreate -an -l1 -n $vg/$lv1
# do not allow stripping for cache-pool
fail lvcreate -H -i 2 -l1 -n cpool1 $vg/$lv1
lvcreate -H -l1 -n cpool1 $vg/$lv1
check lv_attr_bit perm $vg/cpool1 "w"
check lv_attr_bit perm $vg/${lv1}_corig "w"
@@ -211,8 +208,9 @@ lvremove -f $vg
lvcreate --type cache-pool -L10 --chunksize 256 --cachemode writeback $vg/cpool1
check lv_field $vg/cpool1 chunksize "256.00k"
check lv_field $vg/cpool1 cachemode "writeback"
lvcreate -H -L10 -n $lv1 $vg/cpool1
lvs -a -o+cachemode,chunksize $vg
# check striping is supported when creating a cached LV
lvcreate -H -L10 -i 2 -n $lv1 $vg/cpool1
check lv_field $vg/${lv1}_corig stripes "2" -a
check lv_field $vg/$lv1 chunksize "256.00k"
check lv_field $vg/$lv1 cachemode "writeback"
@@ -264,10 +262,4 @@ grep "chunk size" out
# --poolmetadatasize
# --poolmetadataspare
lvremove -f $vg
lvcreate -n corigin -m 1 --type raid1 -l 10 $vg
lvcreate -n cpool -H $vg/corigin -l 10
check active $vg corigin_corig
dmsetup table | grep ^$PREFIX | grep corigin_corig
vgremove -ff $vg

View File

@@ -42,7 +42,7 @@ d2="$DM_DEV_DIR/$vg/$lv2"
lvcreate -l47 -n $lv1 $vg
# Fill end with pattern
dd if=64K of="$d1" bs=8192 seek=45 count=2
dd if=64K of="$d1" bs=8192 seek=45 count=2 conv=fdatasync
# Switch to read-only volume
lvchange -an $vg/$lv1
@@ -58,7 +58,7 @@ cmp -n 16384 -l 64K 16K
# Now extend and rewrite
lvextend -l+2 $vg/$lv2
dd if=64K of="$d2" bs=8192 seek=46 count=3 oflag=direct
dd if=64K of="$d2" bs=8192 seek=46 count=3 conv=fdatasync
dd if="$d2" of=24K bs=8192 skip=46 count=3 iflag=direct
cmp -n 24576 -l 64K 24K
@@ -67,7 +67,7 @@ check lv_field $vg/$lv2 data_percent "66.67"
lvreduce -f -l-24 $vg/$lv2
dd if=64K of="$d2" bs=8192 seek=24 count=1 oflag=direct
dd if=64K of="$d2" bs=8192 seek=24 count=1 conv=fdatasync
dd if="$d2" of=8K bs=8192 skip=24 count=1 iflag=direct
cmp -n 8192 -l 64K 8K
@@ -80,7 +80,7 @@ lvcreate -L256M -T $vg/pool -c 64M
lvcreate -s $vg/$lv1 --name $lv2 --thinpool $vg/pool
lvextend -l+2 $vg/$lv2
dd if=64K of="$d2" bs=8192 seek=45 count=4 oflag=direct
dd if=64K of="$d2" bs=8192 seek=45 count=4 conv=fdatasync
dd if="$d2" of=32K bs=8192 skip=45 count=4 iflag=direct
cmp -n 32768 -l 64K 32K

View File

@@ -0,0 +1,79 @@
#!/bin/sh
# Copyright (C) 2015 Red Hat, Inc. All rights reserved.
#
# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
# play with thin-pool resize in corner cases
#
export LVM_TEST_THIN_REPAIR_CMD=${LVM_TEST_THIN_REPAIR_CMD-/bin/false}
. lib/inittest
test -e LOCAL_LVMPOLLD && skip
aux have_thin 1 0 0 || skip
test -n "$LVM_TEST_THIN_RESTORE_CMD" || LVM_TEST_THIN_RESTORE_CMD=$(which thin_restore) || skip
"$LVM_TEST_THIN_RESTORE_CMD" -V || skip
#
# Temporary solution to create some occupied thin metadata
# This heavily depends on thin metadata output format to stay as is.
# Currently it expects 2MB thin metadata and 200MB data volume size
# Argument specifies how many devices should be created.
fake_metadata_() {
echo '<superblock uuid="" time="1" transaction="'$2'" data_block_size="128" nr_data_blocks="3200">'
for i in $(seq 1 $1)
do
echo ' <device dev_id="'$i'" mapped_blocks="37" transaction="0" creation_time="0" snap_time="1">'
echo ' <range_mapping origin_begin="0" data_begin="0" length="37" time="0"/>'
echo ' </device>'
done
echo "</superblock>"
}
aux have_thin 1 10 0 || skip
aux prepare_pvs 3 256
vgcreate -s 1M $vg $(cat DEVICES)
aux lvmconf 'activation/thin_pool_autoextend_percent = 30' \
'activation/thin_pool_autoextend_threshold = 70'
fake_metadata_ 400 0 >data
lvcreate -L200 -T $vg/pool
lvchange -an $vg
lvcreate -L2M -n $lv1 $vg
"$LVM_TEST_THIN_RESTORE_CMD" -i data -o "$DM_DEV_DIR/mapper/$vg-$lv1"
lvconvert -y --thinpool $vg/pool --poolmetadata $vg/$lv1
# Cannot resize if set to 0%
not lvextend --use-policies --config 'activation{thin_pool_autoextend_percent = 0}' $vg/pool 2>&1 | tee err
grep "0%" err
# Locally active LV is needed
not lvextend --use-policies $vg/pool 2>&1 | tee err
grep "locally" err
lvchange -ay $vg
# Creation of new LV is not allowed when thinpool is over threshold
not lvcreate -V10 $vg/pool
lvextend --use-policies $vg/pool "$dev2" "$dev3"
#should lvextend -l+100%FREE $vg/pool2
lvs -a $vg
vgremove -ff $vg

View File

@@ -40,7 +40,7 @@ fake_metadata_() {
echo '<superblock uuid="" time="1" transaction="'$2'" data_block_size="128" nr_data_blocks="3200">'
for i in $(seq 1 $1)
do
echo ' <device dev_id="'$i'" mapped_blocks="785" transaction="0" creation_time="0" snap_time="1">'
echo ' <device dev_id="'$i'" mapped_blocks="37" transaction="0" creation_time="0" snap_time="1">'
echo ' <range_mapping origin_begin="0" data_begin="0" length="37" time="0"/>'
echo ' </device>'
done
@@ -68,7 +68,7 @@ lvcreate -L2M -n $lv1 $vg
lvchange -an $vg/thin $vg/thin2 $vg/pool
# Prepare some fake metadata with unmatching id
# Transaction_id is lower by 1 and there are no message -> ERROR
# Transaction_id is lower by 1 and there are no messages -> ERROR
fake_metadata_ 10 0 >data
"$LVM_TEST_THIN_RESTORE_CMD" -i data -o "$DM_DEV_DIR/mapper/$vg-$lv1"
lvconvert -y --thinpool $vg/pool --poolmetadata $vg/$lv1
@@ -91,7 +91,7 @@ fake_metadata_ 400 2 >data
"$LVM_TEST_THIN_RESTORE_CMD" -i data -o "$DM_DEV_DIR/mapper/$vg-$lv1"
# Swap volume with restored fake metadata
lvconvert -y --thinpool $vg/pool --poolmetadata $vg/$lv1
lvconvert -y --chunksize 64k --thinpool $vg/pool --poolmetadata $vg/$lv1
vgchange -ay $vg

View File

@@ -21,3 +21,5 @@ aux prepare_vg 3
lvcreate -i2 -l2 -T $vg/pool2
lvextend -l+2 $vg/pool2 "$dev2" "$dev3"
should lvextend -l+100%FREE $vg/pool2
vgremove -ff $vg

View File

@@ -24,7 +24,10 @@ for deactivate in true false; do
# Extend and reduce a 2-way RAID1
lvcreate --type raid1 -m 1 -l 2 -n $lv1 $vg
test $deactivate && lvchange -an $vg/$lv1
test $deactivate && {
aux wait_for_sync $vg $lv1
lvchange -an $vg/$lv1
}
lvresize -l +2 $vg/$lv1
@@ -36,7 +39,10 @@ for deactivate in true false; do
for i in 4 5 6 ; do
lvcreate --type raid$i -i 3 -l 3 -n $lv2 $vg
test $deactivate && lvchange -an $vg/$lv2
test $deactivate && {
aux wait_for_sync $vg $lv2
lvchange -an $vg/$lv2
}
lvresize -l +3 $vg/$lv2

View File

@@ -60,7 +60,7 @@ sel() {
items_found=$(wc -l "$OUT_LOG_FILE" | cut -f 1 -d ' ')
# the number of lines on output must match
test $items_found -eq $# || {
test "$items_found" -eq $# || {
echo " >>> NUMBER OF ITEMS EXPECTED: $# ($@)"
echo " >>> NUMBER OF ITEMS FOUND: $items_found ($(< $OUT_LOG_FILE))"
return 1
@@ -143,10 +143,11 @@ if aux target_at_least dm-snapshot 1 10 0; then
# Before 1.10.0, the snap percent included metadata size.
sel lv 'snap_percent=0' snap
fi
dd if=/dev/zero of="$DM_DEV_DIR/$vg3/snap" bs=1M count=1
dd if=/dev/zero of="$DM_DEV_DIR/$vg3/snap" bs=1M count=1 conv=fdatasync
sel lv 'snap_percent<50' snap
sel lv 'snap_percent>50'
dd if=/dev/zero of="$DM_DEV_DIR/$vg3/snap" bs=1M count=4
# overflow snapshot -> invalidated, but still showing 100%
not dd if=/dev/zero of="$DM_DEV_DIR/$vg3/snap" bs=1M count=4 conv=fdatasync
sel lv 'snap_percent=100' snap
# % char is accepted as suffix for percent values
sel lv 'snap_percent=100%' snap

View File

@@ -34,7 +34,7 @@ mkdir "$mntdir"
mount "$DM_DEV_DIR/mapper/$vg-snap" "$mntdir"
cat /proc/mounts | grep "$mntdir"
not dd if=/dev/zero of="$mntdir/file$1" bs=1M count=5 oflag=direct
not dd if=/dev/zero of="$mntdir/file$1" bs=1M count=5 conv=fdatasync
# Should be nearly instant check of dmeventd for invalid snapshot.
# Wait here for umount and open_count drops to 0 as it may

View File

@@ -24,7 +24,7 @@ lvcreate -aey -L1 -n $lv1 $vg
# Snapshot should be large enough to handle any writes
lvcreate -L2 -s $vg/$lv1 -n $lv2
dd if=/dev/zero of="$DM_DEV_DIR/$vg/$lv2" bs=1M count=1 oflag=direct
dd if=/dev/zero of="$DM_DEV_DIR/$vg/$lv2" bs=1M count=1 conv=fdatasync
# Snapshot must not be 'I'nvalid here
check lv_attr_bit state $vg/$lv2 "a"

View File

@@ -11,6 +11,9 @@
. lib/inittest
# test if snapshot-merge target is available
aux target_at_least snapshot-merge 1 0 0 || skip
which mkfs.ext3 || skip
lvdev_() {
@@ -45,8 +48,6 @@ mkdir test_mnt
# test full merge of a single LV
setup_merge_ $vg $lv1
# now that snapshot LV is created: test if snapshot-merge target is available
aux target_at_least snapshot-merge 1 0 0 || skip
# make sure lvconvert --merge requires explicit LV listing
not lvconvert --merge

View File

@@ -30,24 +30,24 @@ which md5sum || skip
aux prepare_vg
# 8M file with some random data
dd if=/dev/urandom of=data bs=1M count=1
dd if=data of=data bs=1M count=7 seek=1
dd if=/dev/urandom of=data bs=1M count=1 conv=fdatasync
dd if=data of=data bs=1M count=7 seek=1 conv=fdatasync
echo "$(md5sum data | cut -d' ' -f1) $DM_DEV_DIR/$vg/s" >md5.${vg}-s
lvcreate -aey -L 8M -n o $vg
dd if=data of="$DM_DEV_DIR/$vg/o" bs=1M
dd if=data of="$DM_DEV_DIR/$vg/o" bs=1M conv=fdatasync
lvcreate -L 8M -s -n s $vg/o
check_s_
dd if=data of="$DM_DEV_DIR/$vg/o" bs=1234567 count=1 skip=1
dd if=data of="$DM_DEV_DIR/$vg/o" bs=1234567 count=1 skip=1 conv=fdatasync
check_s_
lvchange -an $vg
lvchange -ay $vg
check_s_
dd if=data of="$DM_DEV_DIR/$vg/o" bs=1234567 count=2 skip=1
dd if=data of="$DM_DEV_DIR/$vg/o" bs=1234567 count=2 skip=1 conv=fdatasync
check_s_
lvchange -an $vg

File diff suppressed because it is too large Load Diff

View File

@@ -2348,7 +2348,7 @@ static int _lvconvert_pool_repair(struct cmd_context *cmd,
pmslv = pool_lv->vg->pool_metadata_spare_lv;
/* Check we have pool metadata spare LV */
if (!handle_pool_metadata_spare(pool_lv->vg, 0, NULL, 1))
if (!handle_pool_metadata_spare(pool_lv->vg, 0, lp->pvh, 1))
return_0;
if (pmslv != pool_lv->vg->pool_metadata_spare_lv) {
@@ -2473,7 +2473,7 @@ deactivate_pmslv:
}
/* Try to allocate new pool metadata spare LV */
if (!handle_pool_metadata_spare(pool_lv->vg, 0, NULL, 1))
if (!handle_pool_metadata_spare(pool_lv->vg, 0, lp->pvh, 1))
stack;
if (dm_snprintf(meta_path, sizeof(meta_path), "%s_meta%%d", pool_lv->name) < 0) {
@@ -2489,14 +2489,14 @@ deactivate_pmslv:
if (!detach_pool_metadata_lv(first_seg(pool_lv), &mlv))
return_0;
/* Swap _pmspare and _tmeta name */
if (!swap_lv_identifiers(cmd, mlv, pmslv))
return_0;
/* Used _pmspare will become _tmeta */
if (!attach_pool_metadata_lv(first_seg(pool_lv), pmslv))
return_0;
/* Used _tmeta will become visible _meta%d */
/* Used _tmeta (now _pmspare) becomes _meta%d */
if (!lv_rename_update(cmd, mlv, pms_path, 0))
return_0;
@@ -3191,6 +3191,8 @@ static int _lvconvert_cache(struct cmd_context *cmd,
if (!cache_set_policy(first_seg(cache_lv), lp->policy_name, lp->policy_settings))
return_0;
cache_check_for_warns(first_seg(cache_lv));
if (!lv_update_and_reload(cache_lv))
return_0;

View File

@@ -44,15 +44,20 @@ int swap_lv_identifiers(struct cmd_context *cmd,
struct logical_volume *a, struct logical_volume *b)
{
union lvid lvid;
const char *name;
const char *aname = a->name, *bname = b->name;
lvid = a->lvid;
a->lvid = b->lvid;
b->lvid = lvid;
name = a->name;
a->name = b->name;
if (!lv_rename_update(cmd, b, name, 0))
/* rename temporarily to 'unused' name */
if (!lv_rename_update(cmd, a, "pmove_tmeta", 0))
return_0;
/* name rename 'b' to unused name of 'a' */
if (!lv_rename_update(cmd, b, aname, 0))
return_0;
/* finish name swapping */
if (!lv_rename_update(cmd, a, bname, 0))
return_0;
return 1;

View File

@@ -700,6 +700,7 @@ static int _lvcreate_params(struct cmd_context *cmd,
contiguous_ARG,\
ignoreactivationskip_ARG,\
ignoremonitoring_ARG,\
monitor_ARG,\
mirrors_ARG,\
name_ARG,\
noudevsync_ARG,\
@@ -769,7 +770,8 @@ static int _lvcreate_params(struct cmd_context *cmd,
CACHE_POOL_ARGS,
LVCREATE_ARGS,
POOL_ARGS,
SIZE_ARGS,
extents_ARG,
size_ARG,
cache_ARG,
chunksize_ARG,
-1))
@@ -1095,6 +1097,8 @@ static int _determine_cache_argument(struct volume_group *vg,
}
/* FIXME How to handle skip flag? */
if (arg_from_list_is_set(cmd, "is unsupported with cache conversion",
stripes_ARG,
stripesize_ARG,
setactivationskip_ARG,
ignoreactivationskip_ARG,
-1))

View File

@@ -1478,6 +1478,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
char *arg_new, *arg;
int i;
int skip_hyphens;
int refresh_done = 0;
init_error_message_produced(0);
@@ -1554,6 +1555,7 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
log_error("Updated config file invalid. Aborting.");
return ECMD_FAILED;
}
refresh_done = 1;
}
if (!_prepare_profiles(cmd))
@@ -1562,7 +1564,11 @@ int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
if (!cmd->initialized.connections && !_cmd_no_meta_proc(cmd) && !init_connections(cmd))
return_ECMD_FAILED;
if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) && !init_filters(cmd, 1))
/* Note: Load persistent cache only if we haven't refreshed toolcontext!
* If toolcontext has been refreshed, it means config has changed
* and we can't rely on persistent cache anymore.
*/
if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) && !init_filters(cmd, !refresh_done))
return_ECMD_FAILED;
if (arg_count(cmd, readonly_ARG))

View File

@@ -574,8 +574,10 @@ static int _vgchange_locktype(struct cmd_context *cmd,
}
if (is_lockd_type(vg->lock_type) && is_lockd_type(lock_type)) {
log_error("First change from lock type %s to none, then to lock type %s",
log_error("Cannot change lock type directly from \"%s\" to \"%s\".",
vg->lock_type, lock_type);
log_error("First change lock type to \"none\", then to \"%s\".",
lock_type);
return 0;
}
@@ -876,7 +878,7 @@ static int _vgchange_lock_start(struct cmd_context *cmd, struct volume_group *vg
}
do_start:
return lockd_start_vg(cmd, vg);
return lockd_start_vg(cmd, vg, 0);
}
static int _vgchange_lock_stop(struct cmd_context *cmd, struct volume_group *vg)
@@ -1042,6 +1044,9 @@ static int _lockd_vgchange(struct cmd_context *cmd, int argc, char **argv)
cmd->lockd_vg_enforce_sh = 1;
}
if (arg_is_set(cmd, lockstop_ARG))
cmd->lockd_vg_default_sh = 1;
/* Starting a vg lockspace means there are no locks available yet. */
if (arg_is_set(cmd, lockstart_ARG))

View File

@@ -157,7 +157,7 @@ int vgcreate(struct cmd_context *cmd, int argc, char **argv)
if (is_lockd_type(vg->lock_type)) {
const char *start_opt = arg_str_value(cmd, lockopt_ARG, NULL);
if (!lockd_start_vg(cmd, vg)) {
if (!lockd_start_vg(cmd, vg, 1)) {
log_error("Failed to start locking");
goto out;
}

View File

@@ -149,8 +149,10 @@ static int vg_rename_path(struct cmd_context *cmd, const char *old_vg_path,
if (!drop_cached_metadata(vg))
stack;
if (!lockd_rename_vg_before(cmd, vg))
return_0;
if (!lockd_rename_vg_before(cmd, vg)) {
stack;
goto error;
}
/* Change the volume group name */
vg_rename(cmd, vg, vg_name_new);