1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-08-17 09:49:28 +03:00

Compare commits

...

2402 Commits

Author SHA1 Message Date
cf06d942b8 test: api subdirectory is needed in PATH by pytest 2015-11-02 14:16:46 +01:00
83d3cc76f3 test: Run pytest with installed libs 2015-11-02 12:52:30 +01:00
89574055f7 spec: Add python bindings 2015-11-02 12:42:32 +01:00
7831a65091 post-release 2015-10-31 01:35:47 +00:00
15a97cc610 pre-release 2015-10-30 15:34:00 +00:00
3f1c63c812 WHATS_NEW: reporting commands and -o-/-o+ extension 2015-10-30 15:50:35 +01:00
dd52721b68 commands: update command help for -o|--options for reporting commands 2015-10-30 15:47:56 +01:00
7f125c1116 man: pvs/vgs/lvs and -o+, -o-, -o# 2015-10-30 15:47:56 +01:00
5b04eda93f tests: add report-fields.sh test 2015-10-30 15:47:56 +01:00
77c31d0c39 report: support "-o #field_name1,field_name2,..." 2015-10-30 15:47:56 +01:00
baf320455b report: recognize known prefix when processing "-o -field_name1,field_name2,..." 2015-10-30 15:47:56 +01:00
bb4d3fa7a7 report: add report_get_field_prefix function 2015-10-30 15:47:56 +01:00
3e18b101a0 report: support "-o -field_name1,field_name2,...." 2015-10-30 15:47:56 +01:00
df190dcfa5 report: make report options defined by "-o" groupable
Also, besides making "-o" groupable, use string lists to store
lists of options temporarily while processing all instances of
the "-o" group.
2015-10-30 15:47:56 +01:00
e149fe7fdf refactor: move code detecting report options to a separate function 2015-10-30 15:47:56 +01:00
77605457e7 str_list: add str_list_destroy function
The str_list_destroy function may be called to cleanup memory when
the list is not used anymore and the list itself was not allocated
from the memory pool.
2015-10-30 15:47:56 +01:00
0d5b1294f0 str_list: add str_list_to_str and str_to_str_list functions
The str_list_to_str and str_to_str_list are helper functions to
convert string list to a single string and vice versa.
2015-10-30 15:47:56 +01:00
097d14e64e str_list: also allow memory allocation without memory pool 2015-10-30 15:47:55 +01:00
17196103e0 New entries for pvs related fixes. 2015-10-30 09:05:21 -05:00
ccfc09f79b metadata: format_text: also count with calculated mda size of 0
When checking minimum mda size, make sure the mda_size after alignment
and calculation is more than 0 - if there's no place for an MDA at the
end of the disk, the _text_pv_add_metadata_area does not try to add it
there and it returns (because we already have the MDA at the start of
the disk at least).
2015-10-30 12:02:34 +01:00
9a3b64e81a tests: add test for minimum mda size 2015-10-30 10:02:00 +01:00
c2e88d1107 metadata: format_text: better check for metadata overlap
Actually, we don't need extra condition as introduced in commit
00348c0a63. We should fix the last
condition:

  (mdac->rlocn.size >= mdah->size)

...which should be:

  (MDA_HEADER_SIZE + (rlocn ? rlocn->size : 0) + mdac->rlocn.size >= mdah->size))

Where the "mdac" is new metadata, the "rlocn" is old metadata.

So the main problem with the previous condition was that it
didn't count in MDA_HEADER_SIZE properly (and possible existing
metadata - the "rlocn"). This could have caused the error state
where metadata in ring buffer overlap to not be hit.

Replace the new condition introduced in 00348c0a63
with the improved one for the condition that existed there
already but it was just incomplete.
2015-10-30 08:57:34 +01:00
406d8ff332 WHATS_NEW: recent commits 2015-10-29 16:50:09 +01:00
00348c0a63 metadata: format_text: check VG metadata do not overlap themselves
We're already checking whether old and new meta do not overlap in
ring buffer (as we need to keep both old and new meta during vg_write
up until vg_commit).

We also need to check whether the new metadata do not overlap
themselves in case we don't have old metadata yet (...because
we're in vgcreate). This could happen if we're creating a VG so
that the very first metadata written are long enough that it wraps
themselves in metadata ring buffer.

Although we limited the minimum metadata area size better with the
previous commit ccb8da404d which
makes the initial VG metadata overlap in ring buffer to be less
probable, the risk of hitting this overlap condition is still there
if we still manage to generate big enough metadata somehow.

For example, users can provide many and/or long VG tags during vgcreate
so that the VG metadata is long enough to start to wrap in the ring
buffer again...
2015-10-29 16:46:41 +01:00
ccb8da404d metadata: format_text: check metadata area size is at least MDA_SIZE_MIN 2015-10-29 16:00:32 +01:00
28e54032c0 tests: update test for resize
Drop already tested 'threshold & create' which is in
lvextend-thin-full.sh

Count with now match faster 'dmeventd' wakeup on watermark
as it's now nearly instant after crossing threshold value.
2015-10-29 15:11:16 +01:00
bca55c9b20 tests: replace invalid use of 'fail' with 'die' 2015-10-29 13:30:29 +01:00
f104a81932 tests: let pass bigger readahead
If the underlaying device has actually bigger read-ahead settings,
let it pass.
But anyway switch to 512 strip-size to get really high R-A sector count.
2015-10-29 12:39:07 +01:00
3720eb63be tests: fix wrong line has been commented 2015-10-29 12:39:07 +01:00
8b5525383f tests: no point in using should
lvmetad does not support lvm1 - so expect failure.
2015-10-29 12:39:07 +01:00
f58c634103 cleanup: error is not a WARNING
Drop 'WARNING' from error message.
It's plain error message leading to command failure.
2015-10-29 12:38:59 +01:00
175119fdcd cleanup: remove thin low_water_mark from metadata
This option could never have been printed in lvm2 metadata, so it could
be safely removed as it could have been set only as 0.

These configurable setting is supported via metadata profile.
2015-10-29 12:14:20 +01:00
33a8a2febf cleanup: use same type 2015-10-29 12:14:20 +01:00
f32f0bd2a7 cleanup: easier error messages 2015-10-29 12:14:20 +01:00
99237f0908 thin: enable usage of kernel low_water_mark
Now with correctly functioning dmeventd enable usage of
low_water_mark for faster reaction on pool's threshold.

When user select e.g. 80% as a threshold value,
dmeventd doesn't need to wait 10 seconds till monitoring
timer expires, but nearly instantly resizes thin-pool
to fit bellow threshold.
2015-10-29 12:14:20 +01:00
099466939e thin: dmeventd plugin check number of failures
If plugin's lvm command execution fails too often (>10 times),
there is no point to torture system more then necessary, just log
and drop monitoring in this case.
2015-10-29 12:14:20 +01:00
b3c81d02c9 revert: 3d03e504cd: message about VG metadata size vs. PV mda size
The message needs refinement - it's not correct in all situations.
2015-10-29 11:10:48 +01:00
5886ff64eb pvs: don't treat duplicate PVs as missed
The recent addition to check for PVs that were
missed during the first iteration of processing
was unintentionally catching duplicate PVs because
duplicates were not removed from the all_devices
list when the primary dev was processed.

Also change a message from warn back to verbose.
2015-10-27 12:03:57 -05:00
a4418b34c1 vgs, lvs: ignore error if VG is removed
If a VG is removed between the time that 'vgs'
or 'lvs' (with no args) creates the list of VGs
and the time that it reads the VG to process it,
then ignore the removed VG; don't report an error
that it could not be found, since it wasn't named
by the command.
2015-10-27 10:52:01 -05:00
65ec00ce20 device: Tidy DASD CDL format detection code. 2015-10-27 15:27:52 +00:00
6e1e0e8813 tests: using matching type
Compare time_t.
2015-10-27 16:00:10 +01:00
4159680a0e tests: use more SKIP
Speed-up check_lvmpolld.
2015-10-27 16:00:09 +01:00
76cff10a73 tests: avoid reading utils when skipping
Save even more CPU/time and avoid reading utils, when skipping test.
2015-10-27 16:00:09 +01:00
1af2ab10d0 cleanup: snapshots of snapshots message
No plans to support thick snapshost of snapshots.
2015-10-27 11:42:48 +01:00
729f489009 pvcreate: don't support unpartitioned DASD devices with CDL formatted
The former patch(dab3ebce4c) is a little bit strict. For example, it is
OK to create PV on unpartitioned DASD devices with LDL formatted. So
after lvm version containing the patch, LVs created on those devices
could not be found.

Signed-off-by: Lidong Zhong <lzhong@suse.com>
2015-10-27 11:42:47 +01:00
5d76bdcdbd dmeventd: event string parser handles empty field
Improve event string parser to avoid unneeded alloc+free.

Daemon talk function uses '-' to mark NULL/missing field.
So restore the NULL pointer back on parser.

This should have made old tools like 'dmevent_tool' work again.
As now 'uuid' or 'dso' could become NULL and then be
properly used in _want_registered_device() function.

Since lvm2 always fill these parameters, this change should
have no effect on lvm2.
2015-10-27 11:42:40 +01:00
3b5939bbbb tests: use skip flags
corrected usage of skip flags.
2015-10-27 00:45:37 +01:00
a2dd1f6e19 tests: support skip flags 2015-10-26 23:57:47 +01:00
c301cc5d38 tests: extend timer for 4 hours
Extend max time for test suite to 4 hours.
Also replace some 'non-ascii' chars from source files
and keep them plain ascii.
2015-10-26 23:57:47 +01:00
ba41ee1dc9 thin: limit no-flush using only for thin-pool
For this release keep usage of 'noflush' only for thin-volume/pool.

For rest of keep - keep usage of 'noflush' flag purely for
non-resized mirrors.
2015-10-26 23:57:31 +01:00
b702d67747 dmevent: fix referencing
Plugin increments DSO refcounter in _alloc_thread_status().
2015-10-26 23:31:23 +01:00
44ba862674 toollib: fix wrong paren placement 2015-10-26 16:27:26 -05:00
6624833839 pvs: fix missing PVs when VG is removed
PVs could be missing from the 'pvs' output if
their VG was removed at the same time that the
'pvs' command was run.  To fix this:

1. If a VG is not found when processed, don't
silently skip the PVs in it, as is done when
the "skip" variable is set.

2. Repeat the VG search if some PVs are not
found on the first search through all VGs.
The second search uses a specific list of
PVs that were missed the first time.

testing:
/dev/sdb is a PV
/dev/sdd is a PV
/dev/sdg is not a PV

each test begins with:
vgcreate test /dev/sdb /dev/sdd

variations to test:
vgremove -f test & pvs
vgremove -f test & pvs -a
vgremove -f test & pvs /dev/sdb /dev/sdd
vgremove -f test & pvs /dev/sdg
vgremove -f test & pvs /dev/sdb /dev/sdg

The pvs command should always display /dev/sdb
and /dev/sdd, either as a part of VG test or not.

The pvs command should always print an error
indicating that /dev/sdg could not be found.
2015-10-26 16:07:12 -05:00
b29593378f tests: snapshot now respects threshold 2015-10-26 07:38:23 +01:00
428ca9b120 libdm: enable no_flush for driver version > 11
It appears the driver version 11 has troubles with usage of no_flush
So require at least version 12.
2015-10-26 07:37:59 +01:00
f898cf7539 dev_manager: no flush for extension
Recognize the target only 'extends' and do not enforce
'flush' in this case.  Only the size reduction
still requires flush (so disables usage of no_flush flag).

If some other targets do require flush before suspend,
they have to explicitly ask for it.
2015-10-25 21:09:31 +01:00
844b009584 dev_manager: enabled no_flush for suspend
While the activation code tries to evaluate which target
really needs flush with suspend and which may go without flush,
it has stayed effectively disabled by original commit:
33f732c5e9 since here
it only allows to pass non-pvmoving  'mirrors'.

So remove check for mirror LV type and only disable
no_flush for 'pvmove'..

TODO: Looking into history - it also seemed like raid target
would have always required flushing but it's been later
removed without clean explanation.

If some more targets really do need 'no_flush' it should
been handle at their 'level' - since we now stack multiple
targets over itself.
2015-10-25 21:07:37 +01:00
9ef820a2a5 libdm: dm_tree_node_size_changed recognizes reduction
Add more functionality to size_changed function.
While 'existing' API only detected  0 for
unchanged,  and !0 for changed,
new improved API will also detected if the
size has only went bigger - or there was
size reduction.

Function work for the whole dm-tree - so
no change is size is always 0.
only size extension  1.
and if some size reduction is there - returns -1.

This result can be used for better evaluation
whether we need to flush before suspend.
2015-10-25 21:05:15 +01:00
40eea582ae lv_manip: ensure it will fit bellow threshold
Use single code to evaluate if the percentage value has
crossed threshold.

Recalculate amount value to always fit bellow
threshold so there are not need any extra reiterations
to reach this state in case policy amount is too small.
2015-10-25 21:03:11 +01:00
b780d329aa thin: fix percentage compare
Since plugin's percentage compare has been fixed,
it's now revealed wrong compare here.

The logic for threshold is - to allow to go as high
as given value e.g. 80% - so if pool is exactlu 80%
full it's still allowed to use it (dmeventd will not
resize it).
2015-10-25 21:01:54 +01:00
8f269697d2 vg_read: remove unused inconsistent check
Commit 1a74171ca5 added
a check to ignore a VG that was FAILED_INCONSISTENT
if the command doesn't care if the VG is not found.
Remove that check because that case is never reached
by the current code.
2015-10-23 12:19:11 -05:00
98d81a43ea vgextend: fix use of the wrong flag
The ONE_VGNAME_ARG was being passed and tested as
vg_read() flag but it's a cmd struct flag.

(It affects command arg processing in toollib,
not vg_read behavior.  Flags related to command
processing are generally cmd struct flags, while
vg_read arg flags are generally related to vg_read
behavior.)
2015-10-23 10:21:06 -05:00
1a74171ca5 vg_read: sometimes ignore read errors
Running "vgremove -f VG & pvs" results in the pvs
command reporting that the VG is not found or is
inconsistent.  If the VG is gone or being removed,
the pvs command should just skip it and not print
errors about it.

"Not found" is because the pvs command created the
list of VGs to process, including VG, then vgremove
removed the VG, then the pvs command came to to read
the VG to process it and did not find it.

An "inconsistent" error could be reported if vgremove
had only partially completed removing VG when pvs did
vg_read on the VG to process it, causing pvs to find
the VG in a partially-removed state.

This fix adds a flag that pvs uses to ignore a VG
that can't be read or is inconsistent.
2015-10-23 10:12:34 -05:00
51735f09f7 thin: Fix typo in policy threshold message. 2015-10-23 15:38:31 +01:00
3a42c13ccf lvmcache: update cached info properly when moving from VG to orphan while lvmetad is used
When lvmetad is used and lvmcache update function (lvmcache_update_vgname_and_id)
was called to update existing lvmcache records, a condition was met
which made to retun from the update function immediately, effectively
making it NOOP.

It seems there's no reason for such condition and lvmcache should be
update appropriately even when lvmetad used as lvmcache may be reused,
most notably in lvm shell.

It's possible this is a remnant of the lvmetad development code which
didn't get removed for some reason and the bug didn't get spotted
because lvm shell is not used often (the condition dates back to 2012
or so).

Example, lvmetad and lvm shell used:

lvm> pvs
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sda   vg   lvm2 a--  124.00m 124.00m

Before this patch:
==================
lvm> vgremove vg
  Volume group "vg" successfully removed

lvm> pvs

With this patch applied:
========================

lvm> vgremove vg
  Volume group "vg" successfully removed

lvm> pvs
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sda        lvm2 ---  128.00m 128.00m
2015-10-23 15:58:31 +02:00
8b965bd3d5 pvremove: make sure even invalid info is removed from lvmcache on pvremove
The lvmcache info might be resued, most notably in lvm shell.
We need to be sure that even lvmcache_info marked as invalid
is removed from the lvmcache so it does not confuse any subsequent
code/commands executed later on.

Problematic example with the lvm shell:

lvm> pvs
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sda        lvm2 ---  128.00m 128.00m

Before this patch (/dev/sda still displayed in a way):
======================================================

lvm> pvremove /dev/sda
  Labels on physical volume "/dev/sda" successfully wiped

(without lvmetad)
lvm> pvs
  No physical volume label read from /dev/sda

(with lvmetad)
lvm> pvs
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sda        lvm2 ---  128.00m 128.00m

With this patch applied:
========================

lvm> pvremove /dev/sda
  Labels on physical volume "/dev/sda" successfully wiped

(without lvmetad)
lvm> pvs

(with lvmetad)
lvm> pvs
2015-10-23 15:48:06 +02:00
1a7bea0f0f cleanup: drop debug 2015-10-23 10:54:13 +02:00
b5b2a54834 cleanup: fix gcc compile with older pthread
Older pthread library was missing 'trick'
in pthread_cleanup_pop() which lead to
compilation error:

error: label at end of compound statement

Use explicit ';' to fix it.
2015-10-23 10:54:13 +02:00
21748a8630 cleanup: gcc warning for old-style 2015-10-23 10:54:13 +02:00
e5b686d693 tools: update for lvm2_disable_dmeventd_monitoring
Make lvm2_disable_dmeventd_monitoring() more explicit.

As memlock_inc_daemon() is also used by clvmd, which
does changes dmeventd and suspend ignore state at
some stages - make updates of these 2 variable
tied to the call of  lvm2_disable_dmeventd_monitoring().

Once this call is made dmeventd monitoring
and suspended devices are ignored.

TODO: all lvm-global settings should really be moved
to command context.
2015-10-23 10:54:13 +02:00
87a39d8bac dmeventd: ensure filter is empty
On some error path we could have left filter set to some value.
Not a big issue - but lets make reporting correct as soon
as we can.
2015-10-23 10:54:13 +02:00
cff1c728d8 dmeventd: debug error paths 2015-10-23 10:54:13 +02:00
2786cd27da tests: enable raid test on 4.3
With kernel -rc6 it's passing our raid tests again - so enable
it in tests.

Note: related only to Fedora rawhide kernels...
2015-10-22 22:46:10 +02:00
1a2d0a0c72 cleanup: indents 2015-10-22 22:46:10 +02:00
b1319e0402 cleanup: drop uneeded header file 2015-10-22 22:46:10 +02:00
8be60e6a65 cleanup: easier to read code
Avoid using #ifdef code and use 'cmd' instead of 'die'.
2015-10-22 22:46:10 +02:00
39cffa4e9b cleanup: declare vars before code 2015-10-22 22:46:10 +02:00
2af696c32f dmeventd: exit on idle
Implementing exit when 'dmeventd' is idle.
Default idle timeout set to 1 hour - after this time period
dmeventd will cleanly exit.

On systems with 'systemd' - service is automatically started with
next contact on dmeventd communication socket/fifo.

On other systems - new dmeventd starts again when lvm2 command detects
its missing and monitoring is needed.
2015-10-22 22:43:03 +02:00
4284ba65eb dmeventd: debug signals 2015-10-22 22:41:12 +02:00
aeec62ad19 dmeventd: snapshot plugin unmonitor
Send signal to itself to mark plugin as 'finished' as
the watching rule is no longer usable.
2015-10-22 22:41:12 +02:00
12aa56d298 dmeventd: handle signal from plugin
Add support to unmonitor device when monitor recognizes there is
nothing to monitor anymore.

TODO: possibly API change with return value could be also used.
2015-10-22 22:40:07 +02:00
9156c5d088 dmeventd: rework locking code
Redesign threading code:

- plugin registration runs within its new created thread for
  improved parallel usage.

- wait task is created just once and used during whole plugin lifetime.

- event thread is based over  'events' filter being set - when
  filter is 0, such thread is 'unused'.

- event loop is  simplified.

- timeout thread is never signaling 'processing' thread.

- pending of events filter cnange is properly reported and
  running event thread is signalled when possible.

- helgrind is not reporting problems.
2015-10-22 22:39:24 +02:00
466a1c72b7 cleanup: use enums 2015-10-22 22:36:00 +02:00
81e9ab3156 dmeventd: code mode _get_device_status
Move _get_device_status() in code.
Use dm_task_no_flush() function when reading status.
(e.g. none blocking for thins pool)
2015-10-22 22:35:25 +02:00
15dbd4b56a dmeventd: minimize locking time for get_imeout
Don't hold lock when creating message (allocating memory).
Thread cannot dissapear as it's only the same thread which
may clean it.
2015-10-22 22:34:30 +02:00
e2ea2a8147 dmeventd: drop unneded test
Function is never called without device.uuid.
2015-10-22 22:34:29 +02:00
941c6354db dmeventd: wake up timer when setting new timeout 2015-10-22 22:34:29 +02:00
02eb000f51 dmeventd: use dm_hold_control_dev
Need here to keep  control device opened while there is 'any' dso
plugin loaded - otherwise there would a race closing controlfd
inside lvm2 plugin while some other monitoring thread would
tried to execute another WAITEVENT task.
2015-10-22 22:34:27 +02:00
efc76ca33d dmeventd: move dso handling into single code section
Move all DSO related function in front, so they could be easily
referenced from rest of code.

Add proper error paths with logging and error reporting.

Drop mutex locking when releasing DSO - since DSO is always
allocated and released in main 'event' processing thread.
2015-10-22 22:33:19 +02:00
590091a4fa dmeventd: using warning level
When dmevend notices problems, but continues to operate normally
change log level to warning.
2015-10-22 22:33:19 +02:00
9488cbdd0b dmeventd: no registering of 0 event mask
Whenever user tries to register 0 mask report this as EINVAL.
2015-10-22 22:33:19 +02:00
fa9e41d2e3 dmeventd: thin plugin update
Use  dm_make_percent for percentage calculation like lvm2 command.

Use a single call for resize.
2015-10-22 22:33:07 +02:00
6b0bc5b2d9 dmeventd: snapshot plugin device removal
Add #ifdef-ed code to have ability to even remove unusable device.
For now purely experimental.
2015-10-22 22:29:53 +02:00
7ff5b03e5e dmeventd: snapshot plugin updates
Improve test for invalid snapshot.

Use dm_make_percent() to manipulate with exactly same percentage
as lvm2 command is using.
2015-10-22 22:29:50 +02:00
91350f5c6a dmeventd: mirror plugin update
Don't use  --config  - this requires reload of lvm.conf
2015-10-22 22:28:37 +02:00
9c5c9e2355 dmeventd: raid plugin reporting
Fix raid logging introduced with last updating commit.
2015-10-22 22:28:37 +02:00
cde12cbe9e dmeventd: lvm2 plugin correctly debug
Fix debug message and report exit when really doing it.
Also add missing '_' to static function.
2015-10-22 22:28:37 +02:00
ab6d16a8a5 dmeventd: check for malloc return 2015-10-22 22:28:37 +02:00
09a62cca0c libdm: add dm_hold_control_dev
Support hold of control device open.
Useful for daemons so the control device is not frequently reopenned.
2015-10-22 22:27:31 +02:00
075f85dcb5 tools: do not change signals for memlocked daemons 2015-10-22 22:26:30 +02:00
d2c4ce254b tools: preselect some setting for memlocked daemons
When our daemon is locked into memory - avoid
communication with dmeventd and also skip
suspended devices.
2015-10-22 22:26:30 +02:00
7b78d496bf memlock: report memlock daemon counter
Add internal memlock_count_daemon().

Function can be used to recognize it's being executed
from daemon restricted execution inside /lib code.
2015-10-22 22:26:27 +02:00
19e272ba53 lib: better reporting of threshold
Simplify code reporting warning about incorrect thresholds.
2015-10-22 22:06:14 +02:00
73e679f33f man: document possible lvmetad -l values
In the man page and the lvmetad help output.
2015-10-21 13:36:57 -05:00
a0d819172f libdaemon: fix typo in last log enable commit 2015-10-21 11:22:22 -05:00
0aee04288e libdaemon: allow all debug levels for stderr
The parsing code for log levels was missing
some levels.  Also ignore an unrecognized
level name rather than failing.
2015-10-21 11:19:18 -05:00
ef4d69f456 tests: add lvmetad shutdown on idle test 2015-10-20 15:45:28 +02:00
c15649b3af lvmetad.8.in: update man page with timeout info 2015-10-20 15:45:21 +02:00
f67a52677b lvmetad: add optional timeout option 2015-10-20 15:45:14 +02:00
392248186e tests: add test for missing mirror in-sync info 2015-10-20 12:19:02 +02:00
33465066c5 polldaemon: fix missing mirror in-sync info with lvmpolld
CONVERTING status flag is a tricky one. It's not set when converting
a non-mirror LV type to the mirror type, i.e.: linear -> two leg mirror.
Also the conversion itself is instant and doesn't require to be polled.
When mirror reaches sync state there's no final update on VG metadata
for lvmpolld to be made thereby report_progress in fact doesn't report
percentage of mirror being converted but percentage of mirror
being in sync. Perhaps we should reword the lvconvert output here.

On the other hand CONVERTING is set while we upconvert the mirror
from i.e. two leg mirror to four leg mirror. In such case the operation
is required to be polled so that lvmpolld can cleanup temporary
conversion log when the conversion is over.

Ignore CONVERTING lv_type for the moment and match LVs only by uuids
during 'mirror conversion'/'waiting for a sync to finish'.
2015-10-20 12:18:55 +02:00
a5c4c4efbd conf: clarify compact output settings 2015-10-20 11:01:09 +02:00
83d475626a pvscan: use process_each_pv
The old code made two loops through the PVs: in the first
loop it found the max PV and VG name lengths, and in the
second loop it printed each PV using the name lengths as
field widths for aligning columns.

The new code uses process_each_pv() which makes one loop
through the PVs.  In the *first* call to pvscan_single(),
the max name lengths are found by looping through the
lvmcache entries which have been populated by the generic
process_each code prior to calling any _single functions.
Subsequent calls to pvscan_single() reuse the max lengths
that were found by the first call.
2015-10-19 16:15:51 -05:00
1ea7e2634d conf: regenerate 2015-10-19 10:01:14 +02:00
23d9b17a7b cleanup: typo in comment: compact_output_fields should be compact-output_cols 2015-10-19 09:59:05 +02:00
c3bfe07f2a config: add report/compact_output_cols to control which columns to compact in report output
The new report/compact_output_cols setting has exactly the same effect
as report/compact_output setting. The difference is that with the new
setting it's possible to define which cols should be compacted exactly
in contrast to all cols in case of report/compact_output.

In case both compact_output and compact_output_cols is enabled/set,
the compact_output prevails.

For example:

$ lvmconfig --type full report/compact_output report/compact_output_cols
compact_output=0
compact_output_cols=""

$ lvs vg
  LV    VG   Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lvol0 vg   -wi-a----- 4.00m

---

$ lvmconfig --type full report/compact_output report/compact_output_cols
compact_output=0
compact_output_cols="data_percent,metadata_percent,pool_lv,move_pv,origin"

$ lvs vg
  LV    VG   Attr       LSize Log Cpy%Sync Convert
  lvol0 vg   -wi-a----- 4.00m

---

$ lvmconfig --type full report/compact_output report/compact_output_cols
compact_output=1
compact_output_cols="data_percent,metadata_percent,pool_lv,move_pv,origin"

$ lvs vg
  LV    VG   Attr       LSize
  lvol0 vg   -wi-a----- 4.00m
2015-10-16 17:05:54 +02:00
508f0f5a21 libdm: add dm_report_compact_given_fields
dm_report_compact_given_fields is the same as dm_report_compact_fields,
but it processes only given fields, not all the fields in the report
like dm_report_compact_field does.
2015-10-16 17:05:54 +02:00
df34fcdafd lvmlockd: use flag to avoid blocking in sanlock_acquire
If a host failed while holding a sanlock lease,
sanlock_acquire will by default block and wait
for the lease to expire before returning.  We
want it to return with an error so we can retry
instead of blocking, which allows us to process
other lock operations.

(Enclose this in an ifdef until the new flag
appears in a sanlock release.)
2015-10-14 14:39:29 -05:00
a6d1c8ac65 dmeventd: use matching function
Respect lvm2_log_fn prototype. The idea of 'reusing' print_log with
plain cast is causing very strange crashes with some older 'gcc'  compilers.
So just do it cleanly...
2015-10-14 14:25:27 +02:00
7c36d7c90c thin: enforce local activation when creation new thin
As we need to check how full thin-pool is - require thin-pool is
locally active.
2015-10-14 01:00:35 +02:00
bbef4edd06 makefiles: switch to rpath-link
Plain rpath is to invasive and gets into binary.
We only want to provide hint for linker.
2015-10-14 00:51:55 +02:00
3f1a3b7090 dmeventd: fix missing '!'
During recent code changes '!' was badly converted.
2015-10-13 22:10:47 +02:00
a91fbe9d27 makefiles: older gcc needs hint with rpath
gcc 4.3 seems not to be able to find linked library without
specifying -rpath to linker  (plain -L) is not enough.
2015-10-13 22:02:17 +02:00
ccc39be053 dmeventd: compilable without DEBUG CFLAG
Missed compilability without DEBUG.
2015-10-13 20:59:35 +02:00
0cf787a377 Revert "log: no file for external logging"
This reverts commit 1b1c01a27b.

This caused messages to get dropped instead of logged into the log file.

(The log file and log function are independent at the moment.)
2015-10-13 15:31:57 +01:00
acc70de439 tests: more extend testing 2015-10-13 16:02:21 +02:00
cf1c2da836 tests: wait for initial sync
Raid should be in-sync ATM for any gaming.
2015-10-13 16:02:21 +02:00
c4cc5eabfe tests: start logging dmeventd output
Log dmeventd output from test - keep output logging in test
and avoid sending messages to syslog.
2015-10-13 16:02:21 +02:00
8cc21354c2 tests: better regex check
Enhance check for matching prefix.
2015-10-13 16:02:20 +02:00
2cb1f6eafe tests: show status in in_sync
Make visible actual status line when returing 'raid' is in sync.
Useful to prove when kernel is wrong.
2015-10-13 16:02:20 +02:00
9322918406 makefiles: src dirs have depth 5
For tags generation scan depth 5.
2015-10-13 16:02:20 +02:00
83f00e9156 makefiles: drop explicit linking
Nothing in /sscripts needs devmapper-event library so drop its linking.
2015-10-13 16:02:20 +02:00
4f9e7f692e makefiles: generate Local
Use same  exported symbols list for other generated symfile
as it appeared to be the right way for libdm.

Local {
	local:
		*;
};
2015-10-13 16:02:20 +02:00
4b586ad3c2 dmeventd: rework raid plugin
Switch to per-thread mem-pool and lock only for lvm2 calls.
Use libdm parser for raid status line.
2015-10-13 16:02:19 +02:00
256e432e78 dmeventd: less locking mirror
Rework mirror plugin to use per-thread mem-pool.
This allows to use locking only for lvm2 library calls.
2015-10-13 16:02:18 +02:00
51ff7d5ed8 dmeventd: less locking for snapshot and thin
Use lvm lock for lvm library calls.

dm functions in-use are 'thread-safe' since we use
local per-thread mem pool.
2015-10-13 16:01:41 +02:00
49e11102c7 dmeventd: add local mempool for raid and mirror
Using local mempools allows to drop locks when such memory is needed.
2015-10-13 15:56:23 +02:00
a11cd2ca2d dmeventd: use new macros to init mempool
For thin and snapshot use new macros
to simplify mempool init and destroy
2015-10-13 15:56:03 +02:00
f9926e7e6c dmeventd: introduce macro for init
Simplify commonly used pool creation.
2015-10-13 15:56:03 +02:00
76ea01dd20 dmeventd: new initialization of plugin threads
Rework thread creation code to better use resources.

New code will not leak 'timeout' registered thread on error path.

Also if the thread already exist - avoid creation of thread
object and it's later destruction.

If the race is noticed during adding new monitoring thread,
such thread is put on cleanup list and -EEXIST is reported.
2015-10-13 15:55:05 +02:00
362558cd66 cleanup: typo in comment 2015-10-13 15:22:58 +02:00
09a8479cb7 cleanup: move system defines before structs 2015-10-13 15:22:58 +02:00
0a633750f1 cleanup: avoid using private
Switch private to user.
2015-10-13 15:22:58 +02:00
0e2261dbd1 cleanup: remove multilog 2015-10-13 15:22:57 +02:00
842a7a17e3 cleanup: always set nsec 2015-10-13 15:22:57 +02:00
f4fb97c850 cleanup: more readable code 2015-10-13 15:22:57 +02:00
8b9533f38f dmeventd: support logging on stdout
Add new supported option '-l' log to stdout/stderr.

It has to be paired with '-f' (foreground run).
2015-10-13 15:22:57 +02:00
903e9af1b2 cleanup: static with _
Document ? is printing to stderr.
2015-10-13 15:16:56 +02:00
e261af52eb dmeventd: handle snapshot overflow
When snapshot reports overflow, handle it in the same way as Invalid.
Until better ideas are implemented.
2015-10-13 15:15:44 +02:00
3f03d46fc1 man: dmeventd update 2015-10-13 15:15:43 +02:00
0e27210308 dmeventd: add more debug messages 2015-10-13 15:15:43 +02:00
13086c2523 dmeventd: drop changing logging
As we now use 'unified' logging macro system - we no longer need
to protect from change of logging function pointer - it's set
once at the start of dmeventd and not change anymore
(as lvm2 library no longer interferers here).
2015-10-13 15:15:43 +02:00
42a9c8b4a6 dmeventd: enable new logging 2015-10-13 15:13:28 +02:00
e50583d721 dmeventd: enable new logging 2015-10-13 15:09:35 +02:00
c90363b585 dmeventd: use log_ macros in plugins
Convert from syslog to standard log_() macros in plugins.
2015-10-13 15:09:03 +02:00
915f0faac1 dmeventd: syslog -> log_xxxxx
Convert logging of dmeventd to libdm logging macros.
2015-10-13 14:43:30 +02:00
0641e3a5fd libdmevent: add dm_event_log
Add dm_event_log() logging function.
Controled by dm_event_log_set().
2015-10-13 14:40:46 +02:00
11a084cf42 dmeventd: log all commands with CMD: prefix
For easier grep of all processed command - add CMD: prefix to them.

Use  >>>  for entring command processing
and  <<<  when command is processed.
2015-10-13 14:40:46 +02:00
d60794c3a3 dmeventd: fix loging report
msg.cmd holds return value from processing after _do_process_request,
so save it before call.
2015-10-13 14:40:46 +02:00
1b1c01a27b log: no file for external logging
When external logging is set do not bother creating log file,
as it's not going to be used.
2015-10-13 14:40:44 +02:00
72d700b064 toolcontext: do not change already set dm_log
If the dm_log is already set to non-default logger,
avoid to change it.
2015-10-13 14:39:37 +02:00
86b04ebd19 thin: enhance logging
Add debug message with more details about threshold overflow.
2015-10-13 14:38:52 +02:00
7e1c08bb6a dmeventd: correct ret code for fail
As  _do_register_device() calls  register_device() function that returns
1 success & 0 fail -  ret = -ENOMEM for fail case instead of 0.
2015-10-13 14:38:49 +02:00
c7b4359ff4 thin: check for overflown pool earlier
Check for pool early before we actually start to modify metadata.
This requires locally active thin-pool.
2015-10-13 14:37:07 +02:00
5695c6aca6 libdm: enforce writethrough mode for cleaner
With "cleaner" policy always use 'writethrough' mode.
2015-10-13 14:35:48 +02:00
5ac81657e5 wiping: make libblkid detect all copies of the same signature if use_blkid_wiping=1
Some signatures are spread around the disk in several copies, mainly for
backup. Make libblkid to detect these extra copies - there was missing
"blkid_probe_step_back" fn call after successful wipe of previous signature
copy.

An example with FAT table which has copies:

$ mkfs.vfat /dev/sda1

Before this patch:

$ pvcreate /dev/sda1
WARNING: vfat signature detected on /dev/sda1 at offset 54. Wipe it? [y/n]: y
  Wiping vfat signature on /dev/sda1.
  Physical volume "/dev/sda1" successfully created

With this patch applied:

$ pvcreate /dev/sda1
WARNING: vfat signature detected on /dev/sda1 at offset 54. Wipe it? [y/n]: y
  Wiping vfat signature on /dev/sda1.
WARNING: vfat signature detected on /dev/sda1 at offset 0. Wipe it? [y/n]: y
  Wiping vfat signature on /dev/sda1.
WARNING: vfat signature detected on /dev/sda1 at offset 510. Wipe it? [y/n]: y
  Wiping vfat signature on /dev/sda1.
  Physical volume "/dev/sda1" successfully created
2015-10-13 12:22:09 +02:00
5bd63df237 tests: test vgimportclone and -n option 2015-10-12 12:55:39 +02:00
75420282e1 vgimportclone: make sure there's no prefix in VG name list
Make sure log/prefix is set to "" when getting the list of VG names.
We need this for the format to be correct so it's properly searched
through later on.
2015-10-12 12:54:59 +02:00
38df48d108 vgimportclone: fix vgimportclone with -n to not add number unnecessarily to base VG name
$ vgcreate vgA /dev/sda
  Volume group "vgA" successfully created

$ dd if=/dev/sda of=/dev/sdb bs=1M
$ dd if=/dev/sda of=/dev/sdc bs=1M

(the new VG name is prefix of existing VG name)
$ vgimportclone -n vg /dev/sdb

(the new VG name is suffix of existing VG name)
$ vgimportclone -n gA /dev/sdc

Before this patch:
------------------
(we end up with "vg1" and "gA1" names with the "1" suffix which is not needed)
$ vgs -o vg_name
  VG
  gA1
  vg1
  vgA

With this patch applied:
------------------------
(we end up with "vg" and "gA" names as they're unique already and no extra suffix is added)
$ # vgs -o vg_name
  VG
  gA
  vg
  vgA

Of course, if the name supplied is not unique, the number is added correctly:
$ dd if=/dev/sda of=/dev/sdb bs=1M
$ vgimportclone -n vgA /dev/sdb
$ vgs -o vg_name
  VG
  vgA
  vgA1
2015-10-12 11:11:34 +02:00
21a8ac0cd3 Fix segfault when lvmlockd is running but not lvmetad
If lvmlockd is running, lvmetad is configured (use_lvmetad=1),
but lvmetad is not running, then commands will seg fault
when trying to send a message to lvmetad.

The difference is lvmetad being "active", not just "used".
2015-10-09 12:20:22 -05:00
1f30ba6178 vgimportclone: cleanup the script and remove dependency on awk, grep, cut and tr
We can replace the expressions with awk/grep/cut/tr with --select now and
more suitable reporting options and modes. Also, we don't need to check
the temporary lvm.conf generated within vgimportclone script since we're
generating it ourselves now using lvmconfig, not using sed anymore like
it was before (so we can be pretty sure it's correct - we use lvmconfig
now even for generating the lvm.conf itself).
2015-10-09 16:31:02 +02:00
8733a8d890 report: add vg_missing_pv_count field
We already have pv_count to report number of PVs that a VG has based
on metadata.

This patch exposes the information about how many of these PVs are
missing which is also useful information for a VG. Wwe could count
the sum of pv_missing reporting fields for each PV in the VG before,
but the new field is practical when reporting VG as a whole and there's
no need to process each PV from VG alone.
2015-10-09 16:28:58 +02:00
5446d17756 man lvmsystemid: fix typos 2015-10-08 13:26:09 -05:00
c9ff5c8223 man lvmsystemd: fix typo 2015-10-08 13:14:28 -05:00
d99dd4086d vgcreate: improve error message for multiple lock managers
If 'vgcreate --shared' finds both sanlock and dlm are running,
print a more accurate error message:
"Found multiple lock managers, select one with --lock-type."

When neither is running, we still print:
"Failed to detect a running lock manager to select lock type."
2015-10-08 10:41:13 -05:00
09981afc1c vgcreate: allow both --shared and --lock-type options
Using --lock-type sanlock|dlm implies --shared.

Using --shared selects lock type sanlock|dlm
(by choosing the one that's running.)

Using both --shared and --lock-type sanlock|dlm should
also be allowed (--shared is just redundant information.)
2015-10-08 10:14:33 -05:00
3d03e504cd metadata: format_text: provide more detailed error message when metadata too large for PV mda
Also, leave out the note about "circular buffer" which is
an internal imeplementation detail anyway and not quite
informational for users:

Before this patch:
$ vgcreate vg1 /dev/sda
  VG vg1 metadata too large for circular buffer
  Failed to write VG vg1.

With this patch applied:
$ vgcreate vg1 /dev/sda
  VG vg1 metadata too large: size of metadata to write is 691 bytes while PV metadata area size on /dev/sda is 512 bytes.
  Failed to write VG vg1.
2015-10-08 16:27:03 +02:00
e04424e87e report: identify LV hodling sanlock locks as 'private,lockd,sanlock' within lv_role report field
Before this patch:
$ lvs -a -o name,layout,role test/lvmlock
  LV        Layout     Role
  [lvmlock] linear     public

With this patch applied:
$ lvs -a -o name,layout,role test/lvmlock
  LV        Layout     Role
  [lvmlock] linear     private,lockd,sanlock
2015-10-08 13:44:29 +02:00
277dd0aa7a tests: check devices with prefix aren't in use
Avoid running tests, when prefix already exist in the system.
As prefix just uses  PID number, we may hit a case for long
running tests, where devices from some previous runs were not
properly cleared away - detect this and fail early.
(Such machine should be inspected and fixed).
2015-10-06 15:23:55 +02:00
ded9452174 man: lvcreate continue
Finish remaing bits of updating pages for better rendering
with -Thtml, -Tps.
2015-10-06 15:23:55 +02:00
4b1cadbd87 man: fsadm 2015-10-06 15:21:36 +02:00
2506275c3b cleanup: fix compiler warning 2015-10-06 14:57:30 +02:00
5f7a94a03e blkdeactivate: recognize and deactivate MD devices too 2015-10-06 13:25:41 +02:00
df59db6048 lockd: add error message for EEXIST
The EEXIST error for LV locks is unusual, and
was missing an explanatory error message.
2015-10-02 15:41:23 -05:00
b33d7586e7 raid_manip: fix wrong image size allocation on raid10 "lvconvert --replace ..." 2015-10-02 17:09:37 +02:00
fb957ef322 raid: Add metadata dev information to reports.
Add metadata_devices and seg_metadata_le_ranges report fields.
Currently only defined for raid, but should probably be extended
to all other segment types that don't report all their device
usage in the 'devices' field.
2015-10-02 10:09:28 +01:00
5e5d48348b man lvmcache: updates for mode and policy
Correct some things, e.g. set mode and policy on
the cache lv, not the pool, lvm.conf field for
mode changed.

Add smq which was missing.

Make the sections on cache mode and cache policy
consistent in structure and style.
2015-10-01 14:23:39 -05:00
26da6a3e10 config: improve cache_settings description 2015-10-01 14:23:39 -05:00
4c2cc782aa tests: ensure test will not block
This test is somewhat 'stupid' and simulates mostly unsupported
situation - so avoid blocking here.
2015-10-01 16:45:14 +02:00
05e7fdd5ce tests: use proper target name for check 2015-10-01 16:05:51 +02:00
796e3fb7e4 man: update lvm pages 2015-10-01 15:03:34 +02:00
867a36b419 man: update dmsetup and dmstats pages
Try to provide properly rendered pages no just with
plain 'man' but also for:

man -Tps
man -Thtml
man2html
2015-10-01 15:03:12 +02:00
a139275eca alloc: fix update or area_len
Commit: 192d9ad977
changed logic for area_len formula - so it returns
different values.

Placing () to restore previous behaviour and make it
explicit.
2015-10-01 15:02:49 +02:00
efcb3bbc8d test: Fix timeout handling
Timeouts were considered as warnings only. Signalling failure is
preferred.
2015-10-01 13:19:29 +02:00
309979d578 lockd: add VG name to debug logging
Add the VG name to the new debug logging in
the previous commit.
2015-09-29 14:07:08 -05:00
c805fa7c40 lockd: add debug logging for metadata error
When lvmetad_pvscan_vg() reads VG metadata from each PV,
it compares it to the last one to verify it matches.
If the VG metadata does not match on the PVs, an error
is printed and it fails to read the VG.  In this error
case, use log_debug to show the differences between
the two unmatching copies of the metadata.
2015-09-29 13:51:24 -05:00
634bf8c953 lockd: fix rescanning VG metadata
One host changes a VG, making the cached VG on another
host invalid.  The other host then rereads the VG from
disk to get the latest copy.  If the first host removed
a PV from the VG, the second host attempts to reread the
VG from old PV when rescanning.  Reading the VG from the
removed PV fails, causing vg_read to return "VG not found".
The fix is to simply not fail when a VG is not found while
rereading a PV and continue without it.

(This doesn't happen if the second host happens to first
run a command like 'vgs' that triggers a global revalidation
of metadata.)
2015-09-29 11:28:48 -05:00
be393f6722 raid: Introduce DEFAULT_RAID_MAX_IMAGES
Prepare to allow for the number of images in a raid set to be
larger than the limit for old-style dm raid1.
2015-09-28 21:38:40 +01:00
d94ff20927 raid: Fail if kernel status denominator is zero. 2015-09-28 20:45:44 +01:00
0173c260d8 libdm: Move status fns from deptree to targets.
libdm-deptree is only for functions working with dm tree nodes.
2015-09-28 20:28:31 +01:00
9d815e5f5a raid: Use loop for text uint32_t parameter import.
Plus some other tidying up of the same file.
2015-09-28 14:28:03 +01:00
7097663ddd test: Cope with stripe rounding message change. 2015-09-28 12:25:31 +01:00
eab099b221 segtypes: Use flags in raid segtype macros. 2015-09-24 20:43:18 +01:00
3036620b48 raid: Add a segtype flag for each raid type. 2015-09-24 20:17:57 +01:00
d40830a2b1 lockd: fix changing lock type on VG with pool
vgchange --lock-type iterates through LVs to ensure
no LVs are active before changing the lock type of
the VG, but the loop was not checking that an LV
actually has a lock before trying it, so it would
fail if the VG had any LVs that don't use locks,
e.g it would fail on a tmeta LV from a pool.
2015-09-24 14:03:20 -05:00
028715b0f0 raid: Detect whether or not kernel supports raid0. 2015-09-24 19:59:29 +01:00
4a74e19f80 alloc: Move _calc_area_multiple. 2015-09-24 17:56:19 +01:00
e773e71910 stripes: Introduce _round_to_stripe_boundary. 2015-09-24 17:50:53 +01:00
39a97d86f0 segtypes: Add and use new segtype macros.
Includes fixing an inverted raid10 segtype check in _raid_add_target_line.
2015-09-24 14:59:07 +01:00
41fe225b0d style: lv_manip.c changes 2015-09-24 13:43:58 +01:00
1945a0f504 libdm: fix bogus macro causing false parameter count 2015-09-24 14:22:52 +02:00
4e60e62444 raid: Fix raid target write_behind parameter.
Now uses correct "max_write_behind" instead of "writebehind".
(Includes some tidying up.)
2015-09-23 15:53:27 +01:00
96a6210198 libdm: Improve raid segment parameter handling. 2015-09-23 15:25:46 +01:00
192d9ad977 style: Miscellaneous tidying up of metadata/lv* 2015-09-23 14:37:52 +01:00
cb82919b0d systemd: use {local,remote}-fs-pre.target instead of {local,remote}-fs.target
We want most of our units to be started before any local/remote mount
points are mounted - we used {local,remote}-fs.target for this purpose
before, but it was not 100% correct as there's even {local,remote}-fs-pre.target
special systemd unit reserved for this exact purpose.

See also man 7 systemd.special and "local-fs-pre.target"/"remote-fs-pre.target"
description.
2015-09-23 13:30:51 +02:00
28aff5d240 segtypes: Make constants ULL. 2015-09-22 21:10:46 +01:00
532b2d2d4e man lvmthin: use --poolmetadatasize option
when extending a pool metadata lv, rather than
referencing the _tmeta device.
2015-09-22 13:44:09 -05:00
214e2cddf6 segtypes: Use SEG_TYPE_NAME_ string constants. 2015-09-22 19:04:12 +01:00
0ce150280e segtypes: Extend flags to 64 bits. 2015-09-22 18:03:33 +01:00
3a8a37187d post-release 2015-09-22 16:06:07 +01:00
629398d0f2 pre-release 2015-09-22 16:00:10 +01:00
fd773dffb2 man: drop superfluous '--' in lvmconf man page for --enable/disable-halvm 2015-09-22 14:28:31 +02:00
001f747963 lvmconf: set locking_type=2 if external library is requested
Also, set safe use_lvmetad=0 for external locking (locking_type=2)
similarly to locking_type=3.
2015-09-22 13:33:12 +02:00
2081071bee wiping: warn if use_blkid_wiping=1 is set and LVM not compiled with blkid_wiping support 2015-09-22 11:11:26 +02:00
47f623d64b tests: update removal test
Test is currently checking a very non-standard use case.
Make it a more resistent against being blocked in kernel.
2015-09-22 00:08:45 +02:00
7e63364529 tests: check for block device
Need to detect if block device exist.
2015-09-22 00:08:44 +02:00
2e5bde4a77 lvchange: update help text
Use <> for user specified options.
(meant to match 'Italic' style in man page).
2015-09-22 00:08:44 +02:00
cfe869692f man: update man pages
Start to use 'italic' when the argument is not a fixed string.
Keep 'bold' when user cannot use any other string instead.
2015-09-22 00:08:44 +02:00
a61f3c5316 clvmd: update help test
Use <n> for <input> value.
2015-09-22 00:08:44 +02:00
ce80d73684 lvmcache: Remove verbose msg when rescanning dev. 2015-09-21 19:51:15 +01:00
804c25a81a WHATS_NEW: commits cb8f29d147 - a54b4bba35 2015-09-21 14:28:41 +02:00
a54b4bba35 report: add lv_convert_lv_uuid field 2015-09-21 14:22:23 +02:00
0a01c5aa36 report: add lv_move_pv_uuid field 2015-09-21 14:22:03 +02:00
f01b7afa19 pv: add 'mem' arg for pv_uuid_dup and pv_name_dup 2015-09-21 14:21:42 +02:00
ffa7b37b28 report: add lv_mirror_log_uuid field 2015-09-21 14:21:39 +02:00
f61a394be4 report: add lv_data_lv_uuid field 2015-09-21 14:21:21 +02:00
c2ea5b3dee report: add lv_metadata_lv_uuid field 2015-09-21 14:20:58 +02:00
199697accf report: add lv_origin_uuid field 2015-09-21 14:20:36 +02:00
cb8f29d147 report: add lv_pool_lv_uuid field 2015-09-21 14:20:12 +02:00
0e3042f488 lv: add 'mem' arg for lv_uuid_dup 2015-09-21 12:25:31 +02:00
f644431346 cleanup: report: reuse existing _uuid_disp fn to report pv_uuid field 2015-09-21 12:13:01 +02:00
83a52c07b7 tests: check dmsetup remove --force 2015-09-18 17:45:46 +02:00
7d1dd5f52d tests: use remount-ro for extfs
Avoid showing kernel warn of umounting broken fs.
2015-09-18 17:45:46 +02:00
330d584617 man: use PD/HP for compressed lines
Using .PD 0  to user zero spacing together with .HP is the best way
for condensed list of commands.
2015-09-18 17:45:46 +02:00
11d6f81316 man: enhance dmsetup/dmstats
Document more supported options.
Cleanup man-style when documenting options.
Use .PD 0  and .HP
2015-09-18 17:45:46 +02:00
f9c8cefd06 dmsetup: improve help text
Document more options.
2015-09-18 17:45:45 +02:00
791e76ff70 dmsetup: use noflush with force removal
When user specifies '--force' with remove/remove_all/wipe_table
use '--noflush --nolockfs' resume flags, so the operation
will not block when device underneath is blocked.
2015-09-18 17:45:45 +02:00
e0d915a873 libdm: parse Overflow string from snapshot status
This is likely to be a new 'info' provided by kernel
snapshot target.
For now just parse this string.
2015-09-18 17:45:45 +02:00
90ad817a43 uuid: Report invalid character. 2015-09-18 14:19:32 +01:00
5bc8c713e2 WHATS_NEW: commit 6c0b4a2769 2015-09-17 14:36:39 +02:00
6c0b4a2769 libdm: file: add proper checks for directory components in dm_create_dir
Also make error messages more consistent:

Before this patch:

(/run/lock exists and is not a directory)
$ pvs
  /run/lock/lvm: mkdir failed: Not a directory
  File-based locking initialisation failed.

(/run/lock/lvm exists and is not a directory)
$ pvs
  Directory "/run/lock/lvm" not found
  File-based locking initialisation failed.

With this patch applied:

(/run/lock exists and is not a directory)
$ pvs
  Existing path /run/lock is not a directory.
  Failed to create directory /run/lock/lvm.
  File-based locking initialisation failed

(/run/lock/lvm exists and is not a directory)
$ pvs
  Existing path /run/lock/lvm is not a directory.
  Failed to create directory /run/lock/lvm.
  File-based locking initialisation failed.
2015-09-17 14:29:51 +02:00
afdae26c71 libdm: dev_node: use lstat instead of stat while removing and renaming nodes
When using udev, the /dev/mapper entries are symlinks - fix the code
to count with this.

This patch also fixes the dmsetup mknodes and vgmknodes to properly
repair /dev/mapper content if it sees dangling symlink in /dev/mapper.
2015-09-17 13:37:15 +02:00
b5022102bb libdm: report: make it possible to use blank value as selection for string list report field
$ lvs -o name,tags vg
  LV    LV Tags
  lvol0
  lvol1 mytag

Before this patch:
$ lvs -o name,tags vg -S 'tags=""'
  Failed to parse string list value for selection field lv_tags.
  Selection syntax error at 'tags=""'.
  Use 'help' for selection to get more help.

(and the same for -S 'tags={}' and -S 'tags=[]')

With this patch applied:
$ lvs -o name,tags vg -S 'tags=""'
  LV    LV Tags
  lvol0

(and the same for -S 'tags={}' and -S 'tags=[]')
2015-09-17 10:19:15 +02:00
b7410c95cf lvmlockd: unlock lv if command fails before lock completes
If lvmlockd acquires an lv lock for a command, but the
command exits before the reply, then the command has
not activated the lv and lvmlockd should unlock it.
This only applies when the lv was not already locked.

(There will always be a chance that the lv lock is held
while the lv is not active, i.e. if the command fails in
the small window between getting the lv lock and before
doing the activation.  In that case, rerunning the
activation command corrects the inconsistency.)

This commit helps by automatically clearing the
inconsistency (lv locked by not activated) in the most
common case when the lv lock operation is slow to
complete and the command is canceled by the user.

This commit also adds and cleans up references to the
client id in a bunch of log messages, which is useful
to follow processing on each independent lock request.
2015-09-16 15:56:54 -05:00
fcfca57e2e format-text: label: fix missing dev assignment for struct label in _text_pv_write
When using lvm shell, some structures which are cached in memory may be
reused. This happens for the struct label (a part of lvmcache_info
structure) when lvmetad is used in which case the PV scan is not
done that would normally overwrite these label structures in memory
and making them up-to-date.

This is all consequence of the fact that struct lvmcache_info and
struct label are not always assigned in the same part of the code.
For example, if lvmetad *is not* used, parts of the struct label are
reassigned in label_read fn while struct lvmcache_info is created
elsewhere. No part of the code reused struct label (and its "dev"
field) before calling label_read fn. That's why the real bug is
hidden when using lvm shell without lvmetad.

However, with lvmetad and lvm shell, the situation is a bit different.
The label_read fn is not called if lvmetad *is* used, hence the
struct label may have ended up not initialized properly.

There was missing assignment for the dev field in struct label
in _text_pv_write fn which caused this problem to appear in
lvm shell with lvmetad, for example:

Before this patch:

lvm> pvcreate /dev/sda
  Physical volume "/dev/sda" successfully created
lvm> pvs /dev/sda
  PV             VG     Fmt  Attr PSize   PFree
  unknown device        lvm2 ---  128.00m 128.00m

With this patch applied:

lvm> pvcreate /dev/sda
  Physical volume "/dev/sda" successfully created
lvm> pvs /dev/sda
  PV         VG   Fmt  Attr PSize   PFree
  /dev/sda        lvm2 ---  128.00m 128.00m

Also, this problem had not appeared before changes introduced
by commits e1a63905d1 through
3a6f91d713 which, among other
things, added proper label field type reporting. Before, label
reporting was the same as using struct physical_volume which
has its own dev field assigned and so this problem was not exposed.
2015-09-15 18:07:32 +02:00
0ac10bb23a post-release 2015-09-15 14:09:10 +01:00
a729b1aa29 pre-release 2015-09-15 13:17:50 +01:00
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
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
cee9ed2244 tests: early check for snapshot-merge 2015-09-14 20:18:54 +02:00
e7e15631dd tests: lvextend of full thin pool 2015-09-14 20:18:54 +02:00
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
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
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
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
cd2e4310b3 tests: new thin tests 2015-09-11 21:52:27 +02:00
fd3d795b93 makefiles: distclean missing files 2015-09-11 21:52:27 +02:00
729b035edd pool: validate pool_metadata has proper suffix 2015-09-11 21:52:27 +02:00
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
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
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
19443035a6 configure: correct message 2015-09-11 21:46:34 +02:00
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
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
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
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
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
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
9b8c876293 tests: remove only existing loops
If loop device meanwhile dissapered, skip 'losetup -d' call.
2015-09-10 17:28:47 +02:00
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
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
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
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
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
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
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
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
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
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
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
d323acdfec man lvmlockd: fix typo 2015-09-09 15:43:28 -05:00
81b0e9de7c man lvmlockd: mention device used for first vgcreate 2015-09-09 15:21:10 -05:00
587fd6a0e4 tests: ensure dd flushed all data before exit 2015-09-08 15:41:34 +02:00
6cb7f21e38 tests: better check for compiled version
Use install /lib files to check for expected version.
2015-09-08 15:41:34 +02:00
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
026db90621 WHATS_NEW: commit b77497cbd8 2015-09-08 15:37:23 +02:00
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
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
0ec64370b2 specs: install lvmlockctl only when built
Move install line into proper section.
2015-09-07 23:27:50 +02:00
d7f45ebca5 libdm: clean up stats local variable use 2015-09-07 20:14:53 +01:00
daa94eb792 libdm: fix display of nsec suffixes in histogram strings 2015-09-07 20:14:53 +01:00
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
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
ffbf12504d cleanup: assign seg_name once 2015-09-07 17:44:08 +02:00
330cad1567 specs: package lvmlockctl man page 2015-09-07 17:44:08 +02:00
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
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
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
d62448cb45 configure: regenerate 2015-09-07 17:43:27 +02:00
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
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
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
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
0f5933ecc1 libdm: handle pool errors in dm_histogram_to_string() 2015-09-07 12:01:20 +01:00
e75b4bc2df libdm: check dm_pool_begin_object() return value. 2015-09-07 11:52:54 +01:00
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
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
2a022e9e6e post-release 2015-09-05 23:58:40 +01:00
fb12308416 style: Standardise some error paths. 2015-09-05 23:56:30 +01:00
f5a3b05c7a pre-release 2015-09-05 23:46:22 +01:00
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
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
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
869c0bdeb8 man lvmlockctl: add man page 2015-09-04 11:05:13 -05:00
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
b00ee99a21 man lvmlockd: explain the use of lvmlockctl kill 2015-09-04 11:05:13 -05:00
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
9694854082 vgchange: improve error message about changing lock type 2015-09-04 09:53:33 -05:00
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
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
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
9e8b3d4a98 lockd: check for unlock failure in all cases
This suppresses an unwanted error message.
2015-09-03 16:47:54 -05:00
c27015368b lvmlockd: improve log messages for adding dlm global lockspace 2015-09-03 16:47:54 -05:00
5da497d0a8 tests: update thin test
Use slightly better values
2015-09-03 23:34:37 +02:00
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
ee8200f1c6 cleanup: use just 2 decimal digits 2015-09-03 23:34:37 +02:00
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
32d6ca9196 cleanup: show error message
Add error message on error path.
2015-09-03 23:34:36 +02:00
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
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
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
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
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
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
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
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
49b5022993 dmstats: support --noheadings for histogram fields 2015-09-03 22:04:11 +01:00
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
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
0a73a5012a vgrename: add missing trace on error path 2015-09-03 10:38:16 -05:00
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
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
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
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
b86bd3b074 man: fix typo in dmstats.8.in 2015-09-02 23:01:46 +01:00
3414601788 man: document --regionid in dmstats.8.in 2015-09-02 21:03:03 +01:00
d31c4e0bc1 man: update dmstats.8.in examples
Make sure that correct 'dmstats create' messages are shown for all
examples and fix LV examples to use correct dmsetup output name
format (vg/lv -> vg-lv).
2015-09-02 21:03:03 +01:00
031cd2bb0d dmstats: improve stats column names
Improve the names and labels of stats reports columns, ensure that
the minimum field widths allow unambiguos labels to be shown and
update the man page descriptions of these fields.
2015-09-02 21:03:03 +01:00
3c0fc6f0da dmstats: add histogram support
Add support to dmstats to create and report histograms.

Add a --histogram switch to 'create' that accepts a string
description of bin boundaries and DR_STATS and DR_STATS_META fields
to report bin configuration and absolute and relative histogram
values:

  hist_bins
  hist_bounds
  hist_ranges
  hist_count
  hist_count_bounds
  hist_count_ranges
  hist_percent
  hist_percent_bounds
  hist_percent_ranges

A new 'histogram' subcommand displays a report that emphasizes
histogram data as either counters or percentage values.
2015-09-02 21:02:12 +01:00
a0cf3d47f1 libdm: add latency histogram support
Add support for creating, parsing, and reporting dm-stats latency
histograms on kernels that support precise_timestamps.

Histograms are specified as a series of time values that give the
boundaries of the bins into which I/O counts accumulate (with
implicit lower and upper bounds on the first and last bins).

A new type, struct dm_histogram, is introduced to represent
histogram values and bin boundaries.

The boundary values may be given as either a string of values (with
optional unit suffixes) or as a zero terminated array of uint64_t
values expressing boundary times in nanoseconds.

A new bounds argument is added to dm_stats_create_region() which
accepts a pointer to a struct dm_histogram initialised with bounds
values.

Histogram data associated with a region is parsed during a call to
dm_stats_populate() and used to build a table of histogram values
that are pointed to from the containing area's counter set. The
histogram for a specified area may then be obtained and interogated
for values and properties.

This relies on kernel support to provide the boundary values in
a @stats_list response: this will be present in 4.3 and 4.2-stable. A
check for a minimum driver version of 4.33.0 is implemented to ensure
that this is present (4.32.0 has the necessary precise_timestamps and
histogram features but is unable to report these via @stats_list).

Access methods are provided to retrieve histogram values and bounds
as well as simple string representations of the counts and bin
boundaries.  Methods are also available to return the total count
for a histogram and the relative value (as a dm_percent_t) of a
specified bin.
2015-09-02 20:48:59 +01:00
c4f3732c91 libdm: reset report field widths in _destroy_rows()
For repeating reports field widths should be re-calculated for
each report interval. Not doing so will cause a single row with
wide field data to cause all subsequent rows to share the width:

Name                                      RgID ArID R/s     W/s    Histogram                                     Bounds
vg_hex-lv_home                               0    0 4522.00 834.00 0s:   991, 2ms:   152, 4ms:   161, 6ms:  4052 0s, 2ms, 4ms, 6ms
vg_hex-lv_swap                               0    0    0.00   0.00 0s: 0, 2ms: 0, 4ms: 0, 6ms: 0                 0s, 2ms, 4ms, 6ms
vg_hex-lv_root                               0    0 1754.00 683.00 0s:  369, 2ms:   65, 4ms:   90, 6ms: 1913     0s, 2ms, 4ms, 6ms
luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e    0    0 4522.00 868.00 0s:   985, 2ms:   152, 4ms:   161, 6ms:  4092 0s, 2ms, 4ms, 6ms
vg_hex-lv_images                             0    0    0.00   0.00 0s: 0, 2ms: 0, 4ms: 0, 6ms: 0                 0s, 2ms, 4ms, 6ms

Name                                      RgID ArID R/s     W/s    Histogram                                     Bounds
vg_hex-lv_home                               0    0    0.00   0.00 0s: 0, 2ms: 0, 4ms: 0, 6ms: 0                 0s, 2ms, 4ms, 6ms
vg_hex-lv_swap                               0    0    0.00   0.00 0s: 0, 2ms: 0, 4ms: 0, 6ms: 0                 0s, 2ms, 4ms, 6ms
vg_hex-lv_root                               0    0    0.00   2.00 0s: 1, 2ms: 0, 4ms: 0, 6ms: 1                 0s, 2ms, 4ms, 6ms
luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e    0    0    0.00   0.00 0s: 0, 2ms: 0, 4ms: 0, 6ms: 0                 0s, 2ms, 4ms, 6ms
vg_hex-lv_images                             0    0    0.00   0.00 0s: 0, 2ms: 0, 4ms: 0, 6ms: 0                 0s, 2ms, 4ms, 6ms
                                                                                                ^^^^^^^^^^^^^^^^^
This is especially significant for the current histogram fields:
depending on the time since the last clear operation the first
report iteration may contain very large values leading to a very
large minimum field width. Without resetting field widths this
large minimum field width value is used for all subsequent rows.
2015-09-02 20:48:59 +01:00
a9d954cb3c pvmove: skip polling later in test mode 2015-09-02 17:25:37 +02:00
6e4f2da9b3 lvconvert: skip polling in test mode 2015-09-02 17:25:29 +02:00
ab5df4bc5c lvmpolld.8.in: add missing space 2015-09-02 17:24:34 +02:00
7bbc128c3d lvmpolld: make lvpoll error messages visible
Previously all stderr messages issued by spawned lvpoll command were reported
as INFO only. This made all such messages invisible in syslog or lvmpolld log
while running default configuration.

All lvpoll stderr messages are loged with WARN priority now and lvpoll
command exiting with retcode != 0 is logged with ERROR priority in
syslog and lvmpolld log
2015-09-02 17:24:26 +02:00
cb57f4f89b libdm: Reinstate dm_task_get_info@Base.
Move the version script local:* wildcard into a node of its own
to avoid conflicting with in-source export macro definitions.
2015-09-01 16:26:02 +01:00
8b6226997e lvmlockd: also use vg name in set_vg_info
Include both the VG uuid and name in the lvmetad
set_vg_info message.  This works around an obscure
problem where the VG uuid in lvmlockd is wrong
when one host removes a dlm VG, then creates a new
VG with the same name.  If the dlm lockspace for
the initial VG was never stopped on another host,
that other host will be using the old uuid in its
lvmetad set_vg_info message.  (That can be
corrected with a larger change, but this is an
effective workaround.)
2015-08-28 14:43:58 -05:00
f0b3e05add lvmetad: also accept vg name for set_vg_info
set_vg_info previously accepted only vg uuid,
now accept both vg uuid and vg name.  If the
uuid is provided, it's used just as before,
but if the uuid is not provided, or if it's
not found, then fall back to using the vg
name if that is provided.
2015-08-28 14:36:48 -05:00
09b2649c5f man lvmlockd: various improvements 2015-08-28 11:38:26 -05:00
cc17210bce man: Add install_full_man makefile target.
'make install_full_man' installs all the man pages regardless of
which components were enabled when 'configure' was run.
2015-08-28 13:03:18 +01:00
e5d99cb9e6 lvmlockd: VG lock can be used when changing lock type
This bit was missed from commit de4db6a that added
changing lock_type.
2015-08-27 16:34:51 -05:00
3c1924c9c0 lvmlockd: fix starting dlm global lockspace
lvmlockd would fail to recognize that the global lockspace
failed to start if the dlm wasn't running, so future attempts
to start the dlm global lockspace would do nothing, thinking
it was already running.
2015-08-27 16:00:24 -05:00
e4d5d05119 lvmlockd: remove list of inactive lockspaces
This was only used to return two flags indicating specific
reasons for a lock failure so that a more specific error
message could be printed by the command (lockspace had been
stopped, or lockspace had an error starting.)

Remove the list, given its limited usefulness, the fact it
would easily become inaccurate, and the fact it was causing
misleading error messages.  The error conditions it was meant
to help could be reported differently.
2015-08-27 15:23:14 -05:00
e3f1b1dccb lvmlockd: skip lockd removal check for non-lockd VGs 2015-08-27 10:27:24 -05:00
fd238f3c0e lvmlockd: fix function def for non-lvmlockd build 2015-08-27 10:27:24 -05:00
58713d34dd lvmlockd: detect when dlm lvb is invalidated
The lvb content can be lost during dlm recovery,
and we need to detect when this happens to revalidate.
2015-08-27 10:27:24 -05:00
32e22a0037 lvmlockd: rescan lockd VG in two new cases
Previously, a command would only rescan a lockd VG
when lvmetad returned the "vg_invalid" flag indicating
that the cached copy was invalid (which is done by
lvmlockd.)  This is still the only usual reason for
rescanning a lockd VG, but two new special cases are
added where we also do the rescan:

. When the --shared option is used to display lockd VGs
  from hosts not using lvmlockd.  This is the same case
  as using --foreign to display foreign VGs, but --shared
  was missing the corresponding bits to rescan the VGs.

. When a lockd VG is allowed to be read for displaying
  after failing to acquire the lock from lvmlockd.  In
  this case, the usual mechanism for validating the
  cache is missed, so assume the cache would have been
  invalidated.  (This had been a previous todo item
  that was lost during other cleanup.)

These were long-standing todos that were lost track of.
2015-08-27 10:27:24 -05:00
231b7df6cc lvmlockd: improve VG removal for lock_type dlm
This makes lvmlockd removal steps for dlm VGs closely match
sanlock VGs.  Because dlm lockspaces are not required to be
stopped on all hosts before vgremove, there is an extra bit
for dlm lockspaces, where a flag is set in the VG lock lvb
indicating that the VG was removed.  If other hosts happen
to use the VG lock they will see this flag and stop their
lockspace.
2015-08-27 10:27:24 -05:00
521136181b lvmlockd: fix to work around dlm lvb bug
Work around a dlm bug that fails to copy lvb
on a NL->EX conversion.
2015-08-27 10:27:24 -05:00
fda19b55b1 lvmlockd: fix dlm EAGAIN checks
libdlm returns EAGAIN in errno
2015-08-27 10:27:24 -05:00
de4db6a93b lvmlockd: add full changing of lock type
Remove the existing lock type using the same functions
used to remove the lockd components during vgremove.
This results in a "clean" VG and lvmlockd state after
the vgchange, i.e. no bits left over from previous
lock type.
2015-08-27 10:27:24 -05:00
d797f4d590 post-release 2015-08-26 23:13:34 +01:00
a37fd93fbb pre-release 2015-08-26 23:11:13 +01:00
8740b7cb77 vgdisplay: Drop error message for exported VGs.
Originally when vgdisplay encountered an exported VG it issued a
WARNING.  Commit d6b1de30 replaced this with an error message
but still exited with success (incorrect).  A backtrace was recently
added in commit b193809987.

As vgdisplay already states that the VG is exported in its output,
just drop these messages completely.
2015-08-26 21:11:46 +01:00
746b1bcf2a libdm: Drop ignored duplicate export designation.
dm_stats_create_region is now assigned to DM_1_02_106 by default:
the DM_1_02_104 .exported_symbols file entry was moved into
libdm-stats.c as:
  DM_EXPORT_SYMBOL(dm_stats_create_region, 1_02_104)
so delete it from .exported_symbols.DM_1_02_104.
2015-08-26 17:30:36 +01:00
34c956afc1 make.tmpl: Mark internal sharedlib symbols local.
Since commit 797c18d543 some internal symbols
have been exported in shared libraries by mistake because 'local: *' got
lost.  Fix the shell script not to compare the whole filename with
'Base'
2015-08-26 13:36:23 +01:00
d0ff35c5a6 tests: update cache tests 2015-08-26 11:24:41 +02:00
1307fafe0f man: replace to with for
Better word.
2015-08-26 11:24:41 +02:00
9886fd236e cache: lvconvert accepts --cachemode for --cache
All cache args could be specified when caching LV
(means converting LV to cached).

When --cachemode arg is given during cache-pool conversion,
store it in the metadata.

https://bugzilla.redhat.com/show_bug.cgi?id=1255184
2015-08-26 11:24:41 +02:00
a4fdfc098d cache: report cache pool attrs also for pools
Since cache-pool actualy keeps info about caching,
display this info for cache-pool LV as well
(matches info for cache LV when cache-pool is asociated with it).
2015-08-26 11:24:41 +02:00
cbe81ad393 cache: no report error for cpool without mode
It's perferctly valid to not have cachemode for
unused cache-pool.

https://bugzilla.redhat.com/show_bug.cgi?id=1255184
2015-08-26 10:49:23 +02:00
8c09f12943 makefiles: remove stray ')' 2015-08-25 19:05:45 +01:00
19ef3e0f31 makefiles: fix ld version script generation for older make versions
Commit 82a27a8 introduced a change to the symbol versioning macros
that allows a new version of a function to be introduced while
keeping the old behaviour via a versioned symbol export. The new
symbol is listed in the current .exported_symbols.DM_* file and a
default (@@VERSION) binding is created during linking.

This broke the build on RHEL5, RHEL6 and Debian Lenny. This is
because the make version in these distros returns results from the
$(wildcard *) command in a different order to the RHEL7 and F22
versions: this affects the ordering of the generated .export.sym
version script:

RHEL7/F22
for i in ./.exported_symbols.Base ./.exported_symbols.DM_1_02_99
 ./.exported_symbols.DM_1_02_98 ./.exported_symbols.DM_1_02_97
 ./.exported_symbols.DM_1_02_106 ./.exported_symbols.DM_1_02_105
 ./.exported_symbols.DM_1_02_103 ./.exported_symbols.DM_1_02_101
 ./.exported_symbols.DM_1_02_104 ./.exported_symbols.DM_1_02_100

 290: 000000000003d101   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region_v1_02_104
*388: 000000000003cfc7   314 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region@@DM_1_02_106
 391: 000000000003d101   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region@DM_1_02_104
*552: 000000000003cfc7   314 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region
 944: 000000000003d101   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region_v1_02_104
 992: 000000000003d101   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region@DM_1_02_104

RHEL6:
for i in ./.exported_symbols.Base ./.exported_symbols.DM_1_02_100
 ./.exported_symbols.DM_1_02_101 ./.exported_symbols.DM_1_02_103
 ./.exported_symbols.DM_1_02_104 ./.exported_symbols.DM_1_02_105
 ./.exported_symbols.DM_1_02_106 ./.exported_symbols.DM_1_02_97
 ./.exported_symbols.DM_1_02_98 ./.exported_symbols.DM_1_02_99; do\

 290: 000000000003d0e1   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region_v1_02_104
 390: 000000000003d0e1   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region@DM_1_02_104
*479: 000000000003cfa7   314 FUNC    LOCAL  DEFAULT   12 dm_stats_create_region
 944: 000000000003d0e1   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region_v1_02_104
 992: 000000000003d0e1   106 FUNC    GLOBAL DEFAULT   12 dm_stats_create_region@DM_1_02_104

The F22 build has the correct behaviour (although the sort order is
inconsistent) but on RHEL6 the 1_02_106 symbol file appears after
version 1_02_104 which introduced the original symbol. This causes
the later version of the symbol to lose its version binding and be
reduced to local scope.

If using un-versioned exports of the current version of a symbol
(i.e.  exported with the plain symbol name and no macro) and using
the linker script to set the symbol version, the current version
node must appear first in the version script: the un-versioned
symbol will be bound to the first version node found that contains
it.

On RHEL6 and the other older distros the original version of the
dm_stats_create_region() call sorted before the current version
(DM_1_02_104 vs. DM_1_02_106) leading to a subsequent link error for
the later symbol version:

dmsetup.o: In function `_do_stats_create_regions':
/root/src/git/lvm2/tools/dmsetup.c:4658: undefined reference to
`dm_stats_create_region'

Ensure that the ordering of entries in the version script is
consistent to avoid an old implementation shadowing a newer one by
sorting the list of file names before the loop:

  $$(echo $(EXPORTED_SYMBOLS) | tr ' ' '\n' | sort -rnt_ -k5 )

This only sorts by patch level but this is sufficient to maintain
the correct order for current version files.

Tested on RHEL5, 6, 7 and F22.
2015-08-25 18:51:57 +01:00
463f59eca4 dmstats: add 'precise' flag field to stats report
Add a flag indicating whether or not precise_timestamps are enabled for
a given region or area.
2015-08-24 20:03:21 +01:00
e4145ebc47 dmstats: add --precise switch to enable nanosecond counters. 2015-08-24 20:03:21 +01:00
567189cc76 libdm: add per region precise timestamps property methods 2015-08-24 20:03:21 +01:00
f4262026b6 libdm: add precise timestamps support to libdm-stats
Add support for the kernel precise_timestamps feature. This allows
regions to be created using counters with nanosecond precision.

A new dm_stats method, dm_stats_set_precise_timestamps() causes all
future regions created with this handle to attempt to enable precise
counters.
2015-08-24 20:03:21 +01:00
82a27a85b5 macros: fix default symbol export control
Fix the version export macros to make it possible to export two
different DM_* versions of a symbol: currently it is only possible for a
DM_* symbol to override a symbol in Base. Attempting to export two
symbols at different DM_* version levels (e.g. DM_1_02_104 and
DM_1_02_106) leads to a linker error due to a duplicate symbol
definition.

This is because the DM_EXPORTED_SYMBOL macro makes each exported symbol
the default (@@VERSION):

       __asm__(".symver " #func "_v" #ver ", " #func "@@DM_" #ver )

Fix the macro to use a single '@' for a symbols exported in multiple
versions and rename the macros to DM_EXPORT_*:

  DM_EXPORT_SYMBOL(func,ver)
  DM_EXPORT_SYMBOL_BASE(func,ver)

For functions that have multiple implementations these macros control
symbol export and versioning.

Function definitions that exist in only one version never need to use
these macros.

Backwards compatible implementations must include a version tag of
the form "_v1_02_104" as a suffix to the function name and use the
macro DM_EXPORT_SYMBOL to export the function and bind it to the
specified version string.

Since versioning is only available when compiling with GCC the entire
compatibility version should be enclosed in '#if defined(__GNUC__)',
for example:

  int dm_foo(int bar)
  {
    return bar;
  }

  #if defined(__GNUC__)
  // Backward compatible dm_foo() version 1.02.104
  int dm_foo_v1_02_104(void);
  int dm_foo_v1_02_104(void)
  {
    return 0;
  }
  DM_EXPORT_SYMBOL(dm_foo,1_02_104)
  #endif

A prototype for the compatibility version is required as these
functions must not be declared static.

The DM_EXPORT_SYMBOL_BASE macro is only used to export the base
versions of library symbols prior to the introduction of symbol
versioning: it must never be used for new symbols.
2015-08-24 20:03:21 +01:00
ba898b9ab6 tests: fix check for lvmlockd test 2015-08-21 17:00:21 -05:00
d827dd8b05 tests: add test for lvmlockd lock_args 2015-08-21 15:09:38 -05:00
e53758c5f6 tests: add lib function to test hidden LVs with lvs -a 2015-08-21 15:09:38 -05:00
1f27c9f6a4 tests: create/remove improvements for lvmlockd testing 2015-08-21 15:09:38 -05:00
d310e1f907 test: allow tests with lvmlockd 2015-08-21 15:09:38 -05:00
81d4c4a84c WHATS_NEW 2015-08-21 15:37:56 +02:00
1c811bfcd9 tests: check cachepolicy with lvconvert 2015-08-21 15:35:45 +02:00
6d9e7d48fb cleanup: add . 2015-08-21 15:35:45 +02:00
c868609cff man: fix sqm typo 2015-08-21 15:35:45 +02:00
e4b9ac46d7 thin: metadata size cannot be reduced
Until we implement offline metadata manipulation,
the size of metadata LV cannot be reduced.
2015-08-21 15:35:45 +02:00
45f3e8bbef cache: enable setting cachepolicy in lvconvert 2015-08-21 15:35:45 +02:00
1fae121b22 lvmlockd: fix sending debug info to lvmlockctl
Single messages sent over unix sockets are limited in
size to /proc/sys/net/core/wmem_max, so send the 1MB
debug buffer in smaller chunks to avoid EMSGSIZE.

Also look for EAGAIN and retry sending for a limited
time when the reader is slower than the writer.

Also shift the location of that code so it's the same
as other requests.
2015-08-20 14:07:11 -05:00
180f92d3dc WHATS_NEW: Update. 2015-08-20 19:06:47 +02:00
5476ee8655 cmirrord: avoid resync buffer overflow in LOG_SPRINT
Use snprintf() instead of sprintf() to exclude the possibility of
overflowing the resync history buffers.
2015-08-20 19:06:47 +02:00
3c396cf1e1 cmirrord: avoid debugging buffer overflow in LOG_SPRINT
Use snprintf() instead of sprintf() to exclude the possibility of
overflowing the debugging history buffers.
2015-08-20 19:06:47 +02:00
1ea1cb6dc9 cmirrord: fix stack smashing
With clusters larger than 3 nodes, the 32-byte debug buffer in
cpg_join_callback() is too small to contain all the node IDs, because
32-bit identifiers are generally rendered in 10 decimal digits.  No fixed
size is good in all cases, but this is conditionally logged debug info,
so we can simply truncate it.  Double the size, nevertheless.
2015-08-20 19:06:47 +02:00
8821cc416e cmirrord manual: add --foreground and --help options 2015-08-20 19:06:47 +02:00
92a4b5cc3c cmirrord: add --foreground and --help options. 2015-08-20 19:06:47 +02:00
c0d6056870 cmirrord: move generic setup from daemonize() to init_all()
Apply pidfile creation, removal and signal setup to foreground processes too.
2015-08-20 19:06:47 +02:00
23770214a9 man: fix program_id string in dmstats.8.in 2015-08-20 17:27:28 +01:00
386e91addb libdm: add dm_message_supports_precise_timestamps()
Add a function to test whether the kernel precise_timestamps
feature is available in the current device-mapper driver version.

Presence of precise_timestamps also implies the availability of
latency histograms.
2015-08-20 12:11:23 +01:00
62a87c84ed lvmlockd: ignore cmd close if no locks were taken
When a command closes its connection, don't waste
time looking for locks to purge if it did not make
any lock requests.
2015-08-19 12:16:04 -05:00
ce2e60ab45 lvmlockd: change log_error to log_debug for non error
It's not uncommon for a command like vgchange -an to
deactivate and unlock LVs that were not active, so
don't lock that as an error.
2015-08-19 11:43:39 -05:00
9c5a85ce24 lvmlockctl: fix debug output 2015-08-18 16:49:33 -05:00
c09dad71fb tests: fix lockd options in sanlock-prepare 2015-08-18 15:06:49 -05:00
d08427030d config: improve description text layout
This mainly makes the description text use 80 columns.
There are a few minor adjustments to wording to help
the text layout, and a couple minor improvements to
descriptions.
2015-08-18 14:02:32 -05:00
7b570840cd lockd: no error when unlock fails
The unlock call will fail in expected and normal cases,
and should not cause the command to fail.  (An actual
unlock in the lock manager should never fail.)
2015-08-18 11:18:40 -05:00
c1bd76d6fc configure: check for -lm and log10 function
We already use -lm functions in a couple of places (these are
satisfied by gcc built-ins for most builds): add a configure.in
check and explicitly link to -lm.
2015-08-18 15:25:54 +01:00
a7abade088 cleanup: compare fgets pointer
Check pointer for not being NULL.
2015-08-18 16:05:04 +02:00
abb24370e9 cleanup: move var declaration 2015-08-18 16:05:04 +02:00
6e1feb0f73 cleanup: preserve constness of some pointers 2015-08-18 16:05:04 +02:00
ef7264807f cleanup: log_debug format matches args 2015-08-18 16:05:04 +02:00
bc39506792 man: update dmstats.8.in examples 2015-08-18 14:40:45 +01:00
28b4fa3e27 Revert "lvmcache: check for too long pvid"
This reverts commit 70db1d523d.
Since we use 'strncpy' even for case where it exactly matches
the buffer size and \0 is not expected to be added there.
2015-08-18 15:22:13 +02:00
b193809987 debug: vgdisplay trace failing result code
Add stack on error path.
2015-08-18 15:00:08 +02:00
a8fd88463e cleanup: trace error from lvmcache_update_vgname_and_id
Check result value from lvmcache_update_vgname_and_id().
2015-08-18 15:00:08 +02:00
3a3e17d603 cleanup: check pthread result codes 2015-08-18 15:00:08 +02:00
40af31729f cleanup: typo fix and drop \
Fix 'th e'  and use % directly.
2015-08-18 15:00:08 +02:00
58f8f29c41 cleanup: add FMTssize_t
Add define to print nicely ssize_t type.
2015-08-18 15:00:08 +02:00
3d08a49790 cleanup: add cast 2015-08-18 15:00:08 +02:00
55a9262bdb cleanup: unused header files (Coverity) 2015-08-18 15:00:08 +02:00
ba94d0f144 libdm: simplify dmstats formula.
Since we check for stats for not being 0,
simplify the operation and use a single division.
2015-08-18 15:00:08 +02:00
ae4db9f302 lockd: check for failing unlock
Avoid ignoring unlocking error.
2015-08-18 15:00:07 +02:00
70db1d523d lvmcache: check for too long pvid 2015-08-18 14:53:36 +02:00
8e229cb7ea dmstats: reduce minimum field widths 2015-08-18 10:30:53 +01:00
13d3eeb2ee dmstats: fix type formatting
Fix several instances of 'const char * const*' to be:

  'const char * const *'
2015-08-18 10:30:53 +01:00
dece918bc8 config: create lists of accepted values in descriptions 2015-08-17 14:50:41 -05:00
b091c37595 config: add empty lines around examples
When --withspaces is used, a blank line is
added before and after an Example section,
making the text less dense.
2015-08-17 13:52:34 -05:00
ca70770cfd config: recognize a blank comment line
Consider the comment line "#\n" to be a blank line, and
print a blank line at that position when --withspaces is set.
2015-08-17 13:52:34 -05:00
5243a81c29 config: explain automatic default values
Before printing a commented automatic config value,
print a line describing what it is.  Otherwise, the
commented value can look like it's a part of an
example preceding it.
2015-08-17 13:52:34 -05:00
12acf852c5 dmsetup: check timerfd reads for valid byte count (Coverity)
The timerfd guarantees that it will return 8 bytes when a read(2)
is issued (a uint64_t giving the number of timer events during the
call). Check that it does so and log a non-fatal error if the byte
count is not 8.
2015-08-17 19:28:53 +01:00
074b5de771 libdm: check for zero in _nr_areas() (Coverity) 2015-08-17 18:37:16 +01:00
69fa16048a dmstats: check for zero in _nr_areas_from_step() (Coverity) 2015-08-17 18:37:16 +01:00
b01e9651b0 dmsetup: make sure subcommand is initialised (Coverity) 2015-08-17 18:37:16 +01:00
8967776713 libdm: do not read region before checking dms for NULL (Coverity)
dm_stats_get_area_start() attempts to assign a region pointer from
a stats handle before checking it is non-NULL: move the assignment
after the test.
2015-08-17 18:37:16 +01:00
d1c65d1b28 post-release 2015-08-17 17:26:20 +01:00
be1db6b6c1 pre-release 2015-08-17 17:20:14 +01:00
4227b2ebb4 libdm-stats: only return uint64_t when required
Several interfaced in libdm-stats return a uint64_t when it is
only used to signal success/failure: change all these uses to
return a simple int instead.
2015-08-17 16:59:52 +01:00
15e20bb5c0 conf: Regenerate example.conf. 2015-08-17 16:51:43 +01:00
80bc87e377 cache: more comments for new setting 2015-08-17 17:26:39 +02:00
77357081c8 tests: update thin test
Since we now let pass activation of thin-pool 'off-by-one' for
plain 'vgchange -ay' update the test to use higher TID.
2015-08-17 17:07:09 +02:00
4b28383b1c cache: move detection code to cache_set_policy
Move code which runtime detects settings for cache_policy
out of config dir to cache seg handling code.

Also mark cache_mode as command profilable setting.
2015-08-17 15:52:06 +02:00
94c56559ca dmsetup: fix usage of ifdefs 2015-08-17 15:52:06 +02:00
427d0a5e92 libdm: ensure dm_stats_get_area_offset() returns a value 2015-08-17 14:40:48 +01:00
623b46a17d device: Don't try to close config file on failure.
$file: open failed: Permission denied
Failed to load config file $file
Attempt to close device '$file' which is not open.
2015-08-17 12:57:01 +01:00
a606966029 tests: Revert update for new thin pool messaging
This reverts commit 3dbb9a57ca.
Original code is back as the code restored previous TID handling.
2015-08-17 11:25:03 +02:00
79ea81b8a8 thin: restore transaction_id handling
Revert back to already existing behavior which has been slightly
modified by a900d150e4.

At the end however it seem to be equal to change TID right with first
metadata write.

Existing code missed handling for 'unused' thin-pool which would
require to also check empty message list for TID==0.

So with the fix we now again preserve 'active' thin-pool volume
when first thin volume is created - this property was lost and caused
problems in cluster, where the lock was hold, but volume was no longer
active on the node.

Another missing part was the proper support for already increased,
but unfinished TID change.

So going back here with existing logic -

TID is increased with first MDA update.

Code allows start with either same TID or (TID-1).

If there are messages, TID must be lower by 1 for sending,
otherwise messages were already posted.
2015-08-17 11:25:03 +02:00
d4c024c836 cache: use undefined settings for cache_policy
As cache_policy is evaluated in runtime, we no longer should use
CFG_COMMENTED, but have to switch to CFG_UNDEFINED.

So as long as the value is undefined, it's runtime evaluated.
Once it's set - it's always respected (no runtime fallback).

Also fix version of introduced settings to 2.2.128.
2015-08-17 11:25:03 +02:00
b297d78367 WHATS_NEW: Update. 2015-08-16 01:16:16 +01:00
4a6d5e2012 dmstats: fix --length argument
Commit f10ad95 introduced a regression causing the size of regions
passed in on the command line to be truncated to zero. Initialise
the 'this_len' variable to the supplied length to correct this.
2015-08-15 18:35:10 +01:00
9d5cd4ca14 dmstats: fix new area count for 'create --areasize'
Commit f10ad95 introduced a regression in the calculation of the
number of areas in a region created with the --areasize switch:

vg_hex-lv_home: Created new region with 0 area(s) as region ID 1
vg_hex-lv_swap: Created new region with 0 area(s) as region ID 1

Fis this by using the correct region size when calculating the
value.
2015-08-15 00:42:51 +01:00
0b487802a0 dmstats: change region fields prefix to 'region_' 2015-08-14 23:53:42 +01:00
f3891e90e3 dmstats: make -v enable per area reports for 'stats list'
When dmstats is run with -v or higher enable a per-area reporting
mode for statistics regions. This will output one row per area
(rather than one row per region) and adds additional fields of use
when viewing areas:

 area_id    - index within the region assigned by libdm-stats
 area_start - the start location of the area in the containing
              device.
2015-08-14 22:03:37 +01:00
0f3b81bb2e dmstats: add 'area_offset' field to stats reports 2015-08-14 22:03:37 +01:00
00ed523659 libdm: add dm_stats_get_{current_}area_offset()
Add a method to retrieve the offset of an area within the
containing region (rather than the offset within the containing
device returned by dm_stats_get_area_start()).

Although users of the library can calculate this themselves it is
better to provide this through a method call to avoid users making
assumptions about the structure of regions and areas.
2015-08-14 22:03:37 +01:00
77fae3d852 libdm: ensure dm_stats_get_area_start includes region offset
The dm_stats_get_area_start (and its '_current_' variant) methods
are expected to return the start sector of the area in the
containing device.

Make sure the call adds region->start to the returned value.
2015-08-14 22:03:37 +01:00
16ff2d927f dmsetup: add support for 'stats report --raw'
Add a '--raw' switch to stats reports that causes us to report the
basic counter values rather than derived metrics for each visible
statistics region.
2015-08-14 22:03:37 +01:00
fc7a27bc3d dmsetup: add prefixes for all report types
Add prefixes to all dmsetup report types to allow the 'group_all'
option to be effective:

  DR_NAME       name_
  DR_INFO       info_
  DR_DEPS       deps_
  DR_TREE       tree_
  DR_NAME       splitname_
2015-08-14 22:03:37 +01:00
666722324f dmstats: add 'stat_' prefix to stats report columns 2015-08-14 22:03:37 +01:00
bfb58b7e1c spec: Add cache-*.profile 2015-08-14 21:45:11 +02:00
8852b25fc7 dmsetup: do not track moving average for interval estimate
When run with full verbosity dmsetup or dmstats reports will
output a figure that tracks a moving average over a window of the
last two intervals:

Interval     #3        time delta:    999991087ns
Interval     #3     mean duration:    999907064ns, current err: -8913ns
End interval #3          duration:    999991087ns
Adjusted sample interval duration:    999991087ns

Due to the narrow window this is a very crude estimate and is only
of use to someone debugging or modifying the stats clock: remove
the value and the global variables used to track it.

Anyone with a particular use for this information can construct a
better mean by calculating the value of a greater number of
intervals.
2015-08-14 13:55:26 +01:00
4d5b618d52 WHATS_NEW_DM: recent commits (stats field split and timestamp headers) 2015-08-14 13:43:12 +01:00
e6724f0303 dmstats: make 'dmstats list' use common report infrastructure
Unlike 'info -c' and 'stats report' the 'dmstats list' subcommand
does its own report processing. This complicates the handling of
the DR_STATS and DR_STATS_META fields and leads to inconsistent
behaviour between the different commands. In particular it causes
'stats list' to segfault when using 'all' field options:

Segmentation fault (core dumped)

Delete _stats_list() entirely and adapt _stats_report so that it
can correctly format a DR_STATS_META-only report request.

This requires passing the subcommand into _report_init() where it
is used in addition to the command name to select the default set
of report fields for the 'list' and 'report' stats subcommands.

With this change both 'list' and 'report' dmstats report will use
the correct report object type and ensure that it is initialised
appropriately for the field selection in use.
2015-08-14 13:43:12 +01:00
37dd26e322 dmstats: separate stats meta fields into their own report type
Although statistics and meta fields (region and area properties) share
the same object type the state of the handle they expect differs: meta
only expects a dm_stats_list() operation to have been performed whereas
statistics require a fully populated handle.

Distinguish between these requirements by separating the fields into
two distinct report types:

  DR_STATS = 32,
  DR_STATS_META = 64

The new category is described as "Mapped Device Statistics Region
Information" in the help text.
2015-08-14 13:43:03 +01:00
f10ad95c36 dmstats: cleanup _do_stats_create_regions()
Make the use of the this_start and this_len variables easier to
follow and clarify the use of zero start and len arguments to
request a whole-device region.
2015-08-14 13:36:52 +01:00
9b3dc72506 dmstats: add 'interval' and 'interval_ns' report fields
Add a pair of fields to expose the current per-interval duation
estimate. The 'interval' field provides a real value in units of
seconds and the 'interval_ns' field provides the same quantity
expressed as a whole number of nanoseconds.
2015-08-14 13:36:50 +01:00
4534f0fbcf libdm: do not in include internal bits/time.h header
Do not include bits/time.h as it is an internal libc header file.

A comment at the top of the glibc specific bits/time.h says:
"Never include this file directly; use <time.h> instead."

This fixes the following build error with musl libc:
libdm-timestamp.c:37:23: fatal error: bits/time.h: No such file or directory
---
Compile tested with Alpine Linx (musl libc) and ubuntu 15.04

 libdm/libdm-timestamp.c | 1 -
 1 file changed, 1 deletion(-)
2015-08-14 11:33:12 +01:00
6a93206882 dmsetup: Fix dmsetup return code. 2015-08-14 00:09:40 +01:00
043fb32c4b dmsetup: Restructure arg handling.
Introduce enums and global variables to record cleanly which command we
are processing and eliminate the historically inconsistent use of the
shifted argv[0] and fix assorted bugs discovered along the way.

Add dm_report_is_empty() to indicate there is no data awaiting output
and use this to suppress dmsetup report headings when no data is output
so we don't get a stray line saying 'Help' at the end of reporting help.

Define a report type (as the interface requires) so -o all selects
the right fields in splitname.  (A fix for stats list will follow.)

Exit immediately if no device is supplied to dmsetup wipe_table instead
of hitting errors later and failing.

Adjust the command name printed in usage/help output to match command
invoked (most of the time).
2015-08-13 22:30:39 +01:00
b3cd5d2945 dmstats: do not use "region_id" in error messages
Refer to either '--regionid' or '--allregions' when the user fails
to specify either a single region ID or the --allregions switch.
2015-08-13 19:05:48 +01:00
6b81ac5807 dmstats: replace --force with new stats-specific --alldevices
The '--force' switch is only used by dmstats to allow either
creation or deletion of one or more regions on all devices.

These operations do not carry any risk: just a possible mess of
region IDs to be cleaned up.

Remove the use of '--force' for stats commands and change current
uses to a new '--alldevices' switch.
2015-08-13 19:05:46 +01:00
988ca74351 dmstats: improve region creation messages
The region creation message just outputs the new region_id, e.g.:

Created region: 0

This is fine when the device is unambigous (as above) but produces
unhelpful output when creating multiple regions, or regions on
multiple devices:

Created region: 0
Created region: 0
Created region: 1
Created region: 2
Created region: 0

To address this refactor _stats_create_segments() (previously only
used when creating one-region-per-target for --segments) into a
more general _do_stats_create_regions() that can create regions
for each segment, or a single region spanning either the entire
device or a specied start/len range.

This allows us to output all region creation messages from a
single point where both the device name and all information needed
to derive the number of areas is available.

This allows us to log all these facts in the resulting messages:

vg_hex-lv_home: Created new region with 13 area(s) as region ID 0
vg_hex-lv_home: Created new region with 4 area(s) as region ID 1
vg_hex-lv_home: Created new region with 1 area(s) as region ID 2
vg_hex-lv_swap: Created new region with 1 area(s) as region ID 0
vg_hex-lv_root: Created new region with 10 area(s) as region ID 0
luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e: Created new region with 17 area(s) as region ID 0
vg_hex-lv_images: Created new region with 20 area(s) as region ID 0
vg_hex-lv_images: Created new region with 4 area(s) as region ID 1
2015-08-13 19:05:45 +01:00
86adb6ca63 dmsetup: make timekeeping debug messages more readable
Don't use cryptic abbreviations and make sure that all values can
be understood by someone not familiar with the clock internals.

Include the current interval number (inverse of the _count) in all
interval update messages and attempt to align interval timestamp
logs for interval counts < 99,999.
2015-08-13 19:05:45 +01:00
b22b7d7ba9 dmsetup: Use #define for command names. 2015-08-13 13:10:23 +01:00
7995eedd35 dmstats: don't output column headings if report fails
If _stats_report fails (e.g. due to an invalid device on the
command line) destroy the _report to prevent stats columns headings
from being displayed.

This also requires a change in main to test the return from
_perform_command_for_all_repeatable_args inside the interval loop
and exit immediately in case of error.
2015-08-12 22:02:23 +01:00
098528513f dmstats: don't output column headings when args checks fail
The clear, create, delete, and print commands do not use _report:
make sure it is freed and set to NULL before checking arguments.
2015-08-12 21:40:43 +01:00
829384f46d config: description updates
Make the first line of every description a complete one
line sentence for the benefit of lvmconfig --withsummary.
2015-08-12 15:35:45 -05:00
e96041e18f dmsetup: only free resources once in the final interval
The _update_interval_times() function is called once per reported
object: when shutting down at the end of a run only the first call
should free timestamps. Clear the timestamp pointers after free
and use this to signal to other callers that the clock is already
shut down.
2015-08-12 19:16:05 +01:00
0f45aa7f31 udev: fix missing escape for +
Commit 3ea396e9d2 missed to escape +
which is used by 'sed' as separator for 's'.
2015-08-12 19:46:44 +02:00
2cf3336130 lvcreate: fix return value
Return correct 0 instead of NULL.
2015-08-12 19:46:43 +02:00
a8b9e2eccd dmsetup: use timerfd for interval timing if available
If the Linux timerfd interface to POSIX timers is available at compile
time use it for all report interval timekeeping. This gives more
accurate interval timing when the per-interval processing time is less
than the configured interval and simplifies the timestamp bookkeeping
required to keep accurate time.

For systems without timerfd support fall back to the simple usleep based
timer.
2015-08-12 15:09:57 +01:00
99f55abc56 libdm: add dm_timestamp_copy() 2015-08-12 15:09:57 +01:00
c2d814e78d tests: keep testing mq policy
Tests were written for 'mq' policy, so disable smq.
2015-08-12 14:33:16 +02:00
9e3ef2809a tests: link some new cache profiles 2015-08-12 14:33:16 +02:00
48ed8ac50c cleanup: indent 2015-08-12 14:33:16 +02:00
ece758457d cleanup: use IEC KiB units
Reduce mixing of KB, kiB and use just KiB.
2015-08-12 14:33:15 +02:00
79e9bde0ea libdm: rename to data_block_size
Use common name for pool device - as we use data_block_size
for thin pool metadata, use same name for cache_pool.

This change does not affect API.
2015-08-12 14:33:15 +02:00
08f047eb51 libdm: cache target arg validation
Add some arg validation for dm_tree_node_add_cache_target().
2015-08-12 14:33:15 +02:00
9edd2258ff config: extend definition for Allocation
Extend comment for this section.
2015-08-12 14:33:15 +02:00
13c7bbf8a9 config: support longer config paths
64 bytes might not be enough, so use larger buffer size.
2015-08-12 14:33:15 +02:00
533ac4d47d cache: add more validation 2015-08-12 14:33:14 +02:00
f0c18fceb4 cache: api update
Change logic and naming of some internal API functions.

cache_set_mode() and cache_set_policy() both take segment.

cache mode is now correctly 'masked-in'.

If the passed segment is 'cache' segment - it will automatically
try to find 'defaults' according to profiles if the are NOT
specified on command line or they are NOT already set for cache-pool.

These defaults are never set for cache-pool.
2015-08-12 14:32:24 +02:00
22a1337a9b cache: undefined policy is mq
If the policy_name is unspecified in metadata,
it's automatically 'mq'.
2015-08-12 14:11:18 +02:00
969ee25a74 toollib: get_cache_params
Enhance  get_cache_params() to read common cache args.
2015-08-12 14:11:18 +02:00
6cde12a013 cache: man updates
Better man for cachepolicy and cachesettings.
2015-08-12 14:11:17 +02:00
feb8e9a790 cache: runtime detect default policy
When the policy is not preset in lvm.conf,
detect in runtime whether to use 'mq' or
new available 'smq'.
2015-08-12 14:11:17 +02:00
8a74d1ec79 cache: detect smq policy presence
Add code to detect available cache features.
Support policy_mq & policy_smq  features which might be disabled.

Introduce global_cache_disabled_features_CFG.
2015-08-12 14:11:17 +02:00
694c88e031 cache: introduce mq and smq profiles
Add 2 demo profiles for mq and smq policies.
Show all support profilable params.

Use with: lvcreate --policy cache-mq ....
2015-08-12 14:11:16 +02:00
036d90bba6 cache: add cache_policy cache_settings
Add new profilable configurables:

allocation/cache_policy
allocation/cache_settings

and mark allocation/cache_pool_chunk_size as profilable as well.

Obsolete allocation/cache_pool_cachemode and
introduce new allocation/cache_mode instead.

Rename DEFAULT_CACHE_POOL_POLICY to DEFAULT_CACHE_POLICY.
2015-08-12 14:11:16 +02:00
664a9f4830 configure: --clear-need-check-flag needs 0.5.4
Require version 5.4 of cache_check tool where this option
will work correctly.
2015-08-12 14:11:15 +02:00
3ea396e9d2 udev: use += for SYSTEMD_WANTS instead of =
Instead of using = to override SYSTEMD_WANTS, use += to add
the pvscan service.
2015-08-12 09:33:06 +02:00
819dc1845e lvconvert: fix lockd LV locking
Request a transient LV lock from lvmlockd when
converting an LV.  If the LV is inactive when
lvconvert is run, the LV lock will be acquired
and then released when the command is done.
If the LV is active, a persistent lock exists
already and the transient lock request does nothing.

This fixes the issue that had been mentioned in the
comment previously.
2015-08-11 12:17:24 -05:00
53c08f0bba lvrename: fix lockd LV locking
lvrename should not be done if the LV is active on another host.
This check was mistakenly removed when the code was changed to
use LV uuids in locks rather than LV names.
2015-08-10 15:46:21 -05:00
597de9d586 lvmlockd: add LV name to some debug logging
The LV uuid is used as the lock name, and including
the LV name in some log messages makes it easier to
follow log messages.
2015-08-10 15:07:10 -05:00
f072a76326 libdm-stats: backtrace if fclose fails (Coverity)
Since libdm-stats only uses fmemopen'd FILE objects the only way
that a close can fail is corruption of the memory containing the
FILE: check for this case and emit a backtrace if it occurs.

libdm/libdm-stats.c: 338 in _stats_parse_list()
libdm/libdm-stats.c: 341 in _stats_parse_list()
libdm/libdm-stats.c: 481 in _stats_parse_region()
libdm/libdm-stats.c: 487 in _stats_parse_region()
libdm/libdm-stats.c: 487 in _stats_parse_region()
 - Calling "fclose" without checking return value
2015-08-10 20:26:07 +01:00
856f9cced8 libdm: simplify stats nr_areas calculation (Coverity)
Remove an unneccessary conditional operator and simplify the logic
in _nr_areas:

libdm/libdm-stats.c: 501 in _nr_areas() - Control flow issues  (DEADCODE)
2015-08-10 20:26:07 +01:00
ec87e88c52 dmsetup: don't free handle if dm_stats_create fails (Coverity)
The error path of _stats_list frees the task and stats objects:
don't try to branch to it before they have been allocated.

tools/dmsetup.c: 4589 in _stats_help() - Null pointer dereferences  (FORWARD_NULL)
2015-08-10 20:25:59 +01:00
f9f5aac123 libdm: fix stats handle leak in dm_stats_create (Coverity)
Make sure the newly created handle is freed if we are unable to
also create the pool for it.

tools/dmsetup.c: 4255 in _stats_list() - Variable "dms" going out of scope leaks the storage it points to.
2015-08-10 20:20:30 +01:00
1134de3c89 libdm: fix FILE leak in _program_id_from_proc() (Coverity)
Make sure comm is closed in the error path of _program_id_from_proc().

libdm/libdm-stats.c: 98 in dm_stats_create() - Variable "comm" going out of scope leaks the storage it points to.
2015-08-10 20:20:26 +01:00
3b74824985 dmsetup: remove bogus !_report test in _stats_report (Coverity)
There's no point testing _report here in _stats_report: it's always
initialised before the function is called and if the check did fail
we'd end up freeing an uninitialized dm_task in the error path.

tools/dmsetup.c: 4389 in _stats_report() - Declaring variable "dmt" without initializer.
2015-08-10 20:12:53 +01:00
6bd5bf3cb5 lvmlockd: fix check for other sanlock lockspaces
The check for other sanlock lockspaces was not checking
that the lockspace type was sanlock, so if dlm lockspaces
were visible, they were wrongly included.
2015-08-10 13:16:04 -05:00
1aa7fa354e vgremove: fix locking when lvmlockd global lock is removed
When vgremove is used to remove multiple VGs in one command,
e.g. vgremove foo bar, the first VG (foo) that is removed
may have held the sanlock global lock.  In this case,
do not continue removing further VGs (bar) without the
global lock.
2015-08-10 13:04:11 -05:00
5383697c78 post-release 2015-08-10 01:02:31 +01:00
0b05048341 pre-release 2015-08-10 00:40:42 +01:00
41001dbfdd dmsetup: Also install dmstats. 2015-08-10 00:35:15 +01:00
d62a8d2f15 dmstats: add libdm-stats library and 'dmsetup stats' command
Add the libdm-stats module to libdm: this implements a simple interface
for creating, managing and interrogating I/O statistics regions and
areas on device-mapper devices.

The library interface is documented in libdevmapper.h and provides a
'dm_stats' handle that is used to perform statistics operations and
obtain data.

Public methods are provided to create and destroy handles and to list,
create, and destroy statistics regions as well as to obtain and parse
counter data and calculate rate-based metrics.

This commit also adds a 'dmsetup stats' (aka 'dmstats') command with
'clear', 'create', 'delete', 'list', 'print', and 'report' sub-commands.

See the library documentation and the dmstats.8 manual page for detailed
API and command descriptions.
2015-08-09 14:37:58 +01:00
f06d866110 WHATS_NEW_DM: Update for preliminary stats commits
Add entries for dm_report_column_headings() and report row leaks
and remove the dm_report interval/wait entry.
2015-08-08 17:48:30 +01:00
3638c05ec9 libdm: do not attempt to output column headings with --rows
Columns-as-rows output does not use _report_headings(); don't
try to call it when rh->flags & DM_REPORT_OUTPUT_COLUMNS_AS_ROWS.
2015-08-08 17:48:30 +01:00
54815fff06 libdm: remove report interval support
Don't do interval management and external timekeeping for stats in
dm_report: let applications handle this on their own.

Since this has not been included in a release remove it from the
library entirely and handle report timing directly inside dmsetup.
2015-08-08 11:48:12 +01:00
666c77c0f2 libdm: add dm_report_column_headings
Add a function to print column headings regardless of whether they
have already been output. This will be used by dmstats to issue
periodic reminders of the column headings.

This patch removes a check for RH_HEADINGS_PRINTED from
_report_headings that prevents headings being displayed if the flag
is already set; this check is redundant since the only existing
caller (_output_as_columns()) already tests the flag before
calling the function.
2015-08-08 11:43:52 +01:00
cafe145ba2 libdm: fix report rows and headings memory and state leaks
Not releasing objects back to the pool is fine for short-lived
pools since the memory will be freed when dm_pool_destroy() is
called.

Any pool that may be long-lived needs to be more careful to free
objects back to the pool to avoid leaking memory that will not be
reclaimed until the pool is destroyed at process exit time.

The report pool currently leaks each headings line and some row
data.

Although dm_report_output() tries to free the first allocated row
this may end up freeing a later row due to sorting of the row list
while reporting. Store a pointer to the first allocated row from
_do_report_obect() instead and free this at the end of
_output_as_columns(), _output_as_rows(), and dm_report_clear().

Also make sure to call dm_pool_free() for the headings line built
in _report_headings().

When dmstats is introduced it will maintain dm_report objects for
the whole lifetime of the process: without these changes a stats
report could leak around 600k in 10m (exact rate depends on field
selection and data values):

 top - 12:11:32 up 4 days,  3:16, 15 users,  load average: 0.01, 0.12, 0.14
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 6473 root      20   0  130196   3124   2792 S   0.0  0.0   0:00.00 dmstats

 top - 12:22:04 up 4 days,  3:26, 15 users,  load average: 0.06, 0.11, 0.13
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 6498 root      20   0  130836   3712   2752 S   0.0  0.0   0:00.60 dmstats

With this patch no increase in RSS is seen:

 top - 13:54:58 up 4 days,  4:59, 15 users,  load average: 0.12, 0.14, 0.14
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
13962 root      20   0  130196   2996   2688 S   0.0  0.0   0:00.00 dmstats

 top - 14:04:31 up 4 days,  5:09, 15 users,  load average: 1.02, 0.67, 0.36
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
13962 root      20   0  130196   2996   2688 S   0.3  0.0   0:00.32 dmstats

This also affects report output for repeating reports in the
DM_REPORT_OUTPUT_COLUMNS_AS_ROWS case; row state is not fully cleared for
the next iteration leading to progressive growth of the heading width:

vg_hex-lv_home:vg_hex-lv_swap:vg_hex-lv_root:luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e:vg_hex-lv_images
253:253:253:253:253
2:0:1:4:3
L--w:L--w:L--w:L--w:L--w
1:2:1:1:1
3:1:1:1:2
0:0:0:0:0
LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOiv08BCGvF4WsJSqWUDUt7qtf2hEmjtVvo:LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOiKf7XIiwdAYOJfaGhQe9fu26cTEICGgFS:LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOiEZj7ZXbmrWDuGhd7vvi88VF0NdTMG8iA:CRYPT-LUKS1-797339213f684c929eb7d0aca4c6ba3e-luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e:LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOi2rKredlBPnw2X7v1BiCuEpFo6gaE7BRw

:::::vg_hex-lv_home:vg_hex-lv_swap:vg_hex-lv_root:luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e:vg_hex-lv_images
:::::253:253:253:253:253
:::::2:0:1:4:3
:::::L--w:L--w:L--w:L--w:L--w
:::::1:2:1:1:1
:::::3:1:1:1:2
:::::0:0:0:0:0
:::::LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOiv08BCGvF4WsJSqWUDUt7qtf2hEmjtVvo:LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOiKf7XIiwdAYOJfaGhQe9fu26cTEICGgFS:LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOiEZj7ZXbmrWDuGhd7vvi88VF0NdTMG8iA:CRYPT-LUKS1-797339213f684c929eb7d0aca4c6ba3e-luks-79733921-3f68-4c92-9eb7-d0aca4c6ba3e:LVM-9t8ITqLZa6AuuyVoz5Olp1KwF9ZDBfOi2rKredlBPnw2X7v1BiCuEpFo6gaE7BRw
2015-08-08 11:35:10 +01:00
974e7b9220 libdm: ensure new dm_timestamp objects are initialized
Allocate a dm_timestamp with dm_zalloc() to ensure the memory is
initialized to a known state.
2015-08-08 10:42:14 +01:00
b59cdf0892 man: mention system ID in vgexport and vgimport 2015-08-07 16:35:07 -05:00
993fe07a3c man: add lockd bits to relevant commands 2015-08-07 16:25:00 -05:00
2bbf2fa8eb man lvmlockd: update 2015-08-07 15:18:44 -05:00
1c013e7ae2 man lvmcache: mention LVs must be in the same VG 2015-08-06 10:06:21 -05:00
fd1782b5fc lvmlockd: handle loss of sanlock lease storage
This adds the infrastructure, code paths, error reporting,
etc. to handle storage errors, or storage loss, under the
sanlock leases in a VG that is being used.  The loss of
storage means sanlock cannot renew its leases, which means
that the host needs to stop using the shared VG before its
leases expire.

This still requires manually shutting down a VG that has
lost lease storage, e.g. unmounting file systems,
deactivating LVs in the VG.  The next step is to
automatically use a command like blkdeactivate to do that.
2015-08-05 10:21:45 -05:00
559ca8bc65 dmsetup: Report timestamps of ioctls with -vvv.
If enabled, record timestamp immediately after the ioctl() returns.
2015-08-05 08:28:35 +01:00
2f334afb98 libdm: Whitespace. 2015-08-05 05:21:58 +01:00
88551add97 libdm: Whitespace. 2015-08-05 05:11:42 +01:00
23e8e849e4 libdm: Sort new exported symbols. 2015-08-05 05:07:45 +01:00
362a1a5a82 dmsetup: Tidy whitespace. 2015-08-05 05:03:33 +01:00
ce1528359a man: document --nameprefixes 2015-08-04 14:03:50 +02:00
f02cdcff00 coverity: check vg->lvm1_system_id is not NULL before calling strncmp with that
lib/format1/import-export.c:167: var_deref_model: Passing null pointer "vg->lvm1_system_id" to "strncmp", which dereferences it.
2015-08-04 10:35:31 +02:00
1f3d04cddf coverity: variable init must be done before its use
tools/polldaemon.c:465: uninit_use_in_call: Using uninitialized value "id.vg_name" when calling "print_log".
tools/polldaemon.c:465: uninit_use_in_call: Using uninitialized value "id.lv_name" when calling "print_log".
2015-08-04 09:51:16 +02:00
c78033233a coverity: return value check in lvmlockd-dlm
daemons/lvmlockd/lvmlockd-dlm.c:647: check_return: Calling "closedir" without checking return value (as is done elsewhere 13 out of 14 times).
2015-08-04 09:49:29 +02:00
83541123c8 coverity: fix cppcheck warnings
/lib/log/log.c:88: warning[invalidScanfArgType_int]: %llu in format string (no. 2) requires 'unsigned long long *' but the argument type is 'long long *'.
daemons/lvmlockd/lvmlockd-core.c:791: error[uninitstring]: Dangerous usage of 'version' (strncpy doesn't always null-terminate it).
2015-08-04 09:33:55 +02:00
46e6b2b86e coverity: fix possible resource leak in lvmpolld-core
/daemons/lvmpolld/lvmpolld-core.c:573: leaked_storage: Variable "cmdargv" going out of scope leaks the storage it points to.
2015-08-04 09:25:47 +02:00
6ac5689ce4 report: also recognize variants without underscores for <prefix>_all fields
For example: "pvs -o pv_all" and pvs -o pvall" are same.
2015-08-04 09:03:31 +02:00
d11f8d4228 lvmlockd: automatically remove the dlm global lockspace
The dlm global lockspace is automatically added when the
first dlm VG lockspace is added.  Reverse this by removing
the dlm global lockspace after the last dlm VG lockspace
is removed.  (Remove old non-working code that did this
based on an old command that could explicitly add/remove
the dlm global lockspace.)
2015-08-03 10:23:01 -05:00
71dbe47619 report: update comment for _is_same_field fn 2015-08-03 16:47:02 +02:00
a5b476a7d3 report: recognize report field name variants without any underscores too
Whenver reporting field name is registered with libdevmapper and if
the field name contains any number of underscores ('_'), libdm
can now automatically recognize any of its variant without any
underscores used.

For example:

..for underscores in prefixes:
  pvs -o pv_name
  pvs -o name
  pvs -o pvname (newly recognized besides pvname)

..for underscores in the name:
  lvs -o cache_mode
  lvs -o cachemode

..or even multiple underscores:
  pvs -o pv___na___me

It's all variant of the same field name.
2015-08-03 16:29:50 +02:00
b3997469b5 toolcontext: do not set cmd->initialized_connections = 0 on destroy_toolcontext
The whole cmd context is freed completely in destroy_toolcontext, so do
not write to any of dead cmd variables.
2015-08-03 16:17:17 +02:00
519c309952 dmsetup: Use argcp and argvp. 2015-07-31 22:53:38 +01:00
a161e29c59 dmsetup: Add --count and --interval to reports.
For example, to monitor active devices every second you can now run
dmsetup info -c --count 0.
2015-07-31 21:59:34 +01:00
72f754e2bc lockd: remove ignorelockingfailure checks
These code paths were effectively unused.  The checks
had been added long ago without any real thought behind
what they should do or be used for.
2015-07-31 15:51:50 -05:00
439a579aa2 vgchange/lvchange: allow deactivation without locking
If locking with lvmlockd has failed, allow LVs to be deactivated.
2015-07-31 14:11:24 -05:00
649c9d4719 dmsetup: Allow commands to have subcommands.
No commands set has_subcommands yet.

Move multiple device loop to separate function because we'll
soon want to call it repeatedly.

(Based on patch from bmr.)
2015-07-31 19:09:31 +01:00
51f89f2fbd dmsetup: Add subcommand parameter.
Not yet used.
Allows for dmsetup stats <subcommand> dev1 dev2...
2015-07-31 17:47:03 +01:00
e06d188f0d dmsetup: _find_command returns const 2015-07-31 16:58:14 +01:00
fef3cb3f21 dmsetup: Add _dmsetup to help and usage fns.
Prepare for dmstats.
Adjust some text to avoid 80-char wrap.
2015-07-31 16:26:38 +01:00
027fe112ec dmsetup: Rename _commands to _dmsetup_commands.
We'll need to accommodate sub-commands for dmstats.
2015-07-31 16:13:45 +01:00
f54198eed6 toolcontext: use refresh_filters in refresh_toolcontext
Use refresh_filters instead of destroy_filters and init_filters
in refresh_toolcontext fn which deals with cmd->initialized.filters
correctly on refresh.
2015-07-31 10:25:36 +02:00
0dae377fbf test: Update Makefiles
- Add missing check_lvmpolld to toplevel Makefile
- Document check_system
2015-07-30 20:39:38 +02:00
8bc90a25c2 spec: lockd_dlm requires dlm-lib instead of dlm 2015-07-30 20:39:38 +02:00
b40ccdd57c lvmlockd: create sanlock lv large enough for existing lvs
When changing an existing VG to lock_type sanlock,
make the sanlock lv large enough to hold all the
locks needed for existing LVs.
2015-07-30 12:04:31 -05:00
78135c24b4 lvmlockd: small fixes and cleanup for lvmlockctl
. clean up the info output for readability
. remove some internal debug output
. fix the daemon quit option
2015-07-30 10:50:22 -05:00
d9c67a9b21 cleanup: toolcontext: move report_list_item_separator into its group 2015-07-30 16:14:10 +02:00
e6834b3237 cleanup: toolcontext: make cmd_context more readable
Just shuffle the items and put them into logical groups so it's
visible at first sight what each group contains - it makes it a bit
easier to make heads and tails of the whole cmd_context monster.
2015-07-30 16:01:02 +02:00
c0629c13fe commands: add new NO_METADATA_PROCESSING flag to selected commands
When a command is flagged with NO_METADATA_PROCESSING flag, it means
such command does not process any metadata and hence it doens't require
lvmetad, lvmpolld and it can get away with no locking too. These are
mostly simple commands (like lvmconfig/dumpconfig, version, types,
segtypes and other builtin commands that do not process metadata
in any way).

At first, when lvm command is executed, create toolcontext without
initializing connections (lvmetad,lvmpolld) and without initializing
filters (which depend on connections init). Instead, delay this
initialization until we know we need this. That is, until the
lvm_run_command fn is called in which we know what the actual
command to run is and hence we can avoid any connection, filter
or locking initiliazation for commands that would not make use
of it anyway.

For all the other create_toolcontext calls, we keep the original
behaviour - the filters and connections are initialized together
with the toolcontext.
2015-07-30 13:56:13 +02:00
f6473baffc toolcontext: add switches to create_toolcontext for connections and filters init
Make it possible to decide whether we want to initialize connections and
filters together with toolcontext creation.

Add "filters" and "connections" fields to struct
cmd_context_initialized_parts and set these in cmd_context.initialized
instance accordingly.

(For now, all create_toolcontext calls do initialize connections and
filters, we'll change that in subsequent patch appropriately.)
2015-07-30 13:54:09 +02:00
3e343ba5ef refactor: toolcontext: move lvmetad and lvmpolld init into separate function
Move original lvmetad and lvmpolld initialization code from
_process_config fn to their own functions _init_lvmetad and
_init_lvmpolld (both covered with single _init_connections fn).
2015-07-30 13:54:09 +02:00
6b0c464a34 refactor: toolcontext: add struct cmd_context_initialized_parts
Add struct cmd_context_initialized_parts to wrap up information
about which cmd context pieces are initialized and add variable
of this struct type into struct cmd_context.

Also, move existing "config_initialized" variable that was directly
part of cmd_context into the new cmd_context.initialized wrapper.

We'll be adding more items into the struct cmd_context_initialized_parts
with subsequent patches...
2015-07-30 13:54:05 +02:00
9aabf441bd vgremove: warn when removing sanlock global lock
When the sanlock VG holding the global lock is removed,
print a warning indicating that the global needs to be
enabled in another sanlock VG.
2015-07-29 14:27:32 -05:00
772b54a08b vgcreate: improve checks for existing global lock
This tries harder to avoid creating duplicate global locks in
sanlock VGs by refusing to create a new sanlock VG with a
global lock if other sanlock VGs exist that may have a gl.
2015-07-29 14:27:32 -05:00
e593213b87 lvmcache: add lock_type to VG summary and info structs
vgsummary information contains provisional VG information
that is obtained without holding the VG lock.  This info
can be used to lock the VG, and then read it with vg_read().
After the VG is read properly, the vgsummary info should
be verified.

Add the VG lock_type to the vgsummary.  It needs to be
known before the VG can be locked and read.
2015-07-29 14:27:32 -05:00
3cd644aeb5 libdm: Require librt for new dm_timestamp. 2015-07-29 19:30:22 +01:00
a28fb37b9e libdm: Add dm_timestamp functions. 2015-07-29 19:21:07 +01:00
a5491d3698 dmsetup: Accept vg/lv name format.
If there is exactly one / which is not the first character, check
for /dev/vg/lv (as dm_dir()/../$name i.e. /dev/mapper/../vg/lv.)
2015-07-29 12:24:36 +01:00
ca0d9a70d1 dmsetup: remove dead code that covered "info -c -o help" case once
The "-o help" is now handled as implicit field and it gets processed
just like any other field - all handled by libdevmapper now.
2015-07-29 13:16:09 +02:00
cf700151eb cache: fix regression causing some PVs to bypass filters
This is a regression introduced by commit
6c0e44d5a2 which changed
the way dev_cache_get fn works - before this patch, when a
device was not found, it fired a full rescan to correct the
cache. However, the change coming with that commit missed
this full_rescan call, causing the lvmcache to still contain
info about PVs which should be filtered now.

Such situation may have happened by coincidence of using
old persistent cache (/etc/lvm/cache/.cache) which does not
reflect the actual state anymore, a device name/symlink which
now points to a device which should be filtered and a fact we
keep info about usable DM devices in .cache no matter what
the filter setting is.

This bug could be hidden though by changes introduced in
commit f1a000a477 as it
calls full_rescan earlier before this problem is hit.
But we need to fix this anyway for the dev_cache_get
to be correct if we happen to use the same code path
again somewhere sometime.

For example, simple reproducer was (before commit
1a000a477558e157532d5f2cd2f9c9139d4f87c):

- /dev/sda contains a PV header with UUID y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M

- lvm.conf: filter = [ "r|.*|" ]

- rm -f .cache (to start with clean state)

- dmsetup create test --table "0 8388608 linear /dev/sda 0" (8388608 is
  just the size of the /dev/sda device I use in the reproducer)

- pvs (this will create .cache file which contains
  "/dev/disk/by-id/lvm-pv-uuid-y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M"
  as well as "/dev/mapper/test" and the target node "/dev/dm-1" - all the
  usable DM mappings (and their symlinks) get into the .cache file even
  though the filter "is set to "ignore all" - we do this - so far it's OK)

- dmsetup remove test (so we end up with /dev/disk/by-id/lvm-pv-uuid-...
  pointing to the /dev/sda now since it's the underlying device
  containing the actual PV header)

- now calling "pvs" with such .cache file and we get:
$ pvs
  PV                                                                 VG  Fmt  Attr PSize PFree
  /dev/disk/by-id/lvm-pv-uuid-y5PzRD-RBAv-7sBx-V3SP-vDmy-DeSq-GUh65M vg  lvm2 a--  4.00g    0

Even though we have set filter = [ "r|.*|" ] in the lvm.conf file!
2015-07-29 10:19:12 +02:00
af1c7bf0c7 libdm: Add dm_size_to_string to libdevmapper.
Moved out from lib/display and a little documentation added.
It's tuned to LVM's requirements historically and its behaviour
might not always be what you would expect.
2015-07-27 21:30:20 +01:00
fa11ddd7df lvmlockd: Drop -lrt now handled by configure. 2015-07-27 14:53:08 +01:00
3e333e9b5c configure: Enable realtime by default, if present. 2015-07-27 14:44:58 +01:00
1568ed4d20 configure: Add missing checks. 2015-07-27 14:26:56 +01:00
3934ade5a2 gitignore: Update for in-place build. 2015-07-27 13:18:35 +01:00
f4fa3e1a6b post-release 2015-07-24 23:39:54 +01:00
ce6a0f4469 post-release 2015-07-24 23:21:51 +01:00
33eb7d7dfb pre-release 2015-07-24 23:20:42 +01:00
705caa8c32 tools: Streamline long option hyphen removal. 2015-07-24 19:45:49 +01:00
c1f5ac3eca lockd: remove an unreachable global lock condition
There is no longer an "enable" option for the global lock,
so remove the bit of code that was checking for it.  It
was an optional variation anyway, and not one that was likely
to be used.

Also update the corresponding comment describing global lock
creation.
2015-07-24 10:56:08 -05:00
bcb875dcb1 Fix dehyphenation cases
Stop removing hyphens when = is seen.  With an option
like --profile=thin-performance, the hyphen removal
will stop at = and will not remove - after thin.

Stop removing hyphens altogether when a stand alone arg
of -- appears.
2015-07-24 10:25:13 -05:00
be66243933 clvmd: Fix freeze if client dies holding locks.
Simply running concurrent copies of 'pvscan | true' is enough to make
clvmd freeze: pvscan exits on the EPIPE without first releasing the
global lock.

clvmd notices the client disappear but because the cleanup code that
releases the locks is triggered from within some processing after the
next select() returns, and that processing can 'break' after doing just
one action, it sometimes never releases the locks to other clients.

Move the cleanup code before the select.
Check all fds after select().
Improve some debug messages and warn in the unlikely event that
select() capacity could soon be exceeded.
2015-07-23 23:10:16 +01:00
57534733b7 lvmlockd: improve check for duplicate global locks
When there are duplicate global locks, check if the gl
is still enabled each time a gl or vg lock is acquired
in the lockspace.  Once one of the duplicates is disabled,
then other hosts will recognize that the issue is resolved
without needing to restart the lockspaces.
2015-07-23 10:39:11 -05:00
1612c570b6 libdm: Use wrappers for all malloc functions.
Move the DEBUG_MEM decision inside libdevmapper.so instead of exposing
it in libdevmapper.h which causes failures if the binary and library
were compiled with opposite debugging settings.
2015-07-22 23:11:48 +01:00
b92e502695 pvscan: skip autoactivation for lockd VGs
pvscan autoactivation does not work for lockd VGs because
lock start is needed on a lockd VG before locking can be
done for it.  Add a check to skip the attempt at autoactivate
rather than calling it, knowing it will fail.

Add a comment explaining why pvscan --cache works fine for
lockd VGs without locks, and why autoactivate is not done.
2015-07-22 15:44:20 -05:00
27e6aee390 lvconvert: merge polling fixes for lockd
. the poll check will eventually call finish which will
  write the VG, so an ex VG lock is needed from lvmlockd.

. fix missing unlock on poll error path

. remove the lockd locking while monitoring the progress
  of the command, as suggested by the earlier FIXME comment,
  as it's not needed.
2015-07-22 12:28:06 -05:00
8bfcefe11a config: add CFG_SECTION_NO_CHECK flag
The CFG_SECTION_NO_CHECK flag can be used to mark a section
and its whole subtree as containing settings where checks
won't be made (lvmconfig --validate).

These are setting where we don't know the names and and type
in advance and they're recognized in runtime. As we don't know
the type and name in advance, we can't do any checks here
of course.

Use this flag with great care as it disables config checks
for the whole config subtree found under such section.

This flag is going to be used by subsequent patches from
Zdenek to support some cache settings...
2015-07-22 14:25:42 +02:00
00d24511bc lvconvert: remove unused struct members 2015-07-22 12:56:43 +02:00
03762f42c1 lvconvert: retain retcode consistency
Always return the highest retcode caught during convert command
(regression in commit ae88bf03a1).
Also minor code cleanup.
2015-07-22 12:26:46 +02:00
ae88bf03a1 lvconvert: fix polling outside of core lvconvert
Recent change to move the polling outside of core lvconvert
code was wrongly using 'lv' and 'vg' structs which can't be
used outside of the core code, which caused seg fault.

Properly isolate all use of lv structs within the core of
the lvconvert code, saving any information necessary,
(esp lvid).  After the core of lvconvert is done, use
the saved information to do polling.

FIXME: the need for is_merging_origin and is_merging_origin_thin
in this patch is ugly, and a cleaner way should be found to deal
with that than what is done here.

Also it effectively removed all hacks in _lvconvert_merge_single
performing ugly: VG reread, unlock, polling, lock sequence.

Moreover all polling operations are postponed after all conversions
are finished.

lvm2 (while locking via lvmlockd) should now be able to run with
or without lvmpolld while performing poll operations originating
in lvconvert command.

Signed-off-by: Ondrej Kozina <okozina@redhat.com>
2015-07-22 10:38:02 +02:00
c3fddb0fbb wiping: add "Wiping skipped." for the message context to be complete 2015-07-21 11:00:43 +02:00
697fb353dc wiping: log_warn instead of log_error if blkid wipe ignored for a signature
Comply with the rules we have for log_error and log_warn...

$ pvcreate /dev/sda1
  Failed to get offset of the xfs_external_log signature on /dev/sda1.
  1 existing signature left on the device.
  Aborting pvcreate on /dev/sda1.

$ pvcreate /dev/sda1 --force
  WARNING: Failed to get offset of the xfs_external_log signature on /dev/sda1.
  Physical volume "/dev/sda1" successfully created
2015-07-21 10:34:04 +02:00
2a7c2539c6 wiping: ignore errors during detection if use_blkid_wiping=1 and --force is used
libblkid may return the list of signatures found, but it may not
provide offset and size for each signature detected. This may
happen in case signatures are mixed up or there are more, possibly
overlapping, signatures found.

Make lvm commands pass if such situation happens and we're using
--force (or any stronger force method).

For example:

$ pvcreate /dev/sda1
  Failed to get offset of the xfs_external_log signature on /dev/sda1.
  1 existing signature left on the device.
  Aborting pvcreate on /dev/sda1.

$ pvcreate --force /dev/sda1
  Failed to get offset of the xfs_external_log signature on /dev/sda1.
  Physical volume "/dev/sda1" successfully created
2015-07-21 09:54:20 +02:00
500fd8b9bf log: Add DM_ABORT_ON_INTERNAL_ERRORS lvm override.
Recognise DM_ABORT_ON_INTERNAL_ERRORS in the lvm logging function as
well as the default dm function it replaces.
2015-07-20 15:48:59 +01:00
b4be988732 vgchange/lvchange: enforce the shared VG lock from lvmlockd
The vgchange/lvchange activation commands read the VG, and
don't write it, so they acquire a shared VG lock from lvmlockd.
When other commands fail to acquire a shared VG lock from
lvmlockd, a warning is printed and they continue without it.
(Without it, the VG metadata they display from lvmetad may
not be up to date.)

vgchange/lvchange -a shouldn't continue without the shared
lock for a couple reasons:

. Usually they will just continue on and fail to acquire the
  LV locks for activation, so continuing is pointless.

. More importantly, without the sh VG lock, the VG metadata
  used by the command may be stale, and the LV locks shown
  in the VG metadata may no longer be current.  In the
  case of sanlock, this would result in odd, unpredictable
  errors when lvmlockd doesn't find the expected lock on
  disk.  In the case of dlm, the invalid LV lock could be
  granted for the non-existing LV.

The solution is to not continue after the shared lock fails,
in the same way that a command fails if an exclusive lock fails.
2015-07-17 15:35:34 -05:00
b785a50da4 test: Help, default and relative paths in runner
Add help message.
Handle relative paths first.
Use `.` for OUTDIR instead of `/` if empty.
2015-07-17 20:36:50 +02:00
2bc0525e93 test: Fix hardcoded /usr/share in testsuite 2015-07-17 20:36:50 +02:00
85b42d7c95 lvmlockd: improve errors when lvm is built without a lock manager
When lvmlockd is compiled without support for one of the
lock managers (sanlock or dlm), and a command tries to use
one of them, explain that in the error message.
2015-07-17 11:16:18 -05:00
c7fc06a262 test: Ignore known concurrent VG clvmd failure.
Don't abort test when clvmd processes two VGs concurrently.
  CLVMD: ioctl/libdm-iface.c:1940   Internal error: Performing unsafe table load while 3 device(s) are known to be suspended:  (253:19)
2015-07-17 12:56:52 +01:00
268f53ed0d lockd: fix error cases when built without lvmlockd
When lvm is built without lvmlockd support, vgcreate using a
shared lock type would succeed and create a local VG (the
--shared option was effectively ignored).  Make it fail.

Fix the same issue when using vgchange to change a VG to a
shared lock type.

Make the error messages consistent.
2015-07-16 15:22:06 -05:00
b93b85378d alloc: Fix lvextend failure when varying stripes.
A segfault was reported when extending an LV with a smaller number of
stripes than originally used.  Under unusual circumstances, the cling
detection code could successfully find a match against the excess
stripe positions and think it had finished prematurely leading to an
allocation being pursued with a length of zero.

Rename ix_offset to num_positional_areas and move it to struct
alloc_state so that _is_condition() can obtain access to it.

In _is_condition(), areas_size can no longer be assumed to match the
number of positional slots being filled so check this newly-exposed
num_positional_areas directly instead.  If the slot is outside the
range we are trying to fill, just ignore the match for now.

(Also note that the code still only performs cling detection against
the first segment of the LV.)
2015-07-15 23:12:54 +01:00
e15db15926 vgimport: fix the all VGs case
The ALL_VGS_IS_DEFAULT flag was wrongly removed;
it is needed for vgimport -a to work.
2015-07-15 09:26:10 -05:00
2972604f0c vgexport: fix the all VGs case
The ALL_VGS_IS_DEFAULT flag was wrongly removed;
it is needed for vgexport -a to work.
2015-07-15 09:23:30 -05:00
d947a815e8 config: make a difference between "not found" and "is empty" in log msg for devices/preferred_names
Replace misleading "not found" in the log message when
devices/preferred_names is set to empty array:

Really not found:
device/dev-cache.c:689   devices/preferred_names not found in config: using built-in preferences

Found, but empty:
config/config.c:1431   Setting devices/preferred_names to preferred_names = [ ]
device/dev-cache.c:689   devices/preferred_names is empty: using built-in preferences
2015-07-15 16:14:51 +02:00
d10fb73f63 config: also log the value used if defined in config, not just defaults
Commit 7e728fe1a1 added a log call
directly in find_config_tree_array when defaults are used.

This patch also adds the log for the value which is found in
existing configuration and for which defaults are not used.

For example:

Defaults used:
config/config.c:1428   devices/scan not found in config: defaulting to scan = [ "/dev" ]

Value defined in configuration used:
config/config.c:1431   Setting devices/scan to scan = [ "/dev", "/mydev", "/abc" ]

This makes the logging consistent with the other find_config_tree_* functions.
2015-07-15 16:02:20 +02:00
64c4106219 cleanup: drop unused header file 2015-07-15 13:10:22 +02:00
c45e6e3c78 cleanup: avoid double assign
Variable n1 is assigned without using n1 before.
2015-07-15 13:10:22 +02:00
a7101e7bfb cleanup: drop duplicated seg test
Test is already in seg_is_pool() if branch.
and one minor indent fix.
2015-07-15 13:10:22 +02:00
beb65056cf makefiles: adding target for generating ctags
make tags generates traditional tags ctags ref list.
2015-07-15 13:10:22 +02:00
c2d4330f27 cache: enhance cache-pool validation
Capture cache-pool without cache policy name set.
2015-07-15 13:10:22 +02:00
077645476c cache: capture missing policy name
Policy name has to be always defined.
Capture it as an internal error before write.
When reading metadata without defined policy name, use default defined policy.

TODO: Unsure, but it might have to be actually always 'mq' in this case.
2015-07-15 13:10:22 +02:00
e9e35b011e cache: handle policy_name separately
Keep policy name separate from policy settings and avoid
to mangling and demangling this string from same config tree.
Ensure policy_name is always defined.
2015-07-15 13:10:22 +02:00
86a4d47215 cache: move setting of cache policy
Set policy before saving 1st. metadata and avoid unnecessary reload.
Fixes problem when we stored cache-pool without cache-policy set.
2015-07-15 13:10:21 +02:00
4a33d57143 thin: fix warning for overprovisioning
When lvm.conf is properly configure for auto resize of overprovisioned
thin-pool volume, avoid showing any warning (2.02.124).
2015-07-15 13:10:21 +02:00
34a4109946 config: use find_config_tree_array for all arrays
Use find_config_tree_array for all config arrays. Also, add
INTERNAL_ERROR in case there should have been at least default
value defined for a setting but it was not returned for some
reason (either config_settings.h misconfiguration or other config
tree error printed by functions called by find_config_tree_array).
2015-07-15 10:52:23 +02:00
7e728fe1a1 config: add "defaulting to" message in case we fall back to defaults in find_config_tree_array 2015-07-15 10:50:57 +02:00
96a883a454 metadata: change function name to _allow_extra_system_id
The previous name was misleading since this is not the
primary system_id check, only the "extra" check.
2015-07-14 14:43:16 -05:00
9ab6bdce01 vgchange: fix lock-start filtering and waiting
Both lock_start filters were being skipped when any lock-opt
values were used.  The "auto" lock-opt should cause the
auto_lock_start_list to be used.  The lock_start_list should
always be used.

The behavior of lock_start_list/auto_lock_start_list are tested
and verified to behave like volume_list/auto_activation_volume_list.

Since the default was changed to wait for lock-start to finish,
the "wait" and "autowait" lock-opt values are not needed, but a
new "autonowait" is added to the existing "nowait" avoid the
default waiting.
2015-07-14 14:39:34 -05:00
681f779a3c lockd: fix error message after a failing to get lock
There are two different failure conditions detected in
access_vg_lock_type() that should have different error
messages.  This adds another failure flag so the two
cases can be distinguished to avoid printing a misleading
error message.
2015-07-14 11:36:04 -05:00
ac3143c093 config: {thin,cache}_{check,repair}_options are never undefined
Require global/{thin,cache}_{check,repair}_options to be always defined.
If not defined directly by user in the configuration and if there's no
concrete default option to use, make "" (empty string) the default one -
it's then clearly visible in the "lvmconfig --type default" (and
generated lvm.conf) and also it makes its handling in the code more
straightforward so we don't need to handle undefined values.

This means, if there are no default values for these settings defined,
we end up with this generated now:
  {thin,cache}_{check,repair}_options = [ "" ]

So the value is never undefined and if it is, it's an error.

(The cache_repair_options is actually not used in the code at the moment,
but once the code using this setting is in, it will follow the same logic
as used for thin_repair_options.)
2015-07-14 10:13:41 +02:00
d41bab4028 man lvmlockd: update method for changing lock type
The old description did not work.
2015-07-13 16:33:58 -05:00
3da88b8917 lockd: allow vgexport and vgimport
The "exported" state of the VG can be useful with lockd VGs
because the exported state keeps a VG from being used in general.
It's a way to keep a VG protected and out of the way.

Also fix the command flags: ALL_VGS_IS_DEFAULT is not true for
vgimport/vgexport, since they both return errors immediately if
no VG args are specified.  LOCKD_VG_SH is not true for vgexport
beause it must use an ex lock to write the VG.
2015-07-13 14:07:57 -05:00
9cfa27f9c5 lockd: allow nolocking and readonly options
When --nolocking is used (by vgs, lvs, pvs):

. don't use lvmlockd at all (set use_lvmlockd to 0)
. allow lockd VGs to be read

When --readonly is used (by vgs, lvs, pvs, vgdisplay, lvdisplay,
pvdisplay, lvmdiskscan, lvscan, pvscan, vgcfgbackup):

. skip actual lvmlockd locking calls
. allow lockd VGs to be read
. check that only shared gl/vg locks are being requested
  (even though the actually locking is being skipped)
. check that no LV locks are requested, because no LVs
  should be activated or used in readonly mode
. disable using lvmetad so VGs are read from disk

It is important to note the limited commands that accept
the --nolocking and --readonly options, i.e. no commands
that change/write a VG or change/activate LVs accept these
options, only commands that read VGs.
2015-07-13 13:15:51 -05:00
c39f3026a8 vgexport: do not allow lockd VG to be exported
vgexport and vgimport have no use for a shared VG.
2015-07-10 15:53:21 -05:00
222bb2b88d lockd: note that external origins don't work in lockd VGs
in a comment at the point where it fails, and in the
lvmlockd man page.
2015-07-10 15:53:21 -05:00
b8538f5dcd vgchange: allow changing to lockd type when mirrors exist
and update lvmlockd man page to reflect the fact that
mirror LVs work correctly in lockd VGs.
2015-07-10 15:53:21 -05:00
c4fdcb04be lvconvert: disallow splitting in lockd VGs
A new lockd lock needs to be created for the new LV
created by split mirror and split snapshot.  Disallow
these options in lockd VGs until that is implemented.
2015-07-10 15:53:21 -05:00
0823511262 lockd: disable part of lock_args validation
There are at least a couple instances where
the lock_args check does not work correctly,
(listed in the comment), so disable the
NULL check for lock_args until those are
resolved.
2015-07-10 15:53:21 -05:00
738ae4a77f lvmpolld: Fix segfault on 32 bit architectures
Explicit conversions are needed to align writes and reads on the stack.
int64_t is popped from stack while int was pushed.
2015-07-10 16:16:57 +02:00
47ac6a1a2e test: Fix syntax error in prepare_devs 2015-07-10 16:15:15 +02:00
3d2c4dc034 metadata: fix duplicated LV flag
LOCKD_SANLOCK_LV was using the WRITEMOSTLY flag instead of a new one.
2015-07-09 17:02:30 -05:00
082fcc53cc vgchange: fix disallowed LV types in lockd VG
cow snapshots work in lockd VG (they were wrongly
disallowed), but mirror type LVs do not yet work in
lockd VGs (they were wrongly allowed).
2015-07-09 16:34:23 -05:00
074295245b pvcreate: remove recent warning message
log_warn was added recently because no known code used
the given condition, but running pvcreate on an existing
PV uses this case, and should not produce a warning.
2015-07-09 15:26:32 -05:00
cb14bbdbc9 metadata: add comments describing lock_args for lvmlockd 2015-07-09 15:16:28 -05:00
841c3478fd metadata: vg_validate lock_args 2015-07-09 13:25:00 -05:00
6294509cc6 coverity: cleanup related to lvmlockd
A couple missing mutex unlock on error bugs.
A bunch of buffer size/termination warnings.
2015-07-09 11:29:28 -05:00
1481125042 libdaemon: config_make_nodes_v needs fixing
Put the change from commit #10d27998b3d2f6100e9e29e83d1d99948c55875f
back so we have working tree again for now. This code needs a bit of
a cleanup to return proper return value to check...
2015-07-09 16:34:08 +02:00
10d27998b3 coverity: missing return value checks 2015-07-09 15:15:15 +02:00
a9a7c297ae coverity: missing return value for dm_split_lvm_name pass proper DM name instead of NULL value 2015-07-09 13:11:57 +02:00
023cf21848 coverity: fix possible invalid dereferences
lib/format1/import-export.c:167: var_deref_op: Dereferencing null pointer "vg->lvm1_system_id"
lib/cache/lvmetad.c:1023: var_deref_op: Dereferencing null pointer "this"
daemons/lvmlockd/lvmlockd-core.c:2659: check_after_deref: Null-checking "act" suggests that it may be null, but it has already been dereferenced on all paths leading to the check
/daemons/lvmetad/lvmetad-core.c:1024: check_after_deref: Null-checking "pvmeta" suggests that it may be null, but it has already been dereferenced on all paths leading to the check
2015-07-09 12:07:41 +02:00
cb305b9fc0 lvmconf: fix ignored --startstopservices in lvmconf ... --mirrorservice on systemd
If running lvmconf ... --startstopservice --mirrorservice in systemd
environment, handle lvm2-cmirrord accordingly. A typo in the script
caused the lvm2-cmirrord to not start/stop immediately, it was
only enabled/disabled (so the --startstopservice was ignored in this
case).
2015-07-09 10:40:14 +02:00
a0cc570f86 vgchange: don't disable VG lock in lock_stop
It was an optimization to avoid a pointless unlock call.
It affects all VGs, but was only intended to affect the
VG being stopped.
2015-07-08 15:26:25 -05:00
903569d533 lvmlockd: remove log_error instances for normal conditions
There are a number of log_error instances that are replaced
by log_debug because they are not errors.
2015-07-08 15:25:14 -05:00
d77546773b man: add lvmlocal.conf to config cascade
see BZ 1241182, lvmlocal is searched before lvm.conf but after
lvm_<tag>.conf.
2015-07-08 10:02:28 -07:00
de13abdfdf lvmlockd: fix unreachable code 2015-07-08 11:02:11 -05:00
2566bdfbc3 lvmlockctl: fix uninitialized names
When formatting and printing info from lvmlockd.
Also fix some new line problems.
2015-07-08 10:58:56 -05:00
143a9d7ee6 toollib: skip processing the sanlock LV unless named or all
This prevents 'lvremove vgname' from attempting to remove the
hidden sanlock LV.  Only vgremove should remove the hidden
sanlock LV holding the sanlock locks.
2015-07-08 10:27:21 -05:00
6e1f421a6d tests: follow symlinks
If the srcdir itself is a symlink the find would not return expected
value. So support also this config and use -L.
2015-07-08 15:41:48 +02:00
fd37eeddd6 coverity: fix regresions from 16e9b32c2f
16e9b32c2f incorrectly moved
free of opened descriptor out of if{} - resulted of
closing random file handle.
2015-07-08 15:41:48 +02:00
6b48233f25 coverity: fix NULL check in lv->lvid.s
tools/polldaemon.c:457: array_null: Comparing an array to null is not useful: "lv->lvid.s"

The lv->lvid.s is never NULL. The check was supposed to be *lv->lvid.s
to check if the string is not empty.
2015-07-08 15:08:39 +02:00
3ec4813ba2 coverity: fix missing initialization
... Using uninitialized value "lockd_state" when calling "lockd_vg"
(even though lockd_vg assigns 0 to the lockd_state, but it looks at
previous state of lockd_state just before that so we need to have
that properly initialized!)

libdm/libdm-report.c:2934: uninit_use_in_call: Using uninitialized value "tm". Field "tm.tm_gmtoff" is uninitialized when calling "_get_final_time".

daemons/lvmlockd/lvmlockctl.c:273: uninit_use_in_call: Using uninitialized element of array "r_name" when calling "format_info_r_action". (just added FIXME as this looks unfinished?)
2015-07-08 14:53:30 +02:00
e8dbaf62d3 coverity: previous commit - not "break" but "fall through" 2015-07-08 14:42:31 +02:00
705fee709f coverity: missing break in switch expression
lib/lvmpolld/lvmpolld-client.c:109: fallthrough: The above case falls through to this one
2015-07-08 14:36:02 +02:00
71f4fbfbde coverity: fix uninitialized values and other reported problems
daemons/lvmlockd/lvmlockd-core.c:5709: error[uninitStructMember]: Uninitialized struct member: ds.....
daemons/lvmlockd/lvmlockd-core.c:799: error[uninitstring]: Dangerous usage of 'version' (strncpy doesn't always null-terminate it)
daemons/lvmlockd/lvmlockd-core.c:646: error[memleakOnRealloc]: Common realloc mistake: 'pollfd' nulled but not freed upon failure
2015-07-08 14:19:51 +02:00
16e9b32c2f coverity: fix resource leaks
lib/log/log.c:115: leaked_storage: Variable "st" going out of scope leaks the storage it points to
daemons/lvmpolld/lvmpolld-core.c:573: leaked_storage: Variable "cmdargv" going out of scope leaks the storage it points to
daemons/lvmlockd/lvmlockd-core.c:5341: leaked_handle: Handle variable "fd" going out of scope leaks the handle
daemons/lvmlockd/lvmlockctl.c:575: overwrite_var: Overwriting "able_vg_name" in "able_vg_name = strdup(optarg)" leaks the storage that "able_vg_name" points to
daemons/lvmlockd/lvmlockctl.c:571: overwrite_var: Overwriting "able_vg_name" in "able_vg_name = strdup(optarg)" leaks the storage that "able_vg_name" points to
daemons/lvmlockd/lvmlockctl.c:385: leaked_handle: Handle variable "s" going out of scope leaks the handle
2015-07-08 13:56:06 +02:00
3b6840e099 config: replace find_config_tree_node with find_config_tree_array where appropriate 2015-07-08 13:03:08 +02:00
67a61cce1b config: add find_config_tree_array
Before, we used general find_config_tree_node function to retrieve
array values. This had a downside where if the node was not found,
we had to insert default values directly in-situ after the
find_config_tree_node call. This way, we had two copies of default
values - one in config_settings.h and the other one directly in the
code where we found out that find_config_tree_node returned NULL and
hence we needed to fall back to defaults.

With separate find_config_tree_array used for array config values,
we keep all the defaults centrally in config_settings.h because
the new find_config_tree_array automatically returns these defaults
if it can't find any value set in the configuration.

This patch just makes the behaviour exactly the same for arrays as
for any other non-array type where we call find_config_tree_<type>
already, hence making the internal interface for handling array
values consistent with the rest of the config types.
2015-07-08 12:59:22 +02:00
d9d47b7b88 spec: Move lvm2-lockd into separate package 2015-07-07 16:53:19 +02:00
181e701cc5 spec: Update to use enable_lockd_* 2015-07-07 16:53:19 +02:00
a421879bb5 post-release 2015-07-07 13:57:13 +01:00
3472910177 pre-release 2015-07-07 13:54:37 +01:00
088ee7618d lvmpolld: fix possible memory corruption with mem debug
if lvm2 is built with debug memory options dm_free() is not
mapped directly to std library's free(). This may cause memory corruption
as a line buffer may get reallocated in getline with realloc.

This is a temporary hotfix. Other debug memory failure needs to
be investigated and explained.
2015-07-07 14:49:53 +02:00
a405b89555 conf: regenerate 2015-07-07 14:27:00 +02:00
88760141da WHATS_NEW: Update. Fix renamed config setting vsn. 2015-07-07 13:20:01 +01:00
b174c27d4d conf: regenerate 2015-07-07 14:11:16 +02:00
bfd0689d64 tests: use old snapshot for huge volumes
Avoid stacking thins over thins.
2015-07-07 09:57:32 +02:00
0ac20a8fdb cache: support clear-needs-check
Support newer cache tool which support new option
--clear-needs-check-flag.

Code does same as for thin_check.
2015-07-07 09:57:27 +02:00
d16332be72 lvmetactl: program to interact with lvmetad
This is not installed; it's only a developer utility
at this point.
2015-07-06 15:54:22 -05:00
6a8cc1dcd4 man lvmlockd: minor updates 2015-07-06 15:32:41 -05:00
c923dee8de configure: Separate sanlock and dlm lock config. 2015-07-06 18:20:20 +01:00
633aea92fb config: remove read_only_lock_modes
It had been added as part of lvmlockd code, but it does
not seem particularly useful.
2015-07-06 11:44:28 -05:00
e1733a6271 lockd: remove unused code for overriding lock modes
including the allow_override_lock_modes setting.

It was not possible to override default lock modes any longer,
since the command line options had already been removed.

A mechanism will probably be required later that puts part of
this back.
2015-07-06 11:44:28 -05:00
114744cee1 config: rename lock_retries lvmlockd_lock_retries
Because it only applies to lvmlockd requests, but
sounded too general.
2015-07-06 11:44:28 -05:00
dfe3eb12d0 include: Standardise around new tool.h. 2015-07-06 17:30:18 +01:00
d3605b81f3 configure: enable building lvmlockd without sanlock or dlm 2015-07-06 11:09:58 -05:00
4daea88516 clean-up: typos s/bellow/below/ 2015-07-06 10:15:11 -05:00
810ab095e6 macros: Wrap PRI with FMT.
Create a set of wrappers with embedded % such as
  #define FMTu64 "%" PRIu64
2015-07-06 15:09:17 +01:00
5fb71bd530 lockd: Clean up spec 2015-07-04 14:36:57 +02:00
dd385eb5ac Build lockd only for Fedora >= 22 and RHEL >= 7 2015-07-04 14:36:57 +02:00
b4e8de3a31 post-release 2015-07-03 16:58:24 +01:00
36ce97c625 pre-release 2015-07-03 16:34:40 +01:00
3dbb9a57ca tests: update for new thin pool messaging 2015-07-03 16:13:15 +02:00
a900d150e4 thin: move pool messaging from resume to suspend
Existing messaging intarface for thin-pool has a few 'weak' points:

* Message were posted with each 'resume' operation, thus not allowing
activation of thin-pool with the existing state.

* Acceleration skipped suspend step has not worked in cluster,
since clvmd resumes only nodes which are suspended (have proper lock
state).

* Resume may fail and code is not really designed to 'fail' in this
phase (generic rule here is resume DOES NOT fail unless something serious
is wrong and lvm2 tool usually doesn't handle recovery path in this case.)

* Full thin-pool suspend happened, when taken a thin-volume snapshot.

With this patch the new method relocates message passing into suspend
state.

This has a few drawbacks with current API, but overal it performs
better and gives are more posibilities to deal with errors.

Patch introduces a new logic for 'origin-only' suspend of thin-pool and
this also relates to thin-volume when taking snapshot.

When suspend_origin_only operation is invoked on a pool with
queued messages then only those messages are posted to thin-pool and
actual suspend of thin pool and data and metadata volume is skipped.

This makes taking a snapshot of thin-volume lighter operation and
avoids blocking of other unrelated active thin volumes.

Also fail now happens in 'suspend' state where the 'Fail' is more expected
and it is better handled through error paths.

Activation of thin-pool is now not sending any message and leaves upto a tool
to decided later how to finish unfinished double-commit transaction.

Problem which needs some API improvements relates to the lvm2 tree
construction. For the suspend tree we do not add target table line
into the tree, but only a device is inserted into a tree.
Current mechanism to attach messages for thin-pool requires the libdm
to know about thin-pool target, so lvm2 currently takes assumption, node
is really a thin-pool and fills in the table line for this node (which
should be ensured by the PRELOAD phase, but it's a misuse of internal API)
we would possibly need to be able to attach message to 'any' node.

Other thing to notice - current messaging interface in thin-pool
target requires to suspend thin volume origin first and then send
a create message, but this could not have any 'nice' solution on lvm2
side and IMHO we should introduce something like 'create_after_resume'
message.

Patch also changes the moment, where lvm2 transaction id is increased.
Now it happens only after successful finish of kernel transaction id
change. This change was needed to handle properly activation of pool,
which is in the middle of unfinished transaction, and also this corrects
usage of thin-pool by external apps like Docker.
2015-07-03 16:13:14 +02:00
5bef18f2eb libdm: support for posting messages in suspend
Add support for sending message in suspend tree for thin-pools.
When this operation is requested whole subtree suspend is then skipped.

This is experimantal support for new lvm2 code for sending message
in suspend phase where 'thin-pool origin-only suspend' will send
messages instead of really suspending thin-pool tree.

When suspening thin volume origin-only - only thin volume is suspended,
then messages are posted and thin-pool suspend is skipped.
2015-07-03 16:13:14 +02:00
622064f00f thin: check for overprovisioning 2015-07-03 16:13:14 +02:00
9cee94372a report: select: add handler to recognize fuzzy time specification
Recognize date and time specification within selection criteria
that is formulated in a more free-form way besides to the original
basic YYYY-MM-DD HH:MM format that libdevmapper supports.

Currently, this free-form format is recognized for lv_time field.

Users are able to use expressions from this set:
  - weekday names ("Sunday" - "Saturday" or abbreviated as "Sun" - "Sat")
  - labels for points in time ("noon", "midnight")
  - labels for a day relative to current day ("today", "yesterday")
  - points back in time with relative offset from today (N is a number)
    ( "N" "seconds"/"minutes"/"hours"/"days"/"weeks"/"years" "ago")
    ( "N" "secs"/"mins"/"hrs" ... "ago")
    ( "N" "s"/"m"/"h" ... "ago")
  - time specification either in hh:mm:ss format or with AM/PM suffixes
  - month names ("January" - "December" or abbreviated as "Jan" - "Dec")

For example:

$ date
Fri Jul  3 10:11:13 CEST 2015

$ lvmconfig --type full report/time_format
time_format="%a %Y-%m-%d %T %z %Z [%s]"

$ lvs
  LV    VG     Time
  lvol0 vg     Fri 2014-08-22 21:25:41 +0200 CEST [1408735541]
  lvol2 vg     Sun 2015-04-26 14:52:20 +0200 CEST [1430052740]
  root  fedora Wed 2015-05-27 08:09:21 +0200 CEST [1432706961]
  swap  fedora Wed 2015-05-27 08:09:21 +0200 CEST [1432706961]
  lvol1 vg     Tue 2015-06-30 03:25:43 +0200 CEST [1435627543]
  lvol3 vg     Tue 2015-06-30 14:52:23 +0200 CEST [1435668743]
  lvol6 vg     Wed 2015-07-01 13:35:56 +0200 CEST [1435750556]
  lvol4 vg     Thu 2015-07-02 12:12:02 +0200 CEST [1435831922]
  lvol5 vg     Thu 2015-07-02 14:30:32 +0200 CEST [1435840232]

$ lvs -S 'time=yesterday'
  LV    VG   Time
  lvol4 vg   Thu 2015-07-02 12:12:02 +0200 CEST [1435831922]
  lvol5 vg   Thu 2015-07-02 14:30:32 +0200 CEST [1435840232]

$ lvs -S 'time since "June 30"'
  LV    VG   Time
  lvol1 vg   Tue 2015-06-30 03:25:43 +0200 CEST [1435627543]
  lvol3 vg   Tue 2015-06-30 14:52:23 +0200 CEST [1435668743]
  lvol6 vg   Wed 2015-07-01 13:35:56 +0200 CEST [1435750556]
  lvol4 vg   Thu 2015-07-02 12:12:02 +0200 CEST [1435831922]
  lvol5 vg   Thu 2015-07-02 14:30:32 +0200 CEST [1435840232]

$ lvs -S 'time since "noon June 30"'
  LV    VG   Time
  lvol3 vg   Tue 2015-06-30 14:52:23 +0200 CEST [1435668743]
  lvol6 vg   Wed 2015-07-01 13:35:56 +0200 CEST [1435750556]
  lvol4 vg   Thu 2015-07-02 12:12:02 +0200 CEST [1435831922]
  lvol5 vg   Thu 2015-07-02 14:30:32 +0200 CEST [1435840232]

$ lvs -S 'time since "2 July 9AM"'
  LV    VG   Time
  lvol4 vg   Thu 2015-07-02 12:12:02 +0200 CEST [1435831922]
  lvol5 vg   Thu 2015-07-02 14:30:32 +0200 CEST [1435840232]

$ lvs -S 'time since "2 July 1PM"'
  LV    VG   Time
  lvol5 vg   Thu 2015-07-02 14:30:32 +0200 CEST [1435840232]

...and so on.
2015-07-03 10:51:31 +02:00
3b1422c45c report: call appropriate handler to evaluate fuzzy reserved names and dynamic reserved values
Wire the dm_report_reserved_handler instance call in reporting/selection
infrastructure to handle reserved value actions (currently only
DM_REPORT_RESERVED_PARSE_FUZZY_NAME and DM_REPORT_RESERVED_GET_DYNAMIC_VALUE
actions).
2015-07-03 10:47:38 +02:00
335707b0e2 report: add infrastructure to recognize fuzzy reserved names and returning dynamic reserved values
With fuzzy names we mean the names for which it's hard or even impossible
to enumerate all possible variations of the name - the name needs to
be evaluated. An example of fuzzy name is a name which has a base
(substring) which matches and it can contain arbitrary variations
around this base. We can cover human language better with fuzzy
names as people may use several different names (or sentences) to
denote the same thing.

With dynamic values we mean the values which are not constants
and they need to be evaluated in runtime. An example of dynamic
value is a value which depends on current system state (e.g. time,
current configuration or any other state which may change and it
needs runtime evaluation).

There's a handler that can be registered with reporting/selection
using dm_report_reserved_handler instance. This is a central point
in which the computation/evaluation happens when processing reserved
values. Currently, there are two actions declared:

  DM_REPORT_RESERVED_PARSE_FUZZY_NAME
  (translates fuzzy name into canonical name)

  DM_REPORT_RESERVED_GET_DYNAMIC_VALUE
  (gets value for canonical name)

The handler is then registered as value in struct
dm_report_reserved_value (see explaining comments besided
the struct dm_report_reserved_value in libdevmapper.h).

Also, this patch provides support for simple caching of values
used during report/selection via dm_report_value_cache_{set,get}.
This is supposed to be used mainly in the dm_report_reserved_handler
instances to save values among calls so all the handler calls work
with the same base value used in computation/evaluation and/or
possibly to save resources if the evaluation is more time-consuming.
The cache is attached to the dm_report handle and so the cache is
dropped one dm_report is dropped.
2015-07-03 10:47:09 +02:00
82ecfa6f0e cleanup: commit fe70b03 turned lv_time to STR, put it back to TIM 2015-07-03 09:22:48 +02:00
e944a9c635 lockd: fix stub functions for LV locking
The stub functions for lockd LV locking were returning
the wrong result when lvm was compiled without lvmlockd.
2015-07-02 16:36:04 -05:00
fe70b03de2 Add lvmlockd 2015-07-02 15:42:26 -05:00
a32d5a4afc report: adjust shared flags based on expected type for reserved values
Generic numbers and time values share some operators so make sure
we have the flags correctly adjusted based on expected type if
we're using reserved values.
2015-07-02 16:12:01 +02:00
eaa0d927a4 tests: add test for 454782f (select with synonyms for string field types) 2015-07-02 11:46:58 +02:00
454782f1a3 report: fix regression while selecting string fields using synonyms
$ lvs -o name,cache_policy vg/lvol0
  LV    Cache Policy
  lvol0

Before this patch:
$ lvs -o name,cache_policy -S 'cache_policy=undefined' vg/lvol0
  (no match)

With this patch applied:
$ lvs -o name,cache_policy -S 'cache_policy=undefined' vg/lvol0
  LV    Cache Policy
  lvol0
2015-07-02 11:31:54 +02:00
7f63fff9c4 display: missed to count with 0
dm_snprintf() returns upon success the number of characters printed
(excluding the null byte used to end output to strings).

So add extra byte to preserve \0.
This fixes regression when displaying more then a single lv name.
2015-07-02 00:10:38 +02:00
21c0b1134f libdm: enhance tracing messages
Use new _node_name() and print name major:minor for thin-pool device.
2015-07-01 13:44:28 +02:00
04ae5007e3 libdm: add helper function to print _node_name
_node_name() prepares into dm_tree internal buffer device
name and it (major:minor) for easy usage for debug messages.

To avoid any allocation a small buffer in struct dm_tree is preallocated
to store this message.
2015-07-01 13:41:40 +02:00
a69ded43b0 config: report/time_format appeared in v2.02.123 2015-07-01 08:20:20 +02:00
4c629a5257 locking: Add missing error handling.
Add missing error logging and detection to unlock_vg and callers
of sync_local_dev_names etc.
2015-06-30 18:54:38 +01:00
3489e68ef7 post-release 2015-06-30 17:12:56 +01:00
a3af8b0626 pre-release 2015-06-30 17:11:21 +01:00
92138badd4 conf: Regenerate.
Fix missing --clear-needs-check-flag.
2015-06-30 17:09:56 +01:00
f6ad48f0e5 libdm: Rename struct time_value variables.
warning: declaration of ‘time’ shadows a global declaration
2015-06-30 16:17:22 +01:00
ded279f826 report: add support for time (basic)
This patch adds support for time values used in reporting fields.
The raw values are always stored as number of seconds since epoch.

The support that comes with this patch is the basic one which allows
only for recognition of strictly formatted date and time in selection
criteria (the format follows a subset of formats defined by ISO 8601):

  date time timezone

  date:
    YYYY-MM-DD (or shortly YYYYMMDD)
    YYYY-MM (shortly YYYYMM), auto DD=1
    YYYY, auto MM=01 and DD=01

  time:
    hh:mm:ss (or shortly hhmmss)
    hh:mm (or shortly hhmm), auto ss=0
    hh (or shortly hh), auto mm=0, auto ss=0

  timezone (always with + or - sign):
    +hh:mm or -hh:mm (or shortly +hhmm or -hhmm)
    +hh or -hh

Or directly the time (number of seconds) since Epoch (1970-01-01 00:00:00 UTC)
when the number value is prefixed by "@":

   @number_of_seconds_since_epoch

This patch also adds aliases for comparison operators
used together with time values which are more intuitive
to use:
  since (as alias for >=)
  after (as alias for >)
  until (as alias for <=)
  before (as alias for <)

For example:

$ lvmconfig --type full report/time_format
time_format="%Y-%m-%d %T %z %Z [%s]"

$ lvs -o name,time vg
  LV    Time
  lvol0 2015-06-28 21:25:41 +0200 CEST [1435519541]
  lvol1 2015-06-30 03:25:43 +0200 CEST [1435627543]
  lvol2 2015-04-26 14:52:20 +0200 CEST [1430052740]
  lvol3 2015-06-30 14:52:23 +0200 CEST [1435668743]

$ lvs vg -o name,time -S 'time since "2015-04-26 15:00" && time until "2015-06-30"'
  LV    Time
  lvol0 2015-06-28 21:25:41 +0200 CEST [1435519541]
  lvol1 2015-06-30 03:25:43 +0200 CEST [1435627543]
  lvol3 2015-06-30 14:52:23 +0200 CEST [1435668743]

$ lvs vg -o name,time -S 'time since "2015-04-26 15:00" && time until "2015-06-30 6:00"'
  LV    Time
  lvol0 2015-06-28 21:25:41 +0200 CEST [1435519541]
  lvol1 2015-06-30 03:25:43 +0200 CEST [1435627543]

$ lvs vg -o name,time -S 'time since @1435519541'
  LV    Time
  lvol0 2015-06-28 21:25:41 +0200 CEST [1435519541]
  lvol1 2015-06-30 03:25:43 +0200 CEST [1435627543]
  lvol3 2015-06-30 14:52:23 +0200 CEST [1435668743]

This is basic time recognition support that is directly a part of
libdevmapper. Recognition of more free-form expressions will be a
part of subsequent patches.
2015-06-30 15:15:10 +02:00
89d355ea04 configure: set DEFAULT_FALLBACK_TO_LVM1 in configure and use it in config_settings.h
Just like we have DEFAULT_USE_LVMETAD (or DEFUALT_USE_LVMPOLLD), use
fallback_to_lvm1=1 lvm.conf setting if we configured lvm2 with
--enable-lvm1-fallback and use fallback_to_lvm1=0 otherwise.

Also, generate proper lvm.conf.in with unconfigured value.
2015-06-30 14:09:05 +02:00
d7b9349ce7 cleanup: report: use internal wrapper for various variables used for handling reserved values
Just a cleanup - wrap several variables we use to handle reserved
values into a structure for easier manipulation in the code.
2015-06-30 10:47:51 +02:00
d8996a17d1 select: add support for range reserved values and flagging named-only values
This patch allows for registration and recognition of reserved
values which are ranges, so they're composed of two values actually
to denote the lower and upper bound for the range (stored as an array
with exactly two items to define the boundaries).

Also, this patch allows for flagging reserved values as named-only
which means that such values are not strictly reserved. The strictly
reserved values are reserved values as used before this patch.

Distinction between strictly-reserved and named-only values
is clearly visible with comparisons. Normally, strictly reserved
value is not accounted for if we do "greater than" or "lower than"
comparisons, for example:

1  2  3 ....
   |
  abc

- we have "abc" as reserved value for field with value "2"
- the value reported for the field is "abc" (or "2", it doesn't matter here)
- the selection we're processing is -S 'field < abc'
- the result of the selection gives nothing as "abc" is strictly
reserved value (bound to "2") and there's no order defined for
it and it would only match if we directly compared the value
(so -S 'field = abc' would match)

With named-only values, the "abc" is named-only value for "2",
so selection -S 'field < abc" is the same as using -S 'field < 2'.
The "abc" is just an alias for some value so the value or its
assigned name can be used equally in selection criteria.
2015-06-30 10:47:50 +02:00
77f0e7a450 cleanup: time: error out on incorrect time_format and indentation in config_settings.h 2015-06-29 16:17:33 +02:00
621398ebb7 lv: time: increase buffer to 4k in lv_time_dup 2015-06-29 15:24:00 +02:00
1587236089 toolcontext: use proper set of chars to check time format against 2015-06-29 14:45:53 +02:00
125cd06698 conf: make time format configurable
Make it possible to define format for time that is displayed.
The way the format is defined is equal to the way that is used
for strftime function, although not all formatting options as
used in strftime are available for LVM2 - the set is restricted
(e.g. we do not allow newline to be printed). The lvm.conf
comments contain the whole list that LVM2 accepts for time format
together with brief description (copied from strftime man page).

For example:
(defaults used - the format is the same as used before this patch)
$ lvs -o+time vg/lvol0 vg/lvol1
  LV    VG   Attr       LSize Time
  lvol0 vg   -wi-a----- 4.00m 2015-06-25 16:18:34 +0200
  lvol1 vg   -wi-a----- 4.00m 2015-06-29 09:17:11 +0200

(using 'time_format = "@%s"' in lvm.conf - number of seconds
since the Epoch)
$ lvs -o+time vg/lvol0 vg/lvol1
  LV    VG   Attr       LSize Time
  lvol0 vg   -wi-a----- 4.00m @1435241914
  lvol1 vg   -wi-a----- 4.00m @1435562231
2015-06-29 14:30:35 +02:00
6f793d34ca config: regenerate lvm.conf.in and lvmlocal.conf.in 2015-06-29 13:43:28 +02:00
7b45a1fc60 refactor: rename _out_tags fn to _out_list and use it for string lists in general 2015-06-29 09:43:55 +02:00
f143ad3a93 cleanup: remove unused tags.c file 2015-06-29 09:43:47 +02:00
e29d4773f4 refactor: rename alloc_printed_tags fn to _alloc_printed_str_list and use it for string lists in general 2015-06-29 09:43:41 +02:00
77c2d11657 refactor: rename read_tags fn to _read_str_list and use it for string lists in general 2015-06-29 09:43:32 +02:00
02767c5eb1 tests: tests needs pre 1.13 thin-pool extorg
This test is testing older style, so disable feature when present.
2015-06-26 22:16:01 +02:00
03c4fee5a7 tests: deactivate before remove
Testing if this avoids udev race with removal of snapshot on some
test machines.
See: https://bugzilla.redhat.com/show_bug.cgi?id=1217819
2015-06-26 22:11:46 +02:00
a62cd64db6 makefiles: avoid bash == operator syntax, use = instead
Commit e587b0677b broke the build on
systems where /bin/sh is Dash, for example.

Origin patch by Ferenc Wágner <wferi@niif.hu>  changed later to
avoid using shell call, so makefile add 'server' target when
one of  metad or polld daemon is requested.
2015-06-26 22:11:45 +02:00
844707067b lvmconfig: do not display settings with undefined default values
Do not display settings with undefined default values, but do display
these settings in case the value is defined directly in any part of
the existing config cascade.

For example, the lvmconfig --type current always displays these settings
(as it's somewhere in "current" configuration cascade that makes it defined).
The lvmconfig --type full displays these settings only if it's defined
somewhere in the cascade, but not if default value is used instead
The lvmconfig --type default never displays these settings...

More concrete example - let's have activation/volume_list directly
set in lvm.conf and activation/read_only_volume_list not set.
Both of these settings have *undefined default* values.

  $lvmconfig --type full activation/volume_list activation/read_only_volume_list
  volume_list="/dev/vg/lv"

(...only volume_list is defined, hence it's printed)

However, the comments will display more info (see also previous commit):

  $lvmconfig --type full activation/volume_list activation/read_only_volume_list --withsummary

  # Configuration option activation/volume_list.
  # Only LVs selected by this list are activated.
  # This configuration option does not have a default value defined.
  # Value defined in existing configuration has been used for this setting.
  volume_list="/dev/vg/lv"

  # Configuration option activation/read_only_volume_list.
  # LVs in this list are activated in read-only mode.
  # This configuration option does not have a default value defined.
2015-06-25 13:51:55 +02:00
07a34184db lvmconfig: display comment about value from existing config being used
Display comment abour value from existing config being used. For example:

$ lvmconfig --type full --withsummary report/compact_output report/buffered

 # Configuration option report/compact_output.
 # Do not print empty report fields.
 # Value defined in existing configuration has been used for this setting.
 compact_output=1

 # Configuration option report/buffered.
 # Buffer report output.
 buffered=1
2015-06-25 13:51:54 +02:00
c794c163b5 lvmconfig: add --type full to display full tree of settings
The lvmconfig --type full is actually a combination of --type current
and --type missing together with --mergedconfig options used.

The overall outcome is a configuration tree with settings as LVM sees
it when it looks for the values - that means, if the setting is defined
in some config source (lvm.conf, --config, lvmlocal.conf or any profile
that is used), the setting is used. Otherwise, if the setting is not
defined in any part of the config cascade, the defaults are used.

The --type full displays exactly this final tree with all the values
defined, either coming from configuration tree or from defaults.
2015-06-25 13:33:52 +02:00
f6de196c21 config: also clone associated id when cloning node using dm_config_clone_node{_with_mem} 2015-06-25 10:21:07 +02:00
110a0745cd man: Add missing env vars to lvm man page. 2015-06-24 20:43:35 +01:00
7760665fb8 libdaemon: add comment about using main and init 2015-06-24 12:16:26 -05:00
44c7bc0262 tests: workaround udev problem
If udev has not removed 'dir' entry - just issue TEST WARNING, clear
dir, but do not fail whole rest of test.
2015-06-24 15:19:53 +02:00
e217873ed6 snapshot: add synchronization point
Synchronize with udev logic before reusing device as snapshot.

This patch tries to fix the problem with udev, where we manage
to 'active' LV for clearing, then we deactivate such device and
active again as member of 'origin&snapshot' tree all in 1 step.

There needs to be a sync point where udev has time to remove all links,
otherwise we race with scans and we may end-up with mysterious 'free'
links in the system pointing to wrong dm names.

This patch tries to fix failing topology cluster tests..
2015-06-24 15:18:49 +02:00
cf189a572a commands: --withspaces also for config and lvmconfig cmd aliases 2015-06-24 13:28:40 +02:00
7559d871fb make: use lvmconfig ... --withspaces when generating lvm.conf and lvmlocal.conf 2015-06-24 13:20:38 +02:00
a4724350e4 lvmconfig: add --withspaces option
We shouldn't be adding spaces by default in output as that
may be be used already in scripts and especially for the eval
in shell scripts where spaces are not allowed between key
and value!

Add --withspaces option to lvmconfig for pretty output with
more space in for readability.
2015-06-24 13:19:23 +02:00
a25d92c88b WHATS_NEW: recent commits - config value format flags 2015-06-24 11:34:02 +02:00
982cf44ff0 config: regenerate configure.in to accomodate all recent changes
Hopefully closer to the ideal.
2015-06-24 11:24:10 +02:00
63c5aaaaf2 config: devices/filter and devices/global_filter setting have 'a/.*/' as default value 2015-06-24 11:23:54 +02:00
c725648f6c config: allow empty values for {thin,cache}_{check,repair}_options
It's not an error to define empty values for
{thin,cache}_{check,repair}_options - such empty value means no
options are passed when these external commands are called.
2015-06-24 11:13:38 +02:00
20e336f21c configure: add DEFAULT_USE_BLKID_WIPING
If blkid wiping is possible, than set use_blkid_wiping=1 and
use_blkid_wiping=0 otherwise for its default value. If blkid wiping
is disabled during configure and use_blkid_wiping=1 is set by chance,
it's simply ignored - this patch is just a cleanup that makes it more
obvious for the user (we use similar logic for use_lvmetad and
use_lvmpolld settings).
2015-06-24 11:13:38 +02:00
6575122c63 config: display global/umask in octal form 2015-06-24 11:13:38 +02:00
74bf75a2f5 config: use proper unconfigured default values for use_lvmetad and use_lvmpolld settings
Default value for lvmetad and lvmpolld has hooks in configure script,
the "lvmconfig --type default --unconfigured" should display:

   use_lvmetad = @DEFAULT_USE_LVMETAD@
   use_lvmpolld = @DEFAULT_USE_LVMPOLLD@

Note that these settings are not of string type. Recent change (the
DM_CONFIG_VALUE_FMT_STRING_NO_QUOTES formatting flag) makes it
possible to recognize that the setting is not of string type and if
there's unconfigured value defined for it, the enclosing " " is
automatically removed on output.
2015-06-24 11:13:38 +02:00
1545ebf938 config: cleanup default values for some configuration settings with array values
Do not use "#S" (blank string) as default value as that ends up with
'key = [ "" ]' to be generated which is not what we want in most cases.

Also, fix default values for global/{thin,cache}_{check,repair}_options
and avoid assigning blank values. For example, the thin_check_options
had this set as default value previously:

  "#S" DEFAULT_THIN_CHECK_OPTION1 "#S" DEFAULT_THIN_CHECK_OPTION2

If any (or both) of DEFAULT_THIN_CHECK_OPTION* variables was set
to "", we ended up with clumsy default value generated like:

  thin_check_options = [ "-q", "" ]

With this patch, we end up with correct:

  thin_check_options = [ "-q" ]

or, if all options are undefined:

  thin_check_options = [ ]

Which is the correct way to express this.
2015-06-24 11:13:38 +02:00
9465963faf config: add support for config value formatting flags
There are two basic groups of formatting flags (32 bits):
  - common ones applicable for all config value types (lower 16 bits)
  - type-related formatting flags (higher 16 bits)

With this patch, we initially support four new flags that
modify the the way the config value is displayed:

  Common flags:
  =============

  DM_CONFIG_VALUE_FMT_COMMON_ARRAY - causes array config values
    to be enclosed in "[ ]" even if there's only one item
    (previously, there was no way to recognize an array with one
     item and scalar value, hence array values with one member
     were always displayed without "[ ]" which libdm accepted
     when reading, but it may have been misleading for users)

  DM_CONFIG_VALUE_FMT_COMMON_EXTRA_SPACE - causes extra spaces to
    be inserted in "key = value" (or key = [ value, value, ... ] in
    case of arrays), compared to "key=value" seen on output before.
    This makes the output more readable for users.

  Type-related flags:
  ===================

  DM_CONFIG_VALUE_FMT_INT_OCTAL - prints integers in octal form with
    "0" as a prefix (libdm's config reading code can handle this via
    strtol just fine so it's properly recognized as number in octal
    form already if there's "0" used as prefix)

  DM_CONFIG_VALUE_FMT_STRING_NO_QUOTES - makes it possible to print
    strings without enclosing " "

This patch also adds dm_config_value_set_format_flags and
dm_config_value_get_format_flags functions to set and get
these formatting flags.
2015-06-24 11:13:37 +02:00
c5ba60827e libdaemon: allow main processing function to be specified 2015-06-23 16:55:45 -05:00
ba2b701f2c doc: mention new invalid states in lvmetad_design 2015-06-23 16:48:28 -05:00
c23e7ff2a0 Reread global state the lvmetad copy is stale
This is the client side handling of the global_invalid state
added to lvmetad in commit c595b50cec8a6b95c6ac4988912d1412f3cc0237.

The function added here:
. checks if the global state in lvmetad is invalid
. if so, scans disks to update the state in lvmetad
. clears the global_invalid flag in lvmetad
. updates the local udev db to reflect any changes
2015-06-23 16:36:40 -05:00
679b6b5b29 Reread a VG if the lvmetad copy is stale
and update the lvmetad copy after it is reread from disk.

This is the client side handling of the vg_invalid state
added to lvmetad in commit c595b50cec8a6b95c6ac4988912d1412f3cc0237.
2015-06-23 16:36:40 -05:00
bf77f71711 lvmetad: add invalidation method
Add the ability to invalidate global or individual VG metadata.
The invalid state is returned to lvm commands along with the metadata.
This allows lvm commands to detect stale metadata from the cache and
reread the latest metadata from disk (in a subsequent patch.)

These changes do not change the protocol or compatibility between
lvm commands and lvmetad.

Global information
------------------

Global information refers to metadata that is not isolated
to a single VG , e.g. the list of vg names, or the list of pvs.

When an external system, e.g. a locking system, detects that global
information has been changed from another host (e.g. a new vg has been
created) it sends lvmetad the message: set_global_info: global_invalid=1.
lvmetad sets the global invalid flag to indicate that its cached data is
stale.

When lvm commands request information from lvmetad, lvmetad returns the
cached information, along with an additional top-level config node called
"global_invalid".  This new info tells the lvm command that the cached
information is stale.

When an lvm command sees global_invalid from lvmated, it knows it should
rescan devices and update lvmetad with the latest information.  When this
is complete, it sends lvmetad the message: set_global_info:
global_invalid=0, and lvmetad clears the global invalid flag.  Further lvm
commands will use the lvmetad cache until it is invalidated again.

The most common commands that cause global invalidation are vgcreate and
vgextend.  These are uncommon compared to commands that report global
information, e.g. vgs.  So, the percentage of lvmetad replies containing
global_invalid should be very small.

VG information
--------------

VG information refers to metadata that is isolated to a single VG,
e.g. an LV or the size of an LV.

When an external system determines that VG information has been changed
from another host (e.g. an lvcreate or lvresize), it sends lvmetad the
message: set_vg_info: uuid=X version=N.  X is the VG uuid, and N is the
latest VG seqno that was written.  lvmetad checks the seqno of its cached
VG, and if the version from the message is newer, it sets an invalid flag
for the cached VG.  The invalid flag, along with the newer seqno are saved
in a new vg_info struct.

When lvm commands request VG metadata from lvmetad, lvmetad includes the
invalid flag along with the VG metadata.  The lvm command checks for this
flag, and rereads the VG from disk if set.  The VG read from disk is sent
to lvmetad.  lvmetad sees that the seqno in the new version matches the
seqno from the last set_vg_info message, and clears the vg invalid flag.
Further lvm commands will use the VG metadata from lvmetad until it is
next invalidated.
2015-06-23 16:36:33 -05:00
4c6b3f5ec3 tests: use vgscan after enable_dev
Since our test environment runs also in non-real-udev world,
it's using  /etc/.cache file with scanned files.

So in this case it is mandatory the user runs 'vgscan'
after a device reappears in the system.

This 'first' lvm2 command then fixes metadata (just like vgs did).
2015-06-23 13:39:57 +02:00
ae76e8f0d0 tests: skip when snapshot does not work
Some older kernel (i.e. 3.11.10 on fc20) do not work properly.
Skip the test if snapshot does not meet 50%.
2015-06-23 13:25:09 +02:00
7ee3ccd826 tests: newer version needed for ext-orig 2015-06-23 11:56:42 +02:00
9c86d33e68 cleanup: avoid printing gcc warning
Casting to (void) with gcc doesn't remove unused_result warning.
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509
2015-06-23 11:06:02 +02:00
50d70eff35 post-release 2015-06-20 01:05:21 +01:00
134b727b4f pre-release 2015-06-20 00:57:35 +01:00
b45e9183bc tests: external origin updates
Update test for recent updates to support unalligned sizes
and extension of reduced volume.
2015-06-19 16:33:29 +02:00
00d028fd77 log: flush stdout before print to stderr
Keep logging readable and fflush stdout before printing to stderr.
2015-06-19 16:33:20 +02:00
3173442984 lvm: move hyphen mangling code
Relocate hyphen code from lvm main into lvm_run_command()
so all command and library user will have it.

Update WHATS_NEW with missing changes.
2015-06-19 09:51:48 +02:00
438a65dfdb display: drop allocation from display_lvname
Use of display_lvname() in plain log_debug() may accumulate memory in
command context mempool. Use instead small ringbuffer which allows to
store cuple (10 ATM) names so upto 10 full names can be used at one.

We are not keeping full VG/LV names as it may eventually consume larger
amount of RAM resouces if vgname is longer and lots of LVs are in use.

Note: if there would be ever needed for displaing more names at once,
the limit should be raised (e.g. log_debug() would need to print more
then 10 LVs on a single line).
2015-06-18 18:50:37 +02:00
a3e0d830bd thin: support unaligned size of external origin and thin pool
With thin-pool kernel target module 1.13 it's now support usage of
external origin with sizes which are not 'alligned' with chunk size
of thin-pool.

Enable lvm2 support for this and also fix reporting of data_percent
usage for case sizes are not alligned.
2015-06-18 18:50:36 +02:00
6f2a617c31 thin: drop limitation for extension of reduced thin volume
Drop check which has prevented resize of reduce thin volume with
external origin. User is supposed to use 'zeroing' to get 'clean'
chunks.
2015-06-18 18:48:59 +02:00
69132f55ea libdm: add dm_tree_node_set_thin_pool_read_only
Support thin-pool tree node with activation in read-only mode.
(Native kernel API).
2015-06-18 15:15:39 +02:00
fd1376ebef libdaemon: move compare_config to lib
so it can be used elsewhere.
2015-06-17 13:07:52 -05:00
0a203070f5 cleanup: missing target_type check in device_is_usable filter 2015-06-17 14:27:48 +02:00
5577f2f4f0 cleanup: || instead of |
More efficient with same result here.
2015-06-17 14:12:58 +02:00
1e6a926e85 filter: filter-usable: consider snapshot and origin LV as unusable if its component is suspended
Note that this is just a quick fix and it needs more robust fix to
encompass any combination, not just the (old) snapshot one!

This started with this report:
  https://bugzilla.redhat.com/show_bug.cgi?id=1219222

If we have devices/ignore_suspended_devices=1 set based on which we
filter out suspended devices as unusable (or if we ignore suspended
devices by force, e.g. during lvconvert called from dmeventd) and
when we have snapshot and snapshot origin devices in the play, we
need to look at their components unerneath (*-real and *-cow) to
check if they're not suspended. If they are, the snapshot/snapshot
origin is not usable as well and hence it needs to be filtered out
by filter-usable.c code which does suspended device filtering.

Not going into much details here, more details are in the bugzilla
mentioned above. However, this is a quick fix since snapshot
and this exact situation is not the only one. So this is
something that needs to be revisited and fixed properly
with full dm tree and checking the whole stack to state
whether the device at the very top is usable or not.
2015-06-17 13:37:53 +02:00
a9bc53d5f3 config: fix some settings incorrectly marked as CFG_DEFAULT_COMMENTED instead of CFG_DEFAULT_UNDEFINED and causing segfault
This patch fixes segfault which was caused by incorrectly marking some
settings CFG_DEFAULT_COMMENTED instead of CFG_DEFAULT_UNDEFINED - the
ones which have NULL default value, hence they're really undefined.
A regression caused by a98ceceb1d.

For example:

$ lvmconfig log/file
file="/a"

Before this patch:

$ lvmconfig --type diff
Segmentation fault (core dumped)

With this patch applied:

$ lvmconfig --type diff
log {
	file="/a"
}

The same applies for these settings:

  log/activate_file
  global/library_dir
  global/system_id_file
  <disk_area>/disk_area_id

There were also other settings with NULL default value and marked as
CFG_DEFAULT_COMMENTED instead of CFG_DEFAULT_UNDEFINED, but they were
cfg_array config settings where the NULL value was not causing segfault
(NULL == empty array).
2015-06-17 13:34:31 +02:00
da1f887060 Add a global get_cmd_name()
Which returns the string set by set_cmd_name().
2015-06-16 15:13:10 -05:00
e043e03cd8 lv_refresh: move the bulk of the function into lib
So that it can be used from other lib code.
2015-06-16 13:38:40 -05:00
3d9957e3dd man vgchange lvchange: mention activation option s
and improve the existing text about existing
activation options.
2015-06-16 13:28:07 -05:00
857296c823 man lvm: mention hyphens in option names 2015-06-16 10:33:01 -05:00
d5adec1056 Add the 's' activation mode
Just as 'e' means activation with an exclusive lock,
add an 's' to mean activation with a shared lock.

This allows the existing but implicit behavior of '-ay'
of clvm LVs to be specified explicitly.  For local VGs,
asy simply means ay, just like aey means ay.

For local VGs, ay == aey == asy

For clvm VGs,  ay == asy, aey == aey, asy == asy
2015-06-16 10:18:16 -05:00
1f318dbcee Ignore hyphens in long option names
The hyphens are removed from long option names before
being read.  This means that:

- Option name specifications in args.h must not include hyphens.
  (The hyphen in 'use-policies' is removed.)

- A user can include hyphens anywhere in the option name.
  All the following are equivalent:
  --vgmetadatacopies,
  --vg-metadata-copies,
  --v-g-m-e-t-a-d-a-t-a-c-o-p-i-e-s-
2015-06-16 09:35:52 -05:00
7fe5e4010c xlate: add new variants
New variants use the clearer function names from the kernel.
2015-06-16 09:30:14 -05:00
ce18fb61c0 lvmcache: mention lvconvert --cachemode
for changing the cache mode on an existing LV.
2015-06-15 14:30:58 -05:00
e7eb5b0696 debug: better tracing messages
Enhance traced output.
2015-06-15 14:48:06 +02:00
9a06ae7b35 libdm: better debug message
Print reason for failing ioctl if thin pool message fails.
2015-06-15 14:48:04 +02:00
ac6b355978 cleanup: drop double const
Second const is unneeded.
Also always create whole array with MAX elements.
2015-06-15 14:46:44 +02:00
edbdbddfb6 dmeventd: better debug
Avoid using 'static' variable within threaded environmnent for debuging.
2015-06-15 14:46:44 +02:00
3d5f7f90c8 dmeventd: drop stack 2015-06-15 14:46:44 +02:00
9da07f1d3e dmeventd: drop pthread_cancel
Drop unused pthread canceling as well as DEBUG printing in signal
handler.
2015-06-15 14:46:44 +02:00
f715fefe31 post-release 2015-06-12 21:42:57 +01:00
2c64762a40 pre-release 2015-06-12 21:40:56 +01:00
9c0049b1ce test: Ensure that outdated PVs are wiped just once. 2015-06-10 16:27:59 +02:00
632dde0cbc metadata: When outdated PVs are wiped, notify lvmetad about the fact. 2015-06-10 16:27:12 +02:00
c78b6f18d4 metadata: Reject lvmetad metadata extensions when reading from disk. 2015-06-10 16:25:57 +02:00
4f91ad64c3 lvmetad: Make it possible to clear the outdated PVs list for a VG. 2015-06-10 16:18:57 +02:00
756d027da5 metadata: Explain the pvs_outdated field in struct volume_group. 2015-06-10 16:17:45 +02:00
fd29c7f3a1 lvmetad, lvmpolld: remove DL_LIBS from Makefile
and rdynamic.  They are not needed.
2015-06-08 11:48:22 -05:00
7c31293221 lvmetad.c: internal err on modifying global handle with open connection
lvmetad_init() should not be called with open connection to the daemon.
Doing so is considered to be an internall error within lvm2 code.

Such coincidence can't occur within current code. Let's assure us it won't
ever happen.
2015-06-08 16:01:40 +02:00
b89ad7e2d4 lvmetad.h: rephrase API descriptions
Some of descritpions were misleading at least. Some were completely
off the reality.

lvmetad_init doesn't re-establish or initialise a connection
lvmetad_active and lvmetad_connect_or_warn can do so.
2015-06-08 16:01:32 +02:00
3225f8d175 man: lvmthin chunk and metadata sizes
Clear some stale information, and give a suggestion to use
a metadata size of 1GiB.
2015-05-27 15:53:01 -05:00
778b66a719 tests: check for idle only for raid type 2015-05-27 11:59:10 +02:00
6e4c04b1be lvmetad: missing wrapper for lvmetad less compilation 2015-05-27 11:44:33 +02:00
d3abc25e76 tests: check for clmvd socket
A bit hacky since it expects PID_DIR == DEFAULT_RUN_DIR for now,
just to check whether it fixes startup clvmd sync problem.
2015-05-27 11:10:43 +02:00
f0a4955eb1 tests: better check for array in sync
Update check for raid array being in sync - getting somewhat complex.
It's another way to fight with problems in:
https://bugzilla.redhat.com/show_bug.cgi?id=1210637
2015-05-27 11:10:43 +02:00
c254743ef3 tests: drop debug print 2015-05-27 11:10:43 +02:00
d1531ab26d cleanup: gcc warn fix, don't hide pvs() 2015-05-27 11:10:43 +02:00
1aba262edb lvmpolld: terminate error message with a dot and LF 2015-05-27 11:10:43 +02:00
f0268585dd WHATS_NEW: various updates
commit c069aff21b
commit 8af5f54824
2015-05-26 16:28:04 +02:00
8af5f54824 dmsetup: zero errno in before strtoul call
Testing errno value without explicitly setting to
zero in before the strtoul call may lead to
unexpected failures.
2015-05-26 16:27:10 +02:00
c069aff21b lvmpolld: zero errno in before strtoul call
Testing errno value without explicitly setting to
zero in before the strtoul call may lead to
unexpected failures.
2015-05-26 16:27:03 +02:00
a72a805896 lvconvert.c: fix whitespace mess 2015-05-26 16:26:57 +02:00
eeb498627c libdm: Add dm_task_get_errno to return ioctl errno.
There are reports of unexplained ioctl failures when using dmeventd.
An explanation might be that the wrong value of errno is being used.

Change libdevmapper to store an errno set by from dm ioctl() directly
and provide it to the caller through a new dm_task_get_errno() function.

[Replaced f9510548667754d9209b232348ccd2d806c0f1d8]
2015-05-26 15:13:49 +01:00
b244fffc18 WHATS_NEW: update
update for commit: f8bf641095
2015-05-25 10:48:53 +02:00
da20e0c507 tests: add test for pvscan --cache --background
regression test for a segfault in pvscan --cache --background
bug fixed by commit:
f8bf641095
2015-05-25 10:48:45 +02:00
f8bf641095 lvmetad.c: ignore lvmetad global handle on disconnect
do not unset lvmetad global handle on disconnect. This is
hotfix for issue described in:
https://www.redhat.com/archives/linux-lvm/2015-May/msg00008.html

Reported-by: Christian Hesse <list@eworm.de>
2015-05-25 09:11:04 +02:00
9d558fbcc2 lvconvert: change how to get failed mirrors number
Commit  b00711e312 improperly
convert _area_missing() replacment and moved check for
AREA_PV seg_type() into same if() section.

Signed-off-by: Lidong Zhong <lzhong@suse.com>
2015-05-22 15:35:36 +02:00
ba68aed836 scripts: activation generator: do not use --sysinit if lvmpolld used
If lvmetad is not used, we generate lvm2-activation{-early,-net}.service
systemd services to activate any VGs found on the system. So far we used
--sysinit during this activation as polling was still forked off of the
lvm activation command.

This has changed with lvmpolld - we have proper lvmpolld systemd
service now (activated via its socket unit). As such, we don't need
to use --sysinit anymore during activation in systemd environment
as polling was the only barrier to remove the need for --sysinit.
2015-05-21 12:20:30 +02:00
6d998aa13d lvmpolld-client.c: debug print when querying progress 2015-05-21 11:20:21 +02:00
01b06cb71b polldaemon.c: modify log levels in report_progress
There's a race when asking lvmpolld about progress_status and
actually reading the progress info from kernel:

Even with lvmpolld being used we read status info from
LVM2 command issued by a user (client side from lvmpolld perspective).
The whole cycle may look like following:

1) set up an operation that requires polling (i.e. pvmove /dev/sda)
2) notify lvmpolld about such operation (lvmpolld_poll_init())
3) in case 1) was not called with --background it would continue with:
4) Ask lvmpolld about progress status. it may respond with one of:
   a) in_progress
   b) not_found
   c) finished
   d) any low level error

5) provided the answer was 4a) try to read progress info from polling LV
(i.e. vg00/pvmove1). Repeat steps 4) and 5) until the answer is != 4a).

And now we got into racy configuration: lvmpolld answered with in_progress
but it may be the that in_between 4) and 5) the operation has already
finished and polling LV is already gone or there's nothing to ask for.
Up to now, 5) would report warning and it could print such warning many
times if --interval was set to 0.

We don't want to scary users by warnings in such situation so let's just
print these messages in verbose mode. Error messages due to error while
reading kernel status info (on existing, active and locked LV) remained
the same.
2015-05-21 11:20:11 +02:00
43224f22e4 format_text: Parse (optional) outdated_pvs section in VG metadata. 2015-05-20 19:46:14 +02:00
e8d00e0687 lvmetad: Set up lvmcache & PV structs for outdated_pvs. 2015-05-20 19:46:14 +02:00
55f3369692 lvmetad: Provide entire pvmeta sections for outdated_pvs. 2015-05-20 19:46:14 +02:00
611c8b6d29 metadata: Add pvs_outdated to struct volume_group.
This is a list of PVs that should have their MDAs wiped because they carry
outdated metadata (that used to belong to the VG they are attached to).
2015-05-20 19:46:14 +02:00
5435346052 metadata: Factor _wipe_outdated_pvs() PVs out of _vg_read(). 2015-05-20 19:46:13 +02:00
1562cd7320 lvmetad: Attach an outdated_pvs list to vg_lookup replies. 2015-05-20 19:46:13 +02:00
da1527d65d lvmetad: Clear the vgid_to_outdated_pvs hash on shutdown. 2015-05-20 19:46:13 +02:00
925268794f lvmetad: Maintain info about outdated PVs. 2015-05-20 19:46:13 +02:00
f3c7bd4004 makefiles: use bash subshell
Avoid using  make's $(shell invocation since the eval order is
then somewhat different and use $$(  subshell.

This also fixes a problem when more then one symbol is found,
since target shell has been given separate word list
so the 'R' assignment would need "" around it.
2015-05-20 09:33:51 +02:00
682e0c898e configure: fix missing [ 2015-05-20 09:32:03 +02:00
788e4c5423 WHATS_NEW: various updates 2015-05-19 21:01:24 +02:00
e6b5eb88f2 polldaemon.c: do not report error when LV not found
currently in wait_for_single_lv() fn trying to poll missing pvmove LV
is considered success. It may have been already finished by another
instance of polldaemon. either by another forked off polldaemon
or by lvmpolld.

Let's try to handle the mirror conversion and snapshot merge the same
way.
2015-05-19 20:56:46 +02:00
cf5b4a2286 lvconvert.c: drop get_vg_lock_and_logical_volume fn 2015-05-19 20:56:32 +02:00
f400f9db19 pvmove.c: code cleanup 2015-05-19 20:56:24 +02:00
7a8ce8dbf7 polldaemon: remove get_copy_vg and get_copy_lv wrappers
These wrappers have been replaced by direct calls
to vg_read() and find_lv() in previous commits.

This commit should have no functional impact since
all bits were already unreachable.
2015-05-19 20:56:15 +02:00
6fba37777c polldaemon.c: call find_lv directly 2015-05-19 20:56:07 +02:00
08114840ca lvconvert.c: call find_lv directly 2015-05-19 20:55:57 +02:00
0d300b70f9 polldaemon.c: call vg_read directly
replace calls in wait_for_single_lv() and report_progress() fns
2015-05-19 20:55:50 +02:00
15939e3435 lvconvert.c: call vg_read directly 2015-05-19 20:55:41 +02:00
131c657735 pvmove.c: call vg_read directly 2015-05-19 20:55:31 +02:00
e5e0e22022 polldaemon: move dev_close_all out of poll_get_copy_vg
let's call dev_close_all() only before we're about to 'sleep'
for at least one second during the polling.

(it's questionable whether to call dev_close_all() at all in
polldaemon code. Natural extension would be to drop it completely)
2015-05-19 20:55:22 +02:00
e27182249a tests: add test for duplicate pvs 2015-05-19 11:02:53 -05:00
dc49e1cde0 configure: update localedir
Previous patch incorrectly skipped replace of @LOCALEDIR@.

The standard option is --localedir  so use --with-localedir
as backward compatible option and set localedir if it's not
yet been set (if the could ever happen).

Use double-eval to translate $datarootdir to $prefix to real dir.
2015-05-18 18:48:18 +02:00
aa2d39c2ca configure: LOCALEDIR needs evaluated value
Also fix typo.
2015-05-18 13:06:34 +02:00
0cb9df3cec tests: fix calcucaltion
Code works properly.
2015-05-18 12:45:43 +02:00
caaca15854 tests: thin_restore not needed
Few more test which could live without thin_restore.
2015-05-18 12:45:42 +02:00
62ac80c8fa makefiles: drop LVM_SHARED_PATH
We already have LVM_PATH define used everywhere else
to access LVM binary so stay with one name.
2015-05-18 12:45:42 +02:00
30c3bbcd9e makefiles: better clean
More exact clean of library exported symbols files.

Also use $(firstword) test to check for empty string
so 'make clean' has now cleaner condensed look.

Clean also created include links.
2015-05-18 12:45:42 +02:00
1bed578535 makefiles: use := for shell calls 2015-05-18 12:45:42 +02:00
bf2b1986c2 makefiles: use single target
Possibly  easier to follow - to have just a single dependency line
and use  if() within rule.

Also replace $(words) with $(firstword) which is more commonly used.
2015-05-18 12:45:42 +02:00
fe00b163d6 configure: move DEFS to configure.h 2015-05-18 12:43:25 +02:00
76cc477fba tests: no warn if test does not need thin_repair
Set LVM_TEST_THIN_REPAIR_CMD to /bin/false for test which
doesn't need it.

This way - even if on the system there is no such tool present,
test will not result with warning about missing tool.

Also remove from Makefile settings of TEST vars which are set in
through /lib/paths  - this also allows to override them in test.
2015-05-17 20:24:36 +02:00
2fca6cdeb3 post-release 2015-05-15 23:28:47 +01:00
0300730cc9 pre-release 2015-05-15 23:19:29 +01:00
9e102ecbd9 mirror: use proper 64bit constants
ed2a08bf25 missed to use 64bit
constants.
2015-05-15 22:53:12 +02:00
190e91231c spec: new man page 2015-05-15 21:31:28 +02:00
463c86008b config: remove UNDEFINED from cache_pool_cachemode
Replace UNDEFINED with COMMENTED because the code
requires a value to be returned from the config.
2015-05-15 14:24:23 -05:00
850606e9fa config: remove UNDEFINED from thin_pool_discards and thin_pool_zero
Replace UNDEFINED with COMMENTED for these two since
undefined seems to break things.
2015-05-15 14:03:53 -05:00
77fa958c1e lvmpolld.8.in: man page rewrite
- add client functionality
- fill in long option variants
2015-05-15 20:33:47 +02:00
d4317c0406 lvmpolld: don't return success on invalid option 2015-05-15 20:33:40 +02:00
d34de2d912 lvmpolld: add long option variants for all short ones 2015-05-15 20:33:34 +02:00
b91e1ea95e lvmpolld: introduce client functionality
as of now lvmpolld works as client utility for
querying running instance of lvmpolld server
on metadata, state, etc.

Currently the only request implemented is the '--dump'.
It prints out full lvmpolld state (mimics lvmdump -p command).
2015-05-15 20:33:27 +02:00
04c77bd886 pvmove.c: relocate id components extraction
we don't want to fail properly set pvmove after metadata
update. failure to copy id components could end with dangling
mirror moving PV segments but no monitoring from lvmpolld or
classical polldaemon.
2015-05-15 20:33:21 +02:00
67657f1ff9 lvpoll.c: harden the checks for proper LV name
lvpoll now process passed LV name properly. It respects
LVM_VG_NAME env. variable and is able to process LV name
passed in various formats:

- VG/LV
- LV name only (with LVM_VG_NAME set)
- /dev/mapper/VG-LV
- /dev/VG/LV
2015-05-15 20:33:10 +02:00
ba120640b2 lvpoll.c: replace arg_count with arg_is_set
didn't need to count the occurence but check if set
2015-05-15 20:33:04 +02:00
0d15217a6c example.conf.in: apply previous improvements to example.conf 2015-05-15 20:32:58 +02:00
9f0095fa2c config_settings.h: improve lvmpolld config description 2015-05-15 20:32:51 +02:00
bf19bbbd55 lvm.8.in: add reference to lvpoll built-in command 2015-05-15 20:32:39 +02:00
4f1c1f3d6b lvmdump.8.in: describe lvmpolld related option 2015-05-15 20:32:32 +02:00
e93058ed81 commands.h: reorder lvpoll options 2015-05-15 20:32:25 +02:00
ce3c457dcc lvm-lvpoll.8.in: man page for built-in command 2015-05-15 20:32:16 +02:00
239fb95fde lvmpolld.8.in: hide origin of lvmpolld man page
:)
2015-05-15 20:32:08 +02:00
6cdd153b89 lvmpolld-client.c: explain known return codes
lvmpolld returns few well known return codes. Explain
these to users and suggest reading lvmpolld log files
for more details
2015-05-15 20:31:54 +02:00
333fdfd4b6 lvmpolld: label known return codes
so that lvmpolld-client can decode and describe these
return codes properly
2015-05-15 20:31:48 +02:00
8d594c409c libdaemon: fprintf(stderr...) -> ERROR()
log data structures are ready. so why not pass
error messages through ERROR()
2015-05-15 20:31:42 +02:00
f653b123cf libdaemon: suggest daemon already running
when dm_creat_lockfile fails, it's probably due to
another instance is holding the same pid file...
2015-05-15 20:31:36 +02:00
c0d30da609 config: thin_pool_chunk_size_policy should be commented
It is commented in existing example.conf, so leave
that as it was.
2015-05-15 11:43:56 -05:00
b7db994aba config: thin_pool_chunk_size_policy is not undefined
The default policy setting does not depend on any
system/kernel values.
2015-05-15 11:37:16 -05:00
03aec36fc0 man: missed y|n for wipesignatures 2015-05-15 17:44:52 +02:00
a98ceceb1d config: add comments to match current example.conf
Use CFG_DEFAULT_COMMENTED and CFG_DEFAULT_UNDEFINED to
replicate the existing comments in example.conf.

Fix host_list to be cfg_array.

UNDEFINED is only used if the value depends on other
system/kernel values outside of lvm.  The most common
case is when dm-thin or dm-cache have built-in default
settings in the kernel, and lvm will use those built-in
default values unless the corresponding lvm config setting
is set.

COMMENTED is used to comment out the default setting in
lvm.conf.  The effect is that if the LVM version is
upgraded, and the new version of LVM has new built-in
default values, the new defaults are used by LVM unless
the previous default value was set (uncommented) in lvm.conf.
2015-05-15 10:13:17 -05:00
797c18d543 libdm: new dm_task_get_info with internal_suspend
Introduce new implmentation of dm_task_get_info() function
with support for reading internal_suspend.
.
This time it is done in a 'versioned' way.

We keep the old fashion dm_task_get_info(Base) to implement
the old behavior of 1.02.95 libdm code.

libdm version 1.02.96 introduced 'macro' wrapper
dm_task_get_info_with_deferred_remove with new implementation
of dm_task_get_info() - we cannot do anything else then to
provide compatible version of this symbol.

Now in version 1.02.97 we add new versioned implementation of
dm_task_get_info(DM_1_02_97) symbol.

This has the effect that i.e. rpm build will finaly resolve proper
dependency on a new symbol - so it will be no longer possible,
to build a new binary and use old library
(rpm -q --provides will show libdevmapper.so.1.02(DM_1_02_97)(64bit))

Also the history is now tracked. If a new function is added (or
reimplemented), it needs to be placed in proper file,
so it could be exported with right versioning symbol.
File .exported_symbols.Base should and any existing older DM
should be treated as read-only after a release.

Also - only libdm has been currently enhanced with versioned .Base
file, as soon as other libs (liblvm, libdevmapper-event) needs changes
they should also get their exported symbol files - meanwhile
make.tmpl handles both cases.
2015-05-15 16:48:22 +02:00
3f10dfd6c7 lvm.conf: add more information to the comment header 2015-05-14 10:52:24 -05:00
8081ee1440 config: description can refer to etc location 2015-05-14 09:47:42 -05:00
cf93fe39e3 config: avoid configurable description text
It's just simpler to avoid configurable values in
the description text by rewording to avoid them.
2015-05-14 09:25:48 -05:00
4931d0132c nix: socat for f18, nc for f17
Use common f17_f18 and add extras for f17 and f18
2015-05-14 15:01:01 +02:00
64a9990977 makefiles: disable po file targes
po targets are not correct - so disable them for now.
2015-05-14 14:19:40 +02:00
a929606f2b makefiles: use srcdir
Use -I$(srcdir) as that's what we really want here.
For %.pot use all includes.
2015-05-14 14:19:22 +02:00
679f1a9e29 nix: drop util-linux
Doesn't appear on centos???
2015-05-14 11:45:37 +02:00
4f375d03dd nix: add more packages 2015-05-14 11:42:33 +02:00
f3a19fbe13 spec: package old sysv initscript for lvmpolld 2015-05-14 11:27:52 +02:00
64b40c5554 nix: add pkgconfig
Install for better config
2015-05-14 11:15:56 +02:00
a42c1c5728 tests: respect @CONFDIR@/machine-id
Obtain location of machine-id.

NOTE: lvmconfig cannot dump 'life' value - should be fixed.
2015-05-14 10:52:55 +02:00
57a16abe2c tests: do not use |&
Bash 3.2  doesn't understand this syntax (i.e. RHEL5).
And it's even better - reports syntax error and return success.
2015-05-14 10:52:55 +02:00
1406aba8da nix: socat is quite new package
Install 'nc' on older systems.
Test suite handles both.
2015-05-14 10:52:55 +02:00
b7d80806b6 conf: system_id_source is referencing CONFDIR
Since we allow to configure /etc in configure and compile-in
dir for /etc we need to properly advertise this location later.
2015-05-14 10:52:55 +02:00
6fb2552ef4 makefiles: protect CFLAGS
When CFLAGS and LDFLAGS are passed into - protect them,
and avoid even recursive subdir 'extension' of them.
2015-05-14 00:19:33 +02:00
a2c9ede6b3 makefiles: assign vars before include
Before we include, set INCLUDE and TARGETS.
Extend CFLAGS after include.
2015-05-14 00:19:33 +02:00
b184d7a2ca makefiles: drop DEBUG mangling
DEBUG is already set through make.tmpl.
2015-05-14 00:19:33 +02:00
3fa66d1036 configure: set optimize flags when CFLAGS is unset
If we are given CFLAGS - preserve user's request and avoid placing
just -O2 there.
2015-05-14 00:19:33 +02:00
f207a6d353 configure: preserve CXX/CFLAGS
AC_PROG_CC
AC_PROG_CXX

Does not preserve CFLAGS CXXFLAGS
2015-05-14 00:19:32 +02:00
5e38b8439a nix: fix socat package name 2015-05-14 00:19:32 +02:00
a8fc483ca4 makefiles: use fullpath when in assign
We need to put full path right in the assign moment,
otherwise command:

make rpm rpmbuild=/my/tmp/dir

cannot work as one would have expected.
2015-05-14 00:19:32 +02:00
7bd1559db6 makefiles: testclient is not valid target 2015-05-14 00:19:32 +02:00
ea846f1ca2 makefiles: drop way too generic deps 2015-05-14 00:19:32 +02:00
02e10f4ccd libdaemon: Fix socket reuse error paths.
Invert S_ISSOCK validation.
Fail instead of replacing a symlink with a new socket.
After failure, skip calling fcntl with invalid socket_fd.
2015-05-13 13:42:09 +01:00
cc560b75aa configure: start to use AS_IF 2015-05-13 13:19:36 +02:00
007ac0d36f nix: more base packages 2015-05-13 13:19:35 +02:00
1b43d63368 spec: packaging polld
Package lvmpolld

Drop legacy SysV init subpackage.
2015-05-13 13:18:59 +02:00
d5cef7413f lvmpolld: dump cleanup 2015-05-12 17:17:07 +02:00
8da7915222 lvmpolld-client.c: use lvmpolld debug class where appropriate 2015-05-12 17:17:00 +02:00
2ec51e6185 tests: remove forgotten -vvvv option 2015-05-12 17:16:54 +02:00
257f7febc7 libdm-common.c: remove trailing whitespace 2015-05-12 17:16:49 +02:00
24a92e08c0 lvmpolld-client.c: be more specific about fallback on error
if client fails to contact lvmpolld it fallbacks to using classical
polldaemon. Be more specific and give some hints to users what went
possibly wrong
2015-05-12 17:16:43 +02:00
c3d351ec9b new debug class for lvmpolld client code 2015-05-12 17:16:37 +02:00
e213aa17bd lvmpolld.8.in: clarify the timeout parameter
Remove references to systemd native service. Now
the libdaemon supports shutdown on idle no matter
the init process implementation installed.
2015-05-12 17:16:31 +02:00
cdb7ce6f17 libdaemon: shutdown on idle also in non-systemd environment 2015-05-12 17:16:24 +02:00
100daa7fd8 tests: ndev by default 2015-05-12 12:40:37 +02:00
68e8030fe7 configure: spec.inc is generated at build
Collect all needed info at runtime for spec.inc
2015-05-12 12:40:37 +02:00
13e87045fd makefiles: use LN_S 2015-05-12 12:40:37 +02:00
9c2a6de68f makefiles: runtime spec.inc
Support  CLEAN_DIRS
Var for rpmbuilddir
Use LN_S
Generate spec.inc at runtime for 'make rpm'.
2015-05-12 12:40:37 +02:00
f5199a1cbd tests: remove forgotten set -v in aux 2015-05-11 19:08:19 +02:00
d758115786 lvmpolld: by default spawn lvpoll cmd with -An 2015-05-11 19:08:13 +02:00
5cfd7074af lvmpolld: set use counters properly in lvmpolld_store
set active_polling_count to zero in pdst_init fn
2015-05-11 19:08:00 +02:00
5e0a8fa981 lib/polldaemon.h: remove trailing whitespace 2015-05-11 19:07:55 +02:00
2bbf0425e7 lvmdump.sh: print out lvmpolld service status 2015-05-11 19:07:47 +02:00
5420edd56e tests: split flavours
Remove duplicate flavour-udev-lvmetad-lvmpolld
and put them 1-per-line.
2015-05-11 17:31:09 +02:00
e28ff7e0fc nix: now some files are generate so keep them
more tweaks ahead
2015-05-11 17:31:09 +02:00
d748b3455d vgimport: fall back when lvmetad is not running
If lvmetad is configured, but not running,
vgimport would not fall back and run without
lvmetad, but would report an error about
requiring lvmetad.
2015-05-11 09:28:47 -05:00
3eb2d4d2ce tests: typo in aux
Ooops editor grabbed q in test.
2015-05-11 16:14:24 +02:00
20e9ec3583 makefiles: move clean
Move clean: target below, so it's not a default target to execute.
2015-05-11 16:08:58 +02:00
62e7a6ca1a makefile: cleanup after build
Provide cleaning rules for build dir and release tgz.
2015-05-11 15:53:46 +02:00
fabc19b73c tests: disable lvmetad and lvmpolld
Since now we enable those by default when compiled with those daemons,
explicitely disable them in tests when needed.

Alphabetically sort configurables.
2015-05-11 15:53:21 +02:00
b5b3ad14a8 spec: now generated 2015-05-11 14:40:54 +02:00
7de6153395 makefiles: dist and rpm target
Basic support for upstream 'build' of rpm packages.
Make spec file generated.

2 new simple targets:

make dist  - create LVM2.MAJOR.MINOR.PATCHLEVEL.tgz  from git files.

make rpm   - some generic rpmbuilder using spec files.
             Create packages in build/ subdir.
             DO NOT USE created rpms in any distribution!
2015-05-11 14:36:58 +02:00
ed8ea6cb2f spec: writable instalation
rpmbuild needs writable binaries (for debug symbol extraction)
2015-05-11 14:36:31 +02:00
725136b57e configure: use_lvmetad/polld configurable
Configure provides proper settings for
use_lvmetad  and use_lvmpolld  conf setttings.

When the build of polld & lvmetad, these settings
are enabled by default unless explicitelly disabled
with --disable-use-lvmetad/--disable-use-lvmpolld.
2015-05-11 14:36:10 +02:00
1806694928 metadata: use log_debug_metadata instead of general log_debug for BA debug messages 2015-05-11 11:07:53 +02:00
e3ccf98023 tests: missed conversion
Assuming it should test same number as other functions.
2015-05-09 09:17:26 +02:00
abcab54cca tests: avoid clobering dmesg
Restore old harness access to /dev/kmsg.
2015-05-09 09:17:26 +02:00
3d845e492a cleanup: drop extra test for NULL
vg cannot be NULL here - it's been already used in the code above.
2015-05-09 09:17:26 +02:00
e047f04394 cleanup: remove extraneous parentheses 2015-05-09 09:17:26 +02:00
e587b0677b lvmpolld: Add standalone polldaemon.
See doc/lvmpolld_overview.txt
2015-05-09 00:59:18 +01:00
be23fae488 lvmcache: set device in label when switching devs V2
This is an alternative/equivalent to commit
ca67cf84df

The problem (wrong label->dev after a new preferred
duplicate device is chosen) was isolated to the lvmetad
case (non-lvmetad worked fine), and this fixes the problem
by setting the new label->dev in the lvmetad-specific
code rather than in the general lvmcache code.
2015-05-08 17:10:53 -05:00
ca67cf84df lvmcache: set device in label when switching devs
When using lvmetad, the reporter code was not reporting
the new preferred device because the new preferred dev
was not being set in the label struct.
2015-05-08 14:41:05 -05:00
53aff9322e tests: better filter
Filter $PREFIX rather then just LVMTEST.
2015-05-08 21:00:10 +02:00
1d832aef09 tests: missing vg 2015-05-08 21:00:10 +02:00
8e509b5dd5 toollib: avoid repeated lvmetad vg_lookup
In process_each_{vg,lv,pv} when no vgname args are given,
the first step is to get a list of all vgid/vgname on the
system.  This is exactly what lvmetad returns from a
vg_list request.  The current code is doing a vg_lookup
on each VG after the vg_list and populating lvmcache with
the info for each VG.  These preliminary vg_lookup's are
unnecessary, because they will be done again when the
processing functions call vg_read.  This patch eliminates
the initial round of vg_lookup's, which can roughly cut in
half the number of lvmetad requests and save a lot of extra work.
2015-05-08 11:44:55 -05:00
f25132b354 lvmcache: choose preferred device once
Once the preferred duplicate devices have been set in
lvmcache, don't attempt to pick preferred duplicates
again.
2015-05-08 11:44:49 -05:00
1dfedcc179 lvmcache: update lvmcache with alternate device
When there are duplicate PVs, and one device
replaces another in lvmcache, use label_read
to update lvmcache for the new device.
2015-05-08 11:28:59 -05:00
cbdf514bbc debug: extra validation of passed segment
Always check if passed segment really is correct cache segment.
(Avoids derefernce of possibly NULL seg->pool_lv).
2015-05-08 15:15:11 +02:00
29c709f591 debug: tracing error path 2015-05-08 15:15:10 +02:00
eadebc3b61 debug: show sys errors 2015-05-08 15:15:10 +02:00
ed2a08bf25 cleanup: use 64bit ulongs
Use 64bit arithmetics for all numbers (Coverity).
2015-05-08 15:15:10 +02:00
5232fd13f3 cleanup: cast minor to dev_t
Let the arithmetic run with a single dev_t type (Coverity).
2015-05-08 15:15:10 +02:00
b8dfd7a53d cleanup: indent mismatch
Aling break (Coverity).
2015-05-08 15:15:10 +02:00
28f18404a7 cleanup: drop unneeded header file
Does not resolves any symbols (Coverity).
2015-05-08 15:15:10 +02:00
3c46428fcd cleanup: drop unneeded int test
Testing int  region_size > INT32_MAX is always false
so drop the test (Coverity).
2015-05-08 15:15:10 +02:00
950a21d58a format1: check for lvm1_system_id
As in the code above in this function continue to check for
lvm1_system_id pointer existance before dereferencing it
(Coverity).
2015-05-08 15:15:10 +02:00
05934d2538 format_text: properly validate PV size for restore
Use 64bit arithmentic for PV size calculation (Coverity).

Also remove sector shift for compared PV size, since all
values are already held in sectors.

This fixes validatio of PV size when restoring PV
from vg metadata backup file.
2015-05-08 15:12:35 +02:00
2cea1c1bd9 pvcreate: fix test for wiping status
Commit ed420fb691 changed
paramet wiped to be a pointer, but missed to switch
to test pointer dereferenced value and instead always
checked 'pointer'.
2015-05-08 13:36:39 +02:00
bf5cb4af8e lvmcache: copy just 32bytes
Copy only bytes which fits.

vginfo->vgid  is  [ID_LEN + 1]
vgsummary->vgid has only [ID_LEN]

Reported by Coverity.
2015-05-08 13:31:59 +02:00
87578b5d94 man: Fix recursive lvm-config man page. 2015-05-07 12:07:40 +01:00
6d35c69b06 Python: Improve lv property test coverage
Improve the python unit test case to cover all of the properties of a LV and
the properties of a LV segment.

In addition we also add a 'tag' to the lv so that we can retrieve it
using the 'lv_tags' property to ensure that this works as expected.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-05-06 08:51:05 -05:00
dc5190de74 lvm2app: Correct missing string properties
Synopsis: STR_LIST needs to be treated as STR for properties.

For any lvm property that was internally 'typed' as a string list we were failing
to return a string in the property API.  This was due to the fact that for the
properties to work the value needs to either be evaulated as a string or a
number.  This change corrects the macro used to build the memory array of
structures so that the string bitfield is set as needed to ensure that the value
is a string.

https://bugzilla.redhat.com/show_bug.cgi?id=1139920

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-05-06 08:51:04 -05:00
e8c11c7df0 python: Check for NULL value before constructing string property
When retrieving a property value that is a string, if the character pointer in C
was NULL, we would segfault.  This change checks for non-null before creating a
python string representation.  In the case where the character pointer is NULL
we will return a python 'None' for the value.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-05-06 08:51:04 -05:00
c21f1ba07a python: Build correct python value for numerical property
With the lvm2app C API adding the ability to determine when a property is
signed we can then use this information to construct the correct representation
of the number for python which will maintain value and sign.  Previously, we
only represented the numbers in python as positive integers.

Python long type exceeds the range for unsigned and signed integers, we just
need to use the appropriate parsing code to build correctly.

Python part of the fix for:
https://bugzilla.redhat.com/show_bug.cgi?id=838257

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-05-06 08:51:04 -05:00
91f737383c lvm2app: Add signed numerical property values
Currently lvm2app properties have the following structure:

typedef struct lvm_property_value {
        uint32_t is_settable:1;
        uint32_t is_string:1;
        uint32_t is_integer:1;
        uint32_t is_valid:1;
        uint32_t padding:28;
        union {
                const char *string;
                uint64_t integer;
        } value;
} lvm_property_value_t;

which assumes that numerical values were in the range of 0 to 2**64-1.  However,
some of the properties were 'signed', like LV major/minor numbers and some
reserved values for properties that represent percentages.  Thus when the
values were retrieved they were in two's complement notation.  So for a -1
major number the API user would get a value of 18446744073709551615.  The
API user could cast the returned value to an int64_t to handle this, but that
requires the API developer to look at the source code and determine when it
should be done.

This change modifies the return property structure to:

typedef struct lvm_property_value {
        uint32_t is_settable:1;
        uint32_t is_string:1;
        uint32_t is_integer:1;
        uint32_t is_valid:1;
        uint32_t is_signed:1;
        uint32_t padding:27;
        union {
                const char *string;
                uint64_t integer;
                int64_t signed_integer;
        } value;
} lvm_property_value_t;

With this addition the API user can interrogate that the value is numerical,
(is_integer = 1) and subsequently check if it's signed (is_signed = 1) too.
If signed, then the API developer should use the union's signed_integer to
avoid casting.

This change maintains backwards compatibility as the structure size remains
unchanged and integer value remains unchanged.  Only the additional bit
taken from the pad is utilized.

Bugzilla reference:
https://bugzilla.redhat.com/show_bug.cgi?id=838257

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-05-06 08:51:04 -05:00
5bbf083cd1 tests: do not restart lvmetad when not necessary
overlooked pvmove-restart test during cleanup
2015-05-06 15:20:11 +02:00
9fc6b654f5 WHATS_NEW: update for recent changes
commits:
- bda26acf70
- 76a0dffe6f
2015-05-05 20:52:49 +02:00
7fca7f196d polldaemon: make wait_for_single_lv public
referenced by new lvpoll command after lvmpolld
gets merged.
2015-05-05 20:52:24 +02:00
81c038934c polldaemon: introduce _nanosleep function
querying future lvmpolld with zero wait time is highly undesirable
and can cause serious performance drop of the future daemon. The new
wrapper function may avoid immediate return from syscal by
introducing minimal wait time on demand.
2015-05-05 20:52:17 +02:00
76a0dffe6f polldaemon: refactor polling interfaces
Routines responsible for polling of in-progress pvmove, snapshot merge
or mirror conversion each used custom lookup functions to find vg and
lv involved in polling.

Especially pvmove used pvname to lookup pvmove in-progress. The future
lvmpolld will poll each operation by vg/lv name (internally by lvid).
Also there're plans to make pvmove able to move non-overlaping ranges
of extents instead of single PVs as of now. This would also require
to identify the opertion in different manner.

The poll_operation_id structure together with daemon_parms structure they
identify unambiguously the polling task.
2015-05-05 20:52:07 +02:00
bda26acf70 polldaemon: optimise out waiting after polling
Waiting even after _check_lv_status returned success and
'finished' flag was set to true doesn't make much sense.

Note that while we skip the wait() we also skip the
init_full_scan_done(0) inside the routine. This should
have no impact as long as the code after _wait_for_single_lv
doesn't presume anything about the state of the cache.
2015-05-05 20:51:45 +02:00
22ae43a11e polldaemon: get get_copy_vg ready for refactoring
with refactored code we take some VG locks as read-only.
Make the poll_get_copy_vg ready for the change.
2015-05-05 20:51:34 +02:00
991d646354 lvconvert: code cleanup and preps for refactoring
just a code cleanup and preparations for adding
new code required for polldaemon refactoring.
This commit should not have any functional impact.
2015-05-05 20:51:27 +02:00
32527861d0 polldaemon: respect lv_attr parm in poll_get_copy_lv
as a part of bigger effort to unify polling intefaces
poll_get_copy_lv should be able to look up LVs based
on theirs lv->status field.

Effective after pvmove starts using poll_get_copy_lv
fn as well.
2015-05-04 16:56:52 +02:00
26f4b1da88 polldaemon: move lvconvert_get_copy_lv code
Moving lvconvert_get_copy_lv to polldaemon (poll_get_copy_lv).
Clear move and rename.
2015-05-04 16:56:39 +02:00
079895b8be polldaemon: move lvconvert_get_copy_vg code
Moving lvconvert_get_copy_vg to polldaemon (poll_get_copy_vg).
Clear move and rename.
2015-05-04 16:56:28 +02:00
7a5a4f952e tests: play better with mdadm
Manage mdadm devices on older distros is a challange.
2015-05-04 13:11:41 +02:00
88421c883e raid: reread status when 0 is reported
When kernel target reports sync status as 0%  it might as well mean
it's 100% in sync, just the target is in some race inconsistent
state - so reread once again and take a more optimistic value ;)

Patch tries to work around:
https://bugzilla.redhat.com/show_bug.cgi?id=1210637
2015-05-04 13:09:05 +02:00
2d10a6f6ae tests: check for open_count
Instead of checking /proc/mounts check for open_count of snap device.
Parallel umount has race, so check for open_count.
2015-05-04 10:18:44 +02:00
7a588bce7b tests: drop extra scsi init
Use first test also for checking the support is there -
avoid one extra unnecessary scsi_debug reload.
2015-05-04 10:17:48 +02:00
c90ee0414d tests: check for clvmd process entry
Instead of checking just for pid file - rather check
for process  - since there could be slight race, the
pid file is gone, but process still exists.
2015-05-04 10:16:33 +02:00
3f05e662bb tests: validate passed LVM_TEST_DEVDIR
Quit test early if passed LVM_TEST_DEVDIR dir does not exists.
2015-05-04 10:15:56 +02:00
b09ac72624 tests: wait for scsi device to appear
Continue with test as soon as device appear (avoid 2s delay)
2015-05-04 10:14:52 +02:00
75aa3e951f tests: dd needs to fail in this case 2015-05-03 01:06:20 +02:00
224e30a4b1 tests: more waits on restart
Check for socket presence (hardcoded for now)
2015-05-03 00:43:15 +02:00
31f1375d23 tests: use 800ms write delay
Since this value magically worked for  pvmove-abort*
use it here as well.

Also prepate_lvmetad has better kill&reload mechanism.
2015-05-03 00:43:15 +02:00
4f6660db7d tests: use odirect
Fill snaphot with odirect so we know data hits disk
before we test how full the snapshot is.
2015-05-03 00:43:15 +02:00
74a81a4577 lvm2app: call fin_locking in lvm_quit
lvm_quit() function should also close locking.
Fixes unclosed socket connecting clvmd.
2015-05-03 00:43:13 +02:00
bc52f07a8f configure: detect /run dir
Access /run directly when system supports it.
2015-05-03 00:42:07 +02:00
636bcb020a clvmd: missed newline in help text
Print \n after listing included lock managers.
2015-05-03 00:41:20 +02:00
9fb93fcd90 post-release 2015-05-02 01:52:05 +01:00
bee2df3903 pre-release 2015-05-02 01:41:17 +01:00
796dc9c91c config: Remove newly-exposed default settings.
Reinstate config settings matching the last release until every
case where the generator produces different output has been reviewed
and fresh decisions made about which defaults to expose as protection
against changes in newer releases. We should be trying to reduce, not
increase, this number.
2015-05-02 00:07:12 +01:00
3542fce0fb tests: more advance cleanup of running pvmove
More take down more targets and use time-limited code.
2015-05-01 22:49:38 +02:00
abdfb1e75b tests: configure use_lvmetad when needed 2015-05-01 22:49:38 +02:00
6a171bbdf5 man: expanded explanation of lvmetad 2015-05-01 15:23:43 -05:00
9273b1a964 man: expanded explanation of pvscan
Related to it's role with lvmetad and auto-activation.
2015-05-01 15:23:32 -05:00
9c7063ef89 tests: free -h is quite new option
Stay with -g and and ignore failure.
2015-05-01 15:40:04 +02:00
79844b9066 tests: minor simplifications
minor updates
2015-05-01 15:07:59 +02:00
fee09f0964 tests: disable usage of fuser
Seems we captured problems with debug.log overwrite,
so avoid quite expensive usage of fuser tool with each lvm command.
2015-05-01 15:07:59 +02:00
4ce5b5fdf3 tests: run api tests from startup dir 2015-05-01 15:07:59 +02:00
a3473e60db tests: no lvmetad reload for debugless output
Introduce LVM_TEST_LVMETAD_DEBUG_OPTS to allow to override
default debug opts for lvmetad.

However could be still overloaded on command line:

make check_lvmetad LVM_TEST_LVMETAD_DEBUG_OPTS="-l all"...
2015-05-01 15:07:58 +02:00
dd4e6b4e7e tests: lower version of dm-delay
Let's see what will break with lower version 1.1.

Also avoid repeated check of target version.
2015-05-01 15:07:58 +02:00
16e8006eb0 tests: rename kill_tagged_processes
Better name for aux function.
First use normal -TERM, and only after a while use -KILL
(leaving some time to correctly finish)
Print INFO about killed processes.
2015-05-01 15:07:58 +02:00
c18e969e30 tests: move conf preparing
If the test in the middle is restarting lvmetad
avoid conf regenerating.
2015-05-01 15:07:58 +02:00
0eea780bce tests: hide error message
Hide error about missing declare -A  support.
2015-05-01 15:07:58 +02:00
0480b4743a tests: wait between remount
Let's see if this help with some races...
2015-05-01 15:07:58 +02:00
4daede06e5 tests: move kernel_at_least to aux
Hide func processing and reuse existing
version_at_least().
2015-05-01 15:07:58 +02:00
f48a4c391c tests: watch out for RAM size
Reduce mem-requirements on low memory boxes,
activate less volumes if machine is below 0.5G.

Also print mem size at test header.
2015-05-01 15:07:58 +02:00
11e0dc40dc config: add CFG_DEFAULT_COMMENTED to comment out default value on output 2015-04-30 18:26:56 +02:00
8f25606d3a man: lvmconfig: also mention '--type list' in synopsis 2015-04-30 18:00:39 +02:00
fc65269d68 lvmconfig: add supporting code for handling deprecated settings
This patch adds supporting code for handling deprecated settings.

Deprecated settings are not displayed by default in lvmconfig output
(except for --type current and --type diff). There's a new
"--showdeprecated" lvmconfig option to display them if needed.

Also, when using lvmconfig --withcomments, the comments with info
about deprecation are displayed for deprecated settings and with
lvmconfig --withversions, the version in which the setting was
deprecated is displayed in addition to the version of introduction.

If using --atversion with a version that is lower than the one
in which the setting was deprecated, the setting is then considered
as not deprecated (simply because at that version it was not
deprecated).

For example:

$ lvmconfig --type default activation
activation {
        ...
	raid_region_size=512
        ...
}

$ lvmconfig --type default activation --showdeprecated
activation {
        ...
	mirror_region_size=512
	raid_region_size=512
        ...
}

$ lvmconfig --type default activation --showdeprecated --withversions
activation {
        ...
	# Available since version 1.0.0.
	# Deprecated since version 2.2.99.
	mirror_region_size=512
	# Available since version 2.2.99.
	raid_region_size=512
        ...
}

$ lvmconfig --type default activation --showdeprecated --withcomments
activation {
        ...
	# Configuration option activation/mirror_region_size.
	# This has been replaced by the activation/raid_region_size
	# setting.
	# Size (in KB) of each copy operation when mirroring.
	# This configuration option is deprecated.
	mirror_region_size=512

	# Configuration option activation/raid_region_size.
	# Size in KiB of each raid or mirror synchronization region.
	# For raid or mirror segment types, this is the amount of
	# data that is copied at once when initializing, or moved
	# at once by pvmove.
	raid_region_size=512
        ...
}

$ lvmconfig --type default activation --withcomments --atversion 2.2.98
activation {
       ...
       # Configuration option activation/mirror_region_size.
       # Size (in KB) of each copy operation when mirroring.
       mirror_region_size=512
       ...
}
2015-04-30 17:55:04 +02:00
5a0197121b config_settings: devices/cache, activation/mirror_region_size and activation/mirror_device_fault_policy are deprecated 2015-04-30 17:39:59 +02:00
b769183a98 config: preparation for marking configuration nodes as deprecated
A preparatory code for marking configuration nodes as deprecated:
  - struct cfg_def_item gains 2 new fields ("deprecated_since_version" and "deprecation_comment"
  - cfg* macros to handle new fields
  - related config_settings.h edits to add new fields for each item (null for all at the moment)

Patch with implementation will follow...
2015-04-30 15:39:34 +02:00
9c39d635b6 cleanup: config_settings.h: comments 2015-04-30 14:43:08 +02:00
25e7178e59 cleanup: config_settings.h: add some comments 2015-04-30 14:28:26 +02:00
d2c2718c11 lvmconfig: allow --withversions alone with --type list
Before this patch:

$ lvmconfig --type list --withversions --withsummary global/use_lvmetad
global/use_lvmetad - Use lvmetad to cache metadata and reduce disk scanning. [2.2.93]

$ lvmconfig --type list --withversions global/use_lvmetad
global/use_lvmetad

With this patch applied:

$ lvmconfig --type list --withversions --withsummary global/use_lvmetad
global/use_lvmetad - Use lvmetad to cache metadata and reduce disk scanning. [2.2.93]

$ lvmconfig --type list --withversions global/use_lvmetad
global/use_lvmetad - [2.2.93]
2015-04-30 14:18:14 +02:00
4388ab477c lvmconfig: comment out settings with proper space/tab prefix
We're commenting out settings with undefined default values.
The comment character '#' was printed at the very beginning of
the line, it should be placed just at the beginning of the setting,
after the space/tab prefix is printed.

Before this patch:

  $ lvmconfig --type default activation
  activation {
           ...
  #        volume_list=[]
           ...
  }

With this patch applied:

  $ lvmconfig --type default activation
  activation {
           ...
           # volume_list=[]
           ...
  }
2015-04-30 14:06:55 +02:00
3706abde5e tests: lvmconf update
New lvmconf function is using bash associative arrays - however
older systems like RHEL5 doesn't provide this feature. In this case
stay with older variant.

Restore support for use case like this:
aux lvmconf 'tags/@foo {}'
2015-04-30 11:16:14 +02:00
13fea87960 spec: Pull in lvmconfig and associated manpages. 2015-04-30 06:35:05 +02:00
d6b6246864 man: Fix references to lvmcache(7) that mentioned section 8 by mistake. 2015-04-30 06:35:05 +02:00
299a3be0d3 man: lvmthin section about use-policies 2015-04-29 16:27:40 -05:00
bf73ccb848 man: 'lvmconfig' is preferred over 'lvm config' 2015-04-29 10:14:23 -05:00
08a82aa940 WHATS_NEW: commit e0a62b8fdc 2015-04-29 17:12:04 +02:00
e0a62b8fdc libdaemon: introduce support for exit on idle
works with systemd activated daemons only as of now

each daemon implementation may decide to signalize its
internal idle state (i.e. all background tasks unrelated to
client threads are finished)
2015-04-29 17:10:44 +02:00
b120454b50 toollib: code cleanup in lv_spawn_background_polling
we're going to extract parameters from lv_mirr later
with code refactoring of polldaemon
2015-04-29 17:10:37 +02:00
f0ff3e9982 man: 'lvm config' is preferred over 'lvm lvmconfig' 2015-04-29 10:04:28 -05:00
79ec8eb93c cleanup: lvmconfig man page typo 2015-04-29 16:35:49 +02:00
8b6b90b073 config: consolidate CFG_UNSUPPORTED and CFG_ADVANCED settings
These settings are in the "unsupported" group:

devices/loopfiles
log/activate_file
metadata/disk_areas (section)
metadata/disk_areas/<disk_area> (section)
metadata/disk_areas/<disk_area>/size
metadata/disk_areas/<disk_area>/id

These settings are in the "advanced" group:

devices/dir
devices/scan
devices/types
global/proc
activation/missing_stripe_filler
activation/mlock_filter
metadata/pvmetadatacopies
metadata/pvmetadataignore
metadata/stripesize
metadata/dirs

Also, this patch causes the --ignoreunsupported and --ignoreadvanced
switches to be honoured for all config types (lvmconfig --type).

By default, the --type current and --type diff display unsupported
settings, the other types ignore them - this patch also introduces
--showunsupported switch for all these other types to display even
unsupported settings in their output if needed.
2015-04-29 16:31:47 +02:00
244ca7ee77 tests: minimize teardown when uneeded
If test has not yet initilized any device,
make teardown a bit faster.
2015-04-29 15:09:58 +02:00
c5b4327f3d tests: bash-fu for lvmconf
Sqeeze about 0.1s out of every created conf and use internal
bash associative arrays instead of lot of command forking
2015-04-29 15:09:58 +02:00
923902013c lvmetad: drop unused vars
Squash some unused vars introduced in some previous commit.s
2015-04-29 15:09:58 +02:00
5d8b31ffad python: python 3 compat patch for lvm2
As provided by rhbz: 1136366
2015-04-29 15:09:56 +02:00
4946c64092 lvmetad: Avoid duplicate entries in the list of alternate devices. 2015-04-29 13:23:23 +02:00
3be3eb2995 lvmconfig: add --type list and -l|--list
lvmconfig --type list displays plain list of configuration settings.
Some of the existing decorations can be used (--withsummary and
--withversions) as well as existing options/switches (--ignoreadvanced,
--ignoreunsupported, --ignorelocal, --atversion).

For example (displaying only "config" section so the list is not long):

$lvmconfig --type list config
config/checks
config/abort_on_errors
config/profile_dir

$ lvmconfig --type list --withsummary config
config/checks - If enabled, any LVM configuration mismatch is reported.
config/abort_on_errors - Abort the LVM process if a configuration mismatch is found.
config/profile_dir - Directory where LVM looks for configuration profiles.

$ lvmconfig -l config
config/checks - If enabled, any LVM configuration mismatch is reported.
config/abort_on_errors - Abort the LVM process if a configuration mismatch is found.
config/profile_dir - Directory where LVM looks for configuration profiles.

$ lvmconfig --type list --withsummary --withversions config
config/checks - If enabled, any LVM configuration mismatch is reported. [2.2.99]
config/abort_on_errors - Abort the LVM process if a configuration mismatch is found. [2.2.99]
config/profile_dir - Directory where LVM looks for configuration profiles. [2.2.99]

Example with --atversion (displaying global section):

$ lvmconfig --type list global
global/umask
global/test
global/units
global/si_unit_consistency
global/suffix
global/activation
global/fallback_to_lvm1
global/format
global/format_libraries
global/segment_libraries
global/proc
global/etc
global/locking_type
global/wait_for_locks
global/fallback_to_clustered_locking
global/fallback_to_local_locking
global/locking_dir
global/prioritise_write_locks
global/library_dir
global/locking_library
global/abort_on_internal_errors
global/detect_internal_vg_cache_corruption
global/metadata_read_only
global/mirror_segtype_default
global/raid10_segtype_default
global/sparse_segtype_default
global/lvdisplay_shows_full_device_path
global/use_lvmetad
global/thin_check_executable
global/thin_dump_executable
global/thin_repair_executable
global/thin_check_options
global/thin_repair_options
global/thin_disabled_features
global/cache_check_executable
global/cache_dump_executable
global/cache_repair_executable
global/cache_check_options
global/cache_repair_options
global/system_id_source
global/system_id_file

$ lvmconfig --type list global --atversion 2.2.50
global/umask
global/test
global/units
global/suffix
global/activation
global/fallback_to_lvm1
global/format
global/format_libraries
global/segment_libraries
global/proc
global/locking_type
global/wait_for_locks
global/fallback_to_clustered_locking
global/fallback_to_local_locking
global/locking_dir
global/library_dir
global/locking_library
2015-04-29 11:58:14 +02:00
0ba332e82a refactor: dumpconfig: keep --withcomments to display full comment and use --withsummary for one line summary 2015-04-29 11:14:18 +02:00
15a563c376 polldaemon: remove redundant log messages
also alter comments describing the change in _poll_vg
wrt correct handling of multiple LVs
2015-04-28 23:19:20 +02:00
ea5c1b0a73 pvmove: make log messages more comprehensible
clarify messages printed during pvmove set up (in
_update_metadata fn) and subsequent metadata updates
during a segment progression
2015-04-28 22:45:54 +02:00
a1474b98f9 update copyright info in various files
basically transfer former date ranges from files where
the code originated from (pvmove.c and lvconvert.c)
2015-04-28 22:45:19 +02:00
90cbc5576f tests: try harder to kill all dangling procs
also simplify and make less prone to an error checks
for running bg processes inside a pvmove-resume tests
2015-04-28 22:31:50 +02:00
8c9ab2a4dd tests: simplify removal of dangling bg procs
some tests left dangling bg processes originating in
lvm2 commands being able to spawn any bg polling process
(lvchange, vgchange, pvmove, lvconvert...)

Initial fn 'add_to_kill_list' should collect processes with
specific parameters (proc's command line and parent processes ID).
After testing finishes the fn kill_listed_processes should remove these
listed by 'add_to_kill_list'.

Unfortunately it proved to be prone to an error especially in scenarios
where cmd line of initiating command contained characters required to
be espaced before passing to shell script to make it work correctly.
(Or if cmd spawned more than one bg process with same cmd line. i.e.:
vgchange or lvchange).

The new implementation is much simpler. It uses env. variable (LVM_TEST_TAG)
for marking a process desired to be killed later or during test env. teardown.
(i.e.: LVM_TEST_TAG=kill_me_$PREFIX to kill only processes related to
current test environment)
2015-04-28 22:31:40 +02:00
3f0434057b config: Introduce lvmconfig.
'lvm dumpconfig' now does a lot more than just dumping configuration
information and is no longer only a support tool.  Users now need
to run it to find out about configuration information that has been
removed from the lvm.conf man page so we need to promote this to full
command line status as 'lvmconfig'.  Also accept 'lvm config' and mention
it in the usage information of lvmconf (which should also get merged in
eventually).
2015-04-28 17:00:37 +01:00
beb229e1e8 devices: improve handling of duplicate PVs
Example:

/dev/loop0 and /dev/loop1 are duplicates,
created by copying one backing file to the
other.

'identity /dev/loopX' creates an identity
mapping for loopX named idmloopX, which
adds a duplicate for the named device.

The duplicate selection code for lvmetad is
incomplete, and lvmetad is disabled for this
example.

[~]# losetup -f loopfile0
[~]# pvs
  PV         VG           Fmt  Attr PSize   PFree
  /dev/loop0 foo          lvm2 a--  308.00m 296.00m

[~]# losetup -f loopfile1
[~]# pvs
  Found duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV: using /dev/loop1 not /dev/loop0
  Using duplicate PV /dev/loop1 which is more recent, replacing /dev/loop0
  PV         VG           Fmt  Attr PSize   PFree
  /dev/loop1 foo          lvm2 a--  308.00m 308.00m

[~]# ./identity /dev/loop0
[~]# pvs
  Found duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV: using /dev/loop1 not /dev/loop0
  Using duplicate PV /dev/loop1 without holders, replacing /dev/loop0
  Found duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV: using /dev/mapper/idmloop0 not /dev/loop1
  Using duplicate PV /dev/mapper/idmloop0 from subsystem DM, replacing /dev/loop1
  PV                   VG           Fmt  Attr PSize   PFree
  /dev/mapper/idmloop0 foo          lvm2 a--  308.00m 296.00m

[~]# ./identity /dev/loop1
[~]# pvs
  WARNING: duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV is being used from both devices /dev/loop0 and /dev/loop1
  Found duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV: using /dev/loop1 not /dev/loop0
  Using duplicate PV /dev/loop1 which is more recent, replacing /dev/loop0
  Found duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV: using /dev/mapper/idmloop0 not /dev/loop1
  Using duplicate PV /dev/mapper/idmloop0 from subsystem DM, replacing /dev/loop1
  Found duplicate PV LnSOEqzEYED3RvIOa5PZP2s7uyuBLmAV: using /dev/mapper/idmloop1 not /dev/mapper/idmloop0
  Using duplicate PV /dev/mapper/idmloop1 which is more recent, replacing /dev/mapper/idmloop0
  PV                   VG           Fmt  Attr PSize   PFree
  /dev/mapper/idmloop1 foo          lvm2 a--  308.00m 308.00m
2015-04-28 10:41:32 -05:00
6cc37275ce config: improve the description of options lists
Describe
thin_check_options, thin_repair_options,
cache_check_option, scache_repair_options

as a "list of options", rather than a "string of options"
because a single string, e.g. "-q --clear-needs-check-flag"
does not work, and needs to be entered as a list,
e.g. ["-q", "--clear-needs-check-flag"]
2015-04-28 10:06:23 -05:00
ae0014e2df config: also evaluate default unconfigured values in runtime for 'cfg_runtime' settings
The settings which have their default value evaluated in runtime should
have their 'unconfigured' counterparts also evaluated in runtime since
those values can be constructed by using other settings.

For example, before this patch:

$ lvm dumpconfig --type default --unconfigured devices/cache_dir devices/cache
cache_dir="@DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@"
cache="/etc/lvm/cache/.cache

With this patch applied:

$ lvm dumpconfig --type default --unconfigured devices/cache_dir devices/cache
cache_dir="@DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@"
cache="@DEFAULT_SYS_DIR@/@DEFAULT_CACHE_SUBDIR@/.cache"
2015-04-28 15:36:35 +02:00
afcf472464 config: make it possible to set default unconfigured_value for settings of all types, not just strings
The @something@ used for unconfigured default value is not bound to
CFG_TYPE_STRING settings defined in config_settings.h, it can be
used for any other config type too.
2015-04-28 15:32:38 +02:00
de6deec3b8 refactor: rename struct cfg_def_item's 'unconfigured_path' to 'unconfigured_value'
It's not only path that can be used for setting's default value
in unconfigured form as @something@.
2015-04-28 15:30:48 +02:00
d0c46c9ed5 conf: Avoid temp files when generating config. 2015-04-28 13:02:19 +01:00
71dbfd7c20 tests: more help# 2015-04-28 11:35:56 +02:00
3fbb7b6e35 tests: always zero disk header
It appear that older wipefs doesn't wipe partition table.
So ensure there is no partition on LVM_TEST_BACKING_DEVICE.
2015-04-28 11:32:52 +02:00
1bb5b498f0 tests: more descriptive aux
Tell what's reason of aux fail here.
2015-04-28 11:23:16 +02:00
a378e5a6dd tests: drop debug test
Remove 'debug leftover' from test.
2015-04-28 11:23:16 +02:00
0c1bda9b53 example.conf.in: regenerate
From recent config_settings.h changes.
2015-04-27 14:15:24 -05:00
cfb0174fed config: fix a couple mistakes with defaults
for archive, archive_dir, and cache
2015-04-27 13:54:45 -05:00
a7d28639eb tests: use new help in aux
Simplify tests and use aux mdadm helpers.
2015-04-25 00:40:02 +02:00
1e3c135d71 tests: aux for mdadm
Implement aux helper fce for mdadm.
2015-04-25 00:40:02 +02:00
f50229041b tests: allow add printable skip message 2015-04-25 00:40:02 +02:00
a939857a63 tests: check sysfs more generically
Allow to access more files in device sysfs subtree.
2015-04-25 00:40:02 +02:00
d9176782fe tests: add double quotes around add_to_kill_list parms 2015-04-25 00:40:02 +02:00
d7888e8316 tests: try more advanced clean
When test is executed on real device - lets try a more complete
cleanup - discard whole device first and try to wipe any
headers it might be left from previous test.
2015-04-25 00:39:43 +02:00
066d0a4e19 cleanup: ancestors -> lv_ancestors, descendants -> lv_descendants
Use "lv_" prefix as they're LV fields.
2015-04-24 14:19:28 +02:00
6e4aee0492 report: add lv_ancestors and lv_descendants reporting fields
Show full chain of ancestors and descendants for snapshots
(both thick and thin - in case of thick, the "ancestor" field
is actually equal to "origin" field as snapshots can't be
chained for thick snapshots).

These fields display current state as it is, they do not
display any history! If the snapshot chain is broken in
the middle, we don't report the historical origin (this
is going to be a part of another patch and a different
set of fields or just a switch for existing fields to
show ancestors and descendants with history included).

For example:

(origin --> snapshot)

lvol1 --> lvol2 --> lvol3 --> lvol4
              \
                --> lvol5 --> lvol6 --> lvol7 --> lvol8

$ lvs -o name,pool_lv,origin,ancestors,descendants vg
  LV    Pool Origin Ancestors                     Descendants
  lvol1 pool                                      lvol2,lvol3,lvol4,lvol5,lvol6,lvol7,lvol8
  lvol2 pool lvol1  lvol1                         lvol3,lvol4,lvol5,lvol6,lvol7,lvol8
  lvol3 pool lvol2  lvol2,lvol1                   lvol4
  lvol4 pool lvol3  lvol3,lvol2,lvol1
  lvol5 pool lvol2  lvol2,lvol1                   lvol6,lvol7,lvol8
  lvol6 pool lvol5  lvol5,lvol2,lvol1             lvol7,lvol8
  lvol7 pool lvol6  lvol6,lvol5,lvol2,lvol1       lvol8
  lvol8 pool lvol7  lvol7,lvol6,lvol5,lvol2,lvol1
2015-04-24 11:51:52 +02:00
82f6dbfaf7 select: fix matching reserved values while <,<=,>,>= is used in selection criteria
Scenario:

$ vgs -o+vg_mda_copies
  VG     #PV #LV #SN Attr   VSize VFree #VMdaCps
  fedora   1   2   0 wz--n- 9.51g    0  unmanaged
  vg      16   9   0 wz--n- 1.94g 1.83g         2

$ lvs -o+read_ahead vg/lvol6 vg/lvol7
  LV    VG   Attr       LSize Pool Origin Data%  Rahead
  lvol6 vg   Vwi-a-tz-- 1.00g pool lvol5  0.00      auto
  lvol7 vg   Vwi---tz-k 1.00g pool lvol6         256.00k

Before this patch:

$vgs -o vg_name,vg_mda_copies -S 'vg_mda_copies < unmanaged'
  VG   #VMdaCps
  vg          2

Problem:
Reserved values can be only used with exact match = or !=, not <,<=,>,>=.
In the example above, the "unamanaged" is internally represented as
18446744073709551615, but this should be ignored while not comparing
field directly with "unmanaged" reserved name with = or !=. Users
should not be aware of this internal mapping of the reserved value
name to its internal value and hence it doesn't make sense for such
reserved value to take place in results of <,<=,> and >=.
There's no order defined for reserved values!!! It's a special
*reserved* value that is taken out of the usual value range
of that type.

This is very similar to what we have already fixed with
2f7f6932dc, but it's the other way round
now - we're using reserved value name in selection criteria now
(in the patch 2f7f693, we had concrete value and we compared it
with the reserved value). So this patch completes patch 2f7f693.

This patch also fixes this problem:

$ lvs -o+read_ahead vg/lvol6 vg/lvol7 -S 'read_ahead > 32k'
  LV    VG   Attr       LSize Pool Origin Data%  Rahead
  lvol6 vg   Vwi-a-tz-- 1.00g pool lvol5  0.00      auto
  lvol7 vg   Vwi---tz-k 1.00g pool lvol6         256.00k

Problem:
In the example above, the internal reserved value "auto" is in the
range of selection "> 32k" - it shouldn't match as well. Here the
"auto" is internally represented as MAX_DBL and of course, numerically,
MAX_DBL > 256k. But for users, the reserved value should be uncomparable
to any number so the mapping of the reserved value name to its interna
 value is transparent to users. Again, there's no order defined for
reserved values and hence it should never match if using <,<=,>,>=
operators.

This is actually exactly the same problem as already described in
2f7f6932dc, but that patch failed for
size field types because of incorrect internal representation used.

With this patch applied, both problematic scenarios mentioned
above are fixed now:

$ vgs -o vg_name,vg_mda_copies -S 'vg_mda_copies < unmanaged'
(blank)

$ lvs -o+read_ahead vg/lvol6 vg/lvol7 -S 'read_ahead > 32k'
  LV    VG   Attr       LSize Pool Origin Rahead
  lvol7 vg   Vwi---tz-k 1.00g pool lvol6  256.00k
2015-04-24 09:48:57 +02:00
de0ce46361 tests: fix md raid test on real /dev
Zero raid signatures when raid is stopped - so signatures
are not requiring wipe when pvcreate follows.

Handle real /dev
2015-04-23 20:28:44 +02:00
8853462528 libdm: Add uuid/devno to ioctl failure log message. 2015-04-23 19:26:52 +01:00
1906619187 libdm: Add DM_INTERNAL_SUSPEND_FLAG.
Still needs to be reported by dmsetup.
2015-04-23 18:39:04 +01:00
95da21cc18 config: fix check_options array
The code used it as both a single string, and as
an array of strings in different places.  Fix it
so that it's an array of strings everywhere.
2015-04-23 10:35:34 -05:00
a8bdfbe959 config: thin_disabled_features default should be undefined
An array that's empty by default should be flagged as
undefined.
2015-04-23 10:19:00 -05:00
3fc9615d15 Improve duplicate PV handling
Make the processing of duplicate PVs the
same with and without lvmetad.
2015-04-22 13:22:14 -05:00
92607ecfe6 man: Escape single quotes in an example to avoid groff's unicode conversion. 2015-04-22 17:31:11 +02:00
33429ea083 make: autoconfisms for generate 2015-04-22 10:05:02 -05:00
808f88f9f0 make: let generate use the just built libdm 2015-04-22 09:37:56 -05:00
81d03b46b0 doc: Update dm kernel files.
v4.0-9804-gdb4fd9c
2015-04-22 15:34:25 +01:00
2fea720881 tests: add missing "" around dev 2015-04-22 11:18:31 +02:00
4b161de2e5 tests: aux works better with installed_testsuite
When test suite is used from installed rpm package
we need to handle things better.

This patch is rather first approach - expecting few more
tweaks needed.
2015-04-22 11:18:31 +02:00
7a64a157e1 tests: simplify teardown
If TESTNAME has not been created yet, avoid running complex teardown.
2015-04-22 11:18:31 +02:00
7f8d942268 makefiles: avoid // in datadir usage
DESTDIR already comes with '/'
2015-04-22 10:59:03 +02:00
d8874556cd tests: install also api test
Install .t & .py binaries.
On 'make clean'  ensure also -t files are removed.
2015-04-22 10:57:42 +02:00
3216a9a819 tests: drop DEBUG log after success
At this moment LVM_LOG_FILE_EPOCH with
LVM_EXPECTED_EXIT_STATUS  properly deletes debug logs
only for real commands - support for lvm2 API does not yet
exists
2015-04-22 10:55:37 +02:00
14c3f9603e tests: use 800ms delay
Worked better with pvmove-abort-all so use here as well.
2015-04-22 09:09:26 +02:00
3f8da60079 tests: notify drops log always
Even on success remove debug.log here.
2015-04-22 09:09:26 +02:00
afdff40542 tests: explicitely ignore result code 2015-04-22 09:09:26 +02:00
30e8b284a7 tests: allow to use sysfs filter
Current filtering logic in lvm2 needs some rework.
For now at least enable it in test suite.
2015-04-22 09:09:26 +02:00
16ee4642c7 nix: install also mdadm
Some tests are checking functinality of lvm2 with mdadm.
2015-04-22 09:09:26 +02:00
2e035162a1 config: thin_repair_options and cache_repair_options are undefined
By default these are empty strings, so the config settings
should be flagged as undefined, so they will be commented
out of the generated config.  Otherwise, the lines:

thin_repair_options=""
cache_repair_options=""

in the dump output cause a warning when processed since
lvm doesn't want an empty string.

Also regenerate lvm.conf.in.
2015-04-21 16:03:54 -05:00
3b15f79bf0 generate example.conf.in, lvmlocal.conf.in
These were created by 'make generate'.
2015-04-21 15:04:22 -05:00
47ed4cdc35 config: remove duplication of settings
The specific config settings have been removed
from the lvm.conf(5) man page, and replaced with
a description of how to use lvm dumpconfig to
view the settings.

The sample lvm.conf and lvmlocal.conf files are now generated:

example.conf.base  - initial ungenerated part of the file
example.conf.gen   - generated portion from dumpconfig
example.conf.in    - combination of .base and .gen files
example.conf       - result of configure processing .in file

lvmlocal.conf.base - initial ungenerated part of the file
lvmlocal.conf.gen  - generated portion from dumpconfig
lvmlocal.conf.in   - combination of .base and .gen files
lvmlocal.conf      - result of configure processing .in file

Do not edit the .in files, but edit config_settings.h
or the .base files, and then use 'make generate' to create
the new .in files.

- configure
  with options

- make
  creates tools/lvm

- make generate
  uses tools/lvm to create example.conf.in and lvmlocal.conf.in
  by combining .base files with dumpconfig output.

- configure
  with same options as above
  creates example.conf and lvmlocal.conf from .in files
2015-04-21 14:55:03 -05:00
9b86e8e8f4 dumpconfig: add --ignorelocal
When generating a sample lvm.conf file, we don't want to
include the "local" section, which is kept in lvmlocal.conf.
2015-04-21 14:55:03 -05:00
0d0d50182d toollib: fix duplicate handling in process_each_pv
With use_lvmetad=0, duplicate PVs /dev/loop0 and /dev/loop1,
where in this example, /dev/loop1 is the cached device
referenced by pv->dev, the command 'pvs /dev/loop0' reports:

Failed to find physical volume "/dev/loop0".

This is because the duplicate PV detection by pvid is
not working because _get_all_devices() is not setting
any dev->pvid for any entries.  This is because the
pvid information has not yet been saved in lvmcache.
This is fixed by calling _get_vgnameids_on_system()
before _get_all_devices(), which has the effect of
caching the necessary pvid information.

With this fix, running pvs /dev/loop0, or pvs /dev/loop1,
produces no error and one line of output for the PV (the
device printed is the one cached in pv->dev, in this
example /dev/loop1.)

Running 'pvs /dev/loop0 /dev/loop1' produces no error
and two lines of output, with each device displayed
on one of the lines.

Running 'pvs -a' shows two PVs, one with loop0 and one
with loop1, and both shown as a member of the same VG.

Running 'pvs' shows only one of the duplicate PVs,
and that shows the device cached in pv->dev (loop1).

The above output is what the duplicate handling code
was previously designed to output in commits:

b64da4d8b5 toollib: search for duplicate PVs only when needed
3a7c47af0e toollib: pvs -a should display VG name for each duplicate PV
57d74a45a0 toollib: override the PV device with duplicates
c1f246fedf toollib: handle duplicate pvs in process_in_pv

As a further step after this, we may choose to change
some of those.

For all of these commands, a warning is printed about
the existence of the duplicate PVs:

Found duplicate PV ...: using /dev/loop1 not /dev/loop0
2015-04-20 17:07:58 -05:00
caa9223c85 tests: update to renamed envvars
Enhance 'not' so 'should' now shows log trace from
command which has failed but should not.
2015-04-20 19:18:56 +02:00
85e833c172 tests: add extra keyword for timing control
Control logging of timer with
"## timing off"  and "## timing on"
2015-04-20 19:18:56 +02:00
2b4f10ac66 debug: change envvar
Rename envvar LVM_LOG_FILE_UNLINK_STATUS to LVM_EXPECTED_EXIT_STATUS
and change compare sign from  '!' to  '>'.

Validate LVM_LOG_FILE_EPOCH and support strictly only
up-to 32 alpha chars. If the content doesn't pass
epoch is simply ignored.
2015-04-20 19:18:56 +02:00
cf4df9e349 tests: use new debug logging feature
Enhance 'not' to manage autodeletion of log files in right cases.
Use separately marked epoch log files for clvmd and dmeventd.
Properly manage stack tracing for new debug.log names.
2015-04-20 12:12:22 +02:00
bff3a1651d debug: use epoch for dmeventd logging
When LVM_LOG_FILE_EPOCH is set, route lvm command debug message
to lvm.conf log file instead of syslog.
2015-04-20 12:12:22 +02:00
5723a7cd7e debug: add new envvar
Add support for 2 new envvars for internal lvm2 test suite
(though it could be possible usable for other cases)

LVM_LOG_FILE_EPOCH

Whether to add 'epoch' extension that consist from
the envvar 'string' + pid + starttime in kernel units
obtained from /proc/self/stat.

LVM_LOG_FILE_UNLINK_STATUS

Whether to unlink the log depending on return status value,
so if the command is successful the log is automatically
deleted.

API is still for now experimental to catch various issue.
2015-04-20 12:12:22 +02:00
de4791c052 WHATS_NEW: update for various commits
add info for various commits, most significant were:

- toollib: close connection to lvmetad after fork
  (fe30658a4d)

- toollib: do not spawn polling in lv_change_activate
  (c26d81d6e6)

- pvmove: split pvmove_update_metadata function
  (65623b63a2)

- lvconvert: move poll code in before refactoring
  (5190f56605)

- pvmove: move poll code in before refactoring
  (a098aa419f)
2015-04-20 10:38:54 +02:00
5cd6381717 dumpconfig: add --unconfigured option
Using this option, default string values that are
configurable are printed as unconfigured values,
e.g. "@CONFDIR@" instead of "/etc".
2015-04-17 11:35:34 -05:00
061e371319 pvmove: fix wrong error path in _update_metadata
fix regression introduced in 65623b63a2

should return zero no matter the result of resume_lvs fn in error
path
2015-04-16 17:54:00 +02:00
105c07d1b4 config: edit descriptions
Take some new information and wording from lvm.conf.5.
2015-04-15 14:21:20 -05:00
5f6ac1c812 dumpconfig: add --withfullcomments option
--withfullcomments prints all comment lines for each config option.
--withcomments prints only the first comment line, which should be
a short one-line summary of the option.
2015-04-15 10:56:42 -05:00
9ce52430de NIX: Also install device-mapper-persistent-data on CentOS 7 & FC 19+. 2015-04-15 16:44:15 +02:00
191f3cf52a tests: shell-fu
Preserve quotes for devs and use  shell arrays to pass things around.
2015-04-15 15:09:45 +02:00
43a6f9e726 tests: move print of replaced vars 2015-04-15 15:09:45 +02:00
53c2c45625 tests: align test result in batch mode 2015-04-15 13:35:42 +02:00
e478471dd5 tests: move stamp handling
Shift stamp handling into TimedBuffer,
so it's same everywhere.
2015-04-15 13:35:42 +02:00
5d4695569d tests: hide error output
Hide error message if pid is already away.
2015-04-15 13:35:42 +02:00
930f0aae84 tests: fix aux have test
Previous commit has made have_cache & have_thin producing
false return value.

Fix it and at the some time provide much better reconfiguring
warning message.

If the test machine is missing needed and configured binaries
it will produce TEST WARNING result.
2015-04-15 13:35:42 +02:00
1a7dd13e70 tests: no tables for no devices
If dm table does't contain any PREFIX device, don't bother
to call other commands

No tracing if test is skipped.
2015-04-15 13:35:42 +02:00
f5466fe435 tests: preserve "" around dev 2015-04-15 13:35:42 +02:00
1a814af46b makefiles: fix usage of default value
When a var like LVM_TEST_THIN_CHECK_CMD is set to ""
(which is valid) we need to correctly use '-'.
Otherwise ':-' replaces such value with built-in default.
2015-04-15 13:35:42 +02:00
22defdac64 man: fix some formatting and also mention -vv 2015-04-15 09:19:11 +02:00
6cdab82cf3 config: edit descriptions
Rewording so the first line of the description
works as a single line summary of the option.
2015-04-14 17:00:28 -05:00
7e58ae7dac test: Show all lvmetad messages (errors, warnings), not just debug+wire. 2015-04-14 20:18:27 +02:00
026c38ac1e NIX: Disable profiling in all but one configuration. 2015-04-14 20:18:27 +02:00
24352aff2b lvmetad: Issue warnings about duplicate PV UUIDs (client-side). 2015-04-14 20:18:27 +02:00
a1dd61459c lvmetad: Track alternate devices for PVs.
There are two reasons for this: first, this allows the client side to notice
that some PV has multiple devices associated with it and print appropriate
warnings. Second, if a duplicate device pops up and disappears, after this
change the original connection between the PV and device is not lost.
2015-04-14 20:18:27 +02:00
2ebb4f4ca3 libdaemon: Export chain_node from config-utils.c. 2015-04-14 20:16:53 +02:00
e3c831030d WHATS_NEW: commit 375ed98 2015-04-14 15:28:42 +02:00
375ed98ae9 make: move blkdeactivate script and blkdeactivate.8 man page installation from install_lvm2 to install_device-mapper target
This completes commit 7a4e27eee5.
2015-04-14 15:24:37 +02:00
7a4e27eee5 blkdeactivate: check for lvm binary and skip LVM processing if not present
This removes dependency on lvm binary - if it's not present, all LVM
processing is skipped (shouldn't normally happen because if lvm binary
is missing then there's obviously nothing that would activate it, but
let's make sure).

Without this tight dependency on lvm, the blkdeactivate script can
be packaged with libdevmapper/dmsetup (in contrast to lvm as it was
before) and as such the script can still be used to handle other DM
devices.
2015-04-14 13:35:11 +02:00
d1a770107d tests: update pvmove tests
Put in pvmove background process into list quickly.
Update API for aux add_to_kill_list()/kill_listed_processes().
Run on 'background' (&) only non-background pvmoves.
2015-04-14 13:29:43 +02:00
75454c2b32 tests: rusage skipped only for skipped 2015-04-14 13:29:43 +02:00
4cdf155a87 makefiles: check lcov file has content
genhtml may get confused without content.
2015-04-14 13:29:43 +02:00
a084b3122f tests: integrate default thin/cache tool paths
If the system is correctly configure (cache & thin tools are present)
avoid 'extra' rebuild of configuration.

On the other hand - if some tool is missing - duplicate ##LVMCONF should
make it more straighforward to see.
2015-04-14 10:11:36 +02:00
c6bcfcba85 tests: stacktrace understands fullpath
$0 as name of script could be either relative or full path.
When it's fullpath don't prepend $TESTOLDPWD.
2015-04-14 10:11:36 +02:00
c969e05aab tests: avoid dup of lvm.conf
When running lvmetad test - avoid duplicate create of lvm.conf
Also as lvmetad cannot be used with cluster make it as 2 code paths.
2015-04-14 10:11:35 +02:00
ee6fc17663 makefiles: skip lvmetad tests
When build without lvmetad, skip  n/udev-lvmetad flavour execution.
Update help test.
2015-04-14 10:11:35 +02:00
d5651f44e3 man: lvmconf: more notes on --services option 2015-04-14 09:49:56 +02:00
96124c6c0b tests: [new] check pvmove resume works as expected
various methods of resuming interrupted pvmove are tested:
- pvmove
- pvmove -b
- lvchange
- vgchange

tests for commits:
- c26d81d6e6
- fe30658a4d
2015-04-13 20:53:18 +02:00
fe30658a4d toollib: close connection to lvmetad after fork
sharing connection between parent command and background
processes spawned from parent could lead to occasional failures
due to unexpected corruption in daemon responses sent to either child
or a parent.

lvmetad issued warning about duplicate config values in request.
LVM commands occasionaly failed w/ internal error after receving
corrupted response.

lvmetad connection is renewed when needed after explicit disconnect
in child
2015-04-13 20:52:32 +02:00
c26d81d6e6 toollib: do not spawn polling in lv_change_activate
spawning a background polling from within the lv_change_activate
fn went to two problems:

1) vgchange should not spawn any background polling until after
   the whole activation process for a VG is finished. Otherwise
   it could lead to a duplicite request for spawning background
   polling. This statement was alredy true with one exception of
   mirror up-conversion polling (fixed by this commit).

2) due to current conditions in lv_change_activate lvchange cmd
   couldn't start background polling for pvmove LVs if such LV was
   about to get activated by the command in the same time.

This commit however doesn't alter the lvchange cmd so that it works same as
vgchange with regard to not to spawn duplicate background pollings per
unique LV.
2015-04-13 20:52:22 +02:00
59c417379e vgchange: remove redundant check
pvmove LVs are invisible thus already skipped due to check
lv_is_visible() at the beginning of the cycle.
2015-04-13 20:52:12 +02:00
fa16c9b7cb config: fix description syntax errors
from previous commit
2015-04-13 13:48:01 -05:00
29220a181a config: update descriptions
- filter, preferred_names
2015-04-13 13:40:11 -05:00
e4261ba037 tests: update runner
Reenable TESTDIR  & PREFIX replacement.
Since we need to replace string in proper order (1st. @TESTDIR@,
2nd. @PREFIX@), drop map and use plain string.

Drop timestamp logging when 'stacktracing'
2015-04-13 16:38:32 +02:00
0aef2b719f tests: log parallel debug.log usage as problem 2015-04-13 16:38:32 +02:00
0457224feb tests: sections in test separated
Use  <========  to separate sections.
Use ##  to prefix these outputs.
Drop $top_srcdir from sed  (it's been replacing '..')
Hide more /dev  dirs.
2015-04-13 16:38:31 +02:00
f080ebc123 tests: hide unwanted output 2015-04-13 16:38:31 +02:00
391500643c tests: slowdown mirroring more
Since some of test machines are very slow, slowdown mirroring
even more.
2015-04-13 16:38:31 +02:00
29467abe59 cleanup: put easier tests first
If we could 'break' before calling strcmp() do it.
Use fputc for single char output (\n).
2015-04-13 16:38:31 +02:00
0b99d648ef cleanup: typo in comment 2015-04-13 16:38:30 +02:00
695237f2ae WHATS_NEW: previous commit f814d7wq 2015-04-13 15:49:25 +02:00
f814d763c6 lvmconf: add --enable-halvm, --disable-halvm, --services, --mirrorservice, --startstopservices options and use proper global/use_lvmetad default value
This patch adds new options to lvmconf:

  --enable-halvm (just like --enable-cluster, but configure LVM
                  for use in HA LVM - meaning disabling lvmetad and
                  making sure we have locking_type=1)

  --disable-halvm (just like --disable-cluster, but configure LVM
                   back from HA LVM - meaning enabling lvmetad if
                   it's enabled by default and making sure we have
                   default locking type set)

  --services (causes clvmd and lvmetad services to be enabled or
              disabled appropriately and conforming to the changes
              in lvm configuration we've just made with lvmconf)

  --mirrorservice (in addition to clvmd and lvmetad services, also
                   enable or disable cmirrord service appropriately;
                   this is a separate option because cmirrord is
                   optional and it doesn't need to be always enabled
                   when clvmd is enabled)

  --startstopservices (in addition to enabling or disabling services,
                       start and stop these services immediately)

These options are supposed to help users to make their system ready
for cluster with clvmd (active-active) or HA LVM (active-passive) use
while lvmconf script can handle services as well so users don't need
to bother about setting them manually.

Also, before this patch, we hardcoded global/use_lvmetad=0 as default
value in lvmconf script. Howeverm this default may change by just
flipping the value in config_settings.h and we may forget to edit
the lvmconf. It's better to use lvm dumpconfig --type default global/use_lvmetad
to get the actual default value and use this one instead of hardcoded one.
2015-04-13 15:27:17 +02:00
cc26085b62 alloc: Respect cling_tag_list in contig alloc.
When performing initial allocation (so there is nothing yet to
cling to), use the list of tags in allocation/cling_tag_list to
partition the PVs.  We implement this by maintaining a list of
tags that have been "used up" as we proceed and ignoring further
devices that have a tag on the list.

https://bugzilla.redhat.com/983600
2015-04-11 01:55:24 +01:00
b851b74cba config: editing descriptions
Update wording and formatting.
2015-04-10 16:43:38 -05:00
2872e8c289 alloc: Add A_PARTITION_BY_TAGS to avoid sharing.
Add A_PARTITION_BY_TAGS set when allocated areas should not share tags
with each other and allow _match_pv_tags to accept an alternative list
of tags.  (Not used yet.)
2015-04-10 21:57:52 +01:00
0523c71844 python: Fix ws liblvm.c
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-04-10 11:01:46 -05:00
f29df9acfe python: Unit test ws fixes
pep8 corrections for:
    - mixed leading ws (tabs & spaces)
    - spacing around arithmetic operators

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-04-10 10:52:12 -05:00
2b557b595a python: Make lv addTag/removeTag persistent
Added lvm_vg_write in the addTag/removeTag paths to make the
changes persist.  Added unit test to ensure functionality.

https://bugzilla.redhat.com/show_bug.cgi?id=1210020

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2015-04-10 10:38:43 -05:00
394250ef67 report: lv_metadata_size, data_lv and metadata_lv also reports properties for cache pools 2015-04-10 14:55:28 +02:00
463fd954bb config: add note about 'vsn' macro use in config_settings.h 2015-04-10 09:51:08 +02:00
4eaa399b54 config: comments update
missing \n
2015-04-09 16:35:20 -05:00
303c5ba803 config: update description
Remove examples that simply replicate the default shown.
2015-04-09 16:09:53 -05:00
6f3f421228 config: include full comments
Comments from the sample config files are copied into
the comment field of the config settings structure.
This includes only minimal changes to the text.

With this in place, the sample config files can
be generated from 'lvm dumpconfig', and content
for an lvm.conf man page can also be generated.
2015-04-09 15:35:28 -05:00
a9d48bae2f cache: Set correct vgid when changing PV header.
pv_write is called both to write orphans and to rewrite PV headers
of PVs in VGs.  It needs to select the correct VG id so that the
internal cache state gets updated correctly.

It only affected commands that involved further steps after
the pv_write and was often masked because the metadata would
be re-read off disk and correct itself.

"Incorrect metadata area header checksum" warnings appeared.

Example:
  Create vg1 containing dev1, dev2 and dev3.
  Hide dev1 and dev2 from the system.
  Fix up vg1 with vgreduce --removemissing.
  Bring back dev1 and dev2.
  In a single operation reinstate dev1 and dev2 into vg1 (vgextend).
Done as separate operations (automatically fix-up dev1 and dev2 as orphans,
then vgextend) it worked, but done all in one go the internal cache got
corrupted and warnings about checksum errors appeared.
2015-04-09 21:13:55 +01:00
249d4a921c tests: extend delay
400 was appeared to be good value in pvmove-abort.sh
so use also in abort-all.
2015-04-09 13:16:53 +02:00
1a7c9ce3bd tests: handle debug.log from clvmd
When clvmd starts, it starts it's own command logging into debug.log.
This is interferring with our other command debug.log.
As as sideeffect we may experience log from command,
followed but lots of zeros and continued with clvmd log.

Fix it by renaming debug.log and now we could also print this trace
to get full list of clvmd activity nicely.

Also improve some post-mortem prints from udevadm and dmsetup to
make the output more usable.
2015-04-09 13:13:36 +02:00
073643c9a2 tests: slowdown write on dev3 even more 2015-04-08 23:19:38 +02:00
ebde60beab tests: use single lvmconf call 2015-04-08 23:19:37 +02:00
a5b34f0f1b tests: put "" around dev path 2015-04-08 23:19:37 +02:00
4459413225 clvmd: singlenode signals only when lock changes
There is no benefit in waking-up all the waiters
when there is no actual change in lock state.
This avoid some unnecessarily ping-pong effects like:

 Resource V_LVMTEST15724vg retrying lock in mode:WRITE...
 Resource V_LVMTEST15724vg already locked lockid=40, mode:WRITE
 Resource V_LVMTEST15724vg retrying lock in mode:WRITE...
 Resource V_LVMTEST15724vg already locked lockid=40, mode:WRITE
2015-04-08 23:19:34 +02:00
f32973c78e select: mention { } use in lvm.8 man page and '-S help' properly 2015-04-08 11:14:16 +02:00
8fdca0de79 tests: check scsi_debug support opt_blks
Some older kernels (i.e. lenny) do not have such options.
2015-04-07 14:59:13 +02:00
035276ab83 lvcreate: do not silently accept '-m #' with raid4/5/6
If the user provides '-m #' (# > 0) with mappings
raid4/5/6, the command silently creates
'#mirrors * #stripes + #parity' image component pairs.

Patch rejects '-m #' altogether for those mappings
in order to avoid LV creation with unexpected layout.

- resolves bz#1209445
2015-04-07 14:32:25 +02:00
64353ff74b tests: when test fails collect more info
In some case it might be worth to know some more surrouding info
when command has crashed.

So collect  tables and some udev db content in this case.
2015-04-07 13:40:15 +02:00
ba049e203b tests: skip clvmd testing of mirrored LV vgsplit
There is something wrong when even inactive LV can't be splitted
without cmirrord being present for clustered VG.
2015-04-03 20:14:26 +02:00
87cb0a3e9f tests: change default to 30s.
Keep rather the default lower and avoid to pass it with every call.
2015-04-03 19:40:43 +02:00
32a0f625a5 tests: slow down devices in outer loop
Since now we have metadata parts running with normal speed,
we could avoid reinitilising delayed dev for every test.
(Saving seconds on cookie waits...)
2015-04-03 19:40:42 +02:00
4f94669eca pvmove: don't crash when name is not found
If the device name is not found in our metadata,
we cannot call strdup few lines later with NULL name.

More intersting story goes behind how it happens -
pvmove removal is unfortunatelly 'multi-state' process
and at some point (for now)  we have in lvm2 metadata
LV  pvmove0 as stripe  and mirror image as error.

If such metadata are left - we fail with any further removal.
2015-04-03 17:18:11 +02:00
c88ffbf9df tests: delay only data portion of device 2015-04-03 17:18:11 +02:00
93ab6d5184 tests: better check for empty set
Even when no arg is passed - there is still one "" arg there...
So taky it easy and check for empty string instead.
2015-04-03 16:38:05 +02:00
ce3c61c4af tests: delay only data area 2015-04-03 14:54:22 +02:00
385457de23 tests: test update
Really wait till fsck is running (sleep 2 is not ideal)
Use new  'delay_dev'.
2015-04-03 14:54:22 +02:00
d3a591a7b3 tests: hide unwanted output 2015-04-03 14:54:22 +02:00
dc41859220 tests: enhance delay_dev
Use common code for error_dev & delay_dev.
Both functions now take list of sectors.

From now on we could delay just 'extent' section, while
keeping running  lvm commands fast (having native metadata area).
2015-04-03 14:53:36 +02:00
bd84389c68 tests: add get first_extent_sector
Trvial function to figure out sector position of 1st. extent.
2015-04-03 14:20:03 +02:00
308f9bcc18 tests: simplify check sysfs_queue
Pass just device name and let figure out
sysfs path inside the function.
2015-04-03 10:27:00 +02:00
a701d337d4 tests: slowdown pvmove devs more
Once pvmove is running - slow it even more
since some test machines tend to be very very slow.
2015-04-02 16:02:06 +02:00
1966025245 tests: split bigger test
Use separate new test and avoid teardown_devs
in the middle of single test.
2015-04-02 16:01:01 +02:00
a16324b0d3 tests: drop check for awk 2015-04-02 13:38:41 +02:00
ee65528547 tests: fix test warning
We cannot print TEST WARNING within test shell script
(since it's running in debug mode and thus always prints it)

Use 'should false' trick let the string printed in this case.
So 'non cluster cases' should now end properly.
2015-04-02 13:38:41 +02:00
536f5fa0a3 tests: deal with kernel and broken lcm
If the kernel has 'new lcm()' (3.19) it provides wrong
optimal_io_size value for dm device so lvm2 command cannot
create properly aligned devices.

Use 'should' for this case - so test ends with 'TEST WARNING'.
2015-04-02 13:38:41 +02:00
7a6e3838e9 tests: add check sysfs_queue
Add check function for content of /sys/block/$1/queue/$2 == $3
2015-04-02 13:38:41 +02:00
95dbedb301 tests: move exa test to separate file
Make it visible the 'exa' test passed on an arch.
2015-04-02 13:38:41 +02:00
6d1c9a0eb8 tests: more duplicate testing 2015-04-02 13:38:41 +02:00
53ef14fca0 debug: log scanned value
Fix verbose print of scanned value for topology attribute.
Result is set afterwards in sectors.
2015-04-02 13:38:41 +02:00
e28e22b9e1 lvmcache: skip drop when vg_write lock is not held
Commit 80f4b4b803
introduced undesirable side-effects for lvm2app user
which happens to be our own python binding.

It appear obtaing pvs list keeps global lock.

So restricting this to VG_GLOBAL READ locks and skip
the drop skip if WRITE lock is held.
2015-04-02 13:38:32 +02:00
f199aeb9ea polldaemon: alter few lines related to interval
we do not allow 0 interval for pvmove command issued
without parameters with classical polldaemon. It would
query the kernel too often with possibly many pvmoves
in-progress.
2015-04-01 20:41:52 +02:00
7abb7894e4 polldaemon: separate daemon_parms initialisation 2015-04-01 20:41:39 +02:00
3929b00466 polldaemon: prepare wrapper poll_daemon function
with lvmpolld we'll have two polldaemon implementations
2015-04-01 20:41:30 +02:00
65623b63a2 pvmove: split pvmove_update_metadata function
So far pvmove_update_metadata (originaly _update_metadata) was
used for both initial and subsequent metadata updates during polling.
With a new polldaemon (lvmpolld) all operations that require polling
have to be split in two parts: The initiating one and the polling one.
The later step will be used from lvm command spawned by lvmpolld to
monitor and advance the mirror on next segment if required.

1) The initiation part is _update_metadata in pvmove.c which performs
only the first update, setting up the pvmove itself in metadata.

2) pvmove_update_metadata in pvmove_poll.c now handles all other
subsequent metadata updates except the last one.

Due to the split we could remove some code. Also some functions were
moved back to pvmove.c as they were suited for initialisation of pvmove
only.
2015-04-01 20:41:03 +02:00
5190f56605 lvconvert: move poll code in before refactoring
This commit has no impact on functionality. Code required to
be visible outside lvconvert.c is just moved into new file
lvconvert_poll.c and some calls are made non-static and
declared in new header file lvconvert.h
2015-04-01 20:40:50 +02:00
a098aa419f pvmove: move poll code in before refactoring
This commit has no impact on functionality. Code required to
be visible outside pvmove.c is just moved into new file
pvmove_poll.c and some calls are made non-static and declared in
new header file pvmove.h
2015-04-01 20:40:39 +02:00
bf2d831e7e tests: add clvm case to system_id.sh 2015-03-31 14:45:14 -05:00
20c6192fbb systemd: stop lvm2-monitor.service before dm-event.service 2015-03-31 15:50:16 +02:00
666738d57a systemd: stop lvm2-pvscan@.service before lvm2-lvmetad.service
When lvm2-pvscan@.service and lvm2-lvmetad.service are scheduled to be
stopped lvm2-pvscan@.service should be stopped first since pvscan uses
lvmetad.

This is especially important if lvm2-lvmetad.socket is also scheduled to
be stopped as in this case connection requests are suppressed causing
pvscan to fail.
2015-03-31 15:47:01 +02:00
139df7c4a3 README: fix link to lvm-devel mailing list 2015-03-31 15:44:00 +02:00
974a029a8a lvm.conf: fix typo as -> is in read_only_volume_list comments 2015-03-31 15:38:29 +02:00
04826db7c4 polldaemon: fix indentation in _poll_vg fn 2015-03-31 13:16:01 +02:00
663254d7a5 polldaemon: proper error check in _poll_vg fn
could theoretically cause NULL pointer dereference
2015-03-31 11:26:53 +02:00
b9e6e66de1 tests: add pvmove --abort for all moves in progress
test for bug described in c282a66132
2015-03-30 18:39:30 +02:00
5f7428e4d5 tests: add pvmove --abort test
test for bug described in c282a66132
2015-03-30 18:39:24 +02:00
c282a66132 pvmove: fix pvmove --abort or pvmove w/o parameters
_check_lv_status was called from within dm_list_iterate_items cycle.
This was utterly wrong! _check_lv_status may remove more than one LV from
vg->lvs list we iterated in the same time.

In some scenarios this could lead to deadlock iterationg over same LV
indefinitely or segfault depending on the circumstances.

Fixed by moving the _check_lv_status outside iterating the vg->lvs
list.

Note that commit 6e7b24d34f was not enough
as _check_lv_status may result in removal of more than one LV from the list.
2015-03-30 18:38:50 +02:00
7c66850ce5 tests: add helper routine for pvmove status check 2015-03-30 18:38:50 +02:00
c8caa04b1c tests: fix check for existence of a pvmove Lv 2015-03-30 18:38:50 +02:00
f1e3e99169 alloc: Log PV tags when reserving areas. 2015-03-26 21:13:26 +00:00
e8fa3354f0 alloc: Pass alloc_handle through to _reserve_area. 2015-03-26 20:32:59 +00:00
f9d74ba3d1 alloc: Only report cling tag errors once. 2015-03-26 19:43:51 +00:00
4b1219ee87 metadata: Move alloc_handle init/destroy fns. 2015-03-26 18:44:24 +00:00
9506760c7e datastruct: Add str_list_add_list. 2015-03-26 18:30:37 +00:00
8a87fadbb0 tests: drop vg2 at end of test 2015-03-26 16:11:29 +01:00
22d43ee14a tests: skip system_id test in cluster
Let's see what we can do in cluster for system_id,
until resolved skip test for check_cluster.
2015-03-26 16:10:48 +01:00
147b0a1700 tests: pvmove better delay check
Improve testing for condition that pvmove0 is already running in the
table (so we do not kill pvmove while it has loaded target, but
it's not yet Live).

Also delay_dev for 200ms.
2015-03-26 16:03:24 +01:00
d24b6cfb1f tests: temporarily trace prepare_vg 2015-03-26 15:11:15 +01:00
f08154cc7b tests: update aux
When we use /dev/loopX device - shift first PV1 sector by 1M
so /dev/loop0 and dm device do not appear as same device.

Also notify lvmetad once 'devs' are created - so in case this
command is called in the middle of test - lvmetad properly
drops its metadata for these devices.

Drop used test.img file between reuse so the 'prepare_vg'
always starts with zeroed disks.

When LVM_TEST_AUX_TRACE is set, allow shell tracing of aux commands.
2015-03-26 15:10:31 +01:00
b7ebab7657 tests: avoid multiple pids
On some systems (parisc) pgrep prints more then 1 pid
(all thread IDs are printed)
So print only leading pid and avoid 'kill' being confused.
2015-03-26 15:10:04 +01:00
0bffd99daa tests: move thin-related test from select-tools.sh to select-tools-thin.sh
And skip this test if thin target is not available.
2015-03-24 10:12:27 +01:00
9dbe2d760f tests: select-tools.sh: add test for fix in commit c9f021de0b 2015-03-24 09:50:35 +01:00
8759f7d755 metadata: vg: add removed_lvs field to collect LVs which have been removed
Do not keep dangling LVs if they're removed from the vg->lvs list and
move them to vg->removed_lvs instead (this is actually similar to already
existing vg->removed_pvs list, just it's for LVs now).

Once we have this vg->removed_lvs list indexed so it's possible to
do lookups for LVs quickly, we can remove the LV_REMOVED flag as
that one won't be needed anymore - instead of checking the flag,
we can directly check the vg->removed_lvs list if the LV is present
there or not and to say if the LV is removed or not then. For now,
we don't have this index, but it may be implemented in the future.
2015-03-24 08:43:08 +01:00
c9f021de0b metadata: process_each_lv_in_vg: get the list of LVs to process first, then do the processing
This avoids a problem in which we're using selection on LV list - we
need to do the selection on initial state and not on any intermediary
state as we process LVs one by one - some of the relations among LVs
can be gone during this processing.

For example, processing one LV can cause the other LVs to lose the
relation to this LV and hence they're not selectable anymore with
the original selection criteria as it would be if we did selection
on inital state. A perfect example is with thin snapshots:

$ lvs -o lv_name,origin,layout,role vg
  LV    Origin Layout      Role
  lvol1        thin,sparse public,origin,thinorigin,multithinorigin
  lvol2 lvol1  thin,sparse public,snapshot,thinsnapshot
  lvol3 lvol1  thin,sparse public,snapshot,thinsnapshot
  pool         thin,pool   private

$ lvremove -ff -S 'lv_name=lvol1 || origin=lvol1'
  Logical volume "lvol1" successfully removed

The lvremove command above was supposed to remove lvol1 as well as
all its snapshots which have origin=lvol1. It failed to do so, because
once we removed the origin lvol1, the lvol2 and lvol3 which were
snapshots before are not snapshots anymore - the relations change
as we're processing these LVs one by one.

If we do the selection first and then execute any concrete actions on
these LVs (which is what this patch does), the behaviour is correct
then - the selection is done on the *initial state*:

$ lvremove -ff -S 'lv_name=lvol1 || origin=lvol1'
  Logical volume "lvol1" successfully removed
  Logical volume "lvol2" successfully removed
  Logical volume "lvol3" successfully removed

Similarly for all the other situations in which relations among
LVs are being changed by processing the LVs one by one.

This patch also introduces LV_REMOVED internal LV status flag
to mark removed LVs so they're not processed further when we
iterate over collected list of LVs to be processed.

Previously, when we iterated directly over vg->lvs list to
process the LVs, we relied on the fact that once the LV is removed,
it is also removed from the vg->lvs list we're iterating over.
But that was incorrect as we shouldn't remove LVs from the list
during one iteration while we're iterating over that exact list
(dm_list_iterate_items safe can handle only one removal at
one iteration anyway, so it can't be used here).
2015-03-24 08:43:07 +01:00
83587f0555 post-release 2015-03-24 02:02:07 +00:00
8bb1dfdd32 pre-release 2015-03-24 01:59:35 +00:00
192a83def3 tests: add omitted --atomic mode in pvmove-restart 2015-03-23 14:55:13 +01:00
6e7b24d34f pvmove: use safe version of iteration when iterating over vg->lvs list in _poll_vg
When we're iterating over LVs in _poll_vg fn, we need to use the safe
version of iteration - the LV can be removed from the list which we're
just iterating over if we're finishing or aborting pvmove operation.
2015-03-23 13:40:39 +01:00
361e2d8df7 tests: revert should removal in mirror test
Since cluster test was actually not been working,
removal of should has been premature.
So restore 'should' back - bug in mirror code is still there.
2015-03-20 11:08:44 +01:00
21343ffbfe tests: start clvmd without lib/ 2015-03-20 11:08:21 +01:00
a515a91fcc format_text: Fix precommitted segfault.
The code never mixes reads of committed and precommitted metadata,
so there's no need to attempt to set PRECOMMITTED when
*use_previous_vg is being set.
2015-03-19 11:14:47 +00:00
e4fa756385 tests: export shell vars
Export vars so they are visible in  'aux' calls as well.
(reenables cluster testing)
2015-03-19 11:23:44 +01:00
a13d261466 makefiles: add more dirs for lcov
lvmetad lcovered.
2015-03-19 10:24:34 +01:00
6407d184d1 cache: Store metadata size and checksum.
Refactor the recent metadata-reading optimisation patches.

Remove the recently-added cache fields from struct labeller
and struct format_instance.

Instead, introduce struct lvmcache_vgsummary to wrap the VG information
that lvmcache holds and add the metadata size and checksum to it.

Allow this VG summary information to be looked up by metadata size +
checksum.  Adjust the debug log messages to make it clear when this
shortcut has been successful.

(This changes the optimisation slightly, and might be extendable
further.)

Add struct cached_vg_fmtdata to format-specific vg_read calls to
preserve state alongside the VG across separate calls and indicate
if the details supplied match, avoiding the need to read and
process the VG metadata again.
2015-03-18 23:43:02 +00:00
19c3851d9c toollib: Reorder process_each_pv initialisation.
Perform cheaper command line-based validation before more-expensive
processing and scanning.
2015-03-18 23:34:46 +00:00
5bf74f2997 pvs: Hide inaccessible clustered PVs.
Inaccessible clustered PVs can be hidden from pvs -a in the same way as
foreign PVs, rather than showing them as if they do not belong to a VG.
2015-03-18 23:31:46 +00:00
87941ccd17 systemid: Use correct mempool.
libmem is necessary when this ends up in cmd->system_id.
2015-03-18 23:25:30 +00:00
80f4b4b803 cache: Retain orphans while global lock held.
Fixes segfault when 'pvs' encounters two different PVs sharing the same
uuid but one an orphan, the other in a VG.

If VG_GLOBAL is held, there seems no point in doing a full scan more
than once.

If undesirable side-effects show up, we can try restricting this to
VG_GLOBAL READ locks.  The original code dates back to 2.02.40.
2015-03-18 23:20:09 +00:00
32a6c11877 pvscan: check sysfs dev entry before rescan
When pvscan --cache --major --minor command is issued from
udev REMOVE event, it basically resulted into a whole device
scan since the device was missing. So avoid such scan
and first check via /sysfs (when available) if such device actually
exists.
2015-03-18 16:19:58 +01:00
1260b86b2b config: use timestamp with nanosecond precision
Since kernel 2.6 we can use more precise timestamping,
so e.g. we could better recognize configs are slightly
older then generated .cache file.
2015-03-18 13:42:56 +01:00
6606b1bff3 lvm-file: wrapper to read ctim from stat
When available use nanosecond stat info.

If commands are running closely enough after config update,
the .cache file from persistent filter could have been ignored.

This happens sometimes during i.e. synthetic test suite run.
2015-03-18 13:42:24 +01:00
17583f1b59 configure: detect st_ctim
Check stat has nanosecond precision for ctim.
2015-03-18 13:42:24 +01:00
a10a11bd54 lvchange: disable persistent minors for pools
There is no reason to support persistent major/minor numbers
for pool volumes - it's only meant to be supported for filesystems
(since i.e. nfs may need to keep volume on a persistent device node.)

Support for pools is now explicitely disabled and documented.
2015-03-18 13:42:13 +01:00
95fbbf4f40 metadata: Fix recent vg_validate message text. 2015-03-17 17:48:56 +00:00
038013cf42 lvmetad: pvscan: do not scan and read ignored MDAs from PVs
Metadata areas which are marked as ignored should not be scanned
and read during pvscan --cache. Otherwise, this can cause lvmetad
to cache out-of-date metadata in case other PVs with fresh metadata
are missing by chance.

Make this to work like in non-lvmetad case where the behaviour would
be the same as if the PV was orphan (in case we have no other PVs
with valid non-ignored metadata areas).
2015-03-16 17:00:36 +01:00
ff5217f850 tests: add ""
Add missing "" around 'devs' (since they could
theoritically constain spaces in its name - not
likely supported with udev these day but anyway....)
2015-03-16 15:06:05 +01:00
36bcbeadd0 tests: fix select report
Simplify the function usage and clean up parameter parsing.

There were 2 significant changes made in the test itself
(they passed before because of incorrect shell string handling)

-pvs_sel 'tags="pv_tag1"' "$dev1 $dev2"
+sel pv 'tags="pv_tag1"' "$dev1" "$dev6"

-lvs_sel '(lv_name=vol1 || lv_name=vol2) || vg_tags=vg_tag1' "vol1 vol2
abc orig snap"
+sel lv '(lv_name=vol1 || lv_name=vol2) || vg_tags=vg_tag1' vol1 vol2
orig snap xyz
2015-03-16 15:02:39 +01:00
0e1d1aaca8 tests: check for dmeventd first
Check there is no dmeventd before creating vg.
2015-03-16 12:26:00 +01:00
e6a69af2d7 tests: drop unused "" 2015-03-13 12:12:54 +01:00
05f23e7763 systemd: blk-availability.service: add After=iscsi-shutdown.service
The iscsi-shutdown.service is the one responsible for logging out
iscsi sessions so blk-availability.service (running the blkdeactivate
script) should be run before that on shutdown (so we need to use
After=iscsi-shutdown.service because "After" relates to starting
the service and the opposite order is automatically applied on
stopping the service at shutdown).
2015-03-13 12:08:20 +01:00
c6d96efc38 tests: few more warnings for gcc only
g++ doesn't like them.
2015-03-12 00:12:15 +01:00
eded54df7b tests: avoid loop on older system
Cleanup overload of 'push'.
Don't busy-loop when reading is finished.
2015-03-12 00:07:45 +01:00
26f5ec0e98 tests: update runner
Avoid busy-looping on CPU while reading socket pipe
and always call read only when select tells there is
something for read.

Change the batch output to old nicer output.
2015-03-11 21:17:23 +01:00
1ad9677cb3 tests: update makefile
Respect $LVM_TEST_RESULT dir
Share same target for  clean: & distclean:
Cleanup path-common
2015-03-11 21:17:23 +01:00
bbe4f7e4c5 tests: drop unneeded comment 2015-03-11 21:17:23 +01:00
243a135fe9 tests: capture and print thrown errors 2015-03-11 21:17:23 +01:00
bdf4e3e2f2 tests: do not leak in mem in destructor 2015-03-11 21:17:23 +01:00
e7e499e80f makefiles: split gcc -W options
Avoid using gcc only Warnings for compilation of g++ object files.
2015-03-11 21:17:23 +01:00
8a2b9f045f tests: extend race
Mark test as skipped, if the test could not be made.
2015-03-11 11:02:35 +01:00
ed2dcb796f tests: drop old workaround
Should be usable now without this 'should'.
2015-03-11 11:02:35 +01:00
a042678a83 tests: specify old mirror type
Use old mirror (otherwise it would need  aux have_raid)
2015-03-11 11:02:35 +01:00
6cecf61cc3 tests: cleanup some cxx warnings 2015-03-11 11:02:35 +01:00
3f7e62b340 tests: enable kmsg by default
By default we want to capture kernel log into test trace
(since when test crashes it could be problem to reproduce).
2015-03-11 11:02:35 +01:00
db5166fbfa tests: extend test timeout to 180sec
Some test could take more then minute (with slow udev and slow
emulation) - extend timeout to 180sec.
2015-03-11 11:02:35 +01:00
760cebf47d reporting: should not fail with foreign option if lvm1 pvs exist
When lvm1 PVs are visible, and lvmetad is used, and the foreign
option was included in the reporting command, the reporting
command would fail after the 'pvscan all devs' function saw
the lvm1 PVs.  There is no reason the command should fail
because of the lvm1 PVs; they should just be ignored.
2015-03-10 13:56:25 -05:00
c7290759b0 tests: update to not run vgconvert -M with lvmetad 2015-03-10 09:59:52 -05:00
f5cc96a54e WHATS_NEW vgconvert -M fix 2015-03-10 09:38:43 -05:00
321e19d9cc vgconvert: require lvmetad to not be used
lvmetad does not work with lvm1/format1 metadata,
and vgconvert -M converts to or from lvm1 metadata,
so disallow vgconvert -M when lvmetad is used.
2015-03-10 09:31:54 -05:00
5dbcbbea58 libdaemon: map error level properly
internal daemon error log level was wrongly mapped to debug syslog
level causing most error messages were lost in non-debug mode.
2015-03-10 14:42:40 +01:00
0982c5c79f configure: check for sync-nand
Check whether gcc support this flag.
Some older compilers (gcc version 4.3.2) miss it.
2015-03-10 14:10:18 +01:00
47b704462e display: fix return values
Return 1 on success in pvdisplay_short() and lvdisplay_full()
so commands like vgdisplay are not printinig stracktraces
on successful passes.

As the results of fail/success have been internally ignored for those
calls, it had no other visible side effect - command's return value was
still 0 (success).
2015-03-10 14:10:18 +01:00
1d3711c0b2 format_text: Set system id directly.
Rearrange _read_vg code to set the appropriate system id field directly.
2015-03-09 19:33:27 +00:00
379d9ec8ec systemid: Use temp status var for LVM_WRITE_LOCKED 2015-03-09 19:18:14 +00:00
458b0210d1 vgchange: Additional system ID warnings.
Also prompt before setting a system ID on a VG when none is set
on the host.
Put quotes round system ID in messages where it could be blank.
2015-03-09 19:03:11 +00:00
1334ea214e vgconvert: Check system ID compatibility.
If system ID is set, don't switch to a format that doesn't support it.
2015-03-09 19:01:12 +00:00
a854546234 metadata: Detect internal use of LVM_WRITE_LOCKED.
Generate internal error if LVM_WRITE_LOCKED ever appears
in struct volume_group: it's only used in external
metadata.
2015-03-09 18:56:24 +00:00
faccdeda83 comments: Use full flag names. 2015-03-09 18:53:22 +00:00
e9a233ee8e system_id: detect an lvm1 system id
Detect an lvm1 system id by looking at the WRITE_LOCKED flag.
Don't copy this lvm1 system id into vg->system_id so that the
restrictions associated with the new system id are not applied
to the old VG with the inherited lvm1 system id.
2015-03-09 13:27:34 -05:00
08371a8b80 tests: fix systemid uname test
The string reported by uname -n may include characters
that lvm omits from the system id (like parens, as seen
on a test machine.)  Check against the final system id
string that lvm uses.
2015-03-06 09:57:37 -06:00
588b3bd7a1 tests: speed of many PVS in a VG 2015-03-06 14:29:26 +01:00
85ef614b37 tests: slightly more efficient vgcreate
With larger set of devices it's faster to directly call
vgcreate on empty set of devices then going though separate
pvcreate call first.
2015-03-06 14:05:06 +01:00
04101bc430 lib: drop unneeded vg_read call
Since we take a lock inside vg_lock_newname() and we do a full
detection of presence of  vgname inside all scanned labels,
there is no point to do this for second time to be sure
there is no such vg.

The only side-effect of such call would be a full validation of
some already exising VG metadata - but that's not the task for
vgcreate when create a new VG.

This call noticable reduces number of scans during 'vgcreate'.
2015-03-06 14:05:06 +01:00
a9b28a4f21 lib: reduce parsing in vgname_from_mda
Use similar logic as with text_vg_import_fd() and avoid repeated
parsing of same mda and its config tree for vgname_from_mda().

Remember last parsed vgname, vgid and creation_host in labeller
structure and if the  metadata have the same size and checksum,
return this stored info.

TODO: The reuse of labeller struct is not ideal, some lvmcache API for
this functionality would be nicer.
2015-03-06 13:53:13 +01:00
7e7411966a lib: avoid reparsing same metadata
When reading VG mda from multiple PVs - do all the validation only
when mda is seen for the first time and  when mda checksum and length
is same just return already existing VG pointer.

(i.e. using 300PVs for a VG would lead to create and destroy 300 config trees....)
2015-03-06 13:53:12 +01:00
6a2ae250ff cleanup: add stack trace
Missed stack in error path.
2015-03-06 13:51:54 +01:00
60427d5d42 lib: return value
Drop label out: with goto and return NULL directly.
Add log_debug() for zero metadata offset.
2015-03-06 13:51:43 +01:00
4d16bfaabb lib: zero returned labeller struct
Return zeroed struct.
(Structure will be extended, so ensure all members are initilized.)
2015-03-06 13:17:39 +01:00
6f68f4364b devices: avoid extra open() syscall
If the device is already opened by lvm's device cache,
avoid extra syscall opening devices for obtaining its size.
2015-03-06 13:17:39 +01:00
b48ff3b94e man: add info to lvmsystemid
about losing access to a VG if lvm is downgraded
to an earlier version.
2015-03-05 12:12:42 -06:00
5e25bca1a9 system_id: avoid munging vg and lv fields
Munge the WRITE/WRITE_LOCKED flags in a temp variable
instead of in the vg/lv fields.
2015-03-05 10:23:16 -06:00
8bb76aea81 system_id: undo the previous changes to the lvm1 code
The system_id and lock_type compat changes do not apply
to the lvm1 code.
2015-03-05 10:13:05 -06:00
1e65fdd9ba system_id: make new VGs read-only for old lvm versions
Previous versions of lvm will not obey the restrictions
imposed by the new system_id, and would allow such a VG
to be written.  So, a VG with a new system_id is further
changed to force previous lvm versions to treat it as
read-only.  This is done by removing the WRITE flag from
the metadata status line of these VGs, and putting a new
WRITE_LOCKED flag in the flags line of the metadata.

Versions of lvm that recognize WRITE_LOCKED, also obey the
new system_id.  For these lvm versions, WRITE_LOCKED is
identical to WRITE, and the rules associated with matching
system_id's are imposed.

A new VG lock_type field is also added that causes the same
WRITE/WRITE_LOCKED transformation when set.  A previous
version of lvm will also see a VG with lock_type as read-only.

Versions of lvm that recognize WRITE_LOCKED, must also obey
the lock_type setting.  Until the lock_type feature is added,
lvm will fail to read any VG with lock_type set and report an
error about an unsupported lock_type.  Once the lock_type
feature is added, lvm will allow VGs with lock_type to be
used according to the rules imposed by the lock_type.

When both system_id and lock_type settings are removed, a VG
is written with the old WRITE status flag, and without the
new WRITE_LOCKED flag.  This allows old versions of lvm to
use the VG as before.
2015-03-05 09:50:43 -06:00
c6a57dc4f3 Revert "systemid: Add ACCESS_NEEDS_SYSTEM_ID VG flag."
This reverts commit bfbb5d269a.

This will be done differently.
2015-03-05 09:50:43 -06:00
06b408ecce system_id: enable the options in config file and command line 2015-03-05 09:50:43 -06:00
190d591fbe report: fix seg_monitor field to display monitoring status for thick snapshots and mirrors
The seg_monitor did not display monitored status for thick snapshots
and mirrors (with mirror log *not* mirrored). The seg monitor did work
correctly even before for other segtypes - thins and raids.

Before (mirrors and snapshots, only mirrors with mirrored log properly displayed monitoring status):

[0] f21/~ # lvs -a -o lv_name,lv_layout,lv_role,seg_monitor vg
  LV                                     Layout     Role                             Monitor
  mirror                                 mirror     public
  [mirror_mimage_0]                      linear     private,mirror,image
  [mirror_mimage_1]                      linear     private,mirror,image
  [mirror_mlog]                          linear     private,mirror,log

  mirror_with_mirror_log                 mirror     public                           monitored
  [mirror_with_mirror_log_mimage_0]      linear     private,mirror,image
  [mirror_with_mirror_log_mimage_1]      linear     private,mirror,image
  [mirror_with_mirror_log_mlog]          mirror     private,mirror,log               monitored
  [mirror_with_mirror_log_mlog_mimage_0] linear     private,mirror,image
  [mirror_with_mirror_log_mlog_mimage_1] linear     private,mirror,image

  thick_origin                           linear     public,origin,thickorigin
  thick_snapshot                         linear     public,snapshot,thicksnapshot

With this patch applied (monitoring status displayed for all mirrors and snapshots):

[0] f21/~ # lvs -a -o lv_name,lv_layout,lv_role,seg_monitor vg
  LV                                     Layout     Role                             Monitor
  mirror                                 mirror     public                           monitored
  [mirror_mimage_0]                      linear     private,mirror,image
  [mirror_mimage_1]                      linear     private,mirror,image
  [mirror_mlog]                          linear     private,mirror,log

  mirror_with_mirror_log                 mirror     public                           monitored
  [mirror_with_mirror_log_mimage_0]      linear     private,mirror,image
  [mirror_with_mirror_log_mimage_1]      linear     private,mirror,image
  [mirror_with_mirror_log_mlog]          mirror     private,mirror,log               monitored
  [mirror_with_mirror_log_mlog_mimage_0] linear     private,mirror,image
  [mirror_with_mirror_log_mlog_mimage_1] linear     private,mirror,image

  thick_origin                           linear     public,origin,thickorigin
  thick_snapshot                         linear     public,snapshot,thicksnapshot    monitored
2015-03-05 14:05:34 +01:00
56606b5f21 post-release 2015-03-04 14:00:46 +00:00
930fa3290d pre-release 2015-03-04 13:49:51 +00:00
a7bfc2cbb5 cleanup: tools: "or use -S for selection" --> "or use --select for selection" 2015-03-04 14:40:58 +01:00
733bfe36f5 systemid: Disable --systemid.
Disable use of --systemid for this release.
2015-03-04 13:14:51 +00:00
67c52a4453 config: add CFG_DISABLED flag and mark system_id settings with that flag
If configuration setting is marked in config_setting.h with CFG_DISABLED
flag, default value is always used for such setting, no matter if it's defined
by user (in --config/lvm.conf/lvmlocal.conf).

A warning message is displayed if this happens:

For example:

[1] f21/~ # lvm dumpconfig --validate
  WARNING: Configuration setting global/system_id_source is disabled. Using default value.
  LVM configuration valid.

[1] f21/~ # pvs
  WARNING: Configuration setting global/system_id_source is disabled. Using default value.
  PV         VG     Fmt  Attr PSize   PFree
  /dev/sdb          lvm2 ---  128.00m 128.00m
  ...
2015-03-04 14:08:47 +01:00
e73dad7874 vgremove: select: direct selection to be done per-VG, not per-LV
Though vgremove operates per VG by definition, internally, it
actually means iterating over each LV it contains to do the
remove.

So we need to direct selection a bit in this case so that the
selection is done per-VG, not per-LV.

That means, use processing handle with void_handle.internal_report_for_select=0
for the process_each_lv_in_vg that is called later in vgremove_single fn.
We need to disable internal selection for process_each_lv_in_vg
here as selection is already done by process_each_vg which calls
vgremove_single. Otherwise selection would be done per-LV and not
per-VG as we intend!

An intra-release fix for commit 00744b053f.
2015-03-04 10:44:31 +01:00
bfbb5d269a systemid: Add ACCESS_NEEDS_SYSTEM_ID VG flag.
Set ACCESS_NEEDS_SYSTEM_ID VG status flag whenever there is
a non-lvm1 system_id set.  Prevents concurrent access from
older LVM2 versions.
Not set on VGs that bear a system_id only due to conversion
from lvm1 metadata.
2015-03-04 01:16:32 +00:00
3562b5ab39 systemid: Init and merge lvm2 and lvm1 fields.
Use system_id field in preference to lvm1_system_id.
Initialise both for now.
2015-03-04 01:00:51 +00:00
dcba4781ea vgchange: Prevent lvm1 system ID changes.
(This system_id setting code shouldn't be in two places.)
2015-03-04 00:50:54 +00:00
340369ab25 format1: Export generate_lvm1_system_id.
Export _lvm1_system_id as generate_lvm1_system_id and call it in
vg_setup() so it is set before writing the metadata to disk
and not missing from the initial metadata backup file.
2015-03-04 00:44:15 +00:00
4e6f3e5162 archives: Preserve format type in file.
format_text processes both lvm2 on-disk metadata and metadata read
from other sources such as backup files.  Add original_fmt field
to retain the format type of the original metadata.
Before this patch, /etc/lvm/archives would contain backups of
lvm1 metadata with format = "lvm2" unless the source was lvm1 on-disk
metadata.
2015-03-04 00:30:26 +00:00
2477495922 lvchange, vgchange: fix the system_id check
The check for matching system_id needs to check
that the system_id is not blank.
2015-03-03 16:45:16 -06:00
cccc2b2980 vgchange: deactivate LVs in foreign VG
Apply the same logic as lvchange, which allows
deactivating LVs in a foreign VG.
2015-03-03 13:23:13 -06:00
926b38c0d7 spec: Add lvmlocal.conf to RPMs. 2015-03-03 15:47:13 +01:00
1a41e649a6 metadata: vg: alloc lvm1_system_id in alloc_vg sooner 2015-03-02 13:00:45 +01:00
eeaf3f2e88 metadata: vg: add missing vg->lvm1_system_id initialization
The vg->lvm1_systemd_id needs to be initialized as all the code around
counts with that. Just like we initialize lvm1_system_id in vg_create
(no matter if it's actually LVM1 or LVM2 format), this patch adds this
init in alloc_vg as well so the rest of the code does not segfaul
 when trying to access vg->lvm1_system_id.
2015-03-02 12:17:27 +01:00
047fe6c59f report: check value of args_are_pvs, not the pointer (fix for commit 9ea77b7) 2015-03-02 10:36:32 +01:00
c32efc7f7e system_id: apply consistent naming
In log messages refer to it as system ID (not System ID).

Do not put quotes around the system_id string when printing.

On the command line use systemid.

In code, metadata, and config files use system_id.

In lvmsystemid refer to the concept/entity as system_id.
2015-02-27 13:32:00 -06:00
e09f8a82f1 initscripts: lvm2-monitor: use @DMEVENTD_PIDFILE@ instead of hardcoded /var/run/dmeventd.pid 2015-02-27 15:48:10 +01:00
57e9e76da4 initscripts: lvm2-monitor: implement status action
Two new functions added in the init script: rh_status and rh_status_q.
First one to be used in status() and second one to be used in start(),
stop(), force_stop(). Check for 'dmeventd' added and print list of
lvs being monitored in status().
2015-02-27 15:38:34 +01:00
379fb90b05 cleanup: change check order in condition in _check_pv_list fn
"!dev_cache_get(argv[i], cmd->full_filter) && !rescan_done" --> "!rescan_done && !dev_cache_get(argv[i], cmd->full_filter)

Check the simple condition first (variable), then the function return value
(which in this case certainly takes more time to evaluate) - save some time.
2015-02-27 14:52:38 +01:00
ee4cd2c737 lvchange: Allow -pr to change kernel only. 2015-02-27 13:38:26 +00:00
5b154ae4a3 report: one more comment explaining change of report type when tags are used for original LABEL reporting 2015-02-27 13:48:47 +01:00
9ea77b788b report: fix handling of reports with pure label fields
Two problems fixed by this patch:
  - PV tags were not recognized at all when using them with pvs
    report that has only label fields (regression since 2.02.105)
  - incorrect persistent .cache file to be generated after pvs
    report that has only label fields (regression since 2.02.106)

These bugs come from the transition from process_each_pv to
process_each_label introduced by commit
67a7b7a87d and commit
490226fc47 and related.
2015-02-27 13:39:25 +01:00
8bceb1e0bb conf: be more clear about wipe_signatures_when_zeroing_new_lvs option in comments 2015-02-27 09:17:10 +01:00
0a19238aa3 system_id: remove unwanted foreign error for some commands
Commands that can never use foreign VGs begin with
cmd->error_foreign_vgs = 1.  This tells the vg_read
lib layer to print an error as soon as a foreign VG
is read.

The toollib process_each layer also prints an error if a
foreign VG is read, but is more selective about it.  It
won't print an error if the command did not explicitly
name the foreign VG.  We want to silently ignore foreign VGs
unless a command attempts to use one explicitly.

So, foreign VG errors are printed from two different layers:
vg_read (lower layer) and process_each (upper layer).

Commands that use toollib process_each, only want errors from
the process_each layer, not from both layers.  So, process_each
disables the lower layer vg_read error message by setting
error_foreign_vgs = 0.

Commands that do not use toollib process_each, want errors
from the vg_read layer, otherwise they would get no error
message.  The original cmd->error_foreign_vgs setting
enables this error.

(Commands that are allowed to operate on foreign VGs always
begin with cmd->error_foreign_vgs = 0, and all the commands
in this group use toollib process_each with the selective
error reporting.)
2015-02-26 16:33:36 -06:00
a432066c7c mirror: Explicit cast in region_size_max 2015-02-26 19:49:25 +00:00
cb727a1ccc mirror: Avoid region size compiler warning.
format ‘%u’ expects type ‘unsigned int’, but argument 7 has type ‘uint64_t’
2015-02-26 19:45:55 +00:00
66d074e913 tests: more system_id tests 2015-02-26 13:23:22 -06:00
b5394c8f26 lvchange: Allow -prw to change kernel only.
If an LV is already rw but still ro in the kernel, allow -prw to issue a
refresh to try to change the kernel state to rw.

Intended for use after clearing activation/read_only_volume_list in
lvm.conf.
2015-02-26 18:38:26 +00:00
71d97fd88a man: lvmsystemid: empty string equals no system_id 2015-02-25 16:55:56 -06:00
efd7480de3 tests: add more system_id tests 2015-02-25 16:13:28 -06:00
1248f94a42 pvscan, vgscan: include foreign vgs with --cache
pvscan --cache and vgscan --cache scan devices to refresh lvmetad,
and they should also refresh the lvmetad copy of foreign vgs.
2015-02-25 15:46:27 -06:00
bbaabb8a59 WHATS_NEW: vgimport with lvmetad 2015-02-25 14:59:24 -06:00
2c50cbe8cb tests: fix the system_id tests
That were broken by yesterday's system_id changes.
2015-02-25 14:58:49 -06:00
ebb2205b4c tests: add more systemid tests 2015-02-25 14:58:49 -06:00
dd6a202831 lvchange: deactivate is always possible in foreign vgs
The only realistic way for a host to have active LVs in a
foreign VG is if the host's system_id (or system_id_source)
is changed while LVs are active.

In this case, the active LVs produce an warning, and access
to the VG is implicitly allowed (without requiring --foreign.)
This allows the active LVs to be deactivated.

In this case, rescanning PVs for the VG offers no benefit.
It is not possible that rescanning would reveal an LV that
is active but wasn't previously in the VG metadata.
2015-02-25 14:58:49 -06:00
dd0ee35378 cmirror: Adjust region size to work around CPG msg limit to avoid hang.
cmirror uses the CPG library to pass messages around the cluster and maintain
its bitmaps.  When a cluster mirror starts-up, it must send the current state
to any joining members - a checkpoint.  When mirrors are large (or the region
size is small), the bitmap size can exceed the message limit of the CPG
library.  When this happens, the CPG library returns CPG_ERR_TRY_AGAIN.
(This is also a bug in CPG, since the message will never be successfully sent.)

There is an outstanding bug (bug 682771) that is meant to lift this message
length restriction in CPG, but for now we work around the issue by increasing
the mirror region size.  This limits the size of the bitmap and avoids any
issues we would otherwise have around checkpointing.

Since this issue only affects cluster mirrors, the region size adjustments
are only made on cluster mirrors.  This patch handles cluster mirror issues
involving pvmove, lvconvert (from linear to mirror), and lvcreate.  It also
ensures that when users convert a VG from single-machine to clustered, any
mirrors with too many regions (i.e. a bitmap that would be too large to
properly checkpoint) are trapped.
2015-02-25 14:42:15 -06:00
a88430c6a1 lvcreate.8: Mention --cachepolicy and --cachesettings. 2015-02-25 18:34:01 +01:00
0d313282f2 lvmcache.7: add a section on --cachepolicy/--cachesettings 2015-02-25 18:21:30 +01:00
aa30e95271 vgcfgbackup: enable foreign VG access
Backup of a foreign VG is allowed.
2015-02-25 11:01:37 -06:00
8668a9e81c systemid: silently ignore foreign vgs unless named
A foreign VG should be silently ignored by a reporting/display
command like 'vgs'.  If the reporting/display command specifies
a foreign VG by name on the command line, it should produce an
error message.

Scanning commands pvscan/vgscan/lvscan are always allowed to
read and update caches from all PVs, including those that belong
to foreign VGs.

Other non-report/display/scan commands always ignore a foreign
VG, or report an error if they attempt to use a foreign VG.

vgimport should always invalidate the lvmetad cache because
lvmetad likely holds a pre-vgexported copy of the VG.
(This is unrelated to using foreign VGs; the pre-vgexported
VG may have had no system_id at all.)
2015-02-25 10:53:52 -06:00
4ff9abd01f toolcontext: Fix lvmlocal.conf load fail path. 2015-02-25 16:36:47 +00:00
1e59c0346a example.conf: Update systemid comments.
Avoid using 'cluster' (ambiguous).
Add holding ref for machine-id source.
2015-02-25 14:22:24 +00:00
809a5e142e systemid: Improve concurrent warning. 2015-02-25 14:17:35 +00:00
ac6a4cd707 systemid: Allow empty systemid with warnings.
Add warning messages when empty system ID is set.
2015-02-25 14:12:24 +00:00
7d615a3fe5 cache: Fix a segfault when passing --cachepolicy without --cachesettings. 2015-02-24 11:39:35 +01:00
5793ecd165 systemid: Extend --foreign to reporting commands.
Add --foreign to the remaining reporting and display commands plus
vgcfgbackup.
Add a NEEDS_FOREIGN_VGS flag for vgimport to always set --foreign.
If lvmetad is being used with --foreign, scan foreign VGs (currently
implemented as a full PV scan).
Handle these things centrally in lvmcmdline.c.
Also allow lvchange and vgchange -an/-aln to deactivate any foreign
LVs that happen to be active if something went wrong.
Remember to set the system ID when creating a new VG in vgsplit.
2015-02-23 23:41:38 +00:00
b18feb98e5 systemid: Fix access restrictions.
When checking whether the system ID permits access to a VG, check for
each permitted situation first, and only then issue the appropriate
error message.  Always issue a message for now.  (We'll try to
suppress some of those later when the VG concerned wasn't explicitly
requested.)
Add more messages to try to ensure every return code is checked and
every error path (and only an error path) contains a log_error().
Add self-correction to vgchange -c to deal with situations where
the cluster state and system ID state are out-of-sync (e.g. if
old tools were used).
2015-02-23 23:19:36 +00:00
df227be37c lvm1: Reenable sys ID.
Move the lvm1 sys ID into vg->lvm1_system_id and reenable the #if 0
LVM1 code.  Still display the new-style system ID in the same
reporting field, though, as only one can be set.
Add a format feature flag FMT_SYSTEM_ON_PVS for LVM1 and disallow
access to LVM1 VGs if a new-style system ID has been set.
Treat the new vg->system_id as const.
2015-02-23 23:03:52 +00:00
2fc2928978 config: Rename allow_system_id to extra_system_ids.
Add warnings to the config file templates and briefly document
each value.
Configure lvmlocal.conf and install in /etc/lvm.
2015-02-23 22:19:08 +00:00
3d406e5a8d config: Adjust system_id defaults.
Allow cmd->unknown_system_id to be cleared during toolcontext
refresh.
Set a default value of "none" for global/system_id_source.
Allow local/system_id to be empty so it's not impossible for
a later config file to remove it.
2015-02-23 21:20:51 +00:00
e15b439bf3 systemid: Define file content more precisely.
In a file containing a system ID:
  Any whitespace at the start of a line is ignored;
  Blank lines are ignored;
  Any characters after a # are ignored along with the #.
  The system ID is obtained by processing the first line with
non-ignored characters.
  If further lines with non-ignored characters follow, a warning is
issued.
2015-02-23 20:49:15 +00:00
c2ed5feee5 systemid: Add warnings if invalid.
Add WARNING messages if there are problems setting the requested
system ID.
Ban "localhost" as a prefix regardless of the system_id_source.
Use cmd->hostname instead of calling uname again.
Make system_id_source values case-insensitive (as with new settings like
log_debug_classes) and also accept machine-id to match the filename.
2015-02-23 20:36:27 +00:00
6b6934b009 toolcontext: Include system_id in refresh.
Move _init_system_id() into _process_config() so it's also called when
refreshing the toolcontext.  Add WARNING to log_warn messages.
2015-02-23 20:21:00 +00:00
72e6888dc3 toolcontext: Move lvmlocal.conf loading.
Load lvmlocal.conf after basic initialisation from lvm.conf.
2015-02-23 20:11:00 +00:00
0551d1c56e systemid: Require alphanumeric 1st character.
Require system ID to begin with an alphanumeric character.
Rename fn to make clear it's only validation for systemid
and always terminate result rather than imposing this on the caller.
2015-02-23 19:47:03 +00:00
a5df78e0f0 format_text: Fix creation_host_system_id.
Don't escape quotes - forbidden characters.
2015-02-23 19:19:48 +00:00
cc5e3dbf24 format_text: Store creation_host_system_id.
Record the current system ID at the time of writing out VG metadata
in the outer section of it alongside the hostname and time.
2015-02-23 17:54:47 +00:00
2a1189ebc3 config: Reinstate recursive tags setting.
In 2.02.99, _init_tags() inadvertently began to ignore the
dm_config_tree struct passed to it.  "tags" sections are not
merged together, so the "tags" section in the main config file was
being processed repeatedly and other "tags" sections were ignored.
2015-02-23 17:40:58 +00:00
36a6c0df46 systemid: Add built-in systemid command.
Make it easy to find the system ID when testing.
Also show in general debug output.
2015-02-23 17:26:50 +00:00
fcebf27a9f lvm-string: Fix HYPEN typo. 2015-02-23 17:09:35 +00:00
4847836310 lvmetad: Add fn to scan only foreign VGs.
Not implemented yet - just a wrapper.
2015-02-23 17:03:03 +00:00
42ba7974c5 man lvmsystemid: update changing the system_id 2015-02-20 16:55:27 -06:00
cfd1b8eae2 man lvm: document --foreign option 2015-02-20 16:26:04 -06:00
37a47c0eec vgchange, vgcreate: add systemid option to command help 2015-02-20 15:31:17 -06:00
3361e662f4 man: systemid option for vgcreate and vgchange 2015-02-20 14:58:01 -06:00
55dd45239a tests: skip system_id machineid case when not available
instead of creating a fake /etc/machine-id file on the
system to test with.
2015-02-20 13:12:38 -06:00
e0946dca69 man lvmsystemid: expanded limitations and warnings 2015-02-20 12:21:23 -06:00
6bc35a351a report: fix foreign reporting without lvmetad 2015-02-19 15:24:31 -06:00
b896bf8f5a tests: add system_id test 2015-02-19 14:42:39 -06:00
0c6faaab43 doc: explanation of caching foreign VGs 2015-02-19 11:33:23 -06:00
97e3e84c2c man: update lvmthin about repair and recovery
Explain the thin metadata repair might not work.
Clarify that a full thin pool won't require fsck for journaled fs.
2015-02-19 10:49:39 -06:00
f80e7bb61b configure: typo in configure --with-default-raid10-segtype causing it to be unrecognized
AC_ARG_WITH(default-raid10r-segtype --> AC_ARG_WITH(default-raid10-segtype

(...raid10r... --> ...raid10... - extra "r")
2015-02-19 16:19:15 +01:00
af395e61d5 cleanup: drop unused header file 2015-02-19 14:44:04 +01:00
a18d789684 cleanup: simplify error path code
Mempool needs to free only with first alllocated element,
everything allocated afterwards is released as well.
2015-02-19 14:44:04 +01:00
4c184e9d6b cleanup: drop unused value assign
Dop unused value assignments.

Unknown is detected via other combination
(!linear && !striped).

Also change the log_error() message into a warning,
since the function is not really returning error,
but still keep the INTERNAL_ERROR.

Ret value is always set later.
2015-02-19 14:43:25 +01:00
ed420fb691 pvcreate: switch to "none" dev-ext source during pvcreate
The dev ext source must be reset for the dev_cache_get call
(which evaluates filters), not lvmcache_label_scan - so fix
original commit 727c7ff85d.

Also, add comments in _pvcreate_check fn explaining why
refresh filter and rescan is needed and exactly in which
situations.
2015-02-19 14:34:55 +01:00
69b1e32c8a wiping: blkid: do not count skipped signatures in final number of wipes
We exclude some signatures from being wiped when using blkid wiping.
These are signatures which we simply overwrite. For example, the
LVM2_member signature which denotes a PV - if we call pvcreate on
existing PV, we just overwrite the PV header, no need to wipe it.

Previously, we counted such signatures as if they were wiped
and they were counted in the final number of wiped signatures
that _wipe_known_signatures_with_blkid fn returned in the "wiped"
output arg. Then the code checking this output arg could be
mislead that wiping happened while no wiping took place in real
and we could fire some code uselessly based on this information
(e.g. refreshing filters/rescanning - see also
commit 6b4066585f).
2015-02-19 13:30:05 +01:00
373f855684 clvmd: Fix BZ 1140095 by updating lastfd upon EINTR. 2015-02-18 12:45:43 +01:00
88411fb6f9 test: Avoid a race in pvmove-restart.sh. 2015-02-18 12:27:47 +01:00
733e3f6f98 test: Make pvmove0 device removal more robust, in pvmove-restart.sh. 2015-02-18 10:21:06 +01:00
10b8d2a4ea tests: hide uninteresting output
We don't care about diff output.
2015-02-17 15:54:21 +01:00
973afcbb20 NIX: Fix a typo that broke evaluation of fc19+. 2015-02-17 15:32:04 +01:00
a009c0fb40 cleanup: fix compate of return value
Drop '!' for 'ret' compare.
Since the effect of false compare was only stack trace printing,
it present no real code flow change.
2015-02-17 13:40:35 +01:00
4bb60c05bf cleanup: drop !! from code
It's unused piece of code - but gcc5 noticed problem with
usage of !! on the leftside.
2015-02-17 13:39:47 +01:00
cb144c0097 cleanup: drop unused val 2015-02-17 13:39:26 +01:00
cd1a76a492 tests: syncaction update
Improve syncaction testing with some minor
workaround for current upstream kernel
2015-02-17 11:05:04 +01:00
120e1aa4bd tests: ensure lv1 goes away first
$lv1 may appear in the table after -pvmove0 which could make -pvmove0
unremovable.
2015-02-17 11:05:04 +01:00
6b4066585f filters: no need to refresh filters/rescan if no signature is wiped during pvcreate at all
Before, we refreshed filters and we did full rescan of devices if
we passed through wiping (wipe_known_signatures fn call). However,
this fn returns success even if no signatures were found and so
nothing was wiped. In this case, it's not necessary to do the
filter refresh/rescan of devices as nothing changed clearly.

This patch exports number of wiped signatures from all the
wiping functions below. The caller (_pvcreate_check) then checks
whether any wiping was done at all and if not, no refresh/rescan
is done, saving some time and resources.
2015-02-17 09:46:34 +01:00
1ee82b545b spec: Include lvmsystemid.7 in RPMs. 2015-02-16 17:15:03 +01:00
78d7466713 NIX: Fix CentOS builds. 2015-02-16 15:32:01 +01:00
df28c4d912 NIX: Resolve issues with fedora-release and kernel-modules-extra. 2015-02-16 15:32:01 +01:00
727c7ff85d pvcreate: switch to "none" dev-ext source during pvcreate
pvcreate code path executes signature wiping if there are any signatures
found on device to prepare the device for PV. When the signature is wiped,
the WATCH udev rule triggers the event which then updates udev database
with fresh info, clearing the old record about previous signature.

However, when we're using udev db as dev-ext source, we'd need to wait
for this WATCH-triggered event. But we can't synchronize against such
events (at least not at this moment). Without this sync, if the code
continues, the device could still be marked as containing the old
signature if reading udev db. This may end up even with the device
to be still filtered, though the signature is already wiped.

This problem is then exposed as (an example with md components):

$  mdadm --create /dev/md0 --level=1 --raid-devices=2 /dev/sda /dev/sdb --run
$  mdadm -S /dev/md0
$  pvcreate -y /dev/sda
Wiping linux_raid_member signature on /dev/sda.
/dev/sda: Couldn't find device.  Check your filters?
$ echo $?
5

So we need to temporarily switch off "udev" dev-ext source here
in this part of pvcreate code until we find a way how to sync
with WATCH events.

(This problem does not occur with signature wiping which we do
on newly created LVs since we already handle this properly with
our udev flags - the LV_NOSCAN/LV_TEMPORARY flag. But we can't use
this technique for non-dm devices to keep WATCH rule under control.)
2015-02-16 15:07:00 +01:00
032c9178ca conf: Set default global/etc from --with-confdir. 2015-02-13 19:10:10 +00:00
d726246f78 system_id: warn if the system_id_file cannot be opened 2015-02-13 11:37:11 -06:00
def0866ded system_id: omit leading hyphens from system_id 2015-02-13 11:14:46 -06:00
737c992431 toollib: add underscore to static ignore_vg function 2015-02-13 11:01:55 -06:00
d3f3878ffd WHATS_NEW for system_id 2015-02-13 10:27:17 -06:00
8cdec4c434 system_id: use for VG ownership
See included lvmsystemid(7) for full description.
2015-02-13 10:10:27 -06:00
f5d06efbab vgextend: Use process_each_vg.
Tags and --select are not yet supported because new code is needed
to ensure exactly one VG matches before the VG starts to be processed.
2015-02-13 14:58:51 +00:00
1ced5562cd tests: fix pvcreate-operation-md test to properly clean up devs before their reuse
pvcreate filters out devices with existing partitions defined on them,
we need to properly clean up the devs before we reuse them.
2015-02-13 14:53:26 +01:00
993c988895 tests: comment in select-tools.sh 2015-02-13 11:45:13 +01:00
e0ce728579 tolllib: process_each_pv: always use full_filter unconditionally when getting all devices
(This reverts patch #d95c6154)

Filter complete device list through full_filter unconditionally when
we're getting the list of *all* devices even in case we're interested
only in fraction of those devices - the PVs, not the other devices
which are not PVs yet (e.g. pvs vs. pvs -a).

We need to do this full filtering whenever we're handling *complete*
list of devices, we need to be safe here, mainly if there are any
future changes and we'd forgot to change to use proper filtering then.
Also properly preventing duplicates if there are any block subsystem
components used (mpath, MD ...).

Thing here is that (under use_lvmetad=1), cmd->filter can be used
only if we're sure that the list of devices we're filtering contains
only PVs. We have to use cmd->full_filter otherwise (like it is in
case of _get_all_devices fn which acquires complete list of devices,
no matter if it is a PV or not).

Of course, cmd->full_filter is more extensive than cmd->filter
which is only a subset of full_filter.

We could optimize this in a way that if we're interested in PVs only
during process_each_pv processing (e.g. using pvs in contrast to pvs -a),
we'd get the list of PV devices directly from lvmetad from the
lvmcache_seed_infos_from_lvmetad fn call which currently updates
lvmcache only. We'd add an additional output arg for this fn to get
the list of PV devices directly in addition, without a need to iterate
over all devices which include non-PVs which we're not interested in
anyway, hence we could use only cmd->filter, not the cmd->full_filter.

So the code would look something like this:

static int _get_all_devices(....)
{
	struct device_id_list *dil;

	if (interested_in_pvs_only)
		lvmcache_seed_infos_from_lvmetad(cmd, &dil); /* new "dil" arg */
		/* the "dil" list would be filtered through cmd->filter inside lvmcache_seed_infos_from_lvmetad */
	else {
		lvmcache_seed_infos_from_lvmetad(cmd, NULL);
		dev_iter_create(cmd->full_filter)
		while (dev = dev_iter_get ...) {
			dm_list_add(all_devices, &dil->list);
		}
	}
}
2015-02-13 11:27:09 +01:00
1c005b557a tests: select-tools.sh: pvchange now uses process_each_pv
pvchange now uses process_each_pv so uncomment parts of the test
which check proper functionality of intersection between selection
result and PVs or PV tags directly provided on command line. This
didn't work properly before when pvchange was not using process_each_pv.

For example:

  pvchange -u -S 'pv_name=/dev/sda' /dev/sdb

..changes nothing since clearly the intersection of /dev/sda and
/dev/sdb is empty set. The same applies for tags:

  pvchange -u -S 'pv_name=/dev/sda' @some_tag

..changes nothing if /dev/sda is not tagged with some_tag.
2015-02-13 11:27:09 +01:00
969d2bf448 cleanup: remove deallocate_handle_root arg from destroy_procesing_handle fnw 2015-02-13 11:27:09 +01:00
66b10d6d12 cleanup: replace static struct processing_handle initializer with common init_processing_handle
It's cleaner this way - do not mix static and dynamic
(init_processing_handle) initializers. Use the dynamic one everywhere.
This makes it easier to manage the code - there are no "exceptions"
then and we don't need to take care about two ways of initializing the
same thing - just use one common initializer throughout and it's clear.

Also, add more comments, mainly in the report_for_selection fn explaining
what is being done and why with respect to the processing_handle and
selection_handle.
2015-02-13 11:26:57 +01:00
1a72933143 pvchange: no need to initialize selection handle directly, process_each_pv will do that automatically 2015-02-13 09:29:30 +01:00
e1710f34bb lvchange: change msg about required params (LV or selection) to be consistent with msgs used in other tools 2015-02-13 09:04:21 +01:00
e4e703ab60 pvchange: Use process_each_pv.
Invalid devices no longer included in the counters printed at the end.
May now need to use --ignoreskippedcluster if relying upon exit status.
If more than one change is requested per-PV, attempt to perform them
all.  Note that different arguments still handle exit status
differently.
2015-02-12 16:37:47 +00:00
acb6c06207 autoreconf: recent changes
autoconf-2.69-14.fc20.noarch
automake-1.13.4-6.fc20.noarch
2015-02-12 15:48:12 +01:00
77ceb3ee47 valgrind: when executed within valrind skip close
Since valgrind uses internal file descriptors for communication,
don't try to close them in this case.
2015-02-12 15:40:54 +01:00
9809038b9d memory: disable check with valgrind pool build
When lvm2 is build with valgrind pool detection - always disable
memcheck, since pool memory allocation are unconditionaly passed
into valgrind library.
2015-02-12 15:40:53 +01:00
425c04e4dc configure.in: AC_SUBST needs to be always executed 2015-02-12 15:40:53 +01:00
d303d9973f tests: BACKING_DEV
Reset BACKING_DEV when it's same as LOOP.
Reset only 64K - so just eats a bit less space from underlaying loop
devices...
2015-02-12 15:40:52 +01:00
4b7097b96c tests: ensure array is synchronized
Before continue of repair test, ensure mirror is in sync
2015-02-12 15:38:51 +01:00
739b751046 tests: don't crash if checked string is shorter
Not really sure what is this testing - just avoid coredump if
the test cannot happen since the index would too high.
2015-02-12 15:38:51 +01:00
b1002e98e0 makefiles: more _CFLAGS for -MM
Move of valgrind flags to _CFLAGS make the -MM generation
not compilable (d571eab3b2)

Add these _CFLAGS right into .c->.d rules
(as well as  UDEV)
2015-02-12 15:38:50 +01:00
65d95caad5 tests: respect LVM_TEST_DIR
Check for empty LVM_TEST_DIR
(regression from 48275c7836)
2015-02-12 15:38:50 +01:00
d95c6154ff toollib: process_each_pv: fix commit d38d047e which worked for processing "all devices", but didn't work for "all PVs"
We still need to get the list as the calls underneath process_each_pv
rely on this list. But still keep the change related to the filters -
if we're processing all devices, we need to use cmd->full_filter.
If we're processing only PVs, we can use cmd->filter only to save
some time which would be spent in filtering code.
2015-02-12 14:14:45 +01:00
e52c998c49 toollib: process_each_pv: use cmd->full_filter, not cmd->filter if we're getting full list of PV-capable devices (not just PVs)
When lvmetad is used and at the same time we're getting list of all
PV-capable devices, we can't use cmd->filter (which is used to filter
out lvmetad responses - so we're sure that the devices are PVs already).

To get the list of PV-capable devices, we're bypassing lvmetad (since
lvmetad only caches PVs, not all the other devices which are not PVs).
For this reason, we have to use the "full_filter" filter chain (just
like we do when we're running without lvmetad).

Example scenario:
- sdo and sdp components of MD device md0
- sdq, sdr and sds components of mpatha multipath device
- mpatha multipath device partitioned
- vda device partitioned

=> sdo,sdp,sdr,sds, mpatha and vda should be filtered!

$ lsblk -o NAME,TYPE
NAME            TYPE
sdn             disk
sdo             disk
`-md0           raid0
sdp             disk
`-md0           raid0
sdq             disk
`-mpatha        mpath
  `-mpatha1     part
sdr             disk
`-mpatha        mpath
  `-mpatha1     part
sds             disk
`-mpatha        mpath
  `-mpatha1     part
vda             disk
|-vda1          part
`-vda2          part
  |-fedora-swap lvm
  `-fedora-root lvm

Before this patch:
==================
use_lvmetad=0 (correct behaviour!)
$ pvs -a
  PV                  VG     Fmt  Attr PSize PFree
  /dev/fedora/root                ---     0     0
  /dev/fedora/swap                ---     0     0
  /dev/mapper/mpatha1             ---     0     0
  /dev/md0                        ---     0     0
  /dev/sdn                        ---     0     0
  /dev/vda1                       ---     0     0
  /dev/vda2           fedora lvm2 a--  9.51g    0

use_lvmetad=1 (incorrect behaviour - sdo,sdp,sdq,sdr,sds and mpatha not filtered!)
$ pvs -a
  PV                  VG     Fmt  Attr PSize PFree
  /dev/fedora/root                ---     0     0
  /dev/fedora/swap                ---     0     0
  /dev/mapper/mpatha              ---     0     0
  /dev/mapper/mpatha1             ---     0     0
  /dev/md0                        ---     0     0
  /dev/sdn                        ---     0     0
  /dev/sdo                        ---     0     0
  /dev/sdp                        ---     0     0
  /dev/sdq                        ---     0     0
  /dev/sdr                        ---     0     0
  /dev/sds                        ---     0     0
  /dev/vda                        ---     0     0
  /dev/vda1                       ---     0     0
  /dev/vda2           fedora lvm2 a--  9.51g    0

With this patch applied:
========================
use_lvmetad=1
$ pvs -a
  PV                  VG     Fmt  Attr PSize PFree
  /dev/fedora/root                ---     0     0
  /dev/fedora/swap                ---     0     0
  /dev/mapper/mpatha1             ---     0     0
  /dev/md0                        ---     0     0
  /dev/sdn                        ---     0     0
  /dev/vda1                       ---     0     0
  /dev/vda2           fedora lvm2 a--  9.51g    0
2015-02-12 13:46:11 +01:00
d38d047eec toollib: process_each_pv: do not acquire list of all devices if not necessary
List of all devices is only needed if we want to process devices
which are not PVs (e.g. pvs -a). But if this is not the case, it's
useless to get the list of all devices and then discard it without
any use, which is exactly what happened in process_each_pv where
the code was never reached and the list was unused if we were
processing just PVs, not all PV-capable devices:

int process_each_pv(...)
{
	...
	process_all_devices = process_all_pvs &&
			      (cmd->command->flags & ENABLE_ALL_DEVS) &&
			      arg_count(cmd, all_ARG);
	...
	/*
	 * If the caller wants to process all devices (not just PVs), then all PVs
	 * from all VGs are processed first, removing them from all_devices.  Then
	 * any devs remaining in all_devices are processed.
	*/
	_get_all_devices(cmd, &all_devices);
	...
	ret = _process_pvs_in_vgs(...);
	...
	if (!process_all_devices)
		goto out;

        ret = _process_device_list(cmd, &all_devices, handle, process_single_pv);
	...
}

This patch adds missing check for "process_all_devices" and it gets the
list of all (including non-PV) devices only if needed:
2015-02-12 13:46:11 +01:00
0e9f3dba75 test: Fix missing return in new test harness. 2015-02-12 13:28:26 +01:00
cc755853c2 config: fix version of introduction for devices/external_device_info_source (v115->v116) 2015-02-12 09:30:40 +01:00
54c2e9859f tests: add select-tools.sh to test selection support in toollib
Tests for selection within non-reporting tools while using process_each_* fns.
2015-02-11 18:39:47 +01:00
599cb41f99 tests: rename report-select.sh to select-report.sh
Let's name all selection-related tests with the "select-" prefix for
better sorting.
2015-02-11 16:17:05 +01:00
263f7831df report: define ba_start, vg_free and seg_start fields as DM_REPORT_FIELD_TYPE_SIZE instead of DM_REPORT_FIELD_TYPE_NUM
This makes a difference when using selection criteria based on
these fields - if those fields are defined as DM_REPORT_FIELD_TYPE_SIZE
(in contrast to DM_REPORT_FIELD_TYPE_NUMBER), units are also
recognize in selection clause.

For example:
$ lvs -o+seg_start vg1/lv2
  LV   VG   Attr       LSize  Start
  lv2  vg1  -wi-a----- 12.00m    0
  lv2  vg1  -wi-a----- 12.00m 8.00m

Before this patch:
$ lvs -o+seg_start --select 'seg_start=8m'
  Found size unit specifier but numeric value expected for selection field seg_start.
  Selection syntax error at 'seg_start=8m'.
  Use 'help' for selection to get more help.

With this patch applied:
$lvs -o+seg_start --select 'seg_start=8m'
  LV   VG   Attr       LSize  Start
  lv2  vg1  -wi-a----- 12.00m 8.00m

(the same applies for ba_start and vg_free fields)
2015-02-11 13:57:18 +01:00
b88b75f55f conf: update profile templates for recent changes 2015-02-11 13:22:31 +01:00
437b17964c man: reference -S/--select in {vg,lv,pv}change, {vg,lv}remove, {vg,lv,pv}display and vg{import,export} man pages 2015-02-11 10:04:21 +01:00
bc1bb7f8c5 toollib: select: issue an error message for failed VG/LV/PV selection 2015-02-11 09:36:09 +01:00
3505e88b18 man: dumpconfig: mention LVM_COMMAND_PROFILE env var and add more references to --mergedconfig option
The LVM_COMMAND_PROFILE env var is new - mention it in dumpconfig's
man page.

Also, dumpconfig always displays the top of the config cascade.
To display all the config found in the cascade merged (just like
it's used during LVM command processing), --mergedconfig option
must be used - this one's already described in that man page,
just make sure it's clear and add reference for this option also
in --profile/--commandprofile/--metadataprofile description.
2015-02-11 09:34:19 +01:00
801e47e089 NIX: Drop Fedora 16 builds. 2015-02-10 17:27:10 +01:00
79dc8f5ddd NIX: Adjust lists of extra RPMs to install. 2015-02-10 17:27:10 +01:00
a8b45b7a4c test: Fix harness not building on RHEL5 2015-02-10 17:02:01 +01:00
7f2eebf519 select: initialize selection handle for process_each_* fns with initial report type
This is a followup patch for previous patchset that enables selection in
process_each_* fns to fix an issue where field prefixes are not
automatically used for fields in selection criteria.

Use initial report type that matches the intention of each process_each_* functions:
- _process_pvs_in_vg - PVS
- process_each_vg - VGS
- process_each_lv and process_each_lv_in_vg - LVS

This is not normally needed for the selection handle init, BUT we would
miss the field prefix matching, e.g.

lvchange -ay -S 'name=lvol0'

The "name" above would not work if we didn't initialize reporting with
the LVS type at its start. If we pass proper init type, reporting code
can deduce the prefix automatically ("lv_name" in this case).

This report type is then changed further based on what selection criteria we
have. When doing pure selection, not report output, the final report type
is purely based on combination of this initial report type and report types
of the fields used in selection criteria.
2015-02-10 16:10:17 +01:00
80cca53611 tools: allow -S|--select for vgexport and vgimport 2015-02-10 16:10:17 +01:00
b93f586954 tools: allow -S|--select for vgdisplay, lvdisplay and pvdisplay without -C
We already allowed -S|--select with {vg,lv,pv}display -C (which
was then equal to {vg,lv,pv}s command. Since we support selection
in toolib now, we can support -S also without using -C in *display
commands now.
2015-02-10 16:09:40 +01:00
00744b053f tools: allow -S|--select for vgremove and lvremove 2015-02-10 16:08:42 +01:00
f784c60cd6 tools: allow -S|--select for vgchange, lvchange and pvchange 2015-02-10 16:08:04 +01:00
d6c8f0de28 pvchange: use processing_handle when processing items for pvchange
pvchange is an exception that does not use toollib yet for iterating
over the list of PVs (process_each_pv) so intialize the
processing_handle and use just like it's used in toollib.
2015-02-10 16:07:01 +01:00
56846d7873 report: implement report_for_selection
We have 3 input report types:
  - LVS (representing "_select_match_lv")
  - VGS (representing "_select_match_vg")
  - PVS (representing "_select_match_pv")

The input report type is saved in struct selection_handle's "orig_report_type"
 variable.

However, users can use any combination of fields of different report types in
selection criteria - the resulting report type can thus differ. The struct
selection_handle's "report_type" variable stores this resulting report type.

The resulting report_type can end up as one of:
  - LVS
  - VGS
  - PVS
  - SEGS
  - PVSEGS

This patch adds logic to report_for_selection based on (sensible) combination
of orig_report_type and report_type and calls appropriate reporting functions
or iterates over multiple items that need reporting to determine the selection
result.
2015-02-10 16:06:53 +01:00
984ae7f72d report: add report_for_selection and use it in select_match_{pv,vg,lv}
The report_for_selection does the actual "reporting for selection only".
The selection status will be saved in struct selection_handle's "selected"
variable.
2015-02-10 16:05:36 +01:00
e5b345aff3 refactor: report: factor out code to determine final report type
The code to determine final report type based on combination of input
report type (determined from fields used for reporting to output and selection)
can be reused for pure reporting for selection - factor out this code into
_get_final_report_type function.
2015-02-10 16:05:35 +01:00
de27324711 toollib: select the whole structure if at least one of its items is selected
This applies to:
  - process_each_lv_in_vg - the VG is selected only if at least one of its LVs is selected
  - process_each_segment_in_lv - the LV is selected only if at least one of its LV segments is selected
  - process_each_pv_in_vg - the VG is selected only if at least one of its PVs is selected
  - process_each_segment_in_pv - the PV is selected only if at least one of its PV segments is selected

So this patch causes the selection result to be properly propagated up to callers.
2015-02-10 16:05:32 +01:00
56011918e6 toollib: initialize handles (including reporting for selection) for _select_match_* used in process_each_* fns
Call _init_processing_handle, _init_selection_handle and
_destroy_processing_handle in process_each_* and related functions to
set up and destroy handles used while processing items.
2015-02-10 16:05:29 +01:00
a91bc7a19b toollib: add init_processing_handle, init_selection_handle and destroy_processing_handle helper functions
The init_processing_handle, init_selection_handle and
destroy_processing_handle are helper functions that allocate and
initialize the handles used when processing items in process_each_*
and related functions.
2015-02-10 16:05:27 +01:00
c3180c4a05 toollib: pass struct processing_handle to _select_match_* functions
The "struct processing_handle" contains handles to drive the selection/matching
so pass it to the _select_match_* functions which are entry points to the
selection mechanism used in process_each_* and related functions.

This is revised and edited version of former Dave Teigland's patch which
provided starting point for all the select support in process_each_* fns.
2015-02-10 16:05:26 +01:00
a64b39aef8 report: add report_init_for_selection fn and modify report_object to support reporting for selection only
The new "report_init_for_selection" is just a wrapper over
dm_report_init_with_selection that initializes reporting for selection
only. This means we're not going to do the actual reporting to output
for display and as such we intialize reporting as if no fields are reported
or sorted. The only fields "reported" are taken from the selection criteria
string and all such fields are marked as hidden automatically (FLD_HIDDEN flag).
These fields are used solely for selection criteria matching.

Also, modify existing report_object function that was used for reporting to
output for display. Now, it can either cause reporting to output or reporting
for selection only. The selection result is stored in struct selection_handle's
"selected" variable which can be handled further by any report_object caller.
2015-02-10 16:05:25 +01:00
51d96a1703 toollib: replace void *handle with struct processing_handle for use in processing functions (process_each_*/process_single_* and related)
This patch replaces "void *handle" with "struct processing_handle *handle"
in process_each_*, process_single_* and related functions.

The struct processing_handle consists of two handles inside now:

  - the "struct selection_handle *selection_handle" used for
    applying selection criteria while processing process_each_*,
    process_single_* and related functions (patches using this
    logic will follow)

  - the "void* custom_handle" (this is actually the original handle
    used before this patch - a pointer to custom data passed into
    process_each_*, process_single_* and related functions).
2015-02-10 16:05:24 +01:00
2a19866a74 cleanup: make report type condition consistent with the rest of the code
It's just more readable this way (each condition resulting in a certain
report type is always on one line), just like it's used elsewhere in the
code.
2015-02-10 16:05:23 +01:00
455ef6f2f5 toollib: prepare select_match_{pv,vg,lv} hooks
These hooks will check currently processed PV/VG/LV with current selection
criteria and the processing continues only if there's a match.
2015-02-10 16:04:41 +01:00
123a3383a0 libdm: report: add dm_report_object_is_selected
The new dm_report_object_is_selected fn makes it possible to opt whether the
object reported should be displayed on output or not. Also, in addition to
that, it makes it possible to save the result of selection (either 0 or 1).

So dm_report_object_is_selected is simply  more general form of object
reporting fn - combinations now allow for:

  dm_report_object_is_selected(rh, object, 1, NULL):
  This is exactly the original dm_report_object fn and it's fully equal
  to it.

  dm_report_object_is_selected(rh, object, 0, selected):
  Do not display the result on output, but save info whether the object
  is selected or not in 'selected' variable.

  dm_report_object_is_selected(rh, object, 1, selected):
  Display the result on output (if it passes selection criteria) and save
  whether the object is selected or not in 'selected' variable.

  dm_report_object(rh, object, 0, NULL):
  This combination is not allowed - it will end up with internal error.
  We're either interested in selection status or we want to display the
  result on output or both, but never nothing of the two.
2015-02-10 16:04:38 +01:00
2ee3bcb877 test: Fix a typo in shell/pvmove-restart.sh. 2015-02-10 12:42:05 +01:00
b6f558adcc lvm: recognize LVM_COMMAND_PROFILE env var for default command profile to use in LVM commands
Once LVM_COMMAND_PROFILE environment variable is specified, the profile
referenced is used just like it was specified using "<lvm command> --commandprofile".
If both --commandprofile cmd line option and LVM_COMMAND_PROFILE env
var is used, the --commandprofile cmd line option gets preference.
2015-02-09 14:16:30 +01:00
4e4ea46cfe reporter: properly check for _do_info_and_status return value and free the mempool if created within the fn 2015-02-09 11:48:21 +01:00
4065741a67 configure: Fix a warning about test/Makefile.in. 2015-02-05 16:30:50 +01:00
43d6b44a9f NIX: Request {fedora,centos}-release packages explicitly. 2015-02-05 14:21:31 +01:00
b9a017d94c NIX: Adjust install_rpms (kernel rpm is now required). 2015-02-05 13:51:39 +01:00
81b34dce61 NIX: We need to install lcov for ./configure now as well. 2015-02-05 13:51:38 +01:00
5cd6cce5a4 NIX: Move corosynclib-devel & valgrind-devel out of common. 2015-02-05 13:51:37 +01:00
57c39ecbcd NIX: Allow adding/overriding test configurations. 2015-02-05 13:51:07 +01:00
7c9d690f9e NIX: Set ulimit -c to unlimited, to get backtraces in logs. 2015-02-05 13:51:07 +01:00
6ba05212f7 NIX: Add a CentOS 7.0 64b build. 2015-02-05 13:51:06 +01:00
4686b8cea5 test: Fix a segfault in the test runner. 2015-02-05 13:51:06 +01:00
45e2aee8f9 test: It is not an error for a test daemon to exit before teardown. 2015-02-05 13:51:06 +01:00
78ba413ed1 test: Remove spurious set -x in lvm-wrapper. 2015-02-05 13:51:06 +01:00
d8983d4bd4 test: Properly detect warnings from testcases. 2015-02-05 13:51:06 +01:00
c96e42006d test: Only force an IO sync when the testcase has finished. 2015-02-05 13:51:06 +01:00
72ee3f920b test: Allow a longer timeout for lvextend-snapshot-dmeventd. 2015-02-05 13:51:06 +01:00
839ea48aa9 test: Make dmsetup remove more robust in pvmove-restart. 2015-02-05 13:51:06 +01:00
210a66fbf8 test: Make killing local (test) daemons more robust. 2015-02-05 13:51:06 +01:00
17575403d4 test: Disable lvmetad debug log on another bunch of tests. 2015-02-05 13:51:06 +01:00
1f727f3f3d test: Call $VALGRIND directly in lvm-wrapper. 2015-02-05 13:51:06 +01:00
3af008d405 NIX: Add valgrind-devel to the build environment. 2015-02-05 13:51:04 +01:00
2a8dc7fb53 memlock: Do not check memory balance if RUNNING_ON_VALGRIND. 2015-02-05 13:50:34 +01:00
d571eab3b2 configure: Look for valgrind.h independently of VALGRIND_POOLS. 2015-02-05 13:50:34 +01:00
5d833fd458 test: Add support for running LVM commands in tests through strace. 2015-02-05 13:50:34 +01:00
a6d006d9db test: Make lvm-wrapper available in the installed testsuite, too. 2015-02-05 13:50:33 +01:00
41c2e07a8d NIX: Install valgrind, gdb and strace in the test environment. 2015-02-05 13:50:23 +01:00
e4d5e22c91 NIX: Make timeout and test envvars configurable via --arg. 2015-02-05 13:47:21 +01:00
c2b7642d4d test: Fix prepare_scsi_debug_dev. 2015-02-05 13:47:21 +01:00
580370bea3 test: Avoid passing -c to flock. 2015-02-05 13:47:21 +01:00
7a0aa25c28 test: Re-try with loopback if a backing device is too small. 2015-02-05 13:47:21 +01:00
f3cc6576ee NIX: Detect that the VM booted up more directly. 2015-02-05 13:47:21 +01:00
734a183c56 NIX: Avoid a spurious failure when all tests pass. 2015-02-05 13:47:21 +01:00
bd0806e1f5 test: Fix failures due to undefined abs_top_builddir. 2015-02-05 13:47:21 +01:00
c6f9c46223 test: Avoid running 'dmsetup remove' with no devices. 2015-02-05 13:47:21 +01:00
ad0267b2ad test: Fix 100%FREE RAID tests since test device sizes changed slightly. 2015-02-05 13:47:20 +01:00
c82c69bb56 test: Update brick-shelltest (configurable timeout, better banner, exit code). 2015-02-05 13:47:20 +01:00
b6884f8a87 NIX: Mark builds with failed tests as such. 2015-02-05 13:47:20 +01:00
8b80e949ea test: Do not rely on dev/mapper/* nodes in pvmove-restart.sh. 2015-02-05 13:47:20 +01:00
d04c7ca0b6 test: Fix implementation of check targets with new flavour system. 2015-02-05 13:47:20 +01:00
68f7b422c1 NIX: Update path to /xchg (was /tmp/xchg with older nixpkgs). 2015-02-05 13:47:20 +01:00
f1d273a0b0 NIX: Do not fail aggregation when a sub-job fails to produce output. 2015-02-05 13:47:20 +01:00
93d8455faa NIX: Run each test flavour as a separate derivation. 2015-02-05 13:47:20 +01:00
003bf24723 NIX: Add --kmsg to lvm2-testsuite invocations. 2015-02-05 13:47:20 +01:00
7ed8fc8f7d test: Update brick-shelltest.h. 2015-02-05 13:47:20 +01:00
f9df76f8b3 NIX: Keep the udev log out of tmpfs. 2015-02-05 13:47:20 +01:00
e2dbf44116 NIX: Some kernels need ide/ata modules (i.e. no builtin ata). 2015-02-05 13:47:20 +01:00
eaa9f35540 NIX: Use IDE drive emulation instead of virtio. 2015-02-05 13:47:20 +01:00
c2aa918c53 libdaemon: Use select to yield CPU on a blocked read or write. 2015-02-05 13:47:20 +01:00
19bb62e2ec test: Update brick-shelltest, adding timestamps to logs. 2015-02-05 13:47:20 +01:00
f9dfc5f8a4 NIX: Use the new --heartbeat option on lvm2-testsuite. 2015-02-05 13:47:19 +01:00
8646b50aa9 test: Package up the test runner in a reusable C++ "brick". 2015-02-05 13:47:19 +01:00
f28407943f NIX: Pass --fatal-timeouts to the testsuite. 2015-02-05 13:47:19 +01:00
eec99ffa8c test: Implement --fatal-timeouts to allow a timely VM restart. 2015-02-05 13:47:19 +01:00
34e818042e test: Make the runner's heartbeat more reliable. 2015-02-05 13:47:19 +01:00
f0d314bd6d test: Disable lvmetad logging in lvconvert-{mirror,raid}*. 2015-02-05 13:47:19 +01:00
fa2e84caa8 NIX: Re-work VM monitoring. 2015-02-05 13:47:19 +01:00
f96c310eea NIX: Add Fedora 20 jobs. 2015-02-05 13:47:19 +01:00
0abad40f41 NIX: Existence of results list no longer indicates that the suite has finished. 2015-02-05 13:47:19 +01:00
e3ac180ab3 NIX: Drop -h from rpm invocations as it messes up logs. 2015-02-05 13:47:19 +01:00
6380869f27 NIX: Use nixpkgs kernel for building, distro kernel for testing. 2015-02-05 13:47:19 +01:00
2b6f9152cc NIX: Adapt to the append-based test journal. 2015-02-05 13:47:19 +01:00
285db7a240 NIX: Implement a smarter VM monitoring loop. 2015-02-05 13:47:19 +01:00
dcf5182a96 NIX: Use --batch mode for running the testsuite. 2015-02-05 13:47:19 +01:00
4b5ae31404 NIX: Refactor around the new test runner.
- The RPM build and the tests are now executed in separate VMs.
- Run the testsuite by using the new lvm2-testsuite RPM.
- The VM running the tests is restarted from the outside if it hangs, and the
  runner keeps a journal to avoid running a bad test ad infinitum.
- TODO: lcov reports and more intelligent VM rebooting (track the journal)
2015-02-05 13:47:19 +01:00
d5537e7d6b spec: Add an (optional) lvm2-testsuite subpackage. 2015-02-05 13:47:18 +01:00
d488f03229 test: Implement --only option to runner. 2015-02-05 13:47:18 +01:00
a8eb702093 test: Fix loading of an append-mode journal. 2015-02-05 13:47:18 +01:00
d74c147223 test: Add a missing copyright/licence notice to journal.h. 2015-02-05 13:47:18 +01:00
10c992e861 test: Fix a precedence bug in the runner. 2015-02-05 13:47:18 +01:00
b3caba849d test: Use append for journal maintenance instead of rename. 2015-02-05 13:47:18 +01:00
23b5a006d4 test: Implement specialised --batch output style w/ rusage stats. 2015-02-05 13:47:18 +01:00
a665b90623 test: Add time/rusage formatting to the runner. 2015-02-05 13:47:18 +01:00
3fbea6029d test: Print a heartbeat file (every 20s) in the runner. 2015-02-05 13:47:18 +01:00
e8cc9254e0 test: Avoid sleeps in the runner monitoring loop. 2015-02-05 13:47:18 +01:00
48275c7836 test: Run in /tmp if LVM_TEST_DIR is unset. 2015-02-05 13:47:18 +01:00
246fecee27 test: Rename the --quiet option to --batch. 2015-02-05 13:47:18 +01:00
feb2c7bc47 test: Targets and sources can't have the same name if builddir == srcdir. 2015-02-05 13:47:18 +01:00
2bc76bcdab test: Run the testcases chdir'd into --testdir. 2015-02-05 13:47:18 +01:00
efb3e7ca00 test: Improve IO handling in the runner. 2015-02-05 13:47:18 +01:00
8c8fb67fc2 test: Improve tracking of silence (stuck testcases) in the runner. 2015-02-05 13:47:18 +01:00
dc1d157878 test: Make the runner's journal more reliable. 2015-02-05 13:47:17 +01:00
d27833ba7c test: Implement flavours in the runner. 2015-02-05 13:47:17 +01:00
f3bf89ebcc test: Fix handling of envvars in the runner. 2015-02-05 13:47:17 +01:00
0bd2a9b7b1 test: Makefile updates.
- make check now uses the new test runner
- the testsuite can be installed (make -C test install)
2015-02-05 13:47:17 +01:00
b4215f956f test: Make it possible to run tests from an installed location. 2015-02-05 13:47:17 +01:00
5698953948 test: Use the new flavour setup files in lib/inittest. 2015-02-05 13:47:17 +01:00
9752ee8ed2 test: Fix IO sink destructors in the runner. 2015-02-05 13:47:17 +01:00
df27c64041 test: Add a buffer-backed IO sink (for interactive runs). 2015-02-05 13:47:17 +01:00
f53fcc0746 test: Implement a file-backed IO sink in the runner. 2015-02-05 13:47:17 +01:00
bdd0bc83eb test: Make runner use bigger IO buffers, put them on stack. 2015-02-05 13:47:17 +01:00
7957fc4a44 test: Allow test devices backed by a permanent block device. 2015-02-05 13:47:17 +01:00
c5a120c443 test: Add new flavour definition files. 2015-02-05 13:47:17 +01:00
fa46385164 test: Write a results/list at the end of a test run. 2015-02-05 13:47:17 +01:00
bf16937869 test: Clean up fds properly in the runner. 2015-02-05 13:47:16 +01:00
d2dbc65f00 test: Implement journalling and --continue. 2015-02-05 13:47:16 +01:00
9dfbce0aa7 test: Split up the new runner into multiple files. 2015-02-05 13:47:16 +01:00
b726d66882 test: Use the new runner in make check. 2015-02-05 13:47:16 +01:00
1ec2023cbf test: Build the new test runner. 2015-02-05 13:47:16 +01:00
9d6a92b4d0 configure: Add libexecdir/datadir to make.tmpl.in. 2015-02-05 13:47:16 +01:00
bf1f22cc99 configure: Allow C++ components. 2015-02-03 08:49:35 +01:00
f476655fee test: Import first draft of a new test runner. 2015-02-03 08:49:35 +01:00
f73526f58c libdaemon: set CLOEXEC flag on systemd socket
all sockets opened by a daemon or handed over by systemd
have to have CLOEXEC flag set. Otherwise we get nasty
warnings about leaking descriptors in processes spawned by
daemon.
2015-02-02 10:20:35 +01:00
9dd81df8b2 libdaemon: set CLOEXEC on client socket fd 2015-02-02 10:15:52 +01:00
99c443facc post-release 2015-01-30 16:18:43 +00:00
d0837dcceb pre-release 2015-01-30 16:16:51 +00:00
71e88f761d tests: add --force to sfdisk
Avoid udev sync troubles for now.
2015-01-30 16:46:06 +01:00
04b60e9274 WHATS_NEW
For thin fix.
2015-01-30 16:34:19 +01:00
40102ae014 thin: fix upgrade regression
Older lvm2 tools where always providing linear mapping for thin pool.
Recent lvm2 version however support external usage of thin pool and
empty/unused pools are loaded without such external linear mapping.

So this patch covers 'upgrade' problem, where older tool has activated
thin-pool with 'linear' layer mapping, and newer tools didn't expected
such mapping to exist and were not able to deactivate such table.

So before checking for new layout in dm-table, check if there is not
an old one already there.
2015-01-30 16:22:11 +01:00
a29a3ed3c3 thin: report proper status for thin pool
After commit 158e998876 where we may
start to readlv_attr with a 'shared' ioctl call for a single lvs line
we where obtaing single status for thin pools.
However this is not properly reflecting lvm2 reality.

Correcting this by reading lv status from layered thin pool, but lv info
from non-layered (linear) mapped device which is maintained for proper
cluster locking.
2015-01-30 15:58:12 +01:00
e8aab3a7fd cleanup: conf: auxiliary_device_status_source -> external_device_info_source
auxiliary_device_status_source was name used during development
of this feature, renamed later.
2015-01-30 15:41:42 +01:00
434031719e raid: check lock holding LV
Since raid could be used as stacked LV - check lock holding LV
for proper locking type for clustered usage.
2015-01-30 14:16:27 +01:00
c99cb20715 WHATS_NEW 2015-01-30 13:29:51 +01:00
28ba0450e9 cleanup: add dev-ext-udev-constants.h with constants/names of the properties/values used from udev db 2015-01-30 13:17:12 +01:00
1c7a509bed filters: add firmware RAID filter
Just like MD filtering that detects components of software RAID (md),
add detection for firmware RAID.

We're not adding any native code to detect this - there are lots of
firmware RAIDs out there which is just out of LVM scope. However,
with current changes with which we're able to get device info from
external sources (e.g. external_device_info_source="udev"), we can
do this easily if the external device status source has this kind
of information - which is the case of "udev" source where the results
of blkid scans are stored.

This detection should cover all firmware RAIDs that blkid can detect and
which are identified as:
  ID_FS_TYPE = {adaptec,ddf,hpt45x,hpt37x,isw,jmicron,lsi_mega,nvidia,promise_fasttrack,silicon_medley,via}_raid_member
2015-01-30 13:17:12 +01:00
787f6ce04a filter-partitioned: use new 'udev' device status source to get partition status
Partitioned devices are marked in udev db as:
  ID_PART_TABLE="<partition table type name>"
and at the same time they are *not* marked with:
  ID_PART_ENTRY_DISK="<parent disk major:minor>"

Where partition table type name is dos/gpt/... But checking the presence
of this variable is enough for LVM here - it just needs to know whether
there's a partition table or not, not interested in the actual type.
The same applies for parent disk major:minor.
2015-01-30 13:17:12 +01:00
2fc126b00d filter-usable: move check for pv_min_size from filter-partitioned to filter-usable and use new 'udev' external device info source for this check
The filter-partitioned code should contain only checks in "partition" domain.

The check for pv_min_size should actually be a part of filter-usable.
If the device size is less than pv_min_size, such device is not usable
as a PV so this check clearly belongs here logically.

With udev external info source, we can get device size via libudev's
sysfs reading interface and we can avoid opening the device this way
effectively.
2015-01-30 13:01:12 +01:00
9c030e81a4 filter-mpath: use new 'udev' external device info source to get mpath component status
mpath components are marked in udev db as:
  ID_FS_TYPE="mpath_member"
or
  DM_MULTIPATH_DEVICE_PATH="1"

(it depends on udev rule/blkid version used for handling mpath)
2015-01-30 13:01:12 +01:00
590fbd8961 filter-md: use new 'udev' external device info source to get MD component status
MD components are marked in udev db as:
  ID_FS_TYPE="linux_raid_member"
2015-01-30 13:01:12 +01:00
bf8943b0f6 conf: add devices/external_device_info_source to lvm.conf 2015-01-30 13:01:12 +01:00
c50a90c9e6 filter-composite: add external device info hooks
Composite filter is a filter that can put several filters in one set.
This patch adds a switch when creating the composite filter which will
enable or disable external device info handles for all the filters
the composite filter encompasses.

We want to use this external device info for majority of the filters
which are in the "lvmetad filter chain" (or the respective part if
we're not using lvmetad).

Following patches will use the enabled external device handle in
concrete filters from the composite filter...
2015-01-30 13:01:12 +01:00
fbfde21e7c device: add infrastructure to support external device info 2015-01-30 13:01:12 +01:00
578b236a19 revert "cache: add pool deps for preload"
This reverts commit c3bb6d77dd.

Since we now have  for_each_sub_lv() scanning all sub LVs,
this commit could be safely reverted.
2015-01-30 12:33:52 +01:00
d021284bcf tests: test stacked raid 2015-01-30 12:33:52 +01:00
2055b04c11 cleanup: indent tabs 2015-01-30 12:33:52 +01:00
2e35c68122 lv_manip: add for_each_sub_lv_except_pools()
for_each_sub_lv() now scans in depth also pools, however for
rename we actually do want to skip pools.

So add a new for_each_sub_lv_except_pools() to be used by rename,
every other user of for_each_sub_lv() scans every sub LV with pools
included.

This is i.e. necessary for properly working preload of pools
that are using raid arrays.
2015-01-30 12:33:52 +01:00
c35503e0f7 WHATS_NEW: previous commit 2015-01-30 11:28:10 +01:00
8650404df1 properties: also recognize LVSINFO, LVSSTATUS and LVSINFOSTATUS as subtypes of LVS
LVSINFO, LVSSTATUS and LVSINFOSTATUS is the same as LVS, just with some
extra info/status decoration attached to it. Recognize this when looking
for properties for lvm2app. This fixes lvm_lv_get_property lvm2app call
for fields which already use LVS{INFO,STATUS,INFOSTATUS} - currently,
this is lv_attr field which was converted to LVSINFOSTATUS from
pure LVS type.
2015-01-30 11:13:49 +01:00
531cc58d89 lvm2app: fix lvm_lv_get_attr regression causing unknown values
This is a regression from v115 where some of the fields/properties
were converted to using the common "struct lvinfo" and
"struct lv_seg_status" so we don't need to issue info and status
ioctl several times per one reported line. Not all fields are
converted yet, but one that *is* converted is the lv_attr field
with the lv_attr_dup counterpart used in lvm_lv_get_attr lvm2app fn.

These changes were introduced with e34b004422
and later - this patch introduced the "info_ok" field in the
lv_with_info_and_seg_status structure which encapsulates the lvinfo
and lv_seg_status struct.

For the lv_attr_dup, the lv_attr_dup code  missed the
assignment for the "info_ok" flag which saves the result of the
lv_info_with_seg_status call. Hence such info was marked
as unusable - unknown and it was returned as such via lvm_lv_get_attr
lvm2app fn.
2015-01-30 09:53:34 +01:00
8dc1da2cbe cache: use writethrough cache_mode for older metadata
When cache_mode is undefined, the read of metadata will miss to
set a bit with mode and fails to process metadata on internal
error:

  Internal error: LV vg/lvol1 has uknown feature flags 0.

Fix it by setting it to writethrough mode.
2015-01-29 12:05:58 +01:00
bfeabea631 raid: preload splitted LV only when active
Check splitted leg is active before preload.
(Since splitmirrors currently only does work active raid volumes
it's not a change for current code flow).

Minor optimization included - when already positively checked
for raid image don't check again for raid metadata.
2015-01-28 18:30:08 +01:00
c3bb6d77dd cache: add pool deps for preload
for_each_sub_lv() normally does not put  pool_lv into deps.

So for now go around it in 'lv_preload()' and add explicit
call with pool.

TODO: think about a better way, we want pool_lv deps only in certain
moments, so maybe for_each_sub_lv() needs new arg for this.
2015-01-28 16:29:35 +01:00
4f1309080a thin: preserve chunksize with lvconvert
When repairing thin pool or swapping thin pool metadata,
preserve  chunk_size property and avoid to be automatically changed
later in the code to better match thin pool metadata size.
2015-01-28 15:15:52 +01:00
d2d3f0d747 cleanup: use macro lv_is_visible() 2015-01-28 13:45:27 +01:00
553f37da71 raid: lock holder will skip visible raid LVs
RAID marks legs as VISIBLE with notion it's not longer
true raid leg - so skip tree scannig and take this LV
as top-level LV.
2015-01-28 13:45:27 +01:00
93b9015760 raid: fix raid image splitting
When raid leg is extracted, now the preload code handles this state
correctly and put proper new table entry into dm tree,
so the activation of extracted leg and removed metadata works
after commit.
2015-01-28 13:45:18 +01:00
b254d330e4 raid: fix tree preload for splitting raid images
When raid is being splitted, extracted leg & metadata
is still floating in the table - and thus we need to
detect this case and properly preload their matching
table so consequent activation of extracted LVs properly
renames (and FREES) existing raid images, so ongoing
image name shifting will work.
2015-01-28 13:44:06 +01:00
3e11d85c77 devices: DASD doesn't need to be stackable. 2015-01-23 20:32:31 +00:00
dab3ebce4c devices: Do not support unpartitioned DASD. 2015-01-23 20:01:34 +00:00
4f5ce1fa43 lvm.conf: update error_when_full description
Relate it to the --errorwhenfull option.
2015-01-22 13:01:02 -06:00
4b099d06b1 lvmthin: update monitor and autoextend
and some more in data exhaustion
2015-01-22 12:53:25 -06:00
0fddc5ab5c coverity: missing return value check
Reported by coverity for code added recently - _avoid_pvs_with_other_images_of_lv
which calls process_each_sub_lv and not checking return value.
2015-01-22 10:11:19 +01:00
e0dc3d5efb lvmthin: update data space exhaustion 2015-01-21 14:31:36 -06:00
bea003e94c config: improve config validation to check if setting with string value can be empty.
For example, with dmeventd/executable set to "" which is not allowed for
this setting, the config validation now ends up with:

$ lvm dumpconfig --validate
  Configuration setting "dmeventd/executable" invalid. It cannot be set to an empty value.
  LVM configuration invalid.

This check for empty values for string config settings was not
done before (we only checked empty arrays, but not scalar strings).
2015-01-21 16:44:02 +01:00
57f67ce855 post-release 2015-01-21 13:25:10 +00:00
fa01faaa4a pre-release 2015-01-21 13:08:12 +00:00
25d906dbde dmeventd: Reduce waitevent EINTR message severity. 2015-01-21 12:54:00 +00:00
7cfc9a4f64 libdevmapper: Improve incompatible version msg. 2015-01-21 12:23:56 +00:00
338d98be97 cleanup: for commit 7bcb3fb02d 2015-01-21 11:29:12 +01:00
7bcb3fb02d report: rename lv_error_when_full field to lv_when_full and display either "error", "queue" or ""
Rename original lv_error_when_full field to lv_when_full and also
convert it from binary field to string field displaying three
possible values: "error", "queueu" or "" (blank for undefined).

$ lvs vg/pool vg/pool1 vg/linear_lv -o+lv_when_full
  LV        VG   Attr       LSize Data%  Meta%  WhenFull
  linear_lv vg   -wi-a----- 4.00m
  pool      vg   twi-aotz-- 4.00m 0.00   0.98   queue
  pool1     vg   twi-a-tz-- 4.00m 0.00   0.88   error

For -S|--select these synonyms are recognized:

"error" -> "error when full", "error if no space"
"queue" -> "queue when full", "queue if no space"
   ""   -> "undefined"
2015-01-21 10:50:32 +01:00
5e8f362c9e lvmthin: include errorwhenfull
and don't display the size of pmspare to avoid setting an
expectation of a specific size.
2015-01-20 13:28:34 -06:00
a164d603d3 vgimportclone: remove arg check that uses pvs
The arg check using pvs is unnecessary.  If the arg is not a PV,
the command will just fail later.  Using the pvs command at this
point in the command is a problem when lvmetad is running, because
the pvs command does not report duplicate PVs when using lvmetad.
(Alternatively, use_lvmetad could be disabled by adding a --config
override to this pvs command.)
2015-01-20 13:08:22 -06:00
404c834e14 report: Fix warning in _str_list_append.
../../lib/report/report.c: In function ‘_str_list_append’:
../../lib/report/report.c:256: warning: declaration of ‘dup’ shadows a global declaration
2015-01-20 17:15:28 +00:00
87e80b6aac report: proper lv_attr_dup emulation
We need to create a mempool for proper emulation of lv_attr_dup
for lvm2api.
2015-01-20 16:24:45 +01:00
158e998876 report: add separate LVSINFOSTATUS field type for info+status combined fields
Add separate LVSINFOSTATUS field type for fields which display both
dm info-like and dm status-like information.

The internal interface is there with the introduction of LVSSTATUS
field type which can cope with the combination of LVSSTATUS
and LVSINFO field types (several fields).

However, till now, we considered that *single* field can display
either LVSINFO or LVSSTATUS, but not both at the same time.

Till now, we haven't had single field which needs both - hence
add LVSINFOSTATUS field type for such fields as we currently
need this for the lv_attr field which requires combination of
info and status.

This patch just adds interface for an ability to register such fields
(the code that copes with this is already in).
2015-01-20 16:10:59 +01:00
75b786c5ef thin: support errorwhenfull with thin creation
When thinpool and thinvolume are created at the same time,
still support usage of --errorwhenfull.
2015-01-20 15:43:16 +01:00
a625812bec report: use info
Use LVSINFO since  LVSSTATUS only fills status
2015-01-20 15:25:05 +01:00
3b78d5237d cleanup: indent 2015-01-20 15:02:19 +01:00
3cef00c4ca man: errorwhenfull doc 2015-01-20 15:02:19 +01:00
d80d832ae9 report: seg_monitor undefined
Add 'undefined' value for segment which do not support monitoring.
Fixes crash for commands like 'pvs -o+seg_monitor'.
2015-01-20 15:02:10 +01:00
ae8b9baa04 report: update report_object API
Internal API change - pass single struct for both info & seg_status.
2015-01-20 14:58:43 +01:00
b3a348c03c report: use same info also for lv_attr
Recently the single 'status' code has been used for number of cache
features.

Extend the API a little bit to allow usage also for lv_attr_dup.

As the function itself is used in lvm2api - add a new function:
lv_attr_dup_with_info_and_seg_status() that is able to use
grabbed info & status information.

report_init() is now using directly passed lvdm struct pointer
which holds the infomation whether lv_info() was correctly obtained or
there was some error when trying to read it.

Move 'healt' attribute to status.
TODO convert raid function to use the already known status.
2015-01-20 14:58:41 +01:00
e34b004422 report: reporting unknown status
Add SEG_STATUS_UNKNOWN when status cannot be parsed.
Also add 'info_ok' variable when info was correctly obtained.
2015-01-20 14:53:07 +01:00
64d8ed502d thin: lvchange support for errorwhenfull
Support lvchange --errorwhenfull y|n for thin pools.
2015-01-20 14:53:03 +01:00
07eb1c7dc8 cleanup: add lv_is_error_when_full() macro
Like with other status bits use macro for testing.
(in-release update)
2015-01-20 14:52:06 +01:00
8f90f632f5 vgimportclone: Say safe to ignore lvmetad message. 2015-01-17 11:29:38 +00:00
e5ffacc434 man: Remove renamed writebehind field from lvs.8. 2015-01-17 11:05:25 +00:00
651549594e libdm-report: Fix order of NULL dm_report check. 2015-01-17 10:50:54 +00:00
302b6c99a7 raid_manip: v2 fix multi-segment misallocation on 'lvconvert --repair'
The previous patch felt short WRT disabling allocation on PVs holding other
legs of the RAID LV persistently; this patch introduces an internal,
transient PV flag PV_ALLOCATION_PROHIBITED to address this very problem.

General problem description for completeness:

An 'lvconvert --repair $RAID_LV" to replace a failed leg of a multi-segment
RAID10/4/5/6 logical volume can lead to allocation of (parts of) the replacement
image component pair on the physical volume of another image component
(e.g. image 0 allocated on the same PV as image 1 silently impeding resilience).

Patch fixes this severe resilince issue by prohibiting allocation on PVs
already holding other legs of the RAID set. It allows to allocate free space
on any operational PV already holding parts of the image component pair.
2015-01-16 13:44:16 +01:00
0bcc0cf95d WHATS_NEW: previous commits related to duplicate PVs 2015-01-14 14:52:12 -06:00
b64da4d8b5 toollib: search for duplicate PVs only when needed
A full search for duplicate PVs in the case of pvs -a
is only necessary when duplicates have previously been
detected in lvmcache.  Use a global variable from lvmcache
to indicate that duplicate PVs exist, so we can skip the
search for duplicates when none exist.
2015-01-14 14:47:08 -06:00
3a7c47af0e toollib: pvs -a should display VG name for each duplicate PV
Previously, 'pvs -a' displayed the VG name for only the device
associated with the cached PV (pv->dev), and other duplicate
devices would have a blank VG name.  This commit displays the
VG name for each of the duplicate devices.  The cost of doing
this is not small: for each PV processed, the list of all
devices must be searched for duplicates.
2015-01-14 14:16:03 -06:00
57d74a45a0 toollib: override the PV device with duplicates
When multiple duplicate devices are specified on the
command line, the PV is processed once for each of them,
but pv->dev is the device used each time.

This overrides the PV device to reflect the duplicate
device that was specified on the command line.  This is
done by hacking the lvmcache to replace pv->dev with the
device of the duplicate being processed.  (It would be
preferable to override pv->dev without munging the content
of the cache, and without sprinkling special cases throughout
the code.)

This override only applies when multiple duplicate devices are
specified on the command line.  When only a single duplicate
device of pv->dev is specified, the priority is to display the
cached pv->dev, so pv->dev is not overridden by the named
duplicate device.

In the examples below, loop3 is the cached device referenced
by pv->dev, and is given priority for processing.  Only after
loop3 is processed/displayed, will other duplicate devices
loop0/loop1 appear (when requested on the command line.)

With two duplicate devices, loop0 and loop3:

  # pvs
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
  PV         VG           Fmt  Attr PSize   PFree
  /dev/loop3 loopa        lvm2 a--   12.00m  12.00m

  # pvs /dev/loop3
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
  PV         VG    Fmt  Attr PSize  PFree
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m

  # pvs /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
  PV         VG    Fmt  Attr PSize  PFree
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m

  # pvs -o+dev_size /dev/loop0 /dev/loop3
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop0
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop0 loopa lvm2 a--  12.00m 12.00m  16.00m
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

With three duplicate devices, loop0, loop1, loop3:

  # pvs -o+dev_size
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG           Fmt  Attr PSize   PFree   DevSize
  /dev/loop3 loopa        lvm2 a--   12.00m  12.00m  32.00m

  # pvs -o+dev_size /dev/loop3
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

  # pvs -o+dev_size /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

  # pvs -o+dev_size /dev/loop1
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

  # pvs -o+dev_size /dev/loop3 /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop0 loopa lvm2 a--  12.00m 12.00m  16.00m
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

  # pvs -o+dev_size /dev/loop3 /dev/loop1
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop1 loopa lvm2 a--  12.00m 12.00m  32.00m
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

  # pvs -o+dev_size /dev/loop0 /dev/loop1
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop1 loopa lvm2 a--  12.00m 12.00m  32.00m
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m

  # pvs -o+dev_size /dev/loop0 /dev/loop1 /dev/loop3
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop1 not /dev/loop0
  Found duplicate PV XhLbpVo0hmuwrMQLjfxuAvPFUFZqD4vr: using /dev/loop3 not /dev/loop1
  PV         VG    Fmt  Attr PSize  PFree  DevSize
  /dev/loop0 loopa lvm2 a--  12.00m 12.00m  16.00m
  /dev/loop1 loopa lvm2 a--  12.00m 12.00m  32.00m
  /dev/loop3 loopa lvm2 a--  12.00m 12.00m  32.00m
2015-01-14 11:57:29 -06:00
c1f246fedf toollib: handle duplicate pvs in process_in_pv
Processes a PV once for each time a device with its PV ID
exists on the command line.

This fixes a regression in the case where:

. devices /dev/sdA and /dev/sdB where clones (same PV ID)

. the cached VG references /dev/sdA

. before the regression, the command: pvs /dev/sdB
  would display the cached device clone /dev/sdA

. after the regression, pvs /dev/sdB would display nothing,
  causing vgimportclone /dev/sdB to fail.

. with this fix, pvs /dev/sdB displays /dev/sdA

Also, pvs /dev/sdA /dev/sdB will report two lines, one for each
device on the command line, but /dev/sdA is displayed for each.

This only works without lvmetad.
2015-01-14 11:57:29 -06:00
eac4e1e939 dmeventd: Call lvscan --cache also for mirrors (in addition to RAID). 2015-01-14 18:05:44 +01:00
4a55175bac WHATS_NEW
More news
2015-01-14 15:15:29 +01:00
2908ab3eed thin: errrorwhenfull support
Support error_if_no_space feature for thin pools.
Report more info about thinpool status:
(out_of_data (D), metadata_read_only (M), failed  (F) also as health
attribute.)
2015-01-14 14:52:05 +01:00
1e050a77ff cleanup: missed for build without devmapper
configure --disable-devmapper build fixes.
2015-01-14 14:50:08 +01:00
0869631d7d lv_status: enable lv_status for thinpool
Support also status for thin pools.
2015-01-14 14:50:08 +01:00
0b7ccf835b lv_status: track layered device
For info of i.e. thin-pool we need layered device.
Needs some more thinking about proper interface here.
For now it's usable for cache and thin-pool.
2015-01-14 14:50:08 +01:00
d0f26440ee cleanup: properly align code lines
Misaligned indetion in branches.
2015-01-14 14:50:08 +01:00
d202f43fff cleanup: update API for segment reporting
API for seg reporting is breaking internal lvm coding - it cannot
use vgmem mem pool for allocation of reported value.
So use separate pool instead of 'vgmem' for non vg related allocations

Add consts for many function params - but still many other are left
for now as non-const - needs deeper level of change even on libdm side.
2015-01-14 14:50:08 +01:00
cdd17eee37 raid_manip: fix multi-segment misallocation on 'lvconvert --repair'
An 'lvconvert --repair $RAID_LV" to replace a failed leg of a multi-segment
RAID10/4/5/6 logical volume can lead to allocation of (parts of) the replacement
image component pair on the physical volume of another image component
(e.g. image 0 allocated on the same PV as image 1 silently impeding resilience).

Patch fixes this severe resilince issue by prohibiting allocation on PVs
already holding other legs of the RAID set. It allows to allocate free space
on any operational PV already holding parts of the image component pair.
2015-01-14 13:41:55 +01:00
8804023825 tests: pvscan --cache DevicePath does not fail if the device is just filtered
It's not an error if the device is filtered out and hence cleared from
lvmetad cache - "pvscan --cache DevPath" has now the same behaviour in
this case as "pvscan --cache major:minor" (which is more consistent).

Before, the tests expected failure return code for "pvscan --cache DevicePath"
if the device was filtered (which is a different situation if the device
is missing in the system completely!).
2015-01-12 15:16:57 +01:00
99d895014d dev-type: filter out partitioned device-mapper devices as unsuitable for use as PVs
Normally, if there are partitions defined on top of device-mapper
device, there should be a device-mapper device created for each
partiton on top of the old one and once the underlying DM device
is used by another devices (partition mappings in this case),
it can't be used as a PV anymore.

However, sometimes, it may happen the partition mappings are
missing - either the partitioning tool is not creating them if
it does not contain full support for device-mapper devices or
the mappings were removed.

Better safe than sorry - check for partition header on DM devs
and filter them out as unsuitable for PVs in case the check is
positive. Whatever the user is doing, let's do our best to prevent
unwanted corruption (...by running pvcreate on top of such device
that would corrupt the partition header).
2015-01-12 14:10:44 +01:00
8dbe767340 pvscan: notify lvmetad about device that is gone and pvscan is run with device path instead of major:minor pair
If pvscan is run with device path instead of major:minor pair and this
device still exists in the system and the device is not visible anymore
(due to a filter that is applied), notify lvmetad properly about this.

This makes it more consistent with respect to existing pvscan with
major:minor which already notifies lvmetad about device that is gone
due to filters.

However, if the device is not in the system anymore, we're not able
to translate the original device path into major:minor pair which
lvmetad needs for its action (lvmetad_pv_gone fn). So in this case,
we still need to use major:minor pair only, not device path. But at
least make "pvscan --cache DevicePath" as near as possible to "pvscan
--cahce <major>:<minor>" functionality.

Also add a note to pvscan man page about this difference when using
pvscan --cache with DevicePath and major:minor pair.
2015-01-12 13:59:51 +01:00
1e4a4d48ae toollib: process_each_pv should match by device
When processing PVs specified on the command line, the arg
name was being matched against pv_dev_name, which will not
always work:

- The PV specified on the command line could be an alias,
  e.g. /dev/disk/by-id/...

- The PV specified on the command line could be any random
  path to the device, e.g. /dev/../dev/sdb

To fix this, first resolve the named PV args to struct device's,
then iterate through the devices for processing.
2015-01-09 10:03:31 -06:00
6a77b6f43c scripts: clvmd: replace awk functionality with LVM's selection
No need to use awk now to get appropriate VGs/LVs, use LVM's
own --select - it's quicker, it removes a need for external
dependency on awk and it's also more readable.
2015-01-09 16:41:07 +01:00
fb7e2ff493 metadata: add "Failed to write VG <vg_name>." on failed vg_write and revert previous patch
Better than previous patch which changed log_warn to log_error -
we can have multiple MDAs and if one of them fails to be written,
we can still continue with other MDAs if we're in a mode where
we can handle missing PVs - so keep the log_warn for single
failed MDA write as it was before.

However, add log_error with "Failed to write VG <vg_name>." in
case we're not handling missing PVs or no MDA was written at all
during VG write process. This also prevents an internal error in
which the vg_write fails and we're not issuing any other log_error
in vg_write caller or above, so we end up with:
  "Internal error: Failed command did not use log_error".
2015-01-09 14:04:44 +01:00
db7351d313 metadata: log_error instead of log_warn on failed mda write 2015-01-09 12:00:03 +01:00
08ac12d5e7 WHATS_NEW: line for previous commit 2015-01-09 11:57:25 +01:00
c0e17bca90 dev_manager: do not mark snapshot origins as unusable devices just because of possible blocked mirror underneath
At first, all snapshot-origins where marked as unusable unconditionally
here, but we can't cut off whole snapshot-origin use in a stack just
because of this possible mirror state. This whole "device_is_usable"
check was even incorrectly part of persistent filter before commit
a843d0d97c66aae1872c05b0f6cf4bda176aae2 (where filter cleanup was
done).

The persistent filter is used only if obtain_device_list_from_udev=0,
which means that the former check for snapshot-origin here had not even
been hit with default configuration for a few years before commit
a843d0d97c66aae1872c05b0f6cf4bda176aae2 (the check for snapshot-origin and
skipping of this LV was introduced with commit a71d6051ed
back in 2010).

The obtain_device_list_from_udev=1 (and hence not using persistent
filter and hence not hitting this check for snapshot-origins and skipping) has been
in action since commit edcda01a1e (that is 2011).
So for 3 years this condition was not even checked with default configuration,
making it superfluous.

This all changed in 2014 with commit 8a843d0d97
where "filter-usable" is introduced  and since then all snapshot-origins
have been marked as unusable more often than before and making snapshot-origins
practically unusable in a stack.

This patch removes this incorrect check from commit a71d6051ed
which caused snapshot-origins to be unusable more often recently.

If we want to fix this eventually in a correct way, we need to look
down the stack and if snapshot-origin is hit and there's a blocked
mirror underneath, only then mark the device as unusable. But mirrors
in stack are not supported anymore so it's questionable whether it's
worth spending more time on this at all...
2015-01-09 11:24:16 +01:00
9dbeacf303 WHATS_NEW: previous commit 2015-01-07 13:47:16 +01:00
aaecbb1818 raid: fix mirror image naming when converting from mirror to raid1
$ lvcreate -l1 -m1 --type mirror vg
  Logical volume "lvol0" created.
$ lvconvert --type raid1 vg/lvol0

Before:
$ lvs -a vg
  LV                        VG     Active Attr       LSize   Cpy%Sync Layout     Role
  lvol0                     vg     active rwi-a-r---   4.00m 100.00   raid,raid1 public
  [lvol0_mimage_0_rimage_0] vg     active iwi-aor---   4.00m          linear     private,raid,image
  [lvol0_mimage_1_rimage_1] vg     active iwi-aor---   4.00m          linear     private,raid,image
  [lvol0_rmeta_0]           vg     active ewi-aor---   4.00m          linear     private,raid,metadata
  [lvol0_rmeta_1]           vg     active ewi-aor---   4.00m          linear     private,raid,metadata

Incorrect name: lvol0_mimage_0_rimage_0

With this patch applied:
$ lvs -a vg
  LV               VG   Active Attr       LSize Cpy%Sync Layout     Role
  lvol0            vg   active rwi-a-r--- 4.00m 100.00   raid,raid1 public
  [lvol0_rimage_0] vg   active iwi-aor--- 4.00m          linear     private,raid,image
  [lvol0_rimage_1] vg   active iwi-aor--- 4.00m          linear     private,raid,image
  [lvol0_rmeta_0]  vg   active ewi-aor--- 4.00m          linear     private,raid,metadata
  [lvol0_rmeta_1]  vg   active ewi-aor--- 4.00m          linear     private,raid,metadata

Proper name: lvol0_rimage_0
2015-01-07 13:25:08 +01:00
ff1eca3b6f mirror: do not try to reactivate inactive mirror when removing its LVs which have missing PVs
When mirror has missing PVs and there are mirror images on those missing
PVs, we delete the images and during this delete operation, we also
reactivate the LV. But if we're trying to reactivate the LV in cluster
which is not active and at the same time cmirrord is not running (which
is OK since we may have created the mirror LV as inactive), we end up
with:
  "Error locking on node <node_name>: Shared cluster mirrors are not available."

That is because we're trying to activate the mirror LV without cmirrord.
However, there's no need to do this reactivation if the mirror LV (and
hence it's sub LVs) were not activated before.

This issue caused failure in mirror-vgreduce-removemissing.sh test
recently with this sequence (excerpt from the test script):

  prepare_lvs_
  lvcreate -an -Zn -l2 --type mirror -m1 --nosync -n $lv1 $vg "$dev1" $dev2" "$dev3":$BLOCKS
  mimages_are_on_ $lv1 "$dev1" "$dev2"
  mirrorlog_is_on_ $lv1 "$dev3"
  aux disable_dev "$dev2"
  vgreduce --removemissing --force $vg

The important thing about that test is that we're not running cmirrord,
we're activating the mirror with "-an" so it's inactive and then
vgreduce --removemissing tries to reactivate the mirror images
as part of the _delete_lv function call inside and since cmirrord
is not running, we end up with the "Shared cluster mirrors are not
available." error.
2015-01-07 11:16:19 +01:00
e97023804a pvremove: Avoid metadata re-reads & related error messages. 2015-01-06 14:27:30 +01:00
0987f290a7 lvmetad: Re-use fmt from the VG for PVs when possible. 2015-01-06 14:27:30 +01:00
509650ec4c cmirror: do not check for cmirror availability when creating deactivated cluster mirrors
When creating cluster mirrors while they're not supposed to be activated
immediately after creation, we don't need to check for cmirrord availability.
We can just create these mirrors and let the check to be done on activation
later on. This is addendum for commit cba6186325.
2015-01-06 09:59:04 +01:00
cba6186325 cmirror: check for cmirror availability during cluster mirror creation and activation
When creating/activating clustered mirrors, we should have cmirrord
available and running. If it's not, we ended up with rather cryptic
errors like:

$ lvcreate -l1 -m1 --type mirror vg
  Error locking on node 1: device-mapper: reload ioctl on  failed: Invalid argument
  Failed to activate new LV.

$ vgchange -ay vg
  Error locking on node node 1: device-mapper: reload ioctl on failed: Invalid argument

This patch adds check for cmirror availability and it errors out
properly, also giving a more precise error messge so users are able
to identify the source of the problem easily:

$ lvcreate -l1 -m1 --type mirror vg
  Shared cluster mirrors are not available.

$ vgchange -ay vg
  Error locking on node 1: Shared cluster mirrors are not available.

Exclusively activated cluster mirror LVs are OK even without cmirrord:

$ vgchange -aey vg
  1 logical volume(s) in volume group "vg" now active
2015-01-05 16:54:07 +01:00
3e0ed83bc8 libdm: report: add more comments about helper macros to get reserved values
Since GET_FIELD_RESERVED_VALUE always returns a pointer, don't reference
it with "&" when used - we already have that pointer value (this is an
addendum to recent commit 028ff30947).

Only GET_TYPE_RESERVED_VALUE needs to be referenced with "&" as it
returns directly the value of that type.
2014-12-19 09:23:05 +01:00
57af48d734 report: fix segfault on NULL value hit in cache_settings field
We have to use empty list, not NULL if we want to denote that the list
has no items. Otherwise, the code further can segfault as it expects
there's always a sane value (= some list), including empty list,
but never NULL.
2014-12-18 17:26:12 +01:00
da9da0d8c2 report: properly set "undefined" reserved value for cache_policy field
Use helper macros to handle reserved values and also define "undefined"
reserved value as:

FIELD_RESERVED_VALUE(cache_policy, cache_policy_undef, "", "", "undefined")

Which means:

 - print "" if the cache_policy value is undefined (the first name for this reserved value is "")
 - recognize "undefined" reserved name as synonym to ""
   (so statements like "lvs -S cache_policy=undefined" are still recognized)
2014-12-18 15:21:21 +01:00
028ff30947 cleanup: use helper macros to get reserved value from values.h for vg_mda_copies and lv_read_ahead fields
Avoid making a copy of the keyword which is already registered in
values.h for "unmanaged" (vg_mda_copies field) and "auto" reserved
value (lv_read_ahead field). Also use helper macros to handle these
reserved - this is the correct approach - just do not copy the same
thing again and do not mix it! The GET_FIELD_RESERVED_VALUE and
GET_FIRST_RESERVED_NAME macros guarantees this - use it!

In addition to that, rename reserved values:
  vg_mda_copies --> vg_mda_copies_unmanaged
  lv_read_ahead --> lv_read_ahead_auto

So the field reserved values follows this scheme:

   "<field_name>_<reserved_value_name>".

The same applies for type reserved values with this scheme:

  "<report type name in lowercase>_<reserved_value_name>"

Add a comment about this scheme for others to follow as well
when adding new fields and their reserved values. This makes
it a bit easier to read the code then.
2014-12-18 15:07:46 +01:00
7e85d4f5f6 refactor: rename existing helper macros for reserved value handling and add GET_FIELD_RESERVED_VALUE macro
RESERVED(id)   --> GET_TYPE_RESERVED_VALUE(id)
FIRST_NAME(id) --> GET_FIRST_RESERVED_NAME(id)

Also add GET_FIELD_RESERVED_VALUE(id) macro to get per-field reserved value.

This makes it much more readable and hopefully it'll make it
easier to use these helper macros when adding new reporting
fields with reserved values if needed.
2014-12-18 14:42:14 +01:00
f6f32f39e4 report: dup cache policy name string for report in cache_policy field
The cache policy name taken as LV segment property must be duped
for report as the VG/LV/seg structure is destroyed after processing,
reporting happens later:

$ valgrind lvs -o+cache_policy
...
==16589== Invalid read of size 1
==16589==    at 0x54ABCC3: dm_report_compact_fields
(libdm-report.c:1739)
==16589==    by 0x153FC7: _report (reporter.c:619)
==16589==    by 0x1540A6: lvs (reporter.c:641)
==16589==    by 0x148021: lvm_run_command (lvmcmdline.c:1452)
==16589==    by 0x1495CB: lvm2_main (lvmcmdline.c:1907)
==16589==    by 0x164712: main (lvm.c:21)
==16589==  Address 0x7d465f2 is 8,338 bytes inside a block of size
16,384 free'd
==16589==    at 0x4C2ACE9: free (in
/usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==16589==    by 0x54B8C85: _free_chunk (pool-fast.c:318)
==16589==    by 0x54B84FB: dm_pool_destroy (pool-fast.c:78)
==16589==    by 0x1E59C7: _free_vg (vg.c:78)
==16589==    by 0x1E5A6D: release_vg (vg.c:95)
==16589==    by 0x159B6E: _process_lv_vgnameid_list (toollib.c:1967)
==16589==    by 0x159DD7: process_each_lv (toollib.c:2030)
==16589==    by 0x153ED8: _report (reporter.c:598)
==16589==    by 0x1540A6: lvs (reporter.c:641)
==16589==    by 0x148021: lvm_run_command (lvmcmdline.c:1452)
==16589==    by 0x1495CB: lvm2_main (lvmcmdline.c:1907)
==16589==    by 0x164712: main (lvm.c:21)
2014-12-18 11:54:40 +01:00
aaf25ec6bd libdm: report: also check whether field type is supported for field-specific reserved value
We only checked global per-report-type reserved values for compatibility
with selection code. This patch also adds a check for per-report-field
reserved values. This avoids problems where unsupported report type is
used as reserved value which could cause hard to debug problems
otherwise. So this additional check stops from registering unsupported
and unhandled per-field reserved values.

Registerting such unsupported reserved value is a programmatic error,
so report internal error in this case to stop us from making a mistake
here in the future or even today where STR_LIST fields can't have
reserved values yet.
2014-12-18 11:29:48 +01:00
e471ea7890 WHATS_NEW: previous commit 2014-12-17 15:06:48 +01:00
00ad13eb71 report: Add cache_policy and cache_settings (LV) segment fields. 2014-12-17 14:43:12 +01:00
2e905d4540 man: put back the --binary reference in {pv,vg,lv}display man page 2014-12-11 15:50:37 +01:00
3b02ccd201 tools, man: --binary option is available with -C for {pv,vg,lv}display
The {pv,vg,lv}display *do* use reporting in case "-C|--columns" is used.
The man page was correct, the recognition for the --binary was missing
in the code though!
2014-12-11 15:20:16 +01:00
3ec482a379 man: remove reference to --binary in {pv,vg,lv}display man page
The {pv,vg,lv}display commands don't use reporting capabilites and
as such they can't use --binary. This got into the man pages by
mistake - the display commands do not recognize --binary option.
2014-12-11 10:42:31 +01:00
b21a8412c4 vgimportclone: also notify lvmetad about changes if it's used
All the LVM commands are run in mode without lvmetad use (since lvmetad
can't handle duplicates). When we're finished with vgimportclone, we
need to notify lvmetad about changes.

Before this patch (/dev/sda and /dev/sdb contains a copy VG called "vg"):
$ vgimportclone --basevgname vg_snap /dev/sdb
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  WARNING: Activation disabled. No device-mapper interaction will be attempted.
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  Physical volume "/tmp/snap.zcJ8LCmj/vgimport0" changed  1 physical volume changed / 0 physical volumes not changed
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  WARNING: Activation disabled. No device-mapper interaction will be attempted.
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  Volume group "vg" successfully changed
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  Volume group "vg" successfully renamed to "vg_snap"
  Reading all physical volumes.  This may take a while...
  Found volume group "vg" using metadata type lvm2
  Found volume group "fedora" using metadata type lvm2

$ vgs
  VG     #PV #LV #SN Attr   VSize   VFree
  fedora   1   2   0 wz--n-   9.50g      0
  vg       1   1   0 wz--n- 124.00m 120.00m

(...lvmetad doesn't see the new "vg_snap"!)

With this patch applied:
$ vgimportclone --basevgname vg_snap /dev/sdb
  ...
  WARNING: lvmetad is running but disabled. Restart lvmetad before enabling it!
  Volume group "vg" successfully renamed to "vg_snap"
Notifying lvmetad about changes since it was disabled temporarily.
  Reading all physical volumes.  This may take a while...
  Found volume group "vg_snap" using metadata type lvm2
  Found volume group "fedora" using metadata type lvm2
  Found volume group "vg" using metadata type lvm2

$ vgs
  VG      #PV #LV #SN Attr   VSize   VFree
  fedora    1   2   0 wz--n-   9.50g      0
  vg        1   1   0 wz--n- 124.00m 120.00m
  vg_snap   1   1   0 wz--n- 124.00m 120.00m

The "restart lvmetad before enabling it" message is a bit misleading
here - we should probably suppress this one, but we can't suppress
warning messages selectively at the moment and we don't want to lose
other warning/error messages printed...
2014-12-10 14:00:56 +01:00
00b36ef06a vgimportclone: replace awk with dumpconfig to generate temporary lvm.conf for vgimportclone
With current dumpconfig, we can generate lvm.conf easily - we can merge
current lvm.conf with the config given on cmd line:
  lvm dumpconfig --mergedconfig --config "..."

This is a bit simpler than using awk and it also avoids problems when some of
the configuration is missing in existing lvm.conf file and hardcoded defaults
are used instead. The dumpconfig handles this transparently.
2014-12-10 13:59:38 +01:00
5378a1a63e WHATS_NEW: f94f846 actually fixes DM issue, not LVM issue 2014-12-09 10:52:07 +01:00
f94f8463b0 libdm: report: fix incorrect memory use while using --select with --unbuffered for reporting
Under certain circumstances, the selection code can segfault:

$ vgs --select 'pv_name=~/dev/sda' --unbuffered vg0
  VG   #PV #LV #SN Attr   VSize   VFree
  vg0    6   3   0 wz--n- 744.00m 588.00m
Segmentation fault (core dumped)

The problem here is the use of --ubuffered together with regex used in
selection criteria. If the report output is not buffered, each row is
discarded as soon as it is reported. The bug is in the use of report
handle's memory - in the example above, what happens is:

  1) report handle is initialized together with its memory pool

  2) selection tree is initialized from selection criteria string
     (using the report handle's memory pool!)

    2a) this also means the regex is initialized from report handle's mem pool

  3) the object (row) is reported

    3a) any memory needed for output is intialized out of report handle's mem pool
    3b) selection criteria matching is executed - if the regex is checked the
        very first time (for the very first row reported), some more memory
        allocation happens as regex allocates internal structures "on-demand",
        it's allocating from report handle's mem pool (see also step 2a)

  4) the report output is executed

  5) the object (row) is discarded, meaning discarding all the mem pool
     memory used since step 3.

Now, with step 5) we have discarded the regex internal structures from step 3b.
When we execute reporting for another object (row), we're using the same
selection criteria (step 3b), but tihs is second time we're using the regex
and as such, it's already initialized completely. But the regex is missing the
internal structures now as they got discarded in step 5) from previous
object (row) reporting (because we're using "unbuffered" reporting).

To resolve this issue and to prevent any similar future issues where each
object/row memory is discarded after output (the unbuffered reporting) while
selection tree is global for all the object/rows, use separate memory pool
for report's selection.

This patch replaces "struct selection_node *selection_root" in struct
dm_report with new struct selection which contains both "selection_root"
and "mem" for separate mem pool used for selection.

We can change struct dm_report this way as it is not exposed via libdevmapper.

(This patch will have even more meaning for upcoming patches where selection
is used even for non-reporting commands where "internal" reporting and
selection criteria matching happens and where the internal reporting is
not buffered.)
2014-12-09 10:41:55 +01:00
4c62215bd1 configure: fix automatic use of configure --enable-udev-systemd-background-jobs
Fix incorrect test in configure which sets --enable-udev-systemd-background-jobs
automatically if proper systemd version is available.

The UDEV_SYSTEMD_BACKGROUND_JOBS variable was not properly set to "yes" in
case systemd is available and we had "maybe" for this variable before.
2014-12-08 10:52:47 +01:00
42d71b9af3 libdm: report: return immediately from dm_report_compact_fields without error if there are no rows
Let's make dm_report_compact_fields consistent with dm_report_output fn
which also returns with success immediately if there are no rows.
2014-12-05 15:10:50 +01:00
f867dc6b29 libdm: report: compact output applicable only if report is buffered 2014-12-05 14:18:51 +01:00
f3bd9a2797 raid: properly rename split image
When we split leg from raid - we take a proper new lock for a new LV.
However for now activation checks only 'existince' of device UUID,
but it's not validating device has a proper name.

As a quick fix call suspend()/resume() to rename after split mirror.
2014-12-05 13:39:42 +01:00
00d53d5fc1 config: add report/compact_output lvm.conf setting to enable or isable field compacting
$ lvm dumpconfig report/compact_output
compact_output=0

$ lvs vg
  LV    VG   Attr       LSize Pool Origin Data%  Meta%  Move Log Cpy%Sync Convert
  lvol0 vg   owi-a-s--- 4.00m
  lvol1 vg   -wi-a----- 4.00m
  lvol2 vg   swi-a-s--- 4.00m      lvol0  0.00

$ lvm dumpconfig report/compact_output
compact_output=1

$ lvs vg
  LV    VG   Attr       LSize Origin Data%
  lvol0 vg   owi-a-s--- 4.00m
  lvol1 vg   -wi-a----- 4.00m
  lvol2 vg   swi-a-s--- 4.00m lvol0  0.00
2014-12-05 12:00:28 +01:00
5edf6a56c4 libdm: report: add dm_report_compact_fields
Add new dm_report_compact_fields function to cause report outout
(dm_report_output) to ignore fields which don't have any value set
in any of the rows reported. This provides support for compact report
output where only fields which have something to report are displayed.
2014-12-05 12:00:28 +01:00
44394cd246 libdm: remove unimplemented dm_report_set_output_selection fn
The dm_report_set_output_selection was not implemented in the end -
we have dm_report_init_with_selection instead. This is just a remnant
from development code that got into libdevmapper.h by mistake.
2014-12-05 11:54:25 +01:00
a5baf13a06 pool: fix typo in error message: then -> than 2014-12-04 09:18:16 +01:00
a057f40155 mirror: Validate raid region size config setting.
If necessary, round down to a power of 2 the raid/mirror region size
taken from the config files.
2014-12-03 22:47:08 +00:00
de53e0955d mirror: Restrict region size to power of 2. 2014-12-02 14:24:21 +00:00
9258e57a50 post-release 2014-11-28 23:07:31 +00:00
e492861749 pre-release 2014-11-28 23:06:07 +00:00
6521c4b215 libdaemon: Fix some client leaks.
Free (and clear) h.protocol string on daemon_open() error paths
so it's OK for caller to skip calling daemon_close() if returned
h.socket_fd is -1.

Close h.socket_fd in daemon_close() to avoid possible leak.

https://bugzilla.redhat.com/1164234
2014-11-28 21:31:51 +00:00
530ebd8976 Update WHATS_NEW. 2014-11-27 20:23:57 +01:00
5b2726fc61 lvcreate: Implement --cachepolicy/--cachesettings. 2014-11-27 20:22:03 +01:00
2c3db52356 metadata: Add cache_policy to lvcreate_params and honour it. 2014-11-27 20:20:48 +01:00
9290854163 toollib: Fix uninitialised config value type in get_cachepolicy_params. 2014-11-27 20:19:28 +01:00
4bfdb01f78 toollib: fix regression in parsing /dev/mapper/vg-lv
Commit b0dde9e8f0 introduced regression in parsing
/dev/mapper prefix - and tried to check for '/' one char behind.
2014-11-26 17:29:35 +01:00
c8890e3ac1 coverity: remove dead code in lv_info_with_seg_status (continued) 2014-11-26 11:58:25 +01:00
193f9b26a0 coverity: fix possible NULL dereference
The call to dm_config_destroy can derefence result->mem
while result is still NULL:

struct dm_config_tree *get_cachepolicy_params(struct cmd_context *cmd)
{
	...
	int ok = 0;
	...
	if (!(result = dm_config_flatten(current)))
		goto_out;
	...
	ok = 1;
out:
	 if (!ok) {
		dm_config_destroy(result)
		...
	}
	...
}
2014-11-26 11:46:13 +01:00
86ae68a5f7 coverity: remove dead code in lv_info_with_seg_status
Just call return 0 directly on error path, without using
"goto" - the code is short, no need to use it this way
(the dead code appeared as part of further changes in this
function).
2014-11-26 11:30:01 +01:00
2cd98b2782 makefiles: avoid regeneration of Makefile
When Makefile.in is touched, it's been matched by 'man' rule
and it's been wrongly regnerated.

Put in explicit rules to avoid Makefile sed processing.
2014-11-26 09:36:12 +01:00
2de11c9e9e thin: add missing 64KB rounding
When chunk size needs to be estimated, the code missed to round
to proper 64kb boundaries  (or power of 2 for older thin pool driver).
So for some data and metadata size (i.e. 10GB and 4MB) it resulted
in incorrect chunk size (not being a multiple of 64KB)

Fix it by adding proper rounding and also use 1 routine for 2 places
where the same calculation is made.

Fix also incorrect printed warning that has used 'ffs()'
(which returns first 'least significant' bit in word)
and it was not really giving any useful size info and replace it
with properly estimated chunk size.
2014-11-26 09:29:25 +01:00
13e2049c32 initscripts: fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT variable to be ignored 2014-11-25 15:19:11 +01:00
62f3a4d2d8 pvresize: fix size in 'Resizing to ...' verbose message to show proper result size 2014-11-25 15:19:10 +01:00
cd3b6070aa post-release 2014-11-24 17:48:25 +00:00
2aca834724 pre-release 2014-11-24 17:46:50 +00:00
e50c9bd7cd cache: comment out unsupported pooldatasize
Support for pooldatasize is not yet finished, so keep it commented out
for now.
2014-11-24 17:38:39 +01:00
d184e8d0ba man: update
Improve lvconvert.
Put ENV section downward in lvm.8.
2014-11-24 14:48:13 +01:00
74e6135c4f tests: use proper LVMTEST prefix for VG name
Cleaner needs prefix to do its jobs and clean any left VG from python
test as well.
2014-11-24 14:39:04 +01:00
1e80265c36 lvconvert: earlier detection of conflicting names
Detect same LV names for lvconvert prior opening VG.
i.e. lvconvert --thinpool vg/lvol0  -T lvol0
2014-11-24 14:39:04 +01:00
a058fab118 man: fix pages for generators
Properly generate man page for systemd generators on make.
Simplified  install_clusters
2014-11-24 14:39:04 +01:00
8bc7b4f926 libdm: there is no element in item 0
Items[0] holds only counter in .len.
So don't zero already zeroed items[0].len assigned above.

(finishing fc935495c8)
2014-11-24 14:38:54 +01:00
fb220314ec report: add some comments about how string list is stored internally 2014-11-24 13:14:33 +01:00
b9601b8353 report: add some comments about how string list is stored internally 2014-11-24 10:48:01 +01:00
ced0c17f21 man/lvchange: Mention --cachepolicy and --cachesettings. 2014-11-24 00:02:55 +01:00
1445a74d76 man/lvm.conf: Update to reflect changes in config parser. 2014-11-23 23:41:58 +01:00
14472d62ba Update WHATS_NEW. 2014-11-23 23:30:27 +01:00
a6a7a3a074 cleanup: add missing error path check
New code misses error path check.
2014-11-23 00:49:04 +01:00
ccdea661fa cleanup: warning: declaration of 'remove' shadows a global declaration
Don't shadow stdio.h declaration.
2014-11-23 00:49:04 +01:00
678cc4e375 libdm: report fix memleak on error path
When _alloc_selection_node() fails, rh should be destroyed.

Use 'bad:' label since we have goto_bad with stack embeded.
2014-11-23 00:49:04 +01:00
8eb111dfb8 pool: prevent pool conversion with same name
When same name is given for converted volume and pool volume,
stop further command processing.
2014-11-23 00:49:04 +01:00
0782309713 tests: reduce thin test 2014-11-22 18:51:02 +01:00
4607cbcb0d tests: use old virt snaps in the test
Don't use thin with its thin requirements for the test.
2014-11-22 18:51:02 +01:00
fc935495c8 libdm: fix reporting of empty string list
Don't write behind the allocated array when list is empty.
Use index 0 for the allocated element.

Error triggered by i.e.:  lvs -a -o all,lv_modules
2014-11-22 18:50:53 +01:00
75d79f3dad makefiles: standard usage of make.tmpl
Use lvm2 standard TARGETS.

Make liblvm_python.c as intermediate target (gets deleted after use)

Properly delete build dir on make distclean.

Mark install_python_bindings as .PHONY.
2014-11-22 09:58:31 +01:00
4dc602f79b dev_manager: fix mknodes
Fix regression introduced with a2c1024f6a

_setup_task(mknodes ? name : NULL...

has been replaced with:

_setup_task(type != MKNODES ? name : NULL....

Use '=='
2014-11-22 09:57:31 +01:00
6ce8e57989 configure: fix CLVMD_PATH location
Commit d2c116058e introduced regression
with CLVMD_PATH.

+        CLVMD_PATH="$clvmd_prefix/sbin/clvmd"
         test "$prefix" != NONE && clvmd_prefix=$prefix

It has set CLVMD_PATH before clvmd_prefix got its final value.
Move it one line below.
2014-11-22 09:55:46 +01:00
089bdc0be4 cleanup: drop unused vars 2014-11-20 17:49:32 +01:00
71271cf905 test: Also test repeated --cachesettings in lvchange-cache. 2014-11-20 16:51:07 +01:00
c75ae0846e cache: Implement 'default' as a policy settings value to clear the record. 2014-11-20 16:51:07 +01:00
4b9b8e1282 toollib: Split --cachesettings from --cachepolicy. 2014-11-20 16:51:07 +01:00
310beb73a8 test: Add a test for lvchange --cachepolicy. 2014-11-20 16:51:07 +01:00
c164f59631 lvchange: Accept --cachepolicy. 2014-11-20 16:51:07 +01:00
f67e1fadb0 toollib: Add --cachepolicy and implement get_cachepolicy_params. 2014-11-20 16:51:06 +01:00
d22ffd8c28 cache: Add lv_cache_setpolicy to cache_manip.c. 2014-11-20 16:51:06 +01:00
0050480c0e libdm-config: Warn about duplicate keys. 2014-11-20 16:51:06 +01:00
de2c5ab2ac libdm-config: Implement dm_config_remove_node. 2014-11-20 16:51:06 +01:00
8bc9966763 libdm-config: Interpret barewords after '=' as strings. 2014-11-20 16:51:06 +01:00
274a7a68b8 libdm-config: Implement dm_config_flatten. 2014-11-20 16:51:06 +01:00
956c192841 libdm-config: Re-link config trees to reflect file order of keys/sections. 2014-11-20 16:51:06 +01:00
687029cbbd libdm-config: Allow paths (section/key = value) in config files.
The order of the resulting tree is based on the first appearance of
sections. With no section repeats, the sections stay as listed in the
config file. Sections using the brace syntax 'section { key = value }' are
treated the same way: 'section { x = 1 } section { y = 2 }' is the same as
'section/x = 1 section/y = 2' is the same as 'section { x = 1 y = 2 }'
2014-11-20 16:47:30 +01:00
9f2961f259 cache: check for internal error
Don't try to duplicate NULL on internal error path.
2014-11-20 16:35:46 +01:00
e55c6999ae toollib: release vg on ignore path
Missing call to release_vg().
2014-11-20 08:53:30 +01:00
a61c5c5b3a revert: 7639eae and 4a52a92
Revert 7639eae891 and
4a52a9212c. We need a better fix here.
2014-11-20 08:22:34 +01:00
8d8c1b6624 tests: use snapshot targets 2014-11-19 23:24:18 +01:00
c75548300d tests: prepare control node before clvmd
Make sure there is 'control' node before clvmd is started.
Somehow  'clvmd' is not allowed by selinux to create one.

TODO: Check is selinux policy is right here...
2014-11-19 23:22:52 +01:00
d7985ebead thin: fix error path
Print pool name and not the origin name.
2014-11-19 18:58:30 +01:00
4a52a9212c systemd: clvmd and cmirrord systemd unit - use usrsbindir instead of sbindir 2014-11-19 16:06:05 +01:00
7639eae891 configure: expand prefix and exec_prefix directly in configure
In case someone wants to use @some_path@ that contains
prefix or exec_prefix and it's used in other files than Makefiles
(Makefiles used make.tmpl to expand these).
2014-11-19 16:03:27 +01:00
74ed1ba9f9 configure: make configure --enable-udev-systemd-background-jobs only for systemd >= 205
systemd-run is available in systemd>=205. Also, this fix prevents
systemd-specific udev rules in 69-dm-lvm-metad.rules to appear in
case systemd environment is not available - make configure to check
this automatically and use these systemd specific rules only if it
is applicable.
2014-11-19 13:47:18 +01:00
422d1ac8d2 man: clvmd updates
- closer to the recommendation of man-pages (7) if possible
- Add crossrefs
- Sort options and crossrefs
- Fix default timeout (60 secs) of -t
- Documents -I[auto]

Signed-off-by: Stéphane Aulery <saulery@free.fr>
2014-11-19 01:09:52 +01:00
5226181329 man: clvmd help output
Closer to the recommendation of groff_man (7) if possible

Signed-off-by: Stéphane Aulery <saulery@free.fr>
2014-11-19 01:09:52 +01:00
10330b8782 man: blkdeactivate help output
- Closer to the recommendation of man-pages and groff_man (7) if
  possible
- Sort options and crossrefs
- Relocate sub-options on the right places

Signed-off-by: Stéphane Aulery <saulery@free.fr>
2014-11-19 01:09:24 +01:00
731e99025b man: lvchange update
Fix \fI usage.
2014-11-19 00:31:23 +01:00
53d2db31c6 cleanup: drop unused var 2014-11-18 16:50:49 +01:00
01760967b4 locking: rename LCK_CONVERT
All 'MODE' bits are using _MODE suffix so rename to LCK_CONVERT_MODE
(part of rhbz 735445).
No functional change.
2014-11-18 16:50:49 +01:00
aaa6205d5a toollib: improve ignore_vg case in _process_pvs_in_vgs
ignore_vg now returns 0 for the FAILED_CLUSTERED case,
so all the ignore_vg 1 cases will return vg's with an
empty vg->pvs, so we do not need to iterate through
vg->pvs to remove the entries from the devices list.

Clean up whitespace problems in that area from the
previous commit.
2014-11-18 09:25:56 -06:00
cf37c04347 memlock: Make malloc reserve more robust against glibc tricks. 2014-11-18 03:17:27 +01:00
542b03ee00 tests: deactivate repaired before swap 2014-11-17 08:44:53 +01:00
740fcdae7d tests: thin repair testing
More checks for thin related tools.
Add same functionality for cache related tools.
2014-11-17 00:41:33 +01:00
3a1c609ac4 tests: reduce number of sync waiting
Lets assume faster systems, if we have too big raid arrays,
reduce them.
2014-11-17 00:34:44 +01:00
776934aa08 tests: skip another older kernel from raid456 2014-11-17 00:32:49 +01:00
b622a7fe3f toollib: fixes and cleanup of recent changes
- Fix problems with recent changes related to skipping in:
  . _process_vgnameid_list
  . _process_pvs_in_vgs

- Undo unnecessary changes to the code structure and readability.

- Preserve valid but minor changes:
  . testing FAILED bit values in ignore_vg
  . using "skip" value from ignore_vg instead of "ret" value
  . applying the sigint check to the start of all loops
  . setting stack backtrace when ECMD_PROCESSED is not returned,
    i.e. apply the following pattern:

	ret = process_foo();
	if (ret != ECMD_PROCESSED)
		stack;
	if (ret > ret_max)
		ret_max = ret;
2014-11-14 16:58:09 -06:00
513105c6ac toollib: ignore_vg() with skip is not locked
Extend/fix d8923457b8 commit.

'skip'-ed VG is not holding any lock - so don't unlock such VG.

At the same time simplify the code around and relase VG at a single
place and unlock only not skiped and not ignored VGs.
2014-11-14 19:32:03 +01:00
27182e1ddb tests: explicit raid sync 2014-11-14 18:12:44 +01:00
fd32bb1991 debug: switch to verbose
When there is no real error from the function - avoid using log_error().
2014-11-14 18:12:44 +01:00
b6f921e5cb debug: better message for pool zeroing state 2014-11-14 18:12:35 +01:00
38200c2000 cleanup: add '.' to log messages 2014-11-14 18:12:35 +01:00
f36080a05d vg_read: correct warning
Use log_warn when we are effectively not creating an error -
we 'allowed' inconsistent read for a reason - so it's just warning
level we process inconsistent VG - it's upto caller later to decide
error level of command return value and in case of error it needs
to use log_error then.
2014-11-14 18:12:35 +01:00
d8923457b8 toolib: fix ignore_vg
Rework ignore_vg() API so it properly handles
multiple kind of vg_read_error() states.

Skip processing only otherwise valid VG.

Always return ECMD_FAILED when break is detected.

Check sigint_caught() in front of dm iterator loop.

Add stack for _process failing ret codes.
2014-11-14 18:10:45 +01:00
06e3f1757e vg_read: use new error flag
Failed recovery provides different (NULL) VG then FAILED_INCONSISTENT.
Mark it with different failure bit - since FAILED_INCONSISTENT is
supposed to contain something 'usable' (thought inconsistent).
2014-11-14 18:09:27 +01:00
01bbbc27bf lvmcache: remove unnecessary line break syntax 2014-11-13 11:07:34 -06:00
474c6a5271 lvmcache.7: remove unwanted line continuation syntax 2014-11-13 11:04:15 -06:00
271252eff7 lvconvert.8: fix bold and italic syntax mistake
Signed-off-by: Stéphane Aulery <saulery@free.fr>
2014-11-13 17:49:42 +01:00
88e944b5a3 cleanup: remove unused headers 2014-11-13 17:49:42 +01:00
428b9fcd87 cleanup: validate pointers
Mostly on almost impossible to happen paths - but stay safe.
2014-11-13 17:49:42 +01:00
7278556c76 lvm2api: use fully initilized struct
Don't pass partially initialized struct.
2014-11-13 17:49:41 +01:00
49e3fd1ce8 reporter: drop mem on error path
Coverity noticed.
2014-11-13 17:44:31 +01:00
6308a8b06d cache: wrong feature in seg is internal error 2014-11-13 17:44:31 +01:00
48874703d2 cleanup: free mempool memory used for LV status in PVSEGS reporting
Addendum to previous commit 4de7699855.
2014-11-13 14:41:01 +01:00
4de7699855 cleanup: unify LV info and LV segment status reporting in combination with LVS, SEGS and PVSEGS reporting
Move common code into shared internal fn so the logic for getting the
LV info as well LV segment status is not scattered around - call common
_do_info_and_status to gather required parts in reporting handlers.
2014-11-13 14:28:51 +01:00
83308fdff9 cleanup: cleanup internal interface to acquire segment status
- Add separate lv_status fn (if we're interested only in seg status,
   but not lv info at the same time as it is with existing
   lv_info_with_seg_status fn). So we 3 fns:

     - lv_info (existing one, runs only info ioctl, fills in struct lvinfo only)

     - lv_status (new one, runs status ioctl, fills in struct lv_seg_status only)

     - lv_info_with_seg_status (existing one, runs status ioctl, fills
       in struct lvinfo as well as lv_seg_status)

 - Add more comments in the code explaining the difference between lv_info,
   lv_status and lv_info_with_seg_status and their return values.

 - Move decision whether lv_info_with_seg_status needs to call only
   status ioctl (in case the segment for which we require status is from
   the LV for which we require info) or separate status and info ioctl
   (in case the segment for which we require status is from different
    LV that the one for which we require info) into
   lv_info_with_seg_status fn so caller doesn't need to bother about
   this at all.

 - Cleanup internal interface for this seg status so it's more readable.
2014-11-13 14:28:51 +01:00
efe5245e47 pvck: Use non-zero exit status after failure. 2014-11-13 12:26:43 +00:00
c3e2990359 cleanu: drop duplicate const 2014-11-13 13:15:58 +01:00
8cb79dad0b pool: fix removal of pool metadata spare
Since we support device stack of pools over pool
(thin-pool with cache data volume) the existing code
is no longer able to detect orphan _pmspare.

So instead do a _pmspare check after volume removal,
and remove spare afterwards.
2014-11-13 13:09:07 +01:00
fba86dd42b cache: improve pending_delete
We need to stop guessing deleted names - so rather collect
deleted  UUID into a string list - and then remove them properly
in _clean_tree. Restore origin _clean_tree behaviour them for
currently unconverted removal of snapshots.

Pending delete feature now properly tracks whole subtree of cache
(so i.e. data or metadata as raid volumes).
It properly replaces all related volumes with 'errors' in suspend
preload, then resume them as error and remove collected UUIDs
from root - since they are not longer part of any volume deps.
2014-11-13 11:54:41 +01:00
359dc6fa76 coverity: commit ba2302346 - report log_sys_error properly
log_sys_error uses errno, hence we need to report the first
failure before reporting another failure that uses errno as well.
2014-11-12 15:16:54 +01:00
c03d8473ea coverity: fix possible dereference of NULL pointer
This would be in case the pool segment was not found.

LVM2.2.02.112/lib/metadata/pool_manip.c:238:36: warning: Access to field 'segtype' results in a dereference of a null pointer (loaded from variable 'pool_seg')
2014-11-12 10:17:17 +01:00
ce8730b508 coverity: fix possible integer overflow
LVM2.2.02.112/lib/metadata/cache_manip.c:73: overflow_before_widen: Potentially overflowing expression "*pool_metadata_extents *vg->extent_size" with type "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned).
LVM2.2.02.112/lib/activate/dev_manager.c:217: overflow_before_widen: Potentially overflowing expression "seg_status->seg->len * extent_size" with type "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned).
LVM2.2.02.112/lib/activate/dev_manager.c:217: overflow_before_widen: Potentially overflowing expression "seg_status->seg->le * extent_size" with type "unsigned int" (32 bits, unsigned) is evaluated using 32-bit arithmetic, and then used in a context that expects an expression of type "uint64_t" (64 bits, unsigned).
2014-11-12 10:03:27 +01:00
60cc666c94 coverity: fix compiler warning
LVM2.2.02.112/lib/activate/dev_manager.c:196:5: warning: 'dmtask' may be used uninitialized in this function [-Wmaybe-uninitialized]

In _info_run fn:

switch (type) {
	case INFO:
		...
	case STATUS:
		...
	case MKNODES:
		...
}

The "type" is enum and currently only those three types are supported,
but if we added a new type in the future, this would end up with a bug
(if we forgot to add the new "case" in that "switch"). So let's make
sure proper internal error is printed:

	default:
		log_error(INTERNAL_ERROR "_info_run: unhandled info type");
                return 0;
2014-11-12 09:55:12 +01:00
57c618b0ed cache: fix clean_tree
Fix 8121074fda - the patch
incorrectly removed also other top-level nodes.

It needs to deactivate purely subnodes of _corig.
2014-11-12 09:40:27 +01:00
112302d41a man: fix (\+) syntax warning of Groff
Signed-off-by: Stéphane Aulery <saulery@free.fr>
2014-11-12 09:39:19 +01:00
eccc97f15a coverity: remove redundant condition
LVM2.2.02.112/daemons/clvmd/clvmd.c:1131: warning[arrayIndexOutOfBoundsCond]: Array 'row[8]' accessed at index 8, which is out of bounds. Otherwise condition 'j==8' is redundant.

This code:

int i,j = 0;
...
for (i = 0; i < len; ++i) {
	...
	if ((j == 8) || (i + 1 == len)) {
		for (;j < 8; ++j) {
			...
		}
		...
		j = 0;
	}
}

Indeed - j is 0 at the beginning, then iterating till j < 8,
then always zeroed at the end of the outer loop - so "j" never
reaching value of 8 - the j == 8 condition is redundant.
2014-11-12 09:30:02 +01:00
ba23023464 coverity: fix resource leaks
LVM2.2.02.112/tools/toollib.c:1991: leaked_storage: Variable "iter" going out of scope leaks the storage it points to.
LVM2.2.02.112/lib/filters/filter-usable.c:89: leaked_storage: Variable "f" going out of scope leaks the storage it points to.
LVM2.2.02.112/lib/activate/dev_manager.c:1874: leaked_handle: Handle variable "fd" going out of scope leaks the handle.
2014-11-12 09:19:14 +01:00
131aaeb634 post-release 2014-11-11 14:15:32 +00:00
9a5910bdf9 pre-release 2014-11-11 14:13:00 +00:00
9704515c1e dev_manager: only support status for cache segment at the moment
When getting status for LV segment types, we need to be sure
that proper segment is selected for the status ioctl.

When reporting fields that require status ioctl,
the "_choose_lv_segment_for_status_report" fn in tools/reporter.c
must be completed properly to choose the proper segment for all
the LV types (at the moment, it just takes the first LV segment
by default).

This works fine with cache LVs surely. The other segment types
need more auditing. We use this status ioctl only for cache status
fields at the moment only, so restrict it to the cache only.

Once the _choose_lv_segment_for_status_report is completed
properly, release the restriction in _get_segment_status_from_target_params.
2014-11-11 15:02:21 +01:00
8121074fda cache: pending_delete fixes 2014-11-11 13:32:41 +01:00
9a6e3683a2 cache: never create new table entry for deleted cache 2014-11-11 13:32:41 +01:00
42a3305ec7 cache: no status for pending deleted cache 2014-11-11 13:32:41 +01:00
7fa7ac528d WHATS_NEW: '_' -> ',' 2014-11-11 13:27:34 +01:00
2dde6c6531 report: add cache device status fields
New reporting fields related to cache device status:
  - cache_total_blocks
  - cache_used_blocks
  - cache_dirty_blocks
  - cache_read_hits
  - cache_read_misses
  - cache_write_hits
  - cache_write_misses
2014-11-11 13:07:30 +01:00
a2c1024f6a dev_manager: enhance dev_manager_info to acquire LV segment status if requested, add lv_info_with_seg_status fn 2014-11-11 13:04:02 +01:00
7f90ad84c1 report: add new LVSSTATUS and SEGSSTATUS report type
Similar to LVSINFO type which gathers LV + its DM_DEVICE_INFO, the
new LVSSTATUS/SEGSSTATUS report type will gather LV/segment + its
DM_DEVICE_STATUS.

Since we can report status only for certain segment, in case
of LVSSTATUS we need to choose which segment related to the LV
should be processed that represents the "LV status". In case of
SEGSSTATUS type it's clear - the status is reported for the
segment just processed.
2014-11-11 08:53:28 +01:00
d7e5f03888 refactor: rename struct lv_with_info used in reporting code to lv_with_info_and_seg_status
The former struct lv_with_info is renamed to lv_with_info_and_seg_status as it can
hold more than just "info", there's lv's segment status now in addition:

	struct lv_with_info_and_seg_status {
		struct logical_volume *lv;
		struct lvinfo *info;
		struct lv_seg_status *seg_status;
	}

Where struct lv_seg_status is:

	struct lv_seg_status {
		struct dm_pool *mem;
		struct lv_segment lv_seg;
		lv_seg_status_type_t type;
		void *status; /* struct dm_status_* */
	}

Where lv_seg points to lv's segment that is being reported or
processed in general.

New struct lv_seg_status keeps the information about segment status -
the status retrieved via DM_DEVICE_STATUS ioctl. This information will
be used for reporting dm device target status for the LV segment
specified.

So this patch introduces third level of LV information that is
kept for reuse while reporting fields within one reporting line,
causing only one DM_DEVICE_STATUS ioctl call per LV segment line
reported (otherwise we'd need to call the DM_DEVICE_STATUS for each
segment status field in one LV segment/reporting line which is not
efficient).

This is following exactly the same principle as already introduced
by commit ecb2be5d16.

So currently we have three levels of information that can be used
to report an LV/LV segment:

    - LV metadata itself (struct logical_volume *lv)

    - LV's DM_DEVICE_INFO ioctl result (struct lvinfo *info)

    - LV's segment DM_DEVICE_STATUS ioctl result (this status must be
      bound to a segment, not the whole LV as the whole LV may be
      composed of several segments of course)
      (this is the new struct lv_seg_status *seg_status)
2014-11-11 08:53:28 +01:00
20b22cd023 libdm: still better API
Do not use 'any' policy name as a value in config tree - so we stick
with 'policy_settings' and extra 'policy_name' for libdm params.

Update lvm2 API as well.

Example of supported metadata:

 policy = "mq"
 policy_settings {
      migration_threshold = 2048
      sequential_threshold = 512
      random_threshold = 4
      read_promote_adjustment = 10
 }
2014-11-11 00:54:03 +01:00
ca509c9746 dev_manager: workaround to allow top-level _tmeta, _tdata 2014-11-11 00:53:37 +01:00
a7fc108298 mirror: layer remove doesn't work properly with mirrors 2014-11-10 22:32:43 +01:00
094596cfd2 tests: reach cache params 2014-11-10 22:05:49 +01:00
10ebabdd2a tests: cache snapshot 2014-11-10 22:05:49 +01:00
02f49caa35 debug: log tree type is created
Print tree type and use internal_error for unknown type.
2014-11-10 22:05:49 +01:00
f12e3da639 cleanup: gcc warnings 2014-11-10 22:05:49 +01:00
e5d3f81285 cleanup: indents comments backtraces 2014-11-10 22:05:49 +01:00
1e97d2dd28 cleanup: use chunk_size directly 2014-11-10 22:05:49 +01:00
f5e265a07f cache: use LV_PENDING_DELETE 2014-11-10 22:05:49 +01:00
f6932bfcf9 cache: _corig has UUID suffix
Use -real suffix for cache origin device.
2014-11-10 22:05:49 +01:00
6effcb16fc cache: option 2014-11-10 22:05:49 +01:00
c5c2665a21 man: _corig is reserved 2014-11-10 22:05:49 +01:00
3e230a8ad8 cache: new API for libdm 2014-11-10 22:05:49 +01:00
824019531c libdm: tunning cache API
Support new PASSTHROUGH 'feature' flag.

Add dm_config_node to pass in policy args.

Really use origin_uuid instead of using extra call
to pass seg_areas.

Switch to 64bit feature flag bit set so there is
enough space in future for new bits...
2014-11-10 22:05:48 +01:00
3dbcd2a1c9 cleanup: cache API get/set 2014-11-10 22:05:48 +01:00
2e0c926d56 cleanup: API get/set fixes 2014-11-10 22:05:48 +01:00
8d7340b7a1 report: for cache LV report chunksize
Cache LV reports chunksize via cache-pool.
2014-11-10 22:05:48 +01:00
6a41286c01 snapshot: virtual save commit
More efficient spare volume creation. Save 1 extra commit
and properly activate this volume according to our cluster
activation rules (using lv_active_change() for this).
2014-11-10 22:05:48 +01:00
ff30783a4f lv_manip: remove_layer_from_lv restore lv name
Since we 'layer' for cache origin which and we support dropping
cache layer - we need to restore origin name in case
the origin LV is more complex target  - i.e. raid.

Drop _corig from name

Cleanup and rename parent -> parent_lv.
2014-11-10 22:05:48 +01:00
979d12eb4a lvremove: few more validation before archive
Before we finally call archive, we still can do a few more validation
without modifying VG. So delay archive() call few lines.
2014-11-10 22:05:48 +01:00
e2c4a3ef67 segtype: add SEG_ONLY_EXCLUSIVE flag
Mark segtypes which do require exclusive activation in cluster.r
2014-11-10 22:05:48 +01:00
0dc73f7dbd dmeventd: time scaling for status retry
In normal case it's too slow to wait 1 second for default.
So rather start with short time and increase sleep between status
retesting.
2014-11-10 22:05:48 +01:00
62c7027a7c raid: fix activation order
Cannot 'activate' volumes in suspend state and we need to use
lock holding LV for suspend/resume.
2014-11-10 22:05:48 +01:00
32e4af6479 cache: used cache-pool becomes invisible
While cache-pool is in use - it is considered invisible.
2014-11-10 21:36:21 +01:00
09e32e4add pools: prompt only when metadata lv exists
If the VG has no pool metadata volume, don't prompt about
removal of _pmspare.
2014-11-10 21:35:56 +01:00
138c2417c0 pools: after fail of vg_write no restore
Revert part of commit 51a29e6056,
it's probably bad idea to continue with any recovery, when
vg_write() or vg_commit() fail - so it's better to leave it as it is.
2014-11-10 21:34:02 +01:00
94e4d5fcf5 cleanup: avoid dm_list size calc in common path
Calculate dm_list_size only when there is not just a single
ont segment in list - so it's only counted on error path.
2014-11-05 15:30:59 +01:00
6e5790f2d2 activate: check all snap segs are inactive
When deactivating origin, we may have possibly left table in broken state,
where origin is not active, but snapshot volume is still present.

Let's ensure deactivation of origin detects also all associated
snapshots are inactive - otherwise do not skip deactivation.
(so i.e. 'vgchange -an' would detect errors)
2014-11-05 15:30:58 +01:00
a3a2c792a8 lv: lv_active_change add needs_exclusive flag
Let's use this function for more activations in the code.

'needs_exlusive' will enforce exlusive type for any given LV.

We may want to activate LV in exlusive mode, even when we know
the LV (as is) supports non-exlusive activation as well.

lvcreate -ay   -> exclusive & local
lvcreate -aay  -> exclusive & local
lvcreate -aly  -> exclusive & local
lvcreate -aey  -> exclusive  (might be on any node).
2014-11-05 15:29:43 +01:00
a82dcadf66 snapshot: no snapshot of any cache type LVs
Unsupported as of now.
2014-11-05 15:28:38 +01:00
3261e539a0 cleanup: keep 'fall through' switch case for LVSINFO for compiler to understand this properly 2014-11-05 10:46:52 +01:00
bf4681ba13 report: cleanup: simplify LVSINFO detection
LVSINFO is just a subtype of LVS report type with extra "info" ioctl
called for each LV reported (per output line) so include its processing
within "case LVS" switch, not as completely different kind of reporting
which may be misleading when reading the code.

There's already the "lv_info_needed" flag set in the _report fn, so
call the approriate reporting function based on this flag within the
"case LVS" switch line.

Actually the same is already done for LV is reported per segments
within the "case SEGS" switch line. So this patch makes the code more
consistent so it's processed the same way for all cases.

Also, this is a preparation for another and new subtype that will
be introduced later - the "LVSSTATUS" and "SEGSSTATUS" report type.
2014-11-05 10:42:18 +01:00
160777bb3e dmeventd: Add basic thread debugging messages.
Only with -DDEBUG.
2014-11-04 18:56:20 +00:00
89f635a075 dmeventd: Include shutdown threads in responses.
When responding to DM_EVENT_CMD_GET_REGISTERED_DEVICE no longer
ignore threads that have already been unregistered but which
are still present.

This means the caller can unregister a device and poll dmeventd
to ensure the monitoring thread has gone away before removing
the device.  If a device was registered and unregistered in quick
succession and then removed, WAITEVENT could run in parallel with
the REMOVE.

Threads are moved to the _thread_registry_unused list when they
are unregistered.
2014-11-04 16:58:14 +00:00
6b25faa218 dmeventd: Remove redundant checks.
The status of threads in _thread_registry is always DM_THREAD_RUNNING
(zero).

DM_EVENT_REGISTRATION_PENDING is never stored in thread->events.
2014-11-04 16:55:42 +00:00
cebbda0931 tests: duplicate update of config 2014-11-04 15:29:22 +01:00
00a45ca491 thin: new pool is activated without overlay
Activate of new/unused/empty thin pool volume skips
the 'overlay' part and directly provides 'visible' thin-pool LV to the user.

Such thin pool still gets 'private' -tpool UUID suffix for easier
udev detection of protected lvm2 devices, and also gets udev flags to
avoid any scan.

Such pool device is 'public' LV with regular /dev/vgname/poolname link,
but it's still 'udev' hidden device for any other use.

To display proper active state we need to do few explicit tests
for this condition.

Before it's used for any lvm2 thin volume, deactivation is
now needed to avoid any 'race' with external usage.
2014-11-04 15:29:22 +01:00
8563c3e1a9 thin: check for new pool before creating thin volume
Call check_new_thin_pool() to detect in-use thin-pool.
Save extra reactivation of thin-pool when thin pool is not active.
(it's now a bit more expensive to invoke thin_check for new pools.)

For new pools:

We now active locally exclusively thin-pool as 'public' LV.
Validate transaction_id is till 0.
Deactive.
Prepare create message for thin-pool and exclusively active pool.
Active new thin LV.
And deactivate thin pool if it used to be inactive.
2014-11-04 15:29:19 +01:00
6116b1d6e3 thin: validate unused thin pool
Function tests, that given new thin pool is still unused.
2014-11-04 15:28:00 +01:00
ee627884de thin: no validation skip of new thin pools
Allowing 'external' use of thin-pools requires to validate even
so far 'unused' new thin pools.

Later we may have 'smarter' way to resolve which thin-pools are
owned by lvm2 and which are external.
2014-11-04 15:28:00 +01:00
26aa912b46 thin: add lv_is_new_thin_pool
Recognize 'new' (and never used) lvm2 thin pool - it has 'transaction_id' == 0
(lv_is_used_thin_pool() has slightly different meaning).
2014-11-04 15:28:00 +01:00
89233544e0 libdm: allow to activate any pool with tid == 0
When transaction_id is set 0 for thin-pool, libdm avoids validation
of thin-pool, unless there are real messages to be send to thin-pool.
This relaxes strict policy which always required to know
in front transaction_id for the kernel target.

It now allows to activate thin-pool with any transaction_id
(when transaction_id is passed in)

It is now upto application to validate transaction_id from life
thin-pool volume with transaction_id within it's own metadata.
2014-11-04 15:28:00 +01:00
7092b47ec9 lvconvert: convert missing sizes to extents
After initial 'size' usage converted to extents, continue to use
only extents.

(in-release fix).
2014-11-04 15:25:47 +01:00
847b2aa5b4 tests: thin 2014-11-03 14:19:34 +01:00
e4e96f6b19 tests: usage of -m0 -Mn
Test -m0 passed with types.
Check --readahead and thins.
2014-11-03 14:19:34 +01:00
6c32ced657 cleanup: use lv_is_pool
Use lv_is_pool() to detect both pool versions.
2014-11-03 14:19:34 +01:00
0ba5571bab cleanup: use logical_volume* directly 2014-11-03 14:19:34 +01:00
fdc252ec35 cleanup: consistent name 2014-11-03 14:19:34 +01:00
ce7f06cf4e cleanup: shorter code 2014-11-03 14:19:34 +01:00
1b439a0b8e cleanup: rename function
Make more clear dm_info type.
2014-11-03 14:19:34 +01:00
228e7ff767 cleanup: standard params ordering
Pass lvconvert_params as last arg.
2014-11-03 14:19:34 +01:00
a0f7d6e36a cleanup: init of lcp
Use struct initializer instead of memset().
2014-11-03 14:19:34 +01:00
d6c5445bea cleanup: correcting tracing
Use log_error for real error.
2014-11-03 14:19:34 +01:00
d574072dd8 cleanup: use arg_is_set 2014-11-03 14:19:33 +01:00
ca9482b276 cache: report stats for cache volumes usage
Show some stats with 'lvs'
Display same info for active cache volume and cache-pool.

data% - #used cache blocks/#total cache blocks
meta% - #used metadata blocks/#total metadata blocks
copy% - #dirty/#used cache blocks

TODO: maybe there is a better mapping
 - should be seen as first-try-and-see.
2014-11-03 14:19:33 +01:00
b7bc28b7b7 cache: wipe cache-pool before reuse
Before we reuse cache-pool - we need to ensure metadata volume
has wiped header.
2014-11-03 14:19:33 +01:00
29bd3cccc8 cache: support activation of empty cache-pool
When the cache pool is unused, lvm2 code will internally
allow to activate such cache-pool.

Cache-pool is activate as metadata LV, so lvm2 could easily
wipe such volume before cache-pool is reused.
2014-11-03 14:19:33 +01:00
ab49120465 cache: lv_cache_status
Replace lv_cache_block_info() and lv_cache_policy_info()
with lv_cache_status() which directly returns
dm_status_cache structure together with some calculated
values.

After use  mem pool stored inside lv_status_cache structure
needs to be destroyed.
2014-11-03 14:19:33 +01:00
13e6369d7f cleanup: add arg to _setup_task
Add init of  no_open_count into _setup_task().
Report problem as warning (cannot happen anyway).

Also drop some duplicated debug messages - we have already
printed the info about operation so make log a bit shorter.
2014-11-03 14:19:33 +01:00
cb931eed72 cleanup: rename virtual_extents
Use standard 'virtual_extents' naming.
Move virtual_size into  'lcp' struct out of lvcreate_params.
2014-11-03 14:19:33 +01:00
913f025d3e cleanup: use extents to pass size to /lib
Lib takes sizes in extens - do the same for pool_metadata.
2014-11-03 14:19:33 +01:00
d2e9802ba7 cache: add wipe_cache_pool
Add function for wiping cache pool volume.
Only unused cache-pool could be wiped.
2014-11-03 14:19:33 +01:00
0b7335f847 cache: allow deactivation of empty pool
Tool will use internal activation of unused cache pool to
clear metadata area before next use of cache-pool.
So allow to deactivation unused pool in case some error
case happend and we were not able to deactivation pool
right after metadata wipe.
2014-11-03 14:19:33 +01:00
969ab6bbf0 cache: convert thin-pool
Support caching of thin-pool.

lvresize needs to be resolved - so far, user
has to manually drop cache-pool before resizing.
2014-11-03 14:19:33 +01:00
127cf4895a thin: allow to convert chunksize of empty pool
When pool is not used, allow to change its chunksize.
2014-11-03 14:19:33 +01:00
7f35d42a99 thin: reporting of thin volumes simplified
Simplify reporting of percentage.
Allows easier support for more types.

Move testing of device availability into activate.c
2014-11-03 14:19:32 +01:00
897b091579 pool: validate sizes
0 size are not supported as well as negative.
2014-11-03 14:19:32 +01:00
dc11dcf11d filters: change return code
No data for writing should be seen as 'dump' success.
(reduces one <bactrace> in the log) - it has no other
effect.
2014-11-03 14:19:32 +01:00
c1ee6d4ffc lvcreate: tollerate defaults
lvcreate -m0 and -Mn goes with anything.
Read ahead works either with pools or thin/cache, but not with both.
2014-11-03 14:19:32 +01:00
ed2a0560ad libdm: init char array
When non-root uses dm_check_version() it's been printing some unit
values from stack. So always init those vars.
2014-11-03 14:19:31 +01:00
e09ee21fd4 tests: update raid sync 2014-10-31 00:37:35 +01:00
47d50a8f27 tests: wait for raid sync 2014-10-31 00:31:54 +01:00
e7c130430a tests: explicitely use old snapshots 2014-10-31 00:28:25 +01:00
8926230f6e tests: lvcreate snapshot usage update 2014-10-30 23:58:49 +01:00
b58a0f5cd3 tests: use aux func to disable device 2014-10-30 23:58:49 +01:00
da61e6355e tests: raid syncaction test
Add sync wait for syncaction of raid1 test.
--syncaction requires raid to be in sync first.
2014-10-30 23:58:49 +01:00
fe245d78ff cleanup: shorter code 2014-10-30 23:58:49 +01:00
888b21e9bd cleanup: extents_from_size is 32bit value
Current lvm2 does support only 32bit extents count.
2014-10-30 23:58:49 +01:00
9a6cf3d9f4 cleanup: prints and stacks 2014-10-30 23:58:49 +01:00
0da749c9a4 cleanup: remove unneeded assign 2014-10-30 23:58:49 +01:00
8bf4cd464f metadata: add extents_from_percent_size
Add API call to calculate extents from percentage value.
Size is based in DM_PERCENT_1 units.
(Supporting decimal point number).
This commit is preparing functionality for more global
usage of % with i.e. --size option.
2014-10-30 23:58:49 +01:00
375d7f1c2d pv_manip: check for pe_ranges 2014-10-30 23:58:49 +01:00
464f3b8abd lvmcmdline: support size_mb_arg_with_percent
New size_mb_arg_with_percent is able to read  size_mb_arg
but also it's able to read % values.

Percent parsing is share with int_arg_with_sign_and_percent.
2014-10-30 23:58:49 +01:00
519fbe71e4 lvmcmdline: extra support for decimal point
If root has locales with different decimal point then '.'
(i.e. Czech with ',') lets be tolerant and retry with
"C" locales in the case '.' is found during parse of number.

Locales are then restored back.
2014-10-30 23:58:49 +01:00
97cccfbf1c segtype: drop cmdcontex pointer
Users of context provide their cmd pointer,
so don't keep it inside segtype.
2014-10-30 23:58:49 +01:00
87fc3b710c lvcreate: improving recent lvcreate updates
We need to be able to parse:

lvcreate --type snapshot -s
lvcreate --type thin -s
lvcreate --type cache-pool -H
2014-10-30 23:58:48 +01:00
651613e9a4 man: update lvcreate with sparse
Document sparse device creation and its default segtype selection.
2014-10-30 23:58:48 +01:00
e6e647489d configure: autoreconf
Just rebuild after configure.in update.
2014-10-30 23:58:48 +01:00
e0164f2188 sparse: configurable type for sparse volumes
Support compile type configurable defaults for creation
of sparse volumes.

By default now create 'thin-pools' for sparse volumes.
Use the global/sparse_segtype_default to switch back to old
snapshots if needed.

Apply the same compile logic for newly introduces mirror/raid1 options.
2014-10-30 23:58:48 +01:00
87f59af15c configure: option cleanup
Drop double [[ ]] around default args.
(AC_HELP_STRING is already quoted so double [[]] are not needed).
2014-10-30 23:51:39 +01:00
7049eeeb83 test: for issue fixed in previous commit 2f7f6932dc 2014-10-27 11:53:01 +01:00
2f7f6932dc report: selection: fix selection criteria to not match reserved values when using >, <, >=, <
Some values are reserved for special purpose like 'undefined', 'unmanaged' etc.
When using >, <, >= and < comparison operators where the range is considered,
do not include reserved values as proper values in this range which
would otherwise result in not so obvious criteria match (as the reserved value is
actually transparent for the user). It's incorrect.

Example scenario:
$ vgs -o vg_name,vg_mda_copies vg1 vg2
  VG   #VMdaCps
  vg1          1
  vg2  unmanaged

The "unmanaged" is actually mapped onto reserved value
18446744073709551615 (2^64 - 1) internally.

Such reseved value is already caught on selection criteria input
properly:

$ vgs -o name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies=18446744073709551615'
  Numeric value 18446744073709551615 found in selection is reserved.

However, we still need to fix situaton where the reserved value may be
included in resulting range:

Before this patch:
$ vgs -o vg_name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies >= 1'
  VG   #VMdaCps
  vg1          1
  vg2  unmanaged

With this patch applied:
$ vgs -o vg_name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies >= 1'
  VG   #VMdaCps
  vg1         1

From the examples above, we can see that without this patch applied,
the vg_mda_copies >= 1 also matched the reserved value 18446744073709551615
(which is represented by the "unamanged" string on report). When
applying the operators, such values must be skipped! They're meant to
be matched only against their string representation only, e.g.:

$ vgs -o name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies=unmanaged'
  VG   #VMdaCps
  vg2  unmanaged

...or any synonyms:

$ vgs -o name,vg_mda_copies vg1 vg2 -S 'vg_mda_copies=undefined'
  VG   #VMdaCps
  vg2  unmanaged
2014-10-27 11:25:08 +01:00
e223c801fc pools: workaround hints
Missing code for stacked hint estimation
2014-10-26 19:45:17 +01:00
c28a7706ed tests: update cache creation tests 2014-10-26 18:37:13 +01:00
7bbf3cf306 tests: lvcreate-update
Test with old mirror type.
2014-10-26 18:37:13 +01:00
70616187b3 tests: pytest update 2014-10-26 18:37:13 +01:00
205e3ff888 lvcreate: delay check for free extents
As the rounding for cache creation may change the value of extents
postpone check for free extents.
2014-10-26 18:37:13 +01:00
c9fbbf48ba cache: support more args
Unlike with thin-pool - with cache we support all args also
directly when create cache volume.

So the result of 'separate' cache-pool creation and setting its
options should give same result as specifying those args
during cache creation.

Cache-pool values are used as defaults if the params are
not specified with cache creation.
2014-10-26 18:37:13 +01:00
ff2e8b0de6 thin: simplify thin volume creation
Move code for creation of thin volume into a single place
out of lv_extend().  This allows to drop extra pool arg
for alloc_lv_segment() && lv_extend() and makes code
more easier to read and follow.
2014-10-26 18:37:13 +01:00
52dfa6dd44 cache: apply chunk rounding also for cache creation.
When we create volumes with chunk size bigger then extent size
we try to round up to some nearest chunk boundary.
Until now we did this for thins - use same logic for
cache volumes.
2014-10-26 18:37:13 +01:00
25307e4add pools: prefetch pool_lv and origin_lv
Load pool_lv and origin_lv at a single place and
use it for more types as they need them.
2014-10-26 18:37:13 +01:00
618d818c0d lvm2app: update to new lv_create_single API
lv_create_single is more type based.
2014-10-26 18:37:13 +01:00
7916cae697 vg_read: Remove unused READ_WITHOUT_LOCK.
Unused since 67a7b7a87d:
  report: Iterate over labels instead of PVs for label-only reports.
(included in 2.02.105).
2014-10-24 21:54:04 +01:00
c3bb9629a8 tests: syncaction needs kernel fix
Add 'should' as we currently cannot pass this test.

FIXME:
Add properly wrapper to not use 'should' with fixed kernel.
2014-10-24 16:39:32 +02:00
e1dede6f6b tests: new lvcreate functionality
Fixed syntax parsing means that some commands that used to work are now
failing. Particullary this case:

$ invalid lvcreate -l1 --type thin vg/pool
> Needs to fail becase thin type LV needs  --virtualsize

$ invalid lvcreate --type snapshot vg/lv1
> Needs to fail because old-snapshot segment type needs --size

Some reported error messages have been also updated.
2014-10-24 16:39:32 +02:00
9642f013a1 tests: lvcreate usage 2014-10-24 16:39:32 +02:00
11ea72cfd8 mirror: extra parsing for mirrorlog arg
Put validation of mirrorlog arg into a separate function.
2014-10-24 16:39:32 +02:00
29c14a1194 man: lvconvert/create updates
More description for cache support.
Introduce --pooldatasize option.
2014-10-24 16:39:32 +02:00
fd00d2c6ec cache: separate func for pool/origin validation
Split validate_lv_cache_create() into 2 function
once is called for pool validation other for origin.

It's less misleading the accepting NULLs.
2014-10-24 16:39:32 +02:00
298de1f5c3 segments: mark more of them unzeroable
Use segment flags to avoid zeroing of cache, cache pool
snapshot and thin pool segments.

We never want to zero these segment types.

Note:
Snapshot COW and Cache origin are created as stripes
thus are then properly zeroed.
2014-10-24 16:39:32 +02:00
784c216d2b lvcreate: check for conflicting -Zy -Wy
Let the finaly state of zero & wipe_signature to be
resolved later together with all the types.

Don't play with zero assigment and segtype flag
(i.e. thin-pool -Z  has different meaning).

Check if the passed options do allow requested zeroing/wiping.

lvcreate without -Z or -W will fallback to warning if the device
cannot be zeroed, however if user requested them explicitely
it will give user error.
2014-10-24 16:39:32 +02:00
c7484a139a toollib: persistent major minor
Deduce -M from presence of --minor, --major option if
not specified on command line.
2014-10-24 16:39:32 +02:00
d13239b054 lvcreate: new validation code
Refactor lvcreate code.

Prefer to use arg_outside_list_is_set() so we get automatic 'white-list'
validation of supported options with different segment types.

Drop used lp->cache, lp->cache and use seg_is_cache(), seg_is_thin()

Draw clear border where is the last moment we could change create
segment type.

When segment type is given with --type - do not allow it to be changed
later.

Put together tests related to individual segment types.

Finish cache conversion at proper part of lv_manip code after
the vg_metadata are written - so we could correcly clean-up created
stripe LV for cache volume.
2014-10-24 16:39:32 +02:00
51a29e6056 pools: error path removes metadata
When pool volume is create - it has already managed to update metadata
once within lv_extend - so revert new created LV here.
2014-10-24 16:39:32 +02:00
dfcf03a9ce lvcreate: handle linear segment
Put in code to accept 'linear' segment type
(when specified stripes cannot be used)

Also report 'error' when unknown type is specified.
2014-10-24 16:39:32 +02:00
7359a9df88 pool: better error path handling
Move test for size of new LV names in front before
any creation of LV.

Properly check striped  segtype kernel presence,
since passed 'segtype' is already tested.

Keep deactivation error path local to wiping part of the function.

Create metadata with temporary flag (it's activated, zeroed
and deactivated).
2014-10-24 16:39:32 +02:00
1632064281 cleanup: code move
Update comment and move code to new place.
Gets updated with next commit.
2014-10-24 16:39:32 +02:00
b23e125982 cleanup: function embeded
It's used just in one place now.
2014-10-24 16:39:32 +02:00
21798418fc cleanup: better stack tracing
Show proper backtrace on error path.
2014-10-24 16:39:32 +02:00
a330640063 options: introduce pooldatasize option
Introduce new option to specify pool data size.
This will be user to create i.e.  cache & cachepool at once.
And possible for thin external origin snapshot.

This is only very basic patch to enable options, the
real working code will come later.
2014-10-24 16:39:32 +02:00
9a6758e953 cleanup: use matching flags for permissions
Since our status bits are 64b - use uint64_t for permissions.
2014-10-24 16:39:31 +02:00
37bd12e7ba cleanup: lv_manip drops duplicated internal error
No reason to check the same condition twice with internal error.
2014-10-24 16:39:31 +02:00
958cae8fd8 cleanup: use arg_is_set 2014-10-24 16:39:31 +02:00
f2ea890423 cleanup: don't backup twice 2014-10-24 16:39:31 +02:00
a4788b4994 cleanup: move code for checking vg features
Move code that checks for needed VG features into separate
smaller function.
2014-10-24 16:39:31 +02:00
b726003b85 cleanup: simplier lv name construction
Using NAME_LEN max lv name size.
2014-10-24 16:39:31 +02:00
9e85dbbfd0 cleanup: sort args alphabetically
Give it some order for easier human lookup for options we do support.
2014-10-24 16:39:31 +02:00
cf674142a2 cleanup: move code 2014-10-24 16:39:31 +02:00
4f8ed25a99 cleanup: indent
Various indents and tiny error message improvements.
2014-10-24 16:39:31 +02:00
c6456bd639 cleanup: commands.h update descriptions 2014-10-24 16:39:31 +02:00
df933c2ac9 cleanup: commands.h shorted string
Replace  " "\n"  with simplier  \n"
2014-10-24 16:39:31 +02:00
f1cb267274 lv_manip: preserve read-only status in layered volume 2014-10-24 16:39:31 +02:00
be3f666ef3 lv_manip: improve should_wipe reporting
We want to print smarter warning message only when
the zeroing was not provided on the first zeroable segment
of newly created LV.

Put warning within _should_wipe_lv function to avoid reevaluation
of same conditions twice.
2014-10-24 16:39:31 +02:00
2fc403b0fc toollib: new arg list functions
Check for negative arg list:
arg_from_list_is_negative()

Check for zero arg in list:
arg_from_list_is_zero()
2014-10-24 16:39:31 +02:00
fd1aa7fd5a segments: disable init of free segment
Since it is not needed and would require separate
code for validation disable its initialization.
2014-10-24 16:39:31 +02:00
128131dbc5 lvconvert: external detects more conflicts
Check for more prohibited types for external origin conversion.
TODO: Move this function to separate validation code.
(Continuing in release fixes.)
2014-10-24 16:39:31 +02:00
8a2f553b7d lvcreate: move tests that requires activation
Tests that needs active kernel driver put in single place.
2014-10-24 16:39:31 +02:00
f7cfea251c lvcreate: better logging for temporary device
Hide creation of temporary LVs and print them only in verbose mode.

e.g. hides confusing message about creation of _pmspare
device during creation of pool.
2014-10-24 16:39:31 +02:00
2c057f33f3 segtypes: macro segtype_is_unknown 2014-10-24 16:39:31 +02:00
237c54802c tools: read yes_no_arg via int_value
yes_no_arg is already parsed so read parsed value as int.
2014-10-24 16:39:31 +02:00
5bdf48b489 tools: refactor reporter code
Use new libdm macro DM_LIST_HEAD_INIT().
Embeded 'free' segment type (so it's not needed in the list)
Drop assignments of 0,NULL since they are defaults.
2014-10-24 16:39:31 +02:00
482e572e5d libdm: add DM_LIST_HEAD_INIT macro
Support to initialize dm_list struct members.
2014-10-24 16:39:31 +02:00
a98ea95c4d pool: better error message 2014-10-24 16:39:31 +02:00
a2244c3776 pool: fix testmode support with pools
Allow the --test mode to proceed further.
2014-10-24 16:39:31 +02:00
1c7aae40a1 raid: query lock holder
Ask for lock the proper LV.
Use the top-most LV to query for locally exclusive lock.

The rest of operations are then using 'lv_info()'

TODO:
  Check all devices are reloaded from proper level.
  In general any query on lv_is_active is supposed to be running
  ona lv_lock_holder() volume.
2014-10-24 16:39:31 +02:00
e901a87a69 cache: better error message 2014-10-24 16:39:31 +02:00
6e57dbfcaa cache: validate for locked
Add extra safety.
2014-10-24 16:39:31 +02:00
d4dab0aa34 cleanup: drop default implementation
Now we reference segment name via  lvseg_name() and
we can drop default implementation and leave its
function pointer to be NULL.

Default give us 'return seg->segtype->name'.
2014-10-24 16:39:31 +02:00
9411c19b31 segments: introduce lvseg_name
Instead of segtype->ops->name()  introduce lvseg_name().

This also allows us to leave name() function 'empty' for default
return of segtype->name.

TODO: add functions for rest of ops->
2014-10-24 16:39:30 +02:00
ab94045693 file-locking: skip locking of VG_SYNC_NAMES
VG_SYNC_NAMES is internal name with different meaning,
there is no point to search it in cache.
2014-10-24 16:39:30 +02:00
9351dca863 report: fix selection on {vg,lv}_permissions fields to properly match selection criteria
There was a bug in value and their synonym definition for these two fields
causing selections on these fields to not work correctly - nothing matched
against vg/lv_permissions fields even if selection criteria should have
matched.

Scenario:
$ lvs -o name,lv_permissions vg
  LV    LPerms
  lvol0 read-only
  lvol1 writeable

Before this patch:

$ lvs -o name,lv_permissions vg -S 'permissions=read-only'
(blank)
$ lvs -o name,lv_permissions vg -S 'permissions=writeable
(blank)

With this patch applied:

$ lvs -o name,lv_permissions vg -S 'permissions=read-only'
  LV    LPerms
  lvol0 read-only
$ lvs -o name,lv_permissions vg -S 'permissions=writeable'
  LV    LPerms
  lvol1 writeable

Also synonyms match correctly now:
$ lvs -o name,lv_permissions vg -S 'permissions=rw'
  LV    LPerms
  lvol1 writeable
2014-10-23 15:03:04 +02:00
4b611bb816 report: lv_permissions: display read-only/read-only-override instead of blank when LV is not writeable
Before this patch:
$ lvs -o name,lv_attr,lv_permissions
  LV    Attr       LPerms
  root  -wi-ao---- writeable
  swap  -wi-ao---- writeable
  lvol0 -Ri-a-----
  lvol1 -ri-a-----
  lvol2 -wi-a----- writeable
  lvol3 -ri-------

With this patch applied:
$ lvs -o name,lv_attr,lv_permissions
  LV    Attr       LPerms
  root  -wi-ao---- writeable
  swap  -wi-ao---- writeable
  lvol0 -Ri-a----- read-only-override
  lvol1 -ri-a----- read-only
  lvol2 -wi-a----- writeable
  lvol3 -ri------- read-only

("read-only-override" is displayed if the "writeable" permission
is overriden based on "activation/read_only_volume_list" lvm.conf
setting)
2014-10-23 10:18:29 +02:00
2c8e7821c3 NIX: Fix 32b builds (2G of RAM is 1M too much for 32b QEMU). 2014-10-22 09:03:26 +02:00
4988d799a2 liblvm2cmd: recognize quotes properly when splitting cmd line string into argv array fields
Fix lvm_split that is called when cmd line string is separated into
argv fields to recognize quote chars ('\'" and '"') properly and
when these quotes are used, consider the text within quotes as one
argument, do not separate it based on space characters inside.

The lvm_split is used during processing lvm shell command line or
when calling lvm commands through cmdlib (e.g. dmeventd plugins).

For example, the lvm shell scenario:

Before this patch:
$lvm
lvm> lvs --config 'global{ suffix=0 }'
  Parse error at byte 9 (line 1): unexpected token
  Failed to set overridden configuration entries.

With this patch applied:
$lvm
lvm> lvs --config 'global{ suffix=0 }'
  LV    VG     Attr       LSize   Pool Origin Data%  Meta%  Move Log  Cpy%Sync Convert
  root  fedora -wi-ao----   9.00g
  swap  fedora -wi-ao---- 512.00m

(Exactly the same problem is hit when calling LVM commands with
quoted arguments via lvm2cmd lib in dmeventd plugins.)
2014-10-17 14:03:43 +02:00
a6c294c5d0 toollib: remove unsed variable in process_each_segment_in_pv
Was left unused from the last change to this function.
2014-10-16 15:16:52 -05:00
23a38d242b toollib: remove dead code
Because of the recent change to process_each_pv(), the vg is always
provided when the pv is in a vg.  is_pv(pv) means the pv is in a vg,
which means that the vg arg will not be NULL, which means the removed
block of code is not needed.
2014-10-15 15:47:45 -05:00
4461c624bc NIX: Give the VMs 2G of RAM (for tmpfs) until the new runner is merged. 2014-10-14 21:07:00 +02:00
5e6e2d6b1b vgcreate: Permit non-power-of-2 extent sizes.
Relax validation to permit extent sizes > 128KB that are not powers of 2
with lvm2 format.  Existing code was already capable of handling this.
2014-10-14 18:12:15 +01:00
02628413ca systemd: remove workaround for lvm2-monitor.service's ExecStop line
Bug https://bugzilla.redhat.com/show_bug.cgi?id=843587 is handled better
now - the hang does not occur anymore. There are still error messages
issued though during shutdown if someone stops lvm2-lvmetad.service
manually that lvm2-monitor.service depends on (even during shutdown).
These errors are correct though and will point to incorrect
configuration (still having use_lvmetad=1 in lvm.conf and stopping
lvm2-lvmetad.service manually).

The workaround to prevent the hang is not needed now. So the
'--config "global{use_lvmetad=0}"' is now removed from the
lvm2-monitor.service's ExecStop line.
2014-10-14 10:08:23 +02:00
d1bcdd7338 device: Fix BLKSSZGET definition check. 2014-10-13 18:15:41 +01:00
22a6b0e40b lvchange: Allow appropriate actions on cache (in addition to thin) pools. 2014-10-13 16:21:41 +02:00
b59335fb39 toollib: validate_restricted_lvname_param
Lets make a separate new function to validate names that has
to follow up restriction rules.
2014-10-08 11:35:50 +02:00
c87e5a308a filter-usable: filter out blocked and suspended devices firmly when scanning for lvmetad
We can't hang on blocked or suspended devices when the scan is done
for lvmetad update - when the device gets unblocked or resumed, there's
always CHANGE event generated which will fire the udev rule to run
extra pvscan --cache for that device which makes sure that lvmetad
is up-to-date.
2014-10-08 11:03:08 +02:00
f3bb1c018f vgremove: Use process_each_lv_in_vg. 2014-10-07 16:45:45 +01:00
d623034e62 test: Fix lvconvert-raid-allocation's use of lvconvert --repair. 2014-10-07 16:12:04 +02:00
88959032f7 metadata: Fix find_pv_in_vg for missing PVs/filtered devices. 2014-10-07 16:11:56 +02:00
0cbb381e15 lvcreate: regression fix on lv name limits
When we are given an existing LV name - it needs to be allowed
to pass in even restricted name as the LV could have existed
long before we introduced some new restriction on prefix/suffix.i

Fix the regression on name limits and drop restriction to be applied
on any existing LVs - only the new created LV names have to be
complient with current name restrictions.

FIXME: we are currently using restricted names incorrectly in few
other places - device_is_usable() skips restricted names,
and udev flags are also incorrectly set for restricted names
so these LVs are not getting links properly.
2014-10-07 15:52:31 +02:00
27ff61d012 cleanup: rename _name, _lv and _size
Use some standard names for lv char * names, logical_volume * lv
and sizes internally.
2014-10-07 15:51:53 +02:00
62802ddae0 tests: typos 2014-10-07 10:19:33 +02:00
236db9fc0d tests: put devs into "" 2014-10-07 10:19:33 +02:00
75c4d268e9 tests: check for cache and raid
Skip some tests on systems without cache or raid.
2014-10-07 10:19:33 +02:00
c59ef73206 tests: move cache raid to separate file 2014-10-07 10:19:33 +02:00
9810f8aac7 cleanup: dont hide pv_dev declaration from pv
Just skip using local vars here...
2014-10-07 10:19:32 +02:00
b836525d9c test: Creating a cache on top of active RAID works now. 2014-10-07 09:32:24 +02:00
888da17495 metadata: add internal error if PV has no existing device attached during find_pv_in_vg
find_pv_in_vg fn iterates over the list of PVs covered by the VG and
each PV's pvl->pv->dev is compared with device acquired from device
cache. However, in case pvl->pv->dev is NULL as well as device cache
returns NULL (e.g. when device is filtered), we'll get incorrect match
and the code calling find_pv_in_vg uses incorrect PV (as it thinks
it's the exact PV with the pv_name). The INTERNAL_ERROR covers this
situation and errors out immediately.
2014-10-07 09:15:12 +02:00
b66f16fd63 lvconvert: Allow --repair and --splitmirrors on reserved-name LVs. 2014-10-07 08:58:24 +02:00
86dad329be test: Add process-each toollib tests. 2014-10-07 01:15:43 +01:00
8dc5f42254 metadata: Use flags to control warnings.
The warnings arg was used to enable logging of warnings
when reading a PV.  This arg is turned into a set of flags
with the WARN_PV_READ flag matching the existing behavior.

A new flag WARN_INCONSISTENT is added that will cause
vg_read_internal() to log the "VG is not consistent"
warning so the various callers do not need to log
this warning themselves.

A new vg_read flag READ_WARN_INCONSISTENT is used from
reporting to enable the WARN_INCONSISTENT flag in
vg_read_internal.

[Committed by agk with cosmetic changes and tweaks.]
2014-10-07 01:15:43 +01:00
e458fc9a6a vgreduce: Use process_each_pv.
Adapt process_each_pv for use by vgreduce in the non-repair case.

[Committed by agk with cosmetic changes and tweaks.]
2014-10-07 01:15:43 +01:00
f1a000a477 toollib: Rewrite process_each_pv.
Process PVs by iterating through VGs, then iterating through
devices if the command needs to process non-PV devices.
The process_single function can always use the VG and PV args.

[Committed by agk with cosmetic changes and tweaks.]
2014-10-07 01:15:43 +01:00
aeb4d3b740 lvmcache: Skip VG_GLOBAL cache lock state update.
Avoids message:
  Metadata cache has no info for vgname: "#global"
2014-10-07 01:15:43 +01:00
31f10a0554 man: lvmcache mention automatic pool conversion
When converting an origin to a cache lv, lvm will automatically convert
the specified cache pool into a cache pool if it is not already a cache
pool.
2014-10-06 16:22:54 -05:00
97b16ec26f toollib: Shuffle PV functions. 2014-10-06 22:02:00 +01:00
b7c81769e7 man: lvmcache changes related to removal and splitting 2014-10-06 14:04:09 -05:00
902192abdc man: lvmthin show the lvcreate -n option for pools
lvcreate of thin pools can now use '-n lv vg' like other lv types,
or it can name the new thin pool in the free arg as 'vg/lv', which
is not allowed with other lv types.
2014-10-06 13:29:18 -05:00
1115a9ea51 toollib: Remove unused functions from header file. 2014-10-06 15:22:01 +01:00
fa517221a1 tests: lvconvert cache usage of thin pool
Checked stacking usage of thin pool data volume being cached.
2014-10-06 15:31:44 +02:00
742d250cc5 tests: lvconvert thin pool
More tests.
2014-10-06 15:31:44 +02:00
c243cf6581 tests: lvconvert cache
Many new tests
2014-10-06 15:31:44 +02:00
52821572d5 tests: lvcreate external origin
Fix unsupportable case.
We cannot create thinpool and snapshot at the same time.
(-L could not have 2 meanings).
2014-10-06 15:31:33 +02:00
de0e6029f1 tests: lvcreate thin-pool support --name 2014-10-06 15:23:08 +02:00
4baf4b8cf9 tests: lvcreate cache interface updates 2014-10-06 15:23:08 +02:00
b7a78d81bc cleanup: indent 2014-10-06 15:23:08 +02:00
d9d50e4533 cleanup: typo update 2014-10-06 15:23:08 +02:00
916a68585e cleanup: error is already logged
Function get_only_segment_using_this_lv() already prints error,
no need to show more internal logic to user as an error.
2014-10-06 15:23:08 +02:00
73c74d582c cleanup: lvconvert use standard function exit
Use 1|0 inside _lvconvert_splitsnapshot to match rest of code.
2014-10-06 15:23:07 +02:00
8d272ba0ad validation: use validate_pool_chunk_size
We could validation pool chunk size with a single function.
2014-10-06 15:23:07 +02:00
6c44299006 validation: share more code for pool validation
Reuse thin validation code for cache pool validation.
2014-10-06 15:23:07 +02:00
57a52e7878 lvcreate: validate sizes
Earlier validation of --size and --extents.
Reject 0 size on command line instantly.
2014-10-06 15:23:07 +02:00
a0693da97f toolib: early validation of chunk size
Since we now have validate_pool_chunk_size() we could
validate entered values directly prior openning vg.
2014-10-06 15:23:07 +02:00
59ced3c281 pool: use validation 2014-10-06 15:23:07 +02:00
a2aa609810 pool: validate_pool_chunk_size
Introduce pool function for validation of chunk size.
It's good idea to be able to reject invalid chunk size
when entered on command line before we open VG.
2014-10-06 15:23:01 +02:00
7783fe3e93 man: document -ff for removal
Make it visible in man page that -ff could make removal
process proceed in case of damaged pool.
2014-10-06 15:22:24 +02:00
79ca382b2c vg/lvremove: support --yes
Make --yes equivalent to DONT_PROMT (--force).

So user could use 'lvremove --yes vg/lvol1' skipping prompt.
2014-10-06 15:22:24 +02:00
fbf14b12d8 man: lvconvert new split options
Update man page with info how to split/uncache cached logical
volumes.

lvconvert: splitsnapshot support --yes

Allow to use --yes to skip prompt.
2014-10-06 15:22:24 +02:00
cb49dd4aa4 lvconvert: splitsnapshot supports --yes
Handle --yes arg to skip prompt.
2014-10-06 15:22:22 +02:00
b2b18a5f8b lvconvert more test for thin external origin
Some LV types were not properly disallowed to be used as external origin.
2014-10-06 15:21:36 +02:00
60d2a63368 lvconvert: cache and thin conversion validation
More test for supported conversion.
2014-10-06 15:18:06 +02:00
ee344f1a9e lvconvert: validate cache conversion to snapshot
Cache cannot be converted into snapshot cow nor origin.
2014-10-06 15:18:06 +02:00
f76f2ce1df cache: use same alg for cache size calc
Use the same algorithm for cache metadata size as the cache tool is using.
2014-10-06 15:18:06 +02:00
d46c2f1c94 cache: improve creation code
Move code to better locations.
Improve test and remove invalid ones
(i.e. no reason to require cache size to be >= then origin).

Correctly comment where the code is doing actual conversion
of other existing volume - we do already a similar thing with
external origins.

Lots of new command line options and combinations is now supported.
Hopefully older syntax still works as well.

lvcreate --cache --cachepool vg/pool  -l1
lvcreate --type cache --cachepool vg/pool  -l1
lvcreate --type cache-pool vg/pool  -l1
lvcreate --type cache-pool --name pool vg  -l1
... and many many more ...
2014-10-06 15:18:06 +02:00
189d0f8e1d lvremove: detect cluster wide active state
If the LV is active remotely do not skip question for deactivation.
2014-10-06 15:18:06 +02:00
b37203c819 cache: check activation of volume activated
volume_list may silently skip activation which is then still reported as
success.
2014-10-06 15:18:06 +02:00
75119d85b3 cache: lvremoved cached LV removes cache pool
When we remove cached volume, whole tree must go down.
There is  'lvconvert --splitcache' to preserve cache pool.
2014-10-06 15:18:06 +02:00
cb273fe164 pools: move removal of _pmspare
Since _pmspare is internal volume move it to
lv_remove_single -  so it's automatically removed with
last remove thin-pool.

lv_remove_with_dependencies() is not always used for pool removal.
2014-10-06 15:18:06 +02:00
20803f2275 lvcreate: reuse validation of names
Use validate_lvname_param() for name validation.
2014-10-06 15:18:06 +02:00
0662391ff6 lv_manip: fix out of order backup
We had only 2 remaining places that were leaving unbackuped metadata.
2014-10-06 15:18:05 +02:00
a0cfc5eee2 lvconvert: reuse cache validation
Validation is now already in
validate_lv_cache_create() so reuse it.

Also properly rename var origin -> origin_lv.
2014-10-06 15:18:05 +02:00
5a36691843 cache: add validate_lv_cache_create
Move validation tests into separate function.
2014-10-06 15:18:05 +02:00
a8497e329b lvconvert: options splitcache, split, uncache
--splitcache
  Splits only cached LV (also pool could be specified).
  Detaches cachepool from cached LV.

  --split
  Should be univerzal command to split various complex targets.
  At this moment it knows cache.

  --uncache
  Opposite command to --cache. Detaches and DELETES cachepool for
  cached LV.

Note: we support thin pool cached metadata device for uncaching.
Also use may specify wither cached LV or association cachepool device
to request split of cache.
2014-10-06 15:18:05 +02:00
4e9fbb4b96 toollib: validate also name
In validate_lvname_param() call also validate_name().
2014-10-06 15:18:05 +02:00
68bf974769 lvcreate: support --cache and --cachepool
Enable in cmdline options for cache and cachepool.
2014-10-06 15:18:05 +02:00
fc77e4291b commands: support shortcut -H for cache objects
Introduce cache_long_ARG for those instancies
where --cache is not related to caching LV.
(pvchange,vg|lv|pvscan).

cache_ARG is now with -H shortcut.
2014-10-06 15:18:05 +02:00
1a6c892864 thin: better thin snapshot error detection
While creating thin snapshot, we cannot use size argument.
2014-10-06 15:18:05 +02:00
1ef660be46 thin: lvcreate improve check of thin params
Use arg_from_list_is_set()
Resolve pool_lv at one single place.
Replace use of find_lv_in_vg() with find_lv().
2014-10-06 14:53:16 +02:00
487723e0df lvcreate: refactor code
Over the time lvcreate code has accumulated various hacks.
So try to move that code in right places.

Detect all types early in _lvcreate_params() so functions like
_read_size_params() do not need to change volume types.

Also ultimately respect give volume --type, that its shortcut
(-T, H, -m, -s) and after that options which do type estimation.
(i.e. --cachepool, --thinpool)

Avoid repeative tests - if we know all types are decode at once
place we can 'optimize' number of validations.
2014-10-06 14:52:16 +02:00
072e25a965 test: Show an activation bug in lvcreate of a cache over raid. 2014-10-06 08:11:42 +02:00
d2f901f04f lvconvert: Forward --splitmirror to a cache origin when applicable. 2014-10-06 08:11:06 +02:00
91615603cd toollib: Rewrite process_each_lv.
Copy the same form as the new process_each_vg.
Replace unused struct cmd_vg and cmd_vg_read() replicator
code with struct vg and vg_read() directly.
The failed_lvnames arg is no longer used since the
cmd_vg replicator wrapper was removed.

[Committed by agk with cosmetic changes and tweaks.]
2014-10-03 23:37:49 +01:00
bfb6a4ecc6 toollib: Rewrite process_each_vg.
Split VG argument collection from processing.
This allows the two different loops through VGs to
be replaced by a single loop.
Replace unused struct cmd_vg and cmd_vg_read() replicator
code with struct vg and vg_read() directly.

[Committed by agk with cosmetic changes and tweaks.]
2014-10-03 20:47:19 +01:00
91198ac13e man: lvmcache better cache mode info and other command variations 2014-10-02 12:01:58 -05:00
17ab39f743 cache: include cache mode in vg metadata and display
The cache mode of a new cache pool is always explicitly
included in the vg metadata.  If a cache mode is not
specified on the command line, the cache mode is taken
from lvm.conf allocation/cache_pool_cachemode, which
defaults to "writethrough".

The cache mode can be displayed with lvs -o+cachemode.
2014-10-02 11:17:41 -05:00
a976226e81 cleanup: remove compiler warning about possible uninitialized variable use
filters/filter-usable.c:22: warning: "ucp.check_..." may be used uninitialized in this function

This can't actually be hit in real, but let's clean this up for the compiler
to be happy again.
2014-10-02 13:21:24 +02:00
5011cac9cf filters: add cmd->full_filter - composite of cmd->filter and cmd->lvmetad_filter
There are actually three filter chains if lvmetad is used:
  - cmd->lvmetad_filter used when when scanning devices for lvmetad
  - cmd->filter used when processing lvmetad responses
  - cmd->full_fiilter (which is just cmd->lvmetad_filter + cmd->filter chained together) used
    for remaining situations

This patch adds the third one - "cmd->full_filter" - currently this is
used if device processing does not fall into any of the groups before,
for example, devices which does not have the PV label yet and we're just
creating a new one or we're processing the devices where the list of the
devices (PVs) is not returned by lvmetad initially.

Currently, the cmd->full_filter is used exactly in these functions:
  - lvmcache_label_scan
  - _pvcreate_check
  - pvcreate_vol
  - lvmdiskscan
  - pvscan
  - _process_each_label

If lvmetad is used, then simply cmd->full_filter == cmd->filter because
cmd->lvmetad_filter is NULL in this case.
2014-10-02 13:06:46 +02:00
d3fb69c3f3 cleanup: remove symlink to profile in test dir for CLEAN target 2014-10-02 09:30:38 +02:00
1cdb8766a7 tools: Add ENABLE_ALL_DEVS flag.
The ENABLE_ALL_DEVS flag is added to the command structure
for commands that should process all devs (pvs and non-pvs)
when they call process_each_pv and the command includes the
--all arg.  This will be used in a later process_each_pv patch.
2014-10-01 22:58:23 +01:00
e6ab275aa0 tools: Add ALL_VGS_IS_DEFAULT flag.
The ALL_VGS_IS_DEFAULT flag is added to the command structure
for commands that should process all vgs when they call
process_each_vg or process_each_lv with no args.
This will be used in later patches to process_each functions.
2014-10-01 22:58:00 +01:00
d66f257452 man: lvmthin mention alternate syntax
Users will probably run across the alternate syntax,
so we should explain how it relates to what is used here.
2014-10-01 10:44:18 -05:00
33b96bef5b Revert "Revert "man: lvmcache should use clearer cache pool options""
This reverts commit f120c954fc.
2014-10-01 10:43:53 -05:00
a5f01dad22 filters: refresh filters when lvmetad use is toggled
We need to use proper filter chain when we disable lvmetad use
explicitly in the code by calling lvmetad_set_active(0) while
overriding existing configuration. We need to reinitialize filters
in this case so proper filter chain is used. The same applies
for the other way round - when we enable lvmetad use explicitly in
the code (though this is not yet used).
2014-09-30 16:08:05 +02:00
c2981cf921 filters: use usable device filter and separate lvmetad filter chain so it's not reevaluated for any lvmetad response
With this change, the filter chains used look like this now:

  A) When *lvmetad is not used*:
    - 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

  B) When *lvmetad is used* (two separate filter chains):
     - the lvmetad filter chain used when scanning devs for lvmetad update:
       sysfs filter -> global regex filter -> type filter ->
       usable device filter(FILTER_MODE_PRE_LVMETAD) ->
       mpath component filter -> partitioned filter ->
       md component filter

     - the filter chain used for lvmetad responses:
       persistent filter -> usable device filter(FILTER_MODE_POST_LVMETAD) ->
       regex filter
2014-09-30 13:22:11 +02:00
8a843d0d97 filters: add "usable device" filter
Usable device filter is responsible for filtering out unusable DM devices.
The filter has 3 modes of operation:

  - FILTER_MODE_NO_LVMETAD:
    When this mode is used, we check DM device usability by looking:
      - whether device is empty
      - whether device is blocked
      - whether device is suspended (only on devices/ignore_suspended_devices=1)
      - whether device uses an error target
      - whether device name/uuid is reserved

  - FILTER_MODE_PRE_LVMETAD:
    When this mode is used, we check DM device usability by looking:
      - whether device is empty
      - whether device is suspended (only on devices/ignore_suspended_devices=1)
      - whether device uses an error target
      - whether device name/uuid is reserved

  - FILTER_MODE_POST_LVMETAD:
    When this mode is used, we check DM device usability by looking:
      - whether device is blocked
      - whether device is suspended (only on devices/ignore_suspended_devices=1)

These modes will be used by subsequent patch to create different
instances of this filter, depending on lvmetad use.
2014-09-30 13:11:58 +02:00
00d8ab8492 refactor: make it possible to select what to check exactly when calling device_is_usable fn
Currently, there are 5 things that device_is_usable function checks
(for DM devices only, of course):
  - is device empty?
  - is device blocked? (mirror)
  - is device suspended?
  - is device composed of an error target?
  - is device name/uuid reserved?

If answer to any of these questions is "yes", then the device is not usable.
This patch just adds possibility to choose what to check for exactly - the
device_is_usable function now accepts struct dev_usable_check_params make
this selection possible. This is going to be used by subsequent patches.
2014-09-30 13:11:58 +02:00
fbc28cc7ad conf: Update comments on lvmetad+filters in example.conf.in. 2014-09-30 11:39:07 +02:00
9f3c11b39a man: lvmthin remove unnecessary fixme
The existing method for single step thin-pool + thin creation
makes sense.
2014-09-29 12:28:00 -05:00
9646c3359f Revert "Revert "man: lvmthin should use clearer thin pool options""
This reverts commit 17a1869df5.

We've agreed on the clearer syntax.
2014-09-29 12:26:16 -05:00
d1be66ba37 valgrind: don't eat mem with valgrind
When compiled with valgrind pool support - don't waste time
with preallocation of memory - it just waste of CPU cycles to
trace access to this memory.

We also may get slightly better estimation about real memory usage
during command processing.
2014-09-28 13:49:01 +02:00
f3e9ff7179 cleanup: drop unused variable 2014-09-28 13:49:01 +02:00
ad60805ffd lvconvert: switch to validate_lvname_param
Use new toollib function for validation.
2014-09-28 13:49:01 +02:00
0d4baeba18 toollib: introduce validate_lvname_param
Function for parsing and validating of lvname parameter.
2014-09-28 13:49:01 +02:00
89e1190ef0 cleanup: rename func
Update name of function read_and_validate_major_minor
and put it into the right header file toollib.h.

(In release update for f09f85d027)
2014-09-28 13:49:01 +02:00
911d6efa51 toollib: refactor extract_vgname
Split internals of extract_vgname into _extract_vgname.
This common code will be used for other similar function.

Reuse skip_dev_dir() instead of less mature coded to skip
device dir.

Instead of duplicating full vg/lv name - allocate string
only vg portion of lv name.
2014-09-28 13:49:01 +02:00
b0dde9e8f0 toollib: refactor skip_dev_dir
Detect dev dir just once.
2014-09-28 13:49:01 +02:00
f120c954fc Revert "man: lvmcache should use clearer cache pool options"
Revert: --cachepool  and --thipnpool is the right way

they both take arg

This is a major difference from  --cache   and --thin
2014-09-27 15:10:44 +02:00
17a1869df5 Revert "man: lvmthin should use clearer thin pool options"
Revert: --cachepool  and --thipnpool is the right way

they both take arg

This is a major difference from  --cache   and --thin
2014-09-27 15:08:31 +02:00
95df06d721 man: lvmthin should use clearer thin pool options
Previously, this was the recommended form for creating a thin pool:

lvconvert --thinpool VG/ThinDataLV --poolmetadata VG/ThinMetaLV

but this is confusing, because --thinpool does not actually take
an arg, and is more naturally used to specify an existing thin pool.

The new recommended form is:

lvconvert --type thin-pool --poolmetadata VG/ThinMetaLV VG/ThinDataLV
2014-09-26 16:05:30 -05:00
b53504ed37 man: lvmcache should use clearer cache pool options
Previously, this was the recommended form for creating a cache pool:

lvconvert --cachepool VG/CacheDataLV --poolmetadata VG/CacheMetaLV

but this is confusing, because --cachepool does not actually take
an arg, and is more natually used to specify an existing cache pool.

The new recommended form is:

lvconvert --type cache-pool --poolmetadata VG/CacheMetaLV VG/CacheDataLV
2014-09-26 14:40:40 -05:00
26dd17f834 lvchange: missed bits for a8aee7dba2
lv_info is not used here any more.
This code should have been committed with
lv_check_not_in_use API change commit.
2014-09-24 16:30:02 +02:00
45f57477f4 cleanup: Use segtype.h definitions of segment type names wherever possible
We are not using already defined segement type names where we could.

There is a lot of other places in device-mapper and LVM2 we have those
hardcoded so we should better finally have a common interface in
libdevmapper to avoid this.
2014-09-24 15:24:41 +02:00
21aa850b43 tests: add helper funcionality for using gdb
When there is need for using gdb within test suite
just prefix command with LVM_DBG and run test in
standard shell (for stdin).
2014-09-24 10:54:48 +02:00
9acbb0695f tests: drop * from dmsetup
We cannot use shell expansion for dmsetup here.
2014-09-24 10:54:48 +02:00
bc5031c283 debug: add debug message
Since we leave error printing on the called of deactivation,
at least put in debug log for this case.
2014-09-24 10:54:48 +02:00
edb3902c25 debug: show stacktrace on error path 2014-09-24 10:54:48 +02:00
2bfd986ea3 debug: drop printing debug trace without labeler
Not having labeller on device is not reason eo generate backtrace in log.
2014-09-24 10:54:48 +02:00
4319e06a0f debug: add missing stack trace 2014-09-24 10:54:48 +02:00
7531a9169e debug: monitor_dev_for_events stack trace 2014-09-24 10:54:48 +02:00
03aeb86762 cleanup: reindent
Save some code lines.
2014-09-24 10:54:48 +02:00
3cef6dd721 cleanup: drop duplicate const usage
const char == const char const.
2014-09-24 10:54:48 +02:00
f809fa5a78 cleanup: drop uneeded backup call
lv_update_and_reload already handle backup.
2014-09-24 10:54:48 +02:00
ec4ffeb51c cleanup: use supplied cmd pointer 2014-09-24 10:54:48 +02:00
30777fa46f cleanup: fix typo and use vg mempool
Since we are updating VG -  we can use its own mempool.
2014-09-24 10:54:47 +02:00
914be0696d cleanup: replace error with print message
These are not error messages.
They are informing a user about missconfigured
options which do not change resulting error status.
2014-09-24 10:54:47 +02:00
bc0a3e2355 cleanup: simplier _lv_passes_volumes_filter
Don't recreate string and just check components directly.
2014-09-24 10:54:47 +02:00
a121340139 cleanup: use find_lv_in_vg_by_lvid
Replace another loop with existion function.

TODO: consider using hash maps for lvname & lvid lookups.
2014-09-24 10:54:47 +02:00
a8aee7dba2 activate: update lv_check_not_in_use: API
Use of lv_info() internally in lv_check_not_in_use(),
so it always could use with_open_count properly.

Skip sysfs() testing in open_count == 0 case.

Accept just 'lv' pointer like other functions.

The function has 'built-in' lv_is_active_locally check,
which however is not what we need to check in many place.
For now at least remotely active snapshot merge is
detected and for this case merge on next activation is scheduled.
2014-09-24 10:54:47 +02:00
c96665e6a8 lvconvert: reoder old snapshot merge
Move check for snapshot-merge support before archiving.

Split code on 2 paths - with merge_on_activate
using vg_write & vg_commit
and lv_update_reload call for instant merging.

Move printing after backup.
2014-09-24 10:54:47 +02:00
84cdf85bd2 cleanup: constify activation usage of lv pointer
Let's enforce cheking of write access to LV by compiler.
Activation part does never need to write anything to LV
so keep LV pointer const.
2014-09-24 10:54:47 +02:00
af18e7cfbf cleanup: move printing after backup
Print successful result after making backup.
In this place we are sure to not keep memlock.
2014-09-24 10:54:47 +02:00
9f82a7d114 validation: move check for spare correctness
Check lv feature when we check LVs
2014-09-24 10:54:47 +02:00
93fbef1a45 vgchange: use NULL 'feature' of lv_info call
When NULL is passed for info the call itself
already does the same evaluation.
2014-09-24 10:54:47 +02:00
5b70bdc104 vgchange: add sync point
Before leaving _activate_lvs_in_vg() wait till devices
are active - so we do not print message about active
devices earlier then it really happens for a user.
2014-09-24 10:54:47 +02:00
13c07c685a thin and cache: improve conversion validation
More validations before any thin or cache related conversion begins.

We allow to use and stack:

pool data: cache or raid
pool metadata: raid

pool:  linear, striped
cache: linear, striped, raid
thin(extorig): linear, origin, cow, virtual, thin
2014-09-24 10:53:44 +02:00
cd3345a5b0 thin: no pool can be used for external origins
Cache pool can't be external origin either.
For simplicity use vg from passed LV.
2014-09-24 10:52:02 +02:00
a84d0d0c7b snapshot: use lv_update_and_reload 2014-09-24 10:51:15 +02:00
29970b0c17 snapshot: add missing vg_revert
Error path missed vg_revert call.
2014-09-24 10:50:29 +02:00
736f40134b mirror: extend adjusted_mirror_region_size API
We use adjusted_mirror_region_size() in two different contexts.

Either on command line -
 here we do want to inform user about reduction of size.

Or in pvmove activation context -
 here we should only use 'verbose' info.
2014-09-24 10:48:02 +02:00
fa6482344c lv_update_and_reload: use proper lock holder
When requesting to reload an LV imrove this API to
automatically reload its lock holding LV as in cluster
only top-level LVs are addressable with lock.
2014-09-24 10:48:02 +02:00
9776979b02 lv_ondisk: option search for lv without vg_ondisk
When vg_ondisk is NULL we do not need to search
through the whole VG to find out the same LV.

NOTE: as of now - VG locking is not enabled as some code parts
are breaking memory locking rules (lvm2app).

Once we enforce VG locking for read-only commands the effect
will be much better for larger VGs.
2014-09-24 10:48:01 +02:00
0f2adcc9ef activate: lv_check_not_in_use no check of closed
Don't perform expensive sysfs tests when the device is closed.
(having open_count == 0).
2014-09-24 10:47:00 +02:00
392bb6f46e fix: regression for recent persistent commit
Do not let fly metadata with just 'minor' set
(since they would not be readable on older version)

Be permissive with invalid major/minor number and
just report them as problem, but allow to use
such metadata with default major:minor.
2014-09-19 17:08:41 +02:00
18b8fdc8c9 cleanup: use int32 for major minor
Use consistently int32_t for major, minor.
2014-09-19 17:04:28 +02:00
d274724c83 cache: fix regression and invert test
Last commit c710f02e01
converting code to use lv_update_and_reload()
intoduced invalid test for error result.
Fix it and properly check for  if (!...)
2014-09-19 16:18:39 +02:00
386fbf8e0d debug: enhance mmap catch code
Use nice instruction_HLT macro
Use log_debug_mem()
Don't actually log things after we prohibit 'mmap'.
Move initialization of strerror & udev before blocking mmap.
2014-09-19 15:55:47 +02:00
081e406d0d man: document obsoleted options
It's shown on comand line help and it's accepted argument,
so provide matching man entry.
2014-09-19 15:55:47 +02:00
e3cbdde070 backup: drops locked memory
Since we want to backup metadata, this is the point
we no longer want to hold memory locked.
2014-09-19 15:55:46 +02:00
702b648215 cleanup: lvchange remove some extra code.
We do not need to restore LV content on error path - since
for reactivation we always use  ondisk/commited metadata,
so passed data are never used.

Drop some unneded extra message, since the called function
repeated logs same info.
2014-09-19 15:55:46 +02:00
3adc50ac22 lvchange: backup final metadata
Shift backup after final metadata commit.

Synchronize with wiping.
2014-09-19 15:55:34 +02:00
f09f85d027 tools: common handling of --persistent option
Move common code for reading and processing
of --persistent arguments for lvcreate and lvchange
into lvmcmdline.

Reuse validate_major_minor() routine for validation.

Don't blindly activate LVs after change in cluster
and instead only local reactivation is supported.
(we have now many limited targets now).

Dropping 'sigint_caught()' handling, since
prompt() is resolving this case itself.
2014-09-19 15:54:20 +02:00
73f4fa6bc1 metadata: validate major, minor numbers
Validate major, minor numbers after reading them from metadata.
2014-09-19 15:53:27 +02:00
656ba3a744 cleanup: use const for cmd context 2014-09-19 15:51:31 +02:00
e2312d28ed cleanup: switch to use CHANGE_AEY
Since for other enums we use 'Y' or 'N' use it with 'AE' as well.
2014-09-19 15:51:31 +02:00
f1e9e94a5b wipe_lv: move sync_local_dev_names in front
Synchronize things before checking for locally active volume.
2014-09-19 15:51:30 +02:00
d8b775f4eb memlock: drop uneeded lock
Avoid doing buffered operation within memory lock.
2014-09-19 01:13:49 +02:00
b0bd8ce408 memlock: ensure memory is allocation before locking
strerror may mmap ram if it was not yet used.
dm_udev_get_sync_support  may initilize udev if it was still not used.
2014-09-19 01:12:03 +02:00
2263a3bcf5 debug: mmap traps mmap and mmap64 on i386
Add code to trap both mmap implementation on 32bit arch.
Use dlsym()
Use hlt instraction instead of int3 - generates usable stack trace
when problem is catched.
2014-09-19 01:10:58 +02:00
9ffc8615e5 WHATS_NEW 2014-09-18 18:19:16 +02:00
b72e9d3a93 makefiles: fix linking of PIE code
PIE documentation:
:
https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html
http://lfs.osuosl.org/hlfs/view/unstable/glibc/chapter02/pie.html

suggest to suply -fPIE (or -fpie) with -pie
during executable compilation.

When -fPIC and -fPIE are used together - -fPIE wins

Drop usage of -DPIE - we are not using this flag anywhere

TODO: cleanup linking flags
2014-09-18 18:14:21 +02:00
d450c7fb10 debug: enhance trap of mmap
Don't install trap for mlockall case
Add another code path for -fPIE compilation,
in this case the address of mmap function is 'plt' address.
2014-09-18 16:56:13 +02:00
34bdb83c52 cleanup: update message 2014-09-18 00:53:42 +02:00
6d21438d0c debug: catch mmap with -DDEBUG_MEMLOCK 2014-09-18 00:48:06 +02:00
31548e4e7c cleanup: detect unsupported options earlier
Avoid unnecessary converions of pool.
2014-09-18 00:42:53 +02:00
8cbb04563a cache: Enable cache segment type by default. 2014-09-17 23:13:15 +01:00
ab2dacf6f6 lvconvert: Further restrictions on cache/pools.
Would be better to define what is supported not what isn't, but this'll
have to do for now.
2014-09-17 23:00:41 +01:00
a2a869afc8 lvconvert: Disallow mixing of cache and thin pools.
--cachepool can't take a thin pool and --thinpool can't take a
cache pool.
2014-09-17 17:11:01 +01:00
bdb05cc05e lvconvert: Restrict use of cache LVs.
Refuse use of -m and -s with cache LVs until full support
can be provided.
2014-09-17 16:41:58 +01:00
b4f5be76a3 cleanup: Remove metadata.h from tools dir.
metadata.h is meant to be internal to the library.
metadata-exported.h contains the things needed by tools.
2014-09-17 15:50:24 +01:00
98414ca7dd vgchange: support clustered conversion for active lv
If we want to support conversion of VG to clustered type,
we currently need to relock active LV to get proper DLM lock.

So add extra loop after change of VG clustered attribute
to exlusively activate all active top level LVs.

When doing change -cy -> -cn  we should validate LVs are not
active on other cluster nodes - we could be sure about this only
when with local exclusive activation - for other types
we require user to deactivate volumes first.

As a workaround for this limitation there is always
locking_type = 0 which amongs other skip the detection
of active LVs.

FIXME:
 clvmd should handle looks for cluster locking type all the time.
2014-09-17 14:41:42 +02:00
f90bc22ca5 locking: add locking_supports_remote_queries
Add function to detect whether locking could be used to
query for lock type so we could recognize exclusive
activation.
2014-09-17 14:36:38 +02:00
9d57aa9a0f cache-pool: Fix specification of cachemode when converting to cache-pool
Failure to copy the 'feature_flags' lvconvert_param to the matching
lv_segment field meant that when a user specified the cachemode argument,
the request was not honored.
2014-09-16 22:19:53 -05:00
b87a7683e2 clean-up: better macro usage
Use 'lv_is_mirror' instead of 'lv_is_mirrored && !lv_is_raid' - both
are the same as asking if the non-RAID mirror implementation is being
used.
2014-09-16 21:24:14 -05:00
4a853361b0 vgchange: disable cluster convert for active LVs
While we could probably reacquire some type of lock when
going from non-clustered to clustered vg, we don't have any
single road back to drop the lock and keep LV active.

For now keep it safe and prohibit conversion when LV
is active in the VG.
2014-09-16 11:42:41 +02:00
1ce21c19d5 va_list: properly pass va_list through functions
Code should not just pass va_list arg through the function
as args could be passed in many strange ways.
Use va_copy().

For details look in i.e.:

http://julipedia.meroh.net/2011/09/using-vacopy-to-safely-pass-ap.html
2014-09-16 11:42:40 +02:00
b9c16b7506 devices: Detect rotational devices.
Add dev_is_rotational() for future use by allocation code.
2014-09-16 00:44:25 +01:00
979be63f25 mirrors: Fix checks for mirror/raid/pvmove LVs.
Try to enforce consistent macro usage along these lines:

lv_is_mirror - mirror that uses the original dm-raid1 implementation
               (segment type "mirror")
lv_is_mirror_type - also includes internal mirror image and log LVs

lv_is_raid - raid volume that uses the new dm-raid implementation
             (segment type "raid")
lv_is_raid_type - also includes internal raid image / log / metadata LVs

lv_is_mirrored - LV is mirrored using either kernel implementation
                 (excludes non-mirror modes like raid5 etc.)

lv_is_pvmove - internal pvmove volume
2014-09-16 00:13:46 +01:00
829e5a4037 cmirror: fix endian issues on s390
Cmirrord has endian bugs, which cause failure to lvcreate a mirrored lv
on s390.
- data_size is uint32, should not use xlate64 to convert, which will
  cause data_size 0 after xlate.
- request_type and data_size still used by local(v5_data_switch),
  should convert later.  If request_type xlate too early, it will
  cause request_type judge error; if data_size xlate too early, it
  will cause coredump in case DM_ULOG_CLEAR_REGION.
- when receiving package in clog_request_from_network. vp[0] will always
  be little endian.  We could use xlate64(vp[0]) == vp[0] to decide if
  the local node is little endian or not.

Signed-off-by: Lidong Zhong<lzhong@suse.com> & Liuhua Wang <lwang@suse.com>
Signed-off-by: Jonathan Brassow <jbrassow@redhat.com>
2014-09-15 16:08:35 -05:00
e9216eedfe cleanup: fix last commit 2014-09-15 22:04:14 +01:00
2360ce3551 cleanup: Use lv_is_ macros.
Use lv_is_* macros throughout the code base, introducing
lv_is_pvmove, lv_is_locked, lv_is_converting and lv_is_merging.

lv_is_mirror_type no longer includes pvmove.
2014-09-15 21:33:53 +01:00
10a448eb2f tests: update lv_no_exists
On successful exit path remove debug.log file.
2014-09-15 13:51:19 +02:00
f435bef957 test: test there is no leak of LV on error path 2014-09-15 13:51:19 +02:00
75a5de1462 thin: check for active lv
Before calling deactivate, check the lv is actually active,
as we may reach this 'bad' error path with pool_lv inactive.
2014-09-15 13:51:19 +02:00
ef6508e9a4 WHATS_NEW for filter-related changes 2014-09-13 17:34:13 +02:00
30e0c0d863 libdm: finish the comment 2014-09-12 15:35:57 +02:00
5895657b59 libdm: fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
This is probably better approach than 3880ca5eca.

If dm module is not loaded during dm_is_dm_major call, there are no
lines for dm in /proc/devices, of course. Normally, dm_is_dm_major
is called to check existing devices, hence if module is not loaded,
we can expect there's no DM device present at the same time so we
can directly return 0 here (meaning the major number being inspected
is not dm device's one).

See also https://bugzilla.redhat.com/show_bug.cgi?id=1059711.
2014-09-12 15:28:51 +02:00
25ae9383bb revert: commit 3880ca5eca
There's a better solution to this...
2014-09-12 15:28:51 +02:00
ae08a3a294 cleanup: skip unused assign
Reset of tmp_names is only needed in else{} path.
2014-09-12 13:51:31 +02:00
07b3e6cd74 cleanup: avoid strlen() we know max size
Just use max NAME_LEN size buffer and copy the name.
2014-09-12 13:51:31 +02:00
ab7977de7b cleanup: simplify _extract_image_components
Reorder test - first check for writable flag and then allocate.
2014-09-12 13:51:31 +02:00
6898131091 cleanup: missing error message 2014-09-12 13:51:31 +02:00
3e57143abd cleanup: better error messages 2014-09-12 13:51:30 +02:00
08914ed7c1 raid: destroy allocation handle on error path
Don't leak ah memory pool on error path.
2014-09-12 13:51:30 +02:00
76c3c94bd2 cleanup: update _alloc_image_component function
Return allocated volume directly instead of 1/0.
2014-09-12 13:51:30 +02:00
126463ad1f cleanup: plain code reindent
Just simple reindent and brace changes.
2014-09-12 13:51:30 +02:00
ad376e9e00 debug: add missing stack trace on error path 2014-09-12 13:51:29 +02:00
c10c16cc35 raid: use _generate_raid_name
Use new function to get implicit name validation
(so we do not exit with internal error on metadata validation).
2014-09-12 13:51:29 +02:00
2db0312455 raid: add function for name creation
Add name for construction and validation of raid subvolume
name with a given suffix.

TODO: check if reusable for mirrors as well.
2014-09-12 13:51:29 +02:00
40b7b107b1 raid: check result of get_segtype_from_string
Error here is rather highly unpexpected for these types, but
stay consistent with rest of the code and don't use unchecked value.
2014-09-12 13:45:50 +02:00
08bde75093 raid: add missing archive call
Before starting to update raid metadata, archive existing unmodified one.
2014-09-12 13:45:49 +02:00
569184a3bb raid: add missing vg_revert
After failing vg_write() and suspend_lv() there was missing vg_revert() call.
2014-09-12 13:45:14 +02:00
dd1fa0e808 raid: add missing backups
Add backup() calls that were missing after successful update
of metadata.
2014-09-12 13:42:57 +02:00
15ba2afdc2 allocation: use vg memory pool
Looks like forgotten memory allocation related to VG used cmd mem pool.
2014-09-12 13:39:58 +02:00
3880ca5eca libdm: use dm-mod autoloading during dm_is_dm_major call if needed
For dm_is_dm_major to determine whether the major number given as
an argument belongs to a DM device, libdm code needs to know what
the actual DM major is to do the comparison.

It may happen that the dm-mod module is not loaded during this
call and so for the completness let's try our best before we start
giving various errors - we can still make use of dm-mod autoloading,
though only since kernels 2.6.36 where this feature was introduced.
2014-09-12 12:49:37 +02:00
f0cafc9281 conf: add allocation/physical_extent_size config option for default PE size of VGs.
Removes a need to use "vgcreate -s <desired PE size>" all the
time time just to override hardcoded default which is 4096KiB.
2014-09-12 10:09:21 +02:00
80ac8f37d6 filters: fix incorrect filter indexing in composite filter array
Caused by recent changes - a7be3b12df.
If global filter was not defined, then part of the code
creating composite filter (the cmd->lvmetad_filter) incorrectly
increased index value even if this global filter was not created
as part of the composite filter. This caused a gap with "NULL"
value in the composite filter array which ended up with the rest
of the filters after the gap to be ignored and also it caused a mem
leak when destroying the composite filter.
2014-09-11 09:30:03 +02:00
4748f4a9e4 tests: test for rename of snapshot 2014-09-10 22:59:13 +01:00
671d0ea1b1 lvmetad: Differentiate between filtered and truly missing devices.
We used to print an error message whenever we tried to deal with devices that
lvmetad knew about but were rejected by a client-side filter. Instead, we now
check whether the device is actually absent or only filtered out and only print
a warning in the latter case.
2014-09-10 22:58:22 +01:00
5f9b30d178 test: Add a test for MD component detection in pvscan --cache. 2014-09-10 22:58:12 +01:00
a7be3b12df lvmetad: Re-organise filters to properly avoid scans of component devices.
If a PV label is exposed both through a composite device (MD for example) and
through its component devices, we always want the PV that lvmetad sees to be the
composite, since this is what all LVM commands (including activation) will then
use. If pvscan --cache is triggered for multiple clones of the same PV, the last
to finish wins. This patch basically re-arranges the filters so that
component-device filters are part of the global_filter chain, not of the
client-side filter chain. This has a subtle effect on filter evaluation order,
but should not alter visible semantics in the non-lvmetad case.
2014-09-10 22:58:02 +01:00
1f0c4c811d dev-cache: Filter wipe does not guarantee a full /dev scan.
The code in dev_iter_create assumes that if a filter can be wiped, doing so will
always trigger a call to _full_scan. This is not true for composite filters
though, since they can always be wiped in principle, but there is no way to know
that a component filter inside will exist that actually triggers the scan.
2014-09-10 22:57:49 +01:00
47ff145e08 debug: turn message into debug
This message should be printed only for activation commands,
however since the handling of this flag is not correct
(rhbz 1140029) and will require further changes,
do now just a minor change and switch message into log_debug
(so it's not printed i.e. with every  'lvs -v')
2014-09-10 10:10:13 +02:00
55aa3cc813 tests: test for rename of snapshot 2014-09-09 20:17:47 +02:00
a86d9a3b30 lv_rename: actual fix for snapshot
By my rebasing mistake it's been eliminated from previous patch set.
2014-09-09 20:15:51 +02:00
c710f02e01 lv_update_and_reload: replace code sequence
Use lv_update_and_reload() and lv_update_and_reload_origin()
to handle write/suspend/commit/resume sequence.

In few places this properly handle vg_revert() after suspend failure,
and also ensures there is metadata backup after successful vg_commit().
2014-09-09 19:20:09 +02:00
e4e50863a2 lvconvert: use lv_update_and_reload
Use lib function.
2014-09-09 19:15:26 +02:00
aee8611af5 lv_manip: remove vg_revert
vg_commit is supposed to have implicit revert handling.
(however as of now it needs fixes).
2014-09-09 19:15:26 +02:00
413fc9d3e6 lv_rename: fix snapshot rename
Fix rename operation for snapshot (cow) LV.
Only the snapshot's origin has the lock and by mistake suspend
and resume has been called for the snapshot LV.
This further made volumes unusable in cluster.

So instead of suspend and resuming list of LVs,
we need to just suspend and resume origin.

As the sequence write/suspend/commit/resume
is widely used in lvm2 code base - move it to
new lv_update_and_reload function.
2014-09-09 19:15:24 +02:00
319f67b1ab cleanup: add stacktrace for error path 2014-09-08 22:36:42 +02:00
c774d9a3f3 so: make sure shared libs are built with RELRO option
In addition to using RELRO for daemons, use this option for shared
libraries. See also commit a65ab773b4.
2014-09-04 10:52:41 +02:00
b25e0086b6 post-release 2014-09-01 01:53:44 +01:00
fcb433abec pre-release 2014-09-01 01:51:47 +01:00
fa1a0d170a cleanup: drop extra ()
Pure  '==' test doesn't need extra ().
2014-08-29 13:11:35 +02:00
2a0ec5d396 cleanup: drop duplicate const
No need to specify 'const' twice in these cases.
2014-08-29 13:11:34 +02:00
19375e4fca cleanup: assignment into ()
Put is_float=1 into () - so the intention is obvious.
Remove uneeded extra check for for  *s != 0,
since it's already checked for either digit or '.'.
2014-08-29 13:11:34 +02:00
db77041d93 makefiles: include path missing
For deps calcs path for blkid.h needs to be known.
2014-08-29 13:10:20 +02:00
ca32920b16 WHATS_NEW 2014-08-29 13:10:20 +02:00
3c8fa2aa01 clvmd: use correctly sized buffers for sscanf
sscanf needs extra 1 char for '\0'
2014-08-29 13:10:20 +02:00
91a453de05 WHATS_NEW_DM 2014-08-29 13:10:19 +02:00
93e9b3a1d1 libdm: revert incorrect path length size for sscanf
Commit 94786a3bbf introduced
another bug - since sscanf needs extra 1 byte for \0.

Since there is no easy way to do a macro evaluation for (PATH_MAX-1)
and string concatation of this number to get resulting (%4095s) - let's
go with easiest path and restore extra byte for 0.

Other option would be to prepare sscanf parsing string in runtime.

But lets resolve it when we look at PATH_MAX handling later...
2014-08-29 13:10:18 +02:00
2faf416e0e lvextend: Reinstate --nosync logic for mirrors.
Reinstate the logic for syncing extensions of mirrors created with
--nosync.  (Inadvertently disabled by the approximate allocation
changes.)
2014-08-28 00:40:09 +01:00
3003a9a7be WHATS_NEW 2014-08-27 16:52:32 +02:00
22bfac5dc2 cache: fix allocation size
Commit 0b3d0e79f6 caused regression
in allocation of cache pool. This patch is restoring corect size
for allocation.
2014-08-27 16:47:14 +02:00
8b9eb95ea9 cache: Clean-up error message.
It is not an internal error message to report to the user that they
cannot create a cache LV on top of a cache LV.  It is simply not
supported yet.
2014-08-24 19:44:37 -05:00
dd9700f192 post-release 2014-08-26 16:41:18 +01:00
8b8d21f873 pre-release 2014-08-26 16:34:14 +01:00
50babdf123 revert: commit 8d00499167
Let's test this more...
2014-08-26 17:07:37 +02:00
70e998754e tests: thin and volume_list testing 2014-08-26 14:13:07 +02:00
c37ca279e3 tests: fix volume list test
Proper use of \" escaping and shell vars.
2014-08-26 14:13:07 +02:00
25fe716b12 cleanup: indent and stacktrack
Add missing stacktrace on error path
and newline indent.
2014-08-26 14:13:07 +02:00
24001a08ab cleanup: check pv_count is not 0
Since we already detect writemostly_ARG is non-zero
make it obvious pv_count will also be non-zero in this case.
2014-08-26 14:13:06 +02:00
3b5afac9b4 cleanup: use unsigned 1bit elements
Avoid using signed 'int' type for 1 bit size.
2014-08-26 14:13:06 +02:00
e5356eeba1 cleanup: never return uninitialized buffer
Coverity noticed this function may return untouched buffer,
however in this state can't really happen, but anyway
ensure on error path the buffer will have zero lenght string.
2014-08-26 14:13:06 +02:00
8f518cf197 libdm: add check transaction_id after message
Add extra safety detection for thin pool transaction id
and query pool status after confirmed message.

In case there is a missmatch, immeditelly abort further
processing.
2014-08-26 14:12:20 +02:00
0794a10f91 thin: fix volume_list support
Fixing problem, when user sets volume_list and excludes thin pools
from activation. In this case pool return 'success' for skipped activation.

We need to really check the volume it is actually active to properly
to remove queued pool messages. Otherwise the lvm2 and kernel
metadata started to go async since lvm2 believed, messages were submitted.

Add also better check for threshold when create a new thin volume.
In this case we require local activation of thin pool so we are able
to check pool fullness.
2014-08-26 14:10:18 +02:00
1ee5e18a7b thin: more forced ignoring of pool failure
Support also 'vgremove -ff' to properly remove even inactive/broken thin pools.
Update messages to use 'print_unless_silent' for the forced case.
2014-08-26 14:09:04 +02:00
f4e56b2829 cleanup: consolidate lv_layout and lv_role reporting
This patch makes the keyword combinations found in "lv_layout" and
"lv_role" much more understandable - there were some ambiguities
for some of the combinations which lead to confusion before.

Now, the scheme used is:

LAYOUTS ("how the LV is laid out"):
===================================
[linear] (all segments have number of stripes = 1)

[striped] (all segments have number of stripes > 1)

[linear,striped] (mixed linear and striped)

raid (raid layout always reported together with raid level, raid layout == image + metadata LVs underneath that make up raid LV)
  [raid,raid1]
  [raid,raid10]
  [raid,raid4]
  [raid,raid5] (exact sublayout not specified during creation - default one used - raid5_ls)
    [raid,raid5,raid5_ls]
    [raid,raid5,raid6_rs]
    [raid,raid5,raid5_la]
    [raid,raid5,raid5_ra]
  [raid6,raid] (exact sublayout not specified during creation - default one used - raid6_zr)
    [raid,raid6,raid6_zr]
    [raid,raid6,raid6_nc]
    [raid,raid6,raid6_ns]

[mirror] (mirror layout == log + image LVs underneath that make up mirror LV)

thin (thin layout always reported together with sublayout)
  [thin,sparse] (thin layout == allocated out of thin pool)
  [thin,pool] (thin pool layout == data + metadata volumes underneath that make up thin pool LV, not supposed to be used for direct use!!!)

[cache] (cache layout == allocated out of cache pool in conjunction with cache origin)
  [cache,pool] (cache pool layout == data + metadata volumes underneath that make up cache pool LV, not supposed to be used for direct use!!!)

[virtual] (virtual layout == not hitting disk underneath, currently this layout denotes only 'zero' device used for origin,thickorigin role)

[unknown] (either error state or missing recognition for such layout)

ROLES ("what's the purpose or use of the LV - what is its role"):
=================================================================
- each LV has either of these two roles at least:  [public] (public LV that users may use freely to write their data to)

  [public] (public LV that users may use freely to write their data to)
  [private] (private LV that LVM maintains; not supposed to be directly used by user to write his data to)

- and then some special-purpose roles in addition to that:

  [origin,thickorigin] (origin for thick-style snapshot; "thick" as opposed to "thin")
  [origin,multithickorigin] (there are more than 2 thick-style snapshots for this origin)
  [origin,thinorigin] (origin for thin snapshot)
  [origin,multithinorigin] (there are more than 2 thin snapshots for this origin)
  [origin,extorigin] (external origin for thin snapshot)
  [origin,multiextoriginl (there are more than 2 thin snapshots using this external origin)
  [origin,cacheorigin] (cache origin)

  [snapshot,thicksnapshot] (thick-style snapshot; "thick" as opposed to "thin")
  [snapshot,thinsnapshot] (thin-style snapshot)

  [raid,metadata] (raid metadata LV)
  [raid,image] (raid image LV)

  [mirror,image] (mirror image LV)
  [mirror,log] (mirror log LV)
  [pvmove] (pvmove LV)

  [thin,pool,data] (thin pool data LV)
  [thin,pool,metadata] (thin pool metadata LV)

  [cache,pool,data] (cache pool data LV)
  [cache,pool,metadata] (cache pool metadata LV)

  [pool,spare] (pool spare LV - common role of LV that makes it used for both thin and cache repairs)
2014-08-25 16:14:40 +02:00
2d344c2e45 report: use dm_report_field_string_list_unordered for reporting lv_layout and lv_role fields
This makes it a bit more readable since we can report more general
layouts/roles first and keywords describing the LV more precisely
afterwards in the list.
2014-08-25 16:11:40 +02:00
02dc3c773e report: add dm_report_field_string_list_unsorted 2014-08-25 16:11:40 +02:00
993f8d1b3f refactor: rename 'lv_type' field to 'lv_role'
The 'lv_type' field name was a bit misleading. Better one is 'lv_role'
since this fields describes what's the actual use of the LV currently -
its 'role'.
2014-08-25 16:11:40 +02:00
66326e2fb8 autoreconf 2014-08-22 23:47:44 +01:00
83b5cb3ed5 configure: Fix shared lvm1 typo.
via https://bugs.gentoo.org/520640
2014-08-22 23:42:55 +01:00
a67c484fac lvcreate: disallow snapshot of cache lv 2014-08-22 11:54:49 -05:00
0b3d0e79f6 lvresize: Fix raid/mirror and %PE handling code.
Sort out the lvresize calculation code to handle size changes
specified as physical extents as well as logical extents
and to process mirror resizing and raid extensions correctly.

The 'approx alloc' option was masking the underlying problem.
2014-08-22 01:26:14 +01:00
7e208d6504 man: dmsetup: -n is shortcut for --notable, not --noheadings
The -n was defined for --notable since beginning, but the man page
got wrong at some time...
2014-08-21 10:26:16 +02:00
473a4a6548 tests: proper /dev access
Commit 5ebff6cc9f seemed to introduce
new 'for' loop but the mode is not yet used.
But the access to /dev dir needs to go through $DM_DEV_DIR
and whole path needs to be in "".
2014-08-20 14:37:41 +02:00
8d00499167 lvconvert: snapshot: allow using raid1 for snapshot and snapshot origin
When testing conversion sanity, we checked lv->status & MIRRORED
which encompasses both old mirrors and raid1 mirrors. But we need to
ban only the old mirrors here hence allow raid1 mirrors.
2014-08-20 10:12:09 +02:00
4f05e55f84 cleanup: Remove extra ';' from the end of a line. 2014-08-19 09:57:30 -05:00
c5f2c541f6 cleanup: simplier struct init
Use simplier struct initilizer.
2014-08-19 14:33:07 +02:00
24df01f735 cleanup: avoid double assign
Skip setting a value to a variable which is never
used and overwritten/set afterwards.
2014-08-19 14:33:06 +02:00
94786a3bbf cleanup: use just PATH_MAX size
Avoid playing with +1.

PATH_MAX code needs probably more thinking anyway, since
there is no MAX path in Linux - user may easily create path
with 64kB chars - so 4kB buffer is surelly not enough for
such dirs.

Note:
http://insanecoding.blogspot.cz/2007/11/pathmax-simply-isnt.html
2014-08-19 14:33:06 +02:00
5cd3b5c0cf cleanup: use _ prefix for static functions 2014-08-19 14:33:06 +02:00
3e4a21427b cleanup: reindent and make obvious error path 2014-08-19 14:33:06 +02:00
10e2370d2e libdm: check version prints error
Move 'bad' label above log_error, so the
error message is printed on 'bad' path.
(And return 0 is not without log_error()).
2014-08-19 14:33:06 +02:00
dec39b1a5f lv_manip: check for str_list_dup failure 2014-08-19 14:33:06 +02:00
cdb16a6039 lvscan: check result of id_write_format
Currently rather impossible to happen - but check
for returned value of id_write_format().
2014-08-19 14:33:06 +02:00
ad9aee9af4 metadata: check result of refresh and rescan
Detect failure in case refresh_filters of lvmcache_label_scan fails.
2014-08-19 14:33:06 +02:00
6d7f260f92 dmeventd: fix test for select return value
Do not call read when select return -1 && EINTR.
Also check for return valuer from read() and
abort write function when unexpected error happens.
2014-08-19 14:33:06 +02:00
84860fd54f lv: remove lv_type_name fn
The lv_type_name function is remnant from old code that reported
only single string for the LV type. LV types are now reported
in a more extended way as keyword list that describe the type
precisely (using lv_layout_and_type fn).

The lv_type_name was used in some error messages to display the
type of the LV so just reinstate the old messages back referencing
the type directly with a string - this is enough for error messages.
They don't need to display the LV type as precisely as it's used
on lvs output (which is optimized for selection anyway).
2014-08-19 14:16:39 +02:00
aec4d0c939 report: also display "mirror" keyword in lv_layout for mirrored mirror log and "cache" keyword in lv_layout for cached cache pool
$ lvs -a -o name,vg_name,attr,layout,type
  LV                    VG     Attr       Layout     Type
  lvol0                 vg     mwi-a-m--- mirror     mirror
  [lvol0_mimage_0]      vg     iwi-aom--- linear     image,mirror
  [lvol0_mimage_1]      vg     iwi-aom--- linear     image,mirror
  [lvol0_mlog]          vg     mwi-aom--- mirror     log,mirror
  [lvol0_mlog_mimage_0] vg     iwi-aom--- linear     image,mirror
  [lvol0_mlog_mimage_1] vg     iwi-aom--- linear     image,mirror

(lvol0_mlog properly displayed as "mirror" layout for mirrored mirror log)

$ lvs -a -o name,vg_name,attr,layout,type
  LV                  VG     Attr       Layout     Type
  lvol0               vg     Cwi---C--- cache,pool cache,pool
  [lvol0_cdata]       vg     Cwi------- linear     cache,data,pool
  [lvol0_cmeta]       vg     ewi------- linear     cache,metadata,pool
  [lvol1_pmspare]     vg     ewi------- linear     metadata,pool,spare
  lvol2               vg     Cwi---C--- cache,pool cache,pool
  [lvol2_cdata]       vg     Cwi---C--- cache      cache,data,pool
  [lvol2_cdata_corig] vg     owi---C--- linear     cache,origin
  [lvol2_cmeta]       vg     ewi------- linear     cache,metadata,pool

(lvol2_cdata properly displayed as cached cache pool data)
2014-08-19 13:58:32 +02:00
b806836164 report: also display "mirror" keyword in lv_type for pvmove LV and display "multiple" for external origin used for more than one thin snapshot
$ lvs -a -o name,vg_name,attr,layout,type
  LV        VG     Attr       Layout     Type
  lvol0     vg     -wI-a----- linear     linear
  [pvmove0] vg     p-C-aom--- mirror     mirror,pvmove

(added "mirror" for pvmove LV)

$ lvs -a -o name,vg_name,attr,layout,type
  LV              VG     Attr       Layout     Type
  lvol0           vg     ori------- linear     external,multiple,origin,thin
  [lvol1_pmspare] vg     ewi------- linear     metadata,pool,spare
  lvol2           vg     Vwi-a-tz-- thin       snapshot,thin
  lvol3           vg     Vwi-a-tz-- thin       snapshot,thin
  pool            vg     twi-a-tz-- pool,thin  pool,thin
  [pool_tdata]    vg     Twi-ao---- linear     data,pool,thin
  [pool_tmeta]    vg     ewi-ao---- linear     metadata,pool,thin

(added "multiple" for external origin used for more than one
thin snapshot - lvol0 in the example above)
2014-08-19 09:41:41 +02:00
90c47a4968 report: fix thin external snapshot identification for lv_layout and lv_type fields
Thin snapshots having external origins missed the "snapshot" keyword for
lv_type field. Also, thin external origins which are thin devices (from
another pool) were not recognized properly.

For example, external origin itself can be either non-thin volume (lvol0
below) or it can be a thin volume from another pool (lvol3 below):

Before this patch:

$ lvs -o name,vg_name,attr,pool_lv,origin,layout,type
  Internal error: Failed to properly detect layout and type for for LV vg/lvol3
  Internal error: Failed to properly detect layout and type for for LV vg/lvol3
  LV    VG     Attr       Pool  Origin Layout     Type
  lvol0 vg     ori-------              linear     external,origin,thin
  lvol2 vg     Vwi-a-tz-- pool  lvol0  thin       thin
  lvol3 vg     ori---tz-- pool         unknown    external,origin,thin,thin
  lvol4 vg     Vwi-a-tz-- pool1 lvol3  thin       thin
  pool  vg     twi-a-tz--              pool,thin  pool,thin
  pool1 vg     twi-a-tz--              pool,thin  pool,thin

- lvol2 as well as lvol4 have missing "snapshot" in type field
- lvol3 has unrecognized layout (should be "thin"), but has double
  "thin" in lv_type which is incorrect
- (also there's double "for" in the internal error message)

With this patch applied:

$ lvs -o name,vg_name,attr,pool_lv,origin,layout,type
  LV    VG     Attr       Pool  Origin Layout     Type
  lvol0 vg     ori-------              linear     external,origin,thin
  lvol2 vg     Vwi-a-tz-- pool  lvol0  thin       snapshot,thin
  lvol3 vg     ori---tz-- pool         thin       external,origin,thin
  lvol4 vg     Vwi-a-tz-- pool1 lvol3  thin       snapshot,thin
  pool  vg     twi-a-tz--              pool,thin  pool,thin
  pool1 vg     twi-a-tz--              pool,thin  pool,thin
2014-08-18 15:58:48 +02:00
4d45302e25 RAID: Fail RAID4/5/6 creation if PE size is less than STRIPE_SIZE_MIN
The maximum stripe size is equal to the volume group PE size.  If that
size falls below the STRIPE_SIZE_MIN, the creation of RAID 4/5/6 volumes
becomes impossible.  (The kernel will fail to load a RAID 4/5/6 mapping
table with a stripe size less than STRIPE_SIZE_MIN.)  So, we report an
error if it is attempted.

This is very rare because reducing the PE size down that far limits the
size of the PV below that of modern devices.
2014-08-15 21:15:34 -05:00
42e07d2bce dmsetup: Support remove --deferred.
This patch adds a new flag --deferred to dmsetup remove. If this flag is
specified and the device is open, it is scheduled to be deleted on
close.

struct dm_info is extended.

The existing dm_task_get_info() is converted into a wrapper around the
new version dm_task_get_info_with_deferred_remove() so existing binaries
can still use the old smaller structure.

Recompiled code will pick up the new larger structure.

From: Mikulas Patocka <mpatocka@redhat.com>
2014-08-16 00:34:48 +01:00
ec41bd1920 cleanup: use display_lvname
Show more complete LV names.
2014-08-15 15:53:17 +02:00
c894c3c87f cleanup: gcc warn fix
Since gcc fail to see the origin has been already set under condition
above, just set origin again.
2014-08-15 15:53:17 +02:00
8af2309231 cleanup: gcc warning
One more:

metadata/thin_manip.c:503: warning: declaration of "snapshot_count" shadows a global declaration
2014-08-15 15:43:42 +02:00
8e449ebd63 cleanup: gcc warning
metadata/lv_manip.c:269: warning: declaration of "snapshot_count" shadows a global declaration

There's existing function called "snapshot_count" so rename the
variable to "snap_count".
2014-08-15 15:32:04 +02:00
d213758e57 man: missing (C)ache in target type lv_attr description 2014-08-15 15:21:15 +02:00
9534c21ead cleanup: quite gcc warn
gcc can't see dev_get_primary_dev  returns only 0,1,2
so ensure 'name' is always defined in valid path.
2014-08-15 15:06:45 +02:00
ff33d215ba cleanup: drop extra braces 2014-08-15 15:06:45 +02:00
f183995f8e cleanup: just easier word wrapping 2014-08-15 15:06:44 +02:00
1bde4c19e6 cleanup: drop unneeded inits 2014-08-15 15:06:44 +02:00
5095a6517d cleanup: simplier struct initilization 2014-08-15 15:06:44 +02:00
338b991e40 cleanup: move test for free arg
Move test for list of volumes into common place.
2014-08-15 15:06:44 +02:00
6872adc0ff cleanup: postpone confirmation prompt for snapshot
Prompt user for confimation after more checks are done.
(So we avoid case prompting and failing after prompt)
2014-08-15 15:06:44 +02:00
ba7796e055 man: add some more reserved names 2014-08-15 15:06:44 +02:00
630fcab420 man: show lv name for lvs
Make it more obvious that either just vg name or lv name or path could
be passed as an argument.
2014-08-15 15:06:44 +02:00
7f4b1e7411 toollib: print ignoring vorigin
When ignoring 'listed' volume, print info message.
(So the final command error message is a bit less confusing,
i.e. when user tries to deactive virtual origin:

> lvchange -an vg/lvol2_vorigin
  Ignoring virtual origin logical volume vg/lvol2_vorigin.
  One or more specified logical volume(s) not found.
2014-08-15 15:06:44 +02:00
10e3715564 lvconvert: show name of activated volume
Display the name of volume that needs to be activated for merging.
2014-08-15 15:06:44 +02:00
e8bbcda2a3 Add lv_layout_and_type fn, lv_layout and lv_type reporting fields.
The lv_layout and lv_type fields together help with LV identification.
We can do basic identification using the lv_attr field which provides
 very condensed view. In contrast to that, the new lv_layout and lv_type
fields provide more detialed information on exact layout and type used
for LVs.

For top-level LVs which are pure types not combined with any
other LV types, the lv_layout value is equal to lv_type value.

For non-top-level LVs which may be combined with other types,
the lv_layout describes the underlying layout used, while the
lv_type describes the use/type/usage of the LV.

These two new fields are both string lists so selection (-S/--select)
criteria can be defined using the list operators easily:
  [] for strict matching
  {} for subset matching.

For example, let's consider this:

$ lvs -a -o name,vg_name,lv_attr,layout,type
  LV                    VG     Attr       Layout       Type
  [lvol1_pmspare]       vg     ewi------- linear       metadata,pool,spare
  pool                  vg     twi-a-tz-- pool,thin    pool,thin
  [pool_tdata]          vg     rwi-aor--- level10,raid data,pool,thin
  [pool_tdata_rimage_0] vg     iwi-aor--- linear       image,raid
  [pool_tdata_rimage_1] vg     iwi-aor--- linear       image,raid
  [pool_tdata_rimage_2] vg     iwi-aor--- linear       image,raid
  [pool_tdata_rimage_3] vg     iwi-aor--- linear       image,raid
  [pool_tdata_rmeta_0]  vg     ewi-aor--- linear       metadata,raid
  [pool_tdata_rmeta_1]  vg     ewi-aor--- linear       metadata,raid
  [pool_tdata_rmeta_2]  vg     ewi-aor--- linear       metadata,raid
  [pool_tdata_rmeta_3]  vg     ewi-aor--- linear       metadata,raid
  [pool_tmeta]          vg     ewi-aor--- level1,raid  metadata,pool,thin
  [pool_tmeta_rimage_0] vg     iwi-aor--- linear       image,raid
  [pool_tmeta_rimage_1] vg     iwi-aor--- linear       image,raid
  [pool_tmeta_rmeta_0]  vg     ewi-aor--- linear       metadata,raid
  [pool_tmeta_rmeta_1]  vg     ewi-aor--- linear       metadata,raid
  thin_snap1            vg     Vwi---tz-k thin         snapshot,thin
  thin_snap2            vg     Vwi---tz-k thin         snapshot,thin
  thin_vol1             vg     Vwi-a-tz-- thin         thin
  thin_vol2             vg     Vwi-a-tz-- thin         multiple,origin,thin

Which is a situation with thin pool, thin volumes and thin snapshots.
We can see internal 'pool_tdata' volume that makes up thin pool has
actually a level10 raid layout and the internal 'pool_tmeta' has
level1 raid layout. Also, we can see that 'thin_snap1' and 'thin_snap2'
are both thin snapshots while 'thin_vol1' is thin origin (having
multiple snapshots).

Such reporting scheme provides much better base for selection criteria
in addition to providing more detailed information, for example:

$ lvs -a -o name,vg_name,lv_attr,layout,type -S 'type=metadata'
LV                   VG   Attr       Layout      Type
[lvol1_pmspare]      vg   ewi------- linear      metadata,pool,spare
[pool_tdata_rmeta_0] vg   ewi-aor--- linear      metadata,raid
[pool_tdata_rmeta_1] vg   ewi-aor--- linear      metadata,raid
[pool_tdata_rmeta_2] vg   ewi-aor--- linear      metadata,raid
[pool_tdata_rmeta_3] vg   ewi-aor--- linear      metadata,raid
[pool_tmeta]         vg   ewi-aor--- level1,raid metadata,pool,thin
[pool_tmeta_rmeta_0] vg   ewi-aor--- linear      metadata,raid
[pool_tmeta_rmeta_1] vg   ewi-aor--- linear      metadata,raid

(selected all LVs which are related to metadata of any type)

lvs -a -o name,vg_name,lv_attr,layout,type -S 'type={metadata,thin}'
LV           VG   Attr       Layout      Type
[pool_tmeta] vg   ewi-aor--- level1,raid metadata,pool,thin

(selected all LVs which hold metadata related to thin)

lvs -a -o name,vg_name,lv_attr,layout,type -S 'type={thin,snapshot}'
LV         VG   Attr       Layout     Type
thin_snap1 vg   Vwi---tz-k thin       snapshot,thin
thin_snap2 vg   Vwi---tz-k thin       snapshot,thin

(selected all LVs which are thin snapshots)

lvs -a -o name,vg_name,lv_attr,layout,type -S 'layout=raid'
LV           VG   Attr       Layout       Type
[pool_tdata] vg   rwi-aor--- level10,raid data,pool,thin
[pool_tmeta] vg   ewi-aor--- level1,raid  metadata,pool,thin

(selected all LVs with raid layout, any raid layout)

lvs -a -o name,vg_name,lv_attr,layout,type -S 'layout={raid,level1}'
  LV           VG   Attr       Layout      Type
  [pool_tmeta] vg   ewi-aor--- level1,raid metadata,pool,thin

(selected all LVs with raid level1 layout exactly)

And so on...
2014-08-15 14:50:38 +02:00
8a7682cbc9 libdm: Add DM_DEFERRED_REMOVE to dm-ioctl.h. 2014-08-15 13:45:55 +01:00
8740ecfa64 WHATS_NEW: previous commit 2014-08-15 13:31:21 +02:00
1cd622d98b report: lvs: properly display 'o' for volume type bit and 'C' for target type bit in lv_attr field for cache origin LVs
Before this patch:
LV                 VG     Attr
[cache_orig_corig] vg     -wi-ao----

With this patch applied:
LV                 VG     Attr
[cache_orig_corig] vg     owi-aoC---
2014-08-15 13:28:43 +02:00
8eba33510f cache+thin: add lv_is_{cache,thin}_origin fn to identify origin LVs 2014-08-15 13:28:43 +02:00
ec0d2f7aa4 refactor: add defines for raid segtypes
This will be reused later on in upcoming code...
2014-08-15 13:28:43 +02:00
bf78e55ef3 pvcreate: Fix cache state with filters/sig wiping.
_pvcreate_check() has two missing requirements:
  After refreshing filters there must be a rescan.
    (Otherwise the persistent filter may remain empty.)
  After wiping a signature, the filters must be refreshed.
    (A device that was previously excluded by the filter due to
     its signature might now need to be included.)

If several devices are added at once, the repeated scanning isn't
strictly needed, but we can address that later as part of the command
processing restructuring (by grouping the devices).

Replace the new pvcreate code added by commit
54685c20fc "filters: fix regression caused
by commit e80884cd080cad7e10be4588e3493b9000649426"
with this change to _pvcreate_check().

The filter refresh problem dates back to commit
acb4b5e4de "Fix pvcreate device check."
2014-08-14 01:30:01 +01:00
20503ff067 tests: update report-select test for latest changes 2014-08-13 17:20:09 +02:00
fa793bed64 select: add support for selection to match string list subset, recognize { } operator
Using "[ ]" operator together with "&&" (or ",") inside causes the
string list to be matched if and only if all the items given match
the value reported and the number of items also match. This is
strict list matching and the original behaviour we already have.

In contrast to that, the new "{ }" operator together with "&&" inside
causes the string list to be matched if and only if all the items given
match the value reported but the number of items don't need to match.
So we can provide a subset in selection criteria and if the subset
is found, it matches.

For example:

$ lvs -o name,tags
  LV    LV Tags
  lvol0 a
  lvol1 a,b
  lvol2 b,c,x
  lvol3 a,b,y

$ lvs -o name,tags -S 'tags=[a,b]'
  LV    LV Tags
  lvol1 a,b

$ lvs -o name,tags -S 'tags={a,b}'
  LV    LV Tags
  lvol1 a,b
  lvol3 a,b,y

So in the example above the a,b is subset of a,b,y and therefore
it also matches.

Clearly, when using "||" (or "#") inside, the { } and [ ] is the
same:

$ lvs -o name,tags -S 'tags=[a#b]'
  LV    LV Tags
  lvol0 a
  lvol1 a,b
  lvol2 b,c,x
  lvol3 a,b,y

$ lvs -o name,tags -S 'tags={a#b}'
  LV    LV Tags
  lvol0 a
  lvol1 a,b
  lvol2 b,c,x
  lvol3 a,b,y

Also in addition to the above feature, fix list with single value
matching when using [ ]:

Before this patch:
$ lvs -o name,tags -S 'tags=[a]'
  LV    LV Tags
  lvol0 a
  lvol1 a,b
  lvol3 a,b,y

With this patch applied:
$ lvs -o name,tags -S 'tags=[a]'
  LV    LV Tags
  lvol0 a

In case neither [] or {} is used, assume {} (the behaviour is not
changed here):

$ lvs -o name,tags -S 'tags=a'
  LV    LV Tags
  lvol0 a
  lvol1 a,b
  lvol3 a,b,y

So in new terms 'tags=a' is equal to 'tags={a}'.
2014-08-13 16:10:12 +02:00
6dd98c1fa8 select: fix string list selection to match whole words only but not prefixes of searched string
$ lvs -o name,tags vg/lvol0
  LV    LV Tags
  lvol0 a

Before this patch:

$ lvs -o name,tags vg/lvol0 -S 'tags=[a]'
  LV    LV Tags
  lvol0 a

$ lvs -o name,tags vg/lvol0 -S 'tags=[ab]'
  LV    LV Tags
  lvol0 a
(incorrect!)

$ lvs -o name,tags vg/lvol0 -S 'tags=[abc]'
  LV    LV Tags
  lvol0 a
(incorrect!)

With this patch applied:

$ lvs -o name,tags vg/lvol0 -S 'tags=[a]'
  LV    LV Tags
  lvol0 a

$ lvs -o name,tags vg/lvol0 -S 'tags=[ab]'
(no result - correct!)

$ lvs -o name,tags vg/lvol0 -S 'tags=[abc]'
(no result - correct!)
2014-08-13 16:04:02 +02:00
9738a02d3d filter-mpath: fix primary device lookup failure for partition when processing mpath filter
If using persistent filter and we're refreshing filters (just like we
do for pvcreate now after commit 54685c20fc),
we can't rely on getting the primary device of the partition from the cache
as such device could be already filtered by persistent filter and we get
a device cache lookup failure for such device.

For example:

$ lvm dumpconfig --type diff
devices {
	obtain_device_list_from_udev=0
}

$lsblk /dev/sda
NAME   MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
sda      8:0    0  128M  0 disk
`-sda1   8:1    0  127M  0 part

$cat /etc/lvm/cache/.cache | grep sda
		"/dev/sda1",

$pvcreate /dev/sda1
  dev_is_mpath: failed to get device for 8:1
  Physical volume "/dev/sda1" successfully created

The problematic part of the code called dev_cache_get_by_devt
to get the device for the device number supplied. Then the code
used dev_name(dev) to get the name which is then used in check
whether there's any mpath on top of this dev...

This patch uses sysfs to get the base name for the partition
instead, hence avoiding the device cache which is a correct
approach here.
2014-08-08 10:49:19 +02:00
c52c9a1e31 activation: if LV inactive and non-clustered, do not issue "Cannot deactivate" on -aln
The message "Cannot deactivate remotely exclusive device locally." makes
sense only for clustered LV. If the LV is non-clustered, then it's
always exclusive by definition and if it's already deactivated, this
message pops up inappropriately as those two conditions are met.

So issue the message only if the conditions are met AND we have clustered VG.
2014-08-07 16:44:09 +02:00
ea662ca060 pvmove: remove spurious "Skipping mirror LV" message on pvmove of clustered mirror
With cmirrord, we can do pvmove of clustered mirror. The code checking
suitability of LVs on the PV being moved issued a message if a mirror
LV was found and the VG was clustered. However, the actual pvmove did
work correctly.

The top-level mirror LV is actually skipped in the code since it's
always layered on top of internal LVs making up the mirror LV and for pvmove
we consider these internal devices only as they're actually layered on
top of concrete PVs then. But we don't need to issue any message here
about skipping the top-level mirror LV - it's misleading here.
2014-08-07 15:23:58 +02:00
26885ea119 post-release 2014-08-05 02:12:20 +01:00
9d4e1e51a9 pre-release 2014-08-05 02:07:35 +01:00
e94442bffa report: Remove lv_volume_type field.
Like lv_target_type, this field needs reworking.
2014-08-05 02:04:16 +01:00
2dac5525fb lvscan: Fix possible gcc warnings in --cache implementation. 2014-08-04 17:36:12 +02:00
46262f163b WHATS_NEW: lvscan --cache SEGV fix 2014-08-04 17:05:08 +02:00
0208665209 lvscan: Make --cache impervious to already-missing devices. 2014-08-04 17:03:17 +02:00
03a88da868 test: Add a test for lvscan --cache. 2014-08-04 17:03:17 +02:00
54685c20fc filters: fix regression caused by commit e80884cd08
Commit e80884cd08 tried to dump filters
for them to be reevaluated when creating a PV to avoid overwriting
any existing signature that may have been created after last
scan/filtering.

However, we need to call refresh_filters instead of
persistent_filter->dump since dump requires proper rescannig to fill
up the persistent filter again. However, this is true only for pvcreate
but not for vgcreate with PV creation where the scanning happens before
this PV creation and hence the next rescan (if not full scan), does not
fill the persistent filter.

Also, move refresh_filters so that it's called sooner and only for
pvcreate, vgcreate already calls lvmcache_label_scan(cmd, 2) which
then calls refresh_filters itself, so no need to reevaluate this again.

This caused the persistent filter (/etc/lvm/cache/.cache file) to be
wrong and contain only the PV just being processed with
vgcreate <vg_name> <pv_name_to_create>.

This regression caused other block devices to be filtered out in case
the vgcreate with PV creation was used and then the persistent filter
is used by any other LVM command afterwards.
2014-08-01 11:39:53 +02:00
c7b9f0ab42 lvresize: Allow approximation with +%FREE.
Make lvresize -l+%FREE support approximate allocation.

Move existing "Reducing/Extending' message to verbose level
and change it to say 'up to' if approximate allocation is being used.

Replace it with a new message that gives the actual old and new size or
says 'unchanged'.
2014-08-01 00:35:43 +01:00
0dc3684b87 test: Skip lvextend-thin when thin not available 2014-07-31 22:56:19 +02:00
ef85997980 metadata: remove spurious "Physical volume <dev_name> not found"
This is addendum to commit 2e82a070f3
which fixed these spurious messages that appeared after commit
651d5093ed ("avoid pv_read in
find_pv_by_name").

There was one more "not found" message issued in case the device
could not be found in device cache (commit 2e82a07 fixed this only
for PV lookup itself). But if we "allow_unformatted" for
find_pv_by_name, we should not issue this message even in case
the device can't be found in dev cache as we just need to know
whether there's a PV or not for the code to decide on next steps
and we don't want to issue any messages if either device itself
is not found or PV is not found.

For example, when we were creating a new PV (and so allow_unformatted = 1)
and the device had a signature on it which caused it to be filtered
by device filter (e.g. MD signature if md filtering is enabled),
or it was part of some other subsystem (e.g. multipath), this message
was issued on find_pv_by_name call which was misleading.

Also, remove misleading "stack" call in case find_pv_by_name
returns NULL in pvcreate_check - any error state is reported
later by pvcreate_check code so no need to "stack" here.

There's one more and proper check to issue "not found" message if
the device can't be found in device cache within pvcreate_check fn
so this situation is still covered properly later in the code.

Before this patch (/dev/sda contains MD signature and is therefore filtered):

$ pvcreate /dev/sda
  Physical volume /dev/sda not found
WARNING: linux_raid_member signature detected on /dev/sda at offset 4096. Wipe it? [y/n]:

With this patch applied:

$ pvcreate /dev/sda
WARNING: linux_raid_member signature detected on /dev/sda at offset 4096. Wipe it? [y/n]:

Non-existent devices are still caught properly:

$ pvcreate /dev/sdx
  Device /dev/sdx not found (or ignored by filtering).
2014-07-31 10:03:30 +02:00
7cff640d9a activation: Fix upgrades using uuid suffixes.
2.02.106 added suffixes to some LV uuids in the kernel.

If any of these LVs is activated with 2.02.105 or earlier,
and then a later version is used, the LVs appear invisible and
activation commands fail.

The code now has to check the kernel for both old and new uuids.
2014-07-30 21:55:11 +01:00
c4484d9050 test: Add a test for lvextend -l+100%FREE of a striped thin pool. 2014-07-30 16:17:29 +02:00
321bed7137 post-release 2014-07-23 16:23:52 +01:00
52217f6ebd raid: Fix partial activation logic for non-raid. 2014-07-23 16:13:12 +01:00
25fa725b05 pre-release 2014-07-23 16:05:22 +01:00
8d63d94d85 tests: still unusable kernel 2014-07-23 00:29:32 +02:00
22be7c4417 tests: support cluster run
needs exclusive activation
2014-07-23 00:25:49 +02:00
3a8bb8d3a4 tests: use exclusive activation 2014-07-22 23:44:06 +02:00
ab1887fe47 man: Update the lvscan manpage with a section on --cache. 2014-07-22 22:48:41 +02:00
66686a5bc5 WHATS_NEW: lvscan --cache, dmeventd RAID + lvmetad 2014-07-22 22:48:41 +02:00
5dc6671bb5 dmeventd: Call lvscan --cache in the RAID plugin. 2014-07-22 22:48:21 +02:00
a9ea014e51 lvscan: Implement a --cache mode. 2014-07-22 22:48:21 +02:00
653fd7bee3 tests: new lvconvert features 2014-07-22 22:41:41 +02:00
ee11bb8416 tests: use full option name
Don't overuse shortcut support -
since poolmetadatasize was the only allowed option
it's been equivalent to poolmetadata
2014-07-22 22:41:41 +02:00
b51f1b3df6 man: lvconvert poolmetadataspare
Add missing description for --poolmetadataspare option.
2014-07-22 22:41:41 +02:00
d7d81e1157 cleanup: show better messages 2014-07-22 22:41:40 +02:00
894eda4707 thin and cache: unify pool common code
Fix get_pool_params to only read params.
Add poolmetadataspare option to get_pool_params.
Move all profile code into update_pool_params.
Move recalculate code into pool_manip.c
2014-07-22 22:41:38 +02:00
8c56c5fbac lvconvert: better testing order
Avoid duplicate tests through implicit calls - check directly
result of string assignment.
2014-07-22 22:38:59 +02:00
ab7bcc26f6 tools: switch logic for new arg_ func
Revert logic and rename new arg_ functions to:

arg_from_list_is_set()
arg_outside_list_is_set()

When err_found is given, log_error message is automaticaly
printed.
2014-07-22 22:38:59 +02:00
864ff3cb18 man: rework lvmcache to match lvmthin
Reorganize and rewrite parts to match lvmthin(7).
2014-07-22 15:12:02 -05:00
50961f43d0 report: Remove lv_target_type field.
This field is too complicated to be useful on its own and either needs
redefining or splitting up into multiple fields.
2014-07-22 20:57:57 +01:00
99e3c13012 raid: Moved degraded activation code to raid_manip.
Adjust some messages & fn names.
2014-07-22 20:50:29 +01:00
fe5b282a4a man: lvmcache updates
- use the lvconvert --cachepool syntax to match the lvmthin style
- rewrite removal information
- very minor formatting adjustments
2014-07-21 15:41:42 -05:00
1fe487043d man: use macros for indenting in lvmthin 2014-07-21 10:28:20 -05:00
3366baf076 metadata: Reinstate system info in metadata.
Revert part of cac0722cac

This was deliberate and aids the investigation of problems.
2014-07-21 15:54:20 +01:00
513fd029a6 config: Adjust description of activation_mode. 2014-07-21 15:50:47 +01:00
8c231a5f4d raid: Correct degraded warning message level 2014-07-21 15:40:59 +01:00
27574d0e41 tests: use bigger metadata
Until resolved - use bigger then 4MB cache pool metadata.
2014-07-17 16:27:39 +02:00
53b787e519 cleanup: drop testing impossible path
We cannot get NULL in this test - since if the arg is set
it will always return non-NULL value here.
(in-release update)
2014-07-17 16:20:21 +02:00
ffa1a7b046 cleanup: typo in message
in-release fix.
2014-07-17 16:19:57 +02:00
ab72cdbf81 cleanup: check arg_count once
Do not check quiet_ARG more then necessary.
2014-07-17 16:18:35 +02:00
321592af71 raid: support lvdisplay --maps
Add legs printing for --maps
Somewhat similar to mirror support - maybe there are more things to
show...
2014-07-17 16:18:34 +02:00
cac0722cac metadata: use outfc for comments
Few unecessary comments were written to on-disc metadata.
Use outfc() to have comments only in archived files.
(may also save couple bytes in ringbuffer).

TODO: needed validation against newline char...
2014-07-17 16:17:44 +02:00
f5d6c4b0f3 cache: use get_cache_mode for validation
Use a single function to validate cache mode arg
and set DM_ feature flags.
2014-07-17 16:16:45 +02:00
8f9f180139 lvconvert: improve merge validation
Easier check for conflicting options with --merge.
2014-07-17 16:16:00 +02:00
7abad9ef88 lvconvert: improve splitsnapshot test
Easier check for conflicting options with --splitsnapshot.
2014-07-17 16:15:30 +02:00
4dcacbe369 lvconvert: move to single name validation
Validate all LV names in _lvconvert_name_params().
2014-07-17 16:14:36 +02:00
04acf7a8d0 lvconvert: add missing option for repair
Few more option needs to be allowed with --repair.
(in-release fix).
2014-07-17 16:14:18 +02:00
3e4f24115a man: lvmthin fix line breaks
The html rendering inserted some unpleasant line breaks,
so insert better breaks explicitly.
2014-07-11 15:15:03 -05:00
65a3f50556 lvconvert: fix missing repair option
Support --repair and --use-policies with mirrors.
(fixes another regression from lvconvert change for thin and cache).
TODO: the code path for mirror needs update.
2014-07-11 14:42:21 +02:00
af219fbc04 cleanup: lets make it really obvious for gcc 2014-07-11 14:19:22 +02:00
c0ebe78ef8 lvconvert: fix mirror path
lvconvert rewrite commit missed proper handling
of mirror path for --corelog and --mirrorlog options.
Document this even in man page.
2014-07-11 14:12:35 +02:00
17b92001ea WHATS_NEW: recent commits
Commits:
d169ff1e03
bccc2bef33
f76879ba44
2014-07-11 14:09:05 +02:00
7913f64a02 cleanup: drop unintend debug error line 2014-07-11 13:54:54 +02:00
a62cea3371 cleanup: older gcc is not smart enough
Avoid gcc warning about uninitialized 'seg' variable.
It's not easy for older gcc compiler to deduce it's been set.
2014-07-11 13:52:30 +02:00
d7065f154e tests: updates for new lvconvert 2014-07-11 13:32:52 +02:00
9f703d35a0 cleanup: lvconvert reoder repair check 2014-07-11 13:32:23 +02:00
4bbfac359c man: lvconvert update
Update lvconvert doc for conversion of pools
(thin and cache pools and volumes)

Various more cleanups.
2014-07-11 13:32:23 +02:00
b2988a917a lvconvert: update help
Extend help for lvconvert.
Use COMMON_OPTS for some common options.
2014-07-11 13:32:22 +02:00
970989655f lvconvert: update for thin a cache
Major update of lvconvert code to handle cache and thin.
related targets.

Code tries to unify handling of cache and thin pools.
Better supports lvm2 syntax:

lvconvert --type cache --cachepool vg/pool vg/cache
lvconvert --type thin --thinpool vg/pool vg/extorg
lvconvert --type cache-pool vg/pool
lvconvert --type thin-pool vg/pool

as well as:

lvconvert --cache --cachepool vg/pool vg/cache
lvconvert --thin --thinpool vg/pool vg/extorg
lvconvert --cachepool vg/pool
lvconvert --thinpool vg/pool

While catching much more command line errors.
(Yet couple paths still needs more tests)

Detects as much cmdline errors prior opening VG.

Uses single lvconvert_name_params to convert LV names.

Detects as much incompatibilies in VG prior prompting.

Uses single prompt to confirm whole conversion.

TODO: still the code needs fixes...
2014-07-11 13:32:22 +02:00
fe3ea94e58 cleanup: shift detection of chunksize sign
Sign should be checked prior opening of VG.
Since get_pool_params() needs profiles,
we need to move check for sign earlier.
2014-07-11 13:32:22 +02:00
9955204e0d cleanup: reorder code
Simplify code.
2014-07-11 13:32:21 +02:00
de1ee0bc52 cleanup: move merge option
Put long --merge option into section with long options.
2014-07-11 13:32:21 +02:00
d5d883d91b cleanup: indent changes 2014-07-11 13:32:21 +02:00
f7d6614061 cache: warn about metadata size limits
Cache pools are similar as with thin pools.
Add (needs %s) - since cache has currently
a bit strange need for extra few kb over
our default 4M extent size so make it more obvious.
2014-07-11 13:31:19 +02:00
04b8e55f2a lvconvert: relocate mirror tests 2014-07-11 12:57:45 +02:00
1931d1e58e tools: arg_is_any_set and arg_is_only_set
Helpful functions to more easily detect conflicting
set of options.
2014-07-11 12:57:45 +02:00
c0c1ada88e pool: callback handle cache
Extend the callback functionality to handle also cache pools.

cache_check is now executed on cachepool metadata when
it's activated and deactivated.
2014-07-11 12:57:45 +02:00
120bd2d6b1 pool: move code to pool source file
More code is used commonly for all pool types (cache & thin)
2014-07-11 12:57:25 +02:00
4db5d78cef display: show C only for cache and cachepool
Keep target type (attr6) as the cache data and metadata volume has.
(i.e. when will show 'raid' type if metadata is raid)
2014-07-11 12:50:44 +02:00
ba048612a3 lvchange: just skip on cache pool 2014-07-11 12:50:06 +02:00
8932d4a625 lv_is_pool: add new defines
Defines for lv_is_pool() and  lv_is_pool_metadata()
Also update comments for prompts for their current meaning.
(Though maybe they should be renamed)
2014-07-11 12:50:06 +02:00
56c5ad7b19 lvconvert: snapshot prompts to confirm conversion
Since the type passed LV is changed and content of data detroyed,
query user with prompt to confirm this operation.
Also add a proper wiping of header.

Using '--yes' will skip this prompt:

lvconvert -s --yes vg/lv vg/lvcow
2014-07-11 12:49:55 +02:00
64828d877e lvconvert: fix return codes
Error codes in some function are directly used
as command result - thus return 0 is not error code,
but success - switch to proper ECMD_FAILED.
2014-07-11 12:49:02 +02:00
baf825331c prompt: display 'n' for EOF
When EOF is detect - it could be either 'Ctrl+C'
or empty stdin.

For Ctrl+C there is visual ^C sign.
For EOF print 'n' so decision is clear in debug print.
2014-07-11 12:47:41 +02:00
39cb8aa3ab configure 2014-07-11 12:47:41 +02:00
f9d80c9d31 cache: add tool support
Introducing cache tool support.
2014-07-11 12:47:35 +02:00
5c3d894013 metadata: fix ALLOCATABLE_PV for lvm1 format
This is addendum for commit 6dc7b783c8.

LVM1 format stores the ALLOCATABLE flag directly in PV header, not
in VG metadata. So the code needs to be fixed further to work
properly for lvm1 format so that the correct PV header is written
(the flag is set only if the PV is in some VG, unset otherwise).
2014-07-11 12:24:15 +02:00
fd5912762b report: display 'unknown' value for lv_active_remotely field if the LV is also active locally
Currently, we can't determine whether the LV is active remotely
or not in that case.
2014-07-11 11:56:50 +02:00
c9ae21798e report: display 'unknown' value for active/active_locally/active_remotely/active_exclusively if info bypassed
Before the patch:

$ lvs -o name,active vg/lvol1 --driverloaded n
  WARNING: Activation disabled. No device-mapper interaction will beattempted.
  LV    Active
  lvol1 active

With this patch applied:
$ lvs -o name,active vg/lvol1 --driverloaded n
  WARNING: Activation disabled. No device-mapper interaction will be attempted.
  LV    Active
  lvol1 unknown

The same for active_{locally,remotely,exclusively} fields.
Also, rename headings for these fields (ActLocal/ActRemote/ActExcl).
2014-07-11 11:15:06 +02:00
52af0dfbc0 report: display 'unknown' value for LVSINFO fields if unable to get info
If the lv_info call fails for whatever reason/INFO dm ioctl fails or
the dm driver communication is disabled (--driverloaded n), make
sure we always display "unknown" for LVSINFO fields as that's exactly
what happens - we don't know the state.

Before the patch:

$ lvs -o name,device_open --driverloaded n
  WARNING: Activation disabled. No device-mapper interaction will be attempted.
  Command failed with status code 5.

With this patch applied:

$ lvs -o name,device_open --driverloaded n
  WARNING: Activation disabled. No device-mapper interaction will be attempted.
  LV        DevOpen
  lvol1        unknown
2014-07-11 10:18:59 +02:00
f33d75e2e5 test: Test failing due to too few PVs
Commit 33d69162e4 reduced the number of
PVs to a level where the test could not function.  (It is impossible
to replace 3 PVs of a 4-way RAID1 LV if there are only 5 PVs.)
2014-07-10 18:53:46 -05:00
3063b48602 report: also report linear and striped for lv_target_type 2014-07-10 16:41:42 +02:00
d169ff1e03 conf: add report/list_item_separator lvm.conf option
For example:

$ lvm dumpconfig report/list_item_separator
list_item_separator=","

$ lvs -o name,tags vg/lvol1
  LV    LV Tags
  lvol1 a,x,y

$ lvm dumpconfig report/list_item_separator
list_item_separator=":"

$ lvs -o name,tags vg/lvol1
  LV    LV Tags
  lvol1 ay
2014-07-10 16:18:45 +02:00
e38af4e28f libdm: report: fix string list internal representation if delimiter is composed of more than one char 2014-07-10 16:18:05 +02:00
1e5ec893c7 tests: LV's zero field now reported as binary field 2014-07-10 15:30:28 +02:00
e2448bb0dc report: report LV's zero field as binary field
Like other binary fields we already have:

$ lvs -o name,zero vg/lvx vg/pool vg/pool1
  LV    Zero
  lvx   unknown
  pool
  pool1    zero

$ lvs -o name,zero vg/lvx vg/pool vg/pool1 --binary
  LV    Zero
  lvx     -1
  pool     0
  pool1    1
2014-07-10 15:25:01 +02:00
e31ec38d8e report: reserved value: description for undefined value 2014-07-10 13:42:16 +02:00
175de52ded cleanup: also use values.h for final dm_report_reserved_value array composition 2014-07-10 13:37:40 +02:00
f598aa38ae cleanup: report reserved value macros 2014-07-10 11:54:37 +02:00
fafd10d564 conf: command_profile_template: global/binary_values_as_numeric -> report/binary_values_as_numeric 2014-07-10 09:48:45 +02:00
a4e798bd30 report: add values.h for per-field reserved value declaration 2014-07-10 09:41:21 +02:00
be75076dfc activation: Add "degraded" activation mode
Currently, we have two modes of activation, an unnamed nominal mode
(which I will refer to as "complete") and "partial" mode.  The
"complete" mode requires that a volume group be 'complete' - that
is, no missing PVs.  If there are any missing PVs, no affected LVs
are allowed to activate - even RAID LVs which might be able to
tolerate a failure.  The "partial" mode allows anything to be
activated (or at least attempted).  If a non-redundant LV is
missing a portion of its addressable space due to a device failure,
it will be replaced with an error target.  RAID LVs will either
activate or fail to activate depending on how badly their
redundancy is compromised.

This patch adds a third option, "degraded" mode.  This mode can
be selected via the '--activationmode {complete|degraded|partial}'
option to lvchange/vgchange.  It can also be set in lvm.conf.
The "degraded" activation mode allows RAID LVs with a sufficient
level of redundancy to activate (e.g. a RAID5 LV with one device
failure, a RAID6 with two device failures, or RAID1 with n-1
failures).  RAID LVs with too many device failures are not allowed
to activate - nor are any non-redundant LVs that may have been
affected.  This patch also makes the "degraded" mode the default
activation mode.

The degraded activation mode does not yet work in a cluster.  A
new cluster lock flag (LCK_DEGRADED_MODE) will need to be created
to make that work.  Currently, there is limited space for this
extra flag and I am looking for possible solutions.  One possible
solution is to usurp LCK_CONVERT, as it is not used.  When the
locking_type is 3, the degraded mode flag simply gets dropped and
the old ("complete") behavior is exhibited.
2014-07-09 22:56:11 -05:00
a098cba0eb report: Rename common fields to special fields.
Change the help heading from 'Common Fields' to 'Special Fields' for
the fields: selected, help, ?

Remove the code that does 'all' processing with these special fields as
each of them changes the behaviour of the command in an undesirable way.

'lvs -o all,selected' was of course just printing help.
(via internal expansion to 'lv_all,common_all')

and if we ignored the help fields, then '-o common_all' would still
pull in 'selected' and change the way rows were output.
2014-07-09 23:33:09 +01:00
46ea315f09 report: also recognize 'yes'/'no' for selection criteria on binary fields
We have 1/"descriptive word"/"yes" for 1 and 0/"no" for 0.
For example (the new recognized values are "yes" and "no"):

$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2
  LV    DevOpen
  root        open
  swap        open
  lvol1       open
  lvol2

$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=open'
  LV    DevOpen
  root        open
  swap        open
  lvol1       open

$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=1'
  LV    DevOpen
  root        open
  swap        open
  lvol1       open

$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=yes'
  LV    DevOpen
  root        open
  swap        open
  lvol1       open

$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=0'
  LV    DevOpen
  lvol2

$ lvs -o name,device_open fedora vg/lvol1 vg/lvol2 -S 'device_open=no'
  LV    DevOpen
  lvol2
2014-07-09 15:57:05 +02:00
c1bed36b67 cleanup: move _lvactive_disp and _thinzero_disp under 'attribute' display functions
So all attribute reporting functions are all in one section of code
for quick orientation (all these functions are defined in the order
of their attribute character displayed in pv/vg/lv_attr field).
2014-07-09 15:57:05 +02:00
bccc2bef33 report: add lv_active_{locally,remotely,exclusively} LV reporting fields
lv_active_{locally,remotely,exclusively} display the original
"lv_active" field in a more separate way so that we can create
selection criteria in a binary-based form (yes/no).
2014-07-09 15:57:05 +02:00
b6ac8819f6 report: 'whether' -> 'set if' in field description 2014-07-09 15:57:05 +02:00
ccab185aa7 cleanup: use macros for definition of reporting/selection reserved values
The macros for reserved value definition makes the process a bit easier,
but there's still a place for improvement and make this even more
transparent. We can optimize and provide better automatism here later on.
2014-07-09 15:55:54 +02:00
1a05862732 report: report unknown/-1 for binary fields with unknown value
Also respect --binary arg and/or report/binary_values_as_numeric
when displaying unknown values. If textual form is used, use "unknown",
if numeric value is used, use "-1" (which we already use to denote
unknown numeric values in other reports like lv_kernel_major and
lv_kernel_minor).
2014-07-08 16:16:02 +02:00
f76879ba44 conf: comment out devices/preferred_names and filter setting
This avoids creating void matchers which have no effect anyway and
they just use resources. Also, it makes lvm dumpconfig --type diff
to mark these settings properly as not being different from defaults
(where by default, devices/preferred_names as well as devices/filter
are void).

Also, add a few comments about builtin rules used to select device
alias in case preferred_names is not defined or it doesn't match
any of device aliases.
2014-07-08 10:22:59 +02:00
f6001465ef lv_manip: pool-metadata-spare is just a spare LV, not tightly bound to thin or cache 2014-07-07 17:02:06 +02:00
4b65d7ec72 WHATS_NEW: commits a473435..7021c8f1 2014-07-07 16:52:43 +02:00
9e1c4a3818 report: addendum for previous commit
Really call lv_info only if needed!
2014-07-07 16:28:13 +02:00
83b55c2dfb report: fix segfault while reporting PV/LV segment fields together with LV fields needeing device status (LVSINFO)
There was missing lv_info call for situations where there were
mixed PV/LV segment fields together with LVSINFO fields which
require extra lv_info call for LV device status. This ended up
with NULL lvinfo passed to the field reporting functions, hence
the segfault.
2014-07-07 15:54:13 +02:00
6dc7b783c8 metadata: fix regression causing PVs not in VGs to be marked as allocatable
If the PV is not yet in a VG, it's not allocatable.
A regression introduced by commit 0283c439ec
(_pv_create) and later commit a7ca101517
(pv_read).
2014-07-07 14:07:21 +02:00
7021c8f1a4 report: define reserved values/synonyms for some attribute fields
All binary attr fields have synonyms so selection criteria can use
either 0/1 or words to match against the field value (base type
for these binary fields is numeric one - DM_REPORT_FIELD_TYPE_NUMBER
so words are registered as reserved values):

pv_allocatable          - "allocatable"
pv_exported             - "exported"
pv_missing              - "missing"

vg_extendable           - "extendable"
vg_exported             - "exported"
vg_partial              - "partial"
vg_clustered            - "clustered"

lv_initial_image_sync   - "initial image sync", "sync"
lv_image_synced_names   - "image synced", "synced"
lv_merging_names        - "merging"
lv_converting_names     - "converting"
lv_allocation_locked    - "allocation locked", "locked"
lv_fixed_minor          - "fixed minor", "fixed"
lv_merge_failed         - "merge failed", "failed"

For example, these three are all equivalent:

$ lvs -o name,fixed_minor -S 'fixed_minor=fixed'
  LV    FixMin
  lvol8 fixed minor

$ lvs -o name,fixed_minor -S 'fixed_minor="fixed minor"'
  LV    FixMin
  lvol8 fixed minor

$ lvs -o name,fixed_minor -S 'fixed_minor=1'
  LV    FixMin
  lvol8 fixed minor

The same with binary output - it has no effect on this functionality:

$ lvs -o name,fixed_minor --binary -S 'fixed_minor=fixed'
  LV    FixMin
  lvol8          1

$ lvs -o name,fixed_minor --binary -S 'fixed_minor="fixed
minor"'
  LV    FixMin
  lvol8          1

[1] f20/~ # lvs -o name,fixed_minor --binary -S 'fixed_minor=1'
  LV    FixMin
  lvol8          1
2014-07-04 15:50:50 +02:00
0956fd230f report: adapt selection code to recognize per-field reserved values
In contrast to per-type reserved values that are applied for all fields
of that type, per-field reserved values are only applied for concrete
field only.

Also add 'struct dm_report_field_reserved_value' to libdm for per-field
reserved value definition. This is defined by field number (an index
in the 'fields' array which is given for the dm_report_init_with_selection
function during report initialization) and the value to use for any
of the specified reserved names.
2014-07-04 15:50:50 +02:00
da545ce3b4 tools: add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C and report/binary_values_as_numeric lvm.conf option
The --binary option, if used, causes all the binary values reported
in reporting commands to be displayed as "0" or "1" instead of descriptive
literal values (value "unknown" is still used for values that could not be
determined).

Also, add report/binary_values_as_numeric lvm.conf option with the same
functionality as the --binary option (the --binary option prevails
if both --binary cmd option and report/binary_values_as_numeric lvm.conf
option is used at the same time). The report/binary_values_as_numeric is
also profilable.

This makes it easier to use and check lvm reporting command output in scripts.
2014-07-04 15:40:17 +02:00
d2af4f84c9 report: add separate fields for PV/VG/LV attributes
Physical Volume Fields:
  pv_allocatable         - Whether this device can be used for allocation.
  pv_exported            - Whether this device is exported.
  pv_missing             - Whether this device is missing in system.

Volume Group Fields:
  vg_permissions         - VG permissions.
  vg_extendable          - Whether VG is extendable.
  vg_exported            - Whether VG is exported.
  vg_partial             - Whether VG is partial.
  vg_allocation_policy   - VG allocation policy.
  vg_clustered           - Whether VG is clustered.

Logical Volume Fields:
  lv_volume_type         - LV volume type.
  lv_initial_image_sync  - Whether mirror/RAID images underwent initial resynchronization.
  lv_image_synced        - Whether mirror/RAID image is synchronized.
  lv_merging             - Whether snapshot LV is being merged to origin.
  lv_converting          - Whether LV is being converted.
  lv_allocation_policy   - LV allocation policy.
  lv_allocation_locked   - Whether LV is locked against allocation changes.
  lv_fixed_minor         - Whether LV has fixed minor number assigned.
  lv_merge_failed        - Whether snapshot merge failed.
  lv_snapshot_invalid    - Whether snapshot LV is invalid.
  lv_target_type         - Kernel target type the LV is related to.
  lv_health_status       - LV health status.
  lv_skip_activation     - Whether LV is skipped on activation.

Logical Volume Info Fields
  lv_permissions         - LV permissions.
  lv_suspended           - Whether LV is suspended.
  lv_live_table          - Whether LV has live table present.
  lv_inactive_table      - Whether LV has inactive table present.
  lv_device_open         - Whether LV device is open.
2014-07-04 15:40:17 +02:00
4b9b1f2319 refactor: use new LVSINFO report type for lv_kernel_{major,minor,read_ahead} field 2014-07-04 15:40:17 +02:00
ecb2be5d16 reporter: add separate LVSINFO report type
LVSINFO is exactly the same as existing LVS report type,
but it has the "struct lvinfo" populated in addition for
use - this is useful for fields that display the status
of the LV device itself (e.g. suspended state, tables
present/missing...).

Currently, such properties are reported within the "lv_attr"
field so separation is unnecessary - the "lvinfo" call
to populate the "struct lvinfo" is directly a part of the
field reporting function - _lvstatus_disp/lv_attr_dup.

With upcoming patches, we'd like the lv_attr field bits
to be separated into their own fields. To avoid calling
"lvinfo" fn as many times as there are fields requiring
the "lv_info" structure to be populated while reporting
one row related to one LV, we're separating former LVS
into LVS and LVSINFO report type. With this, there's
just one "lvinfo" call for one report row and LV reporting
fields will take the info needed from this struct then,
hence reusing it and not calling "lvinfo" fn on their own.
2014-07-04 15:40:17 +02:00
6b58647848 lv_manip: add get_lv_type_name/lv_is_linear and lv_is_striped helper fns
The get_lv_type_name helps with translating volume type
to human readable form (can be used in reports or
various messages if needed).

The lv_is_linear and lv_is_striped complete the set of
lv_is_* functions that identify exact volume types.
2014-07-04 15:40:17 +02:00
a4734354ce refactor: remove static modifier for lv_raid_image_in_sync and lv_raid_healthy fn
...to make use of it in other parts of the code.
2014-07-04 15:40:17 +02:00
9d2c445d0a cleanup: just safely copy string
Keep analyzers happier and use constrained strcpy.
2014-07-04 12:31:17 +02:00
86e116450e cleanup: drop unneeded initialization
Code assigns this variable right after clearing.
2014-07-04 12:31:17 +02:00
1f72f8ed40 dev-type: print aborting log_error
When wiping is aborted print immediate log_error message
(log_error comes 1st.)
2014-07-04 12:31:17 +02:00
a94abc0fdd dev-type: print log_sys_debug
For non-fatal error use log_sys_debug as the tool
is not stopping on these errors.
2014-07-04 12:31:17 +02:00
ac60c876c4 vgsplit: Improve message when LV still active.
Mention parent LV as well as the LV triggering the warning.

Still leaves some confusing cases but its not worth fixing them
at the moment.
(Thin pool inactive but a thin volume active => deactivate thin vol.
Inactive mirror/raid with pvmove in progress => complete pvmove and
active&deactivate mirror/raid.
If new VG already exists it requires some LVs to be inactive
unnecessarily.)
2014-07-04 01:13:51 +01:00
137ed3081a report: Add lv_parent field.
Only defined for thin/cache/raid/mirror at this stage as it
relies on get_only_segment_using_this_lv().
2014-07-03 23:49:34 +01:00
1e1c2769a7 vgsplit: Fix VG component of lvid.
Fix VG component of lvid in vgsplit and vgmerge
Update vg_validate() to detect the error.
Call lv_is_active() before moving LV into new VG, not after.
2014-07-03 19:06:04 +01:00
64ce3a8066 report: Add lv_dm_path and lv_full_name fields. 2014-07-02 17:24:05 +01:00
5bfa2ec21d report: Exclude hidden devices from lv_path field. 2014-07-02 14:57:00 +01:00
c6811dd512 tests: ensure data hits cow 2014-07-02 15:10:10 +02:00
39bd6bb89e cleanup: drop inline and add prefix _ for static
Leave inline decision on compiler.
Add '_'prefix for static functions.
2014-07-02 15:09:06 +02:00
d1094ec4c6 tests: replace cat with $(<
Use shell built-in $(<
Print lvm.conf in use for test.
2014-07-02 10:45:44 +02:00
b22ab4dab0 tests: avoid hiding results in local
There is a difference between:

local a=$(shell)

and

local a
a=$(shell)

The first return exit code from shells' local command.
2014-07-02 10:45:43 +02:00
d1dcbe0853 cleanup: add braces for if() 2014-07-02 10:45:43 +02:00
52ab15b2d0 cleanup: use unsigned type for command
Keep command unsigned (as _IOWR() produces them).
2014-07-02 10:45:43 +02:00
57f8b33d5d cleanup: a bit better error message 2014-07-02 10:45:43 +02:00
165cfab7db cleanup: verbose in human readable size
Use normal size like we use everywhere else.
2014-07-02 10:45:42 +02:00
6b3a49876e cleanup: line indent 2014-07-02 10:45:42 +02:00
748af97afc cleanup: libdm simplier error comparation
When testing return value from snprintf
use simplier form '>=' instead of  '+1 >'.
2014-07-02 10:45:42 +02:00
e21d0eb90e display: add display_lvname
Add simple function to print vg/lv name.
Useful i.e. in error messages.
2014-07-02 10:45:42 +02:00
6f6900d457 fsadm: avoid using -a in test 2014-07-02 10:45:41 +02:00
7bdf4719e8 pool: delay conversion prompt
First validate as much params as possible before prompting user
about conversion to data and metadata LV.
2014-07-02 10:45:39 +02:00
3af761ba16 thin: fix chunk_size conversion prompt skip
Use --force only enables prompting for dangerous operation.
User has to add --yes to skip this prompt.
2014-07-02 10:43:56 +02:00
93a80018ae lvremove: remove thin volumes on damaged pools
Support remove of thin volumes With --force --force
when thin pools is damaged.

This way it's possible to remove thin pool with
unrepairable metadata without requiring to
manually edit lvm2 metadata.

lvremove -ff vg/pool

removes all thin volumes and pool even when
thin pool cannot be activated (to accept
removal of thin volumes in kernel metadata)
2014-07-02 10:37:52 +02:00
0b872ce870 raid: don't skip prompt with force
Yes is meant to be used to skip all new prompts.
(--force just adds more prompts).
2014-07-02 10:36:32 +02:00
c460f35cda raid: switch to log_warn
Use log_warn for warning message.
log_error is printed when command returns error code.
2014-07-02 10:34:40 +02:00
355258be58 mirror: mirror_or_raid_type_requested update
mirror_or_raid_type_requested really checks for mirror type.

Convert macros mirror_or_raid_type_requested() and
snapshot_type_requested() into inline functions.
2014-07-02 10:34:39 +02:00
c77197c688 make: Fix pofile and .d file generation.
Use builddir not srcdir with make pofile.

Append 'incfile:' lines to %.d files to handle newly-missing dependencies
without 'make clean' after a file is moved or deleted.
2014-07-02 00:48:50 +01:00
70551eec59 uuid: revert uuids for mirrors and raids
Using suffixes for mirrors and raids will need more work,
before this could be enabled.

Meanwhile revert to previous behavior.

Keep suffixes for thins and caches.
2014-06-30 14:58:30 +02:00
13fb02ff1f cleanup: ignore vg_name in /lib
Since  vg_name inside /lib function has already been ignored mostly
except for a few debug prints - make it and official internal API
feature.

vg_name is used only in  /tools while the VG is not yet openned,
and when  lvresize/lvcreate /lib function is called with VG pointer
already being used, then vg_name becomes irrelevant (it's not been
validated anyway).

So any internal user of lvcreate_params and lvresize_params does not
need to set vg_name pointer and may leave it NULL.
2014-06-30 12:21:36 +02:00
667f93b7d9 uuid: add more private uuid sufixes
Use suffixes for easier detection of private volumes.

This commit makes older volume UUIDs incompatible and
it most probably needs machine reboot after upgrade.
2014-06-30 12:17:07 +02:00
2ada685216 cleanup: more lv_is_ functions 2014-06-30 12:16:08 +02:00
6da14a82c6 thin: do not create reserved LVs
When creating pool's metadata - create initial LV for clearing with some
generic name and after the volume is create & cleared - rename it to
reserved name '_tmeta/_cmeta'.

We should not expose  'reserved' names for public LVs.
2014-06-30 12:16:05 +02:00
eadcea2dae thin: repaired LV uses _meta%d
Don't leave 'regular' LV with reserved suffix for a user.
After succefull repair use 'normal' (non-reserved) LV name
for backup of original metadata.
2014-06-30 12:15:13 +02:00
b6fe906956 activation: fix typo in 'activation skip' message 2014-06-30 11:02:45 +02:00
100342605c libdm: fix double const for "value" in dm_report_reserved_value structure
C++ may have
2014-06-30 09:44:23 +02:00
b41aa985d7 man: do not mention '(i)nherited' for alloc policy in vg_attr field
VG has nothing to inherit from...
2014-06-26 15:15:10 +02:00
ed3c2537b8 raid: Allow repair to reuse PVs from same image that suffered a PV failure
When repairing RAID LVs that have multiple PVs per image, allow
replacement images to be reallocated from the PVs that have not
failed in the image if there is sufficient space.

This allows for scenarios where a 2-way RAID1 is spread across 4 PVs,
where each image lives on two PVs but doesn't use the entire space
on any of them.  If one PV fails and there is sufficient space on the
remaining PV in the image, the image can be reallocated on just the
remaining PV.
2014-06-25 22:26:06 -05:00
7028fd31a0 misc: after releasing a PV segment, merge it with any adjacent free space
Previously, the seg_pvs used to track free and allocated space where left
in place after 'release_pv_segment' was called to free space from an LV.
Now, an attempt is made to combine any adjacent seg_pvs that also track
free space.  Usually, this doesn't provide much benefit, but in a case
where one command might free some space and then do an allocation, it
can make a difference.  One such case is during a repair of a RAID LV,
where one PV of a multi-PV image fails.  This new behavior is used when
the replacement image can be allocated from the remaining space of the
PV that did not fail.  (First the entire image with the failed PV is
removed.  Then the image is reallocated from the remaining PVs.)
2014-06-25 22:04:58 -05:00
b35fb0b15a raid/misc: Allow creation of parallel areas by LV vs segment
I've changed build_parallel_areas_from_lv to take a new parameter
that allows the caller to build parallel areas by LV vs by segment.
Previously, the function created a list of parallel areas for each
segment in the given LV.  When it came time for allocation, the
parallel areas were honored on a segment basis.  This was problematic
for RAID because any new RAID image must avoid being placed on any
PVs used by other images in the RAID.  For example, if we have a
linear LV that has half its space on one PV and half on another, we
do not want an up-convert to use either of those PVs.  It should
especially not wind up with the following, where the first portion
of one LV is paired up with the second portion of the other:
------PV1-------  ------PV2-------
[ 2of2 image_1 ]  [ 1of2 image_1 ]
[ 1of2 image_0 ]  [ 2of2 image_0 ]
----------------  ----------------
Previously, it was possible for this to happen.  The change makes
it so that the returned parallel areas list contains one "super"
segment (seg_pvs) with a list of all the PVs from every actual
segment in the given LV and covering the entire logical extent range.

This change allows RAID conversions to function properly when there
are existing images that contain multiple segments that span more
than one PV.
2014-06-25 21:20:41 -05:00
1f1675b059 test: Test addition to show incorrect allocator behavior
If a RAID LV has images that are spread across more than one PV
and you allocate a new image that requires more than one PV,
parallel_areas is only honored for one segment.  This commit
adds a test for this condition.
2014-06-21 15:33:52 -05:00
e80884cd08 filters: always reevaluate filter before creating a PV
...to avoid using cached value (persistent filter) and therefore
not noticing any change made after last scan/filtering - the state
of the device may have changed, for example new signatures added.

$ lvm dumpconfig --type diff
allocation {
	use_blkid_wiping=0
}
devices {
	obtain_device_list_from_udev=0
}

$ cat /etc/lvm/cache/.cache | grep sda

$ vgscan
  Reading all physical volumes.  This may take a while...
  Found volume group "fedora" using metadata type lvm2

$ cat /etc/lvm/cache/.cache | grep sda
		"/dev/sda",

$ parted /dev/sda mklabel gpt
Information: You may need to update /etc/fstab.

$ parted /dev/sda print
Model: QEMU QEMU HARDDISK (scsi)
Disk /dev/sda: 134MB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:

Number  Start  End  Size  File system  Name  Flags

$ cat /etc/lvm/cache/.cache | grep sda
		"/dev/sda",

====

Before this patch:
$ pvcreate /dev/sda
  Physical volume "/dev/sda" successfully created

With this patch applied:
$ pvcreate /dev/sda
  Physical volume /dev/sda not found
  Device /dev/sda not found (or ignored by filtering).
2014-06-25 16:24:28 +02:00
e329c3146d coverity: mark new switch cases with 'fall through' comment for coverity to stop complaining 2014-06-25 08:51:37 +02:00
3208396ce5 coverity: fix issues reported by coverity 2014-06-24 14:58:53 +02:00
29ca0573ba post-release 2014-06-23 15:23:09 +01:00
647 changed files with 80969 additions and 19334 deletions

11
.gitignore vendored
View File

@ -1,13 +1,16 @@
*.5
*.7
*.8
*.a
*.d
*.o
*.orig
*.pc
*.pot
*.rej
*.so
*.so.*
*.swp
*.sw*
*~
.export.sym
@ -17,11 +20,11 @@
Makefile
make.tmpl
configure.h
version.h
/autom4te.cache/
/autoscan.log
/config.log
/config.status
/configure.scan
/cscope.out
/tags
/tmp/

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.
#
@ -15,6 +15,8 @@
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
@ -91,10 +93,47 @@ cscope.out:
all: cscope.out
endif
DISTCLEAN_TARGETS += cscope.out
CLEAN_DIRS += autom4te.cache
check check_system check_cluster check_local check_lvmetad unit: all
check check_system check_cluster check_local check_lvmetad check_lvmpolld unit: all
$(MAKE) -C test $(@)
conf.generate: tools
# how to use parenthesis in makefiles
leftparen:=(
LVM_VER := $(firstword $(subst $(leftparen), ,$(LVM_VERSION)))
VER := LVM2.$(LVM_VER)
# release file name
FILE_VER := $(VER).tgz
CLEAN_TARGETS += $(FILE_VER)
CLEAN_DIRS += $(rpmbuilddir)
dist:
@echo "Generating $(FILE_VER)";\
(cd $(top_srcdir); git ls-tree -r HEAD --name-only | xargs tar --transform "s,^,$(VER)/," -c) | gzip >$(FILE_VER)
rpm: dist
$(RM) -r $(rpmbuilddir)/SOURCES
$(MKDIR_P) $(rpmbuilddir)/SOURCES
$(LN_S) -f $(abs_top_builddir)/$(FILE_VER) $(rpmbuilddir)/SOURCES
$(LN_S) -f $(abs_top_srcdir)/spec/build.inc $(rpmbuilddir)/SOURCES
$(LN_S) -f $(abs_top_srcdir)/spec/macros.inc $(rpmbuilddir)/SOURCES
$(LN_S) -f $(abs_top_srcdir)/spec/packages.inc $(rpmbuilddir)/SOURCES
DM_VER=$$(cut -d- -f1 $(top_srcdir)/VERSION_DM);\
GIT_VER=$$(cd $(top_srcdir); git describe | cut -d- --output-delimiter=. -f2,3 || echo 0);\
sed -e "s,\(device_mapper_version\) [0-9.]*$$,\1 $$DM_VER," \
-e "s,^\(Version:[^0-9%]*\)[0-9.]*$$,\1 $(LVM_VER)," \
-e "s,^\(Release:[^0-9%]*\)[0-9.]\+,\1 $$GIT_VER," \
$(top_srcdir)/spec/source.inc >$(rpmbuilddir)/SOURCES/source.inc
rpmbuild -v --define "_topdir $(rpmbuilddir)" -ba $(top_srcdir)/spec/lvm2.spec
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)
@ -114,6 +153,9 @@ install_systemd_generators:
install_systemd_units:
$(MAKE) -C scripts install_systemd_units
install_all_man:
$(MAKE) -C man install_all_man
ifeq ("@PYTHON_BINDINGS@", "yes")
install_python_bindings:
$(MAKE) -C liblvm/python install_python_bindings
@ -122,8 +164,11 @@ endif
install_tmpfiles_configuration:
$(MAKE) -C scripts install_tmpfiles_configuration
LCOV_TRACES = libdm.info lib.info tools.info \
daemons/dmeventd.info daemons/clvmd.info
LCOV_TRACES = libdm.info lib.info liblvm.info tools.info \
libdaemon/client.info libdaemon/server.info \
daemons/clvmd.info daemons/dmeventd.info \
daemons/lvmetad.info
CLEAN_TARGETS += $(LCOV_TRACES)
ifneq ("$(LCOV)", "")
@ -152,7 +197,7 @@ lcov: $(LCOV_TRACES)
$(RM) -r $(LCOV_REPORTS_DIR)
$(MKDIR_P) $(LCOV_REPORTS_DIR)
for i in $(LCOV_TRACES); do \
test -s $$i && lc="$$lc $$i"; \
test -s $$i -a $$(wc -w <$$i) -ge 100 && lc="$$lc $$i"; \
done; \
test -z "$$lc" || $(GENHTML) -p @abs_top_builddir@ \
-o $(LCOV_REPORTS_DIR) $$lc
@ -184,3 +229,12 @@ memcheck: test-programs
ruby-test:
$(RUBY) report-generators/test/ts.rb
endif
ifneq ($(shell which ctags),)
.PHONY: tags
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 5 -type f -name '*.[ch]' -exec ctags -a '{}' +
CLEAN_TARGETS += tags
endif

2
README
View File

@ -18,7 +18,7 @@ Mailing list for general discussion related to LVM2:
Mailing lists for LVM2 development, patches and commits:
lvm-devel@redhat.com
Subscribe from https://www.redhat.com/mailman/listinfo/linux-lvm
Subscribe from https://www.redhat.com/mailman/listinfo/lvm-devel
lvm2-commits@lists.fedorahosted.org (Read-only archive of commits)
Subscribe from https://fedorahosted.org/mailman/listinfo/lvm2-commits

View File

@ -1 +1 @@
2.02.107(2)-git (2014-06-23)
2.02.134(2)-git (2015-10-30)

View File

@ -1 +1 @@
1.02.86-git (2014-06-23)
1.02.111-git (2015-10-30)

530
WHATS_NEW
View File

@ -1,3 +1,533 @@
Version 2.02.134 -
====================================
Version 2.02.133 - 30th October 2015
====================================
Support repeated -o|--options for reporting commands.
Support -o- and -o# for reporting commands to remove and compact fields.
Fix missing PVs from pvs output if vgremove is run concurrently.
Remove unwanted error message when running pvs/vgs/lvs and vgremove at once.
Check newly created VG's metadata do not overlap in metadata ring buffer.
Check metadata area size is at least the minimum size defined for the format.
Thin pool targets uses low_water_mark from profile.
Dropping 'yet' from error of unsupported thick snapshot of snapshots.
Do not support unpartitioned DASD devices with CDL formatted with pvcreate.
For thins use flush for suspend only when volume size is reduced.
Enable code which detects the need of flush during suspend.
Ensure --use-policy will resize volume to fit below threshold.
Correct percentage evaluation when checking thin-pool over threshold.
Fix lvmcache to move PV from VG to orphans if VG is removed and lvmetad used.
Fix lvmcache to not cache even invalid info about PV which got removed.
Support checking of memlock daemon counter.
Allow all log levels to be used with the lvmetad -l option.
Add optional shutdown when idle support for lvmetad.
Fix missing in-sync progress info while lvconvert used with lvmpolld.
Add report/compact_output_cols to lvm.conf to define report cols to compact.
Do not change logging in lvm2 library when it's already set.
Check for enough space in thin-pool in command before creating new thin.
Make libblkid detect all copies of the same signature if use_blkid_wiping=1.
Fix vgimportclone with -n to not add number unnecessarily to base VG name.
Cleanup vgimportclone script and remove dependency on awk, grep, cut and tr.
Add vg_missing_pv_count report field to report number of missing PVs in a VG.
Properly identify internal LV holding sanlock locks within lv_role field.
Add metadata_devices and seg_metadata_le_ranges report fields for raid vols.
Fix lvm2-{activation,clvmd,cmirrord,monitor} service to exec before mounting.
Version 2.02.132 - 22nd September 2015
======================================
Fix lvmconf to set locking_type=2 if external locking library is requested.
Remove verbose message when rescanning an unchanged device. (2.02.119)
Add origin_uuid, mirror_log_uuid, move_pv_uuid, convert_lv_uuid report fields.
Add pool_lv_uuid, metadata_lv_uuid, data_lv_uuid reporting fields.
Fix PV label processing failure after pvcreate in lvm shell with lvmetad.
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.
Version 2.02.129 - 26th August 2015
===================================
Drop error message when vgdisplay encounters an exported VG. (2.02.27)
Fix shared library generation to stop exporting internal functions.(2.02.120)
Accept --cachemode with lvconvert.
Fix and improve reporting properties of cache-pool.
Enable usage of --cachepolicy and --cachesetting with lvconvert.
Don't allow to reduce size of thin-pool metadata.
Fix debug buffer overflows in cmirrord logging.
Add --foreground and --help to cmirrord.
Version 2.02.128 - 17th August 2015
===================================
Allocation setting cache_pool_cachemode is replaced by cache_mode.
Don't attempt to close config file that couldn't be opened.
Check for valid cache mode in validation of cache segment.
Change internal interface handling cache mode and policy.
When no cache policy specified, prefer smq (if available) over mq.
Add demo cache-mq and cache-smq profiles.
Add cmd profilable allocation/cache_policy,cache_settings,cache_mode.
Require cache_check 0.5.4 for use of --clear-needs-check-flag.
Fix lvmetad udev rules to not override SYSTEMD_WANTS, add the service instead.
Version 2.02.127 - 10th August 2015
===================================
Do not init filters, locking, lvmetad, lvmpolld if command doesn't use it.
Order fields in struct cmd_context more logically.
Add lock_type to lvmcache VG summary and info structs.
Fix regression in cache causing some PVs to bypass filters (2.02.105).
Make configure --enable-realtime the default now.
Update .gitignore and configure.in files to reflect usage of current tree.
Version 2.02.126 - 24th July 2015
=================================
Fix long option hyphen removal. (2.02.122)
Fix clvmd freeze if client disappears without first releasing its locks.
Fix lvconvert segfaults while performing snapshots merge.
Ignore errors during detection if use_blkid_wiping=1 and --force is used.
Recognise DM_ABORT_ON_INTERNAL_ERRORS env var override in lvm logging fn.
Fix alloc segfault when extending LV with fewer stripes than in first seg.
Fix handling of cache policy name.
Set cache policy before with the first lvm2 cache pool metadata commit.
Fix detection of thin-pool overprovisioning (2.02.124).
Fix lvmpolld segfaults on 32 bit architectures.
Add lvmlockd lock_args validation to vg_validate.
Fix ignored --startstopservices option if running lvmconf with systemd.
Hide sanlock LVs when processing LVs in VG unless named or --all used.
Version 2.02.125 - 7th July 2015
================================
Fix getline memory usage in lvmpolld.
Add support --clear-needs-check-flag for cache_check of cache pool metadata.
Add lvmetactl for developer use only.
Rename global/lock_retries to lvmlockd_retries.
Replace --enable-lvmlockd by --enable-lockd-sanlock and --enable-lockd-dlm.
Version 2.02.124 - 3rd July 2015
================================
Move sending thin pool messages from resume to suspend phase.
Report warning when pool is overprovisioned and not auto resized.
Recognize free-form date/time values for lv_time field in selection criteria.
Added experimental lvmlockd with configure --enable-lvmlockd.
Fix regression in select to match string fields if using synonyms (2.02.123).
Fix regression when printing more lv names via display_lvname (2.02.122).
Add missing error logging to unlock_vg and sync_local_dev_names callers.
Version 2.02.123 - 30th June 2015
=================================
Add report/time_format lvm.conf option to define time format for report.
Fix makefile shell compare == when building lvmetad lvmpolld (2.02.120).
Add --type full to lvmconfig for full configuration tree view.
Add undocumented environment variables to lvm man page. (2.02.119)
Add device synchronization point before activating a new snapshot.
Add --withspaces to lvmconfig to add spaces in output for better readability.
Add custom main function to libdaemon.
Use lvmetad to track out-of-date metadata discovered.
Version 2.02.122 - 20th June 2015
=================================
Flush stdout before printing to stderr.
Use pre-allocated buffer for printed LV names in display_lvname.
Support thins with size of external origin unaligned with thin pool chunk.
Allow extension of reduced thin volumes with external origins.
Consider snapshot and origin LV as unusable if component devices suspended.
Fix lvmconfig segfault on settings with undefined default value (2.02.120).
Add explicit 's' (shared) LV activation mode.
Ignore hyphens in long options names (i.e. --long-option == --longoption).
Version 2.02.121 - 12th June 2015
=================================
Distinguish between on-disk and lvmetad versions of text metadata.
Remove DL_LIBS from Makefiles for daemons that don't need them.
Zero errno in before strtoul call in dmsetup if tested after the call.
Zero errno in before strtoul call in lvmpolld.
Fix a segfault in pvscan --cache --background command.
Fix test for AREA_PV when checking for failed mirrors.
Do not use --sysinit in lvm2-activation{-early,-net}.service if lvmpolld used.
Maintain outdated PV info in lvmetad till all old metadata is gone from disk.
Do not fail polling when poll LV not found (already finished or removed).
Replace poll_get_copy_vg/lv fns with vg_read() and find_lv() in polldaemon.
Close all device fds only in before sleep call in polldaemon.
Simplify Makefile targets that generate exported symbols.
Move various -D settings from Makefiles to configure.h.
Version 2.02.120 - 15th May 2015
================================
Make various adjustments to Makefile compilation flags.
Add lvmpolld debug message class.
Add lvmpolld client mode for querying running server instance for status info.
Fix some libdaemon socket creation and reuse error paths.
Daemons (libdaemon) support exit on idle also in non-systemd environment.
Provide make dist and make rpm targets
Configure lvm.conf for use_lvmetad and use_lvmpolld.
Add lvpoll for cmdline communication with lvmpolld.
Add lvmpolld acting as a free-standing version of polldaemon.
Avoid repeated identical lvmetad VG lookups in commands processing all VGs.
Handle switches to alternative duplicate PVs efficiently with lvmetad.
Properly validate PV size for pvcreate --restorefile.
Fix check if pvcreate wiped device (2.02.117).
Fix storing of vgid when caching metadata (2.02.118).
Fix recursive lvm-config man page. (2.02.119)
Refactor polldaemon interfaces to poll every operation by VG/LV couple
Skip wait after testing in _wait_for_single_lv when polling finished
Return 'None' in python for empty string properties instead of crashing.
Distinguish signed numerical property type in reports for lvm2app library.
Reread raid completion status immediately when progress appears to be zero.
lvm2app closes locking on lvm_quit().
Configure detects /run or /var/run.
Add missing newline in clvmd --help output.
Version 2.02.119 - 2nd May 2015
===============================
New LVM_LOG_FILE_EPOCH, LVM_EXPECTED_EXIT_STATUS env vars. Man page to follow.
Remove detailed content from lvm.conf man page: use lvmconfig instead.
Generate complete config files with lvmconfig or 'make generate'.
Also display info on deprecated config with lvmconfig --withcomments.
Display version since which config is deprecated in lvmconfig --withversions.
Add --showdeprecated to lvmconfig to also display deprecated settings.
Hide deprecated settings in lvmconfig output for all types but current,diff.
Introduce support for exit on idle feature in libdaemon
Add --showunsupported to lvmconfig to also display unsupported settings.
Display unsupported settings for lvmconfig --type current,diff only by default
Honour lvmconfig --ignoreunsupported and --ignoreadvanced for all --type.
Make python bindings usable with python3 (and compatible with 2.6 & 2.7).
Add lvmconfig -l|--list as shortcut for lvmconfig --type list --withsummary.
Add lvmconfig --type list to display plain list of configuration settings.
Introduce lvmconfig as the preferred form of 'lvm dumpconfig'.
Add lv_ancestors and lv_descendants reporting fields.
Add --ignorelocal option to dumpconfig to ignore the local section.
Close connection to lvmetad after fork.
Make lvchange able to resume background pvmove polling again.
Split pvmove update metadata fn in an initial one and a subsequent one.
Refactor shared pvmove and lvconvert code into new _poll files.
Add --unconfigured option to dumpconfig to print strings unconfigured.
Add --withsummary option to dumpconfig to print first line - summary comment.
Use number of device holders to help choose between duplicate PVs.
Try to make lvmetad and non-lvmetad duplicate PV handling as similar as poss.
Issue warnings about duplicate PVs discovered by lvmetad.
Track alternative devices with matching PVIDs in lvmetad.
Check for lvm binary in blkdeactivate and skip LVM processing if not present.
Add --enable-halvm and --disable-halvm options to lvmconf script.
Add --services, --mirrorservice and --startstopservices option to lvmconf.
Use proper default value of global/use_lvmetad when processing lvmconf script.
Respect allocation/cling_tag_list during intial contiguous allocation.
Add A_PARTITION_BY_TAGS set when allocated areas should not share tags.
Make changes persist with python addTag/removeTag.
Set correct vgid when updating cache when writing PV metadata.
More efficient clvmd singlenode locking emulation.
Reject lvcreate -m with raid4/5/6 to avoid unexpected layout.
Don't skip invalidation of cached orphans if vg write lck is held (2.02.118).
Log relevant PV tags when using cling allocation.
Add str_list_add_list() to combine two lists.
Fix LV processing with selection to always do the selection on initial state.
Add internal LV_REMOVED LV status flag.
Version 2.02.118 - 23rd March 2015
==================================
Store metadata size + checksum in lvmcache and add struct lvmcache_vgsummary.
Remove inaccessible clustered PVs from 'pvs -a'.
Don't invalidate cached orphan information while global lock is held.
Avoid rescan of all devices when requested pvscan for removed device.
Measure configuration timestamps with nanoseconds when available.
Disable lvchange of major and minor of pool LVs.
Fix pvscan --cache to not scan and read ignored metadata areas on PVs.
Add After=iscsi-shutdown.service to blk-availability.service systemd unit.
Disallow vgconvert from changing metadata format when lvmetad is used.
Don't do a full read of VG when creating a new VG with an existing name.
Reduce amount of VG metadata parsing when looking for vgname on a PV.
Avoid reparsing same metadata when reading same metadata from multiple PVs.
Save extra device open/close when scanning device for size.
Fix seg_monitor field to report status also for mirrors and thick snapshots.
Replace LVM_WRITE with LVM_WRITE_LOCKED flags in metadata if system ID is set.
Remove ACCESS_NEEDS_SYSTEM_ID VG status flag. (2.02.117)
Enable system ID features.
Version 2.02.117 - 4th March 2015
=================================
Add CFG_DISABLED for new system ID config settings that must not yet be used.
Preserve original format type field when processing backup files.
Implement status action for lvm2-monitor initscript to display monitored LVs.
Allow lvchange -p to change kernel state only if metadata state differs.
Fix incorrect persistent .cache after report with label fields only (2.02.106).
Reinstate PV tag recognition for pvs if reporting label fields only (2.02.105).
Rescan devices before vgimport with lvmetad so exported VG is seen.
Fix hang by adjusting cluster mirror regionsize, avoiding CPG msg limit.
Do not crash when --cachepolicy is given without --cachesettings.
Add NEEDS_FOREIGN_VGS flag to vgimport so --foreign is always supplied.
Add --foreign to the 6 display and reporting tools and vgcfgbackup.
Install /etc/lvm/lvmlocal.conf template with local section for systemid.
Record creation_host_system_id in lvm2 metadata (never set yet).
Reinstate recursive config file tag section processing. (2.02.99)
Add 'lvm systemid' to display the current system ID (never set yet).
Fix configure to properly recognize --with-default-raid10-segtype option.
Do not refresh filters/rescan if no signature is wiped during pvcreate.
Enforce none external dev info for wiping during pvcreate to avoid races.
Add global/system_id_source and system_id_file to lvm.conf (disabled).
Add support for VG system_id to control host access to VGs.
Update vgextend to use process_each_vg.
Add --ignoreskippedcluster to pvchange.
Allow pvchange to modify several properties at once.
Update pvchange to use process_each_pv.
Fix pvs -a used with lvmetad to filter out devices unsuitable for PVs.
Fix selection to recognize units for ba_start, vg_free and seg_start fields.
Add support for -S/--select to vgexport and vgimport.
Add support for -S/--select to vgdisplay, lvdisplay and pvdisplay without -C.
Add support for -S/--select to vgremove and lvremove.
Add support for -S/--select to vgchange,lvchange and pvchange.
Add infrastructure to support selection for non-reporting tools.
Add LVM_COMMAND_PROFILE env var to set default command profile name to use.
Set CLOEXEC flag on file descriptors originating in libdaemon.
Version 2.02.116 - 30th January 2015
====================================
Deactivate unused thin pools activated with lvm2 pre-2.02.112 versions.
Check lock holding LV when lvconverting stacked raid LV in cluster.
Support udev external dev info for filters: PV min size, mpath, md, partition.
Add fw_raid_component_detection lvm.conf option to enable FW raid detection.
Add devices/external_device_info_source lvm.conf option ("none" by default).
Scan pools in for_each_sub_lv() and add for_each_sub_lv_except_pools().
Fix lvm2app lvm_lv_get_property return value for fields with info/status ioctl.
Fix lvm2app regression in lvm_lv_get_attr causing unknown values (2.02.115).
Set default cache_mode to writehrough when missing in metadata.
Preserve chunk size with repair and metadata swap of a thin pool.
Fix raid --splitmirror 1 functionality (2.02.112).
Fix tree preload to handle splitting raid images.
Do not support unpartitioned DASD devices.
Improve config validation to check if setting with string value can be empty.
Version 2.02.115 - 21st January 2015
====================================
Report segment types without monitoring support as undefined.
Support lvchange --errorwhenfull for thin pools.
Improve the processing and reporting of duplicate PVs.
Report lv_health_status and health attribute also for thin pool.
Add lv_when_full reporting field.
Add support for lvcreate --errorwhenfull y|n for thin pools.
Fix lvconvert --repair to honour resilience requirement for segmented RAID LV.
Filter out partitioned device-mapper devices as unsuitable for use as PVs.
Also notify lvmetad about filtered device if using pvscan --cache DevicePath.
Use LVM's own selection instead of awk expressions in clvmd startup scripts.
Do not filter out snapshot origin LVs as unusable devices for an LVM stack.
Fix incorrect rimage names when converting from mirror to raid1 LV (2.02.112).
Introduce pvremove_many to avoid excessive metadata re-reading and messages.
Check for cmirror availability during cluster mirror creation and activation.
Add cache_policy and cache_settings reporting fields.
Add missing recognition for --binary option with {pv,vg,lv}display -C.
Fix vgimportclone to notify lvmetad about changes done if lvmetad is used.
Fix vgimportclone to properly override config if it is missing in lvm.conf.
Fix automatic use of configure --enable-udev-systemd-background-jobs.
Correctly rename active split LV with -splitmirrors for raid1.
Add report/compact_output to lvm.conf to enable/disable compact report output.
Still restrict mirror region size to power of 2 when VG extent size is not.
Version 2.02.114 - 28th November 2014
=====================================
Release socket in daemon_close and protocol string in daemon_open error path.
Add --cachepolicy and --cachesettings to lvcreate.
Fix regression when parsing /dev/mapper dir (2.02.112).
Fix missing rounding to 64KB when estimating optimal thin pool chunk size.
Fix typo in clvmd initscript causing CLVMD_STOP_TIMEOUT var to be ignored.
Fix size in pvresize "Resizing to ..." verbose msg to show proper result size.
Version 2.02.113 - 24th November 2014
=====================================
Add --cachepolicy and --cachesettings options to lvchange.
Validate that converted volume and specified pool volume differ in lvconvert.
Fix regression in vgscan --mknodes usage (2.02.112).
Respect --prefix when setting CLMVD_PATH configure (2.02.89).
Default to configure --enable-udev-systemd-background-jobs for systemd>=205.
Fix ignore_vg() to properly react on various vg_read errors (2.02.112).
Failed recovery returns FAILED_RECOVERY status flag for vg_read().
Exit with non-zero status code when pvck encounters a problem.
Fix clean_tree after activation/resume for cache target (2.02.112).
Version 2.02.112 - 11th November 2014
=====================================
Add cache_{read,write}_{hits,misses} reporting fields.
Add cache_{total,used,dirty}_blocks reporting fields.
Add _corig as reserved suffix.
Reduce number of VG writes and commits when creating spare volumes.
When remove_layer_from_lv() removes layer, restore subLV names.
Cache-pool in use becomes invisible LV.
Don't prompt for removal of _pmspare in VG without pool metadata LV.
Deactivation of snapshot origin detects and deactivates left-over snapshots.
Properly report error when taking snapshot of any cache type LV.
Add basic thread debugging messages to dmeventd.
Include threads being shutdown in dmeventd device registration responses.
Inital support for external users of thin pools based on transaction_id.
Report some basic percentage info for cache pools.
Introduce size_mb_arg_with_percent() for advanced size arg reading.
Add extra support for '.' as decimal point in size args.
Add configure parameters for default segment type choices.
Add global/sparse_segtype_default setting to use thin for --type sparse.
Update and correct lvcreate and lvcovert man pages.
Mark pools and snapshots as unzeroable volumes.
Check for zeroing of volume after segment type is fully detected.
Better support for persistent major and minor options with lvcreate.
Refactor lvcreate towards more complete validation of all supported options.
Support lvcreate --type linear.
Improve _should_wipe_lv() to warn with message.
Inform about temporarily created volumes only in verbose mode.
Better support for --test mode with pool creation.
Query lock holding LV when replacing and converting raid volumes.
Add extra validate for locked lv within validate_lv_cache_create().
Add internal lvseg_name() function.
Skip use of lock files for virtual internal VG names.
Fix selection on {vg,lv}_permissions fields to properly match selection criteria.
Fix lv_permissions reporting to display read-only{-override} instead of blank.
Fix liblvm2cmd and lvm shell to respect quotes around args in cmd line string.
Permit extent sizes > 128KB that are not power of 2 with lvm2 format.
Remove workaround for lvm2-monitor.service hang on stop if lvmetad stopped.
Change vgremove to use process_each_lv_in_vg.
Allow lvconvert --repair and --splitmirrors on internal LVs.
Introduce WARN_ flags to control some metadata warning messages.
Use process_each_pv in vgreduce.
Refactor process_each_pv in toollib.
Introduce single validation routine for pool chunk size.
Support --yes like --force in vg/lvremove to skip y|n prompt.
Support --yes with lvconvert --splitsnapshot.
Fix detection of unsupported thin external lvconversions.
Fix detection of unsupported cache and thin pool lvconversions.
Fix detection of unsupported lvconversion of cache to snapshot.
Improve code for creation of cache and cache pool volumes.
Check cluster-wide (not local) active status before removing LV.
Properly check if activation of removed cached LV really activated.
lvremove cached LV removes cachepool (keep with lvconvert --splitcache).
Always remove spare LV with last removed pool volume.
Support lvconvert --splitcache and --uncache of cached LV.
Option --cache has also shortcut -H (i.e. lvcreate -H).
Refactor lvcreate code and better preserve --type argument.
Refactor filter processing around lvmetad.
Refactor process_each_lv in toollib.
Refactor process_each_vg in toollib.
Pools cannot be used as external origin.
Use lv_update_and_reload() for snapshot reload.
Don't print message in adjusted_mirror_region_size() in activation.
Improve lv_update_and_reload() to find out proper lock holding LV.
Improve search of LV in lv_ondisk().
Do not scan sysfs in lv_check_not_in_use() when device is closed.
Backup final metadata after resync of mirror/raid.
Unify handling of --persistent option for lvcreate and lvchange.
Validate major and minor numbers stored in metadata.
Use -fPIE when linking -pie executables.
Support DEBUG_MEMLOCK to trap unsupported mmap usage.
Enable cache segment type by default.
Ensure only supported volume types are used with cache segments.
Fix inablility to specify cachemode when 'lvconvert'ing to cache-pool.
Grab cluster lock for active LVs when setting clustered attribute.
Use va_copy to properly pass va_list through functions.
Add function to detect rotational devices.
Review internal checks for mirror/raid/pvmove volumes.
Track mirror segment type with separate MIRROR flag.
Fix cmirror endian conversions.
Introduce lv_is_pvmove/locked/converting/merging macros.
Avoid leaving linear logical volume when thin pool creation fails.
Don't leak alloc_handle on raid target error path.
Properly validate raid leg names.
Archive metadata before starting their modification in raid target.
Add missing vg_revert() in suspend_lv() raid and snapshot error path.
Add missing backup of lvm2 metadata after some raid modifications.
Use vg memory pool for extent allocation.
Add allocation/physical_extent_size config option for default PE size of VGs.
Demote an error to a warning when devices known to lvmetad are filtered out.
Re-order filter evaluation, making component filters global.
Fix logic that checks for full scan before iterating through devices.
Introduce common code to modify metadata and reload updated LV.
Fix rename of active snapshot volume in cluster.
Make sure shared libraries are built with RELRO option.
Version 2.02.111 - 1st September 2014
=====================================
Pass properly sized char buffers for sscanf when initializing clvmd.
Reinstate nosync logic when extending mirror. (2.02.110)
Fix total area extent calculation when allocating cache pool. (2.02.110)
Version 2.02.110 - 26th August 2014
===================================
Fix manipulation with thin-pools which are excluded via volume_list.
Support lv/vgremove -ff to remove thin vols from broken/inactive thin pools.
Fix typo breaking configure --with-lvm1=shared.
Modify lvresize code to handle raid/mirrors and physical extents.
Don't allow pvcreate to proceed if scanning or filtering fails.
Cleanly error when creating RAID with stripe size < PAGE_SIZE.
Print name of LV which on activation triggers delayed snapshot merge.
Add lv_layout and lv_role LV reporting fields.
Properly display lvs lv_attr volume type and target type bit for cache origin.
Fix pvcreate_check() to update cache correctly after signature wiping.
Fix primary device lookup failure for partition when processing mpath filter.
If LV inactive and non-clustered, do not issue "Cannot deactivate" on -aln.
Remove spurious "Skipping mirror LV" message on pvmove of clustered mirror.
Version 2.02.109 - 5th August 2014
==================================
Remove lv_volume_type field from reports. (2.02.108)
Fix a segfault in lvscan --cache when devices were already missing. (2.02.108)
Fix incorrect persistent .cache after vgcreate with PV creation. (2.02.108)
Display actual size changed when resizing LV.
Allow approximate allocation with +%FREE in lvextend.
Remove possible spurious "not found" message on PV create before wiping.
Handle upgrade from 2.02.105 when an LV now gaining a uuid suffix is active.
Version 2.02.108 - 23rd July 2014
=================================
Add lvscan --cache which re-scans constituents of a particular LV.
Make dmeventd's RAID plugin re-scan failed PVs when lvmetad is in use.
Improve code sharing for lvconvert and lvcreate and pools (cache & thin).
Improve lvconvert --merge validation.
Improve lvconvert --splitsnapshot validation.
Add report/list_item_separator lvm.conf option.
Add lv_active_{locally,remotely,exclusively} LV reporting fields.
Comment out devices/{preferred_names,filter} in default lvm.conf file.
Enhance lvconvert thin, thinpool, cache and cachepool command line support.
Display 'C' only for cache and cache-pool target types in lvs.
Prompt for confirmation before change LV into a snapshot exception store.
Return proper error codes for some failing lvconvert funtions.
Add initial code to use cache tools (cache_check|dump|repair|restore).
Support lvdisplay --maps for raid.
Add --activationmode degraded to activate degraded raid volumes by default.
Add separate lv_active_{locally,remotely,exclusively} LV reporting fields.
Recognize "auto"/"unmanaged" values in selection for appropriate fields only.
Add report/binary_values_as_numeric lvm.conf option for binary values as 0/1.
Add --binary arg to pvs,vgs,lvs and {pv,vg,lv}display -C for 0/1 on reports.
Add separate reporting fields for each each {pv,vg,lv}_attr bit.
Separate LV device status reporting fields out of LV fields.
Fix regression causing PVs not in VGs to be marked as allocatable (2.02.59).
Fix VG component of lvid in vgsplit/vgmerge and check in vg_validate.
Add lv_full_name, lv_parent and lv_dm_path fields to reports.
Change lv_path field to suppress devices that never appear in /dev/vg.
Postpone thin pool lvconvert prompts (2.02.107).
Require --yes option to skip prompt to lvconvert thin pool chunksize.
Support lvremove -ff to remove thin volumes from broken thin pools.
Require --yes to skip raid repair prompt.
Change makefile %.d generation to handle filename changes without make clean.
Fix use of buildir in make pofile.
Enhance private volumes UUIDs with suffixed for easier detection.
Do not use reserved _[tc]meta volumes for temporary LVs.
Leave backup pool metadata with _meta%d suffix instead of reserved _tmeta%d.
Allow RAID repair to reuse PVs from same image that suffered a failure.
New RAID images now avoid allocation on any PVs in the same parent RAID LV.
Always reevaluate filters just before creating PV.
Version 2.02.107 - 23rd June 2014
=================================
Introduce LCK_ACTIVATION to avoid concurrent activation of basic LV types.

View File

@ -1,3 +1,220 @@
Version 1.02.111 -
====================================
Version 1.02.110 - 30th October 2015
====================================
Disable thin monitoring plugin when it fails too often (>10 times).
Fix/restore parsing of empty field '-' when processing dmeventd event.
Enhance dm_tree_node_size_changed() to recognize size reduction.
Support exit on idle for dmenventd (1 hour).
Add support to allow unmonitor device from plugin itself.
New design for thread co-operation in dmeventd.
Dmeventd read device status with 'noflush'.
Dmeventd closes control device when no device is monitored.
Thin plugin for dmeventd improved percentage usage.
Snapshot plugin for dmeventd improved percentage usage.
Add dm_hold_control_dev to allow holding of control device open.
Add dm_report_compact_given_fields to remove given empty fields from report.
Use libdm status parsing and local mem raid dmeventd plugin.
Use local mem pool and lock only lvm2 execution for mirror dmeventd plugin.
Lock protect only lvm2 execution for snapshot and thin dmeventd plugin.
Use local mempool for raid and mirror plugins.
Reworked thread initialization for dmeventd plugins.
Dmeventd handles snapshot overflow for now equally as invalid.
Convert dmeventd to use common logging macro system from libdm.
Return -ENOMEM when device registration fails instead of 0 (=success).
Enforce writethrough mode for cleaner policy.
Add support for recognition and deactivation of MD devices to blkdeactivate.
Move target status functions out of libdm-deptree.
Correct use of max_write_behind parameter when generating raid target line.
Fix dm-event systemd service to make sure it is executed before mounting.
Version 1.02.109 - 22nd September 2016
======================================
Update man pages for dmsetup and dmstats.
Improve help text for dmsetup.
Use --noflush and --nolockfs when removing device with --force.
Parse new Overflow status string for snapshot target.
Check dir path components are valid if using dm_create_dir, error out if not.
Fix /dev/mapper handling to remove dangling entries if symlinks are found.
Make it possible to use blank value as selection for string list report field.
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 'precise' column to statistics reports.
Add --precise switch to 'dmstats create' to request nanosecond counters.
Add precise argument to dm_stats_create_region().
Add support to libdm-stats for precise_timestamps
Version 1.02.105 - 17th August 2015
===================================
Fix 'dmstats list -o all' segfault.
Separate dmstats statistics fields from region information fields.
Add interval and interval_ns fields to dmstats reports.
Do not include internal glibc headers in libdm-timestamp.c (1.02.104)
Exit immediately if no device is supplied to dmsetup wipe_table.
Suppress dmsetup report headings when no data is output. (1.02.104)
Adjust dmsetup usage/help output selection to match command invoked.
Fix dmsetup -o all to select correct fields in splitname report.
Restructure internal dmsetup argument handling across all commands.
Add dm_report_is_empty() to indicate there is no data awaiting output.
Add more arg validation for dm_tree_node_add_cache_target().
Add --alldevices switch to replace use of --force for stats create / delete.
Version 1.02.104 - 10th August 2015
===================================
Add dmstats.8 man page
Add dmstats --segments switch to create one region per device segment.
Add dmstats --regionid, --allregions to specify a single / all stats regions.
Add dmstats --allprograms for stats commands that filter by program ID.
Add dmstats --auxdata and --programid args to specify aux data and program ID.
Add report stats sub-command to provide repeating stats reports.
Add clear, delete, list, and print stats sub-commands.
Add create stats sub-command and --start, --length, --areas and --areasize.
Recognize 'dmstats' as an alias for 'dmsetup stats' when run with this name.
Add a 'stats' command to dmsetup to configure, manage and report stats data.
Add statistics fields to dmsetup -o.
Add libdm-stats library to allow management of device-mapper statistics.
Add --nosuffix to suppress dmsetup unit suffixes in report output.
Add --units to control dmsetup report field output units.
Add support to redisplay column headings for repeating column reports.
Fix report header and row resource leaks.
Report timestamps of ioctls with dmsetup -vvv.
Recognize report field name variants without any underscores too.
Add dmsetup --interval and --count to repeat reports at specified intervals.
Add dm_timestamp functions to libdevmapper.
Recognise vg/lv name format in dmsetup.
Move size display code to libdevmapper as dm_size_to_string.
Version 1.02.103 - 24th July 2015
=================================
Introduce libdevmapper wrappers for all malloc-related functions.
Version 1.02.102 - 7th July 2015
================================
Include tool.h for default non-library use.
Introduce format macros with embedded % such as FMTu64.
Version 1.02.101 - 3rd July 2015
================================
Add experimental support to passing messages in suspend tree.
Add dm_report_value_cache_{set,get} to support caching during report/select.
Add dm_report_reserved_handler to handle report reserved value actions.
Support dynamic value in select: DM_REPORT_FIELD_RESERVED_VALUE_DYNAMIC_VALUE.
Support fuzzy names in select: DM_REPORT_FIELD_RESERVED_VALUE_FUZZY_NAMES.
Thin pool trace messages show a device name and major:minor.
Version 1.02.100 - 30th June 2015
=================================
Add since, after, until and before time operators to be used in selection.
Add support for time in reports and selection: DM_REPORT_FIELD_TYPE_TIME.
Support report reserved value ranges: DM_REPORT_FIELD_RESERVED_VALUE_RANGE.
Support report reserved value names: DM_REPORT_FIELD_RESERVED_VALUE_NAMED.
Add DM_CONFIG_VALUE_FMT_{INT_OCTAL,STRING_NO_QUOTES} config value format flag.
Add DM_CONFIG_VALUE_FMT_COMMON_{ARRAY,EXTRA_SPACE} config value format flag.
Add dm_config_value_{get,set}_format_flags to get and set config value format.
Version 1.02.99 - 20th June 2015
================================
New dm_tree_node_set_thin_pool_read_only(DM_1_02_99) for read-only thin pool.
Enhance error message when thin-pool message fails.
Fix dmeventd logging to avoid threaded use of static variable.
Remove redundant dmeventd SIGALRM coded.
Version 1.02.98 - 12th June 2015
================================
Add dm_task_get_errno() to return any unexpected errno from a dm ioctl call.
Use copy of errno made after each dm ioctl call in case errno changes later.
Version 1.02.97 - 15th May 2015
===============================
New dm_task_get_info(DM_1_02_97) supports internal_suspend state.
New symbols are versioned and comes with versioned symbol name (DM_1_02_97).
Version 1.02.96 - 2nd May 2015
==============================
Fix selection to not match if using reserved value in criteria with >,<,>=,<.
Fix selection to not match reserved values for size fields if using >,<,>=,<.
Include uuid or device number in log message after ioctl failure.
Add DM_INTERNAL_SUSPEND_FLAG to dm-ioctl.h.
Install blkdeactivate script and its man page with make install_device-mapper.
Version 1.02.95 - 15th March 2015
=================================
Makefile regenerated.
Version 1.02.94 - 4th March 2015
================================
Add dm_report_object_is_selected for generalized interface for report/select.
Version 1.02.93 - 21st January 2015
===================================
Reduce severity of ioctl error message when dmeventd waitevent is interrupted.
Report 'unknown version' when incompatible version numbers were not obtained.
Report more info from thin pool status (out of data, metadata-ro, fail).
Support error_if_no_space for thin pool target.
Fix segfault while using selection with regex and unbuffered reporting.
Add dm_report_compact_fields to remove empty fields from report output.
Remove unimplemented dm_report_set_output_selection from libdevmapper.h.
Version 1.02.92 - 24th November 2014
====================================
Fix memory corruption with sorting empty string lists (1.02.86).
Fix man dmsetup.8 syntax warning of Groff
Accept unquoted strings and / in place of {} when parsing configs.
Version 1.02.91 - 11th November 2014
====================================
Update cache creation and dm_config_node to pass policy.
Allow activation of any thin-pool if transaction_id supplied is 0.
Don't print uninitialized stack bytes when non-root uses dm_check_version().
Fix selection criteria to not match reserved values when using >, <, >=, <.
Add DM_LIST_HEAD_INIT macro to libdevmapper.h.
Fix dm_is_dm_major to not issue error about missing /proc lines for dm module.
Version 1.02.90 - 1st September 2014
====================================
Restore proper buffer size for parsing mountinfo line (1.02.89)
Version 1.02.89 - 26th August 2014
==================================
Improve libdevmapper-event select() error handling.
Add extra check for matching transation_id after message submitting.
Add dm_report_field_string_list_unsorted for str. list report without sorting.
Support --deferred with dmsetup remove to defer removal of open devices.
Update dm-ioctl.h to include DM_DEFERRED_REMOVE flag.
Add support for selection to match string list subset, recognize { } operator.
Fix string list selection with '[value]' to not match list that's superset.
Fix string list selection to match whole words only, not prefixes.
Version 1.02.88 - 5th August 2014
=================================
Add dm_tree_set_optional_uuid_suffixes to handle upgrades.
Version 1.02.87 - 23rd July 2014
================================
Fix dm_report_field_string_list to handle delimiter with multiple chars.
Add dm_report_field_reserved_value for per-field reserved value definition.
Version 1.02.86 - 23rd June 2014
================================
Make "help" and "?" reporting fields implicit.

View File

@ -37,6 +37,10 @@ AC_DEFUN([AC_TRY_CCFLAG],
fi
])
dnl AC_IF_YES([TEST-FOR-YES], [ACTION-IF-TRUE], [ACTION-IF-FALSE])
dnl AS_IF() abstraction, checks shell variable for 'yes'
AC_DEFUN([AC_IF_YES], [AS_IF([test $$1 = yes], [$2], [$3])])
dnl AC_TRY_LDFLAGS([LDFLAGS], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
dnl check if $CC supports given ld flags

6
aclocal.m4 vendored
View File

@ -1,6 +1,6 @@
# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
# generated automatically by aclocal 1.15 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996-2014 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
@ -15,7 +15,7 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
# Copyright © 2004 Scott James Remnant <scott@netsplit.com>.
# Copyright (c) 2004 Scott James Remnant <scott@netsplit.com>.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by

6
conf/.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
command_profile_template.profile
example.conf
lvmlocal.conf
metadata_profile_template.profile
configure.h
lvm-version.h

View File

@ -1,5 +1,5 @@
#
# 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.
#
@ -17,24 +17,41 @@ top_builddir = @top_builddir@
CONFSRC=example.conf
CONFDEST=lvm.conf
CONFLOCAL=lvmlocal.conf
PROFILE_TEMPLATES=command_profile_template.profile metadata_profile_template.profile
PROFILES=$(PROFILE_TEMPLATES) $(srcdir)/thin-generic.profile $(srcdir)/thin-performance.profile
PROFILES=$(PROFILE_TEMPLATES) \
$(srcdir)/cache-mq.profile \
$(srcdir)/cache-smq.profile \
$(srcdir)/thin-generic.profile \
$(srcdir)/thin-performance.profile
include $(top_builddir)/make.tmpl
.PHONY: install_conf install_localconf install_profiles
generate:
(cat $(top_srcdir)/conf/example.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withcomments --ignorelocal --withspaces) > example.conf.in
(cat $(top_srcdir)/conf/lvmlocal.conf.base && LD_LIBRARY_PATH=$(top_builddir)/libdm:$(LD_LIBRARY_PATH) $(top_builddir)/tools/lvm dumpconfig --type default --unconfigured --withcomments --withspaces local) > lvmlocal.conf.in
install_conf: $(CONFSRC)
@if [ ! -e $(confdir)/$(CONFDEST) ]; then \
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST)"; \
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFDEST); \
fi
install_localconf: $(CONFLOCAL)
@if [ ! -e $(confdir)/$(CONFLOCAL) ]; then \
echo "$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL)"; \
$(INSTALL_WDATA) -D $< $(confdir)/$(CONFLOCAL); \
fi
install_profiles: $(PROFILES)
$(INSTALL_DIR) $(DESTDIR)$(DEFAULT_PROFILE_DIR)
$(INSTALL_DATA) $(PROFILES) $(DESTDIR)$(DEFAULT_PROFILE_DIR)/
install_lvm2: install_conf install_profiles
install_lvm2: install_conf install_localconf install_profiles
install: install_lvm2
DISTCLEAN_TARGETS += $(CONFSRC) $(PROFILE_TEMPLATES)
DISTCLEAN_TARGETS += $(CONFSRC) $(CONFLOCAL) $(PROFILE_TEMPLATES)

20
conf/cache-mq.profile Normal file
View File

@ -0,0 +1,20 @@
# Demo configuration 'mq' cache policy
#
# Note: This policy has been deprecated in favor of the smq policy
# keyword "default" means, setting is left with kernel defaults.
#
allocation {
cache_pool_chunk_size = 64
cache_mode = "writethrough"
cache_policy = "mq"
cache_settings {
mq {
sequential_threshold = "default" # #nr_sequential_ios
random_threshold = "default" # #nr_random_ios
read_promote_adjustment = "default"
write_promote_adjustment = "default"
discard_promote_adjustment = "default"
}
}
}

14
conf/cache-smq.profile Normal file
View File

@ -0,0 +1,14 @@
# Demo configuration 'smq' cache policy
#
# The stochastic multi-queue (smq) policy addresses some of the problems
# with the multiqueue (mq) policy and uses less memory.
#
allocation {
cache_pool_chunk_size = 64
cache_mode = "writethrough"
cache_policy = "smq"
cache_settings {
# currently no settins for "smq" policy
}
}

View File

@ -18,13 +18,16 @@ global {
lvdisplay_shows_full_device_path=0
}
report {
compact_output=0
aligned=1
buffered=1
headings=1
separator=" "
list_item_separator=","
prefixes=0
quoted=1
colums_as_rows=0
binary_values_as_numeric=0
devtypes_sort="devtype_name"
devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"

23
conf/example.conf.base Normal file
View File

@ -0,0 +1,23 @@
# This is an example configuration file for the LVM2 system.
# It contains the default settings that would be used if there was no
# @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Refer to 'man lvm.conf' for further information including the file layout.
#
# Refer to 'man lvm.conf' for information about how settings configured in
# this file are combined with built-in values and command line options to
# arrive at the final values used by LVM.
#
# Refer to 'man lvmconfig' for information about displaying the built-in
# and configured values used by LVM.
#
# If a default value is set in this file (not commented out), then a
# new version of LVM using this file will continue using that value,
# even if the new version of LVM changes the built-in default value.
#
# To put this file in a different directory and override @DEFAULT_SYS_DIR@ set
# the environment variable LVM_SYSTEM_DIR before running the tools.
#
# N.B. Take care that each setting only appears once if uncommenting
# example settings in this file.

File diff suppressed because it is too large Load Diff

19
conf/lvmlocal.conf.base Normal file
View File

@ -0,0 +1,19 @@
# This is a local configuration file template for the LVM2 system
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
#
# Refer to 'man lvm.conf' for information about the file layout.
#
# To put this file in a different directory and override
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
# running the tools.
#
# The lvmlocal.conf file is normally expected to contain only the
# "local" section which contains settings that should not be shared or
# repeated among different hosts. (But if other sections are present,
# they *will* get processed. Settings in this file override equivalent
# ones in lvm.conf and are in turn overridden by ones in any enabled
# lvm_<tag>.conf files.)
#
# Please take care that each setting only appears once if uncommenting
# example settings in this file and never copy this file between hosts.

56
conf/lvmlocal.conf.in Normal file
View File

@ -0,0 +1,56 @@
# This is a local configuration file template for the LVM2 system
# which should be installed as @DEFAULT_SYS_DIR@/lvmlocal.conf .
#
# Refer to 'man lvm.conf' for information about the file layout.
#
# To put this file in a different directory and override
# @DEFAULT_SYS_DIR@ set the environment variable LVM_SYSTEM_DIR before
# running the tools.
#
# The lvmlocal.conf file is normally expected to contain only the
# "local" section which contains settings that should not be shared or
# repeated among different hosts. (But if other sections are present,
# they *will* get processed. Settings in this file override equivalent
# ones in lvm.conf and are in turn overridden by ones in any enabled
# lvm_<tag>.conf files.)
#
# Please take care that each setting only appears once if uncommenting
# example settings in this file and never copy this file between hosts.
# Configuration section local.
# LVM settings that are specific to the local host.
local {
# Configuration option local/system_id.
# Defines the local system ID for lvmlocal mode.
# This is used when global/system_id_source is set to 'lvmlocal' in the
# main configuration file, e.g. lvm.conf. When used, it must be set to
# a unique value among all hosts sharing access to the storage,
# e.g. a host name.
#
# Example
# Set no system ID:
# system_id = ""
# Set the system_id to a specific name:
# system_id = "host1"
#
# This configuration option has an automatic default value.
# system_id = ""
# Configuration option local/extra_system_ids.
# A list of extra VG system IDs the local host can access.
# VGs with the system IDs listed here (in addition to the host's own
# system ID) can be fully accessed by the local host. (These are
# system IDs that the host sees in VGs, not system IDs that identify
# the local host, which is determined by system_id_source.)
# Use this only after consulting 'man lvmsystemid' to be certain of
# correct usage and possible dangers.
# This configuration option does not have a default value defined.
# Configuration option local/host_id.
# The lvmlockd sanlock host_id.
# This must be unique among all hosts, and must be between 1 and 2000.
# This configuration option has an automatic default value.
# host_id = 0
}

View File

@ -16,7 +16,7 @@ allocation {
thin_pool_zero=1
thin_pool_discards="passdown"
thin_pool_chunk_size_policy="generic"
# thin_pool_chunk_size=64
# thin_pool_chunk_size=128
}
activation {
thin_pool_autoextend_threshold=100

2649
configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@ -15,7 +15,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
.PHONY: dmeventd clvmd cmirrord lvmetad
.PHONY: dmeventd clvmd cmirrord lvmetad lvmpolld lvmlockd
ifneq ("@CLVMD@", "none")
SUBDIRS += clvmd
@ -36,8 +36,16 @@ ifeq ("@BUILD_LVMETAD@", "yes")
SUBDIRS += lvmetad
endif
ifeq ("@BUILD_LVMPOLLD@", "yes")
SUBDIRS += lvmpolld
endif
ifeq ("@BUILD_LVMLOCKD@", "yes")
SUBDIRS += lvmlockd
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = clvmd cmirrord dmeventd lvmetad
SUBDIRS = clvmd cmirrord dmeventd lvmetad lvmpolld lvmlockd
endif
include $(top_builddir)/make.tmpl

1
daemons/clvmd/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
clvmd

View File

@ -36,10 +36,6 @@ SOURCES = \
lvm-functions.c \
refresh_clvmd.c
ifeq ("@DEBUG@", "yes")
DEFS += -DDEBUG
endif
ifneq (,$(findstring cman,, "@CLVMD@,"))
SOURCES += clvmd-cman.c
LMLIBS += $(CMAN_LIBS) $(CONFDB_LIBS) $(DLM_LIBS)

View File

@ -110,12 +110,12 @@ static void _cluster_init_completed(void)
clvmd_cluster_init_completed();
}
static int _get_main_cluster_fd()
static int _get_main_cluster_fd(void)
{
return cman_get_fd(c_handle);
}
static int _get_num_nodes()
static int _get_num_nodes(void)
{
int i;
int nnodes = 0;
@ -243,7 +243,7 @@ static void _add_up_node(const char *csid)
DEBUGLOG("Added new node %d to updown list\n", nodeid);
}
static void _cluster_closedown()
static void _cluster_closedown(void)
{
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cman_finish(c_handle);
@ -282,7 +282,7 @@ static void count_clvmds_running(void)
}
/* Get a list of active cluster members */
static void get_members()
static void get_members(void)
{
int retnodes;
int status;
@ -380,7 +380,7 @@ static int nodeid_from_csid(const char *csid)
return nodeid;
}
static int _is_quorate()
static int _is_quorate(void)
{
return cman_is_quorate(c_handle);
}

View File

@ -323,6 +323,7 @@ void cmd_client_cleanup(struct local_client *client)
int lkid;
char *lockname;
DEBUGLOG("Client thread cleanup (%p)\n", client);
if (!client->bits.localsock.private)
return;
@ -331,7 +332,7 @@ void cmd_client_cleanup(struct local_client *client)
dm_hash_iterate(v, lock_hash) {
lkid = (int)(long)dm_hash_get_data(lock_hash, v);
lockname = dm_hash_get_key(lock_hash, v);
DEBUGLOG("cleanup: Unlocking lock %s %x\n", lockname, lkid);
DEBUGLOG("Cleanup (%p): Unlocking lock %s %x\n", client, lockname, lkid);
(void) sync_unlock(lockname, lkid);
}
@ -339,7 +340,6 @@ void cmd_client_cleanup(struct local_client *client)
client->bits.localsock.private = NULL;
}
static int restart_clvmd(void)
{
const char **argv;

View File

@ -18,15 +18,10 @@
#ifndef _LVM_CLVMD_COMMON_H
#define _LVM_CLVMD_COMMON_H
#include "configure.h"
#define _REENTRANT
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "libdevmapper.h"
#include "tool.h"
#include "lvm-logging.h"
#include <unistd.h>
#endif

View File

@ -243,7 +243,7 @@ static void openais_cpg_confchg_callback(cpg_handle_t handle,
struct node_info *ninfo;
DEBUGLOG("confchg callback. %" PRIsize_t " joined, "
"%" PRIsize_t " left, %" PRIsize_t " members\n",
FMTsize_t " left, %" PRIsize_t " members\n",
joined_list_entries, left_list_entries, member_list_entries);
for (i=0; i<joined_list_entries; i++) {

View File

@ -208,8 +208,6 @@ static int _lock_resource(const char *resource, int mode, int flags, int *lockid
pthread_mutex_lock(&_lock_mutex);
retry:
pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
if (!(head = dm_hash_lookup(_locks, resource))) {
if (flags & LCKF_CONVERT) {
/* In real DLM, lock is identified only by lockid, resource is not used */
@ -269,12 +267,14 @@ retry:
dm_list_add(head, &lck->list);
}
out:
pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Locked resource %s, lockid=%d, mode=%s\n",
resource, lck->lockid, _get_mode(lck->mode));
return 0;
bad:
pthread_cond_broadcast(&_lock_cond); /* to wakeup waiters */
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Failed to lock resource %s\n", resource);

View File

@ -153,16 +153,11 @@ static if_type_t get_cluster_type(void);
static void usage(const char *prog, FILE *file)
{
fprintf(file, "Usage: %s [options]\n"
" -V Show version of clvmd\n"
" -h Show this help information\n"
" -d[n] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
" -f Don't fork, run in the foreground\n"
" -E<lockuuid> Take this lock uuid as exclusively locked resource (for restart)\n"
" -R Tell all running clvmds in the cluster to reload their device cache\n"
" -S Restart clvmd, preserving exclusive locks\n"
" -C Sets debug level (from -d) on all clvmd instances clusterwide\n"
" -t<secs> Command timeout (default 60 seconds)\n"
" -T<secs> Startup timeout (default none)\n"
" -d[<n>] Set debug logging (0:none, 1:stderr (implies -f option), 2:syslog)\n"
" -E<uuid> Take this lock uuid as exclusively locked resource (for restart)\n"
" -f Don't fork, run in the foreground\n"
" -h Show this help information\n"
" -I<cmgr> Cluster manager (default: auto)\n"
" Available cluster managers: "
#ifdef USE_COROSYNC
@ -177,6 +172,12 @@ static void usage(const char *prog, FILE *file)
#ifdef USE_SINGLENODE
"singlenode "
#endif
"\n"
" -R Tell all running clvmds in the cluster to reload their device cache\n"
" -S Restart clvmd, preserving exclusive locks\n"
" -t<secs> Command timeout (default: 60 seconds)\n"
" -T<secs> Startup timeout (default: 0 seconds)\n"
" -V Show version of clvmd\n"
"\n", prog);
}
@ -222,6 +223,7 @@ void debuglog(const char *fmt, ...)
fprintf(stderr, "CLVMD[%x]: %.15s ", (int)pthread_self(), ctime_r(&P, buf_ctime) + 4);
vfprintf(stderr, fmt, ap);
va_end(ap);
fflush(stderr);
break;
case DEBUG_SYSLOG:
if (!syslog_init) {
@ -597,7 +599,9 @@ int main(int argc, char *argv[])
/* This needs to be started after cluster initialisation
as it may need to take out locks */
DEBUGLOG("starting LVM thread\n");
DEBUGLOG("Starting LVM thread\n");
DEBUGLOG("Main cluster socket fd %d (%p) with local socket %d (%p)\n",
local_client_head.fd, &local_client_head, newfd->fd, newfd);
/* Don't let anyone else to do work until we are started */
pthread_create(&lvm_thread, &stack_attr, lvm_thread_fn, &lvm_params);
@ -697,7 +701,7 @@ static int local_rendezvous_callback(struct local_client *thisfd, char *buf,
newfd->type = LOCAL_SOCK;
newfd->callback = local_sock_callback;
newfd->bits.localsock.all_success = 1;
DEBUGLOG("Got new connection on fd %d\n", newfd->fd);
DEBUGLOG("Got new connection on fd %d (%p)\n", newfd->fd, newfd);
*new_client = newfd;
}
return 1;
@ -849,18 +853,48 @@ static void main_loop(int cmd_timeout)
struct local_client *thisfd;
struct timeval tv = { cmd_timeout, 0 };
int quorate = clops->is_quorate();
int client_count = 0;
int max_fd = 0;
struct local_client *lastfd = &local_client_head;
struct local_client *nextfd = local_client_head.next;
/* Wait on the cluster FD and all local sockets/pipes */
local_client_head.fd = clops->get_main_cluster_fd();
FD_ZERO(&in);
for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
client_count++;
max_fd = max(max_fd, thisfd->fd);
}
if (max_fd > FD_SETSIZE - 32) {
fprintf(stderr, "WARNING: There are too many connections to clvmd. Investigate and take action now!\n");
fprintf(stderr, "WARNING: Your cluster may freeze up if the number of clvmd file descriptors (%d) exceeds %d.\n", max_fd + 1, FD_SETSIZE);
}
for (thisfd = &local_client_head; thisfd; thisfd = nextfd, nextfd = thisfd ? thisfd->next : NULL) {
if (thisfd->removeme && !cleanup_zombie(thisfd)) {
struct local_client *free_fd = thisfd;
lastfd->next = nextfd;
DEBUGLOG("removeme set for %p with %d monitored fds remaining\n", free_fd, client_count - 1);
/* Queue cleanup, this also frees the client struct */
add_to_lvmqueue(free_fd, NULL, 0, NULL);
continue;
}
lastfd = thisfd;
if (thisfd->removeme)
continue;
/* if the cluster is not quorate then don't listen for new requests */
if ((thisfd->type != LOCAL_RENDEZVOUS &&
thisfd->type != LOCAL_SOCK) || quorate)
FD_SET(thisfd->fd, &in);
if (thisfd->fd < FD_SETSIZE)
FD_SET(thisfd->fd, &in);
}
select_status = select(FD_SETSIZE, &in, NULL, NULL, &tv);
@ -876,31 +910,22 @@ static void main_loop(int cmd_timeout)
}
if (select_status > 0) {
struct local_client *lastfd = NULL;
char csid[MAX_CSID_LEN];
char buf[max_cluster_message];
for (thisfd = &local_client_head; thisfd; thisfd = thisfd->next) {
if (thisfd->removeme && !cleanup_zombie(thisfd)) {
struct local_client *free_fd = thisfd;
lastfd->next = thisfd->next;
DEBUGLOG("removeme set for fd %d\n", free_fd->fd);
/* Queue cleanup, this also frees the client struct */
add_to_lvmqueue(free_fd, NULL, 0, NULL);
break;
}
if (FD_ISSET(thisfd->fd, &in)) {
if (thisfd->fd < FD_SETSIZE && FD_ISSET(thisfd->fd, &in)) {
struct local_client *newfd = NULL;
int ret;
/* FIXME Remove from main thread in case it blocks! */
/* Do callback */
ret = thisfd->callback(thisfd, buf, sizeof(buf),
csid, &newfd);
/* Ignore EAGAIN */
if (ret < 0 && (errno == EAGAIN || errno == EINTR))
if (ret < 0 && (errno == EAGAIN || errno == EINTR)) {
continue;
}
/* Got error or EOF: Remove it from the list safely */
if (ret <= 0) {
@ -914,17 +939,16 @@ static void main_loop(int cmd_timeout)
DEBUGLOG("ret == %d, errno = %d. removing client\n",
ret, errno);
thisfd->removeme = 1;
break;
continue;
}
/* New client...simply add it to the list */
if (newfd) {
newfd->next = thisfd->next;
thisfd->next = newfd;
break;
thisfd = newfd;
}
}
lastfd = thisfd;
}
}
@ -1128,7 +1152,7 @@ static void dump_message(char *buf, int len)
row[j] = buf[i];
str[j] = (isprint(buf[i])) ? buf[i] : ' ';
if ((j == 8) || (i + 1 == len)) {
if (i + 1 == len) {
for (;j < 8; ++j) {
row[j] = 0;
str[j] = ' ';
@ -1417,7 +1441,7 @@ static int read_from_local_sock(struct local_client *thisfd)
thisfd->bits.localsock.in_progress = TRUE;
thisfd->bits.localsock.state = PRE_COMMAND;
thisfd->bits.localsock.cleanup_needed = 1;
DEBUGLOG("Creating pre&post thread\n");
DEBUGLOG("Creating pre&post thread for pipe fd %d (%p)\n", newfd->fd, newfd);
status = pthread_create(&thisfd->bits.localsock.threadid,
&stack_attr, pre_and_post_thread, thisfd);
DEBUGLOG("Created pre&post thread, state = %d\n", status);
@ -1671,7 +1695,7 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
sigset_t ss;
int pipe_fd = client->bits.localsock.pipe;
DEBUGLOG("Pre&post thread (%p), pipe %d\n", client, pipe_fd);
DEBUGLOG("Pre&post thread (%p), pipe fd %d\n", client, pipe_fd);
pthread_mutex_lock(&client->bits.localsock.mutex);
/* Ignore SIGUSR1 (handled by master process) but enable
@ -1691,7 +1715,7 @@ static __attribute__ ((noreturn)) void *pre_and_post_thread(void *arg)
if ((status = do_pre_command(client)))
client->bits.localsock.all_success = 0;
DEBUGLOG("Pre&post thread (%p) writes status %d down to pipe %d\n",
DEBUGLOG("Pre&post thread (%p) writes status %d down to pipe fd %d\n",
client, status, pipe_fd);
/* Tell the parent process we have finished this bit */
@ -1973,7 +1997,7 @@ static int process_work_item(struct lvm_thread_cmd *cmd)
{
/* If msg is NULL then this is a cleanup request */
if (cmd->msg == NULL) {
DEBUGLOG("process_work_item: free fd %d\n", cmd->client->fd);
DEBUGLOG("process_work_item: free %p\n", cmd->client);
cmd_client_cleanup(cmd->client);
pthread_mutex_destroy(&cmd->client->bits.localsock.mutex);
pthread_cond_destroy(&cmd->client->bits.localsock.cond);

View File

@ -136,7 +136,7 @@ static const char *decode_flags(unsigned char flags)
flags & LCK_DMEVENTD_MONITOR_MODE ? "DMEVENTD_MONITOR|" : "",
flags & LCK_ORIGIN_ONLY_MODE ? "ORIGIN_ONLY|" : "",
flags & LCK_TEST_MODE ? "TEST|" : "",
flags & LCK_CONVERT ? "CONVERT|" : "",
flags & LCK_CONVERT_MODE ? "CONVERT|" : "",
flags & LCK_DMEVENTD_MONITOR_IGNORE ? "DMEVENTD_MONITOR_IGNORE|" : "",
flags & LCK_REVERT_MODE ? "REVERT|" : "");
@ -375,7 +375,7 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
* of exclusive lock to shared one during activation.
*/
if (!test_mode() && command & LCK_CLUSTER_VG) {
status = hold_lock(resource, mode, LCKF_NOQUEUE | (lock_flags & LCK_CONVERT ? LCKF_CONVERT:0));
status = hold_lock(resource, mode, LCKF_NOQUEUE | ((lock_flags & LCK_CONVERT_MODE) ? LCKF_CONVERT:0));
if (status) {
/* Return an LVM-sensible error for this.
* Forcing EIO makes the upper level return this text
@ -510,7 +510,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
DEBUGLOG("do_lock_lv: resource '%s', cmd = %s, flags = %s, critical_section = %d\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags), critical_section());
if (!cmd->config_initialized || config_files_changed(cmd)) {
if (!cmd->initialized.config || config_files_changed(cmd)) {
/* Reinitialise various settings inc. logging, filters */
if (do_refresh_cache()) {
log_error("Updated config file invalid. Aborting.");
@ -725,7 +725,7 @@ void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
static int get_initial_state(struct dm_hash_table *excl_uuid)
{
int lock_mode;
char lv[64], vg[64], flags[25], vg_flags[25];
char lv[65], vg[65], flags[26], vg_flags[26]; /* with space for '\0' */
char uuid[65];
char line[255];
char *lvs_cmd;
@ -842,7 +842,7 @@ void lvm_do_backup(const char *vgname)
pthread_mutex_lock(&lvm_lock);
vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, 1, &consistent);
vg = vg_read_internal(cmd, vgname, NULL /*vgid*/, WARN_PV_READ, &consistent);
if (vg && consistent)
check_current_backup(vg);
@ -899,7 +899,7 @@ int init_clvm(struct dm_hash_table *excl_uuid)
if (!get_initial_state(excl_uuid))
log_error("Cannot load initial lock states.");
if (!(cmd = create_toolcontext(1, NULL, 0, 1))) {
if (!(cmd = create_toolcontext(1, NULL, 0, 1, 1, 1))) {
log_error("Failed to allocate command context");
return 0;
}

1
daemons/cmirrord/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
cmirrord

View File

@ -15,6 +15,7 @@
#include "link_mon.h"
#include "local.h"
#include <getopt.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/socket.h>
@ -32,14 +33,49 @@ static void daemonize(void);
static void init_all(void);
static void cleanup_all(void);
int main(int argc __attribute__((unused)), char *argv[] __attribute__((unused)))
static void usage (FILE *dest)
{
daemonize();
fprintf (dest, "Usage: cmirrord [options]\n"
" -f, --foreground stay in the foreground, log to the terminal\n"
" -h, --help print this help\n");
}
int main(int argc, char *argv[])
{
int foreground_mode = 0;
struct option longopts[] = {
{ "foreground", no_argument, NULL, 'f' },
{ "help" , no_argument, NULL, 'h' },
{ 0, 0, 0, 0 }
};
int opt;
while ((opt = getopt_long (argc, argv, "fh", longopts, NULL)) != -1) {
switch (opt) {
case 'f':
foreground_mode = 1;
break;
case 'h':
usage (stdout);
exit (0);
default:
usage (stderr);
exit (2);
}
}
if (optind < argc) {
usage (stderr);
exit (2);
}
if (!foreground_mode)
daemonize();
init_all();
/* Parent can now exit, we're ready to handle requests */
kill(getppid(), SIGTERM);
if (!foreground_mode)
kill(getppid(), SIGTERM);
LOG_PRINT("Starting cmirrord:");
LOG_PRINT(" Built: "__DATE__" "__TIME__"\n");
@ -209,6 +245,16 @@ static void daemonize(void)
}
LOG_OPEN("cmirrord", LOG_PID, LOG_DAEMON);
}
/*
* init_all
*
* Initialize modules. Exit on failure.
*/
static void init_all(void)
{
int r;
(void) dm_prepare_selinux_context(CMIRRORD_PIDFILE, S_IFREG);
if (dm_create_lockfile(CMIRRORD_PIDFILE) == 0)
@ -227,16 +273,6 @@ static void daemonize(void)
signal(SIGUSR2, &sig_handler);
sigemptyset(&signal_mask);
signal_received = 0;
}
/*
* init_all
*
* Initialize modules. Exit on failure.
*/
static void init_all(void)
{
int r;
if ((r = init_local()) ||
(r = init_cluster())) {

View File

@ -104,10 +104,11 @@ static SaVersionT version = { 'B', 1, 1 };
#endif
#define DEBUGGING_HISTORY 100
#define DEBUGGING_BUFLEN 128
#define LOG_SPRINT(cc, f, arg...) do { \
cc->idx++; \
cc->idx = cc->idx % DEBUGGING_HISTORY; \
sprintf(cc->debugging[cc->idx], f, ## arg); \
snprintf(cc->debugging[cc->idx], DEBUGGING_BUFLEN, f, ## arg); \
} while (0)
static int log_resp_rec = 0;
@ -150,7 +151,7 @@ struct clog_cpg {
uint32_t checkpoint_requesters[MAX_CHECKPOINT_REQUESTERS];
struct checkpoint_data *checkpoint_list;
int idx;
char debugging[DEBUGGING_HISTORY][128];
char debugging[DEBUGGING_HISTORY][DEBUGGING_BUFLEN];
};
static struct dm_list clog_cpg_list;
@ -1294,7 +1295,9 @@ static void cpg_join_callback(struct clog_cpg *match,
uint32_t my_pid = (uint32_t)getpid();
uint32_t lowest = match->lowest_id;
struct clog_request *rq;
char dbuf[32] = { 0 };
char dbuf[64] = { 0 };
char *dbuf_p = dbuf;
size_t dbuf_rem = sizeof dbuf;
/* Assign my_cluster_id */
if ((my_cluster_id == 0xDEAD) && (joined->pid == my_pid))
@ -1310,9 +1313,17 @@ static void cpg_join_callback(struct clog_cpg *match,
if (joined->nodeid == my_cluster_id)
goto out;
for (i = 0; i < member_list_entries - 1; i++)
sprintf(dbuf+strlen(dbuf), "%u-", member_list[i].nodeid);
sprintf(dbuf+strlen(dbuf), "(%u)", joined->nodeid);
for (i = 0; i < member_list_entries - 1; i++) {
int written = snprintf(dbuf_p, dbuf_rem, "%u-", member_list[i].nodeid);
if (written < 0) continue; /* impossible */
if ((unsigned)written >= dbuf_rem) {
dbuf_rem = 0;
break;
}
dbuf_rem -= written;
dbuf_p += written;
}
snprintf(dbuf_p, dbuf_rem, "(%u)", joined->nodeid);
LOG_COND(log_checkpoint, "[%s] Joining node, %u needs checkpoint [%s]",
SHORT_UUID(match->name.value), joined->nodeid, dbuf);

View File

@ -126,13 +126,14 @@ static int v5_endian_to_network(struct clog_request *rq)
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate64(u_rq->data_size);
rq->originator = xlate32(rq->originator);
v5_data_endian_switch(rq, 1);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate32(u_rq->data_size);
return size;
}
@ -167,7 +168,7 @@ static int v5_endian_from_network(struct clog_request *rq)
u_rq->error = xlate32(u_rq->error);
u_rq->seq = xlate32(u_rq->seq);
u_rq->request_type = xlate32(u_rq->request_type);
u_rq->data_size = xlate64(u_rq->data_size);
u_rq->data_size = xlate32(u_rq->data_size);
rq->originator = xlate32(rq->originator);
@ -182,12 +183,11 @@ int clog_request_from_network(void *data, size_t data_len)
{
uint64_t *vp = data;
uint64_t version = xlate64(vp[0]);
uint64_t unconverted_version = vp[1];
struct clog_request *rq = data;
switch (version) {
case 5: /* Upstream */
if (version == unconverted_version)
if (version == vp[0])
return 0;
break;
case 4: /* RHEL 5.[45] */

View File

@ -32,12 +32,13 @@
#define LOG_OFFSET 2
#define RESYNC_HISTORY 50
#define RESYNC_BUFLEN 128
//static char resync_history[RESYNC_HISTORY][128];
//static int idx = 0;
#define LOG_SPRINT(_lc, f, arg...) do { \
lc->idx++; \
lc->idx = lc->idx % RESYNC_HISTORY; \
sprintf(lc->resync_history[lc->idx], f, ## arg); \
snprintf(lc->resync_history[lc->idx], RESYNC_BUFLEN, f, ## arg); \
} while (0)
struct log_header {
@ -88,7 +89,7 @@ struct log_c {
size_t disk_size; /* size of disk_buffer in bytes */
void *disk_buffer; /* aligned memory for O_DIRECT */
int idx;
char resync_history[RESYNC_HISTORY][128];
char resync_history[RESYNC_HISTORY][RESYNC_BUFLEN];
};
struct mark_entry {
@ -1444,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;
}
@ -1507,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;
}

1
daemons/dmeventd/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
dmeventd

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
@ -12,23 +12,22 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "dm-logging.h"
#include "dmlib.h"
#include "libdevmapper-event.h"
//#include "libmultilog.h"
#include "dmeventd.h"
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/wait.h>
#include <arpa/inet.h> /* for htonl, ntohl */
#include <pthread.h>
#include <syslog.h>
static int _debug_level = 0;
static int _use_syslog = 0;
static int _sequence_nr = 0;
struct dm_event_handler {
@ -199,7 +198,7 @@ static int _check_message_id(struct dm_event_daemon_message *msg)
if ((sscanf(msg->data, "%d:%d", &pid, &seq_nr) != 2) ||
(pid != getpid()) || (seq_nr != _sequence_nr)) {
log_error("Ignoring out-of-sequence reply from dmeventd. "
"Expected %d:%d but received %s", getpid(),
"Expected %d:%d but received %s.", getpid(),
_sequence_nr, msg->data);
return 0;
}
@ -234,7 +233,7 @@ static int _daemon_read(struct dm_event_fifos *fifos,
FD_SET(fifos->server, &fds);
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
if (ret < 0 && errno != EINTR) {
log_error("Unable to read from event server");
log_error("Unable to read from event server.");
return 0;
}
if ((ret == 0) && (i > 4) && !bytes) {
@ -297,13 +296,21 @@ static int _daemon_write(struct dm_event_fifos *fifos,
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
if ((ret < 0) && (errno != EINTR)) {
log_error("Unable to talk to event daemon");
if (ret < 0) {
if (errno == EINTR)
continue;
log_error("Unable to talk to event daemon.");
return 0;
}
if (ret == 0)
break;
ret = read(fifos->server, drainbuf, sizeof(drainbuf));
if (ret < 0) {
if ((errno == EINTR) || (errno == EAGAIN))
continue;
log_error("Unable to talk to event daemon.");
return 0;
}
}
while (bytes < size) {
@ -313,7 +320,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
FD_SET(fifos->client, &fds);
ret = select(fifos->client + 1, NULL, &fds, NULL, NULL);
if ((ret < 0) && (errno != EINTR)) {
log_error("Unable to talk to event daemon");
log_error("Unable to talk to event daemon.");
return 0;
}
} while (ret < 1);
@ -323,7 +330,7 @@ static int _daemon_write(struct dm_event_fifos *fifos,
if ((errno == EINTR) || (errno == EAGAIN))
continue;
else {
log_error("Unable to talk to event daemon");
log_error("Unable to talk to event daemon.");
return 0;
}
}
@ -353,7 +360,7 @@ int daemon_talk(struct dm_event_fifos *fifos,
getpid(), _sequence_nr,
dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
< 0) {
log_error("_daemon_talk: message allocation failed");
log_error("_daemon_talk: message allocation failed.");
return -ENOMEM;
}
msg->cmd = cmd;
@ -441,11 +448,11 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
else if (!pid) {
execvp(args[0], args);
log_error("Unable to exec dmeventd: %s", strerror(errno));
log_error("Unable to exec dmeventd: %s.", strerror(errno));
_exit(EXIT_FAILURE);
} else {
if (waitpid(pid, &status, 0) < 0)
log_error("Unable to start dmeventd: %s",
log_error("Unable to start dmeventd: %s.",
strerror(errno));
else if (WEXITSTATUS(status))
log_error("Unable to start dmeventd.");
@ -518,7 +525,7 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
struct dm_info info;
if (!(dmt = dm_task_create(DM_DEVICE_INFO))) {
log_error("_get_device_info: dm_task creation for info failed");
log_error("_get_device_info: dm_task creation for info failed.");
return NULL;
}
@ -536,17 +543,17 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
/* FIXME Add name or uuid or devno to messages */
if (!dm_task_run(dmt)) {
log_error("_get_device_info: dm_task_run() failed");
log_error("_get_device_info: dm_task_run() failed.");
goto bad;
}
if (!dm_task_get_info(dmt, &info)) {
log_error("_get_device_info: failed to get info for device");
log_error("_get_device_info: failed to get info for device.");
goto bad;
}
if (!info.exists) {
log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found",
log_error("_get_device_info: %s%s%s%.0d%s%.0d%s%s: device not found.",
dmevh->uuid ? : "",
(!dmevh->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
@ -615,12 +622,12 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
!strstr(dmevh->dso, "libdevmapper-event-lvm2snapshot.so") &&
!strstr(dmevh->dso, "libdevmapper-event-lvm2mirror.so") &&
!strstr(dmevh->dso, "libdevmapper-event-lvm2raid.so"))
log_warn("WARNING: %s: dmeventd plugins are deprecated", dmevh->dso);
log_warn("WARNING: %s: dmeventd plugins are deprecated.", dmevh->dso);
if ((err = _do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
log_error("%s: event registration failed: %s",
log_error("%s: event registration failed: %s.",
dm_task_get_name(dmt),
msg.data ? msg.data : strerror(-err));
ret = 0;
@ -647,7 +654,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
if ((err = _do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, dmevh->dmeventd_path, &msg,
dmevh->dso, uuid, dmevh->mask, dmevh->timeout)) < 0) {
log_error("%s: event deregistration failed: %s",
log_error("%s: event deregistration failed: %s.",
dm_task_get_name(dmt),
msg.data ? msg.data : strerror(-err));
ret = 0;
@ -820,6 +827,79 @@ int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
return 1;
}
void dm_event_log_set(int debug_level, int use_syslog)
{
_debug_level = debug_level;
_use_syslog = use_syslog;
}
void dm_event_log(const char *subsys, int level, const char *file,
int line, int dm_errno_or_class,
const char *format, va_list ap)
{
static pthread_mutex_t _log_mutex = PTHREAD_MUTEX_INITIALIZER;
static time_t start = 0;
const char *indent = "";
FILE *stream = stdout;
int prio = -1;
time_t now;
switch (level & ~(_LOG_STDERR | _LOG_ONCE)) {
case _LOG_DEBUG:
if (_debug_level < 3)
return;
prio = LOG_DEBUG;
indent = " ";
break;
case _LOG_INFO:
if (_debug_level < 2)
return;
prio = LOG_INFO;
indent = " ";
break;
case _LOG_NOTICE:
if (_debug_level < 1)
return;
prio = LOG_NOTICE;
indent = " ";
break;
case _LOG_WARN:
prio = LOG_WARNING;
break;
case _LOG_ERR:
prio = LOG_ERR;
stream = stderr;
break;
default:
prio = LOG_CRIT;
}
/* Serialize to keep lines readable */
pthread_mutex_lock(&_log_mutex);
if (_use_syslog) {
vsyslog(prio, format, ap);
} else {
now = time(NULL);
if (!start)
start = now;
now -= start;
fprintf(stream, "[%2d:%02d] %8x:%-6s%s",
(int)now / 60, (int)now % 60,
// TODO: Maybe use shorter ID
// ((int)(pthread_self()) >> 6) & 0xffff,
(int)pthread_self(), subsys,
(_debug_level > 3) ? "" : indent);
if (_debug_level > 3)
fprintf(stream, "%28s:%4d %s", file, line, indent);
vfprintf(stream, _(format), ap);
fputc('\n', stream);
fflush(stream);
}
pthread_mutex_unlock(&_log_mutex);
}
#if 0 /* left out for now */
static char *_skip_string(char *src, const int delimiter)
@ -853,7 +933,7 @@ int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
0, 0))) {
char *p = _skip_string(msg.data, ' ');
if (!p) {
log_error("malformed reply from dmeventd '%s'\n",
log_error("Malformed reply from dmeventd '%s'.",
msg.data);
dm_free(msg.data);
return -EIO;

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2007 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of the device-mapper userspace tools.
*
@ -105,6 +105,25 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next);
int dm_event_register_handler(const struct dm_event_handler *dmevh);
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
/* Set debug level for logging, and whether to log on stdout/stderr or syslog */
void dm_event_log_set(int debug_level, int use_syslog);
/* Log messages acroding to current debug level */
__attribute__((format(printf, 6, 0)))
void dm_event_log(const char *subsys, int level, const char *file,
int line, int dm_errno_or_class,
const char *format, va_list ap);
/* Macro to route print_log do dm_event_log() */
#define DM_EVENT_LOG_FN(subsys) \
void print_log(int level, const char *file, int line, int dm_errno_or_class,\
const char *format, ...)\
{\
va_list ap;\
va_start(ap, format);\
dm_event_log(subsys, level, file, line, dm_errno_or_class, format, ap);\
va_end(ap);\
}
/* Prototypes for DSO interface, see dmeventd.c, struct dso_data for
detailed descriptions. */
// FIXME misuse of bitmask as enum

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -13,15 +13,11 @@
*/
#include "lib.h"
#include "log.h"
#include "lvm2cmd.h"
#include "dmeventd_lvm.h"
#include "libdevmapper-event.h"
#include "lvm2cmd.h"
#include <pthread.h>
#include <syslog.h>
extern int dmeventd_debug;
/*
* register_device() is called first and performs initialisation.
@ -36,48 +32,19 @@ static int _register_count = 0;
static struct dm_pool *_mem_pool = NULL;
static void *_lvm_handle = NULL;
DM_EVENT_LOG_FN("lvm")
static void _lvm2_print_log(int level, const char *file, int line,
int dm_errno_or_class, const char *msg)
{
print_log(level, file, line, dm_errno_or_class, "%s", msg);
}
/*
* Currently only one event can be processed at a time.
*/
static pthread_mutex_t _event_mutex = PTHREAD_MUTEX_INITIALIZER;
/*
* FIXME Do not pass things directly to syslog, rather use the existing logging
* facilities to sort logging ... however that mechanism needs to be somehow
* configurable and we don't have that option yet
*/
static void _temporary_log_fn(int level,
const char *file __attribute__((unused)),
int line __attribute__((unused)),
int dm_errno __attribute__((unused)),
const char *message)
{
level &= ~(_LOG_STDERR | _LOG_ONCE);
switch (level) {
case _LOG_DEBUG:
if (dmeventd_debug >= 3)
syslog(LOG_DEBUG, "%s", message);
break;
case _LOG_INFO:
if (dmeventd_debug >= 2)
syslog(LOG_INFO, "%s", message);
break;
case _LOG_NOTICE:
if (dmeventd_debug >= 1)
syslog(LOG_NOTICE, "%s", message);
break;
case _LOG_WARN:
syslog(LOG_WARNING, "%s", message);
break;
case _LOG_ERR:
syslog(LOG_ERR, "%s", message);
break;
default:
syslog(LOG_CRIT, "%s", message);
}
}
void dmeventd_lvm2_lock(void)
{
pthread_mutex_lock(&_event_mutex);
@ -94,23 +61,26 @@ 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) {
lvm2_log_fn(_temporary_log_fn);
if (!(_lvm_handle = lvm2_init())) {
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_log_fn(_lvm2_print_log);
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");
log_debug("lvm plugin initilized.");
}
_register_count++;
@ -126,11 +96,13 @@ void dmeventd_lvm2_exit(void)
pthread_mutex_lock(&_register_mutex);
if (!--_register_count) {
log_debug("lvm plugin shuting down.");
lvm2_run(_lvm_handle, "_memlock_dec");
dm_pool_destroy(_mem_pool);
_mem_pool = NULL;
lvm2_exit(_lvm_handle);
_lvm_handle = NULL;
log_debug("lvm plugin exited.");
}
pthread_mutex_unlock(&_register_mutex);
@ -153,8 +125,8 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
int r;
if (!dm_split_lvm_name(mem, device, &vg, &lv, &layer)) {
syslog(LOG_ERR, "Unable to determine VG name from %s.\n",
device);
log_error("Unable to determine VG name from %s.",
device);
return 0;
}
@ -168,7 +140,7 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
dm_pool_free(mem, vg);
if (r < 0) {
syslog(LOG_ERR, "Unable to form LVM command. (too long).\n");
log_error("Unable to form LVM command. (too long).");
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2010 Red Hat, Inc. All rights reserved.
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -39,4 +39,36 @@ struct dm_pool *dmeventd_lvm2_pool(void);
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
const char *cmd, const char *device);
#define dmeventd_lvm2_run_with_lock(cmdline) \
({\
int rc;\
dmeventd_lvm2_lock();\
rc = dmeventd_lvm2_run(cmdline);\
dmeventd_lvm2_unlock();\
rc;\
})
#define dmeventd_lvm2_init_with_pool(name, st) \
({\
struct dm_pool *mem;\
st = NULL;\
if (dmeventd_lvm2_init()) {\
if ((mem = dm_pool_create(name, 2048)) &&\
(st = dm_pool_zalloc(mem, sizeof(*st))))\
st->mem = mem;\
else {\
if (mem)\
dm_pool_destroy(mem);\
dmeventd_lvm2_exit();\
}\
}\
st;\
})
#define dmeventd_lvm2_exit_with_pool(pool) \
do {\
dm_pool_destroy(pool->mem);\
dmeventd_lvm2_exit();\
} while(0)
#endif /* _DMEVENTD_LVMWRAP_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -13,20 +13,24 @@
*/
#include "lib.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include "defaults.h"
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
/* FIXME Reformat to 80 char lines. */
#define ME_IGNORE 0
#define ME_INSYNC 1
#define ME_FAILURE 2
struct dso_state {
struct dm_pool *mem;
char cmd_lvscan[512];
char cmd_lvconvert[512];
};
DM_EVENT_LOG_FN("mirr")
static int _process_status_code(const char status_code, const char *dev_name,
const char *dev_type, int r)
{
@ -39,18 +43,15 @@ static int _process_status_code(const char status_code, const char *dev_name,
* U => Unclassified failure (bug)
*/
if (status_code == 'F') {
syslog(LOG_ERR, "%s device %s flush failed.",
dev_type, dev_name);
log_error("%s device %s flush failed.", dev_type, dev_name);
r = ME_FAILURE;
} else if (status_code == 'S')
syslog(LOG_ERR, "%s device %s sync failed.",
dev_type, dev_name);
log_error("%s device %s sync failed.", dev_type, dev_name);
else if (status_code == 'R')
syslog(LOG_ERR, "%s device %s read failed.",
dev_type, dev_name);
log_error("%s device %s read failed.", dev_type, dev_name);
else if (status_code != 'A') {
syslog(LOG_ERR, "%s device %s has failed (%c).",
dev_type, dev_name, status_code);
log_error("%s device %s has failed (%c).",
dev_type, dev_name, status_code);
r = ME_FAILURE;
}
@ -125,52 +126,49 @@ out:
out_parse:
dm_free(args);
syslog(LOG_ERR, "Unable to parse mirror status string.");
log_error("Unable to parse mirror status string.");
return ME_IGNORE;
}
static int _remove_failed_devices(const char *device)
static int _remove_failed_devices(const char *cmd_lvscan, const char *cmd_lvconvert)
{
int r;
#define CMD_SIZE 256 /* FIXME Use system restriction */
char cmd_str[CMD_SIZE];
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
return -ENAMETOOLONG; /* FIXME Replace with generic error return - reason for failure has already got logged */
if (!dmeventd_lvm2_run_with_lock(cmd_lvscan))
log_info("Re-scan of mirrored device failed.");
r = dmeventd_lvm2_run(cmd_str);
/* if repair goes OK, report success even if lvscan has failed */
r = dmeventd_lvm2_run_with_lock(cmd_lvconvert);
syslog(LOG_INFO, "Repair of mirrored device %s %s.", device,
(r) ? "finished successfully" : "failed");
log_info("Repair of mirrored device %s.",
(r) ? "finished successfully" : "failed");
return (r) ? 0 : -1;
return r;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **unused __attribute__((unused)))
void **user)
{
struct dso_state *state = *user;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
const char *device = dm_task_get_name(dmt);
dmeventd_lvm2_lock();
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type) {
syslog(LOG_INFO, "%s mapping lost.", device);
log_info("%s mapping lost.", device);
continue;
}
if (strcmp(target_type, "mirror")) {
syslog(LOG_INFO, "%s has unmirrored portion.", device);
log_info("%s has unmirrored portion.", device);
continue;
}
@ -180,54 +178,75 @@ void process_event(struct dm_task *dmt,
_part_ of the device is in sync
Also, this is not an error
*/
syslog(LOG_NOTICE, "%s is now in-sync.", device);
log_notice("%s is now in-sync.", device);
break;
case ME_FAILURE:
syslog(LOG_ERR, "Device failure in %s.", device);
if (_remove_failed_devices(device))
log_error("Device failure in %s.", device);
if (!_remove_failed_devices(state->cmd_lvscan,
state->cmd_lvconvert))
/* FIXME Why are all the error return codes unused? Get rid of them? */
syslog(LOG_ERR, "Failed to remove faulty devices in %s.",
device);
log_error("Failed to remove faulty devices in %s.",
device);
/* Should check before warning user that device is now linear
else
syslog(LOG_NOTICE, "%s is now a linear device.\n",
device);
log_notice("%s is now a linear device.",
device);
*/
break;
case ME_IGNORE:
break;
default:
/* FIXME Provide value then! */
syslog(LOG_INFO, "Unknown event received.");
log_info("Unknown event received.");
}
} while (next);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
void **user)
{
if (!dmeventd_lvm2_init())
return 0;
struct dso_state *state;
syslog(LOG_INFO, "Monitoring mirror device %s for events.", device);
if (!dmeventd_lvm2_init_with_pool("mirror_state", state))
goto_bad;
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
"lvscan --cache", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
*user = state;
log_info("Monitoring mirror device %s for events.", device);
return 1;
bad:
log_error("Failed to monitor mirror %s.", device);
return 0;
}
int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
void **user)
{
syslog(LOG_INFO, "No longer monitoring mirror device %s for events.",
device);
dmeventd_lvm2_exit();
struct dso_state *state = *user;
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring mirror device %s for events.",
device);
return 1;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2005-2011 Red Hat, Inc. All rights reserved.
* Copyright (C) 2005-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -13,158 +13,133 @@
*/
#include "lib.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include "libdevmapper-event.h"
struct dso_state {
struct dm_pool *mem;
char cmd_lvscan[512];
char cmd_lvconvert[512];
int failed;
};
DM_EVENT_LOG_FN("raid")
#include <syslog.h> /* FIXME Replace syslog with multilog */
/* FIXME Missing openlog? */
/* FIXME Replace most syslogs with log_error() style messages and add complete context. */
/* FIXME Reformat to 80 char lines. */
/*
* run_repair is a close copy to
* plugins/mirror/dmeventd_mirror.c:_remove_failed_devices()
*/
static int run_repair(const char *device)
static int _process_raid_event(struct dso_state *state, char *params, const char *device)
{
int r;
#define CMD_SIZE 256 /* FIXME Use system restriction */
char cmd_str[CMD_SIZE];
struct dm_status_raid *status;
const char *d;
if (!dmeventd_lvm2_command(dmeventd_lvm2_pool(), cmd_str, sizeof(cmd_str),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device))
return -1;
r = dmeventd_lvm2_run(cmd_str);
if (!r)
syslog(LOG_INFO, "Repair of RAID device %s failed.", device);
return (r) ? 0 : -1;
}
static int _process_raid_event(char *params, const char *device)
{
int i, n, failure = 0;
char *p, *a[4];
char *raid_type;
char *num_devices;
char *health_chars;
char *resync_ratio;
/*
* RAID parms: <raid_type> <#raid_disks> \
* <health chars> <resync ratio>
*/
if (!dm_split_words(params, 4, 0, a)) {
syslog(LOG_ERR, "Failed to process status line for %s\n",
device);
return -EINVAL;
}
raid_type = a[0];
num_devices = a[1];
health_chars = a[2];
resync_ratio = a[3];
if (!(n = atoi(num_devices))) {
syslog(LOG_ERR, "Failed to parse number of devices for %s: %s",
device, num_devices);
return -EINVAL;
if (!dm_get_status_raid(state->mem, params, &status)) {
log_error("Failed to process status line for %s.", device);
return 0;
}
for (i = 0; i < n; i++) {
switch (health_chars[i]) {
case 'A':
/* Device is 'A'live and well */
case 'a':
/* Device is 'a'live, but not yet in-sync */
break;
case 'D':
syslog(LOG_ERR,
"Device #%d of %s array, %s, has failed.",
i, raid_type, device);
failure++;
break;
default:
/* Unhandled character returned from kernel */
break;
if ((d = strchr(status->dev_health, 'D'))) {
if (state->failed)
goto out; /* already reported */
log_error("Device #%d of %s array, %s, has failed.",
(int)(d - status->dev_health),
status->raid_type, device);
state->failed = 1;
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvscan))
log_warn("WARNING: Re-scan of RAID device %s failed.", device);
/* if repair goes OK, report success even if lvscan has failed */
if (!dmeventd_lvm2_run_with_lock(state->cmd_lvconvert)) {
log_info("Repair of RAID device %s failed.", device);
dm_pool_free(state->mem, status);
return 0;
}
if (failure)
return run_repair(device);
} else {
state->failed = 0;
log_info("%s array, %s, is %s in-sync.",
status->raid_type, device,
(status->insync_regions == status->total_regions) ? "now" : "not");
}
out:
dm_pool_free(state->mem, status);
p = strstr(resync_ratio, "/");
if (!p) {
syslog(LOG_ERR, "Failed to parse resync_ratio for %s: %s",
device, resync_ratio);
return -EINVAL;
}
p[0] = '\0';
syslog(LOG_INFO, "%s array, %s, is %s in-sync.",
raid_type, device, strcmp(resync_ratio, p+1) ? "not" : "now");
return 0;
return 1;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **unused __attribute__((unused)))
void **user)
{
struct dso_state *state = *user;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
const char *device = dm_task_get_name(dmt);
dmeventd_lvm2_lock();
do {
next = dm_get_next_target(dmt, next, &start, &length,
&target_type, &params);
if (!target_type) {
syslog(LOG_INFO, "%s mapping lost.", device);
log_info("%s mapping lost.", device);
continue;
}
if (strcmp(target_type, "raid")) {
syslog(LOG_INFO, "%s has non-raid portion.", device);
log_info("%s has non-raid portion.", device);
continue;
}
if (_process_raid_event(params, device))
syslog(LOG_ERR, "Failed to process event for %s",
device);
if (!_process_raid_event(state, params, device))
log_error("Failed to process event for %s.",
device);
} while (next);
dmeventd_lvm2_unlock();
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
void **user)
{
if (!dmeventd_lvm2_init())
return 0;
struct dso_state *state;
syslog(LOG_INFO, "Monitoring RAID device %s for events.", device);
if (!dmeventd_lvm2_init_with_pool("raid_state", state))
goto_bad;
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvscan, sizeof(state->cmd_lvscan),
"lvscan --cache", device) ||
!dmeventd_lvm2_command(state->mem, state->cmd_lvconvert, sizeof(state->cmd_lvconvert),
"lvconvert --config devices{ignore_suspended_devices=1} "
"--repair --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
*user = state;
log_info("Monitoring RAID device %s for events.", device);
return 1;
bad:
log_error("Failed to monitor RAID %s.", device);
return 0;
}
int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **unused __attribute__((unused)))
void **user)
{
syslog(LOG_INFO, "No longer monitoring RAID device %s for events.",
device);
dmeventd_lvm2_exit();
struct dso_state *state = *user;
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring RAID device %s for events.",
device);
return 1;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2007-2011 Red Hat, Inc. All rights reserved.
* Copyright (C) 2007-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -13,31 +13,31 @@
*/
#include "lib.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include "libdevmapper-event.h"
#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#include <stdarg.h>
/* FIXME Missing openlog? */
#include <pthread.h>
/* First warning when snapshot is 80% full. */
#define WARNING_THRESH 80
#define WARNING_THRESH (DM_PERCENT_1 * 80)
/* Run a check every 5%. */
#define CHECK_STEP 5
#define CHECK_STEP (DM_PERCENT_1 * 5)
/* Do not bother checking snapshots less than 50% full. */
#define CHECK_MINIMUM 50
#define CHECK_MINIMUM (DM_PERCENT_1 * 50)
#define UMOUNT_COMMAND "/bin/umount"
struct dso_state {
struct dm_pool *mem;
int percent_check;
dm_percent_t percent_check;
uint64_t known_size;
char cmd_str[1024];
char cmd_lvextend[512];
};
DM_EVENT_LOG_FN("snap")
static int _run(const char *cmd, ...)
{
va_list ap;
@ -62,7 +62,7 @@ static int _run(const char *cmd, ...)
va_end(ap);
execvp(cmd, (char **)argv);
syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
log_sys_error("exec", cmd);
exit(127);
}
@ -81,18 +81,56 @@ static int _run(const char *cmd, ...)
static int _extend(const char *cmd)
{
return dmeventd_lvm2_run(cmd);
log_debug("Extending snapshot via %s.", cmd);
return dmeventd_lvm2_run_with_lock(cmd);
}
#ifdef SNAPSHOT_REMOVE
/* Remove invalid snapshot from dm-table */
/* Experimental for now and not used by default */
static int _remove(const char *uuid)
{
int r = 1;
uint32_t cookie = 0;
struct dm_task *dmt;
if (!(dmt = dm_task_create(DM_DEVICE_REMOVE)))
return 0;
if (!dm_task_set_uuid(dmt, uuid)) {
r = 0;
goto_out;
}
dm_task_retry_remove(dmt);
if (!dm_task_set_cookie(dmt, &cookie, 0)) {
r = 0;
goto_out;
}
if (!dm_task_run(dmt)) {
r = 0;
goto_out;
}
out:
dm_task_destroy(dmt);
return r;
}
#endif /* SNAPSHOT_REMOVE */
static void _umount(const char *device, int major, int minor)
{
FILE *mounts;
char buffer[4096];
char *words[3];
struct stat st;
const char procmounts[] = "/proc/mounts";
if (!(mounts = fopen("/proc/mounts", "r"))) {
syslog(LOG_ERR, "Could not read /proc/mounts. Not umounting %s.\n", device);
if (!(mounts = fopen(procmounts, "r"))) {
log_sys_error("fopen", procmounts);
log_error("Not umounting %s.", device);
return;
}
@ -112,21 +150,22 @@ static void _umount(const char *device, int major, int minor)
if (S_ISBLK(st.st_mode) &&
major(st.st_rdev) == major &&
minor(st.st_rdev) == minor) {
syslog(LOG_ERR, "Unmounting invalid snapshot %s from %s.\n", device, words[1]);
if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
syslog(LOG_ERR, "Failed to umount snapshot %s from %s: %s.\n",
device, words[1], strerror(errno));
log_error("Unmounting invalid snapshot %s from %s.", device, words[1]);
if (!_run(UMOUNT_COMMAND, "-fl", words[1], NULL))
log_error("Failed to umount snapshot %s from %s: %s.",
device, words[1], strerror(errno));
}
}
if (fclose(mounts))
syslog(LOG_ERR, "Failed to close /proc/mounts.\n");
log_sys_error("close", procmounts);
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **private)
void **user)
{
struct dso_state *state = *user;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
@ -134,28 +173,47 @@ void process_event(struct dm_task *dmt,
struct dm_status_snapshot *status = NULL;
const char *device = dm_task_get_name(dmt);
int percent;
struct dso_state *state = *private;
struct dm_info info;
/* No longer monitoring, waiting for remove */
if (!state->percent_check)
return;
dmeventd_lvm2_lock();
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type)
goto out;
if (!target_type || strcmp(target_type, "snapshot")) {
log_error("Target %s is not snapshot.", target_type);
return;
}
if (!dm_get_status_snapshot(state->mem, params, &status))
goto out;
if (!dm_get_status_snapshot(state->mem, params, &status)) {
log_error("Cannot parse snapshot %s state: %s.", device, params);
return;
}
if (status->invalid) {
struct dm_info info;
if (dm_task_get_info(dmt, &info)) {
dmeventd_lvm2_unlock();
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (status->invalid || status->overflow || !status->total_sectors) {
log_warn("WARNING: Snapshot %s changed state to: %s and should be removed.",
device, params);
state->percent_check = 0;
if (dm_task_get_info(dmt, &info))
_umount(device, info.major, info.minor);
return;
} /* else; too bad, but this is best-effort thing... */
#ifdef SNAPSHOT_REMOVE
/* Maybe configurable ? */
_remove(dm_task_get_uuid(dmt));
#endif
pthread_kill(pthread_self(), SIGALRM);
goto out;
}
if (length <= (status->used_sectors - status->metadata_sectors)) {
/* TODO eventually recognize earlier when room is enough */
log_info("Dropping monitoring of fully provisioned snapshot %s.",
device);
pthread_kill(pthread_self(), SIGALRM);
goto out;
}
/* Snapshot size had changed. Clear the threshold. */
@ -164,69 +222,50 @@ void process_event(struct dm_task *dmt,
state->known_size = status->total_sectors;
}
/*
* If the snapshot has been invalidated or we failed to parse
* the status string. Report the full status string to syslog.
*/
if (status->invalid || !status->total_sectors) {
syslog(LOG_ERR, "Snapshot %s changed state to: %s\n", device, params);
state->percent_check = 0;
goto out;
}
percent = (int) (100 * status->used_sectors / status->total_sectors);
percent = dm_make_percent(status->used_sectors, status->total_sectors);
if (percent >= state->percent_check) {
/* Usage has raised more than CHECK_STEP since the last
time. Run actions. */
state->percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Snapshot %s is now %i%% full.\n", device, percent);
/* Try to extend the snapshot, in accord with user-set policies */
if (!_extend(state->cmd_str))
syslog(LOG_ERR, "Failed to extend snapshot %s.\n", device);
}
log_warn("WARNING: Snapshot %s is now %.2f%% full.",
device, dm_percent_to_float(percent));
/* Try to extend the snapshot, in accord with user-set policies */
if (!_extend(state->cmd_lvextend))
log_error("Failed to extend snapshot %s.", device);
}
out:
if (status)
dm_pool_free(state->mem, status);
dmeventd_lvm2_unlock();
dm_pool_free(state->mem, status);
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
void **user)
{
struct dm_pool *statemem = NULL;
struct dso_state *state;
if (!dmeventd_lvm2_init())
goto out;
if (!dmeventd_lvm2_init_with_pool("snapshot_state", state))
goto_bad;
if (!(statemem = dm_pool_create("snapshot_state", 512)) ||
!(state = dm_pool_zalloc(statemem, sizeof(*state))))
goto bad;
if (!dmeventd_lvm2_command(state->mem, state->cmd_lvextend,
sizeof(state->cmd_lvextend),
"lvextend --use-policies", device)) {
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
if (!dmeventd_lvm2_command(statemem, state->cmd_str,
sizeof(state->cmd_str),
"lvextend --use-policies", device))
goto bad;
state->mem = statemem;
state->percent_check = CHECK_MINIMUM;
*private = state;
*user = state;
syslog(LOG_INFO, "Monitoring snapshot %s\n", device);
log_info("Monitoring snapshot %s.", device);
return 1;
bad:
if (statemem)
dm_pool_destroy(statemem);
dmeventd_lvm2_exit();
out:
syslog(LOG_ERR, "Failed to monitor snapshot %s.\n", device);
log_error("Failed to monitor snapshot %s.", device);
return 0;
}
@ -235,13 +274,12 @@ int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
void **user)
{
struct dso_state *state = *private;
struct dso_state *state = *user;
syslog(LOG_INFO, "No longer monitoring snapshot %s\n", device);
dm_pool_destroy(state->mem);
dmeventd_lvm2_exit();
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring snapshot %s.", device);
return 1;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2011-2013 Red Hat, Inc. All rights reserved.
* Copyright (C) 2011-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -12,25 +12,33 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lib.h"
#include "libdevmapper-event.h"
#include "lib.h" /* using here lvm log */
#include "dmeventd_lvm.h"
#include "libdevmapper-event.h"
#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#include <stdarg.h>
/* FIXME Missing openlog? */
#include <pthread.h>
/* First warning when thin is 80% full. */
#define WARNING_THRESH 80
/* TODO - move this mountinfo code into library to be reusable */
#ifdef __linux__
# include "kdev_t.h"
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
#endif
/* First warning when thin data or metadata is 80% full. */
#define WARNING_THRESH (DM_PERCENT_1 * 80)
/* Run a check every 5%. */
#define CHECK_STEP 5
/* Do not bother checking thins less than 50% full. */
#define CHECK_MINIMUM 50
#define CHECK_STEP (DM_PERCENT_1 * 5)
/* Do not bother checking thin data or metadata is less than 50% full. */
#define CHECK_MINIMUM (DM_PERCENT_1 * 50)
#define UMOUNT_COMMAND "/bin/umount"
#define MAX_FAILS (10)
#define THIN_DEBUG 0
struct dso_state {
@ -39,18 +47,11 @@ struct dso_state {
int data_percent_check;
uint64_t known_metadata_size;
uint64_t known_data_size;
unsigned fails;
char cmd_str[1024];
};
/* TODO - move this mountinfo code into library to be reusable */
#ifdef __linux__
# include "kdev_t.h"
#else
# define MAJOR(x) major((x))
# define MINOR(x) minor((x))
# define MKDEV(x,y) makedev((x),(y))
#endif
DM_EVENT_LOG_FN("thin")
/* Get dependencies for device, and try to find matching device */
static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_minor)
@ -93,8 +94,8 @@ static int _has_deps(const char *name, int tp_major, int tp_minor, int *dev_mino
{
char dev_name[PATH_MAX];
if (dm_device_get_name(major, minor, 0, dev_name, sizeof(dev_name)))
syslog(LOG_DEBUG, "Found %s (%u:%u) depends on %s",
name, major, *dev_minor, dev_name);
log_debug("Found %s (%u:%u) depends on %s.",
name, major, *dev_minor, dev_name);
}
#endif
r = 1;
@ -141,14 +142,6 @@ out:
return r;
}
static int _extend(struct dso_state *state)
{
#if THIN_DEBUG
syslog(LOG_INFO, "dmeventd executes: %s.\n", state->cmd_str);
#endif
return dmeventd_lvm2_run(state->cmd_str);
}
static int _run(const char *cmd, ...)
{
va_list ap;
@ -168,12 +161,12 @@ static int _run(const char *cmd, ...)
argv = alloca(sizeof(const char *) * (argc + 1));
argv[0] = cmd;
va_start(ap, cmd);
va_start(ap, cmd);
while ((argv[++i] = va_arg(ap, const char *)));
va_end(ap);
execvp(cmd, (char **)argv);
syslog(LOG_ERR, "Failed to execute %s: %s.\n", cmd, strerror(errno));
log_sys_error("exec", cmd);
exit(127);
}
@ -191,9 +184,9 @@ static int _run(const char *cmd, ...)
}
struct mountinfo_s {
const char *device;
struct dm_info info;
dm_bitset_t minors; /* Bitset for active thin pool minors */
const char *device;
};
static int _umount_device(char *buffer, unsigned major, unsigned minor,
@ -202,11 +195,11 @@ static int _umount_device(char *buffer, unsigned major, unsigned minor,
struct mountinfo_s *data = cb_data;
if ((major == data->info.major) && dm_bit(data->minors, minor)) {
syslog(LOG_INFO, "Unmounting thin volume %s from %s.\n",
data->device, target);
log_info("Unmounting thin volume %s from %s.",
data->device, target);
if (!_run(UMOUNT_COMMAND, "-fl", target, NULL))
syslog(LOG_ERR, "Failed to umount thin %s from %s: %s.\n",
data->device, target, strerror(errno));
log_error("Failed to umount thin %s from %s: %s.",
data->device, target, strerror(errno));
}
return 1;
@ -216,78 +209,94 @@ static int _umount_device(char *buffer, unsigned major, unsigned minor,
* Find all thin pool users and try to umount them.
* TODO: work with read-only thin pool support
*/
static void _umount(struct dm_task *dmt, const char *device)
static void _umount(struct dm_task *dmt)
{
/* TODO: Convert to use hash to reduce memory usage */
static const size_t MINORS = (1U << 20); /* 20 bit */
struct mountinfo_s data = {
.device = device,
};
struct mountinfo_s data = { NULL };
if (!dm_task_get_info(dmt, &data.info))
return;
dmeventd_lvm2_unlock();
data.device = dm_task_get_name(dmt);
if (!(data.minors = dm_bitset_create(NULL, MINORS))) {
syslog(LOG_ERR, "Failed to allocate bitset. Not unmounting %s.\n", device);
log_error("Failed to allocate bitset. Not unmounting %s.", data.device);
goto out;
}
if (!_find_all_devs(data.minors, data.info.major, data.info.minor)) {
syslog(LOG_ERR, "Failed to detect mounted volumes for %s.\n", device);
log_error("Failed to detect mounted volumes for %s.", data.device);
goto out;
}
if (!dm_mountinfo_read(_umount_device, &data)) {
syslog(LOG_ERR, "Could not parse mountinfo file.\n");
log_error("Could not parse mountinfo file.");
goto out;
}
out:
if (data.minors)
dm_bitset_destroy(data.minors);
dmeventd_lvm2_lock();
}
static void _use_policy(struct dm_task *dmt, struct dso_state *state)
{
#if THIN_DEBUG
log_info("dmeventd executes: %s.", state->cmd_str);
#endif
if (!dmeventd_lvm2_run_with_lock(state->cmd_str)) {
log_error("Failed to extend thin pool %s.",
dm_task_get_name(dmt));
_umount(dmt);
state->fails++;
} else
state->fails = 0;
}
void process_event(struct dm_task *dmt,
enum dm_event_mask event __attribute__((unused)),
void **private)
void **user)
{
const char *device = dm_task_get_name(dmt);
int percent;
struct dso_state *state = *private;
struct dso_state *state = *user;
struct dm_status_thin_pool *tps = NULL;
void *next = NULL;
uint64_t start, length;
char *target_type = NULL;
char *params;
int needs_policy = 0;
#if 0
/* No longer monitoring, waiting for remove */
if (!state->meta_percent_check && !state->data_percent_check)
return;
#endif
dmeventd_lvm2_lock();
if (event & DM_EVENT_DEVICE_ERROR) {
/* Error -> no need to check and do instant resize */
_use_policy(dmt, state);
goto out;
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!target_type || (strcmp(target_type, "thin-pool") != 0)) {
syslog(LOG_ERR, "Invalid target type.\n");
log_error("Invalid target type.");
goto out;
}
if (!dm_get_status_thin_pool(state->mem, params, &tps)) {
syslog(LOG_ERR, "Failed to parse status.\n");
_umount(dmt, device);
log_error("Failed to parse status.");
_umount(dmt);
goto out;
}
#if THIN_DEBUG
syslog(LOG_INFO, "%p: Got status %" PRIu64 " / %" PRIu64
" %" PRIu64 " / %" PRIu64 ".\n", state,
tps->used_metadata_blocks, tps->total_metadata_blocks,
tps->used_data_blocks, tps->total_data_blocks);
log_debug("Thin pool status " FMTu64 "/" FMTu64 " "
FMTu64 "/" FMTu64 ".",
tps->used_metadata_blocks, tps->total_metadata_blocks,
tps->used_data_blocks, tps->total_data_blocks);
#endif
/* Thin pool size had changed. Clear the threshold. */
@ -301,7 +310,7 @@ void process_event(struct dm_task *dmt,
state->known_data_size = tps->total_data_blocks;
}
percent = 100 * tps->used_metadata_blocks / tps->total_metadata_blocks;
percent = dm_make_percent(tps->used_metadata_blocks, tps->total_metadata_blocks);
if (percent >= state->metadata_percent_check) {
/*
* Usage has raised more than CHECK_STEP since the last
@ -311,18 +320,12 @@ void process_event(struct dm_task *dmt,
/* FIXME: extension of metadata needs to be written! */
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Thin metadata %s is now %i%% full.\n",
device, percent);
/* Try to extend the metadata, in accord with user-set policies */
if (!_extend(state)) {
syslog(LOG_ERR, "Failed to extend thin metadata %s.\n",
device);
_umount(dmt, device);
}
/* FIXME: hmm READ-ONLY switch should happen in error path */
log_warn("WARNING: Thin pool %s metadata is now %.2f%% full.",
device, dm_percent_to_float(percent));
needs_policy = 1;
}
percent = 100 * tps->used_data_blocks / tps->total_data_blocks;
percent = dm_make_percent(tps->used_data_blocks, tps->total_data_blocks);
if (percent >= state->data_percent_check) {
/*
* Usage has raised more than CHECK_STEP since
@ -331,56 +334,53 @@ void process_event(struct dm_task *dmt,
state->data_percent_check = (percent / CHECK_STEP) * CHECK_STEP + CHECK_STEP;
if (percent >= WARNING_THRESH) /* Print a warning to syslog. */
syslog(LOG_WARNING, "Thin %s is now %i%% full.\n", device, percent);
/* Try to extend the thin data, in accord with user-set policies */
if (!_extend(state)) {
syslog(LOG_ERR, "Failed to extend thin %s.\n", device);
state->data_percent_check = 0;
_umount(dmt, device);
}
/* FIXME: hmm READ-ONLY switch should happen in error path */
log_warn("WARNING: Thin pool %s data is now %.2f%% full.",
device, dm_percent_to_float(percent));
needs_policy = 1;
}
if (needs_policy)
_use_policy(dmt, state);
out:
if (tps)
dm_pool_free(state->mem, tps);
dmeventd_lvm2_unlock();
if (state->fails >= MAX_FAILS) {
log_warn("WARNING: Dropping monitoring of %s. "
"lvm2 command fails too often (%u times in raw).",
device, state->fails);
pthread_kill(pthread_self(), SIGALRM);
}
}
int register_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
void **user)
{
struct dm_pool *statemem = NULL;
struct dso_state *state;
if (!dmeventd_lvm2_init())
goto bad;
if (!dmeventd_lvm2_init_with_pool("thin_pool_state", state))
goto_bad;
if (!(statemem = dm_pool_create("thin_pool_state", 2048)) ||
!(state = dm_pool_zalloc(statemem, sizeof(*state))) ||
!dmeventd_lvm2_command(statemem, state->cmd_str,
if (!dmeventd_lvm2_command(state->mem, state->cmd_str,
sizeof(state->cmd_str),
"lvextend --use-policies",
device)) {
if (statemem)
dm_pool_destroy(statemem);
dmeventd_lvm2_exit();
goto bad;
dmeventd_lvm2_exit_with_pool(state);
goto_bad;
}
state->mem = statemem;
state->metadata_percent_check = CHECK_MINIMUM;
state->data_percent_check = CHECK_MINIMUM;
*private = state;
*user = state;
syslog(LOG_INFO, "Monitoring thin %s.\n", device);
log_info("Monitoring thin %s.", device);
return 1;
bad:
syslog(LOG_ERR, "Failed to monitor thin %s.\n", device);
log_error("Failed to monitor thin %s.", device);
return 0;
}
@ -389,13 +389,12 @@ int unregister_device(const char *device,
const char *uuid __attribute__((unused)),
int major __attribute__((unused)),
int minor __attribute__((unused)),
void **private)
void **user)
{
struct dso_state *state = *private;
struct dso_state *state = *user;
syslog(LOG_INFO, "No longer monitoring thin %s.\n", device);
dm_pool_destroy(state->mem);
dmeventd_lvm2_exit();
dmeventd_lvm2_exit_with_pool(state);
log_info("No longer monitoring thin %s.", device);
return 1;
}

2
daemons/lvmetad/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
lvmetad
lvmetactl

View File

@ -18,7 +18,7 @@ top_builddir = @top_builddir@
SOURCES = lvmetad-core.c
SOURCES2 = testclient.c
TARGETS = lvmetad lvmetad-testclient
TARGETS = lvmetad lvmetactl
.PHONY: install_lvmetad
@ -39,8 +39,13 @@ CFLAGS += $(EXTRA_EXEC_CFLAGS)
lvmetad: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
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)", "")

208
daemons/lvmetad/lvmetactl.c Normal file
View File

@ -0,0 +1,208 @@
/*
* Copyright (C) 2014 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*/
#include "tool.h"
#include "lvmetad-client.h"
daemon_handle h;
static void print_reply(daemon_reply reply)
{
const char *a = daemon_reply_str(reply, "response", NULL);
const char *b = daemon_reply_str(reply, "status", NULL);
const char *c = daemon_reply_str(reply, "reason", NULL);
printf("response \"%s\" status \"%s\" reason \"%s\"\n",
a ? a : "", b ? b : "", c ? c : "");
}
int main(int argc, char **argv)
{
daemon_reply reply;
char *cmd;
char *uuid;
char *name;
int val;
int ver;
if (argc < 2) {
printf("lvmetactl dump\n");
printf("lvmetactl pv_list\n");
printf("lvmetactl vg_list\n");
printf("lvmetactl vg_lookup_name <name>\n");
printf("lvmetactl vg_lookup_uuid <uuid>\n");
printf("lvmetactl pv_lookup_uuid <uuid>\n");
printf("lvmetactl set_global_invalid 0|1\n");
printf("lvmetactl get_global_invalid\n");
printf("lvmetactl set_vg_version <uuid> <name> <version>\n");
printf("lvmetactl vg_lock_type <uuid>\n");
return -1;
}
cmd = argv[1];
h = lvmetad_open(NULL);
if (!strcmp(cmd, "dump")) {
reply = daemon_send_simple(h, "dump",
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else if (!strcmp(cmd, "pv_list")) {
reply = daemon_send_simple(h, "pv_list",
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else if (!strcmp(cmd, "vg_list")) {
reply = daemon_send_simple(h, "vg_list",
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else if (!strcmp(cmd, "set_global_invalid")) {
if (argc < 3) {
printf("set_global_invalid 0|1\n");
return -1;
}
val = atoi(argv[2]);
reply = daemon_send_simple(h, "set_global_info",
"global_invalid = %d", val,
"token = %s", "skip",
NULL);
print_reply(reply);
} else if (!strcmp(cmd, "get_global_invalid")) {
reply = daemon_send_simple(h, "get_global_info",
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else if (!strcmp(cmd, "set_vg_version")) {
if (argc < 5) {
printf("set_vg_version <uuid> <name> <ver>\n");
return -1;
}
uuid = argv[2];
name = argv[3];
ver = atoi(argv[4]);
if ((strlen(uuid) == 1) && (uuid[0] == '-'))
uuid = NULL;
if ((strlen(name) == 1) && (name[0] == '-'))
name = NULL;
if (uuid && name) {
reply = daemon_send_simple(h, "set_vg_info",
"uuid = %s", uuid,
"name = %s", name,
"version = %d", ver,
"token = %s", "skip",
NULL);
} else if (uuid) {
reply = daemon_send_simple(h, "set_vg_info",
"uuid = %s", uuid,
"version = %d", ver,
"token = %s", "skip",
NULL);
} else if (name) {
reply = daemon_send_simple(h, "set_vg_info",
"name = %s", name,
"version = %d", ver,
"token = %s", "skip",
NULL);
} else {
printf("name or uuid required\n");
return -1;
}
print_reply(reply);
} else if (!strcmp(cmd, "vg_lookup_name")) {
if (argc < 3) {
printf("vg_lookup_name <name>\n");
return -1;
}
name = argv[2];
reply = daemon_send_simple(h, "vg_lookup",
"name = %s", name,
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else if (!strcmp(cmd, "vg_lookup_uuid")) {
if (argc < 3) {
printf("vg_lookup_uuid <uuid>\n");
return -1;
}
uuid = argv[2];
reply = daemon_send_simple(h, "vg_lookup",
"uuid = %s", uuid,
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else if (!strcmp(cmd, "vg_lock_type")) {
struct dm_config_node *metadata;
const char *lock_type;
if (argc < 3) {
printf("vg_lock_type <uuid>\n");
return -1;
}
uuid = argv[2];
reply = daemon_send_simple(h, "vg_lookup",
"uuid = %s", uuid,
"token = %s", "skip",
NULL);
/* printf("%s\n", reply.buffer.mem); */
metadata = dm_config_find_node(reply.cft->root, "metadata");
if (!metadata) {
printf("no metadata\n");
goto out;
}
lock_type = dm_config_find_str(metadata, "metadata/lock_type", NULL);
if (!lock_type) {
printf("no lock_type\n");
goto out;
}
printf("lock_type %s\n", lock_type);
} else if (!strcmp(cmd, "pv_lookup_uuid")) {
if (argc < 3) {
printf("pv_lookup_uuid <uuid>\n");
return -1;
}
uuid = argv[2];
reply = daemon_send_simple(h, "pv_lookup",
"uuid = %s", uuid,
"token = %s", "skip",
NULL);
printf("%s\n", reply.buffer.mem);
} else {
printf("unknown command\n");
goto out_close;
}
out:
daemon_reply_destroy(reply);
out_close:
daemon_close(h);
return 0;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012 Red Hat, Inc.
* Copyright (C) 2012-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
@ -14,24 +14,117 @@
#define _XOPEN_SOURCE 500 /* pthread */
#include "configure.h"
#define _REENTRANT
#include "tool.h"
#include "daemon-io.h"
#include "config-util.h"
#include "daemon-server.h"
#include "daemon-log.h"
#include "lvm-version.h"
#include <assert.h>
#include <errno.h>
#include <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <math.h> /* fabs() */
#include <float.h> /* DBL_EPSILON */
#define LVMETAD_SOCKET DEFAULT_RUN_DIR "/lvmetad.socket"
/*
* valid/invalid state of cached metadata
*
* Normally when using lvmetad, the state is kept up-to-date through a
* combination of notifications from clients and updates triggered by uevents.
* When using lvmlockd, the lvmetad state is expected to become out of
* date (invalid/stale) when other hosts make changes to the metadata on disk.
*
* To deal with this, the metadata cached in lvmetad can be flagged as invalid.
* This invalid flag is returned along with the metadata when read by a
* command. The command can check for the invalid flag and decide that it
* should either use the stale metadata (uncommon), or read the latest metadata
* from disk rather than using the invalid metadata that was returned. If the
* command reads the latest metadata from disk, it can choose to send it to
* lvmetad to update the cached copy and clear the invalid flag in lvmetad.
* Otherwise, the next command to read the metadata from lvmetad will also
* receive the invalid metadata with the invalid flag (and like the previous
* command, it too may choose to read the latest metadata from disk and can
* then also choose to update the lvmetad copy.)
*
* For purposes of tracking the invalid state, LVM metadata is considered
* to be either VG-specific or global. VG-specific metadata is metadata
* that is isolated to a VG, such as the LVs it contains. Global
* metadata is metadata that is not isolated to a single VG. Global
* metdata includes:
* . the VG namespace (which VG names are used)
* . the set of orphan PVs (which PVs are in VGs and which are not)
* . properties of orphan PVs (the size of an orphan PV)
*
* If the metadata for a single VG becomes invalid, the VGFL_INVALID
* flag can be set in the vg_info struct for that VG. If the global
* metdata becomes invalid, the GLFL_INVALID flag can be set in the
* lvmetad daemon state.
*
* If a command reads VG metadata and VGFL_INVALID is set, an
* extra config node called "vg_invalid" is added to the config
* data returned to the command.
*
* If a command reads global metdata and GLFL_INVALID is set, an
* extra config node called "global_invalid" is added to the
* config data returned to the command.
*
* If a command sees vg_invalid, and wants the latest VG metadata,
* it only needs to scan disks of the PVs in that VG.
* It can then use vg_update to send the latest metadata to lvmetad
* which clears the VGFL_INVALID flag.
*
* If a command sees global_invalid, and wants the latest metadata,
* it should scan all devices to update lvmetad, and then send
* lvmetad the "set_global_info global_invalid=0" message to clear
* GLFL_INVALID.
*
* (When rescanning devices to update lvmetad, the command must use
* the global filter cmd->lvmetad_filter so that it processes the same
* devices that are seen by lvmetad.)
*
* The lvmetad INVALID flags can be set by sending lvmetad the messages:
*
* . set_vg_info with the latest VG seqno. If the VG seqno is larger
* than the cached VG seqno, VGFL_INVALID is set for the VG.
*
* . set_global_info with global_invalid=1 sets GLFL_INVALID.
*
* Different entities could use these functions to invalidate metadata
* if/when they detected that the cache is stale. How they detect that
* the cache is stale depends on the details of the specific entity.
*
* In the case of lvmlockd, it embeds values into its locks to keep track
* of when other nodes have changed metadata on disk related to those locks.
* When acquring locks it can look at these values and detect that
* the metadata associated with the lock has been changed.
* When the values change, it uses set_vg_info/set_global_info to
* invalidate the lvmetad cache.
*
* The values that lvmlockd distributes through its locks are the
* latest VG seqno in VG locks and a global counter in the global lock.
* When a host acquires a VG lock and sees that the embedded seqno is
* larger than it was previously, it knows that it should invalidate the
* lvmetad cache for the VG. If the host acquires the global lock
* and sees that the counter is larger than previously, it knows that
* it should invalidate the global info in lvmetad. This invalidation
* is done before the lock is returned to the command. This way the
* invalid flag will be set on the metadata before the command reads
* it from lvmetad.
*/
struct vg_info {
int64_t external_version;
uint32_t flags; /* VGFL_ */
};
#define GLFL_INVALID 0x00000001
#define VGFL_INVALID 0x00000001
typedef struct {
daemon_idle *idle;
log_state *log; /* convenience */
const char *log_config;
@ -40,6 +133,8 @@ typedef struct {
struct dm_hash_table *vgid_to_metadata;
struct dm_hash_table *vgid_to_vgname;
struct dm_hash_table *vgid_to_outdated_pvs;
struct dm_hash_table *vgid_to_info;
struct dm_hash_table *vgname_to_vgid;
struct dm_hash_table *pvid_to_vgid;
struct {
@ -50,6 +145,7 @@ typedef struct {
pthread_mutex_t pvid_to_vgid;
} lock;
char token[128];
uint32_t flags; /* GLFL_ */
pthread_mutex_t token_lock;
} lvmetad_state;
@ -60,17 +156,19 @@ static void destroy_metadata_hashes(lvmetad_state *s)
dm_hash_iterate(n, s->vgid_to_metadata)
dm_config_destroy(dm_hash_get_data(s->vgid_to_metadata, n));
dm_hash_iterate(n, s->vgid_to_outdated_pvs)
dm_config_destroy(dm_hash_get_data(s->vgid_to_outdated_pvs, n));
dm_hash_iterate(n, s->pvid_to_pvmeta)
dm_config_destroy(dm_hash_get_data(s->pvid_to_pvmeta, n));
dm_hash_destroy(s->pvid_to_pvmeta);
dm_hash_destroy(s->vgid_to_metadata);
dm_hash_destroy(s->vgid_to_vgname);
dm_hash_destroy(s->vgid_to_outdated_pvs);
dm_hash_destroy(s->vgid_to_info);
dm_hash_destroy(s->vgname_to_vgid);
dm_hash_iterate(n, s->device_to_pvid)
dm_free(dm_hash_get_data(s->device_to_pvid, n));
dm_hash_destroy(s->device_to_pvid);
dm_hash_destroy(s->pvid_to_vgid);
}
@ -81,6 +179,8 @@ static void create_metadata_hashes(lvmetad_state *s)
s->device_to_pvid = dm_hash_create(32);
s->vgid_to_metadata = dm_hash_create(32);
s->vgid_to_vgname = dm_hash_create(32);
s->vgid_to_outdated_pvs = dm_hash_create(32);
s->vgid_to_info = dm_hash_create(32);
s->pvid_to_vgid = dm_hash_create(32);
s->vgname_to_vgid = dm_hash_create(32);
}
@ -244,6 +344,30 @@ static int update_pv_status(lvmetad_state *s,
return complete;
}
static struct dm_config_node *add_last_node(struct dm_config_tree *cft, const char *node_name)
{
struct dm_config_node *cn, *last;
cn = cft->root;
last = cn;
while (cn->sib) {
last = cn->sib;
cn = last;
}
cn = dm_config_create_node(cft, node_name);
if (!cn)
return NULL;
cn->v = NULL;
cn->sib = NULL;
cn->parent = cft->root;
last->sib = cn;
return cn;
}
static struct dm_config_node *make_pv_node(lvmetad_state *s, const char *pvid,
struct dm_config_tree *cft,
struct dm_config_node *parent,
@ -307,6 +431,9 @@ static response pv_list(lvmetad_state *s, request r)
cn = make_pv_node(s, id, res.cft, cn_pvs, cn);
}
if (s->flags & GLFL_INVALID)
add_last_node(res.cft, "global_invalid");
unlock_pvid_to_pvmeta(s);
return res;
@ -351,6 +478,9 @@ static response pv_lookup(lvmetad_state *s, request r)
pv->key = "physical_volume";
unlock_pvid_to_pvmeta(s);
if (s->flags & GLFL_INVALID)
add_last_node(res.cft, "global_invalid");
return res;
}
@ -419,14 +549,87 @@ static response vg_list(lvmetad_state *s, request r)
}
unlock_vgid_to_metadata(s);
if (s->flags & GLFL_INVALID)
add_last_node(res.cft, "global_invalid");
bad:
return res;
}
static void mark_outdated_pv(lvmetad_state *s, const char *vgid, const char *pvid)
{
struct dm_config_tree *pvmeta, *outdated_pvs;
struct dm_config_node *list, *cft_vgid;
struct dm_config_value *v;
lock_pvid_to_pvmeta(s);
pvmeta = dm_hash_lookup(s->pvid_to_pvmeta, pvid);
unlock_pvid_to_pvmeta(s);
/* if the MDA exists and is used, it will have ignore=0 set */
if (!pvmeta ||
(dm_config_find_int64(pvmeta->root, "pvmeta/mda0/ignore", 1) &&
dm_config_find_int64(pvmeta->root, "pvmeta/mda1/ignore", 1)))
return;
WARN(s, "PV %s has outdated metadata", pvid);
outdated_pvs = dm_hash_lookup(s->vgid_to_outdated_pvs, vgid);
if (!outdated_pvs) {
if (!(outdated_pvs = dm_config_from_string("outdated_pvs/pv_list = []")) ||
!(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))
abort();
DEBUGLOG(s, "created outdated_pvs list for VG %s", vgid);
}
list = dm_config_find_node(outdated_pvs->root, "outdated_pvs/pv_list");
v = list->v;
while (v) {
if (v->type != DM_CFG_EMPTY_ARRAY && !strcmp(v->v.str, pvid))
return;
v = v->next;
}
if (!(v = dm_config_create_value(outdated_pvs)))
abort();
v->type = DM_CFG_STRING;
v->v.str = dm_pool_strdup(outdated_pvs->mem, pvid);
v->next = list->v;
list->v = v;
}
static void chain_outdated_pvs(lvmetad_state *s, const char *vgid, struct dm_config_tree *metadata_cft, struct dm_config_node *metadata)
{
struct dm_config_tree *cft = dm_hash_lookup(s->vgid_to_outdated_pvs, vgid), *pvmeta;
struct dm_config_node *pv, *res, *out_pvs = cft ? dm_config_find_node(cft->root, "outdated_pvs/pv_list") : NULL;
struct dm_config_value *pvs_v = out_pvs ? out_pvs->v : NULL;
if (!pvs_v)
return;
if (!(res = make_config_node(metadata_cft, "outdated_pvs", metadata_cft->root, 0)))
return; /* oops */
res->sib = metadata->child;
metadata->child = res;
for (; pvs_v && pvs_v->type != DM_CFG_EMPTY_ARRAY; pvs_v = pvs_v->next) {
pvmeta = dm_hash_lookup(s->pvid_to_pvmeta, pvs_v->v.str);
if (!pvmeta) {
WARN(s, "metadata for PV %s not found", pvs_v->v.str);
continue;
}
if (!(pv = dm_config_clone_node(metadata_cft, pvmeta->root, 0)))
continue;
pv->key = dm_config_find_str(pv, "pvmeta/id", NULL);
pv->sib = res->child;
res->child = pv;
}
}
static response vg_lookup(lvmetad_state *s, request r)
{
struct dm_config_tree *cft;
struct dm_config_node *metadata, *n;
struct vg_info *info;
response res = { 0 };
const char *uuid = daemon_request_str(r, "uuid", NULL);
@ -489,6 +692,17 @@ static response vg_lookup(lvmetad_state *s, request r)
unlock_vg(s, uuid);
update_pv_status(s, res.cft, n, 1); /* FIXME report errors */
chain_outdated_pvs(s, uuid, res.cft, n);
if (s->flags & GLFL_INVALID)
add_last_node(res.cft, "global_invalid");
info = dm_hash_lookup(s->vgid_to_info, uuid);
if (info && (info->flags & VGFL_INVALID)) {
n = add_last_node(res.cft, "vg_invalid");
if (!n)
goto bad;
}
return res;
bad:
@ -496,65 +710,13 @@ bad:
return reply_fail("out of memory");
}
/* Test if the doubles are close enough to be considered equal */
static int close_enough(double d1, double d2)
{
return fabs(d1 - d2) < DBL_EPSILON;
}
static int compare_value(struct dm_config_value *a, struct dm_config_value *b)
{
int r = 0;
if (a->type > b->type)
return 1;
if (a->type < b->type)
return -1;
switch (a->type) {
case DM_CFG_STRING: r = strcmp(a->v.str, b->v.str); break;
case DM_CFG_FLOAT: r = close_enough(a->v.f, b->v.f) ? 0 : (a->v.f > b->v.f) ? 1 : -1; break;
case DM_CFG_INT: r = (a->v.i == b->v.i) ? 0 : (a->v.i > b->v.i) ? 1 : -1; break;
case DM_CFG_EMPTY_ARRAY: return 0;
}
if (r == 0 && a->next && b->next)
r = compare_value(a->next, b->next);
return r;
}
static int compare_config(struct dm_config_node *a, struct dm_config_node *b)
{
int result = 0;
if (a->v && b->v)
result = compare_value(a->v, b->v);
if (a->v && !b->v)
result = 1;
if (!a->v && b->v)
result = -1;
if (a->child && b->child)
result = compare_config(a->child, b->child);
if (result) {
// DEBUGLOG("config inequality at %s / %s", a->key, b->key);
return result;
}
if (a->sib && b->sib)
result = compare_config(a->sib, b->sib);
if (a->sib && !b->sib)
result = 1;
if (!a->sib && b->sib)
result = -1;
return result;
}
static int vg_remove_if_missing(lvmetad_state *s, const char *vgid, int update_pvids);
enum update_pvid_mode { UPDATE_ONLY, REMOVE_EMPTY, MARK_OUTDATED };
/* You need to be holding the pvid_to_vgid lock already to call this. */
static int update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
const char *vgid, int nuke_empty)
const char *vgid, int mode)
{
struct dm_config_node *pv;
struct dm_hash_table *to_check;
@ -574,11 +736,14 @@ static int update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
if (!(pvid = dm_config_find_str(pv->child, "id", NULL)))
continue;
if (nuke_empty &&
if (mode == REMOVE_EMPTY &&
(vgid_old = dm_hash_lookup(s->pvid_to_vgid, pvid)) &&
!dm_hash_insert(to_check, vgid_old, (void*) 1))
goto out;
if (mode == MARK_OUTDATED)
mark_outdated_pv(s, vgid, pvid);
if (!dm_hash_insert(s->pvid_to_vgid, pvid, (void*) vgid))
goto out;
@ -602,10 +767,11 @@ static int update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
/* A pvid map lock needs to be held if update_pvids = 1. */
static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids)
{
struct dm_config_tree *old;
struct dm_config_tree *old, *outdated_pvs;
const char *oldname;
lock_vgid_to_metadata(s);
old = dm_hash_lookup(s->vgid_to_metadata, vgid);
outdated_pvs = dm_hash_lookup(s->vgid_to_outdated_pvs, vgid);
oldname = dm_hash_lookup(s->vgid_to_vgname, vgid);
if (!old) {
@ -619,12 +785,15 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids)
dm_hash_remove(s->vgid_to_metadata, vgid);
dm_hash_remove(s->vgid_to_vgname, vgid);
dm_hash_remove(s->vgname_to_vgid, oldname);
dm_hash_remove(s->vgid_to_outdated_pvs, vgid);
unlock_vgid_to_metadata(s);
if (update_pvids)
/* FIXME: What should happen when update fails */
update_pvid_to_vgid(s, old, "#orphan", 0);
dm_config_destroy(old);
if (outdated_pvs)
dm_config_destroy(outdated_pvs);
return 1;
}
@ -668,7 +837,7 @@ static int vg_remove_if_missing(lvmetad_state *s, const char *vgid, int update_p
* this function, so they can be safely destroyed after update_metadata returns
* (anything that might have been retained is copied). */
static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid,
struct dm_config_node *metadata, int64_t *oldseq)
struct dm_config_node *metadata, int64_t *oldseq, const char *pvid)
{
struct dm_config_tree *cft = NULL;
struct dm_config_tree *old;
@ -717,6 +886,10 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid
if (seq < haveseq) {
DEBUGLOG(s, "Refusing to update metadata for %s (at %d) to %d", _vgid, haveseq, seq);
if (pvid)
mark_outdated_pv(s, dm_config_find_str(old->root, "metadata/id", NULL), pvid);
/* TODO: notify the client that their metadata is out of date? */
retval = 1;
goto out;
@ -739,6 +912,8 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid
if (haveseq >= 0 && haveseq < seq) {
INFO(s, "Updating metadata for %s at %d to %d", _vgid, haveseq, seq);
if (oldseq)
update_pvid_to_vgid(s, old, vgid, MARK_OUTDATED);
/* temporarily orphan all of our PVs */
update_pvid_to_vgid(s, old, "#orphan", 0);
}
@ -773,12 +948,46 @@ out: /* FIXME: We should probably abort() on partial failures. */
return retval;
}
static dev_t device_remove(lvmetad_state *s, struct dm_config_tree *pvmeta, dev_t device)
{
struct dm_config_node *pvmeta_tmp;
struct dm_config_value *v = NULL;
dev_t alt_device = 0, prim_device = 0;
if ((pvmeta_tmp = dm_config_find_node(pvmeta->root, "pvmeta/devices_alternate")))
v = pvmeta_tmp->v;
prim_device = dm_config_find_int64(pvmeta->root, "pvmeta/device", 0);
/* it is the primary device */
if (device > 0 && device == prim_device && pvmeta_tmp && pvmeta_tmp->v)
{
alt_device = pvmeta_tmp->v->v.i;
pvmeta_tmp->v = pvmeta_tmp->v->next;
pvmeta_tmp = dm_config_find_node(pvmeta->root, "pvmeta/device");
pvmeta_tmp->v->v.i = alt_device;
} else if (device != prim_device)
alt_device = prim_device;
/* it is an alternate device */
if (device > 0 && v && v->v.i == device)
pvmeta_tmp->v = v->next;
else while (device > 0 && pvmeta_tmp && v) {
if (v->next && v->next->v.i == device)
v->next = v->next->next;
v = v->next;
}
return alt_device;
}
static response pv_gone(lvmetad_state *s, request r)
{
const char *pvid = daemon_request_str(r, "uuid", NULL);
int64_t device = daemon_request_int(r, "device", 0);
int64_t alt_device = 0;
struct dm_config_tree *pvmeta;
char *pvid_old, *vgid;
char *vgid;
DEBUGLOG(s, "pv_gone: %s / %" PRIu64, pvid, device);
@ -792,15 +1001,18 @@ static response pv_gone(lvmetad_state *s, request r)
DEBUGLOG(s, "pv_gone (updated): %s / %" PRIu64, pvid, device);
pvmeta = dm_hash_lookup(s->pvid_to_pvmeta, pvid);
pvid_old = dm_hash_lookup_binary(s->device_to_pvid, &device, sizeof(device));
if (!(pvmeta = dm_hash_lookup(s->pvid_to_pvmeta, pvid)))
return reply_unknown("PVID does not exist");
vgid = dm_hash_lookup(s->pvid_to_vgid, pvid);
dm_hash_remove_binary(s->device_to_pvid, &device, sizeof(device));
dm_hash_remove(s->pvid_to_pvmeta, pvid);
unlock_pvid_to_pvmeta(s);
dm_free(pvid_old);
if (!(alt_device = device_remove(s, pvmeta, device)))
dm_hash_remove(s->pvid_to_pvmeta, pvid);
DEBUGLOG(s, "pv_gone alt_device = %" PRIu64, alt_device);
unlock_pvid_to_pvmeta(s);
if (vgid) {
if (!(vgid = dm_strdup(vgid)))
@ -812,12 +1024,15 @@ static response pv_gone(lvmetad_state *s, request r)
dm_free(vgid);
}
if (!pvmeta)
return reply_unknown("PVID does not exist");
if (!alt_device)
dm_config_destroy(pvmeta);
dm_config_destroy(pvmeta);
return daemon_reply_simple("OK", NULL);
if (alt_device) {
return daemon_reply_simple("OK",
"device = %"PRId64, alt_device,
NULL);
} else
return daemon_reply_simple("OK", NULL );
}
static response pv_clear_all(lvmetad_state *s, request r)
@ -845,11 +1060,11 @@ static response pv_found(lvmetad_state *s, request r)
const char *vgname = daemon_request_str(r, "vgname", NULL);
const char *vgid = daemon_request_str(r, "metadata/id", NULL);
const char *vgid_old = NULL;
struct dm_config_node *pvmeta = dm_config_find_node(r.cft->root, "pvmeta");
struct dm_config_node *pvmeta = dm_config_find_node(r.cft->root, "pvmeta"), *altdev = NULL;
struct dm_config_value *altdev_v;
uint64_t device, device_old_pvid = 0;
struct dm_config_tree *cft, *pvmeta_old_dev = NULL, *pvmeta_old_pvid = NULL;
char *old;
char *pvid_dup;
int complete = 0, orphan = 0;
int64_t seqno = -1, seqno_old = -1, changed = 0;
@ -861,12 +1076,8 @@ static response pv_found(lvmetad_state *s, request r)
if (!dm_config_get_uint64(pvmeta, "pvmeta/device", &device))
return reply_fail("need PV device number");
if (!(cft = dm_config_create()) ||
(!(pvid_dup = dm_strdup(pvid)))) {
if (cft)
dm_config_destroy(cft);
if (!(cft = dm_config_create()))
return reply_fail("out of memory");
}
lock_pvid_to_pvmeta(s);
@ -875,7 +1086,6 @@ static response pv_found(lvmetad_state *s, request r)
if ((old = dm_hash_lookup_binary(s->device_to_pvid, &device, sizeof(device)))) {
pvmeta_old_dev = dm_hash_lookup(s->pvid_to_pvmeta, old);
dm_hash_remove(s->pvid_to_pvmeta, old);
vgid_old = dm_hash_lookup(s->pvid_to_vgid, old);
}
@ -885,35 +1095,69 @@ static response pv_found(lvmetad_state *s, request r)
if (!(cft->root = dm_config_clone_node(cft, pvmeta, 0)))
goto out_of_mem;
pvid = dm_config_find_str(cft->root, "pvmeta/id", NULL);
if (!pvmeta_old_pvid || compare_config(pvmeta_old_pvid->root, cft->root))
changed |= 1;
if (pvmeta_old_pvid && device != device_old_pvid) {
DEBUGLOG(s, "pv %s no longer on device %" PRIu64, pvid, device_old_pvid);
dm_free(dm_hash_lookup_binary(s->device_to_pvid, &device_old_pvid, sizeof(device_old_pvid)));
DEBUGLOG(s, "PV %s duplicated on device %" PRIu64, pvid, device_old_pvid);
dm_hash_remove_binary(s->device_to_pvid, &device_old_pvid, sizeof(device_old_pvid));
if (!dm_hash_insert_binary(s->device_to_pvid, &device_old_pvid,
sizeof(device_old_pvid), (void*)pvid))
goto out_of_mem;
if ((altdev = dm_config_find_node(pvmeta_old_pvid->root, "pvmeta/devices_alternate"))) {
altdev = dm_config_clone_node(cft, altdev, 0);
chain_node(altdev, cft->root, 0);
} else
if (!(altdev = make_config_node(cft, "devices_alternate", cft->root, 0)))
goto out_of_mem;
altdev_v = altdev->v;
while (1) {
if (altdev_v && altdev_v->v.i == device_old_pvid)
break;
if (altdev_v)
altdev_v = altdev_v->next;
if (!altdev_v) {
if (!(altdev_v = dm_config_create_value(cft)))
goto out_of_mem;
altdev_v->next = altdev->v;
altdev->v = altdev_v;
altdev->v->v.i = device_old_pvid;
break;
}
};
altdev_v = altdev->v;
while (altdev_v) {
if (altdev_v->next && altdev_v->next->v.i == device)
altdev_v->next = altdev_v->next->next;
altdev_v = altdev_v->next;
}
changed |= 1;
}
if (!dm_hash_insert(s->pvid_to_pvmeta, pvid, cft) ||
!dm_hash_insert_binary(s->device_to_pvid, &device, sizeof(device), (void*)pvid_dup)) {
!dm_hash_insert_binary(s->device_to_pvid, &device, sizeof(device), (void*)pvid)) {
dm_hash_remove(s->pvid_to_pvmeta, pvid);
out_of_mem:
unlock_pvid_to_pvmeta(s);
dm_config_destroy(cft);
dm_free(pvid_dup);
dm_free(old);
return reply_fail("out of memory");
}
unlock_pvid_to_pvmeta(s);
dm_free(old);
if (pvmeta_old_pvid)
dm_config_destroy(pvmeta_old_pvid);
if (pvmeta_old_dev && pvmeta_old_dev != pvmeta_old_pvid)
dm_config_destroy(pvmeta_old_dev);
if (pvmeta_old_dev && pvmeta_old_dev != pvmeta_old_pvid) {
dev_t d = dm_config_find_int64(pvmeta_old_dev->root, "pvmeta/device", 0);
WARN(s, "pv_found: stray device %"PRId64, d);
if (!device_remove(s, pvmeta_old_dev, device)) {
dm_hash_remove(s->pvid_to_pvmeta, old);
dm_config_destroy(pvmeta_old_dev);
}
}
if (metadata) {
if (!vgid)
@ -924,7 +1168,7 @@ out_of_mem:
if (daemon_request_int(r, "metadata/seqno", -1) < 0)
return reply_fail("need VG seqno");
if (!update_metadata(s, vgname, vgid, metadata, &seqno_old))
if (!update_metadata(s, vgname, vgid, metadata, &seqno_old, pvid))
return reply_fail("metadata update failed");
changed |= (seqno_old != dm_config_find_int(metadata, "metadata/seqno", -1));
} else {
@ -972,6 +1216,39 @@ out_of_mem:
NULL);
}
static response vg_clear_outdated_pvs(lvmetad_state *s, request r)
{
struct dm_config_tree *outdated_pvs;
const char *vgid = daemon_request_str(r, "vgid", NULL);
if (!vgid)
return reply_fail("need VG UUID");
if ((outdated_pvs = dm_hash_lookup(s->vgid_to_outdated_pvs, vgid))) {
dm_config_destroy(outdated_pvs);
dm_hash_remove(s->vgid_to_outdated_pvs, vgid);
}
return daemon_reply_simple("OK", NULL);
}
static void vg_info_update(lvmetad_state *s, const char *uuid,
struct dm_config_node *metadata)
{
struct vg_info *info;
int64_t cache_version;
cache_version = dm_config_find_int64(metadata, "metadata/seqno", -1);
if (cache_version == -1)
return;
info = (struct vg_info *) dm_hash_lookup(s->vgid_to_info, uuid);
if (!info)
return;
if (cache_version >= info->external_version)
info->flags &= ~VGFL_INVALID;
}
static response vg_update(lvmetad_state *s, request r)
{
struct dm_config_node *metadata = dm_config_find_node(r.cft->root, "metadata");
@ -987,8 +1264,10 @@ static response vg_update(lvmetad_state *s, request r)
/* TODO defer metadata update here; add a separate vg_commit
* call; if client does not commit, die */
if (!update_metadata(s, vgname, vgid, metadata, NULL))
if (!update_metadata(s, vgname, vgid, metadata, NULL, NULL))
return reply_fail("metadata update failed");
vg_info_update(s, vgid, metadata);
}
return daemon_reply_simple("OK", NULL);
}
@ -1009,6 +1288,80 @@ static response vg_remove(lvmetad_state *s, request r)
return daemon_reply_simple("OK", NULL);
}
static response set_global_info(lvmetad_state *s, request r)
{
const int global_invalid = daemon_request_int(r, "global_invalid", -1);
if (global_invalid == 1)
s->flags |= GLFL_INVALID;
else if (global_invalid == 0)
s->flags &= ~GLFL_INVALID;
return daemon_reply_simple("OK", NULL);
}
static response get_global_info(lvmetad_state *s, request r)
{
return daemon_reply_simple("OK", "global_invalid = %d",
(s->flags & GLFL_INVALID) ? 1 : 0,
NULL);
}
static response set_vg_info(lvmetad_state *s, request r)
{
struct dm_config_tree *vg;
struct vg_info *info;
const char *name;
const char *uuid;
const int64_t new_version = daemon_request_int(r, "version", -1);
int64_t cache_version;
if (new_version == -1)
goto out;
if (!(uuid = daemon_request_str(r, "uuid", NULL)))
goto use_name;
if ((vg = dm_hash_lookup(s->vgid_to_metadata, uuid)))
goto vers;
use_name:
if (!(name = daemon_request_str(r, "name", NULL)))
goto out;
if (!(uuid = dm_hash_lookup(s->vgname_to_vgid, name)))
goto out;
if (!(vg = dm_hash_lookup(s->vgid_to_metadata, uuid)))
goto out;
vers:
if (!new_version)
goto inval;
cache_version = dm_config_find_int64(vg->root, "metadata/seqno", -1);
if (cache_version != -1 && new_version != -1 && cache_version >= new_version)
goto out;
inval:
info = dm_hash_lookup(s->vgid_to_info, uuid);
if (!info) {
info = malloc(sizeof(struct vg_info));
if (!info)
goto bad;
memset(info, 0, sizeof(struct vg_info));
if (!dm_hash_insert(s->vgid_to_info, uuid, (void*)info))
goto bad;
}
info->external_version = new_version;
info->flags |= VGFL_INVALID;
out:
return daemon_reply_simple("OK", NULL);
bad:
return reply_fail("out of memory");
}
static void _dump_cft(struct buffer *buf, struct dm_hash_table *ht, const char *key_addr)
{
struct dm_hash_node *n;
@ -1035,7 +1388,7 @@ static void _dump_pairs(struct buffer *buf, struct dm_hash_table *ht, const char
*val = dm_hash_get_data(ht, n);
buffer_append(buf, " ");
if (int_key)
(void) dm_asprintf(&append, "%d = \"%s\"", *(int*)key, val);
(void) dm_asprintf(&append, "%d = \"%s\"", *(const int*)key, val);
else
(void) dm_asprintf(&append, "%s = \"%s\"", key, val);
if (append)
@ -1046,6 +1399,52 @@ static void _dump_pairs(struct buffer *buf, struct dm_hash_table *ht, const char
buffer_append(buf, "}\n");
}
static void _dump_info_version(struct buffer *buf, struct dm_hash_table *ht, const char *name, int int_key)
{
char *append;
struct dm_hash_node *n = dm_hash_get_first(ht);
struct vg_info *info;
buffer_append(buf, name);
buffer_append(buf, " {\n");
while (n) {
const char *key = dm_hash_get_key(ht, n);
info = dm_hash_get_data(ht, n);
buffer_append(buf, " ");
(void) dm_asprintf(&append, "%s = %lld", key, (long long)info->external_version);
if (append)
buffer_append(buf, append);
buffer_append(buf, "\n");
dm_free(append);
n = dm_hash_get_next(ht, n);
}
buffer_append(buf, "}\n");
}
static void _dump_info_flags(struct buffer *buf, struct dm_hash_table *ht, const char *name, int int_key)
{
char *append;
struct dm_hash_node *n = dm_hash_get_first(ht);
struct vg_info *info;
buffer_append(buf, name);
buffer_append(buf, " {\n");
while (n) {
const char *key = dm_hash_get_key(ht, n);
info = dm_hash_get_data(ht, n);
buffer_append(buf, " ");
(void) dm_asprintf(&append, "%s = %llx", key, (long long)info->flags);
if (append)
buffer_append(buf, append);
buffer_append(buf, "\n");
dm_free(append);
n = dm_hash_get_next(ht, n);
}
buffer_append(buf, "}\n");
}
static response dump(lvmetad_state *s)
{
response res = { 0 };
@ -1068,6 +1467,9 @@ static response dump(lvmetad_state *s)
buffer_append(b, "\n# VGID to VGNAME mapping\n\n");
_dump_pairs(b, s->vgid_to_vgname, "vgid_to_vgname", 0);
buffer_append(b, "\n# VGID to outdated PVs mapping\n\n");
_dump_cft(b, s->vgid_to_outdated_pvs, "outdated_pvs/vgid");
buffer_append(b, "\n# VGNAME to VGID mapping\n\n");
_dump_pairs(b, s->vgname_to_vgid, "vgname_to_vgid", 0);
@ -1077,6 +1479,12 @@ static response dump(lvmetad_state *s)
buffer_append(b, "\n# DEVICE to PVID mapping\n\n");
_dump_pairs(b, s->device_to_pvid, "device_to_pvid", 1);
buffer_append(b, "\n# VGID to INFO version mapping\n\n");
_dump_info_version(b, s->vgid_to_info, "vgid_to_info", 0);
buffer_append(b, "\n# VGID to INFO flags mapping\n\n");
_dump_info_flags(b, s->vgid_to_info, "vgid_to_info", 0);
unlock_pvid_to_vgid(s);
unlock_pvid_to_pvmeta(s);
unlock_vgid_to_metadata(s);
@ -1098,7 +1506,7 @@ static response handler(daemon_state s, client_handle h, request r)
return daemon_reply_simple("OK", NULL);
}
if (strcmp(token, state->token) && strcmp(rq, "dump")) {
if (strcmp(token, state->token) && strcmp(rq, "dump") && strcmp(token, "skip")) {
pthread_mutex_unlock(&state->token_lock);
return daemon_reply_simple("token_mismatch",
"expected = %s", state->token,
@ -1127,6 +1535,9 @@ static response handler(daemon_state s, client_handle h, request r)
if (!strcmp(rq, "vg_update"))
return vg_update(state, r);
if (!strcmp(rq, "vg_clear_outdated_pvs"))
return vg_clear_outdated_pvs(state, r);
if (!strcmp(rq, "vg_remove"))
return vg_remove(state, r);
@ -1139,6 +1550,15 @@ static response handler(daemon_state s, client_handle h, request r)
if (!strcmp(rq, "vg_list"))
return vg_list(state, r);
if (!strcmp(rq, "set_global_info"))
return set_global_info(state, r);
if (!strcmp(rq, "get_global_info"))
return get_global_info(state, r);
if (!strcmp(rq, "set_vg_info"))
return set_vg_info(state, r);
if (!strcmp(rq, "dump"))
return dump(state);
@ -1174,6 +1594,9 @@ static int init(daemon_state *s)
/* if (ls->initial_registrations)
_process_initial_registrations(ds->initial_registrations); */
if (ls->idle)
ls->idle->is_idle = 1;
return 1;
}
@ -1196,21 +1619,39 @@ static int fini(daemon_state *s)
return 1;
}
static int process_timeout_arg(const char *str, unsigned *max_timeouts)
{
char *endptr;
unsigned long l;
errno = 0;
l = strtoul(str, &endptr, 10);
if (errno || *endptr || l >= UINT_MAX)
return 0;
*max_timeouts = (unsigned) l;
return 1;
}
static void usage(const char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
"%s [-V] [-h] [-f] [-l {all|wire|debug}] [-s path]\n\n"
"%s [-V] [-h] [-f] [-l level[,level ...]] [-s path] [-t secs]\n\n"
" -V Show version of lvmetad\n"
" -h Show this help information\n"
" -f Don't fork, run in the foreground\n"
" -l Logging message level (-l {all|wire|debug})\n"
" -l Logging message levels (all,fatal,error,warn,info,wire,debug)\n"
" -p Set path to the pidfile\n"
" -s Set path to the socket to listen on\n\n", prog);
" -s Set path to the socket to listen on\n"
" -t Time to wait in seconds before shutdown on idle (missing or 0 = inifinite)\n\n", prog);
}
int main(int argc, char *argv[])
{
signed char opt;
struct timeval timeout;
daemon_idle di = { .ptimeout = &timeout };
lvmetad_state ls = { .log_config = "" };
daemon_state s = {
.daemon_fini = fini,
@ -1225,7 +1666,7 @@ int main(int argc, char *argv[])
};
// use getopt_long
while ((opt = getopt(argc, argv, "?fhVl:p:s:")) != EOF) {
while ((opt = getopt(argc, argv, "?fhVl:p:s:t:")) != EOF) {
switch (opt) {
case 'h':
usage(argv[0], stdout);
@ -1245,6 +1686,15 @@ int main(int argc, char *argv[])
case 's': // --socket
s.socket_path = optarg;
break;
case 't':
if (!process_timeout_arg(optarg, &di.max_timeouts)) {
fprintf(stderr, "Invalid value of timeout parameter.\n");
exit(EXIT_FAILURE);
}
/* 0 equals to wait indefinitely */
if (di.max_timeouts)
s.idle = ls.idle = &di;
break;
case 'V':
printf("lvmetad version: " LVM_VERSION "\n");
exit(1);

View File

@ -1,3 +1,18 @@
/*
* Copyright (C) 2011-2014 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU General Public License v.2.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "tool.h"
#include "lvmetad-client.h"
#include "label.h"
#include "lvmcache.h"
@ -105,15 +120,17 @@ void _dump_vg(daemon_handle h, const char *uuid)
int main(int argc, char **argv) {
daemon_handle h = lvmetad_open();
/* FIXME Missing error path */
if (argc > 1) {
int i;
struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0);
struct cmd_context *cmd = create_toolcontext(0, NULL, 0, 0, 1, 1);
for (i = 1; i < argc; ++i) {
const char *uuid = NULL;
scan(h, argv[i]);
}
destroy_toolcontext(cmd);
/* FIXME Missing lvmetad_close() */
return 0;
}
@ -122,6 +139,6 @@ int main(int argc, char **argv) {
_dump_vg(h, vgid);
_pv_add(h, uuid3, NULL);
daemon_close(h);
daemon_close(h); /* FIXME lvmetad_close? */
return 0;
}

2
daemons/lvmlockd/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
lvmlockctl
lvmlockd

View File

@ -0,0 +1,66 @@
#
# Copyright (C) 2014-2015 Red Hat, Inc.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU Lesser General Public License v.2.1.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = lvmlockd-core.c
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
SOURCES += lvmlockd-sanlock.c
endif
ifeq ("@BUILD_LOCKDDLM@", "yes")
SOURCES += lvmlockd-dlm.c
endif
TARGETS = lvmlockd lvmlockctl
.PHONY: install_lvmlockd
include $(top_builddir)/make.tmpl
INCLUDES += -I$(top_srcdir)/libdaemon/server
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
ifeq ("@BUILD_LOCKDSANLOCK@", "yes")
LIBS += -lsanlock_client
endif
ifeq ("@BUILD_LOCKDDLM@", "yes")
LIBS += -ldlm_lt
endif
LDFLAGS += -L$(top_builddir)/libdaemon/server
CLDFLAGS += -L$(top_builddir)/libdaemon/server
lvmlockd: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
lvmlockctl: lvmlockctl.o $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ lvmlockctl.o $(LVMLIBS)
install_lvmlockd: lvmlockd
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvmlockctl: lvmlockctl
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvm2: install_lvmlockd install_lvmlockctl
install: install_lvm2

View File

@ -0,0 +1,753 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*/
#include "tool.h"
#include "lvmlockd-client.h"
#include <stddef.h>
#include <getopt.h>
#include <signal.h>
#include <errno.h>
#include <fcntl.h>
#include <syslog.h>
#include <sys/wait.h>
#include <sys/socket.h>
#include <sys/un.h>
static int quit = 0;
static int info = 0;
static int dump = 0;
static int wait_opt = 0;
static int force_opt = 0;
static int kill_vg = 0;
static int drop_vg = 0;
static int gl_enable = 0;
static int gl_disable = 0;
static int stop_lockspaces = 0;
static char *arg_vg_name = NULL;
#define DUMP_SOCKET_NAME "lvmlockd-dump.sock"
#define DUMP_BUF_SIZE (1024 * 1024)
static char dump_buf[DUMP_BUF_SIZE+1];
static int dump_len;
static struct sockaddr_un dump_addr;
static socklen_t dump_addrlen;
daemon_handle _lvmlockd;
#define log_error(fmt, args...) \
do { \
printf(fmt "\n", ##args); \
} while (0)
#define MAX_LINE 512
/* copied from lvmlockd-internal.h */
#define MAX_NAME 64
#define MAX_ARGS 64
/*
* lvmlockd dumps the client info before the lockspaces,
* so we can look up client info when printing lockspace info.
*/
#define MAX_CLIENTS 100
struct client_info {
uint32_t client_id;
int pid;
char name[MAX_NAME+1];
};
static struct client_info clients[MAX_CLIENTS];
static int num_clients;
static void save_client_info(char *line)
{
uint32_t pid = 0;
int fd = 0;
int pi = 0;
uint32_t client_id = 0;
char name[MAX_NAME+1] = { 0 };
sscanf(line, "info=client pid=%u fd=%d pi=%d id=%u name=%s",
&pid, &fd, &pi, &client_id, name);
clients[num_clients].client_id = client_id;
clients[num_clients].pid = pid;
strcpy(clients[num_clients].name, name);
num_clients++;
}
static void find_client_info(uint32_t client_id, uint32_t *pid, char *cl_name)
{
int i;
for (i = 0; i < num_clients; i++) {
if (clients[i].client_id == client_id) {
*pid = clients[i].pid;
strcpy(cl_name, clients[i].name);
return;
}
}
}
static int first_ls = 1;
static void format_info_ls(char *line)
{
char ls_name[MAX_NAME+1] = { 0 };
char vg_name[MAX_NAME+1] = { 0 };
char vg_uuid[MAX_NAME+1] = { 0 };
char vg_sysid[MAX_NAME+1] = { 0 };
char lock_args[MAX_ARGS+1] = { 0 };
char lock_type[MAX_NAME+1] = { 0 };
sscanf(line, "info=ls ls_name=%s vg_name=%s vg_uuid=%s vg_sysid=%s vg_args=%s lm_type=%s",
ls_name, vg_name, vg_uuid, vg_sysid, lock_args, lock_type);
if (!first_ls)
printf("\n");
first_ls = 0;
printf("VG %s lock_type=%s %s\n", vg_name, lock_type, vg_uuid);
printf("LS %s %s\n", lock_type, ls_name);
}
static void format_info_ls_action(char *line)
{
uint32_t client_id = 0;
char flags[MAX_NAME+1] = { 0 };
char version[MAX_NAME+1] = { 0 };
char op[MAX_NAME+1] = { 0 };
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
sscanf(line, "info=ls_action client_id=%u %s %s op=%s",
&client_id, flags, version, op);
find_client_info(client_id, &pid, cl_name);
printf("OP %s pid %u (%s)\n", op, pid, cl_name);
}
static void format_info_r(char *line, char *r_name_out, char *r_type_out)
{
char r_name[MAX_NAME+1] = { 0 };
char r_type[4] = { 0 };
char mode[4] = { 0 };
char sh_count[MAX_NAME+1] = { 0 };
uint32_t ver = 0;
sscanf(line, "info=r name=%s type=%s mode=%s %s version=%u",
r_name, r_type, mode, sh_count, &ver);
strcpy(r_name_out, r_name);
strcpy(r_type_out, r_type);
/* when mode is not un, wait and print each lk line */
if (strcmp(mode, "un"))
return;
/* when mode is un, there will be no lk lines, so print now */
if (!strcmp(r_type, "gl")) {
printf("LK GL un ver %u\n", ver);
} else if (!strcmp(r_type, "vg")) {
printf("LK VG un ver %u\n", ver);
} else if (!strcmp(r_type, "lv")) {
printf("LK LV un %s\n", r_name);
}
}
static void format_info_lk(char *line, char *r_name, char *r_type)
{
char mode[4] = { 0 };
uint32_t ver = 0;
char flags[MAX_NAME+1] = { 0 };
uint32_t client_id = 0;
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
if (!r_name[0] || !r_type[0]) {
printf("format_info_lk error r_name %s r_type %s\n", r_name, r_type);
printf("%s\n", line);
return;
}
sscanf(line, "info=lk mode=%s version=%u %s client_id=%u",
mode, &ver, flags, &client_id);
find_client_info(client_id, &pid, cl_name);
if (!strcmp(r_type, "gl")) {
printf("LK GL %s ver %u pid %u (%s)\n", mode, ver, pid, cl_name);
} else if (!strcmp(r_type, "vg")) {
printf("LK VG %s ver %u pid %u (%s)\n", mode, ver, pid, cl_name);
} else if (!strcmp(r_type, "lv")) {
printf("LK LV %s %s\n", mode, r_name);
}
}
static void format_info_r_action(char *line, char *r_name, char *r_type)
{
uint32_t client_id = 0;
char flags[MAX_NAME+1] = { 0 };
char version[MAX_NAME+1] = { 0 };
char op[MAX_NAME+1] = { 0 };
char rt[4] = { 0 };
char mode[4] = { 0 };
char lm[MAX_NAME+1] = { 0 };
char result[MAX_NAME+1] = { 0 };
char lm_rv[MAX_NAME+1] = { 0 };
uint32_t pid = 0;
char cl_name[MAX_NAME+1] = { 0 };
if (!r_name[0] || !r_type[0]) {
printf("format_info_r_action error r_name %s r_type %s\n", r_name, r_type);
printf("%s\n", line);
return;
}
sscanf(line, "info=r_action client_id=%u %s %s op=%s rt=%s mode=%s %s %s %s",
&client_id, flags, version, op, rt, mode, lm, result, lm_rv);
find_client_info(client_id, &pid, cl_name);
if (strcmp(op, "lock")) {
printf("OP %s pid %u (%s)\n", op, pid, cl_name);
return;
}
if (!strcmp(r_type, "gl")) {
printf("LW GL %s ver %u pid %u (%s)\n", mode, 0, pid, cl_name);
} else if (!strcmp(r_type, "vg")) {
printf("LW VG %s ver %u pid %u (%s)\n", mode, 0, pid, cl_name);
} else if (!strcmp(r_type, "lv")) {
printf("LW LV %s %s\n", mode, r_name);
}
}
static void format_info_line(char *line, char *r_name, char *r_type)
{
if (!strncmp(line, "info=structs ", strlen("info=structs "))) {
/* only print this in the raw info dump */
} else if (!strncmp(line, "info=client ", strlen("info=client "))) {
save_client_info(line);
} else if (!strncmp(line, "info=ls ", strlen("info=ls "))) {
format_info_ls(line);
} else if (!strncmp(line, "info=ls_action ", strlen("info=ls_action "))) {
format_info_ls_action(line);
} else if (!strncmp(line, "info=r ", strlen("info=r "))) {
/*
* r_name/r_type are reset when a new resource is found.
* They are reused for the lock and action lines that
* follow a resource line.
*/
memset(r_name, 0, MAX_NAME+1);
memset(r_type, 0, MAX_NAME+1);
format_info_r(line, r_name, r_type);
} else if (!strncmp(line, "info=lk ", strlen("info=lk "))) {
/* will use info from previous r */
format_info_lk(line, r_name, r_type);
} else if (!strncmp(line, "info=r_action ", strlen("info=r_action "))) {
/* will use info from previous r */
format_info_r_action(line, r_name, r_type);
} else {
printf("UN %s\n", line);
}
}
static void format_info(void)
{
char line[MAX_LINE];
char r_name[MAX_NAME+1];
char r_type[MAX_NAME+1];
int i, j;
j = 0;
memset(line, 0, sizeof(line));
for (i = 0; i < dump_len; i++) {
line[j++] = dump_buf[i];
if ((line[j-1] == '\n') || (line[j-1] == '\0')) {
format_info_line(line, r_name, r_type);
j = 0;
memset(line, 0, sizeof(line));
}
}
}
static daemon_reply _lvmlockd_send(const char *req_name, ...)
{
va_list ap;
daemon_reply repl;
daemon_request req;
req = daemon_request_make(req_name);
va_start(ap, req_name);
daemon_request_extend_v(req, ap);
va_end(ap);
repl = daemon_send(_lvmlockd, req);
daemon_request_destroy(req);
return repl;
}
/* See the same in lib/locking/lvmlockd.c */
#define NO_LOCKD_RESULT -1000
static int _lvmlockd_result(daemon_reply reply, int *result)
{
int reply_result;
if (reply.error) {
log_error("lvmlockd_result reply error %d", reply.error);
return 0;
}
if (strcmp(daemon_reply_str(reply, "response", ""), "OK")) {
log_error("lvmlockd_result bad response");
return 0;
}
reply_result = daemon_reply_int(reply, "op_result", NO_LOCKD_RESULT);
if (reply_result == -1000) {
log_error("lvmlockd_result no op_result");
return 0;
}
*result = reply_result;
return 1;
}
static int do_quit(void)
{
daemon_reply reply;
int rv = 0;
reply = daemon_send_simple(_lvmlockd, "quit", NULL);
if (reply.error) {
log_error("reply error %d", reply.error);
rv = reply.error;
}
daemon_reply_destroy(reply);
return rv;
}
static int setup_dump_socket(void)
{
int s, rv;
s = socket(AF_LOCAL, SOCK_DGRAM, 0);
if (s < 0)
return s;
memset(&dump_addr, 0, sizeof(dump_addr));
dump_addr.sun_family = AF_LOCAL;
strcpy(&dump_addr.sun_path[1], DUMP_SOCKET_NAME);
dump_addrlen = sizeof(sa_family_t) + strlen(dump_addr.sun_path+1) + 1;
rv = bind(s, (struct sockaddr *) &dump_addr, dump_addrlen);
if (rv < 0) {
rv = -errno;
if (!close(s))
log_error("failed to close dump socket");
return rv;
}
return s;
}
static int do_dump(const char *req_name)
{
daemon_reply reply;
int result;
int fd, rv = 0;
int count = 0;
fd = setup_dump_socket();
if (fd < 0) {
log_error("socket error %d", fd);
return fd;
}
reply = daemon_send_simple(_lvmlockd, req_name, NULL);
if (reply.error) {
log_error("reply error %d", reply.error);
rv = reply.error;
goto out;
}
result = daemon_reply_int(reply, "result", 0);
dump_len = daemon_reply_int(reply, "dump_len", 0);
daemon_reply_destroy(reply);
if (result < 0) {
rv = result;
log_error("result %d", result);
}
if (!dump_len)
goto out;
memset(dump_buf, 0, sizeof(dump_buf));
retry:
rv = recvfrom(fd, dump_buf + count, dump_len - count, MSG_WAITALL,
(struct sockaddr *)&dump_addr, &dump_addrlen);
if (rv < 0) {
log_error("recvfrom error %d %d", rv, errno);
rv = -errno;
goto out;
}
count += rv;
if (count < dump_len)
goto retry;
rv = 0;
if ((info && dump) || !strcmp(req_name, "dump"))
printf("%s\n", dump_buf);
else
format_info();
out:
if (close(fd))
log_error("failed to close dump socket %d", fd);
return rv;
}
static int do_able(const char *req_name)
{
daemon_reply reply;
int result;
int rv;
reply = _lvmlockd_send(req_name,
"cmd = %s", "lvmlockctl",
"pid = %d", getpid(),
"vg_name = %s", arg_vg_name,
NULL);
if (!_lvmlockd_result(reply, &result)) {
log_error("lvmlockd result %d", result);
rv = result;
} else {
rv = 0;
}
daemon_reply_destroy(reply);
return rv;
}
static int do_stop_lockspaces(void)
{
daemon_reply reply;
char opts[32];
int result;
int rv;
memset(opts, 0, sizeof(opts));
if (wait_opt)
strcat(opts, "wait ");
if (force_opt)
strcat(opts, "force ");
reply = _lvmlockd_send("stop_all",
"cmd = %s", "lvmlockctl",
"pid = %d", getpid(),
"opts = %s", opts[0] ? opts : "none",
NULL);
if (!_lvmlockd_result(reply, &result)) {
log_error("lvmlockd result %d", result);
rv = result;
} else {
rv = 0;
}
daemon_reply_destroy(reply);
return rv;
}
static int do_kill(void)
{
daemon_reply reply;
int result;
int rv;
syslog(LOG_EMERG, "Lost access to sanlock lease storage in VG %s.", arg_vg_name);
/* These two lines explain the manual alternative to the FIXME below. */
syslog(LOG_EMERG, "Immediately deactivate LVs in VG %s.", arg_vg_name);
syslog(LOG_EMERG, "Once VG is unused, run lvmlockctl --drop %s.", arg_vg_name);
/*
* It may not be strictly necessary to notify lvmlockd of the kill, but
* lvmlockd can use this information to avoid attempting any new lock
* requests in the VG (which would fail anyway), and can return an
* error indicating that the VG has been killed.
*/
reply = _lvmlockd_send("kill_vg",
"cmd = %s", "lvmlockctl",
"pid = %d", getpid(),
"vg_name = %s", arg_vg_name,
NULL);
if (!_lvmlockd_result(reply, &result)) {
log_error("lvmlockd result %d", result);
rv = result;
} else {
rv = 0;
}
daemon_reply_destroy(reply);
/*
* FIXME: here is where we should implement a strong form of
* blkdeactivate, and if it completes successfully, automatically call
* do_drop() afterward. (The drop step may not always be necessary
* if the lvm commands run while shutting things down release all the
* leases.)
*
* run_strong_blkdeactivate();
* do_drop();
*/
return rv;
}
static int do_drop(void)
{
daemon_reply reply;
int result;
int rv;
syslog(LOG_WARNING, "Dropping locks for VG %s.", arg_vg_name);
/*
* Check for misuse by looking for any active LVs in the VG
* and refusing this operation if found? One possible way
* to kill LVs (e.g. if fs cannot be unmounted) is to suspend
* them, or replace them with the error target. In that
* case the LV will still appear to be active, but it is
* safe to release the lock.
*/
reply = _lvmlockd_send("drop_vg",
"cmd = %s", "lvmlockctl",
"pid = %d", getpid(),
"vg_name = %s", arg_vg_name,
NULL);
if (!_lvmlockd_result(reply, &result)) {
log_error("lvmlockd result %d", result);
rv = result;
} else {
rv = 0;
}
daemon_reply_destroy(reply);
return rv;
}
static void print_usage(void)
{
printf("lvmlockctl options\n");
printf("Options:\n");
printf("--help | -h\n");
printf(" Show this help information.\n");
printf("--quit | -q\n");
printf(" Tell lvmlockd to quit.\n");
printf("--info | -i\n");
printf(" Print lock state information from lvmlockd.\n");
printf("--dump | -d\n");
printf(" Print log buffer from lvmlockd.\n");
printf("--wait | -w 0|1\n");
printf(" Wait option for other commands.\n");
printf("--force | -f 0|1>\n");
printf(" Force option for other commands.\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");
}
static int read_options(int argc, char *argv[])
{
int option_index = 0;
int c;
static struct option long_options[] = {
{"help", no_argument, 0, 'h' },
{"quit", no_argument, 0, 'q' },
{"info", no_argument, 0, 'i' },
{"dump", no_argument, 0, 'd' },
{"wait", required_argument, 0, 'w' },
{"force", required_argument, 0, 'f' },
{"kill", required_argument, 0, 'k' },
{"drop", required_argument, 0, 'r' },
{"gl-enable", required_argument, 0, 'E' },
{"gl-disable", required_argument, 0, 'D' },
{"stop-lockspaces", no_argument, 0, 'S' },
{0, 0, 0, 0 }
};
if (argc == 1) {
print_usage();
exit(0);
}
while (1) {
c = getopt_long(argc, argv, "hqidE:D:w:k:r:S", long_options, &option_index);
if (c == -1)
break;
switch (c) {
case 'h':
/* --help */
print_usage();
exit(0);
case 'q':
/* --quit */
quit = 1;
break;
case 'i':
/* --info */
info = 1;
break;
case 'd':
/* --dump */
dump = 1;
break;
case 'w':
wait_opt = atoi(optarg);
break;
case 'k':
kill_vg = 1;
arg_vg_name = strdup(optarg);
break;
case 'r':
drop_vg = 1;
arg_vg_name = strdup(optarg);
break;
case 'E':
gl_enable = 1;
arg_vg_name = strdup(optarg);
break;
case 'D':
gl_disable = 1;
arg_vg_name = strdup(optarg);
break;
case 'S':
stop_lockspaces = 1;
break;
default:
print_usage();
exit(1);
}
}
return 0;
}
int main(int argc, char **argv)
{
int rv = 0;
rv = read_options(argc, argv);
if (rv < 0)
return rv;
_lvmlockd = lvmlockd_open(NULL);
if (_lvmlockd.socket_fd < 0 || _lvmlockd.error) {
log_error("Cannot connect to lvmlockd.");
return -1;
}
if (quit) {
rv = do_quit();
goto out;
}
if (info) {
rv = do_dump("info");
goto out;
}
if (dump) {
rv = do_dump("dump");
goto out;
}
if (kill_vg) {
rv = do_kill();
goto out;
}
if (drop_vg) {
rv = do_drop();
goto out;
}
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;
}
if (stop_lockspaces) {
rv = do_stop_lockspaces();
goto out;
}
out:
lvmlockd_close(_lvmlockd);
return rv;
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*/
#ifndef _LVM_LVMLOCKD_CLIENT_H
#define _LVM_LVMLOCKD_CLIENT_H
#include "daemon-client.h"
#define LVMLOCKD_SOCKET DEFAULT_RUN_DIR "/lvmlockd.socket"
/* Wrappers to open/close connection */
static inline daemon_handle lvmlockd_open(const char *sock)
{
daemon_info lvmlockd_info = {
.path = "lvmlockd",
.socket = sock ?: LVMLOCKD_SOCKET,
.protocol = "lvmlockd",
.protocol_version = 1,
.autostart = 0
};
return daemon_open(lvmlockd_info);
}
static inline void lvmlockd_close(daemon_handle h)
{
return daemon_close(h);
}
/*
* Errors returned as the lvmlockd result value.
*/
#define ENOLS 210 /* lockspace not found */
#define ESTARTING 211 /* lockspace is starting */
#define EARGS 212
#define EHOSTID 213
#define EMANAGER 214
#define EPREPARE 215
#define ELOCKD 216
#define EVGKILLED 217 /* sanlock lost access to leases and VG is killed. */
#define ELOCKIO 218 /* sanlock io errors during lock op, may be transient. */
#define EREMOVED 219
#endif /* _LVM_LVMLOCKD_CLIENT_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,767 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*/
#define _XOPEN_SOURCE 500 /* pthread */
#define _ISOC99_SOURCE
#include "tool.h"
#include "daemon-server.h"
#include "daemon-log.h"
#include "xlate.h"
#include "lvmlockd-internal.h"
#include "lvmlockd-client.h"
/*
* Using synchronous _wait dlm apis so do not define _REENTRANT and
* link with non-threaded version of library, libdlm_lt.
*/
#include "libdlm.h"
#include <pthread.h>
#include <stddef.h>
#include <poll.h>
#include <errno.h>
#include <endian.h>
#include <fcntl.h>
#include <byteswap.h>
#include <syslog.h>
#include <dirent.h>
#include <sys/socket.h>
struct lm_dlm {
dlm_lshandle_t *dh;
};
struct rd_dlm {
struct dlm_lksb lksb;
struct val_blk *vb;
};
int lm_data_size_dlm(void)
{
return sizeof(struct rd_dlm);
}
/*
* lock_args format
*
* vg_lock_args format for dlm is
* vg_version_string:undefined:cluster_name
*
* lv_lock_args are not used for dlm
*
* version_string is MAJOR.MINOR.PATCH
* undefined may contain ":"
*/
#define VG_LOCK_ARGS_MAJOR 1
#define VG_LOCK_ARGS_MINOR 0
#define VG_LOCK_ARGS_PATCH 0
static int dlm_has_lvb_bug;
static int cluster_name_from_args(char *vg_args, char *clustername)
{
return last_string_from_args(vg_args, clustername);
}
static int check_args_version(char *vg_args)
{
unsigned int major = 0;
int rv;
rv = version_from_args(vg_args, &major, NULL, NULL);
if (rv < 0) {
log_error("check_args_version %s error %d", vg_args, rv);
return rv;
}
if (major > VG_LOCK_ARGS_MAJOR) {
log_error("check_args_version %s major %d %d", vg_args, major, VG_LOCK_ARGS_MAJOR);
return -1;
}
return 0;
}
/* This will be set after dlm_controld is started. */
#define DLM_CLUSTER_NAME_PATH "/sys/kernel/config/dlm/cluster/cluster_name"
static int read_cluster_name(char *clustername)
{
static const char close_error_msg[] = "read_cluster_name: close_error %d";
char *n;
int fd;
int rv;
if (daemon_test) {
sprintf(clustername, "%s", "test");
return 0;
}
fd = open(DLM_CLUSTER_NAME_PATH, O_RDONLY);
if (fd < 0) {
log_debug("read_cluster_name: open error %d, check dlm_controld", fd);
return fd;
}
rv = read(fd, clustername, MAX_ARGS);
if (rv < 0) {
log_error("read_cluster_name: cluster name read error %d, check dlm_controld", fd);
if (close(fd))
log_error(close_error_msg, fd);
return rv;
}
n = strstr(clustername, "\n");
if (n)
*n = '\0';
if (close(fd))
log_error(close_error_msg, fd);
return 0;
}
int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
{
char clustername[MAX_ARGS+1];
char lock_args_version[MAX_ARGS+1];
int rv;
memset(clustername, 0, sizeof(clustername));
memset(lock_args_version, 0, sizeof(lock_args_version));
snprintf(lock_args_version, MAX_ARGS, "%u.%u.%u",
VG_LOCK_ARGS_MAJOR, VG_LOCK_ARGS_MINOR, VG_LOCK_ARGS_PATCH);
rv = read_cluster_name(clustername);
if (rv < 0)
return -EMANAGER;
if (strlen(clustername) + strlen(lock_args_version) + 2 > MAX_ARGS) {
log_error("init_vg_dlm args too long");
return -EARGS;
}
snprintf(vg_args, MAX_ARGS, "%s:%s", lock_args_version, clustername);
rv = 0;
log_debug("init_vg_dlm done %s vg_args %s", ls_name, vg_args);
return rv;
}
int lm_prepare_lockspace_dlm(struct lockspace *ls)
{
char sys_clustername[MAX_ARGS+1];
char arg_clustername[MAX_ARGS+1];
uint32_t major = 0, minor = 0, patch = 0;
struct lm_dlm *lmd;
int rv;
memset(sys_clustername, 0, sizeof(sys_clustername));
memset(arg_clustername, 0, sizeof(arg_clustername));
rv = read_cluster_name(sys_clustername);
if (rv < 0)
return -EMANAGER;
rv = dlm_kernel_version(&major, &minor, &patch);
if (rv < 0) {
log_error("prepare_lockspace_dlm kernel_version not detected %d", rv);
dlm_has_lvb_bug = 1;
}
if ((major == 6) && (minor == 0) && (patch == 1)) {
log_debug("dlm kernel version %u.%u.%u has lvb bug", major, minor, patch);
dlm_has_lvb_bug = 1;
}
if (!ls->vg_args[0]) {
/* global lockspace has no vg args */
goto skip_args;
}
rv = check_args_version(ls->vg_args);
if (rv < 0)
return -EARGS;
rv = cluster_name_from_args(ls->vg_args, arg_clustername);
if (rv < 0) {
log_error("prepare_lockspace_dlm %s no cluster name from args %s", ls->name, ls->vg_args);
return -EARGS;
}
if (strcmp(sys_clustername, arg_clustername)) {
log_error("prepare_lockspace_dlm %s mismatching cluster names sys %s arg %s",
ls->name, sys_clustername, arg_clustername);
return -EARGS;
}
skip_args:
lmd = malloc(sizeof(struct lm_dlm));
if (!lmd)
return -ENOMEM;
ls->lm_data = lmd;
return 0;
}
int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
if (daemon_test)
return 0;
if (adopt)
lmd->dh = dlm_open_lockspace(ls->name);
else
lmd->dh = dlm_new_lockspace(ls->name, 0600, DLM_LSFL_NEWEXCL);
if (!lmd->dh) {
log_error("add_lockspace_dlm %s adopt %d error", ls->name, adopt);
free(lmd);
ls->lm_data = NULL;
return -1;
}
return 0;
}
int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
int rv;
if (daemon_test)
goto out;
/*
* If free_vg is set, it means we are doing vgremove, and we may want
* to tell any other nodes to leave the lockspace. This is not really
* necessary since there should be no harm in having an unused
* lockspace sitting around. A new "notification lock" would need to
* be added with a callback to signal this.
*/
rv = dlm_release_lockspace(ls->name, lmd->dh, 1);
if (rv < 0) {
log_error("rem_lockspace_dlm error %d", rv);
return rv;
}
out:
free(lmd);
ls->lm_data = NULL;
return 0;
}
static int lm_add_resource_dlm(struct lockspace *ls, struct resource *r, int with_lock_nl)
{
struct lm_dlm *lmd = (struct lm_dlm *)ls->lm_data;
struct rd_dlm *rdd = (struct rd_dlm *)r->lm_data;
uint32_t flags = 0;
char *buf;
int rv;
if (r->type == LD_RT_GL || r->type == LD_RT_VG) {
buf = malloc(sizeof(struct val_blk) + DLM_LVB_LEN);
if (!buf)
return -ENOMEM;
memset(buf, 0, sizeof(struct val_blk) + DLM_LVB_LEN);
rdd->vb = (struct val_blk *)buf;
rdd->lksb.sb_lvbptr = buf + sizeof(struct val_blk);
flags |= LKF_VALBLK;
}
if (!with_lock_nl)
goto out;
/* because this is a new NL lock request */
flags |= LKF_EXPEDITE;
if (daemon_test)
goto out;
rv = dlm_ls_lock_wait(lmd->dh, LKM_NLMODE, &rdd->lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv < 0) {
log_error("S %s R %s add_resource_dlm lock error %d", ls->name, r->name, rv);
return rv;
}
out:
return 0;
}
int lm_rem_resource_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;
int rv = 0;
if (daemon_test)
goto out;
lksb = &rdd->lksb;
if (!lksb->sb_lkid)
goto out;
rv = dlm_ls_unlock_wait(lmd->dh, lksb->sb_lkid, 0, lksb);
if (rv < 0) {
log_error("S %s R %s rem_resource_dlm unlock error %d", ls->name, r->name, rv);
}
out:
if (rdd->vb)
free(rdd->vb);
memset(rdd, 0, sizeof(struct rd_dlm));
r->lm_init = 0;
return rv;
}
static int to_dlm_mode(int ld_mode)
{
switch (ld_mode) {
case LD_LK_EX:
return LKM_EXMODE;
case LD_LK_SH:
return LKM_PRMODE;
};
return -1;
}
static int lm_adopt_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
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;
struct dlm_lksb *lksb;
uint32_t flags = 0;
int mode;
int rv;
memset(vb_out, 0, sizeof(struct val_blk));
if (!r->lm_init) {
rv = lm_add_resource_dlm(ls, r, 0);
if (rv < 0)
return rv;
r->lm_init = 1;
}
lksb = &rdd->lksb;
flags |= LKF_PERSISTENT;
flags |= LKF_ORPHAN;
if (rdd->vb)
flags |= LKF_VALBLK;
mode = to_dlm_mode(ld_mode);
if (mode < 0) {
log_error("adopt_dlm invalid mode %d", ld_mode);
rv = -EINVAL;
goto fail;
}
log_debug("S %s R %s adopt_dlm", ls->name, r->name);
if (daemon_test)
return 0;
/*
* dlm returns 0 for success, -EAGAIN if an orphan is
* found with another mode, and -ENOENT if no orphan.
*
* cast/bast/param are (void *)1 because the kernel
* returns errors if some are null.
*/
rv = dlm_ls_lockx(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name), 0,
(void *)1, (void *)1, (void *)1,
NULL, NULL);
if (rv == -1 && errno == -EAGAIN) {
log_debug("S %s R %s adopt_dlm adopt mode %d try other mode",
ls->name, r->name, ld_mode);
rv = -EUCLEAN;
goto fail;
}
if (rv < 0) {
log_debug("S %s R %s adopt_dlm mode %d flags %x error %d errno %d",
ls->name, r->name, mode, flags, rv, errno);
goto fail;
}
/*
* FIXME: For GL/VG locks we probably want to read the lvb,
* especially if adopting an ex lock, because when we
* release this adopted ex lock we may want to write new
* lvb values based on the current lvb values (at lease
* in the GL case where we increment the current values.)
*
* It should be possible to read the lvb by requesting
* this lock in the same mode it's already in.
*/
return rv;
fail:
lm_rem_resource_dlm(ls, r);
return rv;
}
/*
* Use PERSISTENT so that if lvmlockd exits while holding locks,
* the locks will remain orphaned in the dlm, still protecting what
* they were acquired to protect.
*/
int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
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;
int mode;
int rv;
if (adopt) {
/* 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, vb_out);
}
if (!r->lm_init) {
rv = lm_add_resource_dlm(ls, r, 1);
if (rv < 0)
return rv;
r->lm_init = 1;
}
lksb = &rdd->lksb;
flags |= LKF_CONVERT;
flags |= LKF_NOQUEUE;
flags |= LKF_PERSISTENT;
if (rdd->vb)
flags |= LKF_VALBLK;
mode = to_dlm_mode(ld_mode);
if (mode < 0) {
log_error("lock_dlm invalid mode %d", ld_mode);
return -EINVAL;
}
log_debug("S %s R %s lock_dlm", ls->name, r->name);
if (daemon_test) {
memset(vb_out, 0, sizeof(struct val_blk));
return 0;
}
/*
* The dlm lvb bug means that converting NL->EX will not return
* the latest lvb, so we have to convert NL->PR->EX to reread it.
*/
if (dlm_has_lvb_bug && (ld_mode == LD_LK_EX)) {
rv = dlm_ls_lock_wait(lmd->dh, LKM_PRMODE, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv == -1) {
log_debug("S %s R %s lock_dlm acquire mode PR for %d rv %d",
ls->name, r->name, mode, rv);
goto lockrv;
}
/* Fall through to request EX. */
}
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
lockrv:
if (rv == -1 && errno == EAGAIN) {
log_debug("S %s R %s lock_dlm acquire mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
}
if (rv < 0) {
log_error("S %s R %s lock_dlm acquire error %d errno %d", ls->name, r->name, rv, errno);
return rv;
}
if (rdd->vb) {
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));
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));
memcpy(rdd->vb, &vb, sizeof(vb));
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;
}
int lm_convert_dlm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version)
{
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;
uint32_t mode;
uint32_t flags = 0;
int rv;
log_debug("S %s R %s convert_dlm", ls->name, r->name);
flags |= LKF_CONVERT;
flags |= LKF_NOQUEUE;
flags |= LKF_PERSISTENT;
if (rdd->vb && r_version && (r->mode == LD_LK_EX)) {
if (!rdd->vb->version) {
/* first time vb has been written */
rdd->vb->version = cpu_to_le16(VAL_BLK_VERSION);
}
rdd->vb->r_version = cpu_to_le32(r_version);
memcpy(lksb->sb_lvbptr, rdd->vb, sizeof(struct val_blk));
log_debug("S %s R %s convert_dlm set r_version %u",
ls->name, r->name, r_version);
flags |= LKF_VALBLK;
}
mode = to_dlm_mode(ld_mode);
if (daemon_test)
return 0;
rv = dlm_ls_lock_wait(lmd->dh, mode, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv == -1 && errno == EAGAIN) {
/* FIXME: When does this happen? Should something different be done? */
log_error("S %s R %s convert_dlm mode %d rv EAGAIN", ls->name, r->name, mode);
return -EAGAIN;
}
if (rv < 0) {
log_error("S %s R %s convert_dlm error %d", ls->name, r->name, rv);
}
return rv;
}
int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags)
{
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;
/*
* Do not set PERSISTENT, because we don't need an orphan
* NL lock to protect anything.
*/
flags |= LKF_CONVERT;
if (rdd->vb && (r->mode == LD_LK_EX)) {
/* 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 ((lmu_flags & LMUF_FREE_VG) && (r->type == LD_RT_VG)) {
vb_next.flags = cpu_to_le16(VBF_REMOVED);
new_vb = 1;
}
if (r_version) {
vb_next.r_version = cpu_to_le32(r_version);
new_vb = 1;
}
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)
return 0;
rv = dlm_ls_lock_wait(lmd->dh, LKM_NLMODE, lksb, flags,
r->name, strlen(r->name),
0, NULL, NULL, NULL);
if (rv < 0) {
log_error("S %s R %s unlock_dlm error %d", ls->name, r->name, rv);
}
return rv;
}
/*
* This list could be read from dlm_controld via libdlmcontrol,
* but it's simpler to get it from sysfs.
*/
#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";
struct lockspace *ls;
struct dirent *de;
DIR *ls_dir;
if (!(ls_dir = opendir(DLM_LOCKSPACES_PATH)))
return -ECONNREFUSED;
while ((de = readdir(ls_dir))) {
if (de->d_name[0] == '.')
continue;
if (strncmp(de->d_name, LVM_LS_PREFIX, strlen(LVM_LS_PREFIX)))
continue;
if (!(ls = alloc_lockspace())) {
if (closedir(ls_dir))
log_error(closedir_err_msg);
return -ENOMEM;
}
ls->lm_type = LD_LM_DLM;
strncpy(ls->name, de->d_name, MAX_NAME);
strncpy(ls->vg_name, ls->name + strlen(LVM_LS_PREFIX), MAX_NAME);
list_add_tail(&ls->list, ls_rejoin);
}
if (closedir(ls_dir))
log_error(closedir_err_msg);
return 0;
}
int lm_is_running_dlm(void)
{
char sys_clustername[MAX_ARGS+1];
int rv;
memset(sys_clustername, 0, sizeof(sys_clustername));
rv = read_cluster_name(sys_clustername);
if (rv < 0)
return 0;
return 1;
}

View File

@ -0,0 +1,587 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*/
#ifndef _LVM_LVMLOCKD_INTERNAL_H
#define _LVM_LVMLOCKD_INTERNAL_H
#define MAX_NAME 64
#define MAX_ARGS 64
#define R_NAME_GL_DISABLED "_GLLK_disabled"
#define R_NAME_GL "GLLK"
#define R_NAME_VG "VGLK"
#define S_NAME_GL_DLM "lvm_global"
#define LVM_LS_PREFIX "lvm_" /* ls name is prefix + vg_name */
/* global lockspace name for sanlock is a vg name */
/* lock manager types */
enum {
LD_LM_NONE = 0,
LD_LM_UNUSED = 1, /* place holder so values match lib/locking/lvmlockd.h */
LD_LM_DLM = 2,
LD_LM_SANLOCK = 3,
};
/* operation types */
enum {
LD_OP_HELLO = 1,
LD_OP_QUIT,
LD_OP_INIT,
LD_OP_FREE,
LD_OP_START,
LD_OP_STOP,
LD_OP_LOCK,
LD_OP_UPDATE,
LD_OP_CLOSE,
LD_OP_ENABLE,
LD_OP_DISABLE,
LD_OP_START_WAIT,
LD_OP_STOP_ALL,
LD_OP_DUMP_INFO,
LD_OP_DUMP_LOG,
LD_OP_RENAME_BEFORE,
LD_OP_RENAME_FINAL,
LD_OP_RUNNING_LM,
LD_OP_FIND_FREE_LOCK,
LD_OP_KILL_VG,
LD_OP_DROP_VG,
LD_OP_BUSY,
};
/* resource types */
enum {
LD_RT_GL = 1,
LD_RT_VG,
LD_RT_LV,
};
/* lock modes, more restrictive must be larger value */
enum {
LD_LK_IV = -1,
LD_LK_UN = 0,
LD_LK_NL = 1,
LD_LK_SH = 2,
LD_LK_EX = 3,
};
struct list_head {
struct list_head *next, *prev;
};
struct client {
struct list_head list;
pthread_mutex_t mutex;
int pid;
int fd;
int pi;
uint32_t id;
unsigned int recv : 1;
unsigned int dead : 1;
unsigned int poll_ignore : 1;
unsigned int lock_ops : 1;
char name[MAX_NAME+1];
};
#define LD_AF_PERSISTENT 0x00000001
#define LD_AF_NO_CLIENT 0x00000002
#define LD_AF_UNLOCK_CANCEL 0x00000004
#define LD_AF_NEXT_VERSION 0x00000008
#define LD_AF_WAIT 0x00000010
#define LD_AF_FORCE 0x00000020
#define LD_AF_EX_DISABLE 0x00000040
#define LD_AF_ENABLE 0x00000080
#define LD_AF_DISABLE 0x00000100
#define LD_AF_SEARCH_LS 0x00000200
#define LD_AF_WAIT_STARTING 0x00001000
#define LD_AF_DUP_GL_LS 0x00002000
#define LD_AF_ADOPT 0x00010000
#define LD_AF_WARN_GL_REMOVED 0x00020000
#define LD_AF_LV_LOCK 0x00040000
#define LD_AF_LV_UNLOCK 0x00080000
/*
* Number of times to repeat a lock request after
* a lock conflict (-EAGAIN) if unspecified in the
* request.
*/
#define DEFAULT_MAX_RETRIES 4
struct action {
struct list_head list;
uint32_t client_id;
uint32_t flags; /* LD_AF_ */
uint32_t version;
uint64_t host_id;
int8_t op; /* operation type LD_OP_ */
int8_t rt; /* resource type LD_RT_ */
int8_t mode; /* lock mode LD_LK_ */
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
int retries;
int max_retries;
int result;
int lm_rv; /* return value from lm_ function */
char vg_uuid[64];
char vg_name[MAX_NAME+1];
char lv_name[MAX_NAME+1];
char lv_uuid[MAX_NAME+1];
char vg_args[MAX_ARGS+1];
char lv_args[MAX_ARGS+1];
char vg_sysid[MAX_NAME+1];
};
struct resource {
struct list_head list; /* lockspace.resources */
char name[MAX_NAME+1]; /* vg name or lv name */
int8_t type; /* resource type LD_RT_ */
int8_t mode;
unsigned int sh_count; /* number of sh locks on locks list */
uint32_t version;
uint32_t last_client_id; /* last client_id to lock or unlock 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;
char lv_args[MAX_ARGS+1];
char lm_data[0]; /* lock manager specific data */
};
#define LD_LF_PERSISTENT 0x00000001
struct lock {
struct list_head list; /* resource.locks */
int8_t mode; /* lock mode LD_LK_ */
uint32_t version;
uint32_t flags; /* LD_LF_ */
uint32_t client_id; /* may be 0 for persistent or internal locks */
};
struct lockspace {
struct list_head list; /* lockspaces */
char name[MAX_NAME+1];
char vg_name[MAX_NAME+1];
char vg_uuid[64];
char vg_args[MAX_ARGS+1]; /* lock manager specific args */
char vg_sysid[MAX_NAME+1];
int8_t lm_type; /* lock manager: LM_DLM, LM_SANLOCK */
void *lm_data;
uint64_t host_id;
uint64_t free_lock_offset; /* start search for free lock here */
uint32_t start_client_id; /* client_id that started the lockspace */
pthread_t thread; /* makes synchronous lock requests */
pthread_cond_t cond;
pthread_mutex_t mutex;
unsigned int create_fail : 1;
unsigned int create_done : 1;
unsigned int thread_work : 1;
unsigned int thread_stop : 1;
unsigned int thread_done : 1;
unsigned int sanlock_gl_enabled: 1;
unsigned int sanlock_gl_dup: 1;
unsigned int free_vg: 1;
unsigned int kill_vg: 1;
unsigned int drop_vg: 1;
struct list_head actions; /* new client actions */
struct list_head resources; /* resource/lock state for gl/vg/lv */
};
/* val_blk version */
#define VAL_BLK_VERSION 0x0101
/* val_blk flags */
#define VBF_REMOVED 0x0001
struct val_blk {
uint16_t version;
uint16_t flags;
uint32_t r_version;
};
/* lm_unlock flags */
#define LMUF_FREE_VG 0x00000001
#define container_of(ptr, type, member) ({ \
const typeof( ((type *)0)->member ) *__mptr = (ptr); \
(type *)( (char *)__mptr - offsetof(type,member) );})
static inline void INIT_LIST_HEAD(struct list_head *list)
{
list->next = list;
list->prev = list;
}
static inline void __list_add(struct list_head *new,
struct list_head *prev,
struct list_head *next)
{
next->prev = new;
new->next = next;
new->prev = prev;
prev->next = new;
}
static inline void __list_del(struct list_head *prev, struct list_head *next)
{
next->prev = prev;
prev->next = next;
}
static inline void list_add(struct list_head *new, struct list_head *head)
{
__list_add(new, head, head->next);
}
static inline void list_add_tail(struct list_head *new, struct list_head *head)
{
__list_add(new, head->prev, head);
}
static inline void list_del(struct list_head *entry)
{
__list_del(entry->prev, entry->next);
}
static inline int list_empty(const struct list_head *head)
{
return head->next == head;
}
#define list_entry(ptr, type, member) \
container_of(ptr, type, member)
#define list_first_entry(ptr, type, member) \
list_entry((ptr)->next, type, member)
#define list_for_each_entry(pos, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member); \
&pos->member != (head); \
pos = list_entry(pos->member.next, typeof(*pos), member))
#define list_for_each_entry_safe(pos, n, head, member) \
for (pos = list_entry((head)->next, typeof(*pos), member), \
n = list_entry(pos->member.next, typeof(*pos), member); \
&pos->member != (head); \
pos = n, n = list_entry(n->member.next, typeof(*n), member))
/* to improve readability */
#define WAIT 1
#define NO_WAIT 0
#define FORCE 1
#define NO_FORCE 0
/*
* global variables
*/
#ifndef EXTERN
#define EXTERN extern
#define INIT(X)
#else
#undef EXTERN
#define EXTERN
#define INIT(X) =X
#endif
/*
* gl_type_static and gl_use_ are set by command line or config file
* to specify whether the global lock comes from dlm or sanlock.
* Without a static setting, lvmlockd will figure out where the
* global lock should be (but it could get mixed up in cases where
* both sanlock and dlm vgs exist.)
*
* gl_use_dlm means that the gl should come from lockspace gl_lsname_dlm
* gl_use_sanlock means that the gl should come from lockspace gl_lsname_sanlock
*
* gl_use_dlm has precedence over gl_use_sanlock, so if a node sees both
* dlm and sanlock vgs, it will use the dlm gl.
*
* gl_use_ is set when the first evidence of that lm_type is seen
* in any command.
*
* gl_lsname_sanlock is set when the first vg is seen in which an
* enabled gl is exists, or when init_vg creates a vg with gl enabled,
* or when enable_gl is used.
*
* gl_lsname_sanlock is cleared when free_vg deletes a vg with gl enabled
* or when disable_gl matches.
*/
EXTERN int gl_type_static;
EXTERN int gl_use_dlm;
EXTERN int gl_use_sanlock;
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;
EXTERN int daemon_host_id;
EXTERN const char *daemon_host_id_file;
EXTERN int sanlock_io_timeout;
/*
* This flag is set to 1 if we see multiple vgs with the global
* lock enabled. While this is set, we return a special flag
* with the vg lock result indicating to the lvm command that
* there is a duplicate gl in the vg which should be resolved.
* While this is set, find_lockspace_name has the side job of
* counting the number of lockspaces with enabled gl's so that
* this can be set back to zero when the duplicates are disabled.
*/
EXTERN int sanlock_gl_dup;
void log_level(int level, const char *fmt, ...) __attribute__((format(printf, 2, 3)));
#define log_debug(fmt, args...) log_level(LOG_DEBUG, fmt, ##args)
#define log_error(fmt, args...) log_level(LOG_ERR, fmt, ##args)
#define log_warn(fmt, args...) log_level(LOG_WARNING, fmt, ##args)
struct lockspace *alloc_lockspace(void);
int lockspaces_empty(void);
int last_string_from_args(char *args_in, char *last);
int version_from_args(char *args, unsigned int *major, unsigned int *minor, unsigned int *patch);
#ifdef LOCKDDLM_SUPPORT
int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
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,
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,
uint32_t r_version, uint32_t lmu_flags);
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)
{
return 1;
}
#else
static inline int lm_init_vg_dlm(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
{
return -1;
}
static inline int lm_prepare_lockspace_dlm(struct lockspace *ls)
{
return -1;
}
static inline int lm_add_lockspace_dlm(struct lockspace *ls, int adopt)
{
return -1;
}
static inline int lm_rem_lockspace_dlm(struct lockspace *ls, int free_vg)
{
return -1;
}
static inline int lm_lock_dlm(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int adopt)
{
return -1;
}
static inline int lm_convert_dlm(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version)
{
return -1;
}
static inline int lm_unlock_dlm(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags)
{
return -1;
}
static inline int lm_rem_resource_dlm(struct lockspace *ls, struct resource *r)
{
return -1;
}
static inline int lm_get_lockspaces_dlm(struct list_head *ls_rejoin)
{
return -1;
}
static inline int lm_data_size_dlm(void)
{
return -1;
}
static inline int lm_is_running_dlm(void)
{
return 0;
}
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
int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, uint64_t free_offset);
int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r);
int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args);
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,
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,
uint32_t r_version, uint32_t lmu_flags);
int lm_able_gl_sanlock(struct lockspace *ls, int enable);
int lm_ex_disable_gl_sanlock(struct lockspace *ls);
int lm_hosts_sanlock(struct lockspace *ls, int notify);
int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r);
int lm_gl_is_enabled(struct lockspace *ls);
int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin);
int lm_data_size_sanlock(void);
int lm_is_running_sanlock(void);
int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset);
static inline int lm_support_sanlock(void)
{
return 1;
}
#else
static inline int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
{
return -1;
}
static inline int lm_init_lv_sanlock(char *ls_name, char *vg_name, char *lv_name, char *vg_args, char *lv_args, uint64_t free_offset)
{
return -1;
}
static inline int lm_free_lv_sanlock(struct lockspace *ls, struct resource *r)
{
return -1;
}
static inline int lm_rename_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_args)
{
return -1;
}
static inline int lm_prepare_lockspace_sanlock(struct lockspace *ls)
{
return -1;
}
static inline int lm_add_lockspace_sanlock(struct lockspace *ls, int adopt)
{
return -1;
}
static inline int lm_rem_lockspace_sanlock(struct lockspace *ls, int free_vg)
{
return -1;
}
static inline int lm_lock_sanlock(struct lockspace *ls, struct resource *r, int ld_mode,
struct val_blk *vb_out, int *retry, int adopt)
{
return -1;
}
static inline int lm_convert_sanlock(struct lockspace *ls, struct resource *r,
int ld_mode, uint32_t r_version)
{
return -1;
}
static inline int lm_unlock_sanlock(struct lockspace *ls, struct resource *r,
uint32_t r_version, uint32_t lmu_flags)
{
return -1;
}
static inline int lm_able_gl_sanlock(struct lockspace *ls, int enable)
{
return -1;
}
static inline int lm_ex_disable_gl_sanlock(struct lockspace *ls)
{
return -1;
}
static inline int lm_hosts_sanlock(struct lockspace *ls, int notify)
{
return -1;
}
static inline int lm_rem_resource_sanlock(struct lockspace *ls, struct resource *r)
{
return -1;
}
static inline int lm_gl_is_enabled(struct lockspace *ls)
{
return -1;
}
static inline int lm_get_lockspaces_sanlock(struct list_head *ls_rejoin)
{
return -1;
}
static inline int lm_data_size_sanlock(void)
{
return -1;
}
static inline int lm_is_running_sanlock(void)
{
return 0;
}
static inline int lm_find_free_lock_sanlock(struct lockspace *ls, uint64_t *free_offset)
{
return -1;
}
static inline int lm_support_sanlock(void)
{
return 0;
}
#endif /* sanlock support */
#endif /* _LVM_LVMLOCKD_INTERNAL_H */

File diff suppressed because it is too large Load Diff

1
daemons/lvmpolld/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
lvmpolld

View File

@ -0,0 +1,48 @@
#
# Copyright (C) 2014-2015 Red Hat, Inc.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU Lesser General Public License v.2.1.
#
# You should have received a copy of the GNU Lesser General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = lvmpolld-core.c lvmpolld-data-utils.c lvmpolld-cmd-utils.c
TARGETS = lvmpolld
.PHONY: install_lvmpolld
CFLOW_LIST = $(SOURCES)
CFLOW_LIST_TARGET = $(LIB_NAME).cflow
CFLOW_TARGET = lvmpolld
include $(top_builddir)/make.tmpl
INCLUDES += -I$(top_srcdir)/libdaemon/server
LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
LDFLAGS += -L$(top_builddir)/libdaemon/server $(DAEMON_LDFLAGS)
CLDFLAGS += -L$(top_builddir)/libdaemon/server
CFLAGS += $(DAEMON_CFLAGS)
lvmpolld: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) $(LVMLIBS) $(LIBS)
install_lvmpolld: lvmpolld
$(INSTALL_PROGRAM) -D $< $(sbindir)/$(<F)
install_lvm2: install_lvmpolld
install: install_lvm2

View File

@ -0,0 +1,144 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lvmpolld-common.h"
/* extract this info from autoconf/automake files */
#define LVPOLL_CMD "lvpoll"
#define MIN_ARGV_SIZE 8
static const char *const const polling_ops[] = { [PVMOVE] = LVMPD_REQ_PVMOVE,
[CONVERT] = LVMPD_REQ_CONVERT,
[MERGE] = LVMPD_REQ_MERGE,
[MERGE_THIN] = LVMPD_REQ_MERGE_THIN };
const char *polling_op(enum poll_type type)
{
return type < POLL_TYPE_MAX ? polling_ops[type] : "<undefined>";
}
static int add_to_cmd_arr(const char ***cmdargv, const char *str, unsigned *ind)
{
const char **newargv = *cmdargv;
if (*ind && !(*ind % MIN_ARGV_SIZE)) {
newargv = dm_realloc(*cmdargv, (*ind / MIN_ARGV_SIZE + 1) * MIN_ARGV_SIZE * sizeof(char *));
if (!newargv)
return 0;
*cmdargv = newargv;
}
*(*cmdargv + (*ind)++) = str;
return 1;
}
const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary, unsigned abort_polling, unsigned handle_missing_pvs)
{
unsigned i = 0;
const char **cmd_argv = dm_malloc(MIN_ARGV_SIZE * sizeof(char *));
if (!cmd_argv)
return NULL;
/* path to lvm2 binary */
if (!add_to_cmd_arr(&cmd_argv, lvm_binary, &i))
goto err;
/* cmd to execute */
if (!add_to_cmd_arr(&cmd_argv, LVPOLL_CMD, &i))
goto err;
/* transfer internal polling interval */
if (pdlv->sinterval &&
(!add_to_cmd_arr(&cmd_argv, "--interval", &i) ||
!add_to_cmd_arr(&cmd_argv, pdlv->sinterval, &i)))
goto err;
/* pass abort param */
if (abort_polling &&
!add_to_cmd_arr(&cmd_argv, "--abort", &i))
goto err;
/* pass handle-missing-pvs. used by mirror polling operation */
if (handle_missing_pvs &&
!add_to_cmd_arr(&cmd_argv, "--handlemissingpvs", &i))
goto err;
/* one of: "convert", "pvmove", "merge", "merge_thin" */
if (!add_to_cmd_arr(&cmd_argv, "--polloperation", &i) ||
!add_to_cmd_arr(&cmd_argv, polling_ops[pdlv->type], &i))
goto err;
/* vg/lv name */
if (!add_to_cmd_arr(&cmd_argv, pdlv->lvname, &i))
goto err;
/* disable metadata backup */
if (!add_to_cmd_arr(&cmd_argv, "-An", &i))
goto err;
/* terminating NULL */
if (!add_to_cmd_arr(&cmd_argv, NULL, &i))
goto err;
return cmd_argv;
err:
dm_free(cmd_argv);
return NULL;
}
/* FIXME: in fact exclude should be va list */
static int copy_env(const char ***cmd_envp, unsigned *i, const char *exclude)
{
const char * const* tmp = (const char * const*) environ;
if (!tmp)
return 0;
while (*tmp) {
if (strncmp(*tmp, exclude, strlen(exclude)) && !add_to_cmd_arr(cmd_envp, *tmp, i))
return 0;
tmp++;
}
return 1;
}
const char **cmdenvp_ctr(const struct lvmpolld_lv *pdlv)
{
unsigned i = 0;
const char **cmd_envp = dm_malloc(MIN_ARGV_SIZE * sizeof(char *));
if (!cmd_envp)
return NULL;
/* copy whole environment from lvmpolld, exclude LVM_SYSTEM_DIR if set */
if (!copy_env(&cmd_envp, &i, "LVM_SYSTEM_DIR="))
goto err;
/* Add per client LVM_SYSTEM_DIR variable if set */
if (*pdlv->lvm_system_dir_env && !add_to_cmd_arr(&cmd_envp, pdlv->lvm_system_dir_env, &i))
goto err;
/* terminating NULL */
if (!add_to_cmd_arr(&cmd_envp, NULL, &i))
goto err;
return cmd_envp;
err:
dm_free(cmd_envp);
return NULL;
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LVMPOLLD_CMD_UTILS_H
#define _LVM_LVMPOLLD_CMD_UTILS_H
#include "lvmpolld-data-utils.h"
const char **cmdargv_ctr(const struct lvmpolld_lv *pdlv, const char *lvm_binary, unsigned abort, unsigned handle_missing_pvs);
const char **cmdenvp_ctr(const struct lvmpolld_lv *pdlv);
const char *polling_op(enum poll_type);
#endif /* _LVM_LVMPOLLD_CMD_UTILS_H */

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2006 Rackable Systems All rights reserved.
* Copyright (C) 2010-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -12,22 +12,20 @@
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TIMESTAMP_H
#define _LVM_TIMESTAMP_H
struct timestamp;
struct timestamp *get_timestamp(void);
/* cmp_timestamp: Compare two timestamps
*
* Return: -1 if t1 is less than t2
* 0 if t1 is equal to t2
* 1 if t1 is greater than t2
/*
* This file must be included first by every lvmpolld source file.
*/
int cmp_timestamp(struct timestamp *t1, struct timestamp *t2);
#ifndef _LVM_LVMPOLLD_COMMON_H
#define _LVM_LVMPOLLD_COMMON_H
void destroy_timestamp(struct timestamp *t);
#define _REENTRANT
#endif /* _LVM_TIMESTAMP_H */
#include "tool.h"
#include "lvmpolld-cmd-utils.h"
#include "lvmpolld-protocol.h"
#include <assert.h>
#include <errno.h>
#endif /* _LVM_LVMPOLLD_COMMON_H */

View File

@ -0,0 +1,999 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lvmpolld-common.h"
#include "lvm-version.h"
#include "daemon-server.h"
#include "daemon-log.h"
#include <getopt.h>
#include <poll.h>
#include <wait.h>
#define LVMPOLLD_SOCKET DEFAULT_RUN_DIR "/lvmpolld.socket"
#define PD_LOG_PREFIX "LVMPOLLD"
#define LVM2_LOG_PREFIX "\tLVPOLL"
/* predefined reason for response = "failed" case */
#define REASON_REQ_NOT_IMPLEMENTED "request not implemented"
#define REASON_MISSING_LVID "request requires lvid set"
#define REASON_MISSING_LVNAME "request requires lvname set"
#define REASON_MISSING_VGNAME "request requires vgname set"
#define REASON_POLLING_FAILED "polling of lvm command failed"
#define REASON_ILLEGAL_ABORT_REQUEST "abort only supported with PVMOVE polling operation"
#define REASON_DIFFERENT_OPERATION_IN_PROGRESS "Different operation on LV already in progress"
#define REASON_INVALID_INTERVAL "request requires interval set"
#define REASON_ENOMEM "not enough memory"
struct lvmpolld_state {
daemon_idle *idle;
log_state *log;
const char *log_config;
const char *lvm_binary;
struct lvmpolld_store *id_to_pdlv_abort;
struct lvmpolld_store *id_to_pdlv_poll;
};
static pthread_key_t key;
static const char *_strerror_r(int errnum, struct lvmpolld_thread_data *data)
{
#ifdef _GNU_SOURCE
return strerror_r(errnum, data->buf, sizeof(data->buf)); /* never returns NULL */
#elif (_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600)
return strerror_r(errnum, data->buf, sizeof(data->buf)) ? "" : data->buf;
#else
# warning "Can't decide proper strerror_r implementation. lvmpolld will not issue specific system error messages"
return "";
#endif
}
static void _usage(const char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
"%s [-V] [-h] [-f] [-l {all|wire|debug}] [-s path] [-B path] [-p path] [-t secs]\n"
"%s --dump [-s path]\n"
" -V|--version Show version info\n"
" -h|--help Show this help information\n"
" -f|--foreground Don't fork, run in the foreground\n"
" --dump Dump full lvmpolld state\n"
" -l|--log Logging message level (-l {all|wire|debug})\n"
" -p|--pidfile Set path to the pidfile\n"
" -s|--socket Set path to the communication socket\n"
" -B|--binary Path to lvm2 binary\n"
" -t|--timeout Time to wait in seconds before shutdown on idle (missing or 0 = inifinite)\n\n", prog, prog);
}
static int _init(struct daemon_state *s)
{
struct lvmpolld_state *ls = s->private;
ls->log = s->log;
/*
* log warnings to stderr by default. Otherwise we would miss any lvpoll
* error messages in default configuration
*/
daemon_log_enable(ls->log, DAEMON_LOG_OUTLET_STDERR, DAEMON_LOG_WARN, 1);
if (!daemon_log_parse(ls->log, DAEMON_LOG_OUTLET_STDERR, ls->log_config, 1))
return 0;
if (pthread_key_create(&key, lvmpolld_thread_data_destroy)) {
FATAL(ls, "%s: %s", PD_LOG_PREFIX, "Failed to create pthread key");
return 0;
}
ls->id_to_pdlv_poll = pdst_init("polling");
ls->id_to_pdlv_abort = pdst_init("abort");
if (!ls->id_to_pdlv_poll || !ls->id_to_pdlv_abort) {
FATAL(ls, "%s: %s", PD_LOG_PREFIX, "Failed to allocate internal data structures");
return 0;
}
ls->lvm_binary = ls->lvm_binary ?: LVM_PATH;
if (access(ls->lvm_binary, X_OK)) {
FATAL(ls, "%s: %s %s", PD_LOG_PREFIX, "Execute access rights denied on", ls->lvm_binary);
return 0;
}
if (ls->idle)
ls->idle->is_idle = 1;
return 1;
}
static void _lvmpolld_stores_lock(struct lvmpolld_state *ls)
{
pdst_lock(ls->id_to_pdlv_poll);
pdst_lock(ls->id_to_pdlv_abort);
}
static void _lvmpolld_stores_unlock(struct lvmpolld_state *ls)
{
pdst_unlock(ls->id_to_pdlv_abort);
pdst_unlock(ls->id_to_pdlv_poll);
}
static void _lvmpolld_global_lock(struct lvmpolld_state *ls)
{
_lvmpolld_stores_lock(ls);
pdst_locked_lock_all_pdlvs(ls->id_to_pdlv_poll);
pdst_locked_lock_all_pdlvs(ls->id_to_pdlv_abort);
}
static void _lvmpolld_global_unlock(struct lvmpolld_state *ls)
{
pdst_locked_unlock_all_pdlvs(ls->id_to_pdlv_abort);
pdst_locked_unlock_all_pdlvs(ls->id_to_pdlv_poll);
_lvmpolld_stores_unlock(ls);
}
static int _fini(struct daemon_state *s)
{
int done;
const struct timespec t = { .tv_nsec = 250000000 }; /* .25 sec */
struct lvmpolld_state *ls = s->private;
DEBUGLOG(s, "fini");
DEBUGLOG(s, "sending cancel requests");
_lvmpolld_global_lock(ls);
pdst_locked_send_cancel(ls->id_to_pdlv_poll);
pdst_locked_send_cancel(ls->id_to_pdlv_abort);
_lvmpolld_global_unlock(ls);
DEBUGLOG(s, "waiting for background threads to finish");
while(1) {
_lvmpolld_stores_lock(ls);
done = !pdst_locked_get_active_count(ls->id_to_pdlv_poll) &&
!pdst_locked_get_active_count(ls->id_to_pdlv_abort);
_lvmpolld_stores_unlock(ls);
if (done)
break;
nanosleep(&t, NULL);
}
DEBUGLOG(s, "destroying internal data structures");
_lvmpolld_stores_lock(ls);
pdst_locked_destroy_all_pdlvs(ls->id_to_pdlv_poll);
pdst_locked_destroy_all_pdlvs(ls->id_to_pdlv_abort);
_lvmpolld_stores_unlock(ls);
pdst_destroy(ls->id_to_pdlv_poll);
pdst_destroy(ls->id_to_pdlv_abort);
pthread_key_delete(key);
return 1;
}
static response reply(const char *res, const char *reason)
{
return daemon_reply_simple(res, "reason = %s", reason, NULL);
}
static int read_single_line(struct lvmpolld_thread_data *data, int err)
{
ssize_t r = getline(&data->line, &data->line_size, err ? data->ferr : data->fout);
if (r > 0 && *(data->line + r - 1) == '\n')
*(data->line + r - 1) = '\0';
return (r > 0);
}
static void update_idle_state(struct lvmpolld_state *ls)
{
if (!ls->idle)
return;
_lvmpolld_stores_lock(ls);
ls->idle->is_idle = !pdst_locked_get_active_count(ls->id_to_pdlv_poll) &&
!pdst_locked_get_active_count(ls->id_to_pdlv_abort);
_lvmpolld_stores_unlock(ls);
DEBUGLOG(ls, "%s: %s %s%s", PD_LOG_PREFIX, "daemon is", ls->idle->is_idle ? "" : "not ", "idle");
}
/* make this configurable */
#define MAX_TIMEOUT 2
static int poll_for_output(struct lvmpolld_lv *pdlv, struct lvmpolld_thread_data *data)
{
int ch_stat, r, err = 1, fds_count = 2, timeout = 0;
pid_t pid;
struct lvmpolld_cmd_stat cmd_state = { .retcode = -1, .signal = 0 };
struct pollfd fds[] = { { .fd = data->outpipe[0], .events = POLLIN },
{ .fd = data->errpipe[0], .events = POLLIN } };
if (!(data->fout = fdopen(data->outpipe[0], "r")) || !(data->ferr = fdopen(data->errpipe[0], "r"))) {
ERROR(pdlv->ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to open file stream",
errno, _strerror_r(errno, data));
goto out;
}
while (1) {
do {
r = poll(fds, 2, pdlv_get_timeout(pdlv) * 1000);
} while (r < 0 && errno == EINTR);
DEBUGLOG(pdlv->ls, "%s: %s %d", PD_LOG_PREFIX, "poll() returned", r);
if (r < 0) {
ERROR(pdlv->ls, "%s: %s (PID %d) failed: (%d) %s",
PD_LOG_PREFIX, "poll() for LVM2 cmd", pdlv->cmd_pid,
errno, _strerror_r(errno, data));
goto out;
} else if (!r) {
timeout++;
WARN(pdlv->ls, "%s: %s (PID %d) %s", PD_LOG_PREFIX,
"polling for output of the lvm cmd", pdlv->cmd_pid,
"has timed out");
if (timeout > MAX_TIMEOUT) {
ERROR(pdlv->ls, "%s: %s (PID %d) (no output for %d seconds)",
PD_LOG_PREFIX,
"LVM2 cmd is unresponsive too long",
pdlv->cmd_pid,
timeout * pdlv_get_timeout(pdlv));
goto out;
}
continue; /* while(1) */
}
timeout = 0;
/* handle the command's STDOUT */
if (fds[0].revents & POLLIN) {
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught input data in STDOUT");
assert(read_single_line(data, 0)); /* may block indef. anyway */
INFO(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
pdlv->cmd_pid, "STDOUT", data->line);
} else if (fds[0].revents) {
if (fds[0].revents & POLLHUP)
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught POLLHUP");
else
WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "poll for command's STDOUT failed");
fds[0].fd = -1;
fds_count--;
}
/* handle the command's STDERR */
if (fds[1].revents & POLLIN) {
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX,
"caught input data in STDERR");
assert(read_single_line(data, 1)); /* may block indef. anyway */
WARN(pdlv->ls, "%s: PID %d: %s: '%s'", LVM2_LOG_PREFIX,
pdlv->cmd_pid, "STDERR", data->line);
} else if (fds[1].revents) {
if (fds[1].revents & POLLHUP)
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "caught err POLLHUP");
else
WARN(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "poll for command's STDOUT failed");
fds[1].fd = -1;
fds_count--;
}
do {
/*
* fds_count == 0 means polling reached EOF
* or received error on both descriptors.
* In such case, just wait for command to finish
*/
pid = waitpid(pdlv->cmd_pid, &ch_stat, fds_count ? WNOHANG : 0);
} while (pid < 0 && errno == EINTR);
if (pid) {
if (pid < 0) {
ERROR(pdlv->ls, "%s: %s (PID %d) failed: (%d) %s",
PD_LOG_PREFIX, "waitpid() for lvm2 cmd",
pdlv->cmd_pid, errno,
_strerror_r(errno, data));
goto out;
}
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "child exited");
break;
}
} /* while(1) */
DEBUGLOG(pdlv->ls, "%s: %s", PD_LOG_PREFIX, "about to collect remaining lines");
if (fds[0].fd >= 0)
while (read_single_line(data, 0)) {
assert(r > 0);
INFO(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDOUT", data->line);
}
if (fds[1].fd >= 0)
while (read_single_line(data, 1)) {
assert(r > 0);
WARN(pdlv->ls, "%s: PID %d: %s: %s", LVM2_LOG_PREFIX, pdlv->cmd_pid, "STDERR", data->line);
}
if (WIFEXITED(ch_stat)) {
cmd_state.retcode = WEXITSTATUS(ch_stat);
if (cmd_state.retcode)
ERROR(pdlv->ls, "%s: %s (PID %d) %s (retcode: %d)", PD_LOG_PREFIX,
"lvm2 cmd", pdlv->cmd_pid, "failed", cmd_state.retcode);
else
INFO(pdlv->ls, "%s: %s (PID %d) %s", PD_LOG_PREFIX,
"lvm2 cmd", pdlv->cmd_pid, "finished successfully");
} else if (WIFSIGNALED(ch_stat)) {
ERROR(pdlv->ls, "%s: %s (PID %d) %s (%d)", PD_LOG_PREFIX,
"lvm2 cmd", pdlv->cmd_pid, "got terminated by signal",
WTERMSIG(ch_stat));
cmd_state.signal = WTERMSIG(ch_stat);
}
err = 0;
out:
if (!err)
pdlv_set_cmd_state(pdlv, &cmd_state);
return err;
}
static void debug_print(struct lvmpolld_state *ls, const char * const* ptr)
{
const char * const* tmp = ptr;
if (!tmp)
return;
while (*tmp) {
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, *tmp);
tmp++;
}
}
static void *fork_and_poll(void *args)
{
int outfd, errfd, state;
struct lvmpolld_thread_data *data;
pid_t r;
int error = 1;
struct lvmpolld_lv *pdlv = (struct lvmpolld_lv *) args;
struct lvmpolld_state *ls = pdlv->ls;
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
data = lvmpolld_thread_data_constructor(pdlv);
pthread_setspecific(key, data);
pthread_setcancelstate(state, &state);
if (!data) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "Failed to initialize per-thread data");
goto err;
}
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd line arguments:");
debug_print(ls, pdlv->cmdargv);
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "cmd environment variables:");
debug_print(ls, pdlv->cmdenvp);
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "---end---");
outfd = data->outpipe[1];
errfd = data->errpipe[1];
r = fork();
if (!r) {
/* child */
/* !!! Do not touch any posix thread primitives !!! */
if ((dup2(outfd, STDOUT_FILENO ) != STDOUT_FILENO) ||
(dup2(errfd, STDERR_FILENO ) != STDERR_FILENO))
_exit(LVMPD_RET_DUP_FAILED);
execve(*(pdlv->cmdargv), (char *const *)pdlv->cmdargv, (char *const *)pdlv->cmdenvp);
_exit(LVMPD_RET_EXC_FAILED);
} else {
/* parent */
if (r == -1) {
ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "fork failed",
errno, _strerror_r(errno, data));
goto err;
}
INFO(ls, "%s: LVM2 cmd \"%s\" (PID: %d)", PD_LOG_PREFIX, *(pdlv->cmdargv), r);
pdlv->cmd_pid = r;
/* failure to close write end of any pipe will result in broken polling */
if (close(data->outpipe[1])) {
ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to close write end of pipe",
errno, _strerror_r(errno, data));
goto err;
}
data->outpipe[1] = -1;
if (close(data->errpipe[1])) {
ERROR(ls, "%s: %s: (%d) %s", PD_LOG_PREFIX, "failed to close write end of err pipe",
errno, _strerror_r(errno, data));
goto err;
}
data->errpipe[1] = -1;
error = poll_for_output(pdlv, data);
DEBUGLOG(ls, "%s: %s", PD_LOG_PREFIX, "polling for lvpoll output has finished");
}
err:
r = 0;
pdst_lock(pdlv->pdst);
if (error) {
/* last reader is responsible for pdlv cleanup */
r = pdlv->cmd_pid;
pdlv_set_error(pdlv, 1);
}
pdlv_set_polling_finished(pdlv, 1);
if (data)
data->pdlv = NULL;
pdst_locked_dec(pdlv->pdst);
pdst_unlock(pdlv->pdst);
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &state);
lvmpolld_thread_data_destroy(data);
pthread_setspecific(key, NULL);
pthread_setcancelstate(state, &state);
update_idle_state(ls);
/*
* This is unfortunate case where we
* know nothing about state of lvm cmd and
* (eventually) ongoing progress.
*
* harvest zombies
*/
if (r)
while(waitpid(r, NULL, 0) < 0 && errno == EINTR);
return NULL;
}
static response progress_info(client_handle h, struct lvmpolld_state *ls, request req)
{
char *id;
struct lvmpolld_lv *pdlv;
struct lvmpolld_store *pdst;
struct lvmpolld_lv_state st;
response r;
const char *lvid = daemon_request_str(req, LVMPD_PARM_LVID, NULL);
const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
if (!lvid)
return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVID);
id = construct_id(sysdir, lvid);
if (!id) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "progress_info request failed to construct ID.");
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
}
DEBUGLOG(ls, "%s: %s: %s", PD_LOG_PREFIX, "ID", id);
pdst = abort_polling ? ls->id_to_pdlv_abort : ls->id_to_pdlv_poll;
pdst_lock(pdst);
pdlv = pdst_locked_lookup(pdst, id);
if (pdlv) {
/*
* with store lock held, I'm the only reader accessing the pdlv
*/
st = pdlv_get_status(pdlv);
if (st.error || st.polling_finished) {
INFO(ls, "%s: %s %s", PD_LOG_PREFIX,
"Polling finished. Removing related data structure for LV",
lvid);
pdst_locked_remove(pdst, id);
pdlv_destroy(pdlv);
}
}
/* pdlv must not be dereferenced from now on */
pdst_unlock(pdst);
dm_free(id);
if (pdlv) {
if (st.error)
return reply(LVMPD_RESP_FAILED, REASON_POLLING_FAILED);
if (st.polling_finished)
r = daemon_reply_simple(LVMPD_RESP_FINISHED,
"reason = %s", st.cmd_state.signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE,
LVMPD_PARM_VALUE " = %d", (int64_t)(st.cmd_state.signal ?: st.cmd_state.retcode),
NULL);
else
r = daemon_reply_simple(LVMPD_RESP_IN_PROGRESS, NULL);
}
else
r = daemon_reply_simple(LVMPD_RESP_NOT_FOUND, NULL);
return r;
}
static struct lvmpolld_lv *construct_pdlv(request req, struct lvmpolld_state *ls,
struct lvmpolld_store *pdst,
const char *interval, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
unsigned abort_polling, unsigned uinterval)
{
const char **cmdargv, **cmdenvp;
struct lvmpolld_lv *pdlv;
unsigned handle_missing_pvs = daemon_request_int(req, LVMPD_PARM_HANDLE_MISSING_PVS, 0);
pdlv = pdlv_create(ls, id, vgname, lvname, sysdir, type,
interval, uinterval, pdst);
if (!pdlv) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to create internal LV data structure.");
return NULL;
}
cmdargv = cmdargv_ctr(pdlv, pdlv->ls->lvm_binary, abort_polling, handle_missing_pvs);
if (!cmdargv) {
pdlv_destroy(pdlv);
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to construct cmd arguments for lvpoll command");
return NULL;
}
pdlv->cmdargv = cmdargv;
cmdenvp = cmdenvp_ctr(pdlv);
if (!cmdenvp) {
pdlv_destroy(pdlv);
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to construct cmd environment for lvpoll command");
return NULL;
}
pdlv->cmdenvp = cmdenvp;
return pdlv;
}
static int spawn_detached_thread(struct lvmpolld_lv *pdlv)
{
int r;
pthread_attr_t attr;
if (pthread_attr_init(&attr) != 0)
return 0;
if (pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
return 0;
r = pthread_create(&pdlv->tid, &attr, fork_and_poll, (void *)pdlv);
if (pthread_attr_destroy(&attr) != 0)
return 0;
return !r;
}
static response poll_init(client_handle h, struct lvmpolld_state *ls, request req, enum poll_type type)
{
char *id;
struct lvmpolld_lv *pdlv;
struct lvmpolld_store *pdst;
unsigned uinterval;
const char *interval = daemon_request_str(req, LVMPD_PARM_INTERVAL, NULL);
const char *lvid = daemon_request_str(req, LVMPD_PARM_LVID, NULL);
const char *lvname = daemon_request_str(req, LVMPD_PARM_LVNAME, NULL);
const char *vgname = daemon_request_str(req, LVMPD_PARM_VGNAME, NULL);
const char *sysdir = daemon_request_str(req, LVMPD_PARM_SYSDIR, NULL);
unsigned abort_polling = daemon_request_int(req, LVMPD_PARM_ABORT, 0);
assert(type < POLL_TYPE_MAX);
if (abort_polling && type != PVMOVE)
return reply(LVMPD_RESP_EINVAL, REASON_ILLEGAL_ABORT_REQUEST);
if (!interval || strpbrk(interval, "-") || sscanf(interval, "%u", &uinterval) != 1)
return reply(LVMPD_RESP_EINVAL, REASON_INVALID_INTERVAL);
if (!lvname)
return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVNAME);
if (!lvid)
return reply(LVMPD_RESP_FAILED, REASON_MISSING_LVID);
if (!vgname)
return reply(LVMPD_RESP_FAILED, REASON_MISSING_VGNAME);
id = construct_id(sysdir, lvid);
if (!id) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "poll_init request failed to construct ID.");
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
}
DEBUGLOG(ls, "%s: %s=%s", PD_LOG_PREFIX, "ID", id);
pdst = abort_polling ? ls->id_to_pdlv_abort : ls->id_to_pdlv_poll;
pdst_lock(pdst);
pdlv = pdst_locked_lookup(pdst, id);
if (pdlv && pdlv_get_polling_finished(pdlv)) {
WARN(ls, "%s: %s %s", PD_LOG_PREFIX, "Force removal of uncollected info for LV",
lvid);
/*
* lvmpolld has to remove uncollected results in this case.
* otherwise it would have to refuse request for new polling
* lv with same id.
*/
pdst_locked_remove(pdst, id);
pdlv_destroy(pdlv);
pdlv = NULL;
}
if (pdlv) {
if (!pdlv_is_type(pdlv, type)) {
pdst_unlock(pdst);
ERROR(ls, "%s: %s '%s': expected: %s, requested: %s",
PD_LOG_PREFIX, "poll operation type mismatch on LV identified by",
id,
polling_op(pdlv_get_type(pdlv)), polling_op(type));
dm_free(id);
return reply(LVMPD_RESP_EINVAL,
REASON_DIFFERENT_OPERATION_IN_PROGRESS);
}
pdlv->init_rq_count++; /* safe. protected by store lock */
} else {
pdlv = construct_pdlv(req, ls, pdst, interval, id, vgname,
lvname, sysdir, type, abort_polling, 2 * uinterval);
if (!pdlv) {
pdst_unlock(pdst);
dm_free(id);
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
}
if (!pdst_locked_insert(pdst, id, pdlv)) {
pdlv_destroy(pdlv);
pdst_unlock(pdst);
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "couldn't store internal LV data structure");
dm_free(id);
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
}
if (!spawn_detached_thread(pdlv)) {
ERROR(ls, "%s: %s", PD_LOG_PREFIX, "failed to spawn detached monitoring thread");
pdst_locked_remove(pdst, id);
pdlv_destroy(pdlv);
pdst_unlock(pdst);
dm_free(id);
return reply(LVMPD_RESP_FAILED, REASON_ENOMEM);
}
pdst_locked_inc(pdst);
if (ls->idle)
ls->idle->is_idle = 0;
}
pdst_unlock(pdst);
dm_free(id);
return daemon_reply_simple(LVMPD_RESP_OK, NULL);
}
static response dump_state(client_handle h, struct lvmpolld_state *ls, request r)
{
response res = { 0 };
struct buffer *b = &res.buffer;
buffer_init(b);
_lvmpolld_global_lock(ls);
buffer_append(b, "# Registered polling operations\n\n");
buffer_append(b, "poll {\n");
pdst_locked_dump(ls->id_to_pdlv_poll, b);
buffer_append(b, "}\n\n");
buffer_append(b, "# Registered abort operations\n\n");
buffer_append(b, "abort {\n");
pdst_locked_dump(ls->id_to_pdlv_abort, b);
buffer_append(b, "}");
_lvmpolld_global_unlock(ls);
return res;
}
static response _handler(struct daemon_state s, client_handle h, request r)
{
struct lvmpolld_state *ls = s.private;
const char *rq = daemon_request_str(r, "request", "NONE");
if (!strcmp(rq, LVMPD_REQ_PVMOVE))
return poll_init(h, ls, r, PVMOVE);
else if (!strcmp(rq, LVMPD_REQ_CONVERT))
return poll_init(h, ls, r, CONVERT);
else if (!strcmp(rq, LVMPD_REQ_MERGE))
return poll_init(h, ls, r, MERGE);
else if (!strcmp(rq, LVMPD_REQ_MERGE_THIN))
return poll_init(h, ls, r, MERGE_THIN);
else if (!strcmp(rq, LVMPD_REQ_PROGRESS))
return progress_info(h, ls, r);
else if (!strcmp(rq, LVMPD_REQ_DUMP))
return dump_state(h, ls, r);
else
return reply(LVMPD_RESP_EINVAL, REASON_REQ_NOT_IMPLEMENTED);
}
static int process_timeout_arg(const char *str, unsigned *max_timeouts)
{
char *endptr;
unsigned long l;
errno = 0;
l = strtoul(str, &endptr, 10);
if (errno || *endptr || l >= UINT_MAX)
return 0;
*max_timeouts = (unsigned) l;
return 1;
}
/* Client functionality */
typedef int (*action_fn_t) (void *args);
struct log_line_baton {
const char *prefix;
};
daemon_handle _lvmpolld = { .error = 0 };
static daemon_handle _lvmpolld_open(const char *socket)
{
daemon_info lvmpolld_info = {
.path = "lvmpolld",
.socket = socket ?: DEFAULT_RUN_DIR "/lvmpolld.socket",
.protocol = LVMPOLLD_PROTOCOL,
.protocol_version = LVMPOLLD_PROTOCOL_VERSION
};
return daemon_open(lvmpolld_info);
}
static void _log_line(const char *line, void *baton) {
struct log_line_baton *b = baton;
fprintf(stdout, "%s%s\n", b->prefix, line);
}
static int printout_raw_response(const char *prefix, const char *msg)
{
struct log_line_baton b = { .prefix = prefix };
char *buf;
char *pos;
buf = dm_strdup(msg);
pos = buf;
if (!buf)
return 0;
while (pos) {
char *next = strchr(pos, '\n');
if (next)
*next = 0;
_log_line(pos, &b);
pos = next ? next + 1 : 0;
}
dm_free(buf);
return 1;
}
/* place all action implementations below */
static int action_dump(void *args __attribute__((unused)))
{
daemon_request req;
daemon_reply repl;
int r = 0;
req = daemon_request_make(LVMPD_REQ_DUMP);
if (!req.cft) {
fprintf(stderr, "Failed to create lvmpolld " LVMPD_REQ_DUMP " request.\n");
goto out_req;
}
repl = daemon_send(_lvmpolld, req);
if (repl.error) {
fprintf(stderr, "Failed to send a request or receive response.\n");
goto out_rep;
}
/*
* This is dumb copy & paste from libdaemon log routines.
*/
if (!printout_raw_response(" ", repl.buffer.mem)) {
fprintf(stderr, "Failed to print out the response.\n");
goto out_rep;
}
r = 1;
out_rep:
daemon_reply_destroy(repl);
out_req:
daemon_request_destroy(req);
return r;
}
enum action_index {
ACTION_DUMP = 0,
ACTION_MAX /* keep at the end */
};
static const action_fn_t actions[ACTION_MAX] = { [ACTION_DUMP] = action_dump };
static int _make_action(enum action_index idx, void *args)
{
return idx < ACTION_MAX ? actions[idx](args) : 0;
}
static int _lvmpolld_client(const char *socket, unsigned action)
{
int r;
_lvmpolld = _lvmpolld_open(socket);
if (_lvmpolld.error || _lvmpolld.socket_fd < 0) {
fprintf(stderr, "Failed to establish connection with lvmpolld.\n");
return 0;
}
r = _make_action(action, NULL);
daemon_close(_lvmpolld);
return r ? EXIT_SUCCESS : EXIT_FAILURE;
}
static int action_idx = ACTION_MAX;
static struct option long_options[] = {
/* Have actions always at the beginning of the array. */
{"dump", no_argument, &action_idx, ACTION_DUMP }, /* or an option_index ? */
/* other options */
{"binary", required_argument, 0, 'B' },
{"foreground", no_argument, 0, 'f' },
{"help", no_argument, 0, 'h' },
{"log", required_argument, 0, 'l' },
{"pidfile", required_argument, 0, 'p' },
{"socket", required_argument, 0, 's' },
{"timeout", required_argument, 0, 't' },
{"version", no_argument, 0, 'V' },
{0, 0, 0, 0 }
};
int main(int argc, char *argv[])
{
int opt;
int option_index = 0;
int client = 0, server = 0;
unsigned action = ACTION_MAX;
struct timeval timeout;
daemon_idle di = { .ptimeout = &timeout };
struct lvmpolld_state ls = { .log_config = "" };
daemon_state s = {
.daemon_fini = _fini,
.daemon_init = _init,
.handler = _handler,
.name = "lvmpolld",
.pidfile = getenv("LVM_LVMPOLLD_PIDFILE") ?: LVMPOLLD_PIDFILE,
.private = &ls,
.protocol = LVMPOLLD_PROTOCOL,
.protocol_version = LVMPOLLD_PROTOCOL_VERSION,
.socket_path = getenv("LVM_LVMPOLLD_SOCKET") ?: LVMPOLLD_SOCKET,
};
while ((opt = getopt_long(argc, argv, "fhVl:p:s:B:t:", long_options, &option_index)) != -1) {
switch (opt) {
case 0 :
if (action < ACTION_MAX) {
fprintf(stderr, "Can't perform more actions. Action already requested: %s\n",
long_options[action].name);
_usage(argv[0], stderr);
exit(EXIT_FAILURE);
}
action = action_idx;
client = 1;
break;
case '?':
_usage(argv[0], stderr);
exit(EXIT_FAILURE);
case 'B': /* --binary */
ls.lvm_binary = optarg;
server = 1;
break;
case 'V': /* --version */
printf("lvmpolld version: " LVM_VERSION "\n");
exit(EXIT_SUCCESS);
case 'f': /* --foreground */
s.foreground = 1;
server = 1;
break;
case 'h': /* --help */
_usage(argv[0], stdout);
exit(EXIT_SUCCESS);
case 'l': /* --log */
ls.log_config = optarg;
server = 1;
break;
case 'p': /* --pidfile */
s.pidfile = optarg;
server = 1;
break;
case 's': /* --socket */
s.socket_path = optarg;
break;
case 't': /* --timeout in seconds */
if (!process_timeout_arg(optarg, &di.max_timeouts)) {
fprintf(stderr, "Invalid value of timeout parameter.\n");
exit(EXIT_FAILURE);
}
/* 0 equals to wait indefinitely */
if (di.max_timeouts)
s.idle = ls.idle = &di;
server = 1;
break;
}
}
if (client && server) {
fprintf(stderr, "Invalid combination of client and server parameters.\n\n");
_usage(argv[0], stdout);
exit(EXIT_FAILURE);
}
if (client)
return _lvmpolld_client(s.socket_path, action);
/* Server */
daemon_start(s);
return EXIT_SUCCESS;
}

View File

@ -0,0 +1,391 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include "lvmpolld-common.h"
#include "config-util.h"
#include <fcntl.h>
#include <signal.h>
static char *_construct_full_lvname(const char *vgname, const char *lvname)
{
char *name;
size_t l;
l = strlen(vgname) + strlen(lvname) + 2; /* vg/lv and \0 */
name = (char *) dm_malloc(l * sizeof(char));
if (!name)
return NULL;
if (dm_snprintf(name, l, "%s/%s", vgname, lvname) < 0) {
dm_free(name);
name = NULL;
}
return name;
}
static char *_construct_lvm_system_dir_env(const char *sysdir)
{
/*
* Store either "LVM_SYSTEM_DIR=/path/to..."
* - or -
* just single char to store NULL byte
*/
size_t l = sysdir ? strlen(sysdir) + 16 : 1;
char *env = (char *) dm_malloc(l * sizeof(char));
if (!env)
return NULL;
*env = '\0';
if (sysdir && dm_snprintf(env, l, "LVM_SYSTEM_DIR=%s", sysdir) < 0) {
dm_free(env);
env = NULL;
}
return env;
}
static const char *_get_lvid(const char *lvmpolld_id, const char *sysdir)
{
return lvmpolld_id ? (lvmpolld_id + (sysdir ? strlen(sysdir) : 0)) : NULL;
}
char *construct_id(const char *sysdir, const char *uuid)
{
char *id;
int r;
size_t l;
l = strlen(uuid) + (sysdir ? strlen(sysdir) : 0) + 1;
id = (char *) dm_malloc(l * sizeof(char));
if (!id)
return NULL;
r = sysdir ? dm_snprintf(id, l, "%s%s", sysdir, uuid) :
dm_snprintf(id, l, "%s", uuid);
if (r < 0) {
dm_free(id);
id = NULL;
}
return id;
}
struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
const char *sinterval, unsigned pdtimeout,
struct lvmpolld_store *pdst)
{
char *lvmpolld_id = dm_strdup(id), /* copy */
*full_lvname = _construct_full_lvname(vgname, lvname), /* copy */
*lvm_system_dir_env = _construct_lvm_system_dir_env(sysdir); /* copy */
struct lvmpolld_lv tmp = {
.ls = ls,
.type = type,
.lvmpolld_id = lvmpolld_id,
.lvid = _get_lvid(lvmpolld_id, sysdir),
.lvname = full_lvname,
.lvm_system_dir_env = lvm_system_dir_env,
.sinterval = dm_strdup(sinterval), /* copy */
.pdtimeout = pdtimeout < MIN_POLLING_TIMEOUT ? MIN_POLLING_TIMEOUT : pdtimeout,
.cmd_state = { .retcode = -1, .signal = 0 },
.pdst = pdst,
.init_rq_count = 1
}, *pdlv = (struct lvmpolld_lv *) dm_malloc(sizeof(struct lvmpolld_lv));
if (!pdlv || !tmp.lvid || !tmp.lvname || !tmp.lvm_system_dir_env || !tmp.sinterval)
goto err;
memcpy(pdlv, &tmp, sizeof(*pdlv));
if (pthread_mutex_init(&pdlv->lock, NULL))
goto err;
return pdlv;
err:
dm_free((void *)full_lvname);
dm_free((void *)lvmpolld_id);
dm_free((void *)lvm_system_dir_env);
dm_free((void *)tmp.sinterval);
dm_free((void *)pdlv);
return NULL;
}
void pdlv_destroy(struct lvmpolld_lv *pdlv)
{
dm_free((void *)pdlv->lvmpolld_id);
dm_free((void *)pdlv->lvname);
dm_free((void *)pdlv->sinterval);
dm_free((void *)pdlv->lvm_system_dir_env);
dm_free((void *)pdlv->cmdargv);
dm_free((void *)pdlv->cmdenvp);
pthread_mutex_destroy(&pdlv->lock);
dm_free((void *)pdlv);
}
unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv)
{
unsigned ret;
pdlv_lock(pdlv);
ret = pdlv->polling_finished;
pdlv_unlock(pdlv);
return ret;
}
struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv)
{
struct lvmpolld_lv_state r;
pdlv_lock(pdlv);
r.error = pdlv_locked_error(pdlv);
r.polling_finished = pdlv_locked_polling_finished(pdlv);
r.cmd_state = pdlv_locked_cmd_state(pdlv);
pdlv_unlock(pdlv);
return r;
}
void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state)
{
pdlv_lock(pdlv);
pdlv->cmd_state = *cmd_state;
pdlv_unlock(pdlv);
}
void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error)
{
pdlv_lock(pdlv);
pdlv->error = error;
pdlv_unlock(pdlv);
}
void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished)
{
pdlv_lock(pdlv);
pdlv->polling_finished = finished;
pdlv_unlock(pdlv);
}
struct lvmpolld_store *pdst_init(const char *name)
{
struct lvmpolld_store *pdst = (struct lvmpolld_store *) dm_malloc(sizeof(struct lvmpolld_store));
if (!pdst)
return NULL;
pdst->store = dm_hash_create(32);
if (!pdst->store)
goto err_hash;
if (pthread_mutex_init(&pdst->lock, NULL))
goto err_mutex;
pdst->name = name;
pdst->active_polling_count = 0;
return pdst;
err_mutex:
dm_hash_destroy(pdst->store);
err_hash:
dm_free(pdst);
return NULL;
}
void pdst_destroy(struct lvmpolld_store *pdst)
{
if (!pdst)
return;
dm_hash_destroy(pdst->store);
pthread_mutex_destroy(&pdst->lock);
dm_free(pdst);
}
void pdst_locked_lock_all_pdlvs(const struct lvmpolld_store *pdst)
{
struct dm_hash_node *n;
dm_hash_iterate(n, pdst->store)
pdlv_lock(dm_hash_get_data(pdst->store, n));
}
void pdst_locked_unlock_all_pdlvs(const struct lvmpolld_store *pdst)
{
struct dm_hash_node *n;
dm_hash_iterate(n, pdst->store)
pdlv_unlock(dm_hash_get_data(pdst->store, n));
}
static void _pdlv_locked_dump(struct buffer *buff, const struct lvmpolld_lv *pdlv)
{
char tmp[1024];
const struct lvmpolld_cmd_stat *cmd_state = &pdlv->cmd_state;
/* pdlv-section { */
if (dm_snprintf(tmp, sizeof(tmp), "\t%s {\n", pdlv->lvmpolld_id) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvid=\"%s\"\n", pdlv->lvid) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\ttype=\"%s\"\n", polling_op(pdlv->type)) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvname=\"%s\"\n", pdlv->lvname) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvmpolld_internal_timeout=%d\n", pdlv->pdtimeout) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_interval=\"%s\"\n", pdlv->sinterval ?: "<undefined>") > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tLVM_SYSTEM_DIR=\"%s\"\n",
(*pdlv->lvm_system_dir_env ? (pdlv->lvm_system_dir_env + strlen("LVM_SYSTEM_DIR=")) : "<undefined>")) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tlvm_command_pid=%d\n", pdlv->cmd_pid) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tpolling_finished=%d\n", pdlv->polling_finished) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\terror_occured=%d\n", pdlv->error) > 0)
buffer_append(buff, tmp);
if (dm_snprintf(tmp, sizeof(tmp), "\t\tinit_requests_count=%d\n", pdlv->init_rq_count) > 0)
buffer_append(buff, tmp);
/* lvm_commmand-section { */
buffer_append(buff, "\t\tlvm_command {\n");
if (cmd_state->retcode == -1 && !cmd_state->signal)
buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_IN_PROGRESS "\"\n");
else {
buffer_append(buff, "\t\t\tstate=\"" LVMPD_RESP_FINISHED "\"\n");
if (dm_snprintf(tmp, sizeof(tmp), "\t\t\treason=\"%s\"\n\t\t\tvalue=%d\n",
(cmd_state->signal ? LVMPD_REAS_SIGNAL : LVMPD_REAS_RETCODE),
(cmd_state->signal ?: cmd_state->retcode)) > 0)
buffer_append(buff, tmp);
}
buffer_append(buff, "\t\t}\n");
/* } lvm_commmand-section */
buffer_append(buff, "\t}\n");
/* } pdlv-section */
}
void pdst_locked_dump(const struct lvmpolld_store *pdst, struct buffer *buff)
{
struct dm_hash_node *n;
dm_hash_iterate(n, pdst->store)
_pdlv_locked_dump(buff, dm_hash_get_data(pdst->store, n));
}
void pdst_locked_send_cancel(const struct lvmpolld_store *pdst)
{
struct lvmpolld_lv *pdlv;
struct dm_hash_node *n;
dm_hash_iterate(n, pdst->store) {
pdlv = dm_hash_get_data(pdst->store, n);
if (!pdlv_locked_polling_finished(pdlv))
pthread_cancel(pdlv->tid);
}
}
void pdst_locked_destroy_all_pdlvs(const struct lvmpolld_store *pdst)
{
struct dm_hash_node *n;
dm_hash_iterate(n, pdst->store)
pdlv_destroy(dm_hash_get_data(pdst->store, n));
}
struct lvmpolld_thread_data *lvmpolld_thread_data_constructor(struct lvmpolld_lv *pdlv)
{
struct lvmpolld_thread_data *data = (struct lvmpolld_thread_data *) dm_malloc(sizeof(struct lvmpolld_thread_data));
if (!data)
return NULL;
data->pdlv = NULL;
data->line = NULL;
data->line_size = 0;
data->fout = data->ferr = NULL;
data->outpipe[0] = data->outpipe[1] = data->errpipe[0] = data->errpipe[1] = -1;
if (pipe(data->outpipe) || pipe(data->errpipe)) {
lvmpolld_thread_data_destroy(data);
return NULL;
}
if (fcntl(data->outpipe[0], F_SETFD, FD_CLOEXEC) ||
fcntl(data->outpipe[1], F_SETFD, FD_CLOEXEC) ||
fcntl(data->errpipe[0], F_SETFD, FD_CLOEXEC) ||
fcntl(data->errpipe[1], F_SETFD, FD_CLOEXEC)) {
lvmpolld_thread_data_destroy(data);
return NULL;
}
data->pdlv = pdlv;
return data;
}
void lvmpolld_thread_data_destroy(void *thread_private)
{
struct lvmpolld_thread_data *data = (struct lvmpolld_thread_data *) thread_private;
if (!data)
return;
if (data->pdlv) {
pdst_lock(data->pdlv->pdst);
/*
* FIXME: skip this step if lvmpolld is activated
* by systemd.
*/
if (!pdlv_get_polling_finished(data->pdlv))
kill(data->pdlv->cmd_pid, SIGTERM);
pdlv_set_polling_finished(data->pdlv, 1);
pdst_locked_dec(data->pdlv->pdst);
pdst_unlock(data->pdlv->pdst);
}
/* may get reallocated in getline(). dm_free must not be used */
free(data->line);
if (data->fout && !fclose(data->fout))
data->outpipe[0] = -1;
if (data->ferr && !fclose(data->ferr))
data->errpipe[0] = -1;
if (data->outpipe[0] >= 0)
(void) close(data->outpipe[0]);
if (data->outpipe[1] >= 0)
(void) close(data->outpipe[1]);
if (data->errpipe[0] >= 0)
(void) close(data->errpipe[0]);
if (data->errpipe[1] >= 0)
(void) close(data->errpipe[1]);
dm_free(data);
}

View File

@ -0,0 +1,215 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LVMPOLLD_DATA_UTILS_H
#define _LVM_LVMPOLLD_DATA_UTILS_H
#include <pthread.h>
struct buffer;
struct lvmpolld_state;
enum poll_type {
PVMOVE = 0,
CONVERT,
MERGE,
MERGE_THIN,
POLL_TYPE_MAX
};
struct lvmpolld_cmd_stat {
int retcode;
int signal;
};
struct lvmpolld_store {
pthread_mutex_t lock;
void *store;
const char *name;
unsigned active_polling_count;
};
struct lvmpolld_lv {
/*
* accessing following vars doesn't
* require struct lvmpolld_lv lock
*/
struct lvmpolld_state *const ls;
const enum poll_type type;
const char *const lvid;
const char *const lvmpolld_id;
const char *const lvname; /* full vg/lv name */
const unsigned pdtimeout; /* in seconds */
const char *const sinterval;
const char *const lvm_system_dir_env;
struct lvmpolld_store *const pdst;
const char *const *cmdargv;
const char *const *cmdenvp;
/* only used by write */
pid_t cmd_pid;
pthread_t tid;
pthread_mutex_t lock;
/* block of shared variables protected by lock */
struct lvmpolld_cmd_stat cmd_state;
unsigned init_rq_count; /* for debuging purposes only */
unsigned polling_finished:1; /* no more updates */
unsigned error:1; /* unrecoverable error occured in lvmpolld */
};
typedef void (*lvmpolld_parse_output_fn_t) (struct lvmpolld_lv *pdlv, const char *line);
/* TODO: replace with configuration option */
#define MIN_POLLING_TIMEOUT 60
struct lvmpolld_lv_state {
unsigned error:1;
unsigned polling_finished:1;
struct lvmpolld_cmd_stat cmd_state;
};
struct lvmpolld_thread_data {
char *line;
size_t line_size;
int outpipe[2];
int errpipe[2];
FILE *fout;
FILE *ferr;
char buf[1024];
struct lvmpolld_lv *pdlv;
};
char *construct_id(const char *sysdir, const char *lvid);
/* LVMPOLLD_LV_T section */
/* only call with appropriate struct lvmpolld_store lock held */
struct lvmpolld_lv *pdlv_create(struct lvmpolld_state *ls, const char *id,
const char *vgname, const char *lvname,
const char *sysdir, enum poll_type type,
const char *sinterval, unsigned pdtimeout,
struct lvmpolld_store *pdst);
/* only call with appropriate struct lvmpolld_store lock held */
void pdlv_destroy(struct lvmpolld_lv *pdlv);
static inline void pdlv_lock(struct lvmpolld_lv *pdlv)
{
pthread_mutex_lock(&pdlv->lock);
}
static inline void pdlv_unlock(struct lvmpolld_lv *pdlv)
{
pthread_mutex_unlock(&pdlv->lock);
}
/*
* no struct lvmpolld_lv lock required section
*/
static inline int pdlv_is_type(const struct lvmpolld_lv *pdlv, enum poll_type type)
{
return pdlv->type == type;
}
static inline unsigned pdlv_get_timeout(const struct lvmpolld_lv *pdlv)
{
return pdlv->pdtimeout;
}
static inline enum poll_type pdlv_get_type(const struct lvmpolld_lv *pdlv)
{
return pdlv->type;
}
unsigned pdlv_get_polling_finished(struct lvmpolld_lv *pdlv);
struct lvmpolld_lv_state pdlv_get_status(struct lvmpolld_lv *pdlv);
void pdlv_set_cmd_state(struct lvmpolld_lv *pdlv, const struct lvmpolld_cmd_stat *cmd_state);
void pdlv_set_error(struct lvmpolld_lv *pdlv, unsigned error);
void pdlv_set_polling_finished(struct lvmpolld_lv *pdlv, unsigned finished);
/*
* struct lvmpolld_lv lock required section
*/
static inline struct lvmpolld_cmd_stat pdlv_locked_cmd_state(const struct lvmpolld_lv *pdlv)
{
return pdlv->cmd_state;
}
static inline int pdlv_locked_polling_finished(const struct lvmpolld_lv *pdlv)
{
return pdlv->polling_finished;
}
static inline unsigned pdlv_locked_error(const struct lvmpolld_lv *pdlv)
{
return pdlv->error;
}
/* struct lvmpolld_store manipulation routines */
struct lvmpolld_store *pdst_init(const char *name);
void pdst_destroy(struct lvmpolld_store *pdst);
void pdst_locked_dump(const struct lvmpolld_store *pdst, struct buffer *buff);
void pdst_locked_lock_all_pdlvs(const struct lvmpolld_store *pdst);
void pdst_locked_unlock_all_pdlvs(const struct lvmpolld_store *pdst);
void pdst_locked_destroy_all_pdlvs(const struct lvmpolld_store *pdst);
void pdst_locked_send_cancel(const struct lvmpolld_store *pdst);
static inline void pdst_lock(struct lvmpolld_store *pdst)
{
pthread_mutex_lock(&pdst->lock);
}
static inline void pdst_unlock(struct lvmpolld_store *pdst)
{
pthread_mutex_unlock(&pdst->lock);
}
static inline void pdst_locked_inc(struct lvmpolld_store *pdst)
{
pdst->active_polling_count++;
}
static inline void pdst_locked_dec(struct lvmpolld_store *pdst)
{
pdst->active_polling_count--;
}
static inline unsigned pdst_locked_get_active_count(const struct lvmpolld_store *pdst)
{
return pdst->active_polling_count;
}
static inline int pdst_locked_insert(struct lvmpolld_store *pdst, const char *key, struct lvmpolld_lv *pdlv)
{
return dm_hash_insert(pdst->store, key, pdlv);
}
static inline struct lvmpolld_lv *pdst_locked_lookup(struct lvmpolld_store *pdst, const char *key)
{
return dm_hash_lookup(pdst->store, key);
}
static inline void pdst_locked_remove(struct lvmpolld_store *pdst, const char *key)
{
dm_hash_remove(pdst->store, key);
}
struct lvmpolld_thread_data *lvmpolld_thread_data_constructor(struct lvmpolld_lv *pdlv);
void lvmpolld_thread_data_destroy(void *thread_private);
#endif /* _LVM_LVMPOLLD_DATA_UTILS_H */

View File

@ -0,0 +1,52 @@
/*
* Copyright (C) 2015 Red Hat, Inc.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_LVMPOLLD_PROTOCOL_H
#define _LVM_LVMPOLLD_PROTOCOL_H
#include "polling_ops.h"
#define LVMPOLLD_PROTOCOL "lvmpolld"
#define LVMPOLLD_PROTOCOL_VERSION 1
#define LVMPD_REQ_CONVERT CONVERT_POLL
#define LVMPD_REQ_DUMP "dump"
#define LVMPD_REQ_MERGE MERGE_POLL
#define LVMPD_REQ_MERGE_THIN MERGE_THIN_POLL
#define LVMPD_REQ_PROGRESS "progress_info"
#define LVMPD_REQ_PVMOVE PVMOVE_POLL
#define LVMPD_PARM_ABORT "abort"
#define LVMPD_PARM_HANDLE_MISSING_PVS "handle_missing_pvs"
#define LVMPD_PARM_INTERVAL "interval"
#define LVMPD_PARM_LVID "lvid"
#define LVMPD_PARM_LVNAME "lvname"
#define LVMPD_PARM_SYSDIR "sysdir"
#define LVMPD_PARM_VALUE "value" /* either retcode or signal value */
#define LVMPD_PARM_VGNAME "vgname"
#define LVMPD_RESP_FAILED "failed"
#define LVMPD_RESP_FINISHED "finished"
#define LVMPD_RESP_IN_PROGRESS "in_progress"
#define LVMPD_RESP_EINVAL "invalid"
#define LVMPD_RESP_NOT_FOUND "not_found"
#define LVMPD_RESP_OK "OK"
#define LVMPD_REAS_RETCODE "retcode" /* lvm cmd ret code */
#define LVMPD_REAS_SIGNAL "signal" /* lvm cmd terminating singal */
#define LVMPD_RET_DUP_FAILED 100
#define LVMPD_RET_EXC_FAILED 101
#endif /* _LVM_LVMPOLLD_PROTOCOL_H */

View File

@ -0,0 +1,25 @@
/*
* Copyright (C) 2014-2015 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef _LVM_TOOL_POLLING_OPS_H
#define _LVM_TOOL_POLLING_OPS_H
/* this file is also part of lvmpolld protocol */
#define PVMOVE_POLL "pvmove"
#define CONVERT_POLL "convert"
#define MERGE_POLL "merge"
#define MERGE_THIN_POLL "merge_thin"
#endif /* _LVM_TOOL_POLLING_OPS_H */

View File

@ -0,0 +1,86 @@
Q: Why should lvmetad cache foreign VGs?
A: It's the most useful behavior in the "steady state".
How to arrive at that conclusion.
Four code configurations to consider, each in two different circumstances.
configurations:
1. lvm not using lvmetad
2. lvm using lvmetad and lvmlockd
3. lvm using lvmetad, and lvmetad does not cache foreign VGs
(Not currently implemented.)
4. lvm using lvmetad, and lvmetad caches foreign VGs
circumstances:
A. steady state: PVs are not added or removed to/from foreign VGs
B. transient state: PVs are added or removed to/from foreign VGs
combinations:
1.A. A PV is correctly shown in the foreign VG.
1.B. A PV is correctly shown in the foreign VG.
The most accurate representation, at the cost of always scanning disks.
2.A. A PV is correctly shown in the foreign VG.
2.B. A PV is correctly shown in the foreign VG.
The most accurate representation, at the cost of using lvmlockd.
3.A. A PV in a foreign VG is shown as unused.
3.B. A PV in a foreign VG is shown as unused.
If lvmetad ignores foreign VGs and does not cache them, the PVs in the
foreign VGs appear to be unused. This largely defeats the purpose of
system_id, which is meant to treat VGs/PVs as foreign instead of free
(albeit imperfectly, see below.)
4.A. A PV is correctly shown in the foreign VG.
4.B. A PV is not correctly shown in the foreign VG.
This avoids the cost of always scanning disks, and avoids the cost of
using lvmlockd. The steady state 4.A. is an improvement over the steady
state 3.A. When the steady state is the common case, this is a big
advantage. When the steady state is *not* the common case, the foreign VG
concept is not as useful (if shared devices are this dynamic, lvmlockd
should be considered.)
The limitations related to the transient state 4.B. are explained in
lvmsystemid(7), along with how to handle it. The specific inaccuracies
possible in 4.B. are:
. PV is shown as belonging to a foreign VG, but is actually unused.
. PV is shown as unused, but actually belongs to a foreign VG.
To resolve the inaccuracies in the transient state (4.B.), and return the
system to an accurate steady state (4.A.), the disks need to be scanned,
which updates lvmetad. The scanning/updating is a manual step, i.e.
running 'pvscan --cache', which by definition scans disks and updates
lvmetad.
--
The --foreign command line option for report/display commands
(vgs/lvs/pvs/vgdisplay/lvdisplay/pvdisplay) is not directly related to
whether or not lvmetad caches foreign VGs.
By default, foreign VGs are silently ignored and not printed by these
commands. However, when the --foreign option is used, these commands do
produce output about foreign VGs.
(When --foreign is not used, and the command specifically requests a
foreign VG by name, an error is produced about not accessing foreign VGs,
and the foreign VG is not displayed.)
The decision to report/display foreign VGs or not is independent of
whether lvmetad is caching those VGs. When lvmetad is caching the foreign
VG, a report/display command run with --foreign will scan disks to read
the foreign VG and give the most up to date version of it (the copy of the
foreign VG in lvmetad may be out of date due to changes to the VG by the
foreign host.)

View File

@ -30,28 +30,48 @@ multiqueue
This policy is the default.
The multiqueue policy has two sets of 16 queues: one set for entries
waiting for the cache and another one for those in the cache.
The multiqueue policy has three sets of 16 queues: one set for entries
waiting for the cache and another two for those in the cache (a set for
clean entries and a set for dirty entries).
Cache entries in the queues are aged based on logical time. Entry into
the cache is based on variable thresholds and queue selection is based
on hit count on entry. The policy aims to take different cache miss
costs into account and to adjust to varying load patterns automatically.
Message and constructor argument pairs are:
'sequential_threshold <#nr_sequential_ios>' and
'random_threshold <#nr_random_ios>'.
'sequential_threshold <#nr_sequential_ios>'
'random_threshold <#nr_random_ios>'
'read_promote_adjustment <value>'
'write_promote_adjustment <value>'
'discard_promote_adjustment <value>'
The sequential threshold indicates the number of contiguous I/Os
required before a stream is treated as sequential. The random threshold
required before a stream is treated as sequential. Once a stream is
considered sequential it will bypass the cache. The random threshold
is the number of intervening non-contiguous I/Os that must be seen
before the stream is treated as random again.
The sequential and random thresholds default to 512 and 4 respectively.
Large, sequential ios are probably better left on the origin device
since spindles tend to have good bandwidth. The io_tracker counts
contiguous I/Os to try to spot when the io is in one of these sequential
modes.
Large, sequential I/Os are probably better left on the origin device
since spindles tend to have good sequential I/O bandwidth. The
io_tracker counts contiguous I/Os to try to spot when the I/O is in one
of these sequential modes. But there are use-cases for wanting to
promote sequential blocks to the cache (e.g. fast application startup).
If sequential threshold is set to 0 the sequential I/O detection is
disabled and sequential I/O will no longer implicitly bypass the cache.
Setting the random threshold to 0 does _not_ disable the random I/O
stream detection.
Internally the mq policy determines a promotion threshold. If the hit
count of a block not in the cache goes above this threshold it gets
promoted to the cache. The read, write and discard promote adjustment
tunables allow you to tweak the promotion threshold by adding a small
value based on the io type. They default to 4, 8 and 1 respectively.
If you're trying to quickly warm a new cache device you may wish to
reduce these to encourage promotion. Remember to switch them back to
their defaults after the cache fills though.
cleaner
-------

View File

@ -50,14 +50,16 @@ other parameters detailed later):
which are dirty, and extra hints for use by the policy object.
This information could be put on the cache device, but having it
separate allows the volume manager to configure it differently,
e.g. as a mirror for extra robustness.
e.g. as a mirror for extra robustness. This metadata device may only
be used by a single cache device.
Fixed block size
----------------
The origin is divided up into blocks of a fixed size. This block size
is configurable when you first create the cache. Typically we've been
using block sizes of 256k - 1024k.
using block sizes of 256KB - 1024KB. The block size must be between 64
(32KB) and 2097152 (1GB) and a multiple of 64 (32KB).
Having a fixed block size simplifies the target a lot. But it is
something of a compromise. For instance, a small part of a block may be
@ -66,10 +68,11 @@ So large block sizes are bad because they waste cache space. And small
block sizes are bad because they increase the amount of metadata (both
in core and on disk).
Writeback/writethrough
----------------------
Cache operating modes
---------------------
The cache has two modes, writeback and writethrough.
The cache has three operating modes: writeback, writethrough and
passthrough.
If writeback, the default, is selected then a write to a block that is
cached will go only to the cache and the block will be marked dirty in
@ -79,15 +82,38 @@ If writethrough is selected then a write to a cached block will not
complete until it has hit both the origin and cache devices. Clean
blocks should remain clean.
If passthrough is selected, useful when the cache contents are not known
to be coherent with the origin device, then all reads are served from
the origin device (all reads miss the cache) and all writes are
forwarded to the origin device; additionally, write hits cause cache
block invalidates. To enable passthrough mode the cache must be clean.
Passthrough mode allows a cache device to be activated without having to
worry about coherency. Coherency that exists is maintained, although
the cache will gradually cool as writes take place. If the coherency of
the cache can later be verified, or established through use of the
"invalidate_cblocks" message, the cache device can be transitioned to
writethrough or writeback mode while still warm. Otherwise, the cache
contents can be discarded prior to transitioning to the desired
operating mode.
A simple cleaner policy is provided, which will clean (write back) all
dirty blocks in a cache. Useful for decommissioning a cache.
dirty blocks in a cache. Useful for decommissioning a cache or when
shrinking a cache. Shrinking the cache's fast device requires all cache
blocks, in the area of the cache being removed, to be clean. If the
area being removed from the cache still contains dirty blocks the resize
will fail. Care must be taken to never reduce the volume used for the
cache's fast device until the cache is clean. This is of particular
importance if writeback mode is used. Writethrough and passthrough
modes already maintain a clean cache. Future support to partially clean
the cache, above a specified threshold, will allow for keeping the cache
warm and in writeback mode during resize.
Migration throttling
--------------------
Migrating data between the origin and cache device uses bandwidth.
The user can set a throttle to prevent more than a certain amount of
migration occuring at any one time. Currently we're not taking any
migration occurring at any one time. Currently we're not taking any
account of normal io traffic going to the devices. More work needs
doing here to avoid migrating during those peak io moments.
@ -98,12 +124,11 @@ the default being 204800 sectors (or 100MB).
Updating on-disk metadata
-------------------------
On-disk metadata is committed every time a REQ_SYNC or REQ_FUA bio is
written. If no such requests are made then commits will occur every
second. This means the cache behaves like a physical disk that has a
write cache (the same is true of the thin-provisioning target). If
power is lost you may lose some recent writes. The metadata should
always be consistent in spite of any crash.
On-disk metadata is committed every time a FLUSH or FUA bio is written.
If no such requests are made then commits will occur every second. This
means the cache behaves like a physical disk that has a volatile write
cache. If power is lost you may lose some recent writes. The metadata
should always be consistent in spite of any crash.
The 'dirty' state for a cache block changes far too frequently for us
to keep updating it on the fly. So we treat it as a hint. In normal
@ -159,7 +184,7 @@ Constructor
block size : cache unit size in sectors
#feature args : number of feature arguments passed
feature args : writethrough. (The default is writeback.)
feature args : writethrough or passthrough (The default is writeback.)
policy : the replacement policy to use
#policy args : an even number of arguments corresponding to
@ -175,6 +200,13 @@ Optional feature arguments are:
back cache block contents later for performance reasons,
so they may differ from the corresponding origin blocks.
passthrough : a degraded mode useful for various cache coherency
situations (e.g., rolling back snapshots of
underlying storage). Reads and writes always go to
the origin. If a write goes to a cached origin
block, then the cache block is invalidated.
To enable passthrough mode the cache must be clean.
A policy called 'default' is always registered. This is an alias for
the policy we currently think is giving best all round performance.
@ -184,36 +216,43 @@ the characteristics of a specific policy, always request it by name.
Status
------
<#used metadata blocks>/<#total metadata blocks> <#read hits> <#read misses>
<#write hits> <#write misses> <#demotions> <#promotions> <#blocks in cache>
<#dirty> <#features> <features>* <#core args> <core args>* <#policy args>
<policy args>*
<metadata block size> <#used metadata blocks>/<#total metadata blocks>
<cache block size> <#used cache blocks>/<#total cache blocks>
<#read hits> <#read misses> <#write hits> <#write misses>
<#demotions> <#promotions> <#dirty> <#features> <features>*
<#core args> <core args>* <policy name> <#policy args> <policy args>*
#used metadata blocks : Number of metadata blocks used
#total metadata blocks : Total number of metadata blocks
#read hits : Number of times a READ bio has been mapped
metadata block size : Fixed block size for each metadata block in
sectors
#used metadata blocks : Number of metadata blocks used
#total metadata blocks : Total number of metadata blocks
cache block size : Configurable block size for the cache device
in sectors
#used cache blocks : Number of blocks resident in the cache
#total cache blocks : Total number of cache blocks
#read hits : Number of times a READ bio has been mapped
to the cache
#read misses : Number of times a READ bio has been mapped
#read misses : Number of times a READ bio has been mapped
to the origin
#write hits : Number of times a WRITE bio has been mapped
#write hits : Number of times a WRITE bio has been mapped
to the cache
#write misses : Number of times a WRITE bio has been
#write misses : Number of times a WRITE bio has been
mapped to the origin
#demotions : Number of times a block has been removed
#demotions : Number of times a block has been removed
from the cache
#promotions : Number of times a block has been moved to
#promotions : Number of times a block has been moved to
the cache
#blocks in cache : Number of blocks resident in the cache
#dirty : Number of blocks in the cache that differ
#dirty : Number of blocks in the cache that differ
from the origin
#feature args : Number of feature args to follow
feature args : 'writethrough' (optional)
#core args : Number of core arguments (must be even)
core args : Key/value pairs for tuning the core
#feature args : Number of feature args to follow
feature args : 'writethrough' (optional)
#core args : Number of core arguments (must be even)
core args : Key/value pairs for tuning the core
e.g. migration_threshold
#policy args : Number of policy arguments to follow (must be even)
policy args : Key/value pairs
e.g. 'sequential_threshold 1024
policy name : Name of the policy
#policy args : Number of policy arguments to follow (must be even)
policy args : Key/value pairs
e.g. sequential_threshold
Messages
--------
@ -229,12 +268,28 @@ The message format is:
E.g.
dmsetup message my_cache 0 sequential_threshold 1024
Invalidation is removing an entry from the cache without writing it
back. Cache blocks can be invalidated via the invalidate_cblocks
message, which takes an arbitrary number of cblock ranges. Each cblock
range's end value is "one past the end", meaning 5-10 expresses a range
of values from 5 to 9. Each cblock must be expressed as a decimal
value, in the future a variant message that takes cblock ranges
expressed in hexidecimal may be needed to better support efficient
invalidation of larger caches. The cache must be in passthrough mode
when invalidate_cblocks is used.
invalidate_cblocks [<cblock>|<cblock begin>-<cblock end>]*
E.g.
dmsetup message my_cache 0 invalidate_cblocks 2345 3456-4567 5678-6789
Examples
========
The test suite can be found here:
https://github.com/jthornber/thinp-test-suite
https://github.com/jthornber/device-mapper-test-suite
dmsetup create my_cache --table '0 41943040 cache /dev/mapper/metadata \
/dev/mapper/ssd /dev/mapper/origin 512 1 writeback default 0'

View File

@ -4,12 +4,15 @@ dm-crypt
Device-Mapper's "crypt" target provides transparent encryption of block devices
using the kernel crypto API.
For a more detailed description of supported parameters see:
https://gitlab.com/cryptsetup/cryptsetup/wikis/DMCrypt
Parameters: <cipher> <key> <iv_offset> <device path> \
<offset> [<#opt_params> <opt_params>]
<cipher>
Encryption cipher and an optional IV generation mode.
(In format cipher[:keycount]-chainmode-ivopts:ivmode).
(In format cipher[:keycount]-chainmode-ivmode[:ivopts]).
Examples:
des
aes-cbc-essiv:sha256
@ -19,7 +22,11 @@ Parameters: <cipher> <key> <iv_offset> <device path> \
<key>
Key used for encryption. It is encoded as a hexadecimal number.
You can only use key sizes that are valid for the selected cipher.
You can only use key sizes that are valid for the selected cipher
in combination with the selected iv mode.
Note that for some iv modes the key string can contain additional
keys (for example IV seed) so the key contains more parts concatenated
into a single string.
<keycount>
Multi-key compatibility mode. You can define <keycount> keys and
@ -44,7 +51,7 @@ Parameters: <cipher> <key> <iv_offset> <device path> \
Otherwise #opt_params is the number of following arguments.
Example of optional parameters section:
1 allow_discards
3 allow_discards same_cpu_crypt submit_from_crypt_cpus
allow_discards
Block discard requests (a.k.a. TRIM) are passed through the crypt device.
@ -56,11 +63,24 @@ allow_discards
used space etc.) if the discarded blocks can be located easily on the
device later.
same_cpu_crypt
Perform encryption using the same cpu that IO was submitted on.
The default is to use an unbound workqueue so that encryption work
is automatically balanced between available CPUs.
submit_from_crypt_cpus
Disable offloading writes to a separate thread after encryption.
There are some situations where offloading write bios from the
encryption threads to a single thread degrades performance
significantly. The default is to offload write bios to the same
thread because it benefits CFQ to have writes submitted using the
same context.
Example scripts
===============
LUKS (Linux Unified Key Setup) is now the preferred way to set up disk
encryption with dm-crypt using the 'cryptsetup' utility, see
http://code.google.com/p/cryptsetup/
https://gitlab.com/cryptsetup/cryptsetup
[[
#!/bin/sh

108
doc/kernel/era.txt Normal file
View File

@ -0,0 +1,108 @@
Introduction
============
dm-era is a target that behaves similar to the linear target. In
addition it keeps track of which blocks were written within a user
defined period of time called an 'era'. Each era target instance
maintains the current era as a monotonically increasing 32-bit
counter.
Use cases include tracking changed blocks for backup software, and
partially invalidating the contents of a cache to restore cache
coherency after rolling back a vendor snapshot.
Constructor
===========
era <metadata dev> <origin dev> <block size>
metadata dev : fast device holding the persistent metadata
origin dev : device holding data blocks that may change
block size : block size of origin data device, granularity that is
tracked by the target
Messages
========
None of the dm messages take any arguments.
checkpoint
----------
Possibly move to a new era. You shouldn't assume the era has
incremented. After sending this message, you should check the
current era via the status line.
take_metadata_snap
------------------
Create a clone of the metadata, to allow a userland process to read it.
drop_metadata_snap
------------------
Drop the metadata snapshot.
Status
======
<metadata block size> <#used metadata blocks>/<#total metadata blocks>
<current era> <held metadata root | '-'>
metadata block size : Fixed block size for each metadata block in
sectors
#used metadata blocks : Number of metadata blocks used
#total metadata blocks : Total number of metadata blocks
current era : The current era
held metadata root : The location, in blocks, of the metadata root
that has been 'held' for userspace read
access. '-' indicates there is no held root
Detailed use case
=================
The scenario of invalidating a cache when rolling back a vendor
snapshot was the primary use case when developing this target:
Taking a vendor snapshot
------------------------
- Send a checkpoint message to the era target
- Make a note of the current era in its status line
- Take vendor snapshot (the era and snapshot should be forever
associated now).
Rolling back to an vendor snapshot
----------------------------------
- Cache enters passthrough mode (see: dm-cache's docs in cache.txt)
- Rollback vendor storage
- Take metadata snapshot
- Ascertain which blocks have been written since the snapshot was taken
by checking each block's era
- Invalidate those blocks in the caching software
- Cache returns to writeback/writethrough mode
Memory usage
============
The target uses a bitset to record writes in the current era. It also
has a spare bitset ready for switching over to a new era. Other than
that it uses a few 4k blocks for updating metadata.
(4 * nr_blocks) bytes + buffers
Resilience
==========
Metadata is updated on disk before a write to a previously unwritten
block is performed. As such dm-era should not be effected by a hard
crash such as power failure.
Userland tools
==============
Userland tools are found in the increasingly poorly named
thin-provisioning-tools project:
https://github.com/jthornber/thin-provisioning-tools

140
doc/kernel/log-writes.txt Normal file
View File

@ -0,0 +1,140 @@
dm-log-writes
=============
This target takes 2 devices, one to pass all IO to normally, and one to log all
of the write operations to. This is intended for file system developers wishing
to verify the integrity of metadata or data as the file system is written to.
There is a log_write_entry written for every WRITE request and the target is
able to take arbitrary data from userspace to insert into the log. The data
that is in the WRITE requests is copied into the log to make the replay happen
exactly as it happened originally.
Log Ordering
============
We log things in order of completion once we are sure the write is no longer in
cache. This means that normal WRITE requests are not actually logged until the
next REQ_FLUSH request. This is to make it easier for userspace to replay the
log in a way that correlates to what is on disk and not what is in cache, to
make it easier to detect improper waiting/flushing.
This works by attaching all WRITE requests to a list once the write completes.
Once we see a REQ_FLUSH request we splice this list onto the request and once
the FLUSH request completes we log all of the WRITEs and then the FLUSH. Only
completed WRITEs, at the time the REQ_FLUSH is issued, are added in order to
simulate the worst case scenario with regard to power failures. Consider the
following example (W means write, C means complete):
W1,W2,W3,C3,C2,Wflush,C1,Cflush
The log would show the following
W3,W2,flush,W1....
Again this is to simulate what is actually on disk, this allows us to detect
cases where a power failure at a particular point in time would create an
inconsistent file system.
Any REQ_FUA requests bypass this flushing mechanism and are logged as soon as
they complete as those requests will obviously bypass the device cache.
Any REQ_DISCARD requests are treated like WRITE requests. Otherwise we would
have all the DISCARD requests, and then the WRITE requests and then the FLUSH
request. Consider the following example:
WRITE block 1, DISCARD block 1, FLUSH
If we logged DISCARD when it completed, the replay would look like this
DISCARD 1, WRITE 1, FLUSH
which isn't quite what happened and wouldn't be caught during the log replay.
Target interface
================
i) Constructor
log-writes <dev_path> <log_dev_path>
dev_path : Device that all of the IO will go to normally.
log_dev_path : Device where the log entries are written to.
ii) Status
<#logged entries> <highest allocated sector>
#logged entries : Number of logged entries
highest allocated sector : Highest allocated sector
iii) Messages
mark <description>
You can use a dmsetup message to set an arbitrary mark in a log.
For example say you want to fsck a file system after every
write, but first you need to replay up to the mkfs to make sure
we're fsck'ing something reasonable, you would do something like
this:
mkfs.btrfs -f /dev/mapper/log
dmsetup message log 0 mark mkfs
<run test>
This would allow you to replay the log up to the mkfs mark and
then replay from that point on doing the fsck check in the
interval that you want.
Every log has a mark at the end labeled "dm-log-writes-end".
Userspace component
===================
There is a userspace tool that will replay the log for you in various ways.
It can be found here: https://github.com/josefbacik/log-writes
Example usage
=============
Say you want to test fsync on your file system. You would do something like
this:
TABLE="0 $(blockdev --getsz /dev/sdb) log-writes /dev/sdb /dev/sdc"
dmsetup create log --table "$TABLE"
mkfs.btrfs -f /dev/mapper/log
dmsetup message log 0 mark mkfs
mount /dev/mapper/log /mnt/btrfs-test
<some test that does fsync at the end>
dmsetup message log 0 mark fsync
md5sum /mnt/btrfs-test/foo
umount /mnt/btrfs-test
dmsetup remove log
replay-log --log /dev/sdc --replay /dev/sdb --end-mark fsync
mount /dev/sdb /mnt/btrfs-test
md5sum /mnt/btrfs-test/foo
<verify md5sum's are correct>
Another option is to do a complicated file system operation and verify the file
system is consistent during the entire operation. You could do this with:
TABLE="0 $(blockdev --getsz /dev/sdb) log-writes /dev/sdb /dev/sdc"
dmsetup create log --table "$TABLE"
mkfs.btrfs -f /dev/mapper/log
dmsetup message log 0 mark mkfs
mount /dev/mapper/log /mnt/btrfs-test
<fsstress to dirty the fs>
btrfs filesystem balance /mnt/btrfs-test
umount /mnt/btrfs-test
dmsetup remove log
replay-log --log /dev/sdc --replay /dev/sdb --end-mark mkfs
btrfsck /dev/sdb
replay-log --log /dev/sdc --replay /dev/sdb --start-mark mkfs \
--fsck "btrfsck /dev/sdb" --check fua
And that will replay the log until it sees a FUA request, run the fsck command
and if the fsck passes it will replay to the next FUA, until it is completed or
the fsck command exists abnormally.

View File

@ -222,3 +222,5 @@ Version History
1.4.2 Add RAID10 "far" and "offset" algorithm support.
1.5.0 Add message interface to allow manipulation of the sync_action.
New status (STATUSTYPE_INFO) fields: sync_action and mismatch_cnt.
1.5.1 Add ability to restore transiently failed devices on resume.
1.5.2 'mismatch_cnt' is zero unless [last_]sync_action is "check".

186
doc/kernel/statistics.txt Normal file
View File

@ -0,0 +1,186 @@
DM statistics
=============
Device Mapper supports the collection of I/O statistics on user-defined
regions of a DM device. If no regions are defined no statistics are
collected so there isn't any performance impact. Only bio-based DM
devices are currently supported.
Each user-defined region specifies a starting sector, length and step.
Individual statistics will be collected for each step-sized area within
the range specified.
The I/O statistics counters for each step-sized area of a region are
in the same format as /sys/block/*/stat or /proc/diskstats (see:
Documentation/iostats.txt). But two extra counters (12 and 13) are
provided: total time spent reading and writing in milliseconds. All
these counters may be accessed by sending the @stats_print message to
the appropriate DM device via dmsetup.
Each region has a corresponding unique identifier, which we call a
region_id, that is assigned when the region is created. The region_id
must be supplied when querying statistics about the region, deleting the
region, etc. Unique region_ids enable multiple userspace programs to
request and process statistics for the same DM device without stepping
on each other's data.
The creation of DM statistics will allocate memory via kmalloc or
fallback to using vmalloc space. At most, 1/4 of the overall system
memory may be allocated by DM statistics. The admin can see how much
memory is used by reading
/sys/module/dm_mod/parameters/stats_current_allocated_bytes
Messages
========
@stats_create <range> <step> [<program_id> [<aux_data>]]
Create a new region and return the region_id.
<range>
"-" - whole device
"<start_sector>+<length>" - a range of <length> 512-byte sectors
starting with <start_sector>.
<step>
"<area_size>" - the range is subdivided into areas each containing
<area_size> sectors.
"/<number_of_areas>" - the range is subdivided into the specified
number of areas.
<program_id>
An optional parameter. A name that uniquely identifies
the userspace owner of the range. This groups ranges together
so that userspace programs can identify the ranges they
created and ignore those created by others.
The kernel returns this string back in the output of
@stats_list message, but it doesn't use it for anything else.
<aux_data>
An optional parameter. A word that provides auxiliary data
that is useful to the client program that created the range.
The kernel returns this string back in the output of
@stats_list message, but it doesn't use this value for anything.
@stats_delete <region_id>
Delete the region with the specified id.
<region_id>
region_id returned from @stats_create
@stats_clear <region_id>
Clear all the counters except the in-flight i/o counters.
<region_id>
region_id returned from @stats_create
@stats_list [<program_id>]
List all regions registered with @stats_create.
<program_id>
An optional parameter.
If this parameter is specified, only matching regions
are returned.
If it is not specified, all regions are returned.
Output format:
<region_id>: <start_sector>+<length> <step> <program_id> <aux_data>
@stats_print <region_id> [<starting_line> <number_of_lines>]
Print counters for each step-sized area of a region.
<region_id>
region_id returned from @stats_create
<starting_line>
The index of the starting line in the output.
If omitted, all lines are returned.
<number_of_lines>
The number of lines to include in the output.
If omitted, all lines are returned.
Output format for each step-sized area of a region:
<start_sector>+<length> counters
The first 11 counters have the same meaning as
/sys/block/*/stat or /proc/diskstats.
Please refer to Documentation/iostats.txt for details.
1. the number of reads completed
2. the number of reads merged
3. the number of sectors read
4. the number of milliseconds spent reading
5. the number of writes completed
6. the number of writes merged
7. the number of sectors written
8. the number of milliseconds spent writing
9. the number of I/Os currently in progress
10. the number of milliseconds spent doing I/Os
11. the weighted number of milliseconds spent doing I/Os
Additional counters:
12. the total time spent reading in milliseconds
13. the total time spent writing in milliseconds
@stats_print_clear <region_id> [<starting_line> <number_of_lines>]
Atomically print and then clear all the counters except the
in-flight i/o counters. Useful when the client consuming the
statistics does not want to lose any statistics (those updated
between printing and clearing).
<region_id>
region_id returned from @stats_create
<starting_line>
The index of the starting line in the output.
If omitted, all lines are printed and then cleared.
<number_of_lines>
The number of lines to process.
If omitted, all lines are printed and then cleared.
@stats_set_aux <region_id> <aux_data>
Store auxiliary data aux_data for the specified region.
<region_id>
region_id returned from @stats_create
<aux_data>
The string that identifies data which is useful to the client
program that created the range. The kernel returns this
string back in the output of @stats_list message, but it
doesn't use this value for anything.
Examples
========
Subdivide the DM device 'vol' into 100 pieces and start collecting
statistics on them:
dmsetup message vol 0 @stats_create - /100
Set the auxillary data string to "foo bar baz" (the escape for each
space must also be escaped, otherwise the shell will consume them):
dmsetup message vol 0 @stats_set_aux 0 foo\\ bar\\ baz
List the statistics:
dmsetup message vol 0 @stats_list
Print the statistics:
dmsetup message vol 0 @stats_print 0
Delete the statistics:
dmsetup message vol 0 @stats_delete 0

138
doc/kernel/switch.txt Normal file
View File

@ -0,0 +1,138 @@
dm-switch
=========
The device-mapper switch target creates a device that supports an
arbitrary mapping of fixed-size regions of I/O across a fixed set of
paths. The path used for any specific region can be switched
dynamically by sending the target a message.
It maps I/O to underlying block devices efficiently when there is a large
number of fixed-sized address regions but there is no simple pattern
that would allow for a compact representation of the mapping such as
dm-stripe.
Background
----------
Dell EqualLogic and some other iSCSI storage arrays use a distributed
frameless architecture. In this architecture, the storage group
consists of a number of distinct storage arrays ("members") each having
independent controllers, disk storage and network adapters. When a LUN
is created it is spread across multiple members. The details of the
spreading are hidden from initiators connected to this storage system.
The storage group exposes a single target discovery portal, no matter
how many members are being used. When iSCSI sessions are created, each
session is connected to an eth port on a single member. Data to a LUN
can be sent on any iSCSI session, and if the blocks being accessed are
stored on another member the I/O will be forwarded as required. This
forwarding is invisible to the initiator. The storage layout is also
dynamic, and the blocks stored on disk may be moved from member to
member as needed to balance the load.
This architecture simplifies the management and configuration of both
the storage group and initiators. In a multipathing configuration, it
is possible to set up multiple iSCSI sessions to use multiple network
interfaces on both the host and target to take advantage of the
increased network bandwidth. An initiator could use a simple round
robin algorithm to send I/O across all paths and let the storage array
members forward it as necessary, but there is a performance advantage to
sending data directly to the correct member.
A device-mapper table already lets you map different regions of a
device onto different targets. However in this architecture the LUN is
spread with an address region size on the order of 10s of MBs, which
means the resulting table could have more than a million entries and
consume far too much memory.
Using this device-mapper switch target we can now build a two-layer
device hierarchy:
Upper Tier - Determine which array member the I/O should be sent to.
Lower Tier - Load balance amongst paths to a particular member.
The lower tier consists of a single dm multipath device for each member.
Each of these multipath devices contains the set of paths directly to
the array member in one priority group, and leverages existing path
selectors to load balance amongst these paths. We also build a
non-preferred priority group containing paths to other array members for
failover reasons.
The upper tier consists of a single dm-switch device. This device uses
a bitmap to look up the location of the I/O and choose the appropriate
lower tier device to route the I/O. By using a bitmap we are able to
use 4 bits for each address range in a 16 member group (which is very
large for us). This is a much denser representation than the dm table
b-tree can achieve.
Construction Parameters
=======================
<num_paths> <region_size> <num_optional_args> [<optional_args>...]
[<dev_path> <offset>]+
<num_paths>
The number of paths across which to distribute the I/O.
<region_size>
The number of 512-byte sectors in a region. Each region can be redirected
to any of the available paths.
<num_optional_args>
The number of optional arguments. Currently, no optional arguments
are supported and so this must be zero.
<dev_path>
The block device that represents a specific path to the device.
<offset>
The offset of the start of data on the specific <dev_path> (in units
of 512-byte sectors). This number is added to the sector number when
forwarding the request to the specific path. Typically it is zero.
Messages
========
set_region_mappings <index>:<path_nr> [<index>]:<path_nr> [<index>]:<path_nr>...
Modify the region table by specifying which regions are redirected to
which paths.
<index>
The region number (region size was specified in constructor parameters).
If index is omitted, the next region (previous index + 1) is used.
Expressed in hexadecimal (WITHOUT any prefix like 0x).
<path_nr>
The path number in the range 0 ... (<num_paths> - 1).
Expressed in hexadecimal (WITHOUT any prefix like 0x).
R<n>,<m>
This parameter allows repetitive patterns to be loaded quickly. <n> and <m>
are hexadecimal numbers. The last <n> mappings are repeated in the next <m>
slots.
Status
======
No status line is reported.
Example
=======
Assume that you have volumes vg1/switch0 vg1/switch1 vg1/switch2 with
the same size.
Create a switch device with 64kB region size:
dmsetup create switch --table "0 `blockdev --getsize /dev/vg1/switch0`
switch 3 128 0 /dev/vg1/switch0 0 /dev/vg1/switch1 0 /dev/vg1/switch2 0"
Set mappings for the first 7 entries to point to devices switch0, switch1,
switch2, switch0, switch1, switch2, switch1:
dmsetup message switch 0 set_region_mappings 0:0 :1 :2 :0 :1 :2 :1
Set repetitive mapping. This command:
dmsetup message switch 0 set_region_mappings 1000:1 :2 R2,10
is equivalent to:
dmsetup message switch 0 set_region_mappings 1000:1 :2 :1 :2 :1 :2 :1 :2 \
:1 :2 :1 :2 :1 :2 :1 :2 :1 :2

View File

@ -99,13 +99,14 @@ Using an existing pool device
$data_block_size $low_water_mark"
$data_block_size gives the smallest unit of disk space that can be
allocated at a time expressed in units of 512-byte sectors. People
primarily interested in thin provisioning may want to use a value such
as 1024 (512KB). People doing lots of snapshotting may want a smaller value
such as 128 (64KB). If you are not zeroing newly-allocated data,
a larger $data_block_size in the region of 256000 (128MB) is suggested.
$data_block_size must be the same for the lifetime of the
metadata device.
allocated at a time expressed in units of 512-byte sectors.
$data_block_size must be between 128 (64KB) and 2097152 (1GB) and a
multiple of 128 (64KB). $data_block_size cannot be changed after the
thin-pool is created. People primarily interested in thin provisioning
may want to use a value such as 1024 (512KB). People doing lots of
snapshotting may want a smaller value such as 128 (64KB). If you are
not zeroing newly-allocated data, a larger $data_block_size in the
region of 256000 (128MB) is suggested.
$low_water_mark is expressed in blocks of size $data_block_size. If
free space on the data device drops below this level then a dm event
@ -115,6 +116,35 @@ Resuming a device with a new table itself triggers an event so the
userspace daemon can use this to detect a situation where a new table
already exceeds the threshold.
A low water mark for the metadata device is maintained in the kernel and
will trigger a dm event if free space on the metadata device drops below
it.
Updating on-disk metadata
-------------------------
On-disk metadata is committed every time a FLUSH or FUA bio is written.
If no such requests are made then commits will occur every second. This
means the thin-provisioning target behaves like a physical disk that has
a volatile write cache. If power is lost you may lose some recent
writes. The metadata should always be consistent in spite of any crash.
If data space is exhausted the pool will either error or queue IO
according to the configuration (see: error_if_no_space). If metadata
space is exhausted or a metadata operation fails: the pool will error IO
until the pool is taken offline and repair is performed to 1) fix any
potential inconsistencies and 2) clear the flag that imposes repair.
Once the pool's metadata device is repaired it may be resized, which
will allow the pool to return to normal operation. Note that if a pool
is flagged as needing repair, the pool's data and metadata devices
cannot be resized until repair is performed. It should also be noted
that when the pool's metadata space is exhausted the current metadata
transaction is aborted. Given that the pool will cache IO whose
completion may have already been acknowledged to upper IO layers
(e.g. filesystem) it is strongly suggested that consistency checks
(e.g. fsck) be performed on those layers when repair of the pool is
required.
Thin provisioning
-----------------
@ -234,6 +264,8 @@ i) Constructor
read_only: Don't allow any changes to be made to the pool
metadata.
error_if_no_space: Error IOs, instead of queueing, if no space.
Data block size must be between 64KB (128 sectors) and 1GB
(2097152 sectors) inclusive.
@ -255,10 +287,9 @@ ii) Status
should register for the event and then check the target's status.
held metadata root:
The location, in sectors, of the metadata root that has been
The location, in blocks, of the metadata root that has been
'held' for userspace read access. '-' indicates there is no
held root. This feature is not yet implemented so '-' is
always returned.
held root.
discard_passdown|no_discard_passdown
Whether or not discards are actually being passed down to the
@ -275,6 +306,14 @@ ii) Status
contain the string 'Fail'. The userspace recovery tools
should then be used.
error_if_no_space|queue_if_no_space
If the pool runs out of data or metadata space, the pool will
either queue or error the IO destined to the data device. The
default is to queue the IO until more space is added or the
'no_space_timeout' expires. The 'no_space_timeout' dm-thin-pool
module parameter can be used to change this timeout -- it
defaults to 60 seconds but may be disabled using a value of 0.
iii) Messages
create_thin <dev id>
@ -341,9 +380,6 @@ then you'll have no access to blocks mapped beyond the end. If you
load a target that is bigger than before, then extra blocks will be
provisioned as and when needed.
If you wish to reduce the size of your thin device and potentially
regain some space then send the 'trim' message to the pool.
ii) Status
<nr mapped sectors> <highest mapped sector>

View File

@ -11,6 +11,7 @@ Construction Parameters
<data_block_size> <hash_block_size>
<num_data_blocks> <hash_start_block>
<algorithm> <digest> <salt>
[<#opt_params> <opt_params>]
<version>
This is the type of the on-disk hash format.
@ -62,6 +63,22 @@ Construction Parameters
<salt>
The hexadecimal encoding of the salt value.
<#opt_params>
Number of optional parameters. If there are no optional parameters,
the optional paramaters section can be skipped or #opt_params can be zero.
Otherwise #opt_params is the number of following arguments.
Example of optional parameters section:
1 ignore_corruption
ignore_corruption
Log corrupted blocks, but allow read operations to proceed normally.
restart_on_corruption
Restart the system when a corrupted block is discovered. This option is
not compatible with ignore_corruption and requires user space support to
avoid restart loops.
Theory of operation
===================
@ -125,7 +142,7 @@ block boundary) are the hash blocks which are stored a depth at a time
The full specification of kernel parameters and on-disk metadata format
is available at the cryptsetup project's wiki page
http://code.google.com/p/cryptsetup/wiki/DMVerity
https://gitlab.com/cryptsetup/cryptsetup/wikis/DMVerity
Status
======
@ -142,7 +159,7 @@ Set up a device:
A command line tool veritysetup is available to compute or verify
the hash tree or activate the kernel device. This is available from
the cryptsetup upstream repository http://code.google.com/p/cryptsetup/
the cryptsetup upstream repository https://gitlab.com/cryptsetup/cryptsetup/
(as a libcryptsetup extension).
Create hash on the device:

View File

@ -137,6 +137,17 @@ hosts. Overall, this is not hard, but the devil is in the details. I would
possibly disable lvmetad for clustered volume groups in the first phase and
only proceed when the local mode is robust and well tested.
With lvmlockd, lvmetad state is kept up to date by flagging either an
individual VG as "invalid", or the global state as "invalid". When either
the VG or the global state are read, this invalid flag is returned along
with the data. The client command can check for this invalid state and
decide to read the information from disk rather than use the stale cached
data. After the latest data is read from disk, the command may choose to
send it to lvmetad to update the cache. lvmlockd uses version numbers
embedded in its VG and global locks to detect when cached data becomes
invalid, and it then tells lvmetad to set the related invalid flag.
dct, 2015-06-23
Protocol & co.
--------------

81
doc/lvmpolld_overview.txt Normal file
View File

@ -0,0 +1,81 @@
LVM poll daemon overview
========================
(last updated: 2015-05-09)
LVM poll daemon (lvmpolld) is the alternative for lvm2 classical polling
mechanisms. The motivation behind new lvmpolld was to create persistent
system service that would be more durable and transparent. It's suited
particularly for any systemd enabled distribution.
Before lvmpolld any background polling process originating in a lvm2 command
initiated inside cgroup of a systemd service could get killed if the main
process (service) exited in such cgroup. That could lead to premature termination
of such lvm2 polling process.
Also without lvmpolld there were no means to detect a particular polling process
suited for monitoring of specific operation is already in-progress and therefore
it's not desirable to start next one with exactly same task. lvmpolld is able to
detect such duplicate requests and not spawn such redundant process.
lvmpolld is primarily targeted for systems with systemd as init process. For systems
without systemd there's no need to install lvmpolld because there is no issue
with observation described in second paragraph. You can still benefit from
avoiding duplicate polling process being spawned, but without systemd lvmpolld
can't easily be run on-demand (activated by a socket maintained by systemd).
lvmpolld implement shutdown on idle and can shutdown automatically when idle
for requested time. 60 second is recommended default here. This behaviour can be
turned off if found useless.
Data structures
---------------
a) Logical Volume (struct lvmpolld_lv)
Each operation is identified by LV. Internal identifier within lvmpolld
is full LV uuid (vg_uuid+lv_uuid) prefixed with LVM_SYSTEM_DIR if set by client.
such full identifier may look like:
"/etc/lvm/lvm.confWFd2dU67S8Av29IcJCnYzqQirdfElnxzhCdzEh7EJrfCn9R1TIQjIj58weUZDre4"
or without LVM_SYSTEM_DIR being set explicitly:
"WFd2dU67S8Av29IcJCnYzqQirdfElnxzhCdzEh7EJrfCn9R1TIQjIj58weUZDre4"
LV carries various metadata about polling operation. The most significant are:
VG name
LV name
polling interval (usually --interval passed to lvm2 command or default from lvm2
configuration)
operation type (one of: pvmove, convert, merge, thin_merge)
LVM_SYSTEM_DIR (if set, this is also passed among environment variables of lvpoll
command spawned by lvmpolld)
b) LV stores (struct lvmpolld_store)
lvmpolld uses two stores for Logical volumes (struct lvmpolld_lv). One store for polling
operations in-progress. These operations are as of now: PV move, mirror up-conversion,
classical snapshot merge, thin snapshot merge.
The second store is suited only for pvmove --abort operations in-progress. Both
stores are independent and identical LVs (pvmove /dev/sda3 and pvmove --abort /dev/sda3)
can be run concurently from lvmpolld point of view (on lvm2 side the consistency is
guaranteed by lvm2 locking mechanism).
Locking order
-------------
There are two types of locks in lvmpolld. Each store has own store lock and each LV has
own lv lock.
Locking order is:
1) store lock
2) LV lock
Each LV has to be inside a store. When daemon requires to take both locks it has
to take a store lock first and LV lock has to be taken afterwards (after the
appropriate store lock where the LV is being stored :))

View File

@ -1,11 +1,15 @@
@top_srcdir@/daemons/clvmd/clvm.h
@top_srcdir@/daemons/dmeventd/libdevmapper-event.h
@top_srcdir@/daemons/lvmetad/lvmetad-client.h
@top_srcdir@/daemons/lvmpolld/lvmpolld-protocol.h
@top_srcdir@/daemons/lvmpolld/polling_ops.h
@top_srcdir@/daemons/lvmlockd/lvmlockd-client.h
@top_srcdir@/liblvm/lvm2app.h
@top_srcdir@/lib/activate/activate.h
@top_srcdir@/lib/activate/targets.h
@top_srcdir@/lib/cache/lvmcache.h
@top_srcdir@/lib/cache/lvmetad.h
@top_srcdir@/lib/locking/lvmlockd.h
@top_srcdir@/lib/commands/toolcontext.h
@top_srcdir@/lib/config/config.h
@top_srcdir@/lib/config/config_settings.h
@ -13,6 +17,7 @@
@top_srcdir@/lib/datastruct/btree.h
@top_srcdir@/lib/datastruct/str_list.h
@top_srcdir@/lib/device/dev-cache.h
@top_srcdir@/lib/device/dev-ext-udev-constants.h
@top_srcdir@/lib/device/dev-type.h
@top_srcdir@/lib/device/device.h
@top_srcdir@/lib/device/device-types.h
@ -28,6 +33,8 @@
@top_srcdir@/lib/locking/locking.h
@top_srcdir@/lib/log/log.h
@top_srcdir@/lib/log/lvm-logging.h
@top_srcdir@/lib/lvmpolld/lvmpolld-client.h
@top_srcdir@/lib/lvmpolld/polldaemon.h
@top_srcdir@/lib/metadata/lv.h
@top_srcdir@/lib/metadata/lv_alloc.h
@top_srcdir@/lib/metadata/metadata.h
@ -38,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
@ -49,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
@ -69,3 +74,4 @@
@top_srcdir@/libdm/misc/kdev_t.h
@top_srcdir@/po/pogen.h
@top_srcdir@/tools/lvm2cmd.h
@top_srcdir@/tools/tool.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.
#
@ -20,8 +20,12 @@ include $(top_builddir)/make.tmpl
all: .symlinks_created
.symlinks_created: .symlinks
find . -maxdepth 1 -type l -exec $(RM) \{\} \;
LINKS := $(shell find . -maxdepth 1 -type l)
.symlinks_created: .symlinks
ifneq (,$(firstword $(LINKS)))
$(RM) $(LINKS)
endif
for i in `cat $<`; do $(LN_S) $$i ; done
touch $@
@ -31,5 +35,5 @@ device-mapper: all
cflow: all
DISTCLEAN_TARGETS += $(shell find . -maxdepth 1 -type l)
DISTCLEAN_TARGETS += .include_symlinks .symlinks_created .symlinks
DISTCLEAN_TARGETS += .symlinks configure.h lvm-version.h
CLEAN_TARGETS += $(LINKS) .include_symlinks .symlinks_created

View File

@ -1,11 +1,27 @@
/* 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
/* The path to 'cache_check', if available. */
#undef CACHE_CHECK_CMD
/* Define to 1 if the external 'cache_check' tool requires the
--clear-needs-check-flag option */
#undef CACHE_CHECK_NEEDS_CHECK
/* The path to 'cache_dump', if available. */
#undef CACHE_DUMP_CMD
/* Define to 1 to include built-in support for cache. */
#undef CACHE_INTERNAL
/* The path to 'cache_repair', if available. */
#undef CACHE_REPAIR_CMD
/* The path to 'cache_restore', if available. */
#undef CACHE_RESTORE_CMD
/* Define to 1 if the `closedir' function returns void instead of `int'. */
#undef CLOSEDIR_VOID
@ -53,24 +69,52 @@
/* Default DM run directory. */
#undef DEFAULT_DM_RUN_DIR
/* Default system configuration directory. */
#undef DEFAULT_ETC_DIR
/* Fall back to LVM1 by default if device-mapper is missing from the kernel.
*/
#undef DEFAULT_FALLBACK_TO_LVM1
/* Name of default locking directory. */
#undef DEFAULT_LOCK_DIR
/* Default segtype used for mirror volumes. */
#undef DEFAULT_MIRROR_SEGTYPE
/* Default directory to keep PID files in. */
#undef DEFAULT_PID_DIR
/* Name of default configuration profile subdirectory. */
#undef DEFAULT_PROFILE_SUBDIR
/* Default segtype used for raid10 volumes. */
#undef DEFAULT_RAID10_SEGTYPE
/* Default LVM run directory. */
#undef DEFAULT_RUN_DIR
/* Define to 0 to reinstate the pre-2.02.54 handling of unit suffixes. */
#undef DEFAULT_SI_UNIT_CONSISTENCY
/* Default segtype used for sparse volumes. */
#undef DEFAULT_SPARSE_SEGTYPE
/* Path to LVM system directory. */
#undef DEFAULT_SYS_DIR
/* Use blkid wiping by default. */
#undef DEFAULT_USE_BLKID_WIPING
/* Use lvmetad by default. */
#undef DEFAULT_USE_LVMETAD
/* Use lvmlockd by default. */
#undef DEFAULT_USE_LVMLOCKD
/* Use lvmpolld by default. */
#undef DEFAULT_USE_LVMPOLLD
/* Define to 1 to enable LVM2 device-mapper interaction. */
#undef DEVMAPPER_SUPPORT
@ -83,9 +127,27 @@
/* Path to dmeventd pidfile. */
#undef DMEVENTD_PIDFILE
/* Define to enable compat protocol */
#undef DM_COMPAT
/* Define default group for device node */
#undef DM_DEVICE_GID
/* Define default mode for device node */
#undef DM_DEVICE_MODE
/* Define default owner for device node */
#undef DM_DEVICE_UID
/* Define to enable ioctls calls to kernel */
#undef DM_IOCTLS
/* Library version */
#undef DM_LIB_VERSION
/* Define to 1 if you have the `alarm' function. */
#undef HAVE_ALARM
/* Define to 1 if you have `alloca', as a function or macro. */
#undef HAVE_ALLOCA
@ -102,12 +164,18 @@
/* Define to 1 if you have the <assert.h> header file. */
#undef HAVE_ASSERT_H
/* Define to 1 if you have the `atexit' function. */
#undef HAVE_ATEXIT
/* Define to 1 if canonicalize_file_name is available. */
#undef HAVE_CANONICALIZE_FILE_NAME
/* Define to 1 if your system has a working `chown' function. */
#undef HAVE_CHOWN
/* Define to 1 if you have the `clock_gettime' function. */
#undef HAVE_CLOCK_GETTIME
/* Define to 1 if you have the <corosync/cmap.h> header file. */
#undef HAVE_COROSYNC_CMAP_H
@ -117,6 +185,10 @@
/* Define to 1 if you have the <ctype.h> header file. */
#undef HAVE_CTYPE_H
/* Define to 1 if you have the declaration of `strerror_r', and to 0 if you
don't. */
#undef HAVE_DECL_STRERROR_R
/* Define to 1 if you have the <dirent.h> header file. */
#undef HAVE_DIRENT_H
@ -135,6 +207,9 @@
/* Define to 1 if you have the <fcntl.h> header file. */
#undef HAVE_FCNTL_H
/* Define to 1 if you have the <float.h> header file. */
#undef HAVE_FLOAT_H
/* Define to 1 if you have the `fork' function. */
#undef HAVE_FORK
@ -192,6 +267,9 @@
/* Define to 1 if you have the <locale.h> header file. */
#undef HAVE_LOCALE_H
/* Define to 1 if you have the `localtime_r' function. */
#undef HAVE_LOCALTIME_R
/* Define to 1 if `lstat' has the bug that it succeeds when given the
zero-length file name argument. */
#undef HAVE_LSTAT_EMPTY_STRING_BUG
@ -206,6 +284,9 @@
/* Define to 1 if you have the <malloc.h> header file. */
#undef HAVE_MALLOC_H
/* Define to 1 if you have the `memchr' function. */
#undef HAVE_MEMCHR
/* Define to 1 if you have the `memmove' function. */
#undef HAVE_MEMMOVE
@ -242,9 +323,15 @@
/* Define to 1 if you have the `nl_langinfo' function. */
#undef HAVE_NL_LANGINFO
/* Define to 1 if you have the <paths.h> header file. */
#undef HAVE_PATHS_H
/* Define to 1 if you have the <pthread.h> header file. */
#undef HAVE_PTHREAD_H
/* Define to 1 if the system has the type `ptrdiff_t'. */
#undef HAVE_PTRDIFF_T
/* Define to 1 if you have the <readline/history.h> header file. */
#undef HAVE_READLINE_HISTORY_H
@ -255,6 +342,9 @@
and to 0 otherwise. */
#undef HAVE_REALLOC
/* Define to 1 if you have the `realpath' function. */
#undef HAVE_REALPATH
/* Define to 1 to include support for realtime clock. */
#undef HAVE_REALTIME
@ -298,9 +388,15 @@
zero-length file name argument. */
#undef HAVE_STAT_EMPTY_STRING_BUG
/* Define if struct stat has a field st_ctim with timespec for ctime */
#undef HAVE_STAT_ST_CTIM
/* Define to 1 if you have the <stdarg.h> header file. */
#undef HAVE_STDARG_H
/* Define to 1 if stdbool.h conforms to C99. */
#undef HAVE_STDBOOL_H
/* Define to 1 if you have the <stddef.h> header file. */
#undef HAVE_STDDEF_H
@ -328,6 +424,9 @@
/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
/* Define to 1 if you have the `strerror_r' function. */
#undef HAVE_STRERROR_R
/* Define to 1 if you have the <strings.h> header file. */
#undef HAVE_STRINGS_H
@ -337,6 +436,12 @@
/* Define to 1 if you have the `strncasecmp' function. */
#undef HAVE_STRNCASECMP
/* Define to 1 if you have the `strndup' function. */
#undef HAVE_STRNDUP
/* Define to 1 if you have the `strpbrk' function. */
#undef HAVE_STRPBRK
/* Define to 1 if you have the `strrchr' function. */
#undef HAVE_STRRCHR
@ -352,6 +457,9 @@
/* Define to 1 if you have the `strtoul' function. */
#undef HAVE_STRTOUL
/* Define to 1 if you have the `strtoull' function. */
#undef HAVE_STRTOULL
/* Define to 1 if `st_rdev' is a member of `struct stat'. */
#undef HAVE_STRUCT_STAT_ST_RDEV
@ -405,6 +513,9 @@
/* Define to 1 if you have the <sys/stat.h> header file. */
#undef HAVE_SYS_STAT_H
/* Define to 1 if you have the <sys/timerfd.h> header file. */
#undef HAVE_SYS_TIMERFD_H
/* Define to 1 if you have the <sys/time.h> header file. */
#undef HAVE_SYS_TIME_H
@ -438,6 +549,9 @@
/* Define to 1 if you have the <utmpx.h> header file. */
#undef HAVE_UTMPX_H
/* valgrind.h found */
#undef HAVE_VALGRIND
/* Define to 1 if you have the `vfork' function. */
#undef HAVE_VFORK
@ -453,6 +567,21 @@
/* Define to 1 if `vfork' works. */
#undef HAVE_WORKING_VFORK
/* Define to 1 if the system has the type `_Bool'. */
#undef HAVE__BOOL
/* Internalization package */
#undef INTL_PACKAGE
/* Locale-dependent data */
#undef LOCALEDIR
/* Define to 1 to include code that uses lvmlockd dlm option. */
#undef LOCKDDLM_SUPPORT
/* Define to 1 to include code that uses lvmlockd sanlock option. */
#undef LOCKDSANLOCK_SUPPORT
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */
#undef LSTAT_FOLLOWS_SLASHED_SYMLINK
@ -470,6 +599,18 @@
/* Define to 1 to include code that uses lvmetad. */
#undef LVMETAD_SUPPORT
/* Path to lvmlockd pidfile. */
#undef LVMLOCKD_PIDFILE
/* Define to 1 to include code that uses lvmlockd. */
#undef LVMLOCKD_SUPPORT
/* Path to lvmpolld pidfile. */
#undef LVMPOLLD_PIDFILE
/* Define to 1 to include code that uses lvmpolld. */
#undef LVMPOLLD_SUPPORT
/* Path to lvm binary. */
#undef LVM_PATH
@ -546,6 +687,12 @@
/* Define to 1 if you have the ANSI C header files. */
#undef STDC_HEADERS
/* Define to 1 if strerror_r returns char *. */
#undef STRERROR_R_CHAR_P
/* Path to testsuite data */
#undef TESTSUITE_DATA
/* The path to 'thin_check', if available. */
#undef THIN_CHECK_CMD

View File

@ -56,11 +56,13 @@ SOURCES =\
datastruct/btree.c \
datastruct/str_list.c \
device/dev-cache.c \
device/dev-ext.c \
device/dev-io.c \
device/dev-md.c \
device/dev-swap.c \
device/dev-type.c \
device/dev-luks.c \
device/dev-dasd.c \
display/display.c \
error/errseg.c \
unknown/unknown.c \
@ -69,9 +71,11 @@ SOURCES =\
filters/filter-regex.c \
filters/filter-sysfs.c \
filters/filter-md.c \
filters/filter-fwraid.c \
filters/filter-mpath.c \
filters/filter-partitioned.c \
filters/filter-type.c \
filters/filter-usable.c \
format_text/archive.c \
format_text/archiver.c \
format_text/export.c \
@ -79,7 +83,6 @@ SOURCES =\
format_text/format-text.c \
format_text/import.c \
format_text/import_vsn1.c \
format_text/tags.c \
format_text/text_label.c \
freeseg/freeseg.c \
label/label.c \
@ -120,11 +123,6 @@ SOURCES =\
uuid/uuid.c \
zero/zero.c
ifeq ("@HAVE_REALTIME@", "yes")
SOURCES +=\
misc/timestamp.c
endif
ifeq ("@LVM1@", "internal")
SOURCES +=\
format1/disk-rep.c \
@ -193,6 +191,16 @@ ifeq ("@BUILD_LVMETAD@", "yes")
cache/lvmetad.c
endif
ifeq ("@BUILD_LVMPOLLD@", "yes")
SOURCES +=\
lvmpolld/lvmpolld-client.c
endif
ifeq ("@BUILD_LVMLOCKD@", "yes")
SOURCES +=\
locking/lvmlockd.c
endif
ifeq ("@DMEVENTD@", "yes")
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd
LIBS += -ldevmapper-event
@ -219,8 +227,8 @@ CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS)
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

File diff suppressed because it is too large Load Diff

View File

@ -30,6 +30,37 @@ struct lvinfo {
uint32_t read_ahead;
};
typedef enum {
SEG_STATUS_NONE,
SEG_STATUS_CACHE,
SEG_STATUS_RAID,
SEG_STATUS_SNAPSHOT,
SEG_STATUS_THIN,
SEG_STATUS_THIN_POOL,
SEG_STATUS_UNKNOWN
} lv_seg_status_type_t;
struct lv_seg_status {
struct dm_pool *mem; /* input */
const struct lv_segment *seg; /* input */
lv_seg_status_type_t type; /* output */
union {
struct dm_status_cache *cache;
struct dm_status_raid *raid;
struct dm_status_snapshot *snapshot;
struct dm_status_thin *thin;
struct dm_status_thin_pool *thin_pool;
};
};
struct lv_with_info_and_seg_status {
const struct logical_volume *lv; /* input */
int info_ok;
struct lvinfo info; /* output */
int seg_part_of_lv; /* output */
struct lv_seg_status seg_status; /* input/output, see lv_seg_status */
};
struct lv_activate_opts {
int exclusive;
int origin_only;
@ -74,34 +105,54 @@ void activation_release(void);
void activation_exit(void);
/* int lv_suspend(struct cmd_context *cmd, const char *lvid_s); */
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive, struct logical_volume *lv_ondisk, struct logical_volume *lv_incore);
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, struct logical_volume *lv);
int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, unsigned exclusive,
const struct logical_volume *lv_ondisk, const struct logical_volume *lv_incore);
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, const struct logical_volume *lv);
int lv_resume_if_active(struct cmd_context *cmd, const char *lvid_s,
unsigned origin_only, unsigned exclusive, unsigned revert, struct logical_volume *lv);
unsigned origin_only, unsigned exclusive, unsigned revert, const struct logical_volume *lv);
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, struct logical_volume *lv);
int noscan, int temporary, const struct logical_volume *lv);
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s, int exclusive,
int noscan, int temporary, struct logical_volume *lv);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, struct logical_volume *lv);
int noscan, int temporary, const struct logical_volume *lv);
int lv_deactivate(struct cmd_context *cmd, const char *lvid_s, const struct logical_volume *lv);
int lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
/*
* Returns 1 if info structure has been populated, else 0.
* Returns 1 if info structure has been populated, else 0 on failure.
* When lvinfo* is NULL, it returns 1 if the device is locally active, 0 otherwise.
*/
int lv_info(struct cmd_context *cmd, const struct logical_volume *lv, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead);
int lv_info_by_lvid(struct cmd_context *cmd, const char *lvid_s, int use_layer,
struct lvinfo *info, int with_open_count, int with_read_ahead);
int lv_check_not_in_use(struct cmd_context *cmd, struct logical_volume *lv,
struct lvinfo *info);
/*
* Returns 1 if lv_seg_status structure has been populated,
* else 0 on failure or if device not active locally.
*/
int lv_status(struct cmd_context *cmd, const struct lv_segment *lv_seg,
int use_layer, struct lv_seg_status *lv_seg_status);
/*
* Returns 1 if lv_info_and_seg_status structure has been populated,
* else 0 on failure or if device not active locally.
*
* lv_info_with_seg_status is the same as calling lv_info and then lv_status,
* but this fn tries to do that with one ioctl if possible.
*/
int lv_info_with_seg_status(struct cmd_context *cmd, const struct logical_volume *lv,
const struct lv_segment *lv_seg, int use_layer,
struct lv_with_info_and_seg_status *status,
int with_open_count, int with_read_ahead);
int lv_check_not_in_use(const struct logical_volume *lv);
/*
* Returns 1 if activate_lv has been set: 1 = activate; 0 = don't.
*/
int lv_activation_filter(struct cmd_context *cmd, const char *lvid_s,
int *activate_lv, struct logical_volume *lv);
int *activate_lv, const struct logical_volume *lv);
/*
* Checks against the auto_activation_volume_list and
* returns 1 if the LV should be activated, 0 otherwise.
@ -120,12 +171,8 @@ int lv_raid_dev_health(const struct logical_volume *lv, char **dev_health);
int lv_raid_mismatch_count(const struct logical_volume *lv, uint64_t *cnt);
int lv_raid_sync_action(const struct logical_volume *lv, char **sync_action);
int lv_raid_message(const struct logical_volume *lv, const char *msg);
int lv_cache_block_info(struct logical_volume *lv,
uint32_t *chunk_size, uint64_t *dirty_count,
uint64_t *used_count, uint64_t *total_count);
int lv_cache_policy_info(struct logical_volume *lv,
const char **policy_name, int *policy_argc,
const char ***policy_argv);
int lv_cache_status(const struct logical_volume *lv,
struct lv_status_cache **status);
int lv_thin_pool_percent(const struct logical_volume *lv, int metadata,
dm_percent_t *percent);
int lv_thin_percent(const struct logical_volume *lv, int mapped,
@ -147,18 +194,18 @@ int lv_is_active_exclusive(const struct logical_volume *lv);
int lv_is_active_exclusive_locally(const struct logical_volume *lv);
int lv_is_active_exclusive_remotely(const struct logical_volume *lv);
int lv_has_target_type(struct dm_pool *mem, struct logical_volume *lv,
int lv_has_target_type(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer, const char *target_type);
int monitor_dev_for_events(struct cmd_context *cmd, struct logical_volume *lv,
int monitor_dev_for_events(struct cmd_context *cmd, const struct logical_volume *lv,
const struct lv_activate_opts *laopts, int do_reg);
#ifdef DMEVENTD
# include "libdevmapper-event.h"
char *get_monitor_dso_path(struct cmd_context *cmd, const char *libpath);
int target_registered_with_dmeventd(struct cmd_context *cmd, const char *libpath,
struct logical_volume *lv, int *pending);
int target_register_events(struct cmd_context *cmd, const char *dso, struct logical_volume *lv,
const struct logical_volume *lv, int *pending);
int target_register_events(struct cmd_context *cmd, const char *dso, const struct logical_volume *lv,
int evmask __attribute__((unused)), int set, int timeout);
#endif
@ -172,18 +219,19 @@ int add_linear_area_to_dtree(struct dm_tree_node *node, uint64_t size,
int pv_uses_vg(struct physical_volume *pv,
struct volume_group *vg);
struct dev_usable_check_params {
unsigned int check_empty:1;
unsigned int check_blocked:1;
unsigned int check_suspended:1;
unsigned int check_error_target:1;
unsigned int check_reserved:1;
};
/*
* Returns 1 if mapped device is not suspended, blocked or
* is using a reserved name.
*/
int device_is_usable(struct device *dev);
/*
* Returns 1 if the device is suspended or blocking.
* (Does not perform check on the LV name of the device.)
* N.B. This is !device_is_usable() without the name check.
*/
int device_is_suspended_or_blocking(struct device *dev);
int device_is_usable(struct device *dev, struct dev_usable_check_params check);
/*
* Declaration moved here from fs.h to keep header fs.h hidden

File diff suppressed because it is too large Load Diff

View File

@ -25,8 +25,9 @@ struct cmd_context;
struct dev_manager;
struct dm_info;
struct device;
struct lv_seg_status;
int read_only_lv(struct logical_volume *lv, struct lv_activate_opts *laopts);
int read_only_lv(const struct logical_volume *lv, const struct lv_activate_opts *laopts);
/*
* Constructor and destructor.
@ -47,7 +48,8 @@ void dev_manager_exit(void);
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
struct dm_info *info, uint32_t *read_ahead);
struct dm_info *dminfo, uint32_t *read_ahead,
struct lv_seg_status *seg_status);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
dm_percent_t *percent);
@ -62,7 +64,7 @@ int dev_manager_raid_message(struct dev_manager *dm,
const char *msg);
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_cache **status);
struct lv_status_cache **status);
int dev_manager_thin_pool_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_thin_pool **status,
@ -76,14 +78,14 @@ int dev_manager_thin_percent(struct dev_manager *dm,
int dev_manager_thin_device_id(struct dev_manager *dm,
const struct logical_volume *lv,
uint32_t *device_id);
int dev_manager_suspend(struct dev_manager *dm, struct logical_volume *lv,
int dev_manager_suspend(struct dev_manager *dm, const struct logical_volume *lv,
struct lv_activate_opts *laopts, int lockfs, int flush_required);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv,
int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv,
struct lv_activate_opts *laopts);
int dev_manager_preload(struct dev_manager *dm, struct logical_volume *lv,
int dev_manager_preload(struct dev_manager *dm, const struct logical_volume *lv,
struct lv_activate_opts *laopts, int *flush_required);
int dev_manager_deactivate(struct dev_manager *dm, struct logical_volume *lv);
int dev_manager_transient(struct dev_manager *dm, struct logical_volume *lv) __attribute__((nonnull(1, 2)));
int dev_manager_deactivate(struct dev_manager *dm, const struct logical_volume *lv);
int dev_manager_transient(struct dev_manager *dm, const struct logical_volume *lv) __attribute__((nonnull(1, 2)));
int dev_manager_mknodes(const struct logical_volume *lv);

View File

@ -468,8 +468,8 @@ int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
return _fs_op(FS_DEL, dev_dir, vg_name, lv_name, "", "", check_udev);
}
int fs_rename_lv(struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname)
int fs_rename_lv(const struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname)
{
if (strcmp(old_vgname, lv->vg->name)) {
return

View File

@ -27,7 +27,7 @@ int fs_add_lv(const struct logical_volume *lv, const char *dev);
int fs_del_lv(const struct logical_volume *lv);
int fs_del_lv_byname(const char *dev_dir, const char *vg_name,
const char *lv_name, int check_udev);
int fs_rename_lv(struct logical_volume *lv, const char *dev,
int fs_rename_lv(const struct logical_volume *lv, const char *dev,
const char *old_vgname, const char *old_lvname);
/* void fs_unlock(void); moved to activate.h */
uint32_t fs_get_cookie(void);

531
lib/cache/lvmcache.c vendored
View File

@ -56,6 +56,9 @@ struct lvmcache_vginfo {
char _padding[7];
struct lvmcache_vginfo *next; /* Another VG with same name? */
char *creation_host;
char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
size_t vgmetadata_size;
char *vgmetadata; /* Copy of VG metadata as format_text string */
struct dm_config_tree *cft; /* Config tree created from vgmetadata */
@ -65,6 +68,7 @@ struct lvmcache_vginfo {
unsigned vg_use_count; /* Counter of vg reusage */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */
unsigned preferred_duplicates; /* preferred duplicate pvs have been set */
};
static struct dm_hash_table *_pvid_hash = NULL;
@ -76,6 +80,7 @@ static int _scanning_in_progress = 0;
static int _has_scanned = 0;
static int _vgs_locked = 0;
static int _vg_global_lock_held = 0; /* Global lock held when cache wiped? */
static int _found_duplicate_pvs = 0; /* If we never see a duplicate PV we can skip checking for them later. */
int lvmcache_init(void)
{
@ -112,6 +117,47 @@ int lvmcache_init(void)
return 1;
}
/*
* Once PV info has been populated in lvmcache and
* lvmcache has chosen preferred duplicate devices,
* set this flag so that lvmcache will not try to
* compare and choose preferred duplicate devices
* again (which may result in different preferred
* devices.) PV info can be populated in lvmcache
* multiple times, each time causing lvmcache to
* compare the duplicate devices, so we need to
* record that the comparison/preferences have
* already been done, so the preferrences from the
* first time through are not changed.
*
* This is something of a hack to work around the
* fact that the code isn't really designed to
* handle duplicate PVs, and the fact that lvmetad
* has its own way of picking a preferred duplicate
* and lvmcache has another way based on having
* more information than lvmetad does.
*
* If we come up with a better overall method to
* handle duplicate PVs, then this can probably be
* removed.
*
* FIXME: if we want to make lvmetad work with clvmd,
* then this may need to be changed to set
* preferred_duplicates back to 0.
*/
void lvmcache_set_preferred_duplicates(const char *vgid)
{
struct lvmcache_vginfo *vginfo;
if (!(vginfo = lvmcache_vginfo_from_vgid(vgid))) {
stack;
return;
}
vginfo->preferred_duplicates = 1;
}
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd)
{
if (!lvmetad_active() || _has_scanned)
@ -284,6 +330,9 @@ void lvmcache_commit_metadata(const char *vgname)
void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
{
if (lvmcache_vgname_is_locked(VG_GLOBAL) && !vg_write_lock_held())
return;
/* For VG_ORPHANS, we need to invalidate all labels on orphan PVs. */
if (!strcmp(vgname, VG_ORPHANS)) {
_drop_metadata(FMT_TEXT_ORPHAN_VG_NAME, 0);
@ -292,7 +341,7 @@ void lvmcache_drop_metadata(const char *vgname, int drop_precommitted)
/* Indicate that PVs could now be missing from the cache */
init_full_scan_done(0);
} else if (!lvmcache_vgname_is_locked(VG_GLOBAL))
} else
_drop_metadata(vgname, drop_precommitted);
}
@ -367,10 +416,10 @@ void lvmcache_lock_vgname(const char *vgname, int read_only __attribute__((unuse
if (!dm_hash_insert(_lock_hash, vgname, (void *) 1))
log_error("Cache locking failure for %s", vgname);
_update_cache_lock_state(vgname, 1);
if (strcmp(vgname, VG_GLOBAL))
if (strcmp(vgname, VG_GLOBAL)) {
_update_cache_lock_state(vgname, 1);
_vgs_locked++;
}
}
int lvmcache_vgname_is_locked(const char *vgname)
@ -387,7 +436,8 @@ void lvmcache_unlock_vgname(const char *vgname)
log_error(INTERNAL_ERROR "Attempt to unlock unlocked VG %s.",
vgname);
_update_cache_lock_state(vgname, 0);
if (strcmp(vgname, VG_GLOBAL))
_update_cache_lock_state(vgname, 0);
dm_hash_remove(_lock_hash, vgname);
@ -401,6 +451,16 @@ int lvmcache_vgs_locked(void)
return _vgs_locked;
}
/*
* When lvmcache sees a duplicate PV, this is set.
* process_each_pv() can avoid searching for duplicates
* by checking this and seeing that no duplicate PVs exist.
*/
int lvmcache_found_duplicate_pvs(void)
{
return _found_duplicate_pvs;
}
static void _vginfo_attach_info(struct lvmcache_vginfo *vginfo,
struct lvmcache_info *info)
{
@ -693,10 +753,10 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
goto out;
}
if (full_scan == 2 && (cmd->filter && !cmd->filter->use_count) && !refresh_filters(cmd))
if (full_scan == 2 && (cmd->full_filter && !cmd->full_filter->use_count) && !refresh_filters(cmd))
goto_out;
if (!cmd->filter || !(iter = dev_iter_create(cmd->filter, (full_scan == 2) ? 1 : 0))) {
if (!cmd->full_filter || !(iter = dev_iter_create(cmd->full_filter, (full_scan == 2) ? 1 : 0))) {
log_error("dev_iter creation failed");
goto out;
}
@ -719,8 +779,8 @@ int lvmcache_label_scan(struct cmd_context *cmd, int full_scan)
* device cache for the benefit of short-lived processes.
*/
if (full_scan == 2 && cmd->is_long_lived &&
cmd->dump_filter && cmd->filter && cmd->filter->dump &&
!cmd->filter->dump(cmd->filter, 0))
cmd->dump_filter && cmd->full_filter && cmd->full_filter->dump &&
!cmd->full_filter->dump(cmd->full_filter, 0))
stack;
r = 1;
@ -846,6 +906,37 @@ int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo
}
// #endif
int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
struct dm_list *vgnameids)
{
struct vgnameid_list *vgnl;
struct lvmcache_vginfo *vginfo;
lvmcache_label_scan(cmd, 0);
dm_list_iterate_items(vginfo, &_vginfos) {
if (!include_internal && is_orphan_vg(vginfo->vgname))
continue;
if (!(vgnl = dm_pool_alloc(cmd->mem, sizeof(*vgnl)))) {
log_error("vgnameid_list allocation failed.");
return 0;
}
vgnl->vgid = dm_pool_strdup(cmd->mem, vginfo->vgid);
vgnl->vg_name = dm_pool_strdup(cmd->mem, vginfo->vgname);
if (!vgnl->vgid || !vgnl->vg_name) {
log_error("vgnameid_list member allocation failed.");
return 0;
}
dm_list_add(vgnameids, &vgnl->list);
}
return 1;
}
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal)
{
@ -1357,7 +1448,7 @@ static int _lvmcache_update_vgname(struct lvmcache_info *info,
}
static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstatus,
const char *creation_host)
const char *creation_host, const char *lock_type)
{
if (!info || !info->vginfo)
return 1;
@ -1370,11 +1461,11 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
info->vginfo->status = vgstatus;
if (!creation_host)
return 1;
goto set_lock_type;
if (info->vginfo->creation_host && !strcmp(creation_host,
info->vginfo->creation_host))
return 1;
goto set_lock_type;
if (info->vginfo->creation_host)
dm_free(info->vginfo->creation_host);
@ -1388,6 +1479,44 @@ static int _lvmcache_update_vgstatus(struct lvmcache_info *info, uint32_t vgstat
log_debug_cache("lvmcache: %s: VG %s: Set creation host to %s.",
dev_name(info->dev), info->vginfo->vgname, creation_host);
set_lock_type:
if (!lock_type)
goto out;
if (info->vginfo->lock_type && !strcmp(lock_type, info->vginfo->lock_type))
goto out;
if (info->vginfo->lock_type)
dm_free(info->vginfo->lock_type);
if (!(info->vginfo->lock_type = dm_strdup(lock_type))) {
log_error("cache creation host alloc failed for %s",
lock_type);
return 0;
}
out:
return 1;
}
static int _lvmcache_update_vg_mda_info(struct lvmcache_info *info, uint32_t mda_checksum,
size_t mda_size)
{
if (!info || !info->vginfo || !mda_size)
return 1;
if (info->vginfo->mda_checksum == mda_checksum || info->vginfo->mda_size == mda_size)
return 1;
info->vginfo->mda_checksum = mda_checksum;
info->vginfo->mda_size = mda_size;
/* FIXME Add checksum index */
log_debug_cache("lvmcache: %s: VG %s: Stored metadata checksum %" PRIu32 " with size %" PRIsize_t ".",
dev_name(info->dev), info->vginfo->vgname, mda_checksum, mda_size);
return 1;
}
@ -1401,10 +1530,11 @@ int lvmcache_add_orphan_vginfo(const char *vgname, struct format_type *fmt)
return _lvmcache_update_vgname(NULL, vgname, vgname, 0, "", fmt);
}
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *creation_host)
int lvmcache_update_vgname_and_id(struct lvmcache_info *info, struct lvmcache_vgsummary *vgsummary)
{
const char *vgname = vgsummary->vgname;
const char *vgid = (char *)&vgsummary->vgid;
if (!vgname && !info->vginfo) {
log_error(INTERNAL_ERROR "NULL vgname handed to cache");
/* FIXME Remove this */
@ -1412,10 +1542,6 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
vgid = vgname;
}
/* When using lvmetad, the PV could not have become orphaned. */
if (lvmetad_active() && is_orphan_vg(vgname) && info->vginfo)
return 1;
/* If PV without mdas is already in a real VG, don't make it orphan */
if (is_orphan_vg(vgname) && info->vginfo &&
mdas_empty_or_ignored(&info->mdas) &&
@ -1432,10 +1558,11 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
if (!is_orphan_vg(vgname))
info->status &= ~CACHE_INVALID;
if (!_lvmcache_update_vgname(info, vgname, vgid, vgstatus,
creation_host, info->fmt) ||
if (!_lvmcache_update_vgname(info, vgname, vgid, vgsummary->vgstatus,
vgsummary->creation_host, info->fmt) ||
!_lvmcache_update_vgid(info, info->vginfo, vgid) ||
!_lvmcache_update_vgstatus(info, vgstatus, creation_host))
!_lvmcache_update_vgstatus(info, vgsummary->vgstatus, vgsummary->creation_host, vgsummary->lock_type) ||
!_lvmcache_update_vg_mda_info(info, vgsummary->mda_checksum, vgsummary->mda_size))
return_0;
return 1;
@ -1446,6 +1573,12 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
struct pv_list *pvl;
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
struct lvmcache_vgsummary vgsummary = {
.vgname = vg->name,
.vgstatus = vg->status,
.vgid = vg->id,
.lock_type = vg->lock_type
};
pvid_s[sizeof(pvid_s) - 1] = '\0';
@ -1453,9 +1586,7 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
strncpy(pvid_s, (char *) &pvl->pv->id, sizeof(pvid_s) - 1);
/* FIXME Could pvl->pv->dev->pvid ever be different? */
if ((info = lvmcache_info_from_pvid(pvid_s, 0)) &&
!lvmcache_update_vgname_and_id(info, vg->name,
(char *) &vg->id,
vg->status, NULL))
!lvmcache_update_vgname_and_id(info, &vgsummary))
return_0;
}
@ -1466,6 +1597,85 @@ int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted)
return 1;
}
/*
* Replace pv->dev with dev so that dev will appear for reporting.
*/
void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
struct device *dev)
{
struct lvmcache_info *info;
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
strncpy(pvid_s, (char *) &pv->id, sizeof(pvid_s) - 1);
pvid_s[sizeof(pvid_s) - 1] = '\0';
if (!(info = lvmcache_info_from_pvid(pvid_s, 0)))
return;
info->dev = dev;
info->label->dev = dev;
pv->dev = dev;
}
/*
* We can see multiple different devices with the
* same pvid, i.e. duplicates.
*
* There may be different reasons for seeing two
* devices with the same pvid:
* - multipath showing two paths to the same thing
* - one device copied to another, e.g. with dd,
* also referred to as cloned devices.
* - a "subsystem" taking a device and creating
* another device of its own that represents the
* underlying device it is using, e.g. using dm
* to create an identity mapping of a PV.
*
* Given duplicate devices, we have to choose one
* of them to be the "preferred" dev, i.e. the one
* that will be referenced in lvmcache, by pv->dev.
* We can keep the existing dev, that's currently
* used in lvmcache, or we can replace the existing
* dev with the new duplicate.
*
* Regardless of which device is preferred, we need
* to print messages explaining which devices were
* found so that a user can sort out for themselves
* what has happened if the preferred device is not
* the one they are interested in.
*
* If a user wants to use the non-preferred device,
* they will need to filter out the device that
* lvm is preferring.
*
* The dev_subsystem calls check if the major number
* of the dev is part of a subsystem like DM/MD/DRBD.
* A dev that's part of a subsystem is preferred over a
* duplicate of that dev that is not part of a
* subsystem.
*
* The has_holders calls check if the device is being
* used by another, and prefers one that's being used.
*
* FIXME: why do we prefer a device without holders
* over a device with holders? We should understand
* the reason for that choice.
*
* FIXME: there may be other reasons to prefer one
* device over another:
*
* . are there other use/open counts we could check
* beyond the holders?
*
* . check if either is bad/usable and prefer
* the good one?
*
* . prefer the one with smaller minor number?
* Might avoid disturbing things due to a new
* transient duplicate?
*/
struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct device *dev,
const char *vgname, const char *vgid,
@ -1476,6 +1686,14 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
struct label *label;
struct lvmcache_info *existing, *info;
char pvid_s[ID_LEN + 1] __attribute__((aligned(8)));
struct lvmcache_vgsummary vgsummary = {
.vgname = vgname,
.vgstatus = vgstatus,
};
/* N.B. vgid is not NUL-terminated when called from _text_pv_write */
if (vgid)
strncpy((char *)&vgsummary.vgid, vgid, sizeof(vgsummary.vgid));
if (!_vgname_hash && !lvmcache_init()) {
log_error("Internal cache initialisation failed");
@ -1505,49 +1723,166 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
lvmcache_del_bas(info);
} else {
if (existing->dev != dev) {
/* Is the existing entry a duplicate pvid e.g. md ? */
if (dev_subsystem_part_major(dt, existing->dev) &&
!dev_subsystem_part_major(dt, dev)) {
log_very_verbose("Ignoring duplicate PV %s on "
"%s - using %s %s",
pvid, dev_name(dev),
dev_subsystem_name(dt, existing->dev),
dev_name(existing->dev));
int old_in_subsystem = 0;
int new_in_subsystem = 0;
int old_is_dm = 0;
int new_is_dm = 0;
int old_has_holders = 0;
int new_has_holders = 0;
/*
* Here are different devices with the same pvid:
* duplicates. See comment above.
*/
/*
* This flag tells the process_each_pv code to search
* the devices list for duplicates, so that devices
* can be processed together with their duplicates
* (while processing the VG, rather than reporting
* pv->dev under the VG, and its duplicate outside
* the VG context.)
*/
_found_duplicate_pvs = 1;
/*
* The new dev may not have pvid set.
* The process_each_pv code needs to have the pvid
* set in each device to detect that the devices
* are duplicates.
*/
strncpy(dev->pvid, pvid_s, sizeof(dev->pvid));
/*
* Now decide if we are going to ignore the new
* device, or replace the existing/old device in
* lvmcache with the new one.
*/
old_in_subsystem = dev_subsystem_part_major(dt, existing->dev);
new_in_subsystem = dev_subsystem_part_major(dt, dev);
old_is_dm = dm_is_dm_major(MAJOR(existing->dev->dev));
new_is_dm = dm_is_dm_major(MAJOR(dev->dev));
old_has_holders = dm_device_has_holders(MAJOR(existing->dev->dev), MINOR(existing->dev->dev));
new_has_holders = dm_device_has_holders(MAJOR(dev->dev), MINOR(dev->dev));
if (old_has_holders && new_has_holders) {
/*
* This is not a selection of old or new, but
* just a warning to be aware of.
*/
log_warn("WARNING: duplicate PV %s is being used from both devices %s and %s",
pvid_s,
dev_name(existing->dev),
dev_name(dev));
}
if (existing->vginfo->preferred_duplicates) {
/*
* The preferred duplicate devs have already
* been chosen during a previous populating of
* lvmcache, so just use the existing preferences.
*/
log_verbose("Found duplicate PV %s: using existing dev %s",
pvid_s,
dev_name(existing->dev));
return NULL;
} else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
!dm_is_dm_major(MAJOR(dev->dev))) {
log_very_verbose("Ignoring duplicate PV %s on "
"%s - using dm %s",
pvid, dev_name(dev),
dev_name(existing->dev));
}
if (old_in_subsystem && !new_in_subsystem) {
/* Use old, ignore new. */
log_warn("Found duplicate PV %s: using %s not %s",
pvid_s,
dev_name(existing->dev),
dev_name(dev));
log_warn("Using duplicate PV %s from subsystem %s, ignoring %s",
dev_name(existing->dev),
dev_subsystem_name(dt, existing->dev),
dev_name(dev));
return NULL;
} else if (!dev_subsystem_part_major(dt, existing->dev) &&
dev_subsystem_part_major(dt, dev))
log_very_verbose("Duplicate PV %s on %s - "
"using %s %s", pvid,
dev_name(existing->dev),
dev_subsystem_name(dt, existing->dev),
dev_name(dev));
else if (!dm_is_dm_major(MAJOR(existing->dev->dev)) &&
dm_is_dm_major(MAJOR(dev->dev)))
log_very_verbose("Duplicate PV %s on %s - "
"using dm %s", pvid,
dev_name(existing->dev),
dev_name(dev));
/* FIXME If both dm, check dependencies */
//else if (dm_is_dm_major(MAJOR(existing->dev->dev)) &&
//dm_is_dm_major(MAJOR(dev->dev)))
//
else if (!strcmp(pvid_s, existing->dev->pvid))
log_error("Found duplicate PV %s: using %s not "
"%s", pvid, dev_name(dev),
dev_name(existing->dev));
} else if (!old_in_subsystem && new_in_subsystem) {
/* Use new, replace old. */
log_warn("Found duplicate PV %s: using %s not %s",
pvid_s,
dev_name(dev),
dev_name(existing->dev));
log_warn("Using duplicate PV %s from subsystem %s, replacing %s",
dev_name(dev),
dev_subsystem_name(dt, dev),
dev_name(existing->dev));
} else if (old_has_holders && !new_has_holders) {
/* Use new, replace old. */
/* FIXME: why choose the one without olders? */
log_warn("Found duplicate PV %s: using %s not %s",
pvid_s,
dev_name(dev),
dev_name(existing->dev));
log_warn("Using duplicate PV %s without holders, replacing %s",
dev_name(dev),
dev_name(existing->dev));
} else if (!old_has_holders && new_has_holders) {
/* Use old, ignore new. */
log_warn("Found duplicate PV %s: using %s not %s",
pvid_s,
dev_name(existing->dev),
dev_name(dev));
log_warn("Using duplicate PV %s without holders, ignoring %s",
dev_name(existing->dev),
dev_name(dev));
return NULL;
} else if (old_is_dm && new_is_dm) {
/* Use new, replace old. */
/* FIXME: why choose the new instead of the old? */
log_warn("Found duplicate PV %s: using %s not %s",
pvid_s,
dev_name(dev),
dev_name(existing->dev));
log_warn("Using duplicate PV %s which is last seen, replacing %s",
dev_name(dev),
dev_name(existing->dev));
} else if (!strcmp(pvid_s, existing->dev->pvid)) {
/* No criteria to use for preferring old or new. */
/* FIXME: why choose the new instead of the old? */
/* FIXME: a transient duplicate would be a reason
* to select the old instead of the new. */
log_warn("Found duplicate PV %s: using %s not %s",
pvid_s,
dev_name(dev),
dev_name(existing->dev));
log_warn("Using duplicate PV %s which is last seen, replacing %s",
dev_name(dev),
dev_name(existing->dev));
}
} else {
/*
* The new dev is the same as the existing dev.
*
* FIXME: Why can't we just return NULL here if the
* device already exists? Things don't seem to work
* if we do that for some reason.
*/
log_debug_cache("Found same device %s with same pvid %s",
dev_name(existing->dev), pvid_s);
}
if (strcmp(pvid_s, existing->dev->pvid))
log_debug_cache("Updating pvid cache to %s (%s) from %s (%s)",
pvid_s, dev_name(dev),
existing->dev->pvid, dev_name(existing->dev));
/* Switch over to new preferred device */
/*
* This happens when running pvcreate on an existing PV.
*/
if (strcmp(pvid_s, existing->dev->pvid)) {
log_verbose("Replacing dev %s pvid %s with dev %s pvid %s",
dev_name(existing->dev), existing->dev->pvid,
dev_name(dev), pvid_s);
}
/*
* Switch over to new preferred device.
*/
existing->dev = dev;
info = existing;
/* Has labeller changed? */
@ -1572,7 +1907,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
return NULL;
}
if (!lvmcache_update_vgname_and_id(info, vgname, vgid, vgstatus, NULL)) {
if (!lvmcache_update_vgname_and_id(info, &vgsummary)) {
if (!existing) {
dm_hash_remove(_pvid_hash, pvid_s);
strcpy(info->dev->pvid, "");
@ -1707,7 +2042,7 @@ static int _get_pv_if_in_vg(struct lvmcache_info *info,
* lvmcache_label_scan() and drop cached
* vginfo so make a local copy of string.
*/
strcpy(vgname, info->vginfo->vgname);
(void) dm_strncpy(vgname, info->vginfo->vgname, sizeof(vgname));
memcpy(vgid, info->vginfo->vgid, sizeof(vgid));
if (get_pv_from_vg_by_id(info->fmt, vgname, vgid,
@ -1981,3 +2316,65 @@ uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info)
const struct format_type *lvmcache_fmt(struct lvmcache_info *info) {
return info->fmt;
}
int lvmcache_lookup_mda(struct lvmcache_vgsummary *vgsummary)
{
struct lvmcache_vginfo *vginfo;
if (!vgsummary->mda_size)
return 0;
/* FIXME Index the checksums */
dm_list_iterate_items(vginfo, &_vginfos) {
if (vgsummary->mda_checksum == vginfo->mda_checksum &&
vgsummary->mda_size == vginfo->mda_size &&
!is_orphan_vg(vginfo->vgname)) {
vgsummary->vgname = vginfo->vgname;
vgsummary->creation_host = vginfo->creation_host;
vgsummary->vgstatus = vginfo->status;
/* vginfo->vgid has 1 extra byte then vgsummary->vgid */
memcpy(&vgsummary->vgid, vginfo->vgid, sizeof(vgsummary->vgid));
return 1;
}
}
return 0;
}
int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd)
{
struct lvmcache_vginfo *vginfo;
dm_list_iterate_items(vginfo, &_vginfos) {
if (vginfo->lock_type && !strcmp(vginfo->lock_type, "sanlock"))
return 1;
}
return 0;
}
void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
unsigned *pv_max_name_len,
unsigned *vg_max_name_len)
{
struct lvmcache_vginfo *vginfo;
struct lvmcache_info *info;
unsigned len;
*vg_max_name_len = 0;
*pv_max_name_len = 0;
dm_list_iterate_items(vginfo, &_vginfos) {
len = strlen(vginfo->vgname);
if (*vg_max_name_len < len)
*vg_max_name_len = len;
dm_list_iterate_items(info, &vginfo->infos) {
len = strlen(dev_name(info->dev));
if (*pv_max_name_len < len)
*pv_max_name_len = len;
}
}
}

41
lib/cache/lvmcache.h vendored
View File

@ -39,6 +39,27 @@ struct disk_locn;
struct lvmcache_vginfo;
/*
* vgsummary represents a summary of the VG that is read
* without a lock. The info does not come through vg_read(),
* but through reading mdas. It provides information about
* the VG that is needed to lock the VG and then read it fully
* with vg_read(), after which the VG summary should be checked
* against the full VG metadata to verify it was correct (since
* it was read without a lock.)
*
* Once read, vgsummary information is saved in lvmcache_vginfo.
*/
struct lvmcache_vgsummary {
const char *vgname;
struct id vgid;
uint64_t vgstatus;
char *creation_host;
const char *lock_type;
uint32_t mda_checksum;
size_t mda_size;
};
int lvmcache_init(void);
void lvmcache_allow_reads_with_lvmetad(void);
@ -58,8 +79,7 @@ void lvmcache_del(struct lvmcache_info *info);
/* Update things */
int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
const char *vgname, const char *vgid,
uint32_t vgstatus, const char *hostname);
struct lvmcache_vgsummary *vgsummary);
int lvmcache_update_vg(struct volume_group *vg, unsigned precommitted);
void lvmcache_lock_vgname(const char *vgname, int read_only);
@ -68,6 +88,7 @@ int lvmcache_verify_lock_order(const char *vgname);
/* Queries */
const struct format_type *lvmcache_fmt_from_vgname(struct cmd_context *cmd, const char *vgname, const char *vgid, unsigned revalidate_labels);
int lvmcache_lookup_mda(struct lvmcache_vgsummary *vgsummary);
/* Decrement and test if there are still vg holders in vginfo. */
int lvmcache_vginfo_holders_dec_and_test_for_zero(struct lvmcache_vginfo *vginfo);
@ -98,6 +119,9 @@ struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal);
int lvmcache_get_vgnameids(struct cmd_context *cmd, int include_internal,
struct dm_list *vgnameids);
/* Returns list of struct dm_str_list containing pool-allocated copy of pvids */
struct dm_list *lvmcache_get_pvids(struct cmd_context *cmd, const char *vgname,
const char *vgid);
@ -157,4 +181,17 @@ unsigned lvmcache_mda_count(struct lvmcache_info *info);
int lvmcache_vgid_is_cached(const char *vgid);
uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info);
void lvmcache_replace_dev(struct cmd_context *cmd, struct physical_volume *pv,
struct device *dev);
int lvmcache_found_duplicate_pvs(void);
void lvmcache_set_preferred_duplicates(const char *vgid);
int lvmcache_contains_lock_type_sanlock(struct cmd_context *cmd);
void lvmcache_get_max_name_lengths(struct cmd_context *cmd,
unsigned *pv_max_name_len, unsigned *vg_max_name_len);
#endif

832
lib/cache/lvmetad.c vendored

File diff suppressed because it is too large Load Diff

34
lib/cache/lvmetad.h vendored
View File

@ -29,15 +29,14 @@ typedef int (*activation_handler) (struct cmd_context *cmd,
#ifdef LVMETAD_SUPPORT
/*
* Initialise the communication with lvmetad. Normally called by
* lvmcache_init. Sets up a global handle for our process.
* Sets up a global handle for our process.
*/
void lvmetad_init(struct cmd_context *);
/*
* Override the use of lvmetad for retrieving scan results and metadata.
*/
void lvmetad_set_active(int);
void lvmetad_set_active(struct cmd_context *, int);
/*
* Configure the socket that lvmetad_init will use to connect to the daemon.
@ -59,7 +58,9 @@ int lvmetad_socket_present(void);
/*
* Check whether lvmetad is active (where active means both that it is running
* and that we have a working connection with it).
* and that we have a working connection with it). It opens new connection
* with lvmetad in the process when lvmetad is supposed to be used and the
* connection is not open yet.
*/
int lvmetad_active(void);
@ -70,8 +71,9 @@ int lvmetad_active(void);
void lvmetad_connect_or_warn(void);
/*
* Drop connection to lvmetad. A subsequent lvmetad_init() will re-establish
* the connection (possibly at a different socket path).
* Drop connection to lvmetad. A subsequent lvmetad_connect_or_warn or
* lvmetad_active will re-establish the connection (possibly at a
* different socket path).
*/
void lvmetad_disconnect(void);
@ -142,6 +144,12 @@ int lvmetad_pv_lookup_by_dev(struct cmd_context *cmd, struct device *dev, int *f
*/
int lvmetad_vg_list_to_lvmcache(struct cmd_context *cmd);
/*
* Request a list of vgid/vgname pairs for all VGs known to lvmetad.
* Does not do vg_lookup's on each VG, and does not populate lvmcache.
*/
int lvmetad_get_vgnameids(struct cmd_context *cmd, struct dm_list *vgnameids);
/*
* Find a VG by its ID or its name in the lvmetad cache. Gives NULL if the VG is
* not found.
@ -153,15 +161,19 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd,
* Scan a single device and update lvmetad with the result(s).
*/
int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
activation_handler handler);
activation_handler handler, int ignore_obsolete);
int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler);
int lvmetad_pvscan_foreign_vgs(struct cmd_context *cmd, activation_handler handler);
int lvmetad_vg_clear_outdated_pvs(struct volume_group *vg);
void lvmetad_validate_global_cache(struct cmd_context *cmd, int force);
# else /* LVMETAD_SUPPORT */
# define lvmetad_init(cmd) do { } while (0)
# define lvmetad_disconnect() do { } while (0)
# define lvmetad_set_active(a) do { } while (0)
# define lvmetad_set_active(cmd, a) do { } while (0)
# define lvmetad_set_socket(a) do { } while (0)
# define lvmetad_used() (0)
# define lvmetad_socket_present() (0)
@ -178,9 +190,13 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler)
# define lvmetad_pv_lookup(cmd, pvid, found) (0)
# define lvmetad_pv_lookup_by_dev(cmd, dev, found) (0)
# define lvmetad_vg_list_to_lvmcache(cmd) (1)
# define lvmetad_get_vgnameids(cmd, vgnameids) do { } while (0)
# define lvmetad_vg_lookup(cmd, vgname, vgid) (NULL)
# define lvmetad_pvscan_single(cmd, dev, handler) (0)
# define lvmetad_pvscan_single(cmd, dev, handler, ignore_obsolete) (0)
# define lvmetad_pvscan_all_devs(cmd, handler) (0)
# define lvmetad_pvscan_foreign_vgs(cmd, handler) (0)
# define lvmetad_vg_clear_outdated_pvs(vg) (1)
# define lvmetad_validate_global_cache(cmd, force) do { } while (0)
# endif /* LVMETAD_SUPPORT */

View File

@ -19,32 +19,29 @@
#include "text_export.h"
#include "config.h"
#include "str_list.h"
#include "targets.h"
#include "lvm-string.h"
#include "activate.h"
#include "metadata.h"
#include "lv_alloc.h"
#include "defaults.h"
static const char _cache_module[] = "cache";
/* TODO: using static field here, maybe should be a part of segment_type */
static unsigned _feature_mask;
#define SEG_LOG_ERROR(t, p...) \
log_error(t " segment %s of logical volume %s.", ## p, \
dm_config_parent_name(sn), seg->lv->name), 0;
static const char *_name(const struct lv_segment *seg)
{
return seg->segtype->name;
}
static int _cache_pool_text_import(struct lv_segment *seg,
const struct dm_config_node *sn,
struct dm_hash_table *pv_hash __attribute__((unused)))
{
uint32_t chunk_size;
struct logical_volume *data_lv, *meta_lv;
const char *str = NULL;
char *argv_str;
struct dm_pool *mem = seg->lv->vg->vgmem; //FIXME: what mempool should be used?
struct dm_pool *mem = seg->lv->vg->vgmem;
if (!dm_config_has_node(sn, "data"))
return SEG_LOG_ERROR("Cache data not specified in");
@ -52,7 +49,7 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Cache data must be a string in");
if (!(data_lv = find_lv(seg->lv->vg, str)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache data in", str);
"cache data in", str);
if (!dm_config_has_node(sn, "metadata"))
return SEG_LOG_ERROR("Cache metadata not specified in");
@ -60,105 +57,63 @@ static int _cache_pool_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Cache metadata must be a string in");
if (!(meta_lv = find_lv(seg->lv->vg, str)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache metadata in", str);
"cache metadata in", str);
if (!dm_config_get_uint32(sn, "chunk_size", &chunk_size))
if (!dm_config_get_uint32(sn, "chunk_size", &seg->chunk_size))
return SEG_LOG_ERROR("Couldn't read cache chunk_size in");
/*
* Read in features:
* cache_mode = {writethrough|writeback}
* cache_mode = {passthrough|writethrough|writeback}
*
* 'cache_mode' does not have to be present.
*/
if (dm_config_has_node(sn, "cache_mode")) {
if (!(str = dm_config_find_str(sn, "cache_mode", NULL)))
return SEG_LOG_ERROR("cache_mode must be a string in");
if (!strcmp(str, "writethrough"))
seg->feature_flags |= DM_CACHE_FEATURE_WRITETHROUGH;
else if (!strcmp(str, "writeback"))
seg->feature_flags |= DM_CACHE_FEATURE_WRITEBACK;
else
if (!cache_set_mode(seg, str))
return SEG_LOG_ERROR("Unknown cache_mode in");
}
/*
* Read in core arguments (these are key/value pairs)
* core_argc = <# args>
* core_argv = "[<key> <value>]..."
*
* 'core_argc' does not have to be present. If it is not present,
* any other core_* fields are ignored. If it is present, then
* 'core_argv' must be present - even if they are
* 'core_argc = 0' and 'core_argv = ""'.
*/
if (dm_config_has_node(sn, "core_argc")) {
if (!dm_config_has_node(sn, "core_argv"))
return SEG_LOG_ERROR("not all core arguments defined in");
if (!dm_config_get_uint32(sn, "core_argc", &seg->core_argc))
return SEG_LOG_ERROR("Unable to read core_argc in");
str = dm_config_find_str(sn, "core_argv", NULL);
if ((str && !seg->core_argc) || (!str && seg->core_argc))
return SEG_LOG_ERROR("core_argc and core_argv do"
" not match in");
if (!(seg->core_argv =
dm_pool_alloc(mem, sizeof(char *) * seg->core_argc)))
return_0;
if (str &&
(!(argv_str = dm_pool_strdup(mem, str)) ||
((int)seg->core_argc != dm_split_words(argv_str, seg->core_argc,
0, (char **) seg->core_argv))))
return SEG_LOG_ERROR("core_argc and core_argv do"
" not match in");
if (dm_config_has_node(sn, "policy")) {
if (!(str = dm_config_find_str(sn, "policy", NULL)))
return SEG_LOG_ERROR("policy must be a string in");
if (!(seg->policy_name = dm_pool_strdup(mem, str)))
return SEG_LOG_ERROR("Failed to duplicate policy in");
}
/*
* Read in policy:
* policy_name = "<policy_name>"
* policy_argc = <# args>
* policy_argv = "[<key> <value>]..."
* Read in policy args:
* policy_settings {
* migration_threshold=2048
* sequention_threashold=100
* random_threashold=200
* read_promote_adjustment=10
* write_promote_adjustment=20
* discard_promote_adjustment=40
*
* 'policy_name' does not have to be present. If it is not present,
* any other policy_* fields are ignored. If it is present, then
* the other policy_* fields must be present - even if they are
* 'policy_argc = 0' and 'policy_argv = ""'.
* <key> = <value>
* <key> = <value>
* ...
* }
*
* If the policy is not present, default policy is used.
*/
if (dm_config_has_node(sn, "policy_name")) {
if (!dm_config_has_node(sn, "policy_argc") ||
!dm_config_has_node(sn, "policy_argv"))
return SEG_LOG_ERROR("not all policy arguments defined in");
if (!(str = dm_config_find_str(sn, "policy_name", NULL)))
return SEG_LOG_ERROR("policy_name must be a string in");
seg->policy_name = dm_pool_strdup(mem, str);
if ((sn = dm_config_find_node(sn, "policy_settings"))) {
if (!seg->policy_name)
return SEG_LOG_ERROR("policy_settings must have a policy_name in");
if (!dm_config_get_uint32(sn, "policy_argc", &seg->policy_argc))
return SEG_LOG_ERROR("Unable to read policy_argc in");
if (sn->v)
return SEG_LOG_ERROR("policy_settings must be a section in");
str = dm_config_find_str(sn, "policy_argv", NULL);
if ((str && !seg->policy_argc) || (!str && seg->policy_argc))
return SEG_LOG_ERROR("policy_argc and policy_argv do"
" not match in");
if (!(seg->policy_argv =
dm_pool_alloc(mem, sizeof(char *) * seg->policy_argc)))
if (!(seg->policy_settings = dm_config_clone_node_with_mem(mem, sn, 0)))
return_0;
if (str &&
(!(argv_str = dm_pool_strdup(mem, str)) ||
((int)seg->policy_argc != dm_split_words(argv_str,
seg->policy_argc,
0, (char **) seg->policy_argv))))
return SEG_LOG_ERROR("policy_argc and policy_argv do"
" not match in");
}
if (!attach_pool_data_lv(seg, data_lv))
return_0;
if (!attach_pool_metadata_lv(seg, meta_lv))
return_0;
seg->chunk_size = chunk_size;
return 1;
}
@ -174,43 +129,35 @@ static int _cache_pool_text_import_area_count(const struct dm_config_node *sn,
static int _cache_pool_text_export(const struct lv_segment *seg,
struct formatter *f)
{
unsigned i;
char buf[256]; //FIXME: IS THERE AN 'outf' THAT DOESN'T DO NEWLINE?!?
uint32_t feature_flags = seg->feature_flags;
const char *cache_mode;
outf(f, "data = \"%s\"", seg_lv(seg, 0)->name);
outf(f, "metadata = \"%s\"", seg->metadata_lv->name);
outf(f, "chunk_size = %" PRIu32, seg->chunk_size);
if (feature_flags) {
if (feature_flags & DM_CACHE_FEATURE_WRITETHROUGH) {
outf(f, "cache_mode = \"writethrough\"");
feature_flags &= ~DM_CACHE_FEATURE_WRITETHROUGH;
} else if (feature_flags & DM_CACHE_FEATURE_WRITEBACK) {
outf(f, "cache_mode = \"writeback\"");
feature_flags &= ~DM_CACHE_FEATURE_WRITEBACK;
} else {
log_error(INTERNAL_ERROR "Unknown feature flags "
"in cache_pool segment for %s", seg->lv->name);
return 0;
}
}
if (seg->core_argc) {
outf(f, "core_argc = %u", seg->core_argc);
outf(f, "core_argv = \"");
for (i = 0; i < seg->core_argc; i++)
outf(f, "%s%s", i ? " " : "", seg->core_argv[i]);
outf(f, "\"");
/*
* Cache pool used by a cache LV holds data. Not ideal,
* but not worth to break backward compatibility, by shifting
* content to cache segment
*/
if (cache_mode_is_set(seg)) {
if (!(cache_mode = get_cache_mode_name(seg)))
return_0;
outf(f, "cache_mode = \"%s\"", cache_mode);
}
if (seg->policy_name) {
outf(f, "policy_name = \"%s\"", seg->policy_name);
outf(f, "policy_argc = %u", seg->policy_argc);
buf[0] = '\0';
for (i = 0; i < seg->policy_argc; i++)
sprintf(buf, "%s%s", i ? " " : "", seg->policy_argv[i]);
outf(f, "policy_argv = \"%s\"", buf);
outf(f, "policy = \"%s\"", seg->policy_name);
if (seg->policy_settings) {
if (strcmp(seg->policy_settings->key, "policy_settings")) {
log_error(INTERNAL_ERROR "Incorrect policy_settings tree, %s.",
seg->policy_settings->key);
return 0;
}
if (seg->policy_settings->child)
out_config_node(f, seg->policy_settings);
}
}
return 1;
@ -223,12 +170,29 @@ static void _destroy(struct segment_type *segtype)
#ifdef DEVMAPPER_SUPPORT
static int _target_present(struct cmd_context *cmd,
const struct lv_segment *seg __attribute__((unused)),
unsigned *attributes __attribute__((unused)))
const struct lv_segment *seg __attribute__((unused)),
unsigned *attributes __attribute__((unused)))
{
uint32_t maj, min, patchlevel;
/* List of features with their kernel target version */
static const struct feature {
uint32_t maj;
uint32_t min;
unsigned cache_feature;
const char feature[12];
const char module[12]; /* check dm-%s */
} _features[] = {
{ 1, 3, CACHE_FEATURE_POLICY_MQ, "policy_mq", "cache-mq" },
{ 1, 8, CACHE_FEATURE_POLICY_SMQ, "policy_smq", "cache-smq" },
};
static const char _lvmconf[] = "global/cache_disabled_features";
static unsigned _attrs = 0;
static int _cache_checked = 0;
static int _cache_present = 0;
uint32_t maj, min, patchlevel;
unsigned i;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
const char *str;
if (!_cache_checked) {
_cache_present = target_present(cmd, "cache", 1);
@ -242,11 +206,53 @@ static int _target_present(struct cmd_context *cmd,
if ((maj < 1) ||
((maj == 1) && (min < 3))) {
log_error("The cache kernel module is version %u.%u.%u."
" Version 1.3.0+ is required.",
_cache_present = 0;
log_error("The cache kernel module is version %u.%u.%u. "
"Version 1.3.0+ is required.",
maj, min, patchlevel);
return 0;
}
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i) {
if (((maj > _features[i].maj) ||
(maj == _features[i].maj && min >= _features[i].min)) &&
(!_features[i].module[0] || module_present(cmd, _features[i].module)))
_attrs |= _features[i].cache_feature;
else
log_very_verbose("Target %s does not support %s.",
_cache_module, _features[i].feature);
}
}
if (attributes) {
if (!_feature_mask) {
/* Support runtime lvm.conf changes, N.B. avoid 32 feature */
if ((cn = find_config_tree_array(cmd, global_cache_disabled_features_CFG, NULL))) {
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
log_error("Ignoring invalid string in config file %s.",
_lvmconf);
continue;
}
str = cv->v.str;
if (!*str)
continue;
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
if (strcasecmp(str, _features[i].feature) == 0)
_feature_mask |= _features[i].cache_feature;
}
}
_feature_mask = ~_feature_mask;
for (i = 0; i < DM_ARRAY_SIZE(_features); ++i)
if ((_attrs & _features[i].cache_feature) &&
!(_feature_mask & _features[i].cache_feature))
log_very_verbose("Target %s %s support disabled by %s",
_cache_module, _features[i].feature, _lvmconf);
}
*attributes = _attrs & _feature_mask;
}
return _cache_present;
@ -266,7 +272,6 @@ static int _modules_needed(struct dm_pool *mem,
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_pool_ops = {
.name = _name,
.text_import = _cache_pool_text_import,
.text_import_area_count = _cache_pool_text_import_area_count,
.text_export = _cache_pool_text_export,
@ -284,7 +289,7 @@ static int _cache_text_import(struct lv_segment *seg,
struct dm_hash_table *pv_hash __attribute__((unused)))
{
struct logical_volume *pool_lv, *origin_lv;
const char *name = NULL;
const char *name;
if (!dm_config_has_node(sn, "cache_pool"))
return SEG_LOG_ERROR("cache_pool not specified in");
@ -292,7 +297,7 @@ static int _cache_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("cache_pool must be a string in");
if (!(pool_lv = find_lv(seg->lv->vg, name)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache_pool in", name);
"cache_pool in", name);
if (!dm_config_has_node(sn, "origin"))
return SEG_LOG_ERROR("Cache origin not specified in");
@ -300,10 +305,17 @@ static int _cache_text_import(struct lv_segment *seg,
return SEG_LOG_ERROR("Cache origin must be a string in");
if (!(origin_lv = find_lv(seg->lv->vg, name)))
return SEG_LOG_ERROR("Unknown logical volume %s specified for "
"cache origin in", name);
"cache origin in", name);
if (!set_lv_segment_area_lv(seg, 0, origin_lv, 0, 0))
return_0;
seg->cleaner_policy = 0;
if (dm_config_has_node(sn, "cleaner") &&
!dm_config_get_uint32(sn, "cleaner", &seg->cleaner_policy))
return SEG_LOG_ERROR("Could not read cache cleaner in");
seg->lv->status |= strstr(seg->lv->name, "_corig") ? LV_PENDING_DELETE : 0;
if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
return_0;
@ -326,6 +338,9 @@ static int _cache_text_export(const struct lv_segment *seg, struct formatter *f)
outf(f, "cache_pool = \"%s\"", seg->pool_lv->name);
outf(f, "origin = \"%s\"", seg_lv(seg, 0)->name);
if (seg->cleaner_policy)
outf(f, "cleaner = 1");
return 1;
}
@ -339,9 +354,16 @@ static int _cache_add_target_line(struct dev_manager *dm,
struct dm_tree_node *node, uint64_t len,
uint32_t *pvmove_mirror_count __attribute__((unused)))
{
struct lv_segment *cache_pool_seg = first_seg(seg->pool_lv);
struct lv_segment *cache_pool_seg;
char *metadata_uuid, *data_uuid, *origin_uuid;
if (!seg->pool_lv || !seg_is_cache(seg)) {
log_error(INTERNAL_ERROR "Passed segment is not cache.");
return 0;
}
cache_pool_seg = first_seg(seg->pool_lv);
if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv, NULL)))
return_0;
@ -352,24 +374,22 @@ static int _cache_add_target_line(struct dev_manager *dm,
return_0;
if (!dm_tree_node_add_cache_target(node, len,
cache_pool_seg->feature_flags,
metadata_uuid,
data_uuid,
origin_uuid,
cache_pool_seg->chunk_size,
cache_pool_seg->feature_flags,
cache_pool_seg->core_argc,
cache_pool_seg->core_argv,
cache_pool_seg->policy_name,
cache_pool_seg->policy_argc,
cache_pool_seg->policy_argv))
seg->cleaner_policy ? "cleaner" :
/* undefined policy name -> likely an old "mq" */
cache_pool_seg->policy_name ? : "mq",
seg->cleaner_policy ? NULL : cache_pool_seg->policy_settings,
cache_pool_seg->chunk_size))
return_0;
return add_areas_line(dm, seg, node, 0u, seg->area_count);
return 1;
}
#endif /* DEVMAPPER_SUPPORT */
static struct segtype_handler _cache_ops = {
.name = _name,
.text_import = _cache_text_import,
.text_import_area_count = _cache_text_import_area_count,
.text_export = _cache_text_export,
@ -399,12 +419,10 @@ int init_cache_segtypes(struct cmd_context *cmd,
log_error("Failed to allocate memory for cache_pool segtype");
return 0;
}
segtype->cmd = cmd;
segtype->name = "cache-pool";
segtype->flags = SEG_CACHE_POOL;
segtype->name = SEG_TYPE_NAME_CACHE_POOL;
segtype->flags = SEG_CACHE_POOL | SEG_CANNOT_BE_ZEROED | SEG_ONLY_EXCLUSIVE;
segtype->ops = &_cache_pool_ops;
segtype->private = NULL;
if (!lvm_register_segtype(seglib, segtype))
return_0;
@ -415,16 +433,17 @@ int init_cache_segtypes(struct cmd_context *cmd,
log_error("Failed to allocate memory for cache segtype");
return 0;
}
segtype->cmd = cmd;
segtype->name = "cache";
segtype->flags = SEG_CACHE;
segtype->name = SEG_TYPE_NAME_CACHE;
segtype->flags = SEG_CACHE | SEG_ONLY_EXCLUSIVE;
segtype->ops = &_cache_ops;
segtype->private = NULL;
if (!lvm_register_segtype(seglib, segtype))
return_0;
log_very_verbose("Initialised segtype: %s", segtype->name);
/* Reset mask for recalc */
_feature_mask = 0;
return 1;
}

View File

@ -30,6 +30,7 @@
#include "lvmcache.h"
#include "lvmetad.h"
#include "archiver.h"
#include "lvmpolld-client.h"
#ifdef HAVE_LIBDL
#include "sharedlib.h"
@ -55,6 +56,128 @@
static const size_t linebuffer_size = 4096;
/*
* Copy the input string, removing invalid characters.
*/
const char *system_id_from_string(struct cmd_context *cmd, const char *str)
{
char *system_id;
if (!str || !*str) {
log_warn("WARNING: Empty system ID supplied.");
return "";
}
if (!(system_id = dm_pool_zalloc(cmd->libmem, strlen(str) + 1))) {
log_warn("WARNING: Failed to allocate system ID.");
return NULL;
}
copy_systemid_chars(str, system_id);
if (!*system_id) {
log_warn("WARNING: Invalid system ID format: %s", str);
return NULL;
}
if (!strncmp(system_id, "localhost", 9)) {
log_warn("WARNING: system ID may not begin with the string \"localhost\".");
return NULL;
}
return system_id;
}
static const char *_read_system_id_from_file(struct cmd_context *cmd, const char *file)
{
char *line = NULL;
size_t line_size;
char *start, *end;
const char *system_id = NULL;
FILE *fp;
if (!file || !strlen(file) || !file[0])
return_NULL;
if (!(fp = fopen(file, "r"))) {
log_warn("WARNING: %s: fopen failed: %s", file, strerror(errno));
return NULL;
}
while (getline(&line, &line_size, fp) > 0) {
start = line;
/* Ignore leading whitespace */
while (*start && isspace(*start))
start++;
/* Ignore rest of line after # */
if (!*start || *start == '#')
continue;
if (system_id && *system_id) {
log_warn("WARNING: Ignoring extra line(s) in system ID file %s.", file);
break;
}
/* Remove any comments from end of line */
for (end = start; *end; end++)
if (*end == '#') {
*end = '\0';
break;
}
system_id = system_id_from_string(cmd, start);
}
free(line);
if (fclose(fp))
stack;
return system_id;
}
static const char *_system_id_from_source(struct cmd_context *cmd, const char *source)
{
char filebuf[PATH_MAX];
const char *file;
const char *etc_str;
const char *str;
const char *system_id = NULL;
if (!strcasecmp(source, "uname")) {
if (cmd->hostname)
system_id = system_id_from_string(cmd, cmd->hostname);
goto out;
}
/* lvm.conf and lvmlocal.conf are merged into one config tree */
if (!strcasecmp(source, "lvmlocal")) {
if ((str = find_config_tree_str(cmd, local_system_id_CFG, NULL)))
system_id = system_id_from_string(cmd, str);
goto out;
}
if (!strcasecmp(source, "machineid") || !strcasecmp(source, "machine-id")) {
etc_str = find_config_tree_str(cmd, global_etc_CFG, NULL);
if (dm_snprintf(filebuf, sizeof(filebuf), "%s/machine-id", etc_str) != -1)
system_id = _read_system_id_from_file(cmd, filebuf);
goto out;
}
if (!strcasecmp(source, "file")) {
file = find_config_tree_str(cmd, global_system_id_file_CFG, NULL);
system_id = _read_system_id_from_file(cmd, file);
goto out;
}
log_warn("WARNING: Unrecognised system_id_source \"%s\".", source);
out:
return system_id;
}
static int _get_env_vars(struct cmd_context *cmd)
{
const char *e;
@ -122,8 +245,10 @@ static int _parse_debug_classes(struct cmd_context *cmd)
const struct dm_config_value *cv;
int debug_classes = 0;
if (!(cn = find_config_tree_node(cmd, log_debug_classes_CFG, NULL)))
return DEFAULT_LOGGED_DEBUG_CLASSES;
if (!(cn = find_config_tree_array(cmd, log_debug_classes_CFG, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for log/debug_classes.");
return -1;
}
for (cv = cn->v; cv; cv = cv->next) {
if (cv->type != DM_CFG_STRING) {
@ -151,6 +276,8 @@ static int _parse_debug_classes(struct cmd_context *cmd)
debug_classes |= LOG_CLASS_CACHE;
else if (!strcasecmp(cv->v.str, "locking"))
debug_classes |= LOG_CLASS_LOCKING;
else if (!strcasecmp(cv->v.str, "lvmpolld"))
debug_classes |= LOG_CLASS_LVMPOLLD;
else
log_verbose("Unrecognised value for log/debug_classes: %s", cv->v.str);
}
@ -235,7 +362,8 @@ static void _init_logging(struct cmd_context *cmd)
/* Tell device-mapper about our logging */
#ifdef DEVMAPPER_SUPPORT
dm_log_with_errno_init(print_log);
if (!dm_log_is_non_default())
dm_log_with_errno_init(print_log);
#endif
reset_log_duplicated();
reset_lvm_errno(1);
@ -288,7 +416,59 @@ static int _check_config(struct cmd_context *cmd)
return 1;
}
int process_profilable_config(struct cmd_context *cmd) {
static const char *_set_time_format(struct cmd_context *cmd)
{
/* Compared to strftime, we do not allow "newline" character - the %n in format. */
static const char *allowed_format_chars = "aAbBcCdDeFGghHIjklmMpPrRsStTuUVwWxXyYzZ%";
static const char *allowed_alternative_format_chars_e = "cCxXyY";
static const char *allowed_alternative_format_chars_o = "deHImMSuUVwWy";
static const char *chars_to_check;
const char *tf = find_config_tree_str(cmd, report_time_format_CFG, NULL);
const char *p_fmt;
size_t i;
char c;
if (!*tf) {
log_error("Configured time format is empty string.");
goto bad;
} else {
p_fmt = tf;
while ((c = *p_fmt)) {
if (c == '%') {
c = *++p_fmt;
if (c == 'E') {
c = *++p_fmt;
chars_to_check = allowed_alternative_format_chars_e;
} else if (c == 'O') {
c = *++p_fmt;
chars_to_check = allowed_alternative_format_chars_o;
} else
chars_to_check = allowed_format_chars;
for (i = 0; chars_to_check[i]; i++) {
if (c == chars_to_check[i])
break;
}
if (!chars_to_check[i])
goto_bad;
}
else if (isprint(c))
p_fmt++;
else {
log_error("Configured time format contains non-printable characters.");
goto bad;
}
}
}
return tf;
bad:
log_error("Invalid time format \"%s\" supplied.", tf);
return NULL;
}
int process_profilable_config(struct cmd_context *cmd)
{
if (!(cmd->default_settings.unit_factor =
dm_units_to_factor(find_config_tree_str(cmd, global_units_CFG, NULL),
&cmd->default_settings.unit_type, 1, NULL))) {
@ -297,7 +477,49 @@ int process_profilable_config(struct cmd_context *cmd) {
}
cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
cmd->report_binary_values_as_numeric = find_config_tree_bool(cmd, report_binary_values_as_numeric_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
cmd->report_list_item_separator = find_config_tree_str(cmd, report_list_item_separator_CFG, NULL);
if (!(cmd->time_format = _set_time_format(cmd)))
return 0;
return 1;
}
static int _init_system_id(struct cmd_context *cmd)
{
const char *source, *system_id;
int local_set = 0;
cmd->system_id = NULL;
cmd->unknown_system_id = 0;
system_id = find_config_tree_str_allow_empty(cmd, local_system_id_CFG, NULL);
if (system_id && *system_id)
local_set = 1;
source = find_config_tree_str(cmd, global_system_id_source_CFG, NULL);
if (!source)
source = "none";
/* Defining local system_id but not using it is probably a config mistake. */
if (local_set && strcmp(source, "lvmlocal"))
log_warn("WARNING: local/system_id is set, so should global/system_id_source be \"lvmlocal\" not \"%s\"?", source);
if (!strcmp(source, "none"))
return 1;
if ((system_id = _system_id_from_source(cmd, source)) && *system_id) {
cmd->system_id = system_id;
return 1;
}
/*
* The source failed to resolve a system_id. In this case allow
* VGs with no system_id to be accessed, but not VGs with a system_id.
*/
log_warn("WARNING: No system ID found from system_id_source %s.", source);
cmd->unknown_system_id = 1;
return 1;
}
@ -305,12 +527,12 @@ int process_profilable_config(struct cmd_context *cmd) {
static int _process_config(struct cmd_context *cmd)
{
mode_t old_umask;
const char *dev_ext_info_src;
const char *read_ahead;
struct stat st;
const struct dm_config_node *cn;
const struct dm_config_value *cv;
int64_t pv_min_kb;
const char *lvmetad_socket;
int udev_disabled = 0;
char sysfs_dir[PATH_MAX];
@ -338,6 +560,16 @@ static int _process_config(struct cmd_context *cmd)
return_0;
#endif
dev_ext_info_src = find_config_tree_str(cmd, devices_external_device_info_source_CFG, NULL);
if (!strcmp(dev_ext_info_src, "none"))
init_external_device_info_source(DEV_EXT_NONE);
else if (!strcmp(dev_ext_info_src, "udev"))
init_external_device_info_source(DEV_EXT_UDEV);
else {
log_error("Invalid external device info source specification.");
return 0;
}
/* proc dir */
if (dm_snprintf(cmd->proc_dir, sizeof(cmd->proc_dir), "%s",
find_config_tree_str(cmd, global_proc_CFG, NULL)) < 0) {
@ -421,7 +653,7 @@ static int _process_config(struct cmd_context *cmd)
}
}
if ((cn = find_config_tree_node(cmd, activation_mlock_filter_CFG, NULL)))
if ((cn = find_config_tree_array(cmd, activation_mlock_filter_CFG, NULL)))
for (cv = cn->v; cv; cv = cv->next)
if ((cv->type != DM_CFG_STRING) || !cv->v.str[0])
log_error("Ignoring invalid activation/mlock_filter entry in config file");
@ -443,29 +675,8 @@ static int _process_config(struct cmd_context *cmd)
init_detect_internal_vg_cache_corruption
(find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));
lvmetad_disconnect();
lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
if (!lvmetad_socket)
lvmetad_socket = DEFAULT_RUN_DIR "/lvmetad.socket";
/* TODO?
lvmetad_socket = find_config_tree_str(cmd, "lvmetad/socket_path",
DEFAULT_RUN_DIR "/lvmetad.socket");
*/
lvmetad_set_socket(lvmetad_socket);
cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL);
lvmetad_set_token(cn ? cn->v : NULL);
if (find_config_tree_int(cmd, global_locking_type_CFG, NULL) == 3 &&
find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL)) {
log_warn("WARNING: configuration setting use_lvmetad overridden to 0 due to locking_type 3. "
"Clustered environment not supported by lvmetad yet.");
lvmetad_set_active(0);
} else
lvmetad_set_active(find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL));
lvmetad_init(cmd);
if (!_init_system_id(cmd))
return_0;
return 1;
}
@ -524,11 +735,12 @@ static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
const char *tag;
int passes;
if (!(tn = find_config_tree_node(cmd, tags_CFG_SECTION, NULL)) || !tn->child)
/* Access tags section directly */
if (!(tn = find_config_node(cmd, cft, tags_CFG_SECTION)) || !tn->child)
return 1;
/* NB hosttags 0 when already 1 intentionally does not delete the tag */
if (!cmd->hosttags && find_config_tree_bool(cmd, tags_hosttags_CFG, NULL)) {
if (!cmd->hosttags && find_config_bool(cmd, cft, tags_hosttags_CFG)) {
/* FIXME Strip out invalid chars: only A-Za-z0-9_+.- */
if (!_set_tag(cmd, cmd->hostname))
return_0;
@ -559,7 +771,7 @@ static int _init_tags(struct cmd_context *cmd, struct dm_config_tree *cft)
return 1;
}
static int _load_config_file(struct cmd_context *cmd, const char *tag)
static int _load_config_file(struct cmd_context *cmd, const char *tag, int local)
{
static char config_file[PATH_MAX] = "";
const char *filler = "";
@ -567,6 +779,10 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
if (*tag)
filler = "_";
else if (local) {
filler = "";
tag = "local";
}
if (dm_snprintf(config_file, sizeof(config_file), "%s/lvm%s%s.conf",
cmd->system_dir, filler, tag) < 0) {
@ -594,7 +810,9 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
return 1;
}
/* Find and read first config file */
/*
* Find and read lvm.conf.
*/
static int _init_lvm_conf(struct cmd_context *cmd)
{
/* No config file if LVM_SYSTEM_DIR is empty */
@ -606,7 +824,7 @@ static int _init_lvm_conf(struct cmd_context *cmd)
return 1;
}
if (!_load_config_file(cmd, ""))
if (!_load_config_file(cmd, "", 0))
return_0;
return 1;
@ -619,7 +837,7 @@ static int _init_tag_configs(struct cmd_context *cmd)
/* Tag list may grow while inside this loop */
dm_list_iterate_items(sl, &cmd->tags) {
if (!_load_config_file(cmd, sl->str))
if (!_load_config_file(cmd, sl->str, 0))
return_0;
}
@ -642,7 +860,10 @@ static int _init_profiles(struct cmd_context *cmd)
dm_list_init(&cmd->profile_params->profiles);
}
dm_strncpy(cmd->profile_params->dir, dir, sizeof(cmd->profile_params->dir));
if (!(dm_strncpy(cmd->profile_params->dir, dir, sizeof(cmd->profile_params->dir)))) {
log_error("_init_profiles: dm_strncpy failed");
return 0;
}
return 1;
}
@ -763,15 +984,9 @@ static int _init_dev_cache(struct cmd_context *cmd)
init_obtain_device_list_from_udev(device_list_from_udev);
if (!(cn = find_config_tree_node(cmd, devices_scan_CFG, NULL))) {
if (!dev_cache_add_dir("/dev")) {
log_error("Failed to add /dev to internal "
"device cache");
return 0;
}
log_verbose("device/scan not in config file: "
"Defaulting to /dev");
return 1;
if (!(cn = find_config_tree_array(cmd, devices_scan_CFG, NULL))) {
log_error(INTERNAL_ERROR "Unable to find configuration for devices/scan.");
return_0;
}
for (cv = cn->v; cv; cv = cv->next) {
@ -809,7 +1024,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
}
}
if (!(cn = find_config_tree_node(cmd, devices_loopfiles_CFG, NULL)))
if (!(cn = find_config_tree_array(cmd, devices_loopfiles_CFG, NULL)))
return 1;
for (cv = cn->v; cv; cv = cv->next) {
@ -830,9 +1045,9 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
#define MAX_FILTERS 6
#define MAX_FILTERS 8
static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
static struct dev_filter *_init_lvmetad_filter_chain(struct cmd_context *cmd)
{
int nr_filt = 0;
const struct dm_config_node *cn;
@ -855,15 +1070,25 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
nr_filt++;
}
/* regex filter. Optional. */
if (!(cn = find_config_tree_node(cmd, devices_filter_CFG, NULL)))
log_very_verbose("devices/filter not found in config file: "
"no regex filter installed");
else if (!(filters[nr_filt] = regex_filter_create(cn->v))) {
log_error("Failed to create regex device filter");
goto bad;
} else
/* 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");
goto bad;
}
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))) {
@ -872,6 +1097,15 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
}
nr_filt++;
/* usable device filter. Required. */
if (!(filters[nr_filt] = usable_filter_create(cmd->dev_types,
lvmetad_used() ? FILTER_MODE_PRE_LVMETAD
: FILTER_MODE_NO_LVMETAD))) {
log_error("Failed to create usabled device filter");
goto bad;
}
nr_filt++;
/* mpath component filter. Optional, non-critical. */
if (find_config_tree_bool(cmd, devices_multipath_component_detection_CFG, NULL)) {
if ((filters[nr_filt] = mpath_filter_create(cmd->dev_types)))
@ -892,7 +1126,14 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
nr_filt++;
}
if (!(composite = composite_filter_create(nr_filt, filters)))
/* firmware raid filter. Optional, non-critical. */
if (find_config_tree_bool(cmd, devices_fw_raid_component_detection_CFG, NULL)) {
init_fwraid_filtering(1);
if ((filters[nr_filt] = fwraid_filter_create(cmd->dev_types)))
nr_filt++;
}
if (!(composite = composite_filter_create(nr_filt, 1, filters)))
goto_bad;
return composite;
@ -904,29 +1145,105 @@ bad:
return NULL;
}
static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
/*
* The way the filtering is initialized depends on whether lvmetad is uesd or not.
*
* If lvmetad is used, there are three filter chains:
*
* - cmd->lvmetad_filter - the lvmetad filter chain used when scanning devs for lvmetad update:
* sysfs filter -> global regex filter -> type filter ->
* usable device filter(FILTER_MODE_PRE_LVMETAD) ->
* mpath component filter -> partitioned filter ->
* md component filter -> fw raid filter
*
* - cmd->filter - the filter chain used for lvmetad responses:
* persistent filter -> regex_filter -> usable device filter(FILTER_MODE_POST_LVMETAD)
*
* - cmd->full_filter - the filter chain used for all the remaining situations:
* cmd->lvmetad_filter -> cmd->filter
*
* If lvmetad is not used, there's just one filter chain:
*
* - cmd->filter == cmd->full_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 *f3 = NULL, *f4 = NULL, *toplevel_components[2] = { 0 };
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;
if (!cmd->initialized.connections) {
log_error(INTERNAL_ERROR "connections must be initialized before filters");
return 0;
}
cmd->dump_filter = 0;
if (!(f3 = _init_filter_components(cmd)))
cmd->lvmetad_filter = _init_lvmetad_filter_chain(cmd);
if (!cmd->lvmetad_filter)
goto_bad;
init_ignore_suspended_devices(find_config_tree_bool(cmd, devices_ignore_suspended_devices_CFG, NULL));
init_ignore_lvm_mirrors(find_config_tree_bool(cmd, devices_ignore_lvm_mirrors_CFG, NULL));
/*
* If lvmetad is used, there's a separation between pre-lvmetad filter chain
* ("cmd->lvmetad_filter") applied only if scanning for lvmetad update and
* post-lvmetad filter chain ("filter") applied on each lvmetad response.
* However, if lvmetad is not used, these two chains are not separated
* and we use exactly one filter chain during device scanning ("filter"
* that includes also "cmd->lvmetad_filter" chain).
*/
/* filter component 0 */
if (lvmetad_used()) {
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 = cmd->lvmetad_filter;
cmd->lvmetad_filter = NULL;
}
if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
goto_bad;
if (!(f4 = persistent_filter_create(cmd->dev_types, f3, dev_cache))) {
if (!(filter = persistent_filter_create(cmd->dev_types, filter, dev_cache))) {
log_verbose("Failed to create persistent device filter.");
goto bad;
}
cmd->filter = filter;
if (lvmetad_used()) {
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;
/* Should we ever dump persistent filter state? */
if (find_config_tree_bool(cmd, devices_write_cache_state_CFG, NULL))
cmd->dump_filter = 1;
@ -941,31 +1258,40 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
*/
if (!find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL) &&
load_persistent_cache && !cmd->is_long_lived &&
!stat(dev_cache, &st) &&
(st.st_ctime > config_file_timestamp(cmd->cft)) &&
!persistent_filter_load(f4, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
if (!(cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
cmd->filter = f4;
} else if (!(cmd->lvmetad_filter = regex_filter_create(cn->v)))
goto_bad;
else {
toplevel_components[0] = cmd->lvmetad_filter;
toplevel_components[1] = f4;
if (!(cmd->filter = composite_filter_create(2, toplevel_components)))
goto_bad;
!stat(dev_cache, &st)) {
lvm_stat_ctim(&ts, &st);
cts = config_file_timestamp(cmd->cft);
if (timespeccmp(&ts, &cts, >) &&
!persistent_filter_load(cmd->filter, NULL))
log_verbose("Failed to load existing device cache from %s",
dev_cache);
}
cmd->initialized.filters = 1;
return 1;
bad:
if (f4)
f4->destroy(f4);
else if (f3)
f3->destroy(f3);
if (toplevel_components[0])
toplevel_components[0]->destroy(toplevel_components[0]);
if (!filter) {
/*
* composite filter not created - destroy
* each component directly
*/
if (filter_components[0])
filter_components[0]->destroy(filter_components[0]);
if (filter_components[1])
filter_components[1]->destroy(filter_components[1]);
} else {
/*
* composite filter created - destroy it - this
* will also destroy any of its components
*/
filter->destroy(filter);
}
/* if lvmetad is used, the cmd->lvmetad_filter is separate */
if (cmd->lvmetad_filter)
cmd->lvmetad_filter->destroy(cmd->lvmetad_filter);
cmd->initialized.filters = 0;
return 0;
}
@ -1009,7 +1335,7 @@ static int _init_formats(struct cmd_context *cmd)
#ifdef HAVE_LIBDL
/* Load any formats in shared libs if not static */
if (!is_static() &&
(cn = find_config_tree_node(cmd, global_format_libraries_CFG, NULL))) {
(cn = find_config_tree_array(cmd, global_format_libraries_CFG, NULL))) {
const struct dm_config_value *cv;
struct format_type *(*init_format_fn) (struct cmd_context *);
@ -1088,7 +1414,6 @@ int lvm_register_segtype(struct segtype_library *seglib,
struct segment_type *segtype2;
segtype->library = seglib->lib;
segtype->cmd = seglib->cmd;
dm_list_iterate_items(segtype2, &seglib->cmd->segtypes) {
if (strcmp(segtype2->name, segtype->name))
@ -1132,7 +1457,7 @@ static int _init_segtypes(struct cmd_context *cmd)
init_striped_segtype,
init_zero_segtype,
init_error_segtype,
init_free_segtype,
/* disabled until needed init_free_segtype, */
#ifdef SNAPSHOT_INTERNAL
init_snapshot_segtype,
#endif
@ -1176,7 +1501,7 @@ static int _init_segtypes(struct cmd_context *cmd)
#ifdef HAVE_LIBDL
/* Load any formats in shared libs unless static */
if (!is_static() &&
(cn = find_config_tree_node(cmd, global_segment_libraries_CFG, NULL))) {
(cn = find_config_tree_array(cmd, global_segment_libraries_CFG, NULL))) {
const struct dm_config_value *cv;
int (*init_multiple_segtypes_fn) (struct cmd_context *,
@ -1340,11 +1665,80 @@ static int _reopen_stream(FILE *stream, int fd, const char *mode, const char *na
return 1;
}
static int _init_lvmetad(struct cmd_context *cmd)
{
const struct dm_config_node *cn;
const char *lvmetad_socket;
lvmetad_disconnect();
lvmetad_socket = getenv("LVM_LVMETAD_SOCKET");
if (!lvmetad_socket)
lvmetad_socket = DEFAULT_RUN_DIR "/lvmetad.socket";
/* TODO?
lvmetad_socket = find_config_tree_str(cmd, "lvmetad/socket_path",
DEFAULT_RUN_DIR "/lvmetad.socket");
*/
lvmetad_set_socket(lvmetad_socket);
cn = find_config_tree_array(cmd, devices_global_filter_CFG, NULL);
lvmetad_set_token(cn ? cn->v : NULL);
if (find_config_tree_int(cmd, global_locking_type_CFG, NULL) == 3 &&
find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL)) {
log_warn("WARNING: configuration setting use_lvmetad overridden to 0 due to locking_type 3. "
"Clustered environment not supported by lvmetad yet.");
lvmetad_set_active(NULL, 0);
} else
lvmetad_set_active(NULL, find_config_tree_bool(cmd, global_use_lvmetad_CFG, NULL));
lvmetad_init(cmd);
return 1;
}
static int _init_lvmpolld(struct cmd_context *cmd)
{
const char *lvmpolld_socket;
lvmpolld_disconnect();
lvmpolld_socket = getenv("LVM_LVMPOLLD_SOCKET");
if (!lvmpolld_socket)
lvmpolld_socket = DEFAULT_RUN_DIR "/lvmpolld.socket";
lvmpolld_set_socket(lvmpolld_socket);
lvmpolld_set_active(find_config_tree_bool(cmd, global_use_lvmpolld_CFG, NULL));
return 1;
}
int init_connections(struct cmd_context *cmd)
{
if (!_init_lvmetad(cmd)) {
log_error("Failed to initialize lvmetad connection.");
goto bad;
}
if (!_init_lvmpolld(cmd)) {
log_error("Failed to initialize lvmpolld connection.");
goto bad;
}
cmd->initialized.connections = 1;
return 1;
bad:
cmd->initialized.connections = 0;
return 0;
}
/* Entry point */
struct cmd_context *create_toolcontext(unsigned is_long_lived,
const char *system_dir,
unsigned set_buffering,
unsigned threaded)
unsigned threaded,
unsigned set_connections,
unsigned set_filters)
{
struct cmd_context *cmd;
FILE *new_stream;
@ -1465,6 +1859,10 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!_init_tags(cmd, cmd->cft))
goto_out;
/* Load lvmlocal.conf */
if (*cmd->system_dir && !_load_config_file(cmd, "", 1))
goto_out;
if (!_init_tag_configs(cmd))
goto_out;
@ -1478,15 +1876,12 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
goto_out;
if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
find_config_tree_node(cmd, devices_types_CFG, NULL))))
find_config_tree_array(cmd, devices_types_CFG, NULL))))
goto_out;
if (!_init_dev_cache(cmd))
goto_out;
if (!_init_filters(cmd, 1))
goto_out;
memlock_init(cmd);
if (!_init_formats(cmd))
@ -1505,12 +1900,18 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
_init_globals(cmd);
if (set_connections && !init_connections(cmd))
return_0;
if (set_filters && !init_filters(cmd, 1))
goto_out;
cmd->default_settings.cache_vgmetadata = 1;
cmd->current_settings = cmd->default_settings;
cmd->config_initialized = 1;
cmd->initialized.config = 1;
out:
if (!cmd->config_initialized) {
if (!cmd->initialized.config) {
destroy_toolcontext(cmd);
cmd = NULL;
}
@ -1576,18 +1977,25 @@ static void _destroy_dev_types(struct cmd_context *cmd)
cmd->dev_types = NULL;
}
static void _destroy_filters(struct cmd_context *cmd)
{
if (cmd->full_filter) {
cmd->full_filter->destroy(cmd->full_filter);
cmd->lvmetad_filter = cmd->filter = cmd->full_filter = NULL;
}
cmd->initialized.filters = 0;
}
int refresh_filters(struct cmd_context *cmd)
{
int r, saved_ignore_suspended_devices = ignore_suspended_devices();
if (cmd->filter) {
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
}
if (!cmd->initialized.filters)
/* if filters not initialized, there's nothing to refresh */
return 1;
cmd->lvmetad_filter = NULL;
if (!(r = _init_filters(cmd, 0)))
_destroy_filters(cmd);
if (!(r = init_filters(cmd, 0)))
stack;
/*
@ -1616,10 +2024,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
if (cmd->filter) {
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
}
if (!dev_cache_exit())
stack;
_destroy_dev_types(cmd);
@ -1636,7 +2041,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
_destroy_config(cmd);
cmd->config_initialized = 0;
cmd->initialized.config = 0;
cmd->hosttags = 0;
@ -1669,6 +2074,10 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_tags(cmd, cft_tmp))
return_0;
/* Load lvmlocal.conf */
if (*cmd->system_dir && !_load_config_file(cmd, "", 1))
return_0;
/* Doesn't change cmd->cft */
if (!_init_tag_configs(cmd))
return_0;
@ -1689,15 +2098,12 @@ int refresh_toolcontext(struct cmd_context *cmd)
return_0;
if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
find_config_tree_node(cmd, devices_types_CFG, NULL))))
find_config_tree_array(cmd, devices_types_CFG, NULL))))
return_0;
if (!_init_dev_cache(cmd))
return_0;
if (!_init_filters(cmd, 0))
return_0;
if (!_init_formats(cmd))
return_0;
@ -1710,7 +2116,13 @@ int refresh_toolcontext(struct cmd_context *cmd)
if (!_init_backup(cmd))
return_0;
cmd->config_initialized = 1;
cmd->initialized.config = 1;
if (cmd->initialized.connections && !init_connections(cmd))
return_0;
if (!refresh_filters(cmd))
return_0;
reset_lvm_errno(1);
return 1;
@ -1732,8 +2144,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
if (cmd->filter)
cmd->filter->destroy(cmd->filter);
_destroy_filters(cmd);
if (cmd->mem)
dm_pool_destroy(cmd->mem);
dev_cache_exit();
@ -1780,6 +2191,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
lvmetad_release_token();
lvmetad_disconnect();
lvmpolld_disconnect();
release_log_memory();
activation_exit();

View File

@ -60,69 +60,136 @@ struct config_tree_list {
struct dm_config_tree *cft;
};
struct cmd_context_initialized_parts {
unsigned config:1; /* used to reinitialize config if previous init was not successful */
unsigned filters:1;
unsigned connections:1;
};
/* FIXME Split into tool & library contexts */
/* command-instance-related variables needed by library */
struct cmd_context {
struct dm_pool *libmem; /* For permanent config data */
struct dm_pool *mem; /* Transient: Cleared between each command */
/*
* Memory handlers.
*/
struct dm_pool *libmem; /* for permanent config data */
struct dm_pool *mem; /* transient: cleared between each command */
const struct format_type *fmt; /* Current format to use by default */
struct format_type *fmt_backup; /* Format to use for backups */
struct dm_list formats; /* Available formats */
struct dm_list segtypes; /* Available segment types */
const char *hostname;
const char *kernel_vsn;
unsigned rand_seed;
char *linebuffer;
/*
* Command line and arguments.
*/
const char *cmd_line;
struct command *command;
char **argv;
struct arg_values *arg_values;
struct dm_list arg_value_groups;
unsigned is_long_lived:1; /* Optimises persistent_filter handling */
/*
* Format handlers.
*/
const struct format_type *fmt; /* current format to use by default */
struct format_type *fmt_backup; /* format to use for backups */
struct dm_list formats; /* available formats */
struct dm_list segtypes; /* available segment types */
/*
* Machine and system identification.
*/
const char *system_id;
const char *hostname;
const char *kernel_vsn;
/*
* Device identification.
*/
struct dev_types *dev_types; /* recognized extra device types. */
/*
* Initialization state.
*/
struct cmd_context_initialized_parts initialized;
/*
* Switches.
*/
unsigned is_long_lived:1; /* optimises persistent_filter handling */
unsigned handles_missing_pvs:1;
unsigned handles_unknown_segments:1;
unsigned use_linear_target:1;
unsigned partial_activation:1;
unsigned degraded_activation:1;
unsigned auto_set_activation_skip:1;
unsigned si_unit_consistency:1;
unsigned report_binary_values_as_numeric:1;
unsigned metadata_read_only:1;
unsigned ignore_clustered_vgs:1;
unsigned threaded:1; /* Set if running within a thread e.g. clvmd */
unsigned threaded:1; /* set if running within a thread e.g. clvmd */
unsigned independent_metadata_areas:1; /* active formats have MDAs outside PVs */
unsigned unknown_system_id:1;
unsigned include_foreign_vgs:1; /* report/display cmds can reveal foreign VGs */
unsigned include_shared_vgs:1; /* report/display cmds can reveal lockd VGs */
unsigned include_active_foreign_vgs:1; /* cmd should process foreign VGs with active LVs */
unsigned vg_read_print_access_error:1; /* print access errors from vg_read */
unsigned lockd_gl_disable:1;
unsigned lockd_vg_disable:1;
unsigned lockd_lv_disable:1;
unsigned lockd_gl_removed:1;
unsigned lockd_vg_rescan:1;
unsigned lockd_vg_default_sh:1;
unsigned lockd_vg_enforce_sh:1;
unsigned independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
/*
* Filtering.
*/
struct dev_filter *lvmetad_filter; /* pre-lvmetad filter chain */
struct dev_filter *filter; /* post-lvmetad filter chain */
struct dev_filter *full_filter; /* lvmetad_filter + filter */
int dump_filter; /* Dump filter when exiting? */
struct dev_types *dev_types;
struct dev_filter *filter;
struct dev_filter *lvmetad_filter;
int dump_filter; /* Dump filter when exiting? */
struct dm_list config_files; /* master lvm config + any existing tag configs */
struct profile_params *profile_params; /* profile handling params including loaded profile configs */
struct dm_config_tree *cft; /* the whole cascade: CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES */
int config_initialized; /* used to reinitialize config if previous init was not successful */
struct dm_hash_table *cft_def_hash; /* config definition hash used for validity check (item type + item recognized) */
/* selected settings with original default/configured value which can be changed during cmd processing */
struct config_info default_settings;
/* may contain changed values compared to default_settings */
struct config_info current_settings;
/*
* Configuration.
*/
struct dm_list config_files; /* master lvm config + any existing tag configs */
struct profile_params *profile_params; /* profile handling params including loaded profile configs */
struct dm_config_tree *cft; /* the whole cascade: CONFIG_STRING -> CONFIG_PROFILE -> CONFIG_FILE/CONFIG_MERGED_FILES */
struct dm_hash_table *cft_def_hash; /* config definition hash used for validity check (item type + item recognized) */
struct config_info default_settings; /* selected settings with original default/configured value which can be changed during cmd processing */
struct config_info current_settings; /* may contain changed values compared to default_settings */
/*
* Archives and backups.
*/
struct archive_params *archive_params;
struct backup_params *backup_params;
const char *stripe_filler;
/* List of defined tags */
struct dm_list tags;
/*
* Host tags.
*/
struct dm_list tags; /* list of defined tags */
int hosttags;
const char *lib_dir; /* Cache value global/library_dir */
/*
* Paths.
*/
const char *lib_dir; /* cache value global/library_dir */
char system_dir[PATH_MAX];
char dev_dir[PATH_MAX];
char proc_dir[PATH_MAX];
/*
* Buffers.
*/
char display_buffer[NAME_LEN * 10]; /* ring buffer for upto 10 longest vg/lv names */
unsigned display_lvname_idx; /* index to ring buffer */
char *linebuffer;
/*
* Others - unsorted.
*/
const char *report_list_item_separator;
const char *time_format;
unsigned rand_seed;
};
/*
@ -132,14 +199,20 @@ struct cmd_context {
struct cmd_context *create_toolcontext(unsigned is_long_lived,
const char *system_dir,
unsigned set_buffering,
unsigned threaded);
unsigned threaded,
unsigned set_connections,
unsigned set_filters);
void destroy_toolcontext(struct cmd_context *cmd);
int refresh_toolcontext(struct cmd_context *cmd);
int refresh_filters(struct cmd_context *cmd);
int process_profilable_config(struct cmd_context *cmd);
int config_files_changed(struct cmd_context *cmd);
int init_lvmcache_orphans(struct cmd_context *cmd);
int init_filters(struct cmd_context *cmd, unsigned load_persistent_cache);
int init_connections(struct cmd_context *cmd);
struct format_type *get_format_by_name(struct cmd_context *cmd, const char *format);
const char *system_id_from_string(struct cmd_context *cmd, const char *str);
#endif

Some files were not shown because too many files have changed in this diff Show More