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

Compare commits

..

1656 Commits

Author SHA1 Message Date
05716c2d8a clvmd: Fix stack overflow on 64 bit ARM
Seems the amount of allocated data on stack is dependent on page size.
As the page size on aarch64 is 64kiB writing to memory allocated by
alloca results in stack overflow as at the time of allocation the are
already 2 pages allocated. Clearly 128kiB is not sufficient and at least
3 pages are needed.
2014-09-16 17:34:32 +02: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
0bb6ffb81f pre-release 2014-06-23 14:16:39 +01:00
8d27f8e003 pre-release 2014-06-23 14:03:32 +01:00
867b92b031 man: More /dev/vg and /dev/mapper documentation. 2014-06-23 14:01:31 +01:00
9c3c357874 select: add message about 'help' field to get more help on each error hit during selection parsing
Inform about 'help' to get more help about selection fields and operators
after each syntax error hit:

  "Use 'help' for selection to get more help."
2014-06-23 12:21:17 +02:00
69075d0b43 select: also mark uncomparable/unselectable fields in field/selection help 2014-06-23 12:20:49 +02:00
2d48ef7f04 select: add FLD_UNCOMPARABLE flag for fields which can't be compared
A field where it has no meaning to do any type of comparison is the
implicit "help" or "?" field. The error given was a bit cryptic
before this patch, the FLD_UNCOMPARABLE flag makes it easier to identify
this situation anywhere in the code and provide much better error message.
This flag can be applied to other fields that may appear in the future -
mostly usable for implicit fields as they always have special purpose
(so we're not exporting it in libdevmapper for now - usual reporting
fields don't need this).

Before this patch:

$ vgs -S help=1
  dm_report_object: no data assigned to field help
  dm_report_object: no data assigned to field help

(...which is true actually, but let's provide something better...)

With this patch applied:

$vgs -S help=1
  Selection field is uncomparable: help.
  Selection syntax error at 'help=1'.

$vgs -S '(name=vg && help=1) || vg_size > 1g'
  Selection field is uncomparable: help.
  Selection syntax error at 'help=1) || vg_size > 1g'.
2014-06-23 10:09:58 +02:00
c1c2e838e8 locking: fix cluster locking
Hunk missed from last commit 78533f72d3.
2014-06-20 16:38:48 +01:00
78533f72d3 locking: Introduce LCK_ACTIVATION.
Take a local file lock to prevent concurrent activation/deactivation of LVs.
Thin/cache types and an extension for cluster support are excluded for
now.

'lvchange -ay $lv' and 'lvchange -an $lv' should no longer cause trouble
if issued concurrently: the new lock should make sure they
activate/deactivate $lv one-after-the-other, instead of overlapping.

(If anyone wants to experiment with the cluster patch, please get in touch.)
2014-06-20 13:24:02 +01:00
f29ae59a4d pvvmove: add a few comments 2014-06-20 11:41:20 +01:00
f96a499c8d lv: fix lv_is_raid 2014-06-20 11:37:45 +02:00
93597bcbdc tests: add udev sync point
Missed synchronization with udev may lead to error on vgcreate,
if previous vgremove was not handled fast enough by udev.
2014-06-20 11:14:29 +02:00
548269a1dd cleanup: use simplier test
Just like all other tests - use direct LV function test
2014-06-20 11:14:11 +02:00
32ad8ab5a4 memlock: skip more entries
Add more entries for memlock skipping - since those are never
used by lvm code in critical section (suspend state).
2014-06-20 11:13:41 +02:00
59ed4d3bf6 dmsetup: no need to check for "help" field name after report init
The "help" field (as well as "?") is implicit now - libdevmapper
takes care of it completely.
2014-06-19 18:22:51 +02:00
c6d82c992b pvmove: Fix code that looks up the "move pv" for display
'lvs' would segfault if trying to display the "move pv" if the
pvmove was run with '--atomic'.  The structure of an atomic pvmove
is different and requires us to descend another level in the
LV tree to retrieve the PV information.
2014-06-19 10:57:08 -05:00
3964a1a89f pvmove: Clean-up iterator.
In 'find_pvmove_lv', separate the code that searches the atomic
pvmove LVs from the code that searches the normal pvmove LVs.  This
cleans up the segment iterator code a bit.
2014-06-19 10:52:09 -05:00
f16da6ef23 report: display explicit fields first, then implicit fields in field help
It's better to have implicit fields at the very end of the output
so users can see them without scrolling back if the list of fields
is long (the "help" is also an implicit field now so it should be
easily visible).
2014-06-19 16:14:53 +02:00
a40bc36b2e libdevmapper: revoke commit 7c86131233
We have "help" and "?" defined as implicit fields now. As such, we
don't need to export these names in libdevmapper (as it was introduced
by commit 7c86131233 within this release).
If anyone uses these field names by mistake, the libdevmapper code can
error out correctly if it detects that the set of explicit field names
(the ones supplied by "fields" arg in dm_report_init/dm_report_init_with_selection)
contains any of the implicit field names (the ones defined internally
by libdevmapper itself).
2014-06-19 16:09:32 +02:00
cd7325f18d report: make "help" and "?" field implicit
Making "help" and "?" implicit also simplifies code since the
dm_report_init caller (lvm/dmsetup) doesn't need to check on
dm_report_init return whether "help" or "?" was hit while parsing
fields/sort keys in libdevmapper.

The libdevmapper now sets internal "RH_ALREADY_REPORTED" flag
after it reports the "help" or "?" implicit field. Then libdevmapper
itself checks for this flag in dm_report_object and if found,
the actual reporting is skipped (because the "help" implicit field
was reported instead of the actual report).
2014-06-19 16:09:31 +02:00
012dab7aa3 select: add list of allowed types for each selection operator mentioned in help 2014-06-19 15:19:54 +02:00
b33091cb11 pvmove: tidy 2014-06-19 13:40:47 +01:00
bc0a1ca83d tests: remove dmeventd usage
This test is testing --use-policies on cmdline.
So monitoring must not be used.
2014-06-19 12:48:21 +02:00
b193a3b09f cleanup: rename variable wait
With older system headers (sys/wait.h) this shadows declaration.
2014-06-19 12:02:48 +02:00
00af0d13c9 cleanup: more readable
Older gcc complained a bit about uninitialized vars
so reorder code for better readability.
2014-06-19 12:02:48 +02:00
aa3e413093 lvchange: better --refresh of raid and mirrors
Use lv_check_not_in_use() to detect openned device.
Plain info.open_count is not good enough for udev random
device openning.
2014-06-19 12:01:34 +02:00
57faf97e6f test: Clean-up pvmove-basic for atomic pvmove test
The way I was testing for the existence of pvmove mimages was
incorrect for rhel5.  This patch makes it more generic/universal.
2014-06-18 15:40:06 -05:00
e96a4856e6 man: lvmthin
Clean up inconsistencies in the last change.
Improve some bad formatting.
2014-06-18 14:30:57 -05:00
597de5c807 cleanup: use insert_layer_for_lv implicit rename
There is implicit rename for certain layered device.
Do it now for _tdata, _cdata and _corig.

TODO: use better API here...
2014-06-18 15:00:18 +02:00
e6a4cc9c31 lvconvert: print warning when not convert thinpool
Warning about destruction should not be printed,
When we are converting already existing pool
(improving original in-release commit bbf4b2c1c9)
2014-06-18 15:00:18 +02:00
21964f47d5 compilation: fix warnings: build_dm_uuid now accepts whole struct logical_volume, not lvid
replicator/replicator.c:338:2: warning: passing argument 2 of 'build_dm_uuid' from incompatible pointer type [enabled by default]
replicator/replicator.c:629:3: warning: passing argument 2 of 'build_dm_uuid' from incompatible pointer type [enabled by default]
replicator/replicator.c:644:6: warning: passing argument 2 of 'build_dm_uuid' from incompatible pointer type [enabled by default]
replicator/replicator.c:668:7: warning: passing argument 2 of 'build_dm_uuid' from incompatible pointer type [enabled by default]
replicator/replicator.c:677:4: warning: passing argument 2 of 'build_dm_uuid' from incompatible pointer type [enabled by default]
2014-06-18 14:43:13 +02:00
fc6e2a703b man: add man page entry for dmsetup info -c -S/--select + minor cleanups 2014-06-18 13:48:27 +02:00
0548a82e63 cleanup: gcc warnings and report-select test vs snap_percent 0%
Fix gcc warnings:
libdm-report.c:1952:5: warning: "end_op_flag_hit" may be used uninitialized in this function [-Wmaybe-uninitialized]
libdm-report.c:2232:28: warning: "custom" may be used uninitialized in this function [-Wmaybe-uninitialized]

And snap_percent is not 0% in dm < 1.10.0 so
don't test comparison with 0% here.
2014-06-18 13:26:47 +02:00
ca1abe70ff WHATS_NEW: commit 76467bdcfd
Ordering string list items on reports is also new compared to
previous state where items were not ordered at all and they
got reported simply as they appeared/were processed.
2014-06-18 12:30:34 +02:00
63f5be0170 WHATS_NEW: commits 7dbbc05a69c4cb9756464720cad29e3c1ed971c3..b16f5633ab199dedfd25f08562f686a6fb4aba9d
Report selection support...
2014-06-18 10:48:53 +02:00
5ebff6cc9f pvmove: Enable all-or-nothing (atomic) pvmoves
pvmove can be used to move single LVs by name or multiple LVs that
lie within the specified PV range (e.g. /dev/sdb1:0-1000).  When
moving more than one LV, the portions of those LVs that are in the
range to be moved are added to a new temporary pvmove LV.  The LVs
then point to the range in the pvmove LV, rather than the PV
range.

Example 1:
	We have two LVs in this example.  After they were
	created, the first LV was grown, yeilding two segments
	in LV1.  So, there are two LVs with a total of three
	segments.

	Before pvmove:
	      ---------  ---------   ---------
	      | LV1s0 |  | LV2s0 |   | LV1s1 |
	      ---------  ---------   ---------
	         |           |           |
	   -------------------------------------
	PV | 000 - 255 | 256 - 511 | 512 - 767 |
	   -------------------------------------

	After pvmove inserts the temporary pvmove LV:
	          ---------   ---------   ---------
	          | LV1s0 |   | LV2s0 |   | LV1s1 |
	          ---------   ---------   ---------
	              |           |           |
	        -------------------------------------
	pvmove0 |   seg 0   |   seg 1   |   seg 2   |
	        -------------------------------------
	              |           |           |
	        -------------------------------------
	PV      | 000 - 255 | 256 - 511 | 512 - 767 |
	        -------------------------------------

	Each of the affected LV segments now point to a
	range of blocks in the pvmove LV, which purposefully
	corresponds to the segments moved from the original
	LVs into the temporary pvmove LV.

The current implementation goes on from here to mirror the temporary
pvmove LV by segment.  Further, as the pvmove LV is activated, only
one of its segments is actually mirrored (i.e. "moving") at a time.
The rest are either complete or not addressed yet.  If the pvmove
is aborted, those segments that are completed will remain on the
destination and those that are not yet addressed or in the process
of moving will stay on the source PV.  Thus, it is possible to have
a partially completed move - some LVs (or certain segments of LVs)
on the source PV and some on the destination.

Example 2:
	What 'example 1' might look if it was half-way
	through the move.
	             ---------   ---------   ---------
	             | LV1s0 |   | LV2s0 |   | LV1s1 |
	             ---------   ---------   ---------
	                 |           |           |
	           -------------------------------------
	pvmove0    |   seg 0   |   seg 1   |   seg 2   |
	           -------------------------------------
	                 |           |           |
	                 |     -------------------------
	source PV        |     | 256 - 511 | 512 - 767 |
	                 |     -------------------------
	                 |           ||
	           -------------------------
	dest PV    | 000 - 255 | 256 - 511 |
	           -------------------------

This update allows the user to specify that they would like the
pvmove mirror created "by LV" rather than "by segment".  That is,
the pvmove LV becomes an image in an encapsulating mirror along
with the allocated copy image.

Example 3:
	A pvmove that is performed "by LV" rather than "by segment".

	                   ---------   ---------
	                   | LV1s0 |   | LV2s0 |
	                   ---------   ---------
	                       |           |
	                 -------------------------
	        pvmove0  |  * LV-level mirror *  |
	                 -------------------------
                             /                \
	   pvmove_mimage0   /          pvmove_mimage1
	   -------------------------   -------------------------
	   |   seg 0   |   seg 1   |   |   seg 0   |   seg 1   |
	   -------------------------   -------------------------
	        |            |               |           |
	   -------------------------   -------------------------
	   | 000 - 255 | 256 - 511 |   | 000 - 255 | 256 - 511 |
	   -------------------------   -------------------------
	           source PV                    dest PV

The thing that differentiates a pvmove done in this way and a simple
"up-convert" from linear to mirror is the preservation of the
distinct segments.  A normal up-convert would simply allocate the
necessary space with no regard for segment boundaries.  The pvmove
operation must preserve the segments because they are the critical
boundary between the segments of the LVs being moved.  So, when the
pvmove copy image is allocated, all corresponding segments must be
allocated.  The code that merges ajoining segments that are part of
the same LV when the metadata is written must also be avoided in
this case.  This method of mirroring is unique enough to warrant its
own definitional macro, MIRROR_BY_SEGMENTED_LV.  This joins the two
existing macros: MIRROR_BY_SEG (for original pvmove) and MIRROR_BY_LV
(for user created mirrors).

The advantages of performing pvmove in this way is that all of the
LVs affected can be moved together.  It is an all-or-nothing approach
that leaves all LV segments on the source PV if the move is aborted.
Additionally, a mirror log can be used (in the future) to provide tracking
of progress; allowing the copy to continue where it left off in the event
there is a deactivation.
2014-06-17 22:59:36 -05:00
b16f5633ab test: fix report_select test to work in cluster
The snapshot LV is used to check selection of percent values.
The orig volume must be activated exclusively in cluster.
2014-06-17 18:34:46 +02:00
ef43a50926 tests: update lvcreate-thin for latest changes
With recent changes introduced with the report selection support,
the content of lv_modules field is of string list type (before
it was just string type).

String list elements are always ordered now so update lvcreate-thin
test to expect the elements to be ordered.
2014-06-17 18:20:08 +02:00
d09590c4b6 prop: update FIELD macro to accomodate the differentiation of number, size and percent field values
The differentiation of the original number field into number, size and
percent field types has been introduced with recent changes for report
selection support.
2014-06-17 18:14:57 +02:00
94316dfe9d report: select: add man pages for report selection feature 2014-06-17 16:27:21 +02:00
40e0f44495 report: select: add --select arg to lvm devtypes 2014-06-17 16:27:21 +02:00
f88130fd85 report: add support for implicit fields, add implicit "selected" field
Implicit fields are fields that are registered with the report
and reported internally by libdevmapper itself (compared to explicit
fields that are registered by the layer above libdevmapper - e.g. LVM,
dmsetup...).

The "selected" field is the implicit field (for now the only one)
that reports the result of the selection. Since the selection itself
is the property of the libdevmapper, the upper layer using dm_report_init
can't register this field itself and it must be done directly at
libdevmapper layer.

The "selected" field is internally registered as part of the "common"
report type with id 0x80000000 (the last bit in uin32_t) which is then
reserved (the explicit report types are then checked if they do not
contain this id and if yes, we error out).

This way, the "selected" field is recognized by all libdevmapper users
that initialize the reporting with "dm_report_init_with_selection".
If reporting is initialized with the classical "dm_report_init",
there's no functional change (so the "selected" field is not defined
and it's not recognized).
2014-06-17 16:27:21 +02:00
0d8e94ce2e tests: select: add test for report selection feature 2014-06-17 16:27:21 +02:00
51a86dc2f8 report: select: add support for percent selection 2014-06-17 16:27:21 +02:00
cfed0d09e8 report: select: refactor: move percent handling code to libdm for reuse 2014-06-17 16:27:21 +02:00
35c4e4489c report: select: add support for reserved value recognition in report selection string - add struct dm_report_reserved_value
Make dm_report_init_with_selection to accept an argument with an
array of reserved values where each element contains a triple:

  {dm report field type, reserved value, array of strings representing this value}

When the selection is parsed, we always check whether a string
representation of some reserved value is not hit and if it is,
we use the reserved value assigned for this string instead of
trying to parse it as a value of certain field type.

This makes it possible to define selections like:

   ... --select lv_major=undefined (or -1 or unknown or undef or whatever string representations are registered for this reserved value in the future)
   ... --select lv_read_ahead=auto
   ... --select vg_mda_copies=unmanaged

With this, each time the field value of certain type is hit
and when we compare it with the selection, we use the proper
value for comparison.

For now, register these reserved values that are used at the moment
(also more descriptive names are used for the values):

  const uint64_t _reserved_number_undef_64 = UINT64_MAX;
  const uint64_t _reserved_number_unmanaged_64 = UINT64_MAX - 1;
  const uint64_t _reserved_size_auto_64 = UINT64_MAX;

 {
  {DM_REPORT_FIELD_TYPE_NUMBER, _reserved_number_undef_64, {"-1", "undefined", "undef", "unknown", NULL}},
  {DM_REPORT_FIELD_TYPE_NUMBER, _reserved_number_unmanaged_64, {"unmanaged", NULL}},
  {DM_REPORT_FIELD_TYPE_SIZE, _reserved_size_auto_64, {"auto", NULL}},
  NULL
 }

Same reserved value of different field types do not collide.
All arrays are null-terminated.

The list of reserved values is automatically displayed within
selection help output:

  Selection operands
  ------------------
  ...

  Reserved values
  ---------------
    -1, undefined, undef, unknown   - Reserved value for undefined numeric value. [number]
    unmanaged                       - Reserved value for unmanaged number of metadata copies in VG. [number]
    auto                            - Reserved value for size that is automatically calculated. [size]

  Selection operators
  -------------------
  ...
2014-06-17 16:27:21 +02:00
a075ec15c4 report: select: show field type in field list if in context of selection
When the field list is displayed as help for constructing selection
criteria, show also the field value type. This is useful for users
to know what set of operators are allowed for the type - the subsequent
"Selection operands" section in the help output summarize all known
types that can be used in selection.
2014-06-17 16:27:21 +02:00
6d667adeea report: select: add help for creating selections
The "<lvm command> -S/--select help" shows help (including list of fields to match against):

  ...field list here including the field type name...

  Selection operands
  ------------------
    field               - Reporting field.
    number              - Non-negative integer value.
    size                - Floating point value with units specified.
    string              - Characters quoted by ' or " or unquoted.
    string list         - Strings enclosed by [ ] and elements delimited by either
                          "all items must match" or "at least one item must match" operator.
    regular expression  - Characters quoted by ' or " or unquoted.

  Selection operators
  -------------------
    Comparison operators:
        =~  - Matching regular expression.
        !~  - Not matching regular expression.
         =  - Equal to.
        !=  - Not equal to.
        >=  - Greater than or equal to.
         >  - Greater than
        <=  - Less than or equal to.
         <  - Less than.

    Logical and grouping operators:
        &&  - All fields must match
         ,  - All fields must match
        ||  - At least one field must match
         #  - At least one field must match
         !  - Logical negation
         (  - Left parenthesis
         )  - Right parenthesis
         [  - List start
         ]  - List end
2014-06-17 16:27:21 +02:00
03a3f6078d report: select: add support for comparing string lists with selection defined 2014-06-17 16:27:20 +02:00
8faa4ded9c report: select: add support for processing string lists in selection
Selection list items are enclosed in '[' and ']' (if there's only
one item, the '[' and ']' can be omitted). Each element of the list
is a string (either quoted or unquoted, like the usual string operand
used in selection) and each element is delimited either by conjunction
(meaining "match all") or disjunction operator (meaning "match any").

For example, if "," is the conjuction operator and "/" is the
disjunction operator then:

  lv_tags=[a,b,c]

...will match all fields where tags contain *all* a, b and c.

  lv_tags=[a/b/c]

...will match all fields where tags contain *any* of a, b, or c.

Mixing operators within the list is not supported:

  lv_tags=[a,b/c]

...will give an error.

The order in which items are defined in the selection do not matter.

This patch enhances the selection parsing functionality to recognize
such lists.
2014-06-17 16:27:20 +02:00
a6694cfc29 report: select: add DM_REPORT_FIELD_TYPE_STRING_LIST to make a difference between STRING and STRING_LIST
The {pv,vg,lv,seg}_tags and lv_modules fields are reported as string
lists using the new dm_report_field_string_list - so we just pass
the list to the fn that takes care of reporting and item sorting itself.
2014-06-17 16:27:20 +02:00
76467bdcfd report: select: add dm_report_field_string_list to libdm
Add a separate dm_report_field_string_list fn to libdevmapper to
support reporting string lists. Before, the code used libdevmappers's
dm_report_field_string fn which required formatting the list to a
single string. This functionality is now moved to libdevmapper
and the code that needs to report the string list just needs
to pass the list itself and libdevmapper will take care of this.
This also enhances code reuse.

The dm_report_field_string_list also accepts an argument to define
custom delimiter to use. If not defined, a default "," (comma) is
used as item delimiter in the string list reported.

The dm_report_field_string_list automatically sorts the items in
the list before formatting it to a final string. It also encodes
the position and length within the final string where each element
can be found. This can be used to support checking against each
list item reported since since when formatted as a single string
for the actual report, we would lose this information otherwise
(we don't want to copy each item, the position and length within
the final string is enough for us to get the original items back).

When such lists are checked against the selection tree, we can check
each item individually this way and we can support operators like
"match any" and "match all".
2014-06-17 16:27:20 +02:00
5abdb52fdc report: select: refactor: move str_list to libdm
The list of strings is used quite frequently and we'd like to reuse
this simple structure for report selection support too. Make it part
of libdevmapper for general reuse throughout the code.

This also simplifies the LVM code a bit since we don't need to
include and manage lvm-types.h anymore (the string list was the
only structure defined there).
2014-06-17 16:27:20 +02:00
fe952e735a report: select: add --select arg to pvdisplay, vgdisplay and lvdisplay 2014-06-17 16:27:20 +02:00
5b734a0ea1 report: select: add --select arg to pvs, vgs and lvs 2014-06-17 16:27:20 +02:00
3a1c7e5d78 report: select: add --select arg to dmsetup 2014-06-17 16:27:20 +02:00
bc6458de87 report: select: use _check_report_selection in dm_report_object to report only objects that satisfy the report selection
This is rebased and edited version of the original design and
patch proposed by Jun'ichi Nomura:
  http://www.redhat.com/archives/dm-devel/2007-April/msg00025.html

This activates the actual selection process in dm_report_object.
2014-06-17 16:27:20 +02:00
d33280a978 report: select: add _check_selection fn to support checking fields against given selections
This is rebased and edited versions of the original design and
patch proposed by Jun'ichi Nomura:
  http://www.redhat.com/archives/dm-devel/2007-April/msg00025.html

The _check_selection implements the actual field checking against the
selection tree.
2014-06-17 16:27:20 +02:00
0103738ef5 report: select: add dm_report_init_with_selection to libdm
This is rebased and edited version of the original design and
patch proposed by Jun'ichi Nomura:
  http://www.redhat.com/archives/dm-devel/2007-April/msg00025.html

The dm_report_init_with_selection is the same as dm_report_init
but it contains an additional argument to set the selection
in the form of a string that contains field names to check against and
selection operators. The selection string is parsend and a selection
tree is composed for use in the checks against individual fields when
the report is processed. The parsed selection tree is stored in dm_report
structure as "selection_root".
2014-06-17 16:27:20 +02:00
2c3e84a68d report: select: add supporting infrastucture for token parsing in report selections
This is rebased and edited version of the original design and
patch proposed by Jun'ichi Nomura:
  http://www.redhat.com/archives/dm-devel/2007-April/msg00025.html

Add support for parsing numbers, strings (quoted or unquoted), regexes
and operators amogst these operands in selection condition supplied.
2014-06-17 16:27:20 +02:00
4118dd8da3 report: select: add structs for report selection
This is rebased and edited version of the original design and
patch proposed by Jun'ichi Nomura:
  http://www.redhat.com/archives/dm-devel/2007-April/msg00025.html

This patch defines operators and structures that will be used
to store the report selection against which the actual values
reported will be checked.

  Selection operators
  -------------------
    Comparison operators:
        =~  - Matching regular expression.
        !~  - Not matching regular expression.
         =  - Equal to.
        !=  - Not equal to.
        >=  - Greater than or equal to.
         >  - Greater than
        <=  - Less than or equal to.
         <  - Less than.

    Logical and grouping operators:
        &&  - All fields must match
         ,  - All fields must match
        ||  - At least one field must match
         #  - At least one field must match
         !  - Logical negation
         (  - Left parenthesis
         )  - Right parenthesis
2014-06-17 16:27:20 +02:00
7dbbc05a69 report: select: add DM_REPORT_FIELD_TYPE_SIZE to make a difference between NUMBER and SIZE
This makes it easier to check against the fields (following patches for
report selection) and check whether size units are allowed or not
with the field value.
2014-06-17 16:27:20 +02:00
378fa9d158 tests: check new snapshot skills 2014-06-17 13:43:05 +02:00
8403bbd4ad tests: detect version of thin_restore command
Skip test when missing.
2014-06-17 13:43:05 +02:00
6fb19f37fe tests: wait for udev
Before test exits, wait for udev.
2014-06-17 13:43:04 +02:00
0558b1a086 cleanup: we already know max device name size
Use NAME_LEN constant to simplify creation of device name.
Since the max size should be already tested in validation,
throw INTERNAL_ERROR if the size of vg/lv is bigger then NAME_LEN.
2014-06-17 13:43:04 +02:00
7aef45f9bb cleanup: use stack for small buffer
Avoid error checking of allocation error when just few bytes are needed
for short string and use stack.
Stacktrace lvmetad_pv_gone() fail path.
2014-06-17 13:42:45 +02:00
494db11004 snapshot: %ORIGIN is relative to data size
Let's use the size of origin as the real base for percenta calculation,
and 'silenly' add needed metadata space for snapshot.

So now command   'lvcreate -s -l100%ORIGIN vg/lv' should always create a
snapshot to handle full device overwrite.
2014-06-17 13:41:01 +02:00
cd6d6fc24e snapshot: report proper error message
Expresing -lXX%LV is not valid for snapshot, but error message for
snapshost case was not complete and missed %ORIGIN.
Also document correct settings for in manpage properly where
it missed %PVS.
2014-06-17 13:36:33 +02:00
15e7066fe3 snapshot: do not spawn when origin is not active
Since the code is not doing anything when origin is not active,
avoid spawning polling thread.
2014-06-17 13:36:07 +02:00
c46d4a745d snapshot: check snapshot exists
Return 0 if the LV is not even snapshot.
2014-06-17 13:36:07 +02:00
435c82f8f6 snapshot: check it's still snapshot
While polling for snapshot, detect first the snapshot still
exits.  It's valid to have multiple polling threads watching
for the same thing and just 1 can 'win' the finish part.
All others should nicely 'fail'.
2014-06-17 13:36:07 +02:00
a20de8af20 poll_daemon: Cleanly exit polling if the LV is no longer active
If the we are polling an LV due to some sort of conversion and it
becomes inactive, a rather worrisome message is produced, e.g.:
"  ABORTING: Mirror percentage check failed."

We can cleanly exit if we do a simple check to see if the LV is
active before performing the check.  This eliminates the scary
message.
2014-06-16 18:56:32 -05:00
962a40b981 cache: Properly rename origin LV tree when adding "_corig"
When creating a cache LV with a RAID origin, we need to ensure that
the sub-LVs of that origin properly change their names to include
the "_corig" extention of the top-level LV.  We do this by first
performing a 'lv_rename_update' before making the call to
'insert_layer_for_lv'.
2014-06-16 18:15:39 -05:00
fea8abe56a systemd: use RemoveOnStop for dm-event.socket and lvm2-lvmetad.socket
Systemd version 214 introduced new "RemoveOnStop" option for socket
units to remove the socket/FIFO when the particular unit is stopped.

Also https://bugzilla.redhat.com/show_bug.cgi?id=802748.
2014-06-13 15:45:25 +02:00
4c9fbe048f spec: new thin-generic.profile 2014-06-13 10:01:34 +02:00
8e0687ca69 profile: add thin-generic.profile
The thin-generic.profile contains settings for thin/thin pool volumes
suitable for generic environment/use containing default settings.
This allows users to change the global lvm.conf settings at will
and still keep the original settings for volumes that have this
thin profile assigned already.
2014-06-13 09:56:29 +02:00
cf4d5ead02 test: pvs bz1108394 2014-06-12 11:56:06 +02:00
eb316fec33 libdm: dm_report_object report error for no data
NULL data would cause problems....
2014-06-12 11:56:06 +02:00
3d9737442b libdm: dm_report_object avoid duplicat strlen call
Remember strlen result.
2014-06-12 11:56:06 +02:00
922f884abe report: avoid passing NULL label
Internal reporting function cannot handle NULL reporting value,
so ensure there is at least dummy label.

So move dummy_lable from tools/reporter.c and use it for all
report_object() calls in lib/report/report.c.
(Fixes RHBZ 1108394)

Simlify lvm_report_object initialization.
2014-06-12 11:55:58 +02:00
c230ae95ab tests: change to inittest 2014-06-11 17:46:55 +02:00
3f81b7c55c tests: update vgchange -c
Vgchange now detects runnig clvmd - so update test to reflect this.
2014-06-11 11:11:10 +02:00
f845afe7cf man: dmsetup manglename
More updates to manglename option.
Add reference to LVM2 resource page, since for a long time,
this is the right places for sources for libdevmapper....
2014-06-11 11:11:10 +02:00
4db71422a2 man: kiB uppercase 2014-06-11 11:10:56 +02:00
d13efac51b man: update lvmthin
Improve graphics form of page and use shorter correct and suggested
forms of thin pool manipulation commands.
2014-06-11 11:10:55 +02:00
e156837636 man: more compliant 2014-06-11 11:10:55 +02:00
0896987633 man: properly escape -
Dash should be using '\' to be typographically correct.
2014-06-11 11:10:55 +02:00
4956091027 man: use bullets 2014-06-11 11:10:55 +02:00
d2b60c6e35 man: advertise lvmcache, lvmthin
Add references to new man pages so they get known.
2014-06-11 11:10:54 +02:00
6766cdc8a1 tests: some more renames lib/test -> lib/inittest 2014-06-11 11:07:32 +02:00
5c5177c37c tests: rename test to inittest
We are getting into problem when we use 'test' for commands like
should/not/...

So avoid overloading test name and change it to inittest.
2014-06-10 10:51:27 +02:00
9f68aadb74 tests: make timeouts longer
Add more time for tests, since debug kernels are getting slower...
and we add more and more tests.

However many test should be shortened to avoid testing disk-perfomance
and focus on lvm functionality...
(Often we should probably test with inactive volumes when we check
metadata operation of lvm2)

We may need to support option for 'DEEP' longer testing.

Also something like LVM_TEST_TIMEOUT_FACTOR might be useful
though it would be much better if test suite could approximete
from system perfomance test lenght...
2014-06-10 10:51:26 +02:00
9f9a196dc0 cleanup: add missing log_error
log_error about no change in volume group with 'n' prompt answer.
(in-release fix)
2014-06-10 10:51:26 +02:00
5e52a7788f cleanup: drop inline keyword
Inline would need function body in header file.
2014-06-10 10:51:26 +02:00
2f260c9909 activation: retry cleanup deactivation
Enable 'retry' deactivation also in 'cleanup' phase.
It shouldn't be mostly needed - however udev now produces
more and more completelny non-synchronizable device opens,
so even for orphan devices we can't easily predict where
udevd opens devices.

So it's more preferable here to log error about device being open
and retry clean, but let the command proceed.
2014-06-10 10:51:24 +02:00
1824a781db lvmetad: Drop active connection upon lvmetad_set_active(0). 2014-06-09 01:55:33 +02:00
488f308527 libdaemon: Keep track of client threads, wait before shutdown. 2014-06-09 01:50:57 +02:00
4bb1efe2fb test: Reflect that --sysinit only treats lvmetad specially with -aay (not -ay). 2014-06-08 23:37:08 +02:00
ee200ddfc3 pvremove: Update lvmcache => avoid spurious error messages. 2014-06-08 22:57:04 +02:00
02e1bf406b lvmetad: Avoid "connect failed" spamming when lvmetad is not available. 2014-06-08 22:09:29 +02:00
150165591f test: Try harder to vgremove in lvmetad-lvm1.sh. 2014-06-08 22:01:02 +02:00
b3bdd41092 lvm1: Fail vg_write graciously when devices are missing. 2014-06-08 21:57:18 +02:00
60443d6a5d test: Fix the vgck test after vg_write change. 2014-06-08 21:10:47 +02:00
f58a7f305b test: Fail devices silently in lvconvert-repair-transient.sh. 2014-06-08 21:10:47 +02:00
eda4c3a41d test: Make it possible to enable/disable devices silently. 2014-06-08 21:10:47 +02:00
dba6dec661 metadata: Make it possible to write partial VGs obtained from lvmetad. 2014-06-08 17:41:11 +02:00
943f3aec3d cleanup: move the "daemon is running" checks to lvm-wrappers
And use ifdefs there, not exposing it in the tool code itself.
Later in the future, we should probably make the PIDFILE and
daemon checking code available also in case the daemon itself
is not built.
2014-06-06 14:21:09 +02:00
f115a4a53f configure: update libcpg test
PKG_CHECK_MODULES needs old-way if;then;fi.
2014-06-06 10:31:45 +02:00
14f482077d cleanup: default.profile is not used (and it was split in two and renamed anyway) 2014-06-06 10:24:50 +02:00
291e55557e cleanup: commit c0f9c79 to work also with for non-clustered configuration 2014-06-06 10:17:26 +02:00
c0f9c79ae8 vgchange: With '--yes', don't prompt the user
If the user supplies a '--yes' argument, then don't bother them with
a question to confirm whether to change the cluster attribute (even
if clvmd isn't running).
2014-06-05 22:45:19 -05:00
1f2aedb190 WHATS_NEW: For commit 9399b743 (prompt for VG cluster attr change)
Minor change, but put a comment in WHATS_NEW anyway.
2014-06-05 22:30:50 -05:00
9399b74356 vgchange: Prompt when setting VG cluster attr if cluster is not setup
If clvmd is not running or the locking type is not clustered and someone
attempts to set the cluster attribute on a volume group, prompt them to
see if they are sure.  (Only prompt for one though.  If neither are true,
simply ask them once.)
2014-06-05 22:27:40 -05:00
de12310c45 tests: disable python failing test
Aborts and needs fixes...
2014-06-05 23:07:23 +02:00
7b8133e0b2 tests: fix test compare
Comparing 64T can't use -eq
2014-06-05 23:06:45 +02:00
eb7ca96b59 tests: adapt test for newline delimit
content of DEVICES is now delimited by newlines
2014-06-05 23:05:52 +02:00
46b0cd10fe configure: do not exit with error code
Since the test is the last command make a test in a form it will be
after its finished 0.
(regression from last configure cleanup)
2014-06-05 18:02:40 +02:00
c4e0c61272 tests: typo 2014-06-05 17:49:35 +02:00
54da0ea61a tests: use get_devs
Check how get_devs is usable with shell array DEVICES
2014-06-05 17:49:35 +02:00
77d4e317a4 tests: use manglename none for dmsetup 2014-06-05 17:49:34 +02:00
9196942312 tests: add get_devs function
Instead of rereading device list via cat - keep
the list in bash array. (Also solves problem
with spaces in device path)

Move usage of  "$path" out of lvm shell usage,
since we don't support such thing there...
2014-06-05 17:49:34 +02:00
223bdc5eb2 tests: use shell arrays to keep device names
Better preserving spaces in device path name,
though admitely rest of test suite need
more repairs...
2014-06-05 17:49:34 +02:00
21db25b3c4 tests: fix use of double apostrophes in get
Need to put "" around parameters.
2014-06-05 17:49:34 +02:00
1b59f5a99c configure: reconfigure 2014-06-05 17:47:23 +02:00
7cead4afea configure: cleanups
Replace AC_PATH_PROG with AC_PATH_TOOL.
Drop 'x' when already using "" around shell variable.
Simlify some long line and ifs.
Merge multiple test evaluation with '-a', '-o'.
Use 'case' instead if several ifs when it's more elegant.
Improve usage of pkg_config_init and add it where it's been missing.
Check for UDEV_HAS_BUILTIN_BLKID and when building udev-rules.
2014-06-05 17:47:23 +02:00
b3ace4f9af configure: accept 'none' as mangling mode
Since we advertise 'none' as mangling name, accept it.
Keep it backward compatible and leave disabled option still working
(though I guess there is likely no user of this option...)
2014-06-05 17:47:23 +02:00
93c2614e56 man: document DM_DEFAULT_NAME_MANGLING_MODE
Document DM_DEFAULT_NAME_MANGLING_MODE environmental variable.
(its default setting is build time configurable)
2014-06-05 17:47:21 +02:00
4454a580df test: use direct I/O when injecting bad data into RAID images
When directly corrupting RAID images for the purpose of testing,
we must use direct I/O (or a 'sync' after the 'dd') to ensure that
the writes are not caught in the buffer cache in a way that is not
reachable by the top-level RAID device.
2014-05-30 17:26:10 -05:00
0362169277 report: fix report field type for lv_kernel_major/minor
Should be defined as numeric field, not string field.
2014-05-30 17:24:07 +02:00
442820aae3 activation: Remove empty DM device when table fails to load.
As part of better error handling, remove DM devices that have been
sucessfully created but failed to load a table.  This can happen
when pvmove'ing in a cluster and the cluster mirror daemon is not
running on a remote node - the mapping table failing to load as a
result.  In this case, any revert would work on other nodes running
cmirrord because the DM devices on those nodes did succeed in loading.
However, because no table was able to load on the non-cmirrord nodes,
there is no table present that points to what needs to be reverted.
This causes the empty DM device to remain on the system without being
present in any LVM representation.

This patch should only be considered a partial fix to the overall
problem.  This is because only the device which failed to load a
table is removed.  Any LVs that may have been loaded as requirements
to the DM device that failed to load may be left in place.  Complete
clean-up will require tracking those devices which have been created
as dependencies and removing them along with the device that failed
to load a table.
2014-05-28 10:17:15 -05:00
8212dac849 tests: rename test 2014-05-28 15:41:06 +02:00
2adaef8272 revert: restore original timeout
Accidently it's been commited - but it has also shown,
that on heavy loaded systems (like our test machine could be)
slightly bigger timeouts which waits longer for udev rules
processing does help and avoids occasional refuse of deactivation
because device is still being open.
(i.e. lvcreate...; lvchange -an...)

Unsure how we could now synchronize for this. On very slow(/loaded)
system 5 second timeout is simply not enough.

TODO: introduce at least lvm.conf configurable setting to
allow longer 'retry' loops.
2014-05-28 15:33:41 +02:00
171a668e81 tests: dd needs to hit disk
Unsure if this is feature or bug of syncaction,
but it needs to be present physically on the media
and it ignores content of buffer cache...

(maybe lvchange should implicitely fsync all disks
that are members of raid array before starting test??)
2014-05-28 15:33:41 +02:00
ba3e6e7c32 tests: raid syncaction activation race
Demonstrace problem of syncaction being called right after activation.
2014-05-28 15:33:41 +02:00
a67774c1fa tests: detect same uuid on PV
Check we know how to handle same UUID
Test  currently does NOT work on lvmetad
(or it's unclear it even should - thus test error
is currently lowered to 'test warning')

TODO: replace lib/test with a better shell script name
2014-05-27 17:09:05 +02:00
9240aca369 raid: cleanup error messages
Add log_error messages on error paths.
2014-05-27 17:08:49 +02:00
ae43d1afa2 activate: cleanup lv_check_not_in_use
Reindent lv_check_not_in_use to simplify internal loop code.
Also return always '0/1'  (drop -1) - since we only
check for failure (0) - and we don't really know
why  lv_info() has failed.
2014-05-27 17:08:49 +02:00
1569e7a498 udev: also print subsystem udev flags in debug message about udev flags + fix typo DM_SUBSSYTEM_UDEV_FLAG7 -> DM_SUBSYSTEM_UDEV_FLAG7 2014-05-27 14:44:11 +02:00
b3539907f5 tests: support thin_restore configurable
Currently this tool is used only in tests.
2014-05-26 23:30:09 +02:00
b0ff3359f2 tests: update aux disable_dev
disable_dev can't use transaction - since it may lead occasionaly to
weird error - example could be nomda-missing.sh test case.
Here occasionaly device instead of being removed was left as
error device and testing different code path (which is unfortunatelly
buggy)

When we want to test 'error' device -  'aux error_dev()' should be used.
2014-05-26 22:57:28 +02:00
49521f4e56 cleanup: internal error for impossible path
Add 'default' path for impossible execution code path.
2014-05-26 22:57:28 +02:00
965592340d man: cleanup dmsetup
Add few bold texts.
2014-05-26 22:57:20 +02:00
3cb2658fb7 dmsetup: add warning
Warn when --udevcookie/DM_UDEV_COOKIE is used with 'dmsetup remove --force'.

When command is doing multiple ioctl operations on a single device,
it may invoke udev activity, that is colliding with further ioctl commands.
The result of such operation becomes unpredictable.
Use of --retry could partially help...
2014-05-26 22:56:30 +02:00
6e9105c7bb cleanup: use const for endptr in dm_units_to_factor 2014-05-26 12:09:01 +02:00
cfe18d85c1 tests: improve command coverage 2014-05-23 23:35:42 +02:00
b7476e91ef tests: add unusable kernel for raid5 testing 2014-05-23 23:35:42 +02:00
c5c3995ed5 tests: increase min version for raid testing
Seems smaller version are causing weird kernel lookups.
2014-05-23 23:35:42 +02:00
3f8048f28c vgextend: allow --yes to skip prompt 2014-05-23 23:35:40 +02:00
1a84032322 cleanup: indent 2014-05-23 21:37:12 +02:00
bf6b69c46b cleanup: use directly segtype->name
Simplify printing of segtype name.
2014-05-23 21:36:55 +02:00
952514611d cleanup: add seg_is_pool macro
Simplify code querying for pool segtype.
2014-05-23 21:36:55 +02:00
cb7bba9ffe dev_manager: disable extra udev loop
Disable code which has postprocessed whole tree and reset udev flags.
We need to find out which case was troublesome - since this loop
was just hidding bug in other code parts (most probably preload tree)
2014-05-23 21:36:55 +02:00
ec9da34d86 tests: check more things with vgchange 2014-05-22 12:01:44 +02:00
65b0948c1e tests: swap tests 2014-05-22 12:01:44 +02:00
1208e92b34 tests: add check vg_attr_bit
Similar function like  'check lv_attr_bit'
2014-05-22 12:01:44 +02:00
406ce3760b tests: detect raid presence 2014-05-22 12:01:44 +02:00
496953fb39 cleanup: use y/n instead of y|n
Use same for of yes no query everywhere.
2014-05-22 12:01:43 +02:00
1c4fe47308 lvm_init: don't use name mangling for LVM
LVM has restricter character set that is allowed for VG-LV names
and the dm names constructed do not contain any blacklisted characters
that would require name mangling.

Also, when any other device-mapper device is scanned that could
possibly contain such blacklisted characters, we reference the
device by its major:minor instead of dm name (e.g. _device_is_usable fn).
2014-05-22 10:00:19 +02:00
b2da0f0a5b tests: raid and dmeventd 2014-05-21 23:14:42 +02:00
37b4dc7775 tests: more pvchange tests 2014-05-21 23:14:42 +02:00
79f4665243 tests: more vgcfgrestore testing
Check '-l' and archiving.
2014-05-21 23:14:41 +02:00
a4ac21aded cleanup: make error message more readable 2014-05-21 23:14:41 +02:00
aafd7c878c cleanup: indent 2014-05-21 23:14:41 +02:00
3ac7d2deb4 vgcfgrestore: return invalid cmd line
When error is detected on command line options, return '3'.
2014-05-21 23:14:41 +02:00
9c4953df1b tests: restore disable_dev behavior
Notify needs to go  with major:minor before device disappears.
2014-05-21 16:59:38 +02:00
8db67d2aff tests: skips on unsupported systems 2014-05-21 16:48:06 +02:00
092659644a man: missing space between option name and value name 2014-05-21 15:51:28 +02:00
e78092fa3a man: more man page updates for --commandprofile and --metadataprofile split 2014-05-21 14:53:56 +02:00
b7431f69ed man: update lvm.conf man page for latest changes 2014-05-21 13:25:09 +02:00
23f9c45a1b profiles: remove default.profile and add {command,metadata}_profile_template.profile
The "default.profile" name was misleading. It's actually a helper
*template* that can be used for copying and further editing to create
a new profile.

Also, we have separate command and metadata profiles now so the templates
are separated as well - we can't mix profile settings from one group with
another - such profile is rejected by lvm tools.
2014-05-21 12:36:52 +02:00
c34c33d9ba tests: notify loop needs maj:min
Missed in previous commit.
2014-05-21 12:00:32 +02:00
cbdb8fa589 tests: notify lvmetad after udev transation
Delay udev notification after the point udev transaction
is finished - since otherwise some device may still
be found missing until udev transaction is finished.
2014-05-21 11:43:24 +02:00
97c91b020e man: update dumpconfig man page for latest changes 2014-05-21 11:01:19 +02:00
1ddc68ccd7 man: call installers only when there are set vars.
When MAN7, MAN8CLUSTER or MAN8SYSTEMD_GENERATORS would be empty,
don't call respective INSTALL tools.
On older systems they even generate error causing abort
of makefile target.
2014-05-21 10:52:33 +02:00
fca77a1ea4 cleanup: remove duplicate --commandprofile reference in dumpconfig's help string 2014-05-21 10:30:02 +02:00
e9db11f387 systemd: use umask 022 for generated systemd units by lvm2-activation-generator 2014-05-21 10:12:02 +02:00
7d7c1f2025 systemd: install lvm2-cluster-activation script as executable 2014-05-21 09:45:29 +02:00
b57b4db889 tests: checking mirror_remove_missing
FIXME:

Seems like conversion of log is not supported in clustered VG
and needs to be fixed.
2014-05-20 22:50:52 +02:00
f919a255b7 tests: lvconvert needs --yes 2014-05-20 22:50:33 +02:00
e538354e28 spec: configurable cache build
Install lvmcache man page when being configured with cache support.
Install lvmthin man page only with thin support.
2014-05-20 21:50:30 +02:00
08fd244506 tests: rebuild paths when Makefile is updated 2014-05-20 21:50:30 +02:00
2e9792121f tests: add have_cache and have_raid
Need to be aware of build options, when system would be
configure without raid or cache support
2014-05-20 21:50:30 +02:00
7f92c3a13e tests: wait before down-convert 2014-05-20 21:50:29 +02:00
205be24768 tests: update lvconvert test
Split raid test to separate file
Add --yes flag to automated testing
2014-05-20 21:50:29 +02:00
16424fed54 thin: improve lvconvert messages
Add more info into printed message.
2014-05-20 21:50:29 +02:00
d1d50d4023 cleanup: use print when displaying info
Use error or warn only when we really have some problem in the code.
2014-05-20 21:50:29 +02:00
54184f92ac cleanup: indent 2014-05-20 21:50:28 +02:00
2941cffd2c cleanup: unneeded initialization
Move or drop initialization where it is not needed.
2014-05-20 21:50:28 +02:00
65b3fe9b05 man: cleanup style 2014-05-20 21:50:28 +02:00
9fd0be2a85 debug: fix backtracing 2014-05-20 21:50:28 +02:00
c70c100cce lvconvert: check ret code of mirror_remove_missing
When mirror_remove_missing() fails, stop repairing mirror.
2014-05-20 21:49:42 +02:00
bbf4b2c1c9 thin: lvconvert warn before conversion
Warn user before converting volume to different type.

  WARNING: Converting vg/lvol0 logical volume to pool's meta/data volume.
  THIS WILL DESTROY CONTENT OF LOGICAL VOLUME (filesystem etc.)

Since the content of volume is lost we have to query user to confirm
such operation.  If user is 100% sure, he may use '--yes' to avoid prompts.
2014-05-20 21:48:47 +02:00
83f468be4e tests: update profiles.sh test for latest changes 2014-05-20 16:27:09 +02:00
9c937e7d54 dumpconfig: add --type profilable-command/profilable-metadata, --metadataprofile/--commandprofile
The dumpconfig now understands --commandprofile/--profile/--metadataprofile

The --commandprofile and --profile functionality is almost the same
with only one difference and that is that the --profile is just used
for dumping the content, it's not applied for the command itself
(while the --commandprofile profile is applied like it is done for
any other LVM command).

We also allow --metadataprofile for dumpconfig - dumpconfig *does not*
touch VG/LV and metadata in any way so it's OK to use it here (just for
dumping the content, checking the profile validity etc.).

The validity of the profile can be checked with:
      dumpconfig --commandprofile/--profile/--metadataprofile --validate

...depending on the profile type.

Also, mention --config in the dumpconfig help string so users know
that  dumpconfig handles this too (it did even before, but it was not
documented in the help string).
2014-05-20 16:27:07 +02:00
9e3e4d6994 config: differentiate command and metadata profiles and consolidate profile handling code
- When defining configuration source, the code now uses separate
  CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers
  (before, it was just CONFIG_PROFILE that did not make the
  difference between the two). This helps when checking the
  configuration if it contains correct set of options which
  are all in either command-profilable or metadata-profilable
  group without mixing these groups together - so it's a firm
  distinction. The "command profile" can't contain
  "metadata profile" and vice versa! This is strictly checked
  and if the settings are mixed, such profile is rejected and
  it's not used. So in the end, the CONFIG_PROFILE_COMMAND
  set of options and CONFIG_PROFILE_METADATA are mutually exclusive
  sets.

- Marking configuration with one or the other marker will also
  determine the way these configuration sources are positioned
  in the configuration cascade which is now:

  CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES

- Marking configuration with one or the other marker will also make
  it possible to issue a command context refresh (will be probably
  a part of a future patch) if needed for settings in global profile
  set. For settings in metadata profile set this is impossible since
  we can't refresh cmd context in the middle of reading VG/LV metadata
  and for each VG/LV separately because each VG/LV can have a different
  metadata profile assinged and it's not possible to change these
  settings at this level.

- When command profile is incorrect, it's rejected *and also* the
  command exits immediately - the profile *must* be correct for the
  command that was run with a profile to be executed. Before this
  patch, when the profile was found incorrect, there was just the
  warning message and the command continued without profile applied.
  But it's more correct to exit immediately in this case.

- When metadata profile is incorrect, we reject it during command
  runtime (as we know the profile name from metadata and not early
  from command line as it is in case of command profiles) and we
  *do continue* with the command as we're in the middle of operation.
  Also, the metadata profile is applied directly and on the fly on
  find_config_tree_* fn call and even if the metadata profile is
  found incorrect, we still need to return the non-profiled value
  as found in the other configuration provided or default value.
  To exit immediately even in this case, we'd need to refactor
  existing find_config_tree_* fns so they can return error. Currently,
  these fns return only config values (which end up with default
  values in the end if the config is not found).

- To check the profile validity before use to be sure it's correct,
  one can use :

    lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate

  (the --commandprofile/--metadataprofile for dumpconfig will come
   as part of the subsequent patch)

- This patch also adds a reference to --commandprofile and
  --metadataprofile in the cmd help string (which was missing before
  for the --profile for some commands). We do not mention --profile
  now as people should use --commandprofile or --metadataprofile
  directly. However, the --profile is still supported for backward
  compatibility and it's translated as:

    --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange
                 (as these commands are able to attach profile to metadata)

    --profile == --commandprofile for all the other commands
                (--metadataprofile is not allowed there as it makes no sense)

- This patch also contains some cleanups to make the code handling
  the profiles more readable...
2014-05-20 16:21:48 +02:00
c5fbd2c59f config: add CFG_PROFILABLE_METADATA flag
Mark profilable settings with a separate CFG_PROFILABLE_METADATA
flag where the profile can be attached to VG/LV. This makes it possible
to differentiate global command-profilable settings (CFG_PROFILABLE flag)
and contextual metadata-profilable (per VG/LV) settings (CFG_PROFILABLE_METADATA flag).
2014-05-19 16:31:15 +02:00
22cab9c481 commands: do not register profile_ARG for lvcreate/lvchange separetely
The --profile is globally available for all commands.
2014-05-19 16:30:49 +02:00
24f32721a9 dumpconfig: fix dumpconfig --type diff used in lvm shell as second and later command
The dumpconfig reuses existing config_def_check results in case
the check is done during general lvm command context initialization
(when enabled by config/checks=1) so dumpconfig does not need to run
the same check again during its execution, hence saving some time.

However, we don't check for differences from defaults during general
lvm command initialization as it's useless at that time. It makes
sense only in case when such a check is directly requested (like in
the case of lvm dumpconfig --type diff). We need to take care that
the reused information was already produced with this "diff" checking
before and if not, we need to force the check so the check status also
gathers the new "diff" info now.

Also, do not do diff checking for any other dumpconfig command that
is run after dumpconfig --type diff.
2014-05-19 15:41:25 +02:00
9a324df3b3 config: fix incorrect profile initialization on cmd context refresh
When cmd refresh is called, we need to move any already loaded profiles
to profiles_to_load list which will cause their reload on subsequent
use. In addition to that, we need to take into account any change
in config/profile configuration setting on cmd context refresh
since this setting could be overriden with --config.

Also, when running commands in the shell, we need to remove the
global profile used from the configuration cascade so the profile
is not incorrectly reused next time when the --profile option is
not specified anymore for the next command in the shell.

This bug only affected profile specified by --profile cmd line
arg, not profiles referenced from LVM metadata.
2014-05-19 15:39:55 +02:00
c42f72867a config: attach cft_check_handle to each config tree instead of global cmd_context
Before, the cft_check_handle used to direct configuration checking
was part of cmd_context. It's better to attach this as part of the
exact config tree against which the check is done. This patch moves
the cft_check_handle out of cmd_context and it attaches it to the
config tree directly as dm_config_tree->custom->config_source->check_handle.

This change makes it easier to track the config tree check results
and provides less space for bugs as the results are directly attached
to the tree and we don't need to be cautious whether the global value
is correct or not (and whether it needs reinitialization) as it was
in the case when the cft_check_handle was part of cmd_context.
2014-05-19 15:38:04 +02:00
ff9d27a1c7 config: add CONFIG_FILE_SPECIAL config source id
Add CONFIG_FILE_SPECIAL config source id to make a difference between
real configuration tree (like lvm.conf and tag configs) and special purpose
configuration tree (like LVM metadata, persistent filter).

This makes it easier to attach correct customized data to the config
tree that is created out of the source then.
2014-05-19 15:37:41 +02:00
ecccb75904 tests: drop nosync
Mirrors currently do not support any conversion,
when they are created no-sync.
2014-05-19 13:22:46 +02:00
477351fc4d man: lvmcache
separate man page for lvm cache
2014-05-18 20:09:47 +02:00
91284bd9b9 cleanup: device extent_size first 2014-05-18 20:08:07 +02:00
58777756e8 debug: backtrace error path
Add backtrace for 'n' answer.
2014-05-18 20:07:24 +02:00
b73a786755 man: lvmcache
Migrate cache description into  man(7) entry
(like lvmthin).
2014-05-15 12:13:24 +02:00
11bedf1baf display: print skipped prompt
Since decisions in the silent mode may not be always obvious,
print skipped prompt with answer 'n'.

Also document  '-qq' behaviour (single -q only shuts
logging, while -qq sets silent mode).
2014-05-15 12:11:35 +02:00
76c06c7252 tests: speedup
Avoid some expencive raid/mirror synchronization when testing
just allocation sizes.
Use lv_attr_bit
2014-05-15 12:08:35 +02:00
309201a53b man:misc updates 2014-05-15 12:08:35 +02:00
7c86131233 report: export DM_REPORT_FIELD_RESERVED_NAME_{HELP,HELP_ALT} and show help on '<lvm_command> -O help'
Share DM_REPORT_FIELD_RESERVED_NAME_{HELP,HELP_ALT} between libdm and
any libdm user to handle reserved field names, in this case the virtual
field name to show help instead of failing on unrecognized field.
The libdm user also needs to check the field name so it can fire
proper code in this case (cleanup, exit etc.).
2014-05-15 10:58:14 +02:00
5684cfcb1c report: Add metadata_percent to lvs_cols. 2014-05-15 08:32:27 +01:00
42d7409da2 man: lvmthin cover snapshot merge and xfs
also fix a couple inconsistent example values.
2014-05-14 15:15:35 -05:00
044b796800 man: more lvmthin discard references
and some fixes from Tom.
2014-05-14 15:15:35 -05:00
3b989e317f allocation: Fix alloc anywhere with parity.
Take account of parity areas with alloc anywhere in
_calc_required_extents.  Extents beyond area_count were treated
incorrectly as mirror logs.
2014-05-14 16:25:43 +01:00
422b3b0fb5 man: Fix man7 dir dependency.
https://bugs.gentoo.org/510202
2014-05-13 11:18:13 +01:00
85cf5a23d2 cleanup: improve error message
Update impossile to happen error message.
2014-05-13 10:33:17 +02:00
7b766b0648 tests: updates
Move thin test out of listing.
2014-05-13 10:28:55 +02:00
6f057e3c66 tests: replance hostname call 2014-05-12 16:24:40 +02:00
c07fb7678e cleanup: drop unused header 2014-05-12 16:24:40 +02:00
506ade802b cleanup: cast int to typedef 2014-05-12 16:24:40 +02:00
90c44f5371 conf: document new thin_check option 2014-05-12 16:24:40 +02:00
8b95c82fed coverity: catch unwanted path
We validate this path already earlier.
2014-05-12 16:24:39 +02:00
2e1192f691 configure: improve needs_check thin_check test
Improve testing for needs_check - when old tools are installed,
issue proper warning from configure, but stop sending needs_check
flag to the old tool.
2014-05-12 16:24:39 +02:00
5b787a24f0 configure: drop siginterrupt
Not used anymore
2014-05-12 16:24:39 +02:00
e416d84e10 cleanup: use enum return codes 2014-05-07 14:17:46 +02:00
2cc02c570e cleanup: constify pointers 2014-05-07 14:17:46 +02:00
9845f8c767 clenaup: drop unused assigns 2014-05-07 14:17:46 +02:00
9bccaf7ae4 cleanup: missed conversion to dm_malloc/free usage
Few missed unconverted dm_malloc/free calls.
2014-05-07 14:17:46 +02:00
d3e68c8a71 cleanup: cosmetics.
Initialized attrs so analyzers are less confused
(since currently our method calls should always initialize attrs on
return).
2014-05-07 14:17:46 +02:00
d88fab8d3a cleanup: drop uneeded headers 2014-05-07 14:17:45 +02:00
bcd6deea18 coverity: ignore ret val
Since we intentionaly do not want to check them,
cast result values to void.
2014-05-07 14:17:12 +02:00
d11617864a coverity: error for undefined origin
If we would have been missing origin here, it would
be an internal error - since these values are validated
earlier.
2014-05-07 14:16:18 +02:00
a8042f33d0 coverity: check for profile
Ensure str is not NULL for analyzer.
2014-05-07 14:15:52 +02:00
48a8cf28f7 cache: avoid expression overflow
Cast data_extents to 64bit so calculation is in 64b arithmetic.
2014-05-07 14:14:54 +02:00
e585a6bbcf signals: better nesting support
Support upto 3 levels os nesting signal blocking.
As of today - code blocks signals immediatelly when it opens
VG in read-write mode - this however makes current prompt usage
then partially unusable since user may not 'break' command
during prompt (something most user would expect).

Until a better fix for prompting is implemented, put in support
for signal nesting - thus when prompt enables signal acceptance,
make it possible to really break command at this point.
2014-05-07 14:09:33 +02:00
31ac200a37 debug: add more debug message for signal handling
Adding log_sys_debug for eventual logging of system errors.
(Using debug level, since currently signal handling functions
do not fail when any error is encoutered).
2014-05-07 14:07:13 +02:00
04b29a3587 locking: use sigaction signal handling
Use sigint_allow/restore function instead of duplicating code
and switch to use only sigactiction based signal handling.
2014-05-07 14:01:13 +02:00
9d64573da1 make: fix commit 1756bf6
"DIST_TARGET" should be "DISTCLEAN_TARGET"
2014-05-07 12:13:36 +02:00
1899783aa6 cleanup: fix compiler warning
locking/file_locking.c:162:2: warning: implicit declaration of function ‘init_signals’
2014-05-06 14:38:38 +02:00
8b49d61d83 logging: Add LCK_REVERT_MODE to flags printed by decode_flags()
The decode_flags() function does not yet know about the
LCK_REVERT_MODE flag.
2014-05-05 14:30:09 -05:00
09064cc2db signals: Add init_signals. 2014-05-01 20:31:19 +01:00
2eed136f0f signals: Move sigint handling out to lvm-signal. 2014-05-01 20:07:17 +01:00
29a3fbf067 locking: Separate out flock and signal code. 2014-05-01 17:37:14 +01:00
239ba5bb04 systemd: use lvm binary insetad of command symlink in lvm2-pvscan.service 2014-04-30 15:21:25 +02:00
81b096af34 systemd: make sysinit.target to pull in lvm2-lvmetad.socket, not sockets.target
The sysinit.target is ordered even before sockets.target and there
may be situations in which the lvmetad is needed early, for example
in rescue.target to activate some LVs on which mountpoints reside.
Also, like in the case of rescue.target, the sockets.target is not
pulled in (unless some other service pulls it in explicitly).

See also: https://bugzilla.redhat.com/show_bug.cgi?id=1087586#c26
for the summary of the problem.
2014-04-30 14:52:10 +02:00
4e559103d5 tests: lets the test continue
unwanted start of dmeventd was caused by seg_monitor status.
2014-04-30 10:26:31 +02:00
9401827919 cleanup: modules_needed only for devmapper
Drop compilation of modules_needed and add_target_lin
function when compiled without devmapper support.
Cleanup surrounding ifdefs.
2014-04-30 10:26:30 +02:00
62e8dd4f6e cleanup: indent 2014-04-30 10:26:30 +02:00
cbdf63fdd2 cleanup: indent in devmapper-event
Drop header inclusion - this file is already included.
Shorten code.
2014-04-30 10:26:30 +02:00
b56aef1915 unknown: add_target_line is not needed
Leave addition of unknown segment to table as internal error.
Do not replace unknown segment with error device.
2014-04-30 10:26:30 +02:00
1756bf6c63 makefile: fix regression
Commit 1af05a7a16 was incorrect.
Generated files from configure could be only distclean-ed.
(in-release fix)
2014-04-30 10:26:29 +02:00
62ad6dee18 lv: show X attr when lv_info fails
Print 'X' also when lv_info() fails.
(i.e. compilation with --disable-ioctl)
2014-04-30 10:26:29 +02:00
816cc94ac1 devmapper-event: always initialize timeout
Always pass fully initialized timeval struct to select.
2014-04-30 10:26:29 +02:00
675fcfe9b7 devmapper: fix compilation without devmapper
Fix compilation when configured with --disable-devmapper option.
2014-04-30 10:26:29 +02:00
905d4cda7a libdm: cleanup complation without DM_IOCTLS 2014-04-30 10:26:29 +02:00
ad77fb50bd configure: corrected ioctl option
The correct name for disable ioctl option is --disable-ioctl
(--disable-driver never worked)
Also sort scripts generated files alphabetically.
2014-04-30 10:26:28 +02:00
517b002648 display: check for dmeventd support
When quering for dmeventd monitoring status, check first
if lvm2 is configured to monitor to avoid unwanted start
of dmeventd process for answering monitoring status.
2014-04-30 10:26:26 +02:00
b1f765d72a pvremove: Catch CTRL-c during prompts. 2014-04-29 08:16:28 +01:00
26989e0cd7 tests: improve coverage
Test more code paths for lvscan & lvdisplay
2014-04-28 12:42:57 +02:00
d8214cb154 cleanup: put all tests within switch
No reason to check for VALID in extra if.
2014-04-28 12:42:56 +02:00
d1aba7ccf6 lvscan: drop test for snapshosts
When showing  ACTIVE status for snapshot's origin,
avoid testing all its snapshot - it's not useful
to tell user origin is inactivate, while it's clearly
available and running - just one of its snapshot leg
is invalid...
2014-04-28 12:42:53 +02:00
4c405a9b49 thin: move segment info display to correct code section
Relocate info from thin pool and thin volume segments
to proper code section for segments.
Add discards and thin count status info.

Info is shown with  'lvdisplay --maps' (like for other segments).
2014-04-28 12:41:25 +02:00
71314a9905 thin: display info when -tpool is running
For percentage display we need -tpool - so check for layered
device presence here instead of plain pool device.
Also update 'info' - so when pool is 'available' we
display open count for -tpool device instead of mostly
irrelevant pool.
TODO: Maybe we should actually display this open info always?
(even when just -tpool is available, but pool is not)
2014-04-28 12:40:17 +02:00
91a8e4a3d8 display: show monitoring status
When displaying segments  (lvdisplay --maps)
show monitoring status when supported by segment.
2014-04-28 12:39:03 +02:00
e6168b8d70 display: use Virtual for virtual LV
Emphesize virtual extents for virtual LVs and for
those use  'Virtual extents' instead of 'Logical extents',
so it's immeditatelly visible, which extents do have
straighforward physical backend.
2014-04-28 12:37:50 +02:00
5b28cbd7c2 cleanup: _move_pv is static
metadata/metadata.c:363:5: warning: no previous prototype for '_move_pv' [-Wmissing-prototypes]
2014-04-28 12:11:44 +02:00
4360fdf89c libdevmapper: add dm_units_to_factor for size unit parsing
Actually moving the existing code from LVM to libdm for reuse.
2014-04-28 10:25:43 +02:00
75d399800a NIX: Use VM images with the correct root module list. 2014-04-26 13:46:25 +02:00
3bce3ad52a test: Add the new vgsplit RAID test file forgotten in the last commit 2014-04-25 16:59:09 -05:00
c671be434c test: Move the RAID vgsplit test into a separate file 2014-04-25 16:57:43 -05:00
3c4234f825 vgsplit: Make RAID 4/5/6 fail cleanly when too few PV specified
While the 'raid1/10' segment types were being handled inadvertently
by '_move_mirrors()', the parity RAIDs were not being properly checked
to ensure that the user had specified all necessary PVs when moving
them.  Thus, internal errors were being triggered when only part of
a RAID LV was moved to the new VG.  I've added a new function,
'_move_raid()', which properly checks over any affected RAID LVs and
ensures that all the necessary PVs are being moved.
2014-04-25 16:24:50 -05:00
4dffb9fca9 test/vgsplit-operation.sh: Add vgsplit tests for RAID
vgsplit of RAID volumes was problematic because the metadata area
and data areas were always on the same PVs.  This problem is similar
to one that was just fixed for mirrors that had log and images sharing
a PV (commit 9ac858f).  We can now add RAID LVs to the tests for
vgsplit.

Note that there still seems to be an issue when specifying an
incomplete set of PVs when moving RAID LVs.
2014-04-25 16:22:40 -05:00
76687f4cac WHATS_NEW: Add message for commit 9ac858f
WHATS_NEW for commit:
9ac858f vgsplit: Make vgsplit work on mirrors with leg and log on same PV
2014-04-25 14:55:32 -05:00
9ac858fe6b vgsplit: Make vgsplit work on mirrors with leg and log on same PV
Given a named mirror LV, vgsplit will look for the PVs that compose it
and move them to a new VG.  It does this by first looking at the log
and then the legs.  If the log is on the same device as one of the mirror
images, a problem occurs.  This is because the PV is moved to the new VG
as the log is processed and thus cannot be found in the current VG when
the image is processed.  The solution is to check and see if the PV we are
looking for has already been moved to the new VG.  If so, it is not an
error.
2014-04-25 14:53:34 -05:00
0ee9d59b48 test: configurable write timeout
Hard-coded 3 minutes is far too short when investigating problems.
2014-04-24 22:44:22 +01:00
448af9ff0b NIX: Fix failure mode for "make check". 2014-04-24 21:35:31 +02:00
9676ee9ba9 test: Fix default.profile path.
It's a generated file.
2014-04-24 18:52:29 +01:00
22037ee328 tests: fix creation of scsi debug
Use proper '||' test form to avoid unwanted test abort
on failure.
(i.e. running failing test profiles-thin.sh on a real /dev)
2014-04-24 14:42:27 +02:00
8e8a47143f config: use devices/ignore_suspended_devices=0 by default
ignore_suspended_devices=0 is already used in lvm.conf we distribute,
but it was still "1" in the code (so it was used when lvm.conf value
was not defined). It should be "0" too.
2014-04-24 12:12:39 +02:00
2b09def606 man: minor fixes in lvmetad man page
- better add reference to lvm dumpconfig --type default
   than stating that lvmetad is not enabled by default
 - substitute #DEFAULT_PID_DIR# with concrete value
2014-04-23 14:34:42 +02:00
795944f178 test: add lvresize tests
- test for Bug 1088153
- test lvextend does not reduce nor lvreduce extend LV
2014-04-22 12:53:30 +02:00
7a1777302f cleanup: dmeventd simplify restart message parsing
Since we already check every characted in the message,
skip extra callback to strlen, and do the implicit
message length checking.
2014-04-18 16:53:29 +02:00
1f701c7bf6 cleanup: dmeventd drop setting of size
Size is not used when msg->data is NULL.
2014-04-18 16:52:59 +02:00
78c6dea48e cleanup: dmeventd improve _handle_request
Let the compiler resolve cmd lookup and leave it to optimize it as it
needs.
2014-04-18 16:52:45 +02:00
0927605ec3 cleanup: dmeventd improve _clien_write code
Switch to allocate buffer from heap, since it might be potentially
bigger when extremaly large set of volumes would be monitored.
In case of allocation failure send ENOMEM message.
Also implicitelly ignore msg->size when msg->data is NULL.
2014-04-18 16:52:35 +02:00
3febd2c9d4 cleanup: dmeventd set next_time when registering
Don't change next_time, when thread is already registered.
2014-04-18 16:52:11 +02:00
dc21bbfabd cleanup: dmeventd improve _get_status
Use directly dm_asprintf() to allocate buffer with message,
and properly detect failing on replacement of snprintf()
which also returns -1 on error.
2014-04-18 16:51:54 +02:00
0503af8466 cleanup: dmeventd simplify buffer write loop 2014-04-18 16:50:55 +02:00
13d05211d0 cleanup: dmeventd simplify status processing
Since we always know the string length, use simplier memcpy.
2014-04-18 16:38:52 +02:00
4fb588c34e cleanup: dmeventd reorder _fill_device_data
Just simplify the function.
2014-04-18 16:38:51 +02:00
6b701c3a48 cleanup: dmeventd abstract lvm2cmd interface
Keep  lvm2cmd  interface hidden inside dmeventd_lvm
and use regular 1/0 return codes, this we may
avoid using lvm2cmd.h in other lvm2 plugins.
2014-04-18 16:38:51 +02:00
6448428d05 cleanup: add some comment indents...
Just cleanup things
2014-04-18 16:38:51 +02:00
91eb8927fd cleanup: skip zeroing of cleared areas
Zalloc mem is already zeroed.
2014-04-18 16:38:51 +02:00
20179523e2 cleanup: set _REENTRANT in header
Use same way of setting _REENTRANT as in other
files - set it in the first included header file
(clvmd-common.h)
2014-04-18 16:38:50 +02:00
451a168bf8 cleanup: drop inclusion of devmap - merge 2014-04-18 16:38:50 +02:00
559c003ee2 cleanup: reduce inclusion of unnecessary headers
Remove those file which are not needed by .c files
or already include because the headers already needs them.
2014-04-18 16:38:50 +02:00
589983a257 cleanup: include stdarg.h where needed.
Avoid dependency on implicit inclusion of stdarg.h with
libdevmapper.h.
2014-04-18 16:38:50 +02:00
b7741f0a83 libdaemon: header cleanup
Ensure  daemon-io.h is used as a generic header included
with configure defines before other headers.
(In future all lvm2 libraries should settle on a single lib.h header)
Rename couple defines to better match header file names.
2014-04-18 16:38:49 +02:00
e552824dc0 makefiles: move subdir into same section
Just shift few lines
2014-04-18 16:38:49 +02:00
07274f3dd4 makefiles: drop linking of deamon libs to plugins
Daemon lib is linked into lvm2cmd library.
2014-04-18 16:38:49 +02:00
2b748e3118 makefiles: compile files on make
Make install should install already compiled/generated files.
2014-04-18 16:38:49 +02:00
1af05a7a16 makefiles: clear targets in with make clean
Make clean usually cleans all compiled files.
Make distclean cleans configure generated files
2014-04-18 16:38:48 +02:00
4955dae4be makefiles: wait till include is populated
Since libdaemon needs configure.h header, wait forl links.
2014-04-18 16:38:48 +02:00
db0045dfc9 devmapper-event: always initialize timeout
Before calling select, always set all struct members of timeout.
2014-04-18 16:38:48 +02:00
08e7de986c dmeventd: check for list size within lock
Move check for _thread_registry list size behind mutex.
Use alloca() instead of buffer[count] (they are the same anyway)
2014-04-18 16:38:48 +02:00
0e05e1cf6c asprintf: fix test for error result
On error this function returns -1. Since the functions however
do not propagate error upward, it's rather cleanup change.
2014-04-18 16:38:47 +02:00
0b6d6bfb77 thin: dmeventd plugins support more minors
Kernel supports upto 1M (20bit) minors.
TODO: convert to hash to reduce memory requirements
2014-04-18 16:38:47 +02:00
47a60369a0 unknown: fix mempool used for name allocation
Use cmd libmem mempool for name allocation, since mem mempool
is released after each clvmd command.
2014-04-18 16:38:47 +02:00
b5f8f452ac tools: Add --readonly support.
Offer lock-free access to display virtual machine or clustered VG metadata
while it might be in use.
2014-04-18 02:46:34 +01:00
17e304e0ac metadata: Fix unlock on VG recovery error path.
If lock conversion failed it tried to unlock VG that was no longer locked.
2014-04-18 02:27:16 +01:00
177ece01a9 reports: Use X for unknown LV attr when no dm.
It's safer not to tell people an LV is inactive when we aren't sure.
2014-04-18 02:23:39 +01:00
e8a3ba1865 pvscan: Use lvmetad_used().
Config variables that are processed during setup prior to calling into
particular tools must not be accessed directly afterwards in case the
values already got overridden.

_process_config() already used the tests I'm removing here to call
lvmetad_set_active() and set up lvmetad_used().
2014-04-18 02:13:46 +01:00
702180b30c configure: use configure's --enable-udev-systemd-background-jobs by default
This should be the preferred way of configuring lvm2 for udev/systemd
since otherwise one can end up with the processes run from udev (the
pvscan we run for lvmetad update on events) to be killed prematurely
and this can end up with LVM volumes not activated in the end.
2014-04-16 11:33:44 +02:00
18caa562fe lvmdump: list also inactive units for lvmdump -s 2014-04-15 15:43:20 +02:00
a6763c64a7 lvmdump: add -s to gather system info and context (currently systemd-related only)
This is sort of info we always ask people to retrieve when
inspecting problems in systemd environment so let's have this
as part of lvmdump directly.

The -s option does not need to be bound to systemd only. We could
add support for initscripts or any other system-wide/service tracking
info that can help us with debugging problems.
2014-04-15 15:27:30 +02:00
704609b17e profiles: comment out thin_pool_chunk_size in default.profile
By default, the thin_pool_chunk_size is automatically calculated.
When defined, it disables the automatic calculation. So to be more
precise here, we should comment it out for the default.profile.

Also, "lvm dumpconfig --type profilable" was used here to generate
the default.profile content. This will be done automatically in the
future once we have the infrastructure for this in (see also
https://bugzilla.redhat.com/show_bug.cgi?id=1073415).
2014-04-15 10:15:38 +02:00
8980592514 alloc: Correct existing use of positional fill.
Perform two allocation attempts with cling if maximise_cling is set,
first with then without positional fill.

Avoid segfaults from confusion between positional and sorted sequential
allocation when number of stripes varies as reported here:
https://www.redhat.com/archives/linux-lvm/2014-March/msg00001.html
2014-04-15 02:34:35 +01:00
1bf4c3a1fa alloc: Introduce A_POSITIONAL_FILL.
Set A_POSITIONAL_FILL if the array of areas is being filled
positionally (with a slot corresponding to each 'leg') rather
than sequentially (with all suitable areas found, to be sorted
and selected from).
2014-04-15 01:13:47 +01:00
c9a8264b8b alloc: Access alloc_parms from alloc_state.
alloc_parms is constant while allocating.
2014-04-15 01:05:34 +01:00
3c82a37aee tests: correct test condition
Abort loop when PIDFILE is gone
2014-04-14 14:55:14 +02:00
92ee51a4c3 tests: check there is really pvmove lv
Since the kill may take various amount of time,
(especially when running with valgrind)
check it's really pvmoved LV.

Restore initial restart of clvmd - it's currently
broken at various moments - basically killed lvm2
command may leave clvmd and confusing state leading
to reports of internal errors.
2014-04-14 13:02:28 +02:00
4d48577ab9 tests: implement lv_attr_bit
Add easy check function for cheking lv_attr bits
2014-04-14 13:02:28 +02:00
1d803ee980 cleanup: corrent indent level 2014-04-14 13:02:28 +02:00
d896abc705 cleanup: clvmd drop unused enum state 2014-04-14 13:02:27 +02:00
e2f194952a cleanup: clvmd reindent local_pipe_callback
Move !node_up check in front and reindent
rest of the function to the left.
2014-04-14 13:02:27 +02:00
eccc50d861 clvmd: use thread-safe ctime_r when debugging
Use thread friendly version of ctime
TODO:should be probably replaced with strftime()
2014-04-14 13:02:25 +02:00
639983b6b7 clvmd: skip adding reply when finished
Prior adding new reply to the list, check
if the reply thread is not already finished.
In that case discard adding message
(which would otherwise be leaked).
2014-04-14 13:01:42 +02:00
7236b92857 clvmd: improve mutex usage in request_timed_out
Use mutex to access localsock values, so check
num_replies when the thread is not yet finished.

Check for threadid prior the mutex taking
(though this check is probably not really needed)
2014-04-14 13:00:51 +02:00
7075656034 clvmd: drop reply_mutex
Added complexity with extra reply mutex is not worth the troubles.
The only place which may slightly benefit from this mutex is timeout
and since this is rather error case - let's convert it to
localsock.mutex and keep it simple.
2014-04-14 12:59:07 +02:00
6115c0d112 clvmd: set finished flag with mutex
Setting this variable needs to be protected with mutex.
2014-04-14 12:58:28 +02:00
cc0096ebdd clvmd: move mutex init and detroy
Move the pthread mutex and condition creation and destroy
to correct place right after client memory is allocatedd
or is going to be released.

In the original place it's been in race with lvm thread
which could have still unlock mutex while it's been already
destroyed.
2014-04-14 12:57:39 +02:00
91f4e09b48 clvmd: fix test mode race
When TEST_MODE flag is passed around the cluster,
it's been use in thread unprotected way, so it may have
influenced behaviour of other running parallel lvm commands
(activation/deactivation/suspend/resume).

Fix it by set/query function only under lvm mutex.
For hold_un/lock function calls check lock_flags bits directly.
2014-04-14 12:55:46 +02:00
bd3e44643d memlock: ignore more libraries
Extend the list of ignored libraries. Since we do not
use those libraries during suspend, skip their locking.
2014-04-14 12:53:07 +02:00
84ff3ae703 pvmove: remove locked flag from error pvmove0
When pvmove0 is finished, it replaces temporarily pvmove0
with error segment, however in this case, pvmove0 remains
unremovable in case pvmove --abort is interrupted in this
moment - since it's not a pvmove anymore and normal
lvremove can't be used to remove LOCKED lv.
2014-04-14 12:52:32 +02:00
45f45c9932 polldaemon: ret invalid cmd for negative interval
Negative intervals are not supported.
2014-04-14 12:47:14 +02:00
a8d63994ea alloc: Refactor area reservation code.
No functional changes intended to be included in this patch.
2014-04-10 20:48:59 +01:00
6320c3b905 post-release 2014-04-10 17:13:27 +01:00
2043f8c729 pre-release 2014-04-10 16:28:28 +01:00
35721ee134 tests: add test for pvcreate --dataalignment --dataalignmentoffset --restorefile compatibility
Also, avoid division by zero in the pvcreate's param validation
in case someone supplies "pvcreate --dataalignment 0".
2014-04-10 15:02:35 +02:00
05eb6a167e tests: add separate test file for bootloader area support and enhance tests
Enahnce bootloader area test to check whether restoring values from
backup works correctly.
2014-04-10 14:18:59 +02:00
6c79556f4f pvcreate: fix ignored --dataalignment/dataalignment offset for pvcreate --restorefile
There were two bugs before when using pvcreate --restorefile together
with data alignment and its offset specified:

  - the --dataalignment was always ignored due to missing braces in the
    code when validating the divisibility of supplied --dataalignment
    argument with pe_start which we're just restoring:

	if (pp->rp.pe_start % pp->data_alignment)
		log_warn("WARNING: Ignoring data alignment %" PRIu64
			 " incompatible with --restorefile value (%"
			 PRIu64").", pp->data_alignment, pp->rp.pe_start);
        pp->data_alignment = 0

    The pp->data_alignment should be zeroed only if the pe_start is not
    divisible with data_alignment.

  - the check for compatibility of restored pe_start was incorrect too
    since it did not properly count with the dataalignmentoffset that
    could be supplied together with dataalignment

The proper formula is:

  X * dataalignment + dataalignmentoffset == pe_start

So it should be:

  if ((pp->rp.pe_start % pp->data_alignment) != pp->data_alignment_offset) {
	...ignore supplied dataalignment and dataalignment offset...
  }
2014-04-10 13:43:46 +02:00
b45d2768a8 tests: add some coverage for bootloader areas 2014-04-09 15:44:26 +02:00
10e10cfa4f lvmetad: fix lost bootloader area information
The refactoring made by 732859d21f
caused this. The former "ea" was not renamed to "ba" and we used
incorrect tree node name to search for the value.
2014-04-09 14:53:45 +02:00
87e559f1ec tests: check prohibited names 2014-04-08 11:00:16 +02:00
bfbf6b7c12 cleanup: libdm drop already zeroed elements
Drop zeroing of zalloc-ed memory.
2014-04-08 11:00:16 +02:00
a41ab41b70 cleanup: reindent return
Since the return here is the only path, reindent for readability.
2014-04-08 11:00:16 +02:00
c1ae39e2ef cleanup: update comments
Fix cut&paste comments
2014-04-08 11:00:16 +02:00
d4d8060ff4 cleanup: do include lvm headers in libdm build
Relocate some defines from lvm headers to those
few shared between libdm and lib code.
2014-04-08 11:00:15 +02:00
5553a099d1 cleanup: use DM_ARRAY_SIZE
More use of libdevmapper macro
2014-04-08 11:00:15 +02:00
56175f6ba9 cleanup: refactor apply_lvname_restrictions
Split apply_lvname_restrictions into 2 internal
function:

_lvname_has_reserved_prefix()
_lvname_has_reserved_string()
2014-04-08 11:00:15 +02:00
9eab84aa2b debug: catch invalid request for tree
In general for non-toplevel LVs we shouldn't allow any _tree_action.
For now error on request for cache_pool activation which
doesn't even exist in dm-table.
2014-04-08 11:00:15 +02:00
43f849296e lvconvert: do not activate cache pool
Cache pool cannot be active alone.
2014-04-08 11:00:14 +02:00
db4cf30106 man: cleanup new params
Correcting cachemode args
2014-04-08 11:00:14 +02:00
2868d897da lvm-string: add cdata/cmeta as reserved name 2014-04-08 11:00:14 +02:00
700b4bfc94 log: skip repeated hashing when logging once
When a message is already found in the hash, no need to hash it again.
2014-04-08 11:00:14 +02:00
96cf9dc017 raid: use internal variables for array alloc
Don't use passed pointer when allocating policies' array.
(In case policy_argc would be NULL, this would have caused
NULL dereference).
2014-04-08 11:00:13 +02:00
89615af349 exec_cmd: skip fork when argv[0] is null
Skip whole fork code path if the arg would be null.
2014-04-08 11:00:13 +02:00
6190ded5f1 libdm: simplify segtype search
For cache target use directly SEG_CACHE.
Hide dm_segtypes as internal static variable _dm_segtypes,
since noone is supposed to use it.
2014-04-08 11:00:13 +02:00
6d3d2d5e3d libdm: check for _build_dev_path failure
Enhance internal function _build_dev_path for failure
if buffer would be too small.
Use memcpy instead printf for a single string.
2014-04-08 11:00:13 +02:00
2c28197630 libdm: check for size when opening control node
Use dm_snprintf() to detect fail if open_control node would
not have fit into buffer.
2014-04-08 11:00:13 +02:00
583fbdba84 libdm: fail if buffer for version is to short
Return fail error code, if supplied buffer is too small.
2014-04-08 11:00:12 +02:00
f0003d3be5 libdm: always dm_lib_init mangling mode
If there ever would be a second call to dm_lib_init()
and envvar would be improperly set, some last set value
would be used while it should reset to default mangling mode.
2014-04-08 11:00:12 +02:00
bd2500e62e libdm: track implicit dependecies
When the node enters dtree with implicit dependency, it
automatically has udev flags from parent node
and could not be changed later when the node has been
entered again via i.e lvm's preload tracking.

Resolve this by tracking whether the node has been
created by implicit dependency tracking or has been
entered explicitely. Implicit node could be later
upgraded by an explicit _add_dev() with proper udev_flags.

For implicit devices add special udev flags to avoid
any scan and udev rule processing if we resume such device.

Patch allows easier removing of orphan nodes.
2014-04-08 11:00:12 +02:00
05a421960f NIX: Avoid test-installing lvm2-sysvinit (fails on recent Fedoras). 2014-04-07 20:38:43 +02:00
0996b5ccf4 spec: Add lvmthin.7.gz to packages.inc. 2014-04-07 20:38:42 +02:00
f13977e8fe autoreconf 2014-04-07 16:47:07 +01:00
eb1602406b configure: Warn if old thin_check tool found.
If thin_check is auto-detected, issue a warning if the version is older
than 0.3.x.
2014-04-07 16:44:29 +01:00
2fd5c67f32 man: lvmthin clean up lvm.conf references 2014-04-04 09:51:56 -05:00
a7c930b18d tools: don't require --major to be specified when using -My option on kernels > 2.4
Since kernel > 2.4 have dynamically assigned major numbers.

[0] raw/~ $ lvcreate -l1 -My --minor 10 vg
  Logical volume "lvol0" created

[0] raw/~ $ lvcreate -l1 -My --major 254 --minor 11 vg
  Ignoring supplied major number - kernel assigns major numbers dynamically. Using major number 253 instead.
  Logical volume "lvol1" created

[0] raw/~ $ lvs --profile out -o+major,minor
  lvol0 vg     -wima-----    4.00 253  10
  lvol1 vg     -wima-----    4.00 253  11
2014-04-04 13:29:39 +02:00
4d0c3ed0f8 configure: regenerate
Used rhel7 autoreconf.
2014-04-04 02:36:47 +01:00
5d7614fcf9 format_text: Report failed close. 2014-04-04 02:28:10 +01:00
cc72f340d7 thin: Support thin_check --clear-needs-check-flag.
Update thin provisioning tools to version 0.3.2 or later!
2014-04-04 02:22:40 +01:00
b38a3d8c85 lvmetad: Update retry logic vars and comments.
Avoid using variables with same name as functions.
Use lvm_even_rand for random numbers.
2014-04-04 01:46:53 +01:00
d36f721bb9 reports: FIXME for unnecessary cache wipes. 2014-04-04 01:41:06 +01:00
3f0f558786 dev-cache: Improve open device check messages. 2014-04-04 01:39:42 +01:00
c16c1a9f70 clvmd: Update new remove_info INTERNAL_ERRORS. 2014-04-04 01:37:43 +01:00
12ddaa5f10 lib: Share lvm_even_rand for random numbers. 2014-04-04 01:26:19 +01:00
e7b8e0a10c vgsplit: Mark cache moving code NOTREACHED. 2014-04-04 01:19:04 +01:00
6d2a26f6b6 man: Add lvmthin(7). 2014-04-04 01:14:25 +01:00
6c6468f91d RAID: Improve an error message
When down-converting a RAID1 LV, if the user specifies too few devices,
they will get a confusing message.
Ex:
[root]# lvcreate -m 2 --type raid1 -n raid -L 500M taft
  Logical volume "raid" created

[root]# lvconvert -m 0 taft/raid /dev/sdd1
  Unable to extract enough images to satisfy request
  Failed to extract images from taft/raid

This patch makes the error message a bit clearer by telling the user
the count they are trying to remove and the number of devices they
supplied.

[root@bp-01 lvm2]# lvcreate --type raid1 -m 3 -L 200M -n lv vg
  Logical volume "lv" created

[root@bp-01 lvm2]# lvconvert -m -3 vg/lv /dev/sdb1
  Unable to remove 3 images:  Only 1 device given.
  Failed to extract images from vg/lv

[root@bp-01 lvm2]# lvconvert -m -3 vg/lv /dev/sd[bc]1
  Unable to remove 3 images:  Only 2 devices given.
  Failed to extract images from vg/lv

[root@bp-01 lvm2]# lvconvert -m -3 vg/lv /dev/sd[bcd]1
[root@bp-01 lvm2]# lvs -a -o name,attr,devices vg
  LV   Attr       Devices
  lv   -wi-a----- /dev/sde1(1)

This patch doesn't work in all cases.  The user can specify the right
number of devices, but not a sufficient amount of devices from the LV.
This will produce the old error message:
[root@bp-01 lvm2]# lvconvert -m -3 vg/lv /dev/sd[bcf]1
  Unable to extract enough images to satisfy request
  Failed to extract images from vg/lv
However, I think this error message is sufficient for this case.
2014-04-03 16:57:41 -05:00
f242c0611d man: lvmthin pool space exhaustion
Initial description and instructions for
data/metadata space exhaustion.
2014-04-03 16:20:15 -05:00
7b11b1b4b5 man: add lvmthin man page 2014-04-01 16:04:08 -05:00
c2876ee1c9 cache: enforce local exlusive activation
For cache flushing local exlusive activation is needed.
2014-04-01 21:29:28 +02:00
c95d43b28c tests: update lvcreate-cache 2014-04-01 20:54:10 +02:00
dc5a3c9964 debug: add internal error for passed LV
TODO: in fact we should parameter LV.
2014-04-01 20:54:09 +02:00
1eaef2b705 cleanup: just rename for interal function 2014-04-01 20:54:09 +02:00
9cb053339e cleanup: cache updates messages
Passing non cached device is an internal error.
Print messages at non-error level.
Shorten sleep delay for cache flush.
2014-04-01 20:54:09 +02:00
e2ea3cd7ba cleanup: cache use const char policy
Policy should be const char pointer.
2014-04-01 20:54:09 +02:00
d58cc2c0fc cleanup: cache reuse code for pool test
Using same error message for pool associated devices.
2014-04-01 20:18:05 +02:00
e72dea55bf cache: fix order of metadata change
Start to change metadata after they are archived.
And since cache_pool is virtual skip deactivation
call for this LV.
2014-04-01 20:17:10 +02:00
d3004479cc cache: use remove_layer_from_lv
Since the usability problem were fixed, we can use this function.
Cleanup orphan LVs with TEMPORARY flags
(reduces couple blkid error reports, but couple of them
is still left...)
2014-04-01 20:17:10 +02:00
0a15a210a5 cache: cache segment is non-discardable
Since cache segment is purely virtual mapping, it has nothing for
discard. Discardable is cache origin here which is now
properly removed on 'delete' phase.

Plain lv_empty() call needs to only detach cache origin and leave
origin unchanged.
2014-04-01 20:17:10 +02:00
a018c57f0b cache: never activate cache pool
Since cache-pool is purely lvm abstraction layer LV, it never
need any device node, so do not add even 'error' device for it.
2014-04-01 20:17:10 +02:00
504c328e3d tests: add profiles-thin and prepare_profiles helper fn 2014-04-01 15:52:54 +02:00
af73a0a518 libdm: Add missing UDEV_CFLAGS. 2014-04-01 15:26:26 +02:00
d5682ccbac lvm-wrappers: Remove spurious #include <libudev.h>. 2014-04-01 15:26:26 +02:00
490226fc47 pvs: Wipe persistent filters when given a device argument. 2014-04-01 14:46:22 +02:00
a30219a8c0 tests: update profiles.sh for recent changes 2014-04-01 11:48:49 +02:00
13009adbf2 man: add a note about --profile when using dumpconfig --mergedconfig 2014-04-01 11:19:38 +02:00
68bb639a08 config: fix compile error in config-settings.h if using --disable-dmeventd
config/config_settings.h:257:102: error: 'DMEVENTD_PATH' undeclared here (not in a function)
2014-03-31 15:57:42 +02:00
367e4551a1 tests: add more rename test
Drop test, which are now in other files (listings.sh)
2014-03-31 12:05:35 +02:00
ee8708cc8e tests: more listing tests 2014-03-31 12:05:35 +02:00
f93c9b447b cleanup: skip eval of minor when major is true
Use normal '||'.
2014-03-31 12:05:34 +02:00
a33d4355a1 cleanup: lvdisplay indent 2014-03-31 12:05:34 +02:00
84beba5d7f vg_validate: check size of lv_name + vg_name
Since the whole dm device name may not exceed 127 characters,
validate no LV names is bigger then this limit.
2014-03-31 12:05:32 +02:00
6570d36ad5 lv_rename: resume fail is certainly error
Failing resume path means command has failed,
even when commit was ok.
2014-03-31 12:03:25 +02:00
d3e4934a15 lvrename: fix name length validation
This test for LV name restriction check name of device is below 128
chars (which is enforced by dm target).
Thus it should not count with device name.
(Though the test for PATH_MAX size should be probably also added,
but this is runtime test, since theoretically devpath might differ in cluster)
2014-03-31 12:02:18 +02:00
caa429da2e lvdiplay: prohibit use of -c and -m
It's unclear why we should prohibit use of -v output.
So reenable (like with other 'display' tools)
But -c -m is really unsupported - return invalid cmd.
2014-03-31 12:00:45 +02:00
8f9150c241 tests: add more pvdisplay tests 2014-03-30 23:45:00 +02:00
1216aa7826 tests: workaround clvmd .cache consistency
May need futher fixes, but it's needed only on non-udev systems
(systems which still needs .cache - just like test suite)
2014-03-30 23:45:00 +02:00
2c8f0c9800 tests: more vgexport tests
cover more options
2014-03-30 23:45:00 +02:00
cc82dc7b23 cleanup: pvdisplay indent
Reindent else path, since other branch already exits with return.
2014-03-30 23:44:59 +02:00
d7b6334079 cleanup: vgexport drops pv pointer
PV pointer is not really needed.
2014-03-30 23:44:59 +02:00
31d68b7124 man: sort options
Sort order for -C|--columns as with other options,
and use short capital name as the first (as with other options).
Also drop multiple reference for pvs/lvs/vgs, since now
the text for -C is really close to referrence of lvm anyway.
2014-03-30 23:43:31 +02:00
7a9c569eb4 pvscan: return error when free parameter is given
Just like vgscan, pvscan (without --cache option) is not
accepting and 'free' args  (i.e.  pvscan /dev/sdx)
2014-03-30 23:42:57 +02:00
844afa32a0 pvdisplay: fix option error
Properly show error for '-m'.
Also report unsupported  '-c & -s' (just like with vg/lvdisplay)
2014-03-30 23:41:52 +02:00
cf29de5de0 vgimport/vgexport: return invalid cmd
When option parsing fails, return invalid cmd instead of fail.
2014-03-30 23:40:27 +02:00
5aa2e5ec8c tests: update pvs test
TODO:
It seems commit 7e685e6c70
has changed the old logic, when  'pvs device_name' used
to work. (regression from 2.02.104)
Currently put in extra pvscan.
2014-03-28 17:06:13 +01:00
3181dc72e7 tests: more coverage for pvchange
Change metadataignore
Argless pvchange
Alocatability for orphans
2014-03-28 11:38:50 +01:00
2a79971004 tests: check pvchange changes uuid 2014-03-28 10:41:59 +01:00
09b180cfc2 tests: expect failing pvs when missing PV 2014-03-28 10:41:59 +01:00
88a9705222 pvchange: populate lvmcache for --all
When running pvchange --all  learn about available VGs from lvmetad.
2014-03-28 10:41:58 +01:00
3d0ba79f86 lvconvert: fix help message cache_pool -> cache-pool 2014-03-28 09:10:30 +01:00
a512ea6a6a tests: updates 2014-03-28 00:41:19 +01:00
bd805ff048 tests: move some tests to better places
Some tests already have separate test scripts - so move
those tests to listing and vgcfgbackup files.
2014-03-28 00:41:19 +01:00
5b44a036b1 tests: support invalid and fail results
Allow more detailed check for failing exit code:

invalid  -  expects 3
fail - expects 5
2014-03-28 00:41:19 +01:00
0e02551f04 spec: add dumpconfig man 2014-03-28 00:41:19 +01:00
6d314466f3 man: better formatting for lvm dumpconfig man page 2014-03-27 14:18:41 +01:00
801d43445d man: add man page for lvm dumpconfig 2014-03-27 14:03:28 +01:00
c7a89323f5 fix spurios char
Mistyped char left in code.
2014-03-27 13:49:24 +01:00
4ebdfcfb59 tests: more pvchange options examined 2014-03-27 13:13:22 +01:00
04a6918518 tests: cover more commands
Visit more code lines.
2014-03-27 13:13:09 +01:00
fc8185601d cleanup: indent change 2014-03-27 13:13:09 +01:00
5076456a73 debug: avoid warning when compiled with valgrind
Declare 'c' only when compiling without valgrind.
This cleans compiler warning about unused var when
compiled with valgrind pool support.
2014-03-27 13:13:08 +01:00
356fdda46d lv_manip: drop cmd pointer from for_each_sub_lv
Drop unused passed cmd pointer from function.

TODO:

We have two similar functions (though not identical)

lv_manip.c: for_each_sub_lv()
metadata.c: _lv_each_dependency()

They seem to not always match - we should probably convert
to use only a single function.
2014-03-27 13:10:13 +01:00
22579b4451 lv_rename: validate renamed sublv
Use proper vgmem memory pool for allocation of LV name in the vg
and check if new renamed LV is a valid name.

TODO: validation should really use also VG name, othewise we are not
able to tell "vgname-lvname" will be valid.
2014-03-27 13:06:23 +01:00
28e4bf0b6d lvrename: fix exit code
Return invalid cmd line (3) when error is detect on cmd line input.
Cmd failed (5) is used when command processing fails.
2014-03-27 13:04:55 +01:00
80fe100afa pvchange: fix exit code regression
Commit 1a832398a7 moved
some code from _pvchange_single() to main pvchange() and
introduced exit code regression as return codes have not
been properly changed, thus pvchange command exited
with '0' exit code, even though it has reported error.
Also there is a missing vg unlock in error path.

Fix it by counting the total number of expected calls before
checking for pvname and also unlock and relase vg when
pv is not found.
2014-03-27 13:01:51 +01:00
2a93eba68e cleanup: easier casting
Use 32bit for extent calcs.
Drop uneeded implicit case.
2014-03-26 14:11:37 +01:00
0499e87ace cleanup: simplify pv name size estimation
Reuse buffer with size of 2 * PATH_MAX to handle worst case escape
and avoid extra calculation of espaced len.
2014-03-26 14:11:37 +01:00
3fda296da6 cleanup: lvmetad use dm_hash_iterator
Simplify code with the use of dm_hash_iterator
2014-03-26 14:11:37 +01:00
dae455f806 man: colorization fixes
Fix style
2014-03-26 14:11:37 +01:00
bda0fe95ad man: add repair info for thin pools
Document lvconvert --repair for thin pools.
2014-03-26 14:11:36 +01:00
a3615f3149 lvmetad: Fix an endless wait loop introduced in c13f5dbb. 2014-03-26 11:45:28 +01:00
a2614c6866 tests: missed exclusive activation 2014-03-26 00:22:23 +01:00
5b900dbef5 tests: pass list devs to allocate from 2014-03-26 00:05:46 +01:00
1259ae5954 tests: cover code from more commands 2014-03-26 00:05:46 +01:00
4b30863e85 tests: check forced backup 2014-03-26 00:05:46 +01:00
4adbb85c37 tests: disable test for broken kernel raid targe
Since using raid5 - validate it's usable on the system
2014-03-26 00:04:59 +01:00
fb471a372d tests: remove also 3.14 fc21 kernels 2014-03-26 00:04:59 +01:00
c13f5dbb25 lvmetad: Wait at least 80s for the initial scan. 2014-03-25 16:38:35 +01:00
65bbfdf74d lvmetad: add missing dev_close in error path
Fixes missing dev_close() in dev_read error path
introduced in commit
a368698672
3e5bec37e9

(in-release fix)
2014-03-25 14:55:58 +01:00
ce78cb58eb lvmdump: add lvm dumpconfig --type diff/missing
For a quick overview of config when debugging and to quickly check
which values are different from defaults and which are not defined
in the config and for which defaults are used.
2014-03-25 13:06:59 +01:00
0738f0ad72 pvresize: fail exit code for negative size
Pvresize with negative value retuns invalid cmd line exit code.
2014-03-25 11:52:03 +01:00
8471fb01d8 tests: wipe signature
Check for usable blkid.
2014-03-25 11:23:00 +01:00
3c9204a75a tests: update 2014-03-25 11:23:00 +01:00
36d87eddcf tests: use exclusive activation
pvmove in cluster needs exlusive activation or cmirrord running.
2014-03-25 11:23:00 +01:00
db1d4ba4ac tests: argless pvremove 2014-03-25 11:23:00 +01:00
04861b9bed tests: more pvresize tests
Maybe move to separate pvresize test,
remove vgck size this is already executed elsewhere.
2014-03-25 11:22:59 +01:00
db04d3e6d2 tests: relocate vgimport test
It seem like a better-fit here.
2014-03-25 11:22:59 +01:00
13258d6e96 debug: add proper backtrace debug
When failure happens inside refresh, print proper debug backtrace.
2014-03-25 11:22:59 +01:00
89575d6895 cleanup: drop init of already zalloced mem 2014-03-25 11:22:59 +01:00
406ec4162f cleanup: use dm_free without extra test
It's ok to free(NULL).
2014-03-25 11:22:59 +01:00
4a6f05e420 cleanup: use trigraph 2014-03-25 11:22:58 +01:00
db71739f42 cleanup: initilization of vars 2014-03-25 11:22:58 +01:00
5c9165705a cleanup: indent 2014-03-25 11:22:58 +01:00
c7b2c08a6b cleanup: use NULL for pointer reset 2014-03-25 11:22:58 +01:00
b714c7ebc6 clvmd: validate open device state
If clvmd does not hold any lock, it should also not keep any opened
device.

The reason for this patch is, that refresh_toolcontext calls
dev_cache_exit() which destroys whole device cache (even those with
opened file) - previous patch added recovery path to avoid memory
corruption, but opened files are still bugs that need to be fixed.

So this patch certainly kills many internal mirror & raid tests,
since they leak opened file descriptors (when tests are executed
with 'abort_on_error').
2014-03-25 11:22:57 +01:00
b522312678 clvmd: hardening leak on exit
Operate with lvm_thread_exit while holding lvm_thread_mutex.
Don't leave unfinished work in the lvm thread queue
and always finish all queued tasks before exit,
so no cmd struct is left in the list.

(in-release fix)
2014-03-25 11:22:57 +01:00
68d13b2517 dev-cache: fix mem corruption on refresh context
When lvm2 command works with clvmd and uses locking in wrong way,
it may 'leak' certain file descriptors in opened (incorrect) state.

dev_cache_exit then destroys memory pool of cached devices, while
_open_devices list in dev-io.c was still referencing them if they
were still opened.

Patch properly calls _close() function to 'self-heal' from this
invalid state, but it will report internal error (so execution
with abort_on_internal_error causes immediate death). On the
normal 'execution', error is only reported, but memory state is
corrected, and linked list is not referencing devices from
released mempool.

For crash see: https://bugzilla.redhat.com/show_bug.cgi?id=1073886
2014-03-25 11:22:57 +01:00
d29fe919e6 WHATS_NEW: commit f12ee43 2014-03-25 11:00:44 +01:00
c84face8ce libdaemon: fix misleading "WARNING: Ignoring unsupported value for expected." when communicating with daemon
When we're trying to search for certain tree node
in daemon's reply, we default to a blank string ""
if the node is not found. This happens during lvmetad
initialization.

However, when the default blank string is used, we
can't use dm_config_find_str at the same time - the
dm_config_find_str_allow_empty should be used instead.
Otherwise a a warning message:

  "WARNING: Ignoring unsupported value for ..."

is issued.
2014-03-24 16:47:08 +01:00
9446978e64 config: define default value for global/thin_disabled_features as NULL instead
Before:
  thin_disabled_features = ""
Now:
  thin_disabled_features = []

Which is a more correct and consistent way of specifying void array
though parses can handle both forms.
2014-03-24 16:31:27 +01:00
4e47c34ffc config: also check empty arrays for difference against default values 2014-03-24 16:30:47 +01:00
5dcec1734e dumpconfig: add dumpconfig --type diff to show differences from defaults 2014-03-24 15:35:54 +01:00
76ff38fa5c config: add support for comparing used config values with default ones 2014-03-24 15:35:47 +01:00
630e0af14e cleanup: move _get_def_array_values fn
So we can use reuse it for the code that will follow...
2014-03-24 15:20:19 +01:00
c595b20e56 dev-swap: use SECTOR_SHIFT 2014-03-22 20:43:05 +01:00
936bfeb8de dev-swap: detect swap signature on devices smaller then 2MB
Smallest supported size for swap device is 40KB, however current
test skipped devices smaller then 4096 sectors (2MB).

Since page is in bytes, convert it to sectors before comparing
with device size (in sectors).
2014-03-22 20:36:14 +01:00
93d77455ea WHATS_NEW update 2014-03-21 22:29:28 +01:00
c0c55846b0 tests: wait for clvmd.pid file
Just like with dmeventd and lvmetad.
Do few indent changes around.
2014-03-21 22:29:28 +01:00
8b1916fd5a tests: simplify 2014-03-21 22:29:28 +01:00
de5683d8d9 tests: add quotes around device paths 2014-03-21 22:29:27 +01:00
01efb20bdb cleanup: clvmd add more info debug message 2014-03-21 22:29:27 +01:00
0d449fe183 cleanup: clvmd uses struct initializers
Code easier to read
2014-03-21 22:29:27 +01:00
9196274c1e cleanup: clvmd zombie removal loop
Simplier code to start scan from the next node,
and remove matching pipe client.
2014-03-21 22:29:27 +01:00
5740c00f3b cleanup: clvmd reindent read_from_local_sock
Shift indent of else branch to right since
error path returns in the front.
(Simplier to read)
2014-03-21 22:29:26 +01:00
dd17286c90 cleanup: clvmd indent change
Plain indent changes.
2014-03-21 22:29:26 +01:00
0b79979bb9 cleanup: clvmd dump_messages 2014-03-21 22:29:26 +01:00
f8cd435cd8 cleanup: clvmd update log_error
Drop \n from log_error() and add '.'
2014-03-21 22:29:26 +01:00
4c97ea2ce5 cleanup: clvmd drop goto 2014-03-21 22:29:25 +01:00
7d49c33ffc cleanup: clvmd skip reset of null pointer 2014-03-21 22:29:25 +01:00
bf19c6be2c cleanup: clvmd move destroy_lvhash into main
Keep destruction code path consistent and simple and
destroy lvhash in the place it's been created.
Also issue debug message from a single place.
2014-03-21 22:29:25 +01:00
1ee8688de0 cleanup: memlock line indent 2014-03-21 22:29:25 +01:00
46ae028cd3 singlenode: reset pointer when hash is destroyed
Just keep pointer consistent.
2014-03-21 22:29:25 +01:00
7041c8bf51 clvmd: drop dead code
Since pipe_client has been already reset to NULL,
remove this dead code.
2014-03-21 22:29:24 +01:00
73978f8d7d clvmd: drop unused local_sock parameter 2014-03-21 22:29:24 +01:00
37396e2fe5 clvmd: update add_reply_to_list
Take mutex lock after the allocation just before
the structure is merged into reply list.
2014-03-21 22:29:24 +01:00
2847994624 clvmd: use dm_malloc
Use libdm malloc wrapper functions.
2014-03-21 22:29:24 +01:00
c45cd6eb8d clvmd: move call of cluster_closedown
We have to close cluster in some predicatable way,
otherwise we may access released memory from different
threads.

So move closedown till the point we know all thread
are closed. New messages from cluster are discarded.
2014-03-21 22:29:23 +01:00
fc39ad677b clvmd: move destroy_lvm into lvm thread
Since lvm was initialized in lvm thread call destroy there as well.
2014-03-21 22:29:23 +01:00
8431d47b3b clvmd: add special lvm thread exit
When multiple threads act on the same 'quit' variable
the order of exit becomes unpredictable.

So let the main_loop() finish first and then clean up
all queued lvm jobs.

Do not add any new work, when lvm_thread_exit is set.
2014-03-21 22:29:23 +01:00
05a532e171 clvmd: always set cleanup_needed
When thread is created, set the cleanup_needed flag
immediately so it could be used properly any time later
when cleanup_zombie() is needed.
2014-03-21 22:29:23 +01:00
5bea2b5c82 clvmd: fix clean memory on exit
Properly clean 'client' structure only for LOCAL_SOCK type.
(Fixes bug from commit 460c19df62)
(in release fix)

Also cleanup-up associated pthreads by using cleanup_zombie() function.
Since this function may change the list, restart scanning always from
the list header.

Note: couple following patches are necessary to make this working properly.
2014-03-21 22:29:22 +01:00
486b15d36c memlock: drop locked mem in critical section
When daemon releases memory and it is still in critical
section, issue an error message and drop memory.

We cannot do anything better for now and we at least
release allocated resource.

FIXME:

This code is triggered when i.e. clvmd is killed while
some LVs are suspend - in this case suspended devices leak,
so if this happens during i.e. clvmd upgrade we have
unresolved problem - even locked rootfs...
2014-03-21 22:29:22 +01:00
0ca16c6946 activate: report release with critical section
This function is typically called for cmd context refresh or destroy.
On the non-clustered case we already unlocked all messages,
however when i.e. 'clvmd' gets break signal it may have
still couple messages queued.

For now just report an error.
2014-03-21 22:29:22 +01:00
e5382c063d lvmcache: fix debug trace
Recent debug tracing commit introduce read of uninitialized memory,
since VGID is not really a proper string which ends with '\0'.
Enforce at most 32 (ID_LEN) chars are read from vgid.
(in release fix)
2014-03-21 22:29:22 +01:00
fc280bcc42 lvmcache: handle reinit without error
Since commit f12ee43f2e call destroy,
it start to check all VGs are unlocked. However when we become_daemon,
we simply reset locking (since lock is still kept by parent process).
So implement a simple 'reset' flag.
2014-03-21 22:29:21 +01:00
bdd7baeab3 cmirrord: Clean-up stray warning message (attempt #2)
There are two types of CPG communications in a corosync cluster:
messages and state transitions.  Cmirrord processes the state
transitions first.

When a cluster mirror issues a POSTSUSPEND, it signals the end of
cluster communication with the rest of the nodes in the cluster.
The POSTSUSPEND marks the last communication of the 'message'
type that will go around the cluster.  The node then calls
cpg_leave which causes a final 'state transition' communication to
all of the nodes.  Once the out-going node receives its own state
transition notice from the cluster, it finalizes the leave.  At this
point, the state of the log is 'INVALID'; but it is possible that
there remains some cluster trafic that was queued up behind the
state transition that still wants to be processed.  It is harmless
to attempt to dispatch any remaining messages - they won't be
delivered because the node is no longer in the cluster.  However,
there was a warning message that was being printed in this case
that is now removed by this patch.  The failure of the dispatch
created a false positive condition that triggered the message.
2014-03-19 14:43:00 -05:00
f12ee43f2e polldaemon: Re-initialise lvmcache properly on fork (fixes RHBZ 1073670). 2014-03-19 16:25:12 +01:00
2f279797f5 WHATS_NEW: commit 5eef269 2014-03-19 09:49:09 +01:00
000e81a999 cleanup: add cmd_context reference to struct cft_check_handle
So we have all things needed to do a configuration check packaged
in one handle. It makes function calls inside a bit more readable.
2014-03-19 08:45:05 +01:00
b6eb2ac10a cleanup: indent 2014-03-19 00:58:02 +01:00
852a2b98be pvscan: cleanup updates
Simplify code:
 remove unneeded assignments
 use unsigned values for length
2014-03-19 00:58:02 +01:00
3d7eaf9226 pvscan: fix report of long pv names
pvscan --uuid was broken since it was using only 128 char buffers
without checking any write size, so any longer device path leads to
crash.

Also ansure format is properly aligned into columns with this option.
2014-03-19 00:58:01 +01:00
caf93eb1cb cleanup: simplify pv name print
pv_vg_name() now already hides orphans.
2014-03-19 00:58:01 +01:00
506091be70 pv_vg_name: do not expose internal orphans to lvm2 users
Check for orphan VG name and return just empty string,
Use internally pv->vg_name if the real orphan name is needed.
2014-03-19 00:57:59 +01:00
5b69bfb6f8 pvdisplay: fix man to refer to sectors, not KB
The PV size is displayed in sectors, not kilobytes
for 'pvdisplay -c'

Signed-off-by: Thomas Fehr <fehr@suse.de>
Acked-by: Hannes Reinecke <hare@suse.de>
2014-03-19 00:49:32 +01:00
52525bde04 pvdisplay: use log_print_unless_silent for info messages 2014-03-19 00:48:39 +01:00
013f5f4550 metadata: print VG with invalid chars in quotes
We we report invalid chars, put quotes around vg name.
2014-03-19 00:48:39 +01:00
6a8d3d7811 clvmd: avoid resending local sync commands
Instead of sending repeatedly  LOCAL_SYNC commands to clvmds
like 'lvs', rememeber the last sent commmand, and if there was no other
clvmd command, drop this redundant SYNC call message.

The problem has started with commit:
56cab8cc03

This introduced correct synchronisation of name, when user requests to know
open_count (needs to wait for udev), however it is also executed for
read-only cases like 'lvs' command.

For now implement very simple solution, which is only monitoring
outgoing clvmd command, and when sequence of LOCAL sync names are
recognized, they are skipped automatically.

TODO:
Future solution might move this variable info 'cmd_context' and
use  'needs_sync' flag also i.e. in file locking code.
2014-03-19 00:47:58 +01:00
a6b159e99c file_locking: use PATH_MAX for dir name
Using just 128 chars for locking dir may wail if longer
dir entry is used, swich to default linux max path.
2014-03-19 00:46:28 +01:00
08018a5345 archiver: drop unneeded backup check
When the backup is disabled, avoid testing backup presence.
This only leads to errors being logged in debug trace and the missing
backup can't be fixed, since it's disabled.
2014-03-19 00:45:41 +01:00
25f5e2da8d dumpconfig: fix memleak when using --mergedconfig
Check whether lvm dumpconfig --mergedconfig is used only
with --type current (where we're merging current config and
the config supplied on command line). With other types
the config was merged, but it was thrown away since we're
generating other type of config anyway. This lead to a memleak.

Error out if --mergedconfig is used with anything else than
--type current (or without specifying --type in which case
the --type current is used by default).
2014-03-18 11:11:31 +01:00
aed36c12f8 tests: use check lv_tree_on
Use internal /lib function.
Reduce extent size for test to create smaller devices.
2014-03-18 10:28:09 +01:00
81166a84be tests: more fedora kernels unusable for testing raid456 2014-03-18 10:28:08 +01:00
599a05f658 lvmcache: add mode debug prints
Decorate NULL returns with debug_cache output so the
debug log doesn't contain spurios <bactrace> line without
any reason for it.

Add internal errors when cache is misused.
2014-03-18 10:28:08 +01:00
21b3c983fd config: make global/lvdisplay_shows_full_device_path profilable 2014-03-18 09:49:53 +01:00
3a6bc7fc65 WHATS_NEW: previous commit 2014-03-18 09:28:52 +01:00
927784cd06 config: make global/suffix profilable and add it to lvm.conf
The global/suffix was missing from example lvm.conf but it can
be very useful when using lvm in scripts and now in profiles as well
Let's expose it more.
2014-03-18 09:24:17 +01:00
64086c3bd8 doc: cleanup/extend some man pages/conf comments
man/lvm2-activation-generator.8:
  Generator Specification -> Generators Specification
  (this is the exact word in the systemd man page)

conf/example.conf.in:
  cleanup recent edits related to report section

man/lvm.conf.5:
  add a line about a possibility to generate a new
  profile with lvm dumpconfig command as an alternative
  to copying the default profile
2014-03-18 08:28:58 +01:00
31b1d06ddd tests: replace skip_if_mirror_recovery_broken
Use mirror_recovery_works instead with easier to follow logic.
2014-03-17 16:33:29 +01:00
19fd6040c2 tests: quotes for LVM_TEST vars 2014-03-17 16:32:29 +01:00
e3d208f7c2 tests: put vars in quotes
This shell var has space in middle
2014-03-17 16:30:52 +01:00
c1ce2cc86c config: make global/units and global/si_unit_consistency profilable 2014-03-17 16:07:29 +01:00
a2c544dc91 tests: make test usable in cluster
Origin needs exclusive activation
2014-03-17 15:18:20 +01:00
ae2d80dd7e tests: update error message check 2014-03-17 15:18:02 +01:00
e398901ed1 tests: zero and error type tests 2014-03-17 14:31:45 +01:00
fe8603dd60 tests: lvconvert snapshot testing 2014-03-17 14:31:45 +01:00
27d556de9e tests: enhance snapshot test
Improve cleanup routine and use it also for vg removal.
2014-03-17 14:31:45 +01:00
1a0fea104b tests: put test envvar into braces
Ensure we not fail on space.
2014-03-17 14:31:45 +01:00
95f74af404 tests: skip mangling test
Mangling is only using dmsetup commands,
so there is no lvm command and no contact with
clvmd nor lvmetad so skip this test there.
2014-03-17 14:31:45 +01:00
909e2207bd tests: test spare volume removal 2014-03-17 14:31:44 +01:00
404593c710 tests: more coverage 2014-03-17 14:31:44 +01:00
7d3fa6fc32 tests: skip more Fedora kernels for raid456 2014-03-17 14:31:44 +01:00
0fc17fe1ce tests: add more help text and paths quotes
Add LVM_VALGRDIN help text
Use proper quotes for  abs_  paths
(Assignment in makefile doesn't need them, only shell usage)
2014-03-17 14:31:44 +01:00
d686f3856a cleanup: relocate check for mirror
Move testing code into _lvconvert_snapshot function.
2014-03-17 14:31:43 +01:00
b738260c7c lvconvert: delay archiving of metadata
Delay archiving of metadata until we really start to
update metadata when converting volume into a snapshot.
Archive is not necessary when we abort operation early.
2014-03-17 14:31:43 +01:00
d425e788e9 lvconvert: validate min chunk size for snapshot
Do not allow conversion of too small LV into a COW snapshot device.

Without this patch snapshot target is generating these kernel
messages before creation fails:

attempt to access beyond end of device
dm-9: rw=16, want=8, limit=2
attempt to access beyond end of device
...
device-mapper: table: 253:11: snapshot: Failed to read snapshot metadata
device-mapper: ioctl: error adding target to table
device-mapper: reload ioctl on  failed: Input/output error
2014-03-17 14:31:43 +01:00
3a82490ee1 snapshot: wrap min_chunk test into a lib function
Create a separate function to validation snapshot min chunk value
and relocate code into snapshot_manip file.

This function will be shared with lvconvert then.
2014-03-17 14:31:43 +01:00
f3b9ee37e9 lvconvert: disallow usage of origin for snapshot
Usage of origin as a snapshot 'COW' volume is unsupported.

Without this test lvm2 is able to generate this ugly internal error message.

To test this:

lvcreate -L1 -n lv1 vg
lvcreate -L1 -n lv2 -s vg/lv1
lvcreate -L1 -n lv3 vg
lvconvert -s vg/lv3 vg/lv1

Internal error: LVs (5) != visible LVs (1) + snapshots (1) + internal LVs (0) in VG vg
2014-03-17 14:31:42 +01:00
455f23586f config: make report settings profilable
Users can create several profiles for how the tools report
the output very easily and then just use

  <lvm reporting command> --profile <report_profile_name>
2014-03-17 14:27:49 +01:00
f9070c196b conf: add existing report settings to lvm.conf
These settings exist for ages but they were not exposed in lvm.conf
and so majority of users didn't event know about them.
2014-03-17 14:24:21 +01:00
12eb284eec tests: fix name-mangling test
We need to use "--verifyudev" for dmsetup mangle command used in
the name-mangling test since without the --verifyudev, we'd end up
with the failed rename.

Also, add direct check for the dev nodes - node with old name must
be gone and node with new name must be present. Before, we checked
just the output of the command.

One bug popped up here when renaming with udev and libdevmapper
fallback checking the udev when target mangle mode is "none"
(fixme added in the libdevmapper's node rename code).
2014-03-17 11:51:30 +01:00
b16235de96 cleanup: use 'define' for systemd runtime unit file directory 2014-03-14 15:57:44 +01:00
ada47c164a autoactivation: use VG read lock
The activation (including the refresh) should take the VG read lock
like the usual activation/refresh.
2014-03-14 12:10:52 +01:00
58e812a13f tests: use DMEVENTD_PIDFILE
Test for compiled-in pidfile location
(so we are not based on assumption /var/run or /run link exists)
2014-03-14 11:16:24 +01:00
ca880a4f13 autoactivation: issue a VG refresh before autoactivation only if 'change' lvmetad flag is set
This prevents numerous VG refreshes on each "pvscan --cache -aay" call
if the VG is found complete. We need to issue the refresh only if the PV:
  - is new
  - was gone before and now it reappears (device "unplug/plug back" scenario)
  - the metadata has changed
2014-03-14 10:48:56 +01:00
900cb6717b tests: quick update of location of pid file
Until better fix is put in - replace with /run.
2014-03-14 10:40:48 +01:00
551b6b7998 lvmetad: Fix pvmeta_old_{pvid,dev} logic when they are the same. 2014-03-14 10:09:16 +01:00
67c539f346 lvmetad: Fix previous commit
"%d" in buffer_append_vf is 64 bit wide. Using just `int` for the
variable will fetch more from va_list than intended and shifting
remaining arguments resulting in errors like:

    Internal error: Bad format string at '#orphan'
2014-03-14 08:09:37 +01:00
816197aaab lvmetad: Indicate whether pv_found caused the VG to change. 2014-03-14 03:08:19 +01:00
5eef269f77 lvmetad: Also return vgname in reply to pv_found requests. 2014-03-14 03:08:19 +01:00
a31ab7c171 man: Fix man page containing BUILDROOT
This breaks brew/koji as DESTDIR should not be contained in any file and
results in message like:

    + /usr/lib/rpm/check-buildroot
    /builddir/build/BUILDROOT/lvm2-2.02.106-0.311.el7.x86_64/usr/share/man/man8/lvm2-activation-generator.8:.B /builddir/build/BUILDROOT/lvm2-2.02.106-0.311.el7.x86_64/usr/lib/systemd/system-generators/lvm2-activation-generator
    Found '/builddir/build/BUILDROOT/lvm2-2.02.106-0.311.el7.x86_64' in installed files; aborting
    error: Bad exit status from /var/tmp/rpm-tmp.UfX2SX (%install)
2014-03-14 00:36:19 +01:00
2189d66a27 man: install lvm2-activation-generator man page only on make install_systemd_generators 2014-03-13 13:20:28 +01:00
031666ef66 man: add man page for lvm2-activation-generator 2014-03-13 13:01:06 +01:00
c0f1eb5f0f dev_manager: check prohibited devices earlier
Reorder detection for internal device - since this test
is much simpler then target analysis, check it sooner.

Replace test for '68' with sizeof & ID_LEN

Add FIXME about device alias problem with is_reserved_lvname,
since this test fails on devices like /dev/dm-X
so we need to convert tests to UUID.
2014-03-12 19:38:34 +01:00
b50b4471bd cleanup: drop unused define 2014-03-12 19:12:34 +01:00
8b14ebb2f1 tests: another kernel with unusable kmem_check 2014-03-12 16:17:36 +01:00
bf42119b22 config: accept empty values for global/thin_disabled_features
Let's do this the other way round - this makes more logic than commit b995f06.
So let's allow empty values for global/thin_disabled_features where
such an empty value now means "none of this features are disabled".
2014-03-12 15:53:20 +01:00
b995f06abf config: mark global/thin_disabled_features as having no default value
The global/thin_disabled_features should be marked as having no default
value. Otherwise the output from 'lvm dumpconfig --type default' would
have 'thin_disabled_features=""' which will produce an error message
'Ignoring empty string in config file ...' if such output is feed
back to lvm.
2014-03-12 15:17:52 +01:00
a2c64e21fd tests: check we are no reading pool device 2014-03-12 00:26:47 +01:00
dd690d5fd1 tests: add inactive pool creation test 2014-03-12 00:25:59 +01:00
4cc5c689b8 thin: add pool uuid suffix for pool volume
Even though we make pool volume as a public visible LV,
we still do not want tools to look at this volume.

While we do not create /dev/vg/lv link, device is still
accessible via /dev/mapper/vg-lv and there is no easy
way to recognize it's private without lvm2 metadata.

Enhance UUID with -pool suffix and directly skip
any LV with a suffix in  device_is_usable() call.

TODO: enhance other targets with this logic.
blkid may probably use same simple logic.
2014-03-12 00:16:27 +01:00
8a60cbcf45 thin: always activate and deactive pool when creating
When we create thin-pool we have used trick to keep
volume active, but since we now support TEMPORARY flag,
we could just localy active & deactive metadata LV,
and let the thinpool through normal activation process.
2014-03-12 00:16:27 +01:00
6a0d97a65c lvm: change build_dm_uuid API
Pass directly 'lv' into this build routine,
so we can eventually add more private UUID suffixes.
2014-03-12 00:16:20 +01:00
4d64e91efd thin: do not check of empty pool with messages
The empty pool is also the pool which has yet queued list of messages
and transaction_id == 1.

Problem is exposed when pool is created inactive.

lvcreate -L10 -T vg/pool -an
lvcreate -V10 -T vg/pool
2014-03-12 00:15:22 +01:00
1850a6e454 thin: fix pool_has_message return for NULL params
When pool_has_message() is queried with NULL lv and 0 device_id
it should just return 'true' when there is any message queued.
So it needs to return negative value dm_list_empty().

Since there is no user for this code path in code currently,
this bug has not been triggered.
2014-03-12 00:13:21 +01:00
7574b3bc80 autoreconf: sync configure with current configure.in 2014-03-11 16:32:02 +01:00
6c892be4a5 clvmd: fix the len setting in last commit
When theoretically sending 0 length buffer, ensure 0 is returned.
2014-03-10 12:35:44 +01:00
5dc9402774 tests: dmeventd valgrind testing 2014-03-10 12:24:11 +01:00
c7262d5b38 tests: aux adds kill_sleep_kill_
Move common code to subfunction
2014-03-10 12:24:11 +01:00
1c18fc42ec tests: drop unused make_ioerror 2014-03-10 12:24:11 +01:00
6cc75d1497 tests: workaround bash bug
Seems new bash4.3 is somewhat buggy
https://bugzilla.redhat.com/show_bug.cgi?id=1074202

Put in cheap workaround for now.
2014-03-10 12:24:10 +01:00
4eed2c8142 tests: skip valgrind testing when assigned to 0
When LVM_VALGRIND_CLVMD/LVMETAD is set to 0  skip testing.
(Proviosly any value caused to run valgrind testing,
so now '0' skips testing))
2014-03-10 12:24:10 +01:00
41e1b12e03 tests: skip another kernel
This kernel has still buggy kmem_cache debugging so skip it for raid456.
2014-03-10 12:24:10 +01:00
d913fcbd46 tests: improve wait for open
Add loop to detect open device from 'sleep <'
2014-03-10 12:24:10 +01:00
fa23234e71 tests: reuse existing check dev_md5sum
Create md5sum in reusable way and use exiting check function.
2014-03-10 12:24:10 +01:00
d080abf7d6 cleanup: dmeventd convert multiline to single line
Instead of doing multiple different calls, select
stream within a condition.

Replace fprintf with fputc for '\n'
2014-03-10 12:24:10 +01:00
7b17dfed69 cleanup: dmeventd code simplified
Improve readbility of code.
2014-03-10 12:24:10 +01:00
341055ddb3 cleanup: clvmd use struct initializers
Simplify code, and use compiler capability to
initilize struct members on its own.
2014-03-10 12:24:10 +01:00
c44ede31a3 cleanup: clvmd use else if
When string already matches, skip rest of tests.
2014-03-10 12:24:09 +01:00
2cfe0840d2 cleanup: clvmd assign NULL to pointers
Use NULL when assigning to void*.
2014-03-10 12:24:09 +01:00
c824369fbd cleanup: clvmd indent changes
Improve readbility of clvmd code.
Remove some unneeded braces.
2014-03-10 12:24:09 +01:00
109564d6a5 cleanup: clvmd simplify loops
Rewrite write loops to be more readable.
2014-03-10 12:24:09 +01:00
3d23404081 cleanup: clvmd rewrite send_message
Improve readability of code and make it clear what it tries
to achieve.
2014-03-10 12:24:09 +01:00
cbca815dc4 cleanup: clvmd reindent lock_vg code
Code had wrong indent level, improve readability.
2014-03-10 12:24:09 +01:00
7a6c0e2425 dmeventd: wakeup timeout thread earlier
When the last entry in the timeout queue is unregistered,
wakeup sleeping condition, so the thread is deleted earlier.
So the thread resource is release earlier.

Also when monitored with tools like valgrind this eliminites reported
leak.
2014-03-10 12:24:07 +01:00
2a9b62c7f9 dmeventd: remember number of log disablings
Individual events are handled through separate threads,
so once we have more then a single thread in this eventwait
sleeping, we got race on the dm_log setting, since
if one event is timeout out on alarm, while another is still waiting,
then dm log has been restored to NULL and the next sigalarm
has been reported as error.

Fix it by introducing counter which is protected via mutex,
and only when the last event is released, logging is restored.

TODO: libdm seems to have some static vars which may audit
for this type of use.
2014-03-10 12:22:47 +01:00
460c19df62 clvmd: fix memleak on exit
This patch will releases allocated private resources from
startup. Needs previous dm_zalloc patch to ensure unset
private pointer is NULL.

TODO: check on real cluster.
2014-03-10 12:21:32 +01:00
38ce06e448 clvmd: use dm_zalloc for socket allocation
Instead of doing individual settings for struct members,
ensure whole struct is in defined state.
2014-03-10 12:20:49 +01:00
bfffccca94 config: keep config paths with variable names properly marked on output 2014-03-07 18:04:02 +01:00
eeff7729d9 config: use small local static buffer instead of mempool for temporary config path
We can't use mempool for temporary variable for configuration path inside
find_config_tree_* functions since these functions can use the mempool
themselves deeper in the code and we can free mempool chunks only from
top to bottom which is not the case here (some default string
configuration values can be allocated from the mempool).
2014-03-07 17:50:01 +01:00
7409009a20 cleanup: remove superfluous slash in default cache dir path 2014-03-07 13:03:09 +01:00
ef1d910dee tests: updates for new test
snaphost needs exclusive origin for cluster
older md5 needs 2 space char
2014-03-06 18:01:21 +01:00
6b561a7a3b tests: check created snapshot has good max size
Testing if we are creating large enough old-snapshot
(so the COW max size is correct)
https://bugzilla.redhat.com/show_bug.cgi?id=1035871
2014-03-06 17:30:10 +01:00
d0673b0ddc tests: detect old-snap metadata consitency
Add some test for correctness of snapshot metadata.
Based upon original test from Mikulas.
Needs correctly working kernel snapshot target.
2014-03-06 17:30:10 +01:00
d5a00c4597 makefiles: link blkid library only to lvm
Don't add blkid to every linkage.
Link udev library just with lvm tools.
Drop extra linkage of udev library, since deps from libdevmapper
are already resolved in linked -ldevmapper.
2014-03-06 17:30:10 +01:00
7a595d7388 makefiles: use BLKID/UDEV_CFLAGS properly
blkid.h needs BLKID_CFLAGS
Do not add UDEV_CFLAGS everywhere and use it only when needed.
2014-03-06 17:30:06 +01:00
216c57eed7 readline: switch to new-style readline typedef
Based on patch:
https://www.redhat.com/archives/lvm-devel/2014-March/msg00015.html

The CPPFunction typedef (among others) have been deprecated in favour of
specific prototyped typedefs since readline 4.2 (circa 2001).
It's been working since because compatibility typedefs have been in
place until they where removed in the recent readline 6.3 release.
Switch to the new style to avoid build breakage.

But also add full backward compatibility with define.

Signed-off-by: Gustavo Zacarias <gustavo zacarias com ar>
2014-03-06 17:28:40 +01:00
061acd177f configure: drop duplicated SUBST
These subst are already there from pkg_config
2014-03-06 16:16:11 +01:00
cfc9e178bf tests: fix name-mangling test and remove udev transaction in dmsetup wrapper 2014-03-06 14:46:50 +01:00
42eb9b4526 WHATS_NEW: config handling changes 2014-03-06 13:03:51 +01:00
9a1d31a3c6 cleanup: remove superfluous forward declaration 2014-03-06 12:43:21 +01:00
74a3fc4e85 config: add default for allocation/cache_pool_chunk_size
The same as for allocation/thin_pool_chunk_size - the default value
used is just a starting point. The calculation continues using the
properties of the devices actually used.
2014-03-06 11:34:02 +01:00
d27868e94f config: runtime default for allocation/thin_pool_chunk_size
The allocation/thin_pool_chunk_size is a bit more complex. It's default
value is evaluated in runtime based on selected thin_pool_chunk_size_policy.
But the value is just a starting point. The calculation then continues
with dependency on the properties of the devices used. Which means for
such a default value, we know only the starting value.
2014-03-06 11:26:02 +01:00
932e75e89f config: separate cfg_def_default_value_hint out of cfg_def_get_default_value
If the config setting is defined as having no default value, but it's
still not NULL, it means such a value acts as a *hint* only
(e.g. a starting value from which the default value is calculated).

The new "cfg_def_get_default_value_hint" will always return the value
as defined in config_settings.h.

The original "cfg_def_get_default_value" will always return 0/NULL if
the config setting is defined with CFG_DEFAULT_UNDEFINED flag (hence
ignoring the hint).

This is needed for proper distiction between a correct default value
and the value which is just a hint or a starting point in calculation,
but it's not the final value (yes, we do have such settings!).
2014-03-06 11:18:19 +01:00
eecf191d3e config: runtime default for activation/mirror_image_fault_policy
The activation/mirror_image_fault_policy default value copies the
value (or default one) used for activation/mirror_device_fault_policy.
2014-03-06 11:16:23 +01:00
11039589d3 config: runtime default for config/profile_dir
The config/profile_dir default value takes LVM_SYSTEM_DIR into consideraton.
2014-03-06 11:16:04 +01:00
0da1e5d9f8 config: runtime default for backup/backup_dir, backup/archive_dir
The backup/backup_dir and backup/archive_dir default value is evaluated
in runtime and takes LVM_SYSTEM_DIR into consideration...
2014-03-06 11:15:21 +01:00
f6adef9825 config: runtime default for devices/cache, devices/cache_dir
The devices/cache and devices/cache_dir are evaluated in runtime this way:

  - if devices/cache is set, use it

  - if devices_cache/dir or devices/cache_file_prefix is set, make up a
    path out of that for devices/cache in runtime, taking into account
    the LVM_SYSTEM_DIR environment variable if set

  - otherwise make up the path out of default which is:
    <LVM_SYSTEM_DIR>/<cache_dir>/<cache_file_prefix>.cache

With the runtime defaults, we can encode this easily now. Also, the lvm
dumpconfig can show proper and exact information about this setting then
(the variant that shows default values).
2014-03-06 11:07:54 +01:00
b53ec37286 config: add CFG_DEFAULT_RUN_TIME for config options with runtime defaults
Previously, we declared a default value as undefined ("NULL") for
settings which require runtime context to be set first (e.g. settings
for paths that rely on SYSTEM_DIR environment variable or they depend
on any other setting in some way).

If we want to output default values as they are really used in runtime,
we should make it possible to define a default value as function which
is evaluated, not just providing a firm constant value as it was before.

This patch defines simple prototypes for such functions. Also, there's
new helper macros "cfg_runtime" and "cfg_array_runtime" - they provide
exactly the same functionality as the original "cfg" and "cfg_array"
macros when defining the configuration settings in config_settings.h,
but they don't set the constant default value. Instead, they automatically
link the configuration setting definition with one of these functions:

  typedef int (*t_fn_CFG_TYPE_BOOL) (struct cmd_context *cmd, struct profile *profile);
  typedef int (*t_fn_CFG_TYPE_INT) (struct cmd_context *cmd, struct profile *profile);
  typedef float (*t_fn_CFG_TYPE_FLOAT) (struct cmd_context *cmd, struct profile *profile);
  typedef const char* (*t_fn_CFG_TYPE_STRING) (struct cmd_context *cmd, struct profile *profile);
  typedef const char* (*t_fn_CFG_TYPE_ARRAY) (struct cmd_context *cmd, struct profile *profile);

(The new macros actually set the CFG_DEFAULT_RUNTIME flag properly and
set the default value link to the function accordingly).

Then such configuration setting requires a function of selected type to
be defined. This function has a predefined name:

  get_default_<id>

...where the <id> is the id of the setting as defined in
config_settings.h. For example "backup_archive_dir_CFG" if defined
as a setting with default value evaluated in runtime with "cfg_runtime"
will automatically have "get_default_backup_archive_dir_CFG" function
linked to this setting to get the default value.
2014-03-06 10:54:17 +01:00
e2870c94cf config: use mempool for config paths used in find_config_tree_* functions
Using mempool is much safer than using the global static variable.
The global variable would be rewritten on each find_config_tree_* call
and we need to be very careful not to get into this problem (we don't
do now, but we can with the patches for "runtime defaults" that will follow).
2014-03-06 10:50:47 +01:00
c5a4e60c11 config: fixup default values for selected config settings
These settings don't have any default value predefined:
  log/file
  log/activate_file
  global/library_dir

This settings has default value but not yet declared in config_settings.h:
  global/locking_library (default is DEFAULT_LOCKING_LIB)
2014-03-06 09:49:57 +01:00
52aa3dbcab cmirrord: Clean-up stray warning message
cmirrord polls for messages on the kernel and cluster interfaces.
Sometimes it is possible for messages to be received on the cluster
interface and be waiting for processing while the node is in the
process of leaving the cluster group.  When this happens, the
messages received on the cluster interface are attempted to be
dispatched, but an error is returned because the connection is no
longer valid.  It is a harmless situation.  So, if we get the
specific error (CS_ERR_BAD_HANDLE) and we know that we have left
the group, then simply don't print the message.
2014-03-05 10:44:20 -06:00
2c42f60890 udev: run pvscan --cache via systemd-run in udev if the PV label is detected lost
If the PV label is lost (e.g. by doing a dd on the device), call
"systemd-run pvscan --cache <major>:<minor>" in 69-dm-lvm-metad.rules
to inform lvmetad about this state.

The reason for this is that ENV{SYSTEMD_WANTS}="lvm2-pvscan@<major>:<minor>"
logic will not cause the pvscan to be fired in this case since this works
only on proper device addition/removal cycle - the lvm2-pvscan service's
ExecStop is called only on proper REMOVE event - the service is bound to
device existence. Hence we need pvscan call via systemd-run (that
instantiates a quick transient service just to call the command).

See also https://bugzilla.redhat.com/show_bug.cgi?id=1063813.
2014-03-05 14:30:58 +01:00
3c9887467f test: Use correct path to /dev in lvchange-raid.sh. 2014-03-05 10:22:39 +01:00
08aedff1fc tests: testing usable of /dev/kmsg
It's not so easy to recongnize unusable /dev/kmsg
Reorder the code in a way if the first regular read of /dev/kmsg
fail, fallback to klogctl interface.

Call drain_dmesg also for the case there is no user log output.
2014-03-04 17:54:33 +01:00
9a99cb8c79 tests: hide error message
Make the logging looks normal for this case
2014-03-04 16:41:07 +01:00
a01e2ff81c tests: print kernel version 2014-03-04 16:27:00 +01:00
b47bdb4dca tests: check readability of /dev/kmsg
Looks like there are systems with /dev/kmsg device,
which is however not readable

Fix check for result value of klogctl and use only positive value.
2014-03-04 16:27:00 +01:00
30810de1b0 tests: reinstantiate support for klogctl
Add a bit more complexity here - Switch to use /dev/kmsg
which has been introduced in 3.5 kernels and could run without
lossing lines from /proc/kmsg.

On older systems user may set env var LVM_TEST_CAN_CLOBBER_DMESG=1
to get kernel messages via klogctl() call (which deletes dmesg buffer)
otherwise no logging of kernel messages is provided.
2014-03-04 15:18:19 +01:00
cb77bdc253 test: Make teardown (more) resistant to funny DM device names. 2014-03-04 11:16:00 +01:00
d739e16d85 tests: restore .txt suffix 2014-03-03 19:30:48 +01:00
719261a33a tests: speedup kmsg processing
Since there could be multiple readers of kmsg (test & journald) it needs
to be fast, to capture things like sysrq trace.

But to capture whole output it would need to prioritize reading of kmsg,
thus we would first log kernel messages and followed by command output.

As a trade-off always log command output first and use large drain
buffer so is captures most of messages, but occasionaly miss some
lines.
2014-03-03 19:30:47 +01:00
52007a9191 tests: split raid test
Use separate files for raid1, raid456, raid10.
They need different target versions to work, so support
more precise test selection.

Optimize duplicate tests of target avalability and skip
unsupported test cases sooner.
2014-03-03 11:23:57 +01:00
a92fae079b lvmetad: fix minor gcc warning
Cast to pass in non-const pointer
2014-03-03 11:23:32 +01:00
445c0a5585 test: Remove incorrect evaluation 2014-03-03 08:31:33 +01:00
6df716332c tests: detect nc or socat
Since shell is not in -o pipefail mode here,
we need to generate separate failure ahead of tee.
2014-03-02 21:48:28 +01:00
6c377f5b3c tests: restore usage of reading kmsg
Basically reverts commit af8580d756.
"test: Use klogctl in the harness instead of reading /var/log/messages."

Problem is - this interface clears dmesg buffer
(just like call of dmesg -c)
Thus after running lvm2 test suitedmesg is empty - while all the
messages are usually logged in the journal/message, it's still not nice to
clear dmesg buffer.

It's not a pure revert, but switch to use /proc/kmsg directly instead of
reading /var/log/messages.
2014-03-02 21:30:26 +01:00
33d69162e4 tests: split raid test
Use separate test file for raid456
Change test for broken kernel which has broken raid456 support.
2014-03-02 21:27:26 +01:00
3ff10f5e61 tests: disable test which leaks node
This test is not detected as fault but leak device node
on a real /dev.
Added FIXME.
2014-03-02 21:27:26 +01:00
75b5855ca1 tests: report selinux mode 2014-03-02 21:27:26 +01:00
a2af5855c5 tests: use longer sleep
Eplore why 30sec is not enough for hydra and try higher value.
2014-03-02 21:27:25 +01:00
fade191aed test: Test that we cope with stray device nodes. 2014-03-02 20:53:43 +01:00
3b958984f1 test: Properly synchronize direct dmsetup calls. 2014-03-02 20:53:43 +01:00
72ecf8e591 tests: detect reiserfs support
Since reiserfs is not commonly available detect its presence in kernel.
Stop reporting skipped test as WARNING.
2014-03-01 14:08:59 +01:00
090e81281f lvmetad: more reuse precommit buffer
This patch moves more allocation to vg_write
(as started in 8c878438f5)
TODO: relocate also communication.
(in-release update)
2014-03-01 14:08:58 +01:00
bda98c4b8d lvmetad: move memalloc/free out of lock
Small code move to lower locking time and make memory
allocation and free outside of lock.

Drop duplicate test of NULL pointer before calling dm_free.
2014-03-01 14:08:58 +01:00
d8513da9be lvmetad: fix memleak when pv changes it device
Test vgimportclone invokes mem leak of pvid which
would be otherwise lost when device_old_pvid
is removed from hash table.
2014-03-01 14:00:15 +01:00
c8e868f6e0 lvmetad: Fix an invalid memory read that could cause a deadlock. 2014-03-01 00:42:09 +01:00
301ac8a07c NIX: Cope with existence of multiple primary.xml files.
This can happen temporarily while a mirror is syncing (parsing repomd.xml
would be a better fix, but slightly tricky since it's xml).
2014-02-28 23:56:04 +01:00
daa897fe90 test: Fix stat calls in lvmetad-pvscan-filter. 2014-02-28 23:33:30 +01:00
1bb29bb402 test: Downgrade lvmetad-lvm1 failure to a warning. 2014-02-28 23:33:17 +01:00
6733ac86d7 test: Fix the failing branch in aux lvmetad_talk. 2014-02-28 23:30:17 +01:00
fb003cdfd5 format-text: Fix a warning. 2014-02-28 16:23:16 +01:00
3e5bec37e9 format-text: Fix _raw_read_mda_header (missing close, open r/o). 2014-02-28 16:21:09 +01:00
c69d37d126 spec: udev rules don't live under %{_prefix} on fc16/rhel6 2014-02-28 14:18:15 +01:00
f3b9fe6024 test: Add lvmetad_talk and lvmetad_dump to aux. 2014-02-28 11:23:53 +01:00
8e814eb899 test: Fix notify_lvmetad for symlinked devices. 2014-02-28 11:23:53 +01:00
bf29eabdba lvmetad: Keep the cache consistent when a PV moves around.
In cases where PV appears on a new device without disappearing from an old one
first, the device->pvid pointers could become ambiguous. This could cause the
ambiguous PV to be lost from the cache when a different PV comes up on one of
the ambiguous devices.
2014-02-28 11:23:52 +01:00
a368698672 lvmetad: Hide corrupt MDAs from the cache.
This is probably not optimal, but makes the lvmetad case mimic non-lvmetad code
more closely. It also fixes vgremove of a partially corrupt VG with lvmetad, as
_vg_write_raw (and consequently, entire vg_write) currently panics when it
encounters a corrupt MDA. Ideally, we'd be able to explicitly control when it is
safe to ignore them.
2014-02-28 11:23:52 +01:00
6b43db5804 NIX: Change the URL for the lcov RPM to a more canonic location. 2014-02-28 11:23:52 +01:00
ea5ec4ad51 NIX: Update the release.nix path in build.sh. 2014-02-28 11:23:52 +01:00
b86489843e NIX: Add a short README (to be expanded). 2014-02-28 11:23:52 +01:00
421ca4cd14 spec: Add a copyright header and an explanatory notice. 2014-02-28 11:23:52 +01:00
658f8976a3 NIX: Move nix-related bits under nix/. 2014-02-28 11:23:52 +01:00
244b80d948 spec: Package the new clvmd/cmirrord systemd units. 2014-02-28 11:23:52 +01:00
9770c03ce0 NIX: On RHEL<=6 and FC<=16, udevd is /sbin/udevd. 2014-02-28 11:23:52 +01:00
2c99601267 NIX: Add a local nix-build.sh script. 2014-02-28 11:23:52 +01:00
fb2c6fffe1 NIX: Add CentOS 6.5 builds. 2014-02-28 11:23:52 +01:00
31e8fa883d NIX: Retire the CentOS 6.3 builds. 2014-02-28 11:23:52 +01:00
55964cedcb NIX: Use vault.centos.org to get older revisions. 2014-02-28 11:23:52 +01:00
cc6ed8fa66 spec: We do want thin support on RHEL 6. 2014-02-28 11:23:52 +01:00
4d081f072f spec: Do not treat --with-?=none as having the thing. 2014-02-28 11:23:51 +01:00
581eeaf950 spec: Explicitly disable thin when we don't want it. 2014-02-28 11:23:51 +01:00
9c8db4e33f NIX: Run system-wide tests separately, with RPMs installed. 2014-02-28 11:23:51 +01:00
d567d0d307 spec: Make it possible for %check_commands to prevent %clean-ing. 2014-02-28 11:23:51 +01:00
00dee59702 NIX: Revert to calling make check inside the RPM build. 2014-02-28 11:23:51 +01:00
13d5c78a8d spec: Add lvm2-pvscan@.service to filelist. 2014-02-28 11:23:51 +01:00
49ea253aaf spec: Add thin-performance.profile to the filelist. 2014-02-28 11:23:51 +01:00
8a0cf9cb0a NIX: Update URL for lcov RPM. 2014-02-28 11:23:51 +01:00
7cb3e7d016 NIX: Skip autoconf, as we include ./configure in git. 2014-02-28 11:23:51 +01:00
2b953df0f9 NIX: Try harder to set dmesg levels. 2014-02-28 11:23:51 +01:00
fe4d473c5b NIX: Give the VMs more RAM (768M instead of 512M). 2014-02-28 11:23:51 +01:00
7fea3f4469 NIX: Fix a centos64 failure due to old dmesg. 2014-02-28 11:23:51 +01:00
4eaaad0caa NIX: Do not insmod 9p/virtfs on centos64 as it BUGs out right away. 2014-02-28 11:23:51 +01:00
9434611924 NIX: Restore CIFS modules, as 9p is broken on many kernels. 2014-02-28 11:23:51 +01:00
5f60d53fcc NIX: Add %with thin_dump to the specfile. 2014-02-28 11:23:51 +01:00
bf67c0b393 NIX: Add %with thin_repair to the specfile. 2014-02-28 11:23:50 +01:00
adf262e079 NIX: Fedora 19 is now stable. Add builds that include updates. 2014-02-28 11:23:50 +01:00
39d00da752 NIX: Use the new "check_full" target for comprehensive testing. 2014-02-28 11:23:50 +01:00
765337dcc1 nix: Look a bit harder for udevd. 2014-02-28 11:23:50 +01:00
2df5eb250d nix: Set kernel console log level to debug. 2014-02-28 11:23:50 +01:00
4fc075e040 nix: Run udevd in foreground. 2014-02-28 11:23:50 +01:00
4757ef824c NIX: Run tests with /dev and (on recent Fedora) with udevd running. 2014-02-28 11:23:50 +01:00
9c927f7b27 NIX: Fix chrooted builds, passing down package lists explicitly. 2014-02-28 11:23:50 +01:00
a0d3a7d569 NIX: The mergeUsr attribute was renamed to unifiedSystemDir. 2014-02-28 11:23:50 +01:00
cad28a49ab NIX: Add default.profile to the spec file. 2014-02-28 11:23:50 +01:00
28143505f8 NIX: Add an fc18 build that includes fedora updates. 2014-02-28 11:23:50 +01:00
c5fbccab21 NIX: Adapt to use of 9P in VM builds. 2014-02-28 11:23:50 +01:00
9716af8c14 NIX: Make it possible to only run a subset of tests (via T). 2014-02-28 11:23:50 +01:00
39c8cd3d05 NIX: Fix a couple typos in build product handling. 2014-02-28 11:23:50 +01:00
4fdcb27b3e NIX: Copy collected test results into the output. 2014-02-28 11:23:49 +01:00
f6350b4568 NIX: Grab specfile from lvm2Nix (at least for now). 2014-02-28 11:23:49 +01:00
2f16d2ce27 NIX: Fix build-dependencies for FC 18. 2014-02-28 11:23:49 +01:00
2fbc94f974 nix: Import the modular specfile we use for nix-driven builds. 2014-02-28 11:23:49 +01:00
38ab4c31a6 test: warn rather than fail when %FREE isn't working right
%FREE allocation has been broken for RAID.  At 100%FREE, there is
still an extent left for certain tests.  For now, change the test
to warn rather than completely fail.
2014-02-27 22:47:30 -06:00
a7dc422bde tests: remove extra vgremove
These vgremove calls were not correct.
2014-02-27 14:53:33 +01:00
c23cd12023 tests: quote dev 2014-02-27 14:49:49 +01:00
f4afd07700 tests: drop remove
Generates waaaaay too much log from lvmetad test.

TODO: once we will be able to remove more LVs with a single
write - we may restore....
2014-02-27 14:48:32 +01:00
07ba047116 cleanup: relocate segment flags
Move flags for segments to segtype header where it seems more closely
related as the features are related to segtype and not activation.

Use unsigned #define - since it's more common in lvm2 source code
for bit flags.
2014-02-27 14:46:11 +01:00
47b15b805e tests: updates
Add some vgremove calls.
Remove uneeded test for some unused commands.
Add tests for missing commands.
2014-02-27 13:01:04 +01:00
d00fc1de78 snapshot: correct previous snapshot commit
Condition was swapped - however since it's been based on 'random'
memory content it's been missed as attribute has not been set.

So now we have quite a few possible results when testing.

We have old status without separate metadata and
we have kernels with fixed snapshot leak bug.

(in-release update)
2014-02-27 13:00:49 +01:00
1769eddde7 lvmetad: Make token_mismatch handling more robust in the clients. 2014-02-26 15:11:00 +01:00
4143b284f8 lvmetad: Make "reason" in a token_mismatch reply more informative. 2014-02-26 15:10:21 +01:00
40e6176d25 snapshots: fix incorrect calculation of cow size
Code uses target driver version for better estimation of
max size of COW device for snapshot.

The bug can be tested with this script:
VG=vg1
lvremove -f $VG/origin
set -e
lvcreate -L 2143289344b -n origin $VG
lvcreate -n snap -c 8k -L 2304M -s $VG/origin
dd if=/dev/zero of=/dev/$VG/snap bs=1M count=2044 oflag=direct

The bug happens when these two conditions are met
* origin size is divisible by (chunk_size/16) - so that the last
  metadata area is filled completely
* the miscalculated snapshot metadata size is divisible by extent size -
  so that there is no padding to extent boundary which would otherwise
  save us

Signed-off-by:Mikulas Patocka <mpatocka@redhat.com>
2014-02-26 14:25:09 +01:00
014ba37cb1 lvresize: fix stripe size validation
While stripe size is twice the physical extent size,
the original code will not reduce stripe size to maximum
(physical extent size).

Signed-off-by: Zhiqing Zhang <zhangzq.fnst@cn.fujitsu.com>
2014-02-26 13:25:50 +01:00
b5e03c88b8 tests: support for older snapshot target version
TODO: unsure about 1.10...
2014-02-26 11:17:39 +01:00
aef6016011 tests: improve read-only test for snapshot
Switch to use ext2 to make it usable on older systems.
Previous test has not been able to catching problem.

Multiple tests are now put in.

FIXME: validate what is doing kernel target when
the header is undeleted and same chunk size is used.

It seems snapshot target successfully resumes and
just complains COW is not big enough:

kernel: dm-8: rw=0, want=40, limit=24
kernel: attempt to access beyond end of device

When chunk size is different it fails instantly.

For checking this with lvm2 and this test case use this patch:

--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -769,7 +769,7 @@ static int _read_activation_params(struct
lvcreate_params *lp,
        lp->permission = arg_uint_value(cmd, permission_ARG,
                                        LVM_READ | LVM_WRITE);

-       if (lp->snapshot) {
+       if (0 && lp->snapshot) {
                /* Snapshot has to zero COW header */
                lp->zero = 1;
                lp->wipe_signatures = 0;

---
and switch to use  -c 4 for both snapshots
2014-02-26 10:19:46 +01:00
2b044452e3 snapshot: zero cow header for read-only snapshot
When read-only snapshot was created, tool was skipping header
initialization of cow device.  If it happened device has been
already containing header from some previous snapshot, it's
been 'reused' for a newly created snapshot instead of being cleared.
2014-02-26 00:22:46 +01:00
3bb9eda97c man: Enhancements to various man pages for cache[-pool] segtypes
Better formatting.  More consistent naming.  Better clarity.
2014-02-25 12:17:03 -06:00
f8bf4d7dfb dumpconfig: add a comment to each config with variable name, use '<name>' to denote that for config paths
Just to make the dumpconfig output (the comments) more readable
when we hit configuration lines that have variable names (e.g. tags).
2014-02-25 11:32:54 +01:00
558c932444 dumpconfig: comment out config lines without default values defined
To make "lvm dumpconfig --type default" output to be usable like any
other config, we need to comment out lines that have no default value
defined. Otherwise, we'd have the output with config options
with blank or zero values which is not the same as when the value
is not defined! And such configuration can't be feed into lvm again
without further edits. So let's fix this.

Currently this covers these configuration options exactly:

  devices/loopfiles
  devices/preferred_names
  devices/filter
  devices/global_filter
  devices/types
  allocation/cling_tag_list
  global/format_libraries
  global/segment_libraries
  activation/volume_list
  activation/auto_activation_volume_list
  activation/read_only_volume_list
  activation/mlock_filter
  metadata/dirs
  metadata/disk_areas
  metadata/disk_areas/<disk_area>
  metadata/disk_areas/<disk_area>/start_sector
  metadata/disk_areas/<disk_area>/size
  metadata/disk_areas/<disk_area>/id
  tags/<tag>
  tags/<tag>/host_list
2014-02-25 11:32:54 +01:00
d0b5e51d29 config: use DMEVENTD_PATH for default dmeventd executable config 2014-02-25 11:32:29 +01:00
1b566a2152 cleanup: keep pv_count unsigned 2014-02-25 09:43:04 +01:00
e7d189baf7 allocation: add default path
Make it obvious for compiler extents is always defined for
valid code path.
2014-02-25 09:36:26 +01:00
3e49753e6c tests: cache needs 1.3 2014-02-25 09:36:07 +01:00
502213e06c mirror: move declaration to define
For compilation without cmirrord hide unused vars.
(in-release update)
2014-02-25 09:35:26 +01:00
962af71b76 mirror: look for mirror seg only in mirror LV
Find mirror seg only in MIRROR_IMAGE.
(in-release update)
2014-02-25 09:34:02 +01:00
b84797be32 cache: Disallow vgsplit when there are cache LVs in the VG
The code seems to work fine for the most trivial case - moving a
simple cache LV.  However, it can cause problems when trying to
split out other LVs on different VGs and there hasn't been sufficient
testing for LV stacks that contain cache to enable the code.  So,
we actively disable what is already broken and wait for the next
release to fix it.
2014-02-24 16:54:09 -06:00
b359b86f88 allocation: improve approx alloc with resize
Start to convert percentage size handling in lvresize to the new
standard.  Note in the man pages that this code is incomplete.
Fix a regression in non-percentage allocation in my last check in.

This is what I am aiming for:

-l<extents>
-l<percent> LV/ORIGIN
	sets or changes the LV size based on the specified quantity
	of logical logical extents (that might be backed by
	a higher number of physical extents)

-l<percent> PVS/VG/FREE
	sets or changes the LV size so as to allocate or free the
	desired quantity of physical extents (that might amount to a
	lower number of logical extents for the LV concerned)

-l+50%FREE - Use up half the remaining free space in the VG when
	carrying out this operation.

-l50%VG - After this operation, this LV should be using up half the
	space in the VG.

-l200%LV - Double the logical size of this LV.

-l+100%LV - Double the logical size of this LV.

-l-50%LV - Reduce the logical size of this LV by half.
2014-02-24 22:48:23 +00:00
8083143822 tests: add extra wait
Parallel upconvert & downconvert is now tested separately
in lvconvert-mirror-updown.sh
2014-02-24 21:13:36 +01:00
dc839fb361 tests: check for python before other tests 2014-02-24 21:13:36 +01:00
32138969f9 tests: enhance thin test
Add more tests to also check validaty of transaction_id
and also detect we are not leaving active unusable thin pool LVs.
2014-02-24 21:13:36 +01:00
9c9f4515ae tests: add some quotes
Use quotes for DM_DEV_DIR
2014-02-24 21:13:36 +01:00
f8780e2d79 tests: drop mirror from filter 2014-02-24 21:13:36 +01:00
a920bc1a40 cleanup: indent, drop unneeded braces 2014-02-24 21:13:35 +01:00
408e276a61 cleanup: extend struct init usage 2014-02-24 21:13:35 +01:00
0118d6aa48 cleanup: spelling 2014-02-24 21:13:35 +01:00
710c0df68a cleanup: reorder commonly available devs in system to the front
Just shorting strcmp....
2014-02-24 21:13:35 +01:00
5097463fb3 mirror: detect attrs just once
Reorder detection of cmirrord. Now if cmirrord is not
running, target will not try to load kernel log module,
for communication with cmirrord.

Whole check for attrs now also happens just once.
2014-02-24 21:13:11 +01:00
95fe823eba raid: use feature attributes for raid10
Test raid10 availability as a target feature (instead of doing
it in all the places where raid10 should be checked).

TODO: activation needs runtime validation - so metadata with raid10
are skipped from activation in user-friendly way in lvm2.
2014-02-24 21:10:13 +01:00
23c069d16f thin: cleanup target_present call
Mark 'seg' as unused attribute.
Pass seg as NULL (as it is unused) in this function.
2014-02-24 21:09:29 +01:00
8c878438f5 metadata: move vg parsing to vg_write
Parsing vg structure during  supend/commit/resume may require a lot of
memory - so move this into vg_write.

FIXME: there are now multiple cache layers which our doing some thing
multiple times at different levels. Moreover there is now different
caching path with and without lvmetad - this should be unified
and both path should use same mechanism.
2014-02-24 21:08:53 +01:00
203affffc7 libdm: enhance thin transaction_id validation
Reuse _node_send_messages for just checking
for valid transaction_id with preload.

This allows earlier detection of incosistent thin pool.

Code does the same thing, except for sending messages.
2014-02-24 21:06:31 +01:00
c7b7cb60e4 libdm: hardening transaction_id validation
Improve testing of transation_id to not allow other difference
then either kernel TID is equal or is lower by oned and there
are queued messages for transaction.

Mark messages as submitted if the transaction_id is already matching.

Do not try to deactivate node on failure here and leave it on
proper error path of the caller.
2014-02-24 21:04:50 +01:00
6116333ccc libdm: proper traversion of revert list
Deactivation of top level node has to happen,
before traversing subtree.

Swap list logic and rather append new nodes to the head
and then use normal iteration.

(in-release update)
2014-02-24 21:01:59 +01:00
1911c61639 libdm: call preload callback only when success
Do not call node's preload callback, if there is
any failure during preload.
2014-02-24 21:01:13 +01:00
c132fc3ff6 libdm: drop unneded assignment 2014-02-24 20:59:10 +01:00
8346f106b4 libdm: internal is_selinux_enabled wrapper
There is no point to call this external function more then once.
(As suggested by selinux developer)
2014-02-24 20:58:41 +01:00
ee89ac7b88 pvmove: Disallow pvmove of cache LVs
Skip over LVs that have a cache LV in their tree of LV dependencies
when performing a pvmove.

This means that users cannot move a cache pool or a cache LV's origin -
even when that cache LV is used as part of another LV (e.g. a thin pool).

The new test (pvmove-cache-segtypes.sh) currently builds up various LV
stacks that incorporate cache LVs.  pvmove tests are then performed to
ensure that cache related LVs are /not/ moved.  Once pvmove is enabled
for cache, those tests will switch to ensuring that the LVs /are/
moved.
2014-02-24 12:25:18 -06:00
fdb7356d6a test: Add cache[pool] support to lv_tree_devices_ test suite function. 2014-02-24 10:40:00 -06:00
f3d1debb18 cache: Disallow resizing of cache related LVs
For now, disallow lvextend/lvreduce/lvresize of cache LVs, cache
pool LVs, and cache pool sub-LVs.
2014-02-24 10:19:50 -06:00
46223c4284 test: move RAID10 tests from lvcreate-raid.sh to lvcreate-raid10.sh 2014-02-21 18:28:16 -06:00
13c3f53f55 allocation: misc fixes for percent/raid rounding
Several fixes for the recent changes that treat allocation percentages
as upper limits.
Improve messages to make it easier to see what is happening.
Fix some cases that failed with errors when they didn't need to.
Fix crashes when first_seg() returns NULL.
Remove a couple of log_errors that were actually debugging messages.
2014-02-22 00:26:01 +00:00
294671fa62 test: Only try raid10 on dm-raid versions that support it. 2014-02-21 19:47:06 +01:00
84d02542bd WHATS_NEW: for commit b391ae88e5 2014-02-21 11:36:55 +01:00
bbe4aca7c4 coverity: check dm_strncpy return value in dmeventd/_get_parameters 2014-02-20 15:06:13 +01:00
08116a4962 cleanup: missing header file 2014-02-20 09:07:38 +01:00
5e83682ccf tests: add small test for clustered conversion of mirror
Test currently fails with make check_cluster - so uses 'should'

CLVMD[4f435880]: Feb 19 23:27:36 Send local reply
format_text/archiver.c:230   WARNING: This metadata update is NOT backed up
metadata/mirror.c:1105   Failed to initialize log device
metadata/mirror.c:1145         <backtrace>
lvconvert.c:1547         <backtrace>
lvconvert.c:3084         <backtrace>
2014-02-19 23:34:07 +01:00
b391ae88e5 format-text: Avoid a label_scan while in a critical_section(). 2014-02-19 17:43:30 +01:00
00ce01e52d cache-pool: Change segtype name from cache_pool to cache-pool
Thin pools use "thin-pool" for the segment type name.  To be consistent,
we use "cache-pool" instead of "cache_pool".
2014-02-19 09:26:03 -06:00
c71a3bcbc0 activation: lv_activation_skip remove always same arg.
Remove 'skip' argument passed into the function.
We always used '0' - as this is the only supported
option (-K) and there is no complementary option.

Also add some testing for behaviour of skipping.
2014-02-19 11:33:39 +01:00
750a310a40 cleanup: indent 2014-02-18 21:22:00 +01:00
e6fd16f8ea cleanup: use is_change_activating
Use a single inline function to detect activation/deactivation
2014-02-18 21:21:59 +01:00
fb519c35bb cleanup: move verbose message to lv_activation_skip
Simplify code and put verbose message into a single place.
2014-02-18 20:49:32 +01:00
fdcd95a3b3 tests: check locking is not lost during thin_check 2014-02-18 14:58:41 +01:00
417e52c13a udev: create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for a PV
We already have /dev/disk/by-id/dm-uuid-... (which encompasses the
VG UUID and LV UUID in case of LVs since the mapping's UUID is
VG+LV UUID together) and /dev/disk/by-id/dm-name-... (which encompasses
the VG and LV name in case of LVs).

This patch addds /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> that completes
this scheme and makes navigation a bit easier using PV UUIDs since
one can navigate using PV UUIDs only and there's no need to do extra
PV UUID <--> kernel name matching (the PV UUID is stable across reboots).
This may come in handy in various scripts.

Since we already have the PV UUID stored in udev database (as a result
of blkid call - returned in ID_FS_UUID blkid's variable), this operation
is very cheap indeed, just creating the extra one symlink.
2014-02-18 11:37:20 +01:00
0e0f91b6dd tests: use exclusive activation for mirror case
Since mirror doesn't take exclusive lock implicitely yet,
enforce it for cluster testing.
2014-02-18 10:39:29 +01:00
b1e8284f33 pvcreate: do not print stack when pv not found while doing pvcreate_check
Not finding an existing PV on a disk where we're just
creating the PV is not an error or any bad condition.
Remove misleading "stack" call.
2014-02-18 10:01:11 +01:00
6a00a7e33d RAID: Allow implicit stripe (and parity) when creating RAID LVs
There are typically 2 functions for the more advanced segment types that
deal with parameters in lvcreate.c: _get_*_params() and _check_*_params().
(Not all segment types name their functions according to this scheme.)
The former function is responsible for reading parameters before the VG
has been read.  The latter is for sanity checking and possibly setting
parameters after the VG has been read.

This patch adds a _check_raid_parameters() function that will determine
if the user has specified 'stripe' or 'mirror' parameters.  If not, the
proper number is computed from the list of PVs the user has supplied or
the number that are available in the VG.  Now that _check_raid_parameters()
is available, we move the check for proper number of stripes from
_get_* to _check_*.

This gives the user the ability to create RAID LVs as follows:
# 5-device RAID5, 4-data, 1-parity (i.e. implicit '-i 4')
~> lvcreate --type raid5 -L 100G -n lv vg /dev/sd[abcde]1

# 5-device RAID6, 3-data, 2-parity (i.e. implicit '-i 3')
~> lvcreate --type raid6 -L 100G -n lv vg /dev/sd[abcde]1

# If 5 PVs in VG, 4-data, 1-parity RAID5
~> lvcreate --type raid5 -L 100G -n lv vg

Considerations:
This patch only affects RAID.  It might also be useful to apply this to
the 'stripe' segment type.  LVM RAID may include RAID0 at some point in
the future and the implicit stripes would apply there.  It would be odd
to have RAID0 be able to auto-determine the stripe count while 'stripe'
could not.

The only draw-back of this patch that I can see is that there might be
less error checking.  Rather than informing the user that they forgot
to supply an argument (e.g. '-i'), the value would be computed and it
may differ from what the user actually wanted.  I don't see this as a
problem, because the user can check the device count after creation
and remove the LV if they have made an error.
2014-02-17 20:18:23 -06:00
0be6caba6e tests: drop more debug.log
Avoid login result from last lvm command when target_at_least fails.
2014-02-17 22:25:53 +01:00
18cac16540 tests: more clustered testing 2014-02-17 22:25:53 +01:00
37cf201906 tests: on older system use mirror type 2014-02-17 22:25:53 +01:00
8eedb18c73 tests: add short delay
Give some extra delay so the file will be opened.
2014-02-17 22:25:53 +01:00
9974136b90 cleanup: indent 2014-02-17 22:25:53 +01:00
25cea92338 thin: fix merge of old snaphost
Fix merging of old snapshot into thinvolume origin.
Add also internal error for the error case when
merging requests activation of merged LV.
2014-02-17 22:25:53 +01:00
f33a224ef0 scripts: use --ignoreskippedcluster in lvm2-monitor initscript/systemd unit
When clustered VG is available in the system but we don't have
clustering set up for whatever reason, the lvm2-monitor scripts should
not fail completely just because these clustered VGs are skipped during
vgs/vgchange calls in lvm2-monitor initscript/systemd unit.
2014-02-17 16:29:49 +01:00
6e2f706233 cleanup: use struct initializer 2014-02-15 11:36:53 +01:00
a508786664 cleanup: indent spaces 2014-02-15 11:36:53 +01:00
c651c614ec cache: using unsigned argc
Convert using unsigned for _argc.
2014-02-15 11:36:53 +01:00
da268eb4cc cache: convert libdm to use plain function call
Avoid introducing libdm structure allocated in library user.
Use direct call with all currently supported args.
When new arg is added, new function will cover it.
2014-02-15 11:36:53 +01:00
7ec8e691c4 libdm: use 64bit type for raid index
Used properly signed 64bit constant for shifting.
2014-02-15 11:36:37 +01:00
f0f4248333 activation: drop test r/w vg state for activing LV
VG status read/write is meant to influence only VG metadata.
It's not related to the read/write status of the LV itself.
2014-02-15 11:34:54 +01:00
fa4812bf7b cache: Fix cache LV not being instantiated in kernel
When an origin exists and the 'lvcreate' command is used to create
a cache pool + cache LV, the table is loaded into the kernel but
never instantiated (suspend/resume was never called).  A user running
LVM commands would never know that the kernel did not have the
proper state unless they also ran the dmsetup 'table/status' command.
The solution is to suspend/resume the cache LV to make the loaded
tables become active.
2014-02-14 16:04:31 -06:00
554159d519 systemd: do not use default dependencies for clvmd/cmirrord units
Do not use default dependencies that systemd adds to the units
so we have better control of when the service is started/stopped
and we don't end up with unexpected behaviour.
2014-02-14 14:37:19 +01:00
4210219a8b systemd: Use --ignoreskippedcluster in generated activation systemd units
When the activation units are generated if use_lvmetad=0 (no
autoactivation), use --ignoreskippedcluster option for vgchange calls
since the cluster with cLVM is set up by separate units.

This avoids a situation in which the generated activation units are
improperly in failed state just because of the vgchange return value
when clustered VGs are encountered while the activation of non-clustered
VGs does proceed normally.
2014-02-14 11:59:12 +01:00
94d8779ae2 Update WHATS_NEW for approximate allocation check-in 2014-02-13 21:12:28 -06:00
4b6e3b5e5e allocation: Allow approximate allocation when specifying size in percent
Introduce a new parameter called "approx_alloc" that is set when the
desired size of a new LV is specified in percentage terms.  If set,
the allocation code tries to get as much space as it can but does not
fail if can at least get some.

One of the practical implications is that users can now specify 100%FREE
when creating RAID LVs, like this:
~> lvcreate --type raid5 -i 2 -l 100%FREE -n lv vg
2014-02-13 21:10:28 -06:00
f4658b53d7 man: Add example/explanation section for cache LVs to lvm.8
I've added an "Advanced Logical Volume Types" section that I hope
to contain information on the logical volume types that may use
multiple steps and multiple commands to create.  Cache is the
first entry into this section.  I'd like to see thin and RAID in
here in the future.
2014-02-13 11:53:31 -06:00
907641cd3d cache: Update man page to reflect need for dm-cache 1.3.0
Update the man page so the user knows that dm-cache 1.3.0 module
is needed.  Also, enforce that in the code and print a warning if
the module is not new enough.
2014-02-13 09:13:57 -06:00
a060b3b390 Fix premature return from get_pool_params 2014-02-13 10:50:56 +01:00
e8225b8615 cache: Do not configure cache[pool] support by default
Users wanting cache[_pool] segment type support need to include
"--with-cache=internal" when configure'ing.
2014-02-12 10:58:20 -06:00
5bfe4aaf95 cache[pool]: Man page updates for lvs, lvcreate, lvconvert 2014-02-12 10:29:07 -06:00
0912cf67aa cache: Ability to convert an existing LV into a cached LV
Users now have the ability to convert their existing logical volumes
into cached logical volumes.  A cache pool LV must be specified using
the '--cachepool' argument.  The cachepool is the small, fast LV used
to cache the large, slow LV that is being converted.
2014-02-12 09:55:35 -06:00
c8b6c4aee9 cachepool: Ability to convert existing LVs to cachepool type
This patch allows users to convert existing logical volumes into
cache pool LVs.  Since cache pool LVs consist of data and metadata
sub-LVs, there is also the '--poolmetadata' (similar to thin_pool)
which allows for the specification of the metadata device.
2014-02-12 09:51:42 -06:00
48aef76ec5 cache: lv_cache_create returns LV ptr, so return NULL not 0 on error 2014-02-11 13:47:26 -06:00
d68e5d5ab9 tests: utilize check and get
Replace some in-test use of lvs commands with their check
and get equivalent.

Advantage is these 'checking' commands are not necessarily always
valiadated via extensive valgrind testing and also the output noice
is significantly reduces since the output of check/get is suppressed.
2014-02-11 19:00:07 +01:00
177db48c11 tests: add check lv_not_exists 2014-02-11 19:00:06 +01:00
4ed831e7ef tests: remove debug.log in enable_dev
In aux functions we may drop debug log from
last running lvm command - so we do not
get debug log from properly executed command,
when we fail here.
2014-02-11 19:00:06 +01:00
108ae0edc6 cleanup: fix some lvm.conf typos 2014-02-11 19:00:06 +01:00
9d69585b82 cleanup: remove unneeded header files 2014-02-11 19:00:06 +01:00
e5d59d9618 cleanup: use string constant with '_' 2014-02-11 19:00:06 +01:00
f86e18bfeb cleanup: condition reodering
Check SEG_CANNOT_BE_ZEROED before even calling arg_str_value which
is not needed in this case.

Set it to 1 or 0 and not just result of strcmp call.
2014-02-11 19:00:06 +01:00
bcd6b643be cleanup: update clearing message
Since some targets are using this routine to setup
other values then 0 and also may clear much more data then
just disk header - add better message.
2014-02-11 18:59:22 +01:00
40a9c443a9 man: use some existing indentifier
Avoid confusing user, since some may get impression there is
such variable (max_archives) in the config file.
Pick rather something existing.
2014-02-11 18:55:54 +01:00
c1faa4048a lvm2app: access params after its checked
Since params is checked for NULL, move code that dereferences
params after its check.
2014-02-11 18:50:37 +01:00
38e457c478 raid: drop invalid modication of active parameter
lv_active_change will enforce proper activation.
Modification of activation was wrong and lead to misuse of
autoactivation. Fix allows to use proper local exclusive activation,
while the removed code turned this into just exclusive
activation (losing required local property).
2014-02-11 18:48:38 +01:00
8a21dcebac raid: use unsigned 64b constant for shift 2014-02-11 18:47:15 +01:00
1a5062c9a7 cleanup: clarify man pages about lvchange/vgchange -aay, use -aay in lvm2-cluster-activation script 2014-02-11 13:48:04 +01:00
a092cd33be systemd: rename lvm2-cluster-activation and lvm2-clvmd services to follow existing naming
lvm2_cluster_activation_red_hat.service.in -> lvm2_cluster_activation_systemd_red_hat.service.in
lvm2_clvmd_red_hat.service.in -> lvm2_clvmd_red_hat.service.in

Edit lvm2-cluster-activation reference on cmirror - take new
lvm2-cmirrord.service, it was just cmirrord(.service) before
as the old initscript was used in compatibility mode.

Also, use WantedBy=multi-user.target instead of sysinit.target
in lvm2-cluster-activation.service.
2014-02-11 10:12:39 +01:00
ef91de2a0c systemd: add systemd unit for cmirrord 2014-02-11 10:06:19 +01:00
a0d64554e6 autoreconf: latest changes 2014-02-10 19:02:18 +01:00
fd41dd8f9c Add systemd native service for clvmd and cluster activation
The commit splits original clvmd service in two new native services
for systemd enabled systems while original init scripts remain unaltered.

New systemd native services:

  1) clvmd daemon itself (lvm2_clvmd_red_hat.service.in)
  2) (de)activation of clustered VGs (lvm2_cluster_activation_red_hat.service.in)

There're several reasons to split it. First, there's no support for conditional
stop in systemd and AFAIK they don't plan to support it. In other words:
if the deactivation fails for some reason, systemd doesn't care and will simply
kill all remaining processes in original cgroup (by default). Killing the
remaining procs can be suppressed however it doesn't solve the following problem:

You can't repeat the stop command of a failed service. The repeated stop command
is simply not propagated to the service in a failed state. You would have to start
and then try to stop the service again. Unfortunately, this can't be done while
the daemon is still running (and we need the daemon to stay active until all
clustered VGs are deactivated properly).

In a separated setup we need only to restart the failed activation service and
that's fine.
2014-02-10 17:13:49 +01:00
ffa623c53d systemd: cleanup for lvmetad systemd unit
No need to fork lvmetad when running under systemd.
Also, the "lvmetad -R" support has been removed in lvm2 v2.02.98
so remove the ExecReload line that called it on "systemctl reload".
2014-02-10 16:20:45 +01:00
38457e1be9 libdevmapper-event: Print a deprecation warning for non-default plugins. 2014-02-10 14:52:59 +01:00
ed166a3b1d wiping: wipe DM_snapshot_cow signature without prompt in newly created LVs
The libblkid can detect DM_snapshot_cow signature and when creating
new LVs with blkid wiping used (allocation/use_blkid_wiping=1 lvm.conf
setting and --wipe y used at the same time - which it is by default).

Do not issue any prompts about this signature when new LV is created
and just wipe it right away without asking questions. Still keep the
log in verbose mode though.
2014-02-10 13:28:13 +01:00
5635816094 cleanup: missing parentheses in a condition
gcc reports:
  metadata/merge.c:229:58: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
  metadata/merge.c:232:58: warning: suggest parentheses around '&&' within '||' [-Wparentheses]
2014-02-10 09:05:17 +01:00
290e58b0b6 WHATS_NEW: latest commits 2014-02-06 18:19:24 +01:00
73f30ed6a4 dmeventd: check pidfile for exit instead of polling via protocol
Since we use unlink + _exit now on dmeventd DIE message, we can
check the pidfile existence to see whether the dmeventd has finished.
2014-02-06 17:53:03 +01:00
90286fa0e9 dmeventd: use _exit(0) instead of raise(9) on dmeventd DIE message
Just a cleaner way to die.
2014-02-06 17:41:13 +01:00
fbeb08f320 dmeventd: add DM_EVENT_GET_PARAMETERS request to dmeventd protocol
The DM_EVENT_GET_PARAMETERS requests the parameters under which
the running dmeventd is run and the it sends them to caller.

The parameters sent:
  - the pid of the running dmeventd
  - foreground state
  - exec_method (currently either "direct" or "systemd")

The exact message sent back:
  pid=<pid> daemon=<no/yes> exec_method=<direct/systemd>
2014-02-06 17:41:12 +01:00
8a8abc5ed9 dmeventd: fix dmeventd -R to work properly with systemd
Trying to restart dmeventd as a reload action is causing problems
under systemd environment. The systemd loses track of new dmeventd
this way. See also https://bugzilla.redhat.com/show_bug.cgi?id=1060134
for more info.

We need to call dmeventd -R directly instead of "systemctl reload dm-event.service"
that was used before (the reload is aimed at configuration reload anyway,
not stateful restart of the daemon - we did this before just because
there's no ExecRestart in systemd and there's only ExecStart and
ExecStop with which we'd lose the state).

Also, use ExecStart="dmeventd -f" to run dmeventd in foreground
(and let's rely on systemd to daemonize it) and change the
service type from "forking" to "simple".
2014-02-06 17:15:19 +01:00
36f9fadcb4 cache[pool]: Populate existing report fields with cache data
For the report fields that already exist that are relevent to cache
and cache pool LVs (like 'origin', 'metadata_lv', etc), populate
them.
2014-02-05 09:44:37 -06:00
96626f64fa cache: Code to allow the create/remove of cache LVs
This patch allows users to create cache LVs with 'lvcreate'.  An origin
or a cache pool LV must be created first.  Then, while supplying the
origin or cache pool to the lvcreate command, the cache can be created.

Ex1:
Here the cache pool is created first, followed by the origin which will
be cached.
~> lvcreate --type cache_pool -L 500M -n cachepool vg /dev/small_n_fast
~> lvcreate --type cache -L 1G -n lv vg/cachepool /dev/large_n_slow

Ex2:
Here the origin is created first, followed by the cache pool - allowing
a cache LV to be created covering the origin.
~> lvcreate -L 1G -n lv vg /dev/large_n_slow
~> lvcreate --type cache -L 500M -n cachepool vg/lv /dev/small_n_fast

The code determines which type of LV was supplied (cache pool or origin)
by checking its type.  It ensures the right argument was given by ensuring
that the origin is larger than the cache pool.

If the user wants to remove just the cache for an LV.  They specify
the LV's associated cache pool when removing:
~> lvremove vg/cachepool

If the user wishes to remove the origin, but leave the cachepool to be
used for another LV, they specify the cache LV.
~> lvremove vg/lv

In order to remove it all, specify both LVs.

This patch also includes tests to create and remove cache pools and
cache LVs.
2014-02-04 16:50:16 -06:00
97be8b3482 cache: Code changes to allow creation of cache pools
This patch allows the creation and removal of cache pools.  Users are not
yet able to create cache LVs.  They are only able to define the space used
for the cache and its characteristics (chunk_size and cache mode ATM) by
creating the cache pool.
2014-02-04 11:57:08 -06:00
013cf27bff cache pool: Add 'update_cache_pool_params'
Similar function to 'update_thin_pool_params', but for cache.  Performs
the adjustements for chunk_size, metdata device size, etc.
2014-02-04 11:50:27 -06:00
8ddc7f641c misc: disambiguate 'update_pool_params'
s/update_pool_params/update_thin_pool_params/ to disambiguate it from
a future 'update_cache_pool_params'.
2014-02-04 09:58:35 -06:00
afe2ba657b misc: rename variables [min|max]_chunk to [min|max]_chunk_size
better variable names.
2014-02-04 08:20:10 -06:00
b94a3ee9f6 cache: Add functions that create/remove cache LVs
A cache LV - from LVM's perpective - is a user accessible device that
links the cachepool LV and the origin LV.  The following functions
were added to facilitate the creation and removal of this top-level
LV:
1) 'lv_cache_create' - takes a cachepool and an origin device and links
   them into a new top-level LV of 'cache' segment type.  No allocation
   is necessary in this function, as the sub-LVs contain all of the
   necessary allocated space.  Only the top-level layer needs to be
   created.

2) 'lv_cache_remove' - this function removes the top-level LV of a
   cache LV - promoting the cachepool and origin sub-LVs to top-level
   devices and leaving them exposed to the user.  That is, the
   cachepool is unlinked and free to be used with another origin to
   form a new cache LV; and the origin is no longer cached.
   (Currently, if the cache needs to be flushed, it is done in this
   function and the function waits for it to complete before proceeding.
   This will be taken out in a future patch in favor of polling.)
2014-02-04 07:59:58 -06:00
ef6c5795a0 raid: add temporary activation for raid metadata clear
Use LV_TEMPORARY when activating devices for clearing
raid metadata.
2014-02-04 14:51:05 +01:00
ef557b8091 tests: update test
Remove some unneeded traces and outputs.
2014-02-04 14:49:38 +01:00
3247819531 pool: Make another thin pool fn generic for cache usage also
Make '_recalculate_thin_pool_chunk_size_with_dev_hints' so it can
be used for cache and thin pools.
2014-02-04 07:03:52 -06:00
131383963f misc: Fix copy+paste error
'cache_pool_metadata_require_separate_pvs' was added in version 2.02.106
not 2.02.89.
2014-01-31 17:09:47 -06:00
4aa8a14fc2 compilation: Rename tags variables to tagsl. 2014-01-30 21:09:28 +00:00
83358d4c03 tools: Add internal tags command. 2014-01-30 13:09:15 +00:00
e833d84e67 cache/pool: Make the fns in pool_manip.c work with cache pools
The functions in pool_manip.c are specific to thin pools.  It's
now time to make them more generic and able to handle cache pools
as well.
2014-01-28 12:25:07 -06:00
70fd2139e1 cache: Allocation code changes necessary to support cache_pool
Cache pools require a data and metadata area (like thin pools).  Unlike
thin pool, if 'cache_pool_metadata_require_separate_pvs' is not set to
'1', the metadata and data area will be allocated from the same device.
It is also done in a manner similar to RAID, where a single chunk of
space is allocated and then split to form the metadata and data device -
ensuring that they are together.
2014-01-28 12:25:02 -06:00
75b8ea195c cache: New functions for gathering info on cache devices
Building on the new DM function that parses DM cache status, we
introduce the following LVM level functions to aquire information
about cache devices:
- lv_cache_block_info: retrieves information on the cache's block/chunk usage
- lv_cache_policy_info: retrieves information on the cache's policy
2014-01-28 12:24:51 -06:00
d9bec60a23 cache/misc: Revert commit 94377dfd
I am reverting the commit below - removing the new 'dm_config_get_int'
function and simply calling 'dm_config_get_uint32' while casting the
'int *' pointer parameter.

Commit being reverted:
commit 94377dfd5e
Author: Jonathan Brassow <jbrassow@redhat.com>
Date:   Mon Jan 27 05:26:19 2014 -0600

    Misc: New function for reading lvm config file fields

    Introduce 'dm_config_get_int', which will be used by the upcoming
    cachepool segment type.
2014-01-28 11:26:05 -06:00
42fa0e6dd1 tests: validate acceptable external origin size 2014-01-29 14:59:09 +01:00
155405b0e1 thin: validate external origin size
Avoid use of external origin with size unaligned/incompatible with
thin pool chunk size, since the last chunk is not correctly provisioned
when it is overwritten.
2014-01-29 14:58:13 +01:00
8074d8056a thin:drop stack trace when pool is above threshold
Since this path is expected, do not log_debug stacktrace.
2014-01-29 14:26:06 +01:00
5a1e1d0d39 cleanup: fix cut&paste and move initialization
Use C initializers and fix cut&paste core_arg error.

(in release fix)
2014-01-29 09:00:16 +01:00
e9d9852c55 thin: more validation of thin name
Avoid starting conversion of the LV to the thin pool and thin volume
at the same time.  Since this is mostly a user mistake, do not try
to just convert to one of those type, since we cannot assume if the
user wanted LV to become thin volume or thin pool.

Before the fix tool reported pretty strange internal error:
Internal error: Referenced LV lvol1_tdata not listed in VG mvg.

Fixed output:
lvconvert --thinpool lvol0 -T mvg/lvol0
Can't use same LV mvg/lvol0 for thin pool and thin volume.
2014-01-28 13:21:39 +01:00
bc5f40ee1c tests: check for mkfs
Test mkfs.ext3 presence for test.
Test also on singlenode cluster.
Speed up a bit slowed down device.
2014-01-28 10:40:08 +01:00
c0bd436dcb thin: disable extension of reduced thin with etx.origin
Since we are currently incapable of providing zeroes for
reextended thin volume area, let's disable extension of
such already reduce thin volumes.

(in-release change)
2014-01-28 10:40:08 +01:00
7786443530 devices: support zvol
Support partitions on ZFS zvol.
Requested via https://bugzilla.redhat.com/show_bug.cgi?id=913597

Author: hakimian@aha.com
2014-01-28 10:33:29 +01:00
df181cc51e cache: Add DM interface for retrieving a cache's status
This patch defines a structure for holding all of the device-mapper
cache target's status information.  The associated function provides
an easy way for higher levels (LVM) to consume the information.

This patch finishes the device-mapper interface for the cache and
cachepool segment types (i.e. the cache target).
2014-01-27 05:30:42 -06:00
1ff7e214e0 cache: New 'cache' segment type
This patch adds the cache segment type - the second of two necessary
to create cache logical volumes.  This segment type references the
cachepool (the small fast device) and the origin (the large slow device);
linking them to create the cache device.  The cache device is the
hierarchical device-mapper device that the user ulitmately makes use
of.

The cache segment sources the information necessary to construct the
device-mapper cache target from the origin and cachepool segments to
which it links.
2014-01-27 05:29:35 -06:00
90bbed3255 cache: New 'cachepool' segment type
This patch adds the new cachepool segment type - the first of two
necessary to eventually create 'cache' logical volumes.  In addition
to the new segment type, updates to makefiles, configure files, the
lv_segment struct, and some necessary libdevmapper flags.

The cachepool is the LV and corresponding segment type that will hold
all information pertinent to the cache itself - it's size, cachemode,
cache policy, core arguments (like migration_threshold), etc.
2014-01-27 05:27:16 -06:00
94377dfd5e Misc: New function for reading lvm config file fields
Introduce 'dm_config_get_int', which will be used by the upcoming
cachepool segment type.
2014-01-27 05:26:19 -06:00
6b73d21ba9 locking: avoid dropping locks
When lvm2 command forks, it calls reset_locking(),
which as an unwanted side effect unlinked lock file from filesystem.

Patch changes the behavior to just close locked file descriptor
in children - so the lock is being still properly hold in the parent.
2014-01-27 12:13:29 +01:00
f18ee04fab lvmetad: respect LVM_LVMETAD_PIDFILE settings in lvm
Test LVM_LVMETAD_PIDFILE for pid for lvm command.
Fix WHATS_NEW envvar name usage
Fix init order in prepare_lvmetad to respect set vars
and avoid clash with system settings.
Update test to really test the 'is running' message.
2014-01-24 15:59:38 +01:00
89d7732617 thin: fix missing ~ in previous commit 2014-01-24 13:13:37 +01:00
731c298e12 thin: use LV_TEMPORARY for metadata initialization
This flag need to be specified when we create thin pool - to avoid
scanning device with watch rules.
2014-01-24 12:30:28 +01:00
432ff4bd72 cleanup: indent 2014-01-24 12:30:28 +01:00
5e4647ec99 Typo: s/Unale/Unable/ 2014-01-22 23:04:27 -06:00
c1df1f3a81 tests: thin external origin resize 2014-01-23 14:22:34 +01:00
f8b20fb8e8 thin: fix feature compare function
Comparing for available feature missed the code path, when
maj is already bigger.

The bug would be only hit in the case, thin pool target would have
increased major version.
2014-01-23 14:22:31 +01:00
902b343e0e thin: validate resize of thin LV with ext. origin
When thin volume is using external origin, current thin target
is not able to supply 'extended' size with empty pages.

lvm2 detects version and disables extension of LV past the external
origin size in this case.

Thin LV could be however still reduced and extended freely bellow
this size.
2014-01-23 14:20:34 +01:00
2dae78b722 thin: rename function
Rename pool_can_resize_metadata() to more reusable
thin_pool_feature_supported() which could be queried
for mutiple different features.
2014-01-23 14:19:17 +01:00
1d7b2715e5 missed pool_manip.c
Seems like this file is missing from the thin_manip move.
Make the tree compilable again.
2014-01-23 09:57:22 +01:00
998af1a4fb Misc: Change name of lvcreate_params field - s/create_thin_pool/create_pool/
In preparation for other segment types that create and use "pools", we
s/create_thin_pool/create_pool/.  This way it is not awkward when creating
a cachepool, for example, to use "create_thin_pool".
2014-01-22 10:30:55 -06:00
5590448c32 Misc: Move some thin pool functions to a new file
Functions that handle set-up, tear-down and creation of thin pool
volumes will be more generally applicable when more targets exist
that make use of device-mapper's persistent data format.  One of
these targets is the dm-cache target.  I've selected some functions
that will be useful for the cache segment type to be moved, since
they will no longer be thin pool specific but are more broadly
useful to any segment type that makes use of a 'pool' LV.
2014-01-22 10:11:29 -06:00
2b9d25133e wiping: issue error if libblkid detects signature and fails to return offset/length
We need both offset and length when trying to wipe detected signatures.
The libblkid can fail so it's good to have an error message issued for
this state instead of being silent (libblkid does not issue any error
messages here). We just issued "stack" here before but that was not
quite useful if some error occurs...
2014-01-22 16:29:52 +01:00
cb595a5a13 coverity: check return value of dev_close in dev_get_block_size() 2014-01-22 16:20:09 +01:00
34e6d59bba WHATS_NEW: be more specific about cryptsetup version that sets the udev flags 2014-01-22 15:48:40 +01:00
36a09cf463 udev: drop cryptsetup specific rules from 10-dm.rules
These udev flags are set directly in cryptsetup for some
time now so there's no need to have it in our rules then.

See also:
https://code.google.com/p/cryptsetup/source/detail?spec=svn4f14b43a3d3e7310465005c401f37e19f8cb85e6&r=4f14b43a3d3e7310465005c401f37e19f8cb85e6
2014-01-22 15:18:57 +01:00
d2956f0a59 autoconf: Update config.guess/sub to 2014-01-01. 2014-01-21 22:00:15 +00:00
efe36fcd43 tests: more testing for online thin metadata resize
Some more tests for online resize, but it's still disabled
by default, since kernel doesn't work yet for this feature.
2014-01-21 13:53:10 +01:00
22d9daff12 thin: online metadata resize requires 1.10
Version 1.10 starts to look promissing, let's enable
online resize when this thin-pool kernel target is present.
2014-01-21 13:50:17 +01:00
899a079c8f post-release 2014-01-20 19:41:30 +00:00
aa21e79991 pre-release 2014-01-20 19:22:56 +00:00
cf97d8d5f9 udev: clear temporary variable properly
Clear temporary DM_DISABLE_OTHER_RULES_FLAG properly. This did not
cause any bug or problem as the temporary variable is overwritten next
time it's used again, but we should still clean it properly!
2014-01-20 12:54:10 +01:00
91b26b63b4 thin: fix thin LV flagging for udev to skip scanning
Only flag thin LV for no scanning in udev if this LV is about
to be wiped. This happens only in case the thin LV's pool was not
created with zeroing of the new blocks enabled.
2014-01-20 12:38:21 +01:00
79768b2e9c tests: update testing for xfs 2014-01-20 12:02:33 +01:00
59336a2a06 fsadm: use xfs_repair when available
Since support for xfs_check is going to be obsoleted,
replace its usage with xfs_repair -n tool.

However this tool needs further intrumentation, since for really small
xfs devices (having just 1 allocation group) it needs to pass in
flag: "-o force_geometry". As we run the tool with '-n', it should
be safe to pass this flag always.

FIXME: figure way without always passing this flag.
2014-01-20 11:57:39 +01:00
5f90353636 libdm: WHATSNEW 2014-01-17 11:02:29 +01:00
0638d1d82e libdm: preload revert after failing callback
Revert activated volumes if callback fails.
This is currently used only for thin_check failure support.

When thin_check detects failure in thin metadata device, it deactivate
volumes in reversed order that have been preloaded for thin pool activation.
After this change lvm command will not leave active pool subvolumes
in dm table.
2014-01-17 10:48:49 +01:00
d98511c717 cleanup: indent 2014-01-17 10:48:49 +01:00
5eee73bd7c pvresize: Fix orphan PV size calculation.
The size of any metadata must be ignored when calculating the size of an
orphan PV.

Bug introduced by 603b45e0ed ("pvresize: Do
not use pv_read (get the PV from orphan VG).")
2014-01-17 01:12:04 +00:00
ebac2ed5be pvresize: Avoid archiving orphan VG metadata.
Block creations of archive and backup files for internal orphan VGs.

Bug introduced by 603b45e0ed ("pvresize: Do
not use pv_read (get the PV from orphan VG).")
2014-01-16 23:02:59 +00:00
b662f3c8dd udev: do not drop SYSTEMD_READY for non-activating events
Do not drop device's flag to report readiness for systemd
processing if there's any event that follows the activatiion
event itself. Otherwise, systemd would lost track of this device
on any other event that follows the activating event (IOW, we
need to make SYSTEMD_READY variable change level-based, not edge-based).

This patch applies for MD and loop devices used as PVs.

(intra-release fix for commit 4c267c7286)
2014-01-14 17:59:56 +01:00
3813cd7a3c format1: Mark obsolete and do not use with lvmetad.
DO NOT USE LVMETAD IF YOU HAVE ANY LVM1-FORMATTED PVS.

You may continue to use it without lvmetad, but do please schedule
an upgrade to the lvm2 format (with 'vgconvert').

Sending the original LVM1 formatted metadata to lvmetad is breaking
assumptions made by the code, so I am marking the format as obsolete for
now and no longer sending it to lvmetad.

This means that if you are using lvmetad, lvm1 volumes will usually
appear invisible - though not always: it depends on exactly what
sequence of commands you run!

The current situation is not satisfactory.

We'll either fix lvmetad and reenable this or we'll fix the code to
issue appropriate warning messages when lvm1 PVs are encountered
to avoid accidents.

(The latest unfixed problem is that lvmetad assumes metadata sequence
numbers exist and always increase - but the lvm1 format does not define
or store any sequence number, confusing both the daemon and client
when default values get passed to-and-fro.)
2014-01-14 03:27:45 +00:00
5a450eab6a pvs: fix segfaults with orphans
Several fields used to display 0 if undefined.  Recent changes
to the way the fields are reported threw away some tests for
valid pointers, leading to segfaults with 'pvs -o all'.

Reinstate the original behaviour.
2014-01-14 03:17:27 +00:00
4c2b4c37e7 lvmcache: Invalidate cached VG if PV is orphaned.
If a PV in an existing VG becomes orphaned (with 'pvcreate -ff', for
example) the VG struct cached against its vginfo must be invalidated.
This is because the struct device it references no longer contains
the PV label so becomes incorrect.

This triggers the error:
  Internal error: PV $dev unexpectedly not in cache.
when the PV from the cached VG metadata is subsequently looked up
in the cache.

Bug introduced in 2.02.87 by commit 7ad0d47c3c
("Cache and share generated VG structs").

Before:

lvm> pvs
  PV         VG   Fmt  Attr PSize  PFree
  /dev/loop3 vg12 lvm2 a--  28.00m 28.00m
  /dev/loop4 vg12 lvm2 a--  28.00m 28.00m
lvm> pvcreate -ff /dev/loop3
Really INITIALIZE physical volume "/dev/loop3" of volume group "vg12" [y/n]? y
  WARNING: Forcing physical volume creation on /dev/loop3 of volume group "vg12"
  Physical volume "/dev/loop3" successfully created
lvm> pvs
  Internal error: PV /dev/loop3 unexpectedly not in cache.
  PV         VG   Fmt  Attr PSize  PFree
  /dev/loop3 vg12 lvm2 a--  28.00m 28.00m
  /dev/loop3      lvm2 a--  32.00m 32.00m
  /dev/loop4 vg12 lvm2 a--  28.00m 28.00m

After:
lvm> pvs
  PV         VG   Fmt  Attr PSize  PFree
  /dev/loop3 vg12 lvm2 a--  28.00m 28.00m
  /dev/loop4 vg12 lvm2 a--  28.00m 28.00m
lvm> pvcreate -ff /dev/loop3
Really INITIALIZE physical volume "/dev/loop3" of volume group "vg12" [y/n]? y
  WARNING: Forcing physical volume creation on /dev/loop3 of volume group "vg12"
  Physical volume "/dev/loop3" successfully created
lvm> pvs
  PV             VG   Fmt  Attr PSize  PFree
  /dev/loop3          lvm2 a--  32.00m 32.00m
  /dev/loop4     vg12 lvm2 a--  28.00m 28.00m
  unknown device vg12 lvm2 a-m  28.00m 28.00m
2014-01-14 02:57:03 +00:00
9c445f3c2c reporter: Set labeller on dummy labels (fixes missing fmt field). 2014-01-13 11:45:38 +01:00
d61c9eb52f report: Do not try to get dev_size of a NULL device. 2014-01-13 11:45:18 +01:00
5f7286f15d toollib: Fix a pool leak in _process_all_devs. 2014-01-13 11:26:43 +01:00
e892ac7398 test: Increase the overall timeout to 3 hours. 2014-01-08 17:11:32 +01:00
d52c4154c5 test: Time out the entire testsuite after an hour. 2014-01-08 17:11:32 +01:00
af8580d756 test: Use klogctl in the harness instead of reading /var/log/messages. 2014-01-08 17:11:32 +01:00
1937715d2c test: Add a regression test for pvcreate -ff. 2014-01-08 15:24:43 +01:00
8a8e59fb5a lvmetad: Fix getting vgid_old & avoid removing in-transition VGs. 2014-01-08 15:22:24 +01:00
2b7f7d0ab4 tests: use compiled lvm for clvmd executed lvs 2014-01-08 13:52:05 +01:00
5f246bf768 liblvm: mark constant as unsigned 2014-01-08 12:04:41 +01:00
4417cd288b lvmetad: add parentheses around assignment 2014-01-08 11:57:43 +01:00
af7297c73e libdm: pass dnode to callback
Pass dnode  pointer instead of rather unknown child pointer.
The pointer is currently unused and passing child pointer
is quite undefined, while dnode has at least some usability.
2014-01-08 11:57:43 +01:00
95b1af7280 thin: accept const struct 2014-01-08 11:57:43 +01:00
de3abfa622 thin: cleanup _thin_pool_add_message
Make this code a bit more readable for Coverity as otherwise
it marks the "type" variable in the "_thin_pool_add_message" fn
as undefined for certain path (...which is normally unreachable anyway,
but let's clean this up).
2014-01-08 10:56:05 +01:00
0a13815e68 pvscan: use format feature flags in lvmetad code
Introduce FMT_OBSOLETE to identify pool metadata and use it and FMT_MDAS
instead of hard-coded format names.
Explain device accesses on pvscan --cache man page.
2014-01-08 02:13:13 +00:00
21c3b41ea8 lvmetad: free fid after vg lookup failure 2014-01-08 01:51:23 +00:00
3a4efb2f16 Misc: Get rid of some compiler warnings. 2014-01-07 19:37:07 -06:00
a832120521 lvmetad: Flush a VG if it goes completely missing due to pv_found. 2014-01-07 03:28:20 +01:00
89e7d81d92 lvmetad: Fix a corruption-prone race in error path. 2014-01-07 03:04:14 +01:00
087d33d73b toollib: Fix a mis-merge in _process_all_devs (duplicated pvs -a output). 2014-01-07 02:49:12 +01:00
eaeb33abd4 liblvm: Save off and restore umask values
lvm has a default umask value in the config file that defaults
to 0077 which lvm changes to during normal operation.  This
causes a problem when the code is used as a library with
liblvm as it is changing the umask for the process.  This
patch saves off the current umask, sets to what is specified
in the config file and restores it what it was on library
function call exit.

The user is now free to change the umask in their application at
anytime including between library calls.

This fix address BZ:
https://bugzilla.redhat.com/show_bug.cgi?id=1012113

Tested by setting umask to 0777 and running the python unit
test and verifying that umask is still same value as expected
at the test completion and with a successful run.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-12-20 13:36:22 -06:00
f270bbd442 device: if BLKPBSZGET is unavailable, try to use BLKSSZGET with fallback to 512b 2013-12-18 13:52:01 +01:00
359291b41c systemd: use only major:minor for pvscan in lvm2-pvscan@.service
When using filters for the pvscan --cache (the global_filter),
there's a difference between:

  pvscan --cache -aay /dev/block/<major>:<minor>

and

  pvscan --cache -aay <major>:<minor> (or --major <major> --minor <minor>)

In the first case, we need to be sure to have an exact matching line
in the filter for the device to be used, no aliases are considered
So for example even if we have accept rule for "/dev/sda" present,
this won't apply for "/dev/block/8:0" even though it's the same device!
This is because we're comparing the path used on command line directly
with the path written in the rule.

For the second one, any alias mentioned in the filter will apply
as we're comparing the major and minor pair, not looking at actual
device names - so any alias mentioned in the rules will suffice for
the filtering rule to apply.

For the global_filter to be properly used, we need to call the
second one in the lvm2-pvscan@.service - nobody is able to tell
what value of major:minor the kernel assignes next time, hence
this bug makes the use of global_filter quite unusable!
2013-12-18 12:23:59 +01:00
3c818c8946 device: if BLKPBSZGET is unavailable, enforce 512
If there is no define for BLKPBSZGET - we have hard time how to
decrypt physical block size - we can't use here block_size,
since this is usually 4k while we need to use 512b.

FIXME: find some better way, until that enforce value 512.
Eventually we could also try to put in:

+#ifndef BLKPBSZGET
+# define BLKPBSZGET _IO(0x12,123)
+#endif

but this will still not work well on old kernels.
2013-12-18 10:52:09 +01:00
434d95cef3 tests: clear inactive table before resuming in teardown 2013-12-18 10:40:36 +01:00
3776832499 man: syntax and spelling fixes. 2013-12-18 09:03:42 +01:00
c3d82d717c Revert "tree_action: destroy devices from failing activation"
This reverts commit 24639be558.

Ok - seems we could be here a bit too active - and we
may remove devices which are unsuable for reasons we are not
aware of - thus taking down whole device could be way to big hammer.

So we still need some solution to recover from failing preload
and activation - but it needs more tunning.
2013-12-17 15:21:28 +01:00
3652083f38 device: use BLKPBSZGET for physical block size only if the op is available, otherwise use logical block size
Older kernels < 2.6.32 don't have BLKPBSZGET defined.
2013-12-17 15:17:28 +01:00
24639be558 tree_action: destroy devices from failing activation
When activation fails - we may leak large tree of partially loaded
devices in the dm table (i.e. failure in snapshot activation)

The best we can do here is try to deactivate whole device and
remove as much inactive table entries as we can.
2013-12-17 14:08:54 +01:00
94137b72ed lv_dependency: scan also snapshots and extorigins
When LV is scanned for its dependencies - scan also origin's snapshots,
and thin external origins.

So if any PV from snapshot or external origin device is missing - lvm2 will
avoid trying to activate such device.
2013-12-17 14:08:54 +01:00
760714829b cleanup: skip double assign
Assing NULL to type only in defaut: switch.
Debug print '--'  for  unlocked and unused resource (-1)
2013-12-17 14:08:54 +01:00
904a02335f tests: hide expected error message
Test typically enables disabled device - so it mostly expects
error target will be reloaded here - thus hide confusing message.
2013-12-17 14:08:54 +01:00
fd73b2b7b9 tests: skip pool-label test for lvmetad
Unsupported by lvmetad.
2013-12-17 14:08:54 +01:00
a8b5dce997 systemd: make sure lvm2-lvmetad.socket is available for lvm2-pvscan@.service 2013-12-17 10:40:32 +01:00
56af6cae08 test: Turn check_full into check_system complementary with normal check. 2013-12-15 17:26:28 +01:00
18afca5ddd pvscan --cache: Use FMT_LVM1_NAME instead of hardcoded "lvm1". 2013-12-15 16:44:47 +01:00
bd3edb2566 pvscan --cache: Error out on pool-format VGs for now. 2013-12-15 16:44:47 +01:00
97fbbbc150 test: Make the harness optionally less verbose (QUIET=1). 2013-12-15 16:44:47 +01:00
d443bfac21 config: fix metadata/disk_areas config setting registration
The metadata/disk_areas setting was incorrectly registered as
"string" configuration option but it's a section where each area
is defined in its own subsection with "start_sector", "size" and "id"
setting.

This setting is not officialy supported, it's undocumented and it's
used solely for debugging.

Note: At this moment, it does not seem to be working with lvmetad!
2013-12-13 16:52:51 +01:00
32080c4ff7 device: add physical block size info and make sure VG extent size >= PV's phys. block size 2013-12-12 15:02:36 +01:00
3eed0aa7dc man: -Z zeroes 4KiB, not just 1KiB 2013-12-12 15:02:12 +01:00
131693c421 autoreconf: latest changes 2013-12-12 14:32:40 +01:00
b424b6398b configure: update recent change
Full path needs to be supplied.
Keep on using 'autodetect' keyword as default argument.
2013-12-12 14:29:15 +01:00
fd0068a66e cleanup: remove unused variable
Recent commit made this variable unused
2013-12-12 13:59:39 +01:00
aefab64e69 autoreconf: latest changes 2013-12-12 13:45:48 +01:00
6c0e44d5a2 dev-cache: skip double stat() call on each _insert
When the device is inserted in dev_name_confirmed() stat() is
called twice as _insert() has it's own stat() call.

Extend _insert() parameter with struct stat* - which could be used
if it has been just obtained.  When NULL is passed code is
doing its own stat() call as before.
2013-12-12 13:42:28 +01:00
7c5feaed3b dmeventd: prevent busy looping on CPU
Use usleep when looping on DM_WAIT_RETRY.
2013-12-12 13:40:55 +01:00
b87c148499 dmeventd: change locking code
Ensure global lock is being hold when working with thread->.
2013-12-12 13:38:55 +01:00
4fc97980b6 dmeventd: drop taking timeout mutex
Taking _timeout_mutex is not needed when registering and unregistering.
Global mutex is already being hold for this case.
2013-12-12 13:32:49 +01:00
10a13dc03c thin: enable build of thin provisioning by default
Use internal type by default for thin provisioning.
If user is not interested in thin provisiong and doesn't
have thin provisining supporting tools installed,
configure will just print warning at the end of configure
process about limited support.
2013-12-12 13:31:23 +01:00
9fcbe3c6f0 cleanup: add missing backtrace in fail path 2013-12-12 13:29:59 +01:00
fe21b02fab cleanup: improve tag processing
Boolean algebra changes for process_each_lv_in_vg().

1st.
Drop process_lv variable since it's not needed.

2nd.
process_lv was always initilized to 0 - so the condition was always true.
It the condition (!tags_supplied && !lvargs_supplied) evaluates as "true",
process_all is already set to 1, so skip vg tags evaluation.

3rd.
Move check for matching lv name in the front of lv tags check
since this check can't be skipped for lvargs_matched counter.
If this filter evaluates to true, skip lv tags evaluation.
2013-12-12 13:29:20 +01:00
1c2cc2f794 cleanup: remove duplicate code
As dev_name_confirmed() has check for DEV_REGULAR
remove this duplicated extra check prior its call.
2013-12-12 13:28:19 +01:00
30a81e5989 cleanup: self compilable headers 2013-12-12 13:28:19 +01:00
b53e9ba66a cleanup: simplify logging code
Condense code for logging.
2013-12-12 13:27:59 +01:00
877418b1a2 WHATS_NEW: commit 4c267c7286
See also https://bugzilla.redhat.com/show_bug.cgi?id=1026860
for more info, comment 76 for summary.
2013-12-11 16:50:52 +01:00
4c267c7286 udev: fix SYSTEMD_READY assignment for foreign devices in lvmetad rules
Some devices, similarly to us, are not prepared after ADD event, but
after an extra CHANGE event when the device is properly set up.
This includes MD and loop devices. This patch fixes the
SYSTEMD_READY assignment that is crucial for proper functionality
of SYSTEMD_WANTS that we use to instantiate a lvm2-pvscan@.service
systemd service to activate the VG/LVs (see also bug
info).

All that extra handling of foreign devices should eventually be moved
to rules which process those devices primarily (MD and loop)! We should
only check a dedicated variable whether the device is usable or not.
2013-12-11 13:46:15 +01:00
c9fe05eee2 tests: count interrupted test as failed 2013-12-10 11:21:40 +01:00
e3b7fa4b8d thin: thin metadata resize unsupported with 1.9
Thin kernel target 1.9 still does not support online resize of
thin pool metadata properly - so disable it with expectation
for much higher version - and reenable after fixing kernel.
2013-12-10 11:17:37 +01:00
99d5b4b807 cleanup: share segtype macros
Write query macro just once.
2013-12-10 11:16:53 +01:00
cf857ecabd cleanup: shorter raid initialization
Avoid multiple queries for raid library for each initialized raid
seg type and use shorter code.
2013-12-10 11:16:51 +01:00
9f0e27a18c cleanup: tiny speedup of lib_dir checking
Instead of repeated lookup of global/library_dir - remember first
search in command context - saves couple lines in debug output...
2013-12-10 11:15:48 +01:00
0fcdc8a020 conf: clarify wipe_signatures_when_zeroing_new_lvs 2013-12-10 10:16:37 +01:00
16eab3ec08 config: shorten new sig wiping option string
Rename wipe_signatures_on_new_logical_volumes_when_zeroing  to
wipe_signatures_when_zeroing_new_lvs.
2013-12-09 09:35:47 +00:00
2b3adf4eea tests: more limits for python test
It will be most probably more problem with
incomplete initialization of lvm.conf settings
when lvm2app is in use.

Skip cluster & lvmetad test for now.
2013-12-06 10:37:49 +01:00
f460d6d9b5 tests: python test needs dmeventd
Until lvm2app respects all lvm.conf setting,
this test require dmeventd.
2013-12-06 10:08:34 +01:00
73a109d434 lvmdump: follow symbolic links in /etc/lvm 2013-12-05 16:36:45 +01:00
a344466e26 compile/link: EXTRA_EXEC_CFLAGS must be applied for *.o 2013-12-05 14:19:10 +01:00
481edce41f compile/link: use RELRO/PIE compiler/linker options for executables 2013-12-05 14:03:10 +01:00
b494881e68 tests: sysrq only when stuck with no output.
If we are stuck in user for too long without output,
grab kernel stack traces.
If we just produce too many lines of output, it's
not probably kernel related bug.
2013-12-05 12:40:47 +01:00
c7b733cd6c tests: do not run lvmetad tests without lvmetad
Skip tests when lvmetad is not compiled.
2013-12-05 12:40:47 +01:00
6f0300de96 lv_remove_single: update parameter name
Since we have already a meaning for 'silent'
replace its name with more explanator suppress_remove_message
(updates recent commit).
2013-12-05 12:40:47 +01:00
aa75698a17 tests: harness prints debug.log
When the test is interrupted because debug.log has got to big,
and the test doesn't react on SIGINT - and needs to be only
killed with SIGKILL - it's still valuable to print at least
a portion of this debug.log (currently 4MB).

LVM_TEST_UNLIMITED  could be set to avoid this limitation
(i.e. when busy-looping lvm command needs to be running
for gdb attachment)
2013-12-05 11:18:15 +01:00
7baf411c97 dev-cache: return success when ignoring dirs
When there is no failure from the insert operation itself,
just dirs and links are skipped - return success.
2013-12-05 11:17:37 +01:00
74878bc2bc cleanup: gcc can't see the code path
This is a bit to hard for gcc to see the condition can't
be triggered, so make it easier and initialize to 0.
2013-12-05 09:42:50 +01:00
ac6cd9baa7 lvmetad: remove unused override variables 2013-12-05 01:13:18 +00:00
b6d3fd62fc libdm: prevent empty config file section names
Change c353949597 to use existing
_dup_string_tok().  alloca() doesn't fail cleanly (and needs
replacing.)
2013-12-05 01:09:03 +00:00
76ca82df82 tests: drop RUN... already have this var elsewhere 2013-12-04 21:37:33 +01:00
d9461ae89b tests: replace built-in popen
It seems some older bashes have problems to properly execute
both pipes - so replace this code with separate temporary files.
2013-12-04 19:50:53 +01:00
e06cfd7437 tests: reuse timeout code for too long debug.log
Jump to the same code used for timeout when no output
is made for long time.

Increase the allowed debug.log size to 32MB.
2013-12-04 19:48:29 +01:00
c144305d3e tests: update pvmove-test
Do not lock test when trying to grab cluster lock.
There seems to be still something weird in this test
so it still needs some inspection.
2013-12-04 17:10:31 +01:00
7c6b14b74f tests: monitor debug.log size
Show testing directory from test and monitor it in
harness - so when it gets too big - kill test.
2013-12-04 17:10:31 +01:00
598c82fc07 vgchange: move detection of remote exlusivness
Since activation takes only read-lock, there could be
multiple activation running in parallel.

So instead of checking before taking any real lock,
let the locking resolve the problem and just
detect if the reason for failure has been remote
exlusive activation.

It should be also faster, since each activation does
not need to do explicit lock query.
2013-12-04 17:09:51 +01:00
28939dba09 configure: also LDFLAGS, not LDLAGS for proper restore 2013-12-04 15:00:56 +01:00
1592bb216e test: thin snapshot merge
Testing thin snapshot merge cases.
TODO: Probably still misses some cases.
2013-12-04 14:30:26 +01:00
91496e0eda thin: enable thin snapshot merge 2013-12-04 14:30:26 +01:00
971ab733b7 thin: activation of merging thin snapshot
For merging thin snapshot we have to do couple extra
checks before we allow this operation.

We pretend  thin-snapshot and thin-origin
are tied together and we have to properly
maintain locking.
2013-12-04 14:30:26 +01:00
ff112eee18 thin: merge display 2013-12-04 14:30:26 +01:00
1200b7e7c2 thin: deactivation of merging thin snapshot
Before trying to deactivate merging thin snapshot
(which is invisible) check if it's not in-use.
2013-12-04 14:30:26 +01:00
5fc3352a15 thin: merge removal
When thin is merged - properly handly device removal.
2013-12-04 14:30:26 +01:00
664a695561 thin: merge support for device tree
When thin snapshot merge is requested, tree must detect
if user tries to active such LV while origin or
snapshost is still active.
2013-12-04 14:30:25 +01:00
e286904da6 thin: snapshot merge support 2013-12-04 14:30:25 +01:00
572983d793 thin: read table line with thin device id
Add functions to parse thin table line to
obtain thin device id.
2013-12-04 14:30:25 +01:00
cf7f451238 merge: test only for meging origin
It's enough to check only for merging origin.
This will be also used for thin volume merges which
do not need to be origins.
2013-12-04 14:30:25 +01:00
993831bdb1 cleanup: size is already 64bit value
Cast is not needed.
2013-12-04 14:30:25 +01:00
51783676fb cleanup: swap condition logic
Use easier to follow logic of code.
When checking for merging origin, do a merging.
2013-12-04 14:30:25 +01:00
6d7a76ccbf cleanup: code move
Move _swap_lv_identifiers() above  _finish_lvconvert_merge()
so it could be used from this function.
2013-12-04 14:30:25 +01:00
5a6794a2ce lv_remove_single: add silent arg
Support silence for removal message.
2013-12-04 14:30:25 +01:00
84b3852ee5 snapshots: use lv_check_not_in_use
Switch from a simple 'open_count' test on opened snaphost
to a more 'skilled'  lv_check_not_in_use().
2013-12-04 14:30:24 +01:00
778de22d51 refresh: print error message with failing lv name
If there is  suspend/resume error, print error message
with lv name.
Drop goto.
2013-12-04 14:30:24 +01:00
37853cc7a9 make: CFLAGS, not CLDFLAGS 2013-12-04 14:28:40 +01:00
a65ab773b4 daemons: use PIE and RELRO compiler/linker options
The PIE and RELRO compiler/linker options can be used to produce a code
some techniques applied that makes the code more immune to some attacks:

  - PIE (Position Independent Executable). It can make use of the ASLR
    (Address Space Layout Randomization) provided by kernel to avoid
    static locations for .text regions of executables (this is the 'pie'
    compiler and linker option)

  - RELRO (Relocation Read-Only). This prevents overwrite attacks of
    the GOT (Global Offset Table) and PLT (Procedure Lookup Table)
    used for relocations by making it read-only after all relocations
    are resolved (these are the 'relro' and 'now' linker options) -
    hence all symbols are resolved at the very start so there's no
    need for those tables to be writeable later.

These compiler/linker options are now used by default for daemons
if the compiler/linker supports it.
2013-12-04 13:30:08 +01:00
fc37d4fb0d make: support per-object defines
In the case we have a dir with multiple objects and for
an individual object file we need special define -
allow to define it without adding extra rules.

To ensure dmeventd.o compilation will use EXTRA_FLAGS:
CFLAGS_dmeventd.o += $(EXTRA_FLAGS)

Then it's better to use:
dmeventd.o: CFLAGS += $(EXTRA_FLAGS)
2013-12-04 13:30:08 +01:00
6c6bcc00e4 configure: check compiler/linker support for RELRO and PIE options
Also, add AC_TRY_LDFLAGS m4 macro to help with checking ld flags.
2013-12-04 13:30:08 +01:00
163666e513 tests: one LV should be active and one inactive in covercmd test 2013-12-04 09:38:00 +01:00
7b65363bf7 lvconvert: Implement --splitsnapshot. 2013-12-04 02:09:37 +00:00
ff769ecfe7 lvconvert: Fix reload after snapshot conversion.
At the end of lvconvert --snapshot with an active origin, the origin
gets reloaded.

Commit 57c0f72b1d ("lvconvert: use
_reload_lv on more places") accidentally replaced this with a snapshot
LV reload (which does nothing because only the origin is active).
2013-12-04 02:04:29 +00:00
6232cac86c vgdisplay: select only active volumes groups if -A option is used
Where "active" means "at least one LV is active in the volume group".
2013-12-03 14:43:00 +01:00
c353949597 libdm-config: Allow quoted section (and key) names. 2013-12-01 20:57:42 +01:00
2e82a070f3 pvcreate: Avoid spurious 'not found' messages.
Replacement of pv_read by find_pv_by_name in commit
651d5093ed caused spurious
error messages when running pvcreate or vgextend against an
unformatted device.

Physical volume /dev/loop4 not found
Physical volume "/dev/loop4" successfully created

Physical volume /dev/loop4 not found
Physical volume /dev/loop4 not found
Physical volume "/dev/loop4" successfully created
Volume group "vg1" successfully extended
2013-11-29 21:45:37 +00:00
84394c0219 lvmetad: extend socket/pid file handling
Make it easier to run a live lvmetad in debugging mode and
to avoid conflicts if multiple test instances need to be run
alongside a live one.

No longer require -s when -f is used: use built-in default.
Add -p to lvmetad to specify the pid file.
No longer disable pidfile if -f used to run in foreground.
If specified socket file appears to be genuine but stale, remove it
before use.
On error, only remove lvmetad socket file if created by the same
process.  (Previous code removes socket even while a running instance
is using it!)
2013-11-29 20:56:29 +00:00
d2d5c24a68 configure: require libblkid >= 2.24 for blkid wiping
Some symbols/identifiers were defined even later than 2.22, like BLKID_SUBLKS_BADCSUM.
2013-11-29 16:38:53 +01:00
75628f341a configure: enable blkid_wiping by default if the blkid library is present 2013-11-29 15:27:56 +01:00
b3074560eb lvmetad: Add newline to missing socket error mesg 2013-11-28 19:16:25 +00:00
3f8083107e tests: add test for lvcreate signature wiping 2013-11-28 15:47:20 +01:00
08bab406b5 tests: wipe fs signature manually in pvcreate-operation test
So that the next pvcreate that is called does not issue any
warnings/prompts about existing signature (when blkid wiping is used).
2013-11-28 14:10:55 +01:00
c24b558c8c tests: initialize signature wiping
Do not use signature wiping for newly created LVs in tests - we're
reusing the devs in tests and such detection could just interfere
inappropriately. We'd need to modify all tests to anwer the prompt
whether any signature found should be removed or not or we'd need
to use "-y" option for all lvcreates in tests. It's better to disable
this feature then and let's do a separate test to test this signature
wiping functionality.
2013-11-28 13:27:52 +01:00
6a1957badc pvcreate: do not issue warning about any existing PV
If we're calling pvcreate on a device that already has a PV label,
the blkid detects the existing PV and then we consider it for wiping
before we continue creating the new PV label and we issue a warning
with a prompt whether such old PV label should be removed. We don't
do this with native signature detection code. Let's make it consistent
with old behaviour.

But still keep this "PV" (identified as "LVM1_member" or "LVM2_member"
by blkid) detection when creating new LVs to avoid unexpected PV label
appeareance inside LV.
2013-11-28 13:14:46 +01:00
ce8ebda3fc cleanup: tab indent 2013-11-28 12:48:01 +01:00
6bf6430ae9 cleanup: convert log_error with log_warn
Collapse 2 ifs and replace log_error() with log_warn(), since\
the reported message is not causing tools error.
(and cannot be probably triggered anyway).
2013-11-28 12:48:01 +01:00
5bdbaf4ed7 cleanup: convert log_sys_error to log_sys_debug
Use debug for those error reports which do not lead to error return
call.
2013-11-28 12:48:01 +01:00
6c787d9b6e cleanup: move declaration to the front 2013-11-28 12:48:01 +01:00
50e1fad86a cleanup: use matching signed types 2013-11-28 12:47:51 +01:00
c6cfd7b2b9 cleanup: drop extra dm_list_empty
Since dm_list_first has this check already include,
skip extra call in while().
Moreover analyzers are then sure pvl is not NULL.
2013-11-28 12:45:52 +01:00
bfcf3edcc6 cleanup: fold test into printf arg
When arg is folded, compiler is able to check all args.
(better for security)
2013-11-28 12:45:52 +01:00
8c96afd361 cleanup: use compound literals for wipe_lv
Optimize and cleanup recently introduced new function wipe_lv.
Use compound literals to get nicely initialized wipe_params struct.
Pass in lv as explicit argument for wipe_lv.
Use cmd from lv structure.
Initialize only non-null members so it's easy to see what
is the special arg.
2013-11-28 12:45:52 +01:00
a1eda8ea24 toollib: drop init of ret
Keep the ret uninitialized, so we get compiler warning, when tried
to use this value instead of ret_max as function return value.
2013-11-28 12:45:52 +01:00
8724c0fceb snapshot: move code of old snapshot merge
Move code for merging old snapshot into its own function.
2013-11-28 12:45:28 +01:00
b3679590df dmeventd: simplify error path
Use common 'bad:' label for exit error path where
fifo is closed before exit().
2013-11-28 12:45:02 +01:00
6dae237303 dmeventd: fifo init and close cleanup
Use structure initialization for easier to read code.
Close only descriptors >= 0.
2013-11-28 12:43:14 +01:00
fc9d4dd11f config: use int for type
Since the type is used for 'or' operation of enumerated bit fields,
it doesn't not have type cfg_def_type_t - use proper int type for
bitmask.
2013-11-28 12:42:44 +01:00
79991aa769 snapshot: drop find_merging_snapshot
Drop find_merging_snapshot() function. Use find_snapshot()
called after check for lv_is_merging_origin() which
is the commonly used code path - so we avoid duplicated
tests and potential risk of derefering NULL point
in unhandled error path.
2013-11-28 12:42:43 +01:00
01c438a96c format-text: ensure aligment is not 0
Make sure this path of code is not used for alignment == 0,
to prevent division by 0.
2013-11-28 12:42:39 +01:00
5a4137c804 profile: wipe_signatures_on_new_logical_volumes_when_zeroing not yet profilable
But it might be - needs more testing...
2013-11-27 16:49:12 +01:00
5968f07fd5 man: lvcreate -W/--wipesignatures 2013-11-27 15:49:15 +01:00
eaa23d3273 wiping: add support for blkid wiping
This is actually the wipefs functionailty as a matter of fact
(wipefs uses the same libblkid calls).

libblkid is more rich when it comes to detecting various
signatures, including filesystems and users can better
decide what to erase and what should be kept.

The code is shared for both pvcreate (where wiping is necessary
to complete the pvcreate operation) and lvcreate where it's up
to the user to decide.

The verbose output contains a bit more information about the
signature like LABEL and UUID.

For example:
  raw/~ # lvcreate -L16m vg
  WARNING: linux_raid_member signature detected on /dev/vg/lvol0 at offset 4096. Wipe it? [y/n]

or more verbose one:
  raw/~ # lvcreate -L16m vg -v
  ...
     Found existing signature on /dev/vg/lvol0 at offset 4096: LABEL="raw.virt:0" UUID="da6af139-8403-5d06-b8c4-13f6f24b73b1" TYPE="linux_raid_member" USAGE="raid"
WARNING: linux_raid_member signature detected on /dev/vg/lvol0 at offset 4096. Wipe it? [y/n]

The verbose output is the same output as found in blkid.
2013-11-27 15:49:15 +01:00
ab2f858af7 conf: add allocation/use_blkid_wiping
Add allocation/use_blkid_wiping setting to lvm.conf to select between
LVM2 native code to detect signatures to wipe or blkid library code.
2013-11-27 15:49:14 +01:00
9bfc0be493 configure: add --enable-blkid_wiping 2013-11-27 15:48:16 +01:00
b6dab4e059 lv_manip: rename set_lv -> wipe_lv and include signature wiping capability
Use common wipe_lv (former set_lv) fn to do zeroing as well as signature
wiping if needed. Provide new struct wipe_lv_params to define the
functionality.

Bind "lvcreate -W/--wipesignatures y" with proper wipe_lv call.

Also, add "yes" and "force" to lvcreate_params so it's possible
to apply them for the prompt: "WARNING: %s detected on %s. Wipe it? [y/n]".
2013-11-27 15:48:15 +01:00
169b4c1586 lvcreate: recognize --wipesignatures arg
Recognize the new --wipesignatures arg in lvcreate that is supposed
to wipe known signatures if found on newly created LV.
2013-11-27 15:48:15 +01:00
5b7e543cae conf: add allocation/wipe_signatures_on_new_logical_volumes_when_zeroing
This setting controls whether signature wiping on newly created logical
volumes will follow the state of zeroing (-Z/--zero option).
2013-11-27 15:48:06 +01:00
03c941a4ca device: cleanup signature wiping functions
The wipe_known_signatures fn now wraps the _wipe_signature fn that is called
for each known signature (currently md, swap and luks). This patch makes the
code more readable, not repeating the same sequence when used anywhere in the
code. We're going to reuse this code later...
2013-11-27 12:56:58 +01:00
120df55610 activation: change log_error to log_warn if refresh before autoactivation fails 2013-11-27 08:53:26 +01:00
d6e67b8503 WHATS_NEW: commit 729b104 2013-11-27 08:33:02 +01:00
729b104413 activation: continue with autoactivation if refresh fails
If the refresh fails for any reason before autoactivation, let's not
make this a stopper for autoactivation itself - just log the error
message if it appears.

The reason is that in some rare situations, we can still hit the
problem with the suspend call to fail (as already described in
commit d8085edf65, also
https://bugzilla.redhat.com/show_bug.cgi?id=1027314). The refresh
itself is done for only one reason - to refresh any dm tables
for LVs for which the underlying PVs got unplugged/disconnected
and then plugged/connected back (see also
https://bugzilla.redhat.com/show_bug.cgi?id=954061 for more info).
In this case, the major:minor pair is changed and we need to
update dm tables for LVs accordingly.

Now if refresh fails, the error is still logged, but autoactivation
continues.
2013-11-27 08:20:02 +01:00
8d5cff5b9b lv/vgchange: do not try to connect to lvmetad if socket absent and --sysinit -aay used
If using lv/vgchange --sysinit -aay and lvmetad is enabled, we'd like to
avoid the direct activation and rely on autoactivation instead so
it fits system initialization scripts.

But if we're calling lv/vgchange --sysinit -aay too early when even
lvmetad service is not started yet, we just need to do the direct
activation instead without printing any error messages (while
trying to connect to lvmetad and not finding its socket).

This patch adds two helper functions - "lvmetad_socket_present" and
"lvmetad_used" which can be used to check for this condition properly
and avoid these lvmetad connections when the socket is not present
(and hence lvmetad is not yet running).
2013-11-26 14:51:23 +01:00
47110f7e27 tests: add WARNED test to final list
WARNED result should not be forgotten - it's supposed
to be fixed...

keep enum alphabetically sorted
2013-11-22 21:00:56 +01:00
b8f72c0f2c cleanup: use const format 2013-11-22 21:00:56 +01:00
62db5c1e48 cleanup: make gcc happier with initializers
Whole struct will be set to 0, just
if the first member is array, gcc gives warning
we should initialized this element as array,
so pick any later simple type.
2013-11-22 21:00:56 +01:00
6ebbf19828 cleanup: drop unused header
Header is not used here.
2013-11-22 21:00:56 +01:00
07d766d270 cleanup: use string directly 2013-11-22 21:00:55 +01:00
3e0fb102de cleanup: simplify pv uuid display
Shorter code with explicit type casting.
2013-11-22 21:00:55 +01:00
bea118a87c cleanup: use safe iterator
Simplify code and use dm_list_iterate_items_safe() and avoid
scanning the list mutliple times.
Use dm_list_move().
2013-11-22 21:00:55 +01:00
19cc92230c cleanup: use trigraph
Shorter code...
2013-11-22 21:00:55 +01:00
879ea38c53 dmeventd: drop duplicated code
Do not call pthread_attr_init() twice.
The second call has all proper tests.
2013-11-22 21:00:55 +01:00
1ff53bb7b6 snapshot: code move
Move some code lines in front, they will be shared with thin snapshot
merge later.
2013-11-22 21:00:55 +01:00
30c127eaf8 fix missing header 2013-11-22 21:00:55 +01:00
b4fc397de6 do_flock: mark descriptor as closed
Keep the structure content valid in error path
and mark descriptor as closed (-1).
2013-11-22 21:00:55 +01:00
782a356e7c archiver: add check for dm_pool_strdup
It will likely not fail to duplicate empty string, but
just keep the test of result of this function consistent.

Also on error path restore extent_size if in some
case someone would still use that variable.
2013-11-22 21:00:54 +01:00
d079c81ab4 dev-type: use text format as direct arg for printf
Put common printf() case into a function and use
the string with text format as direct arg to make
the compile time validation of args easier and
code shorter.

Switch log_error() to log_warn(), since 'return 0'
doesn't cause any failure here.
2013-11-22 21:00:54 +01:00
6fa95d17ee dmeventd: move format text to printf
Instead of passing argument with format string to printf(),
put the string as arg directly.
Also move there remains args to make the code shorter.
2013-11-22 21:00:51 +01:00
069fa6c49d activate: modify read_only when dev_manager exists
Change opts only when dm has been successfully created.
So on the error path we leave structure unmodified.
2013-11-22 20:58:13 +01:00
4a061a35c7 snapshot: use lv_check_not_in_use
Instead of plain open_count check, try to use 'smarter'
lv_check_not_in_use() function.
2013-11-22 20:58:11 +01:00
6d196410fc snapshot: revert and move check to lvconvert
Revert 4777eb6872 which put
target_present check into init_snapshot_merge(). However
this function is also used when parsing metadata. So we would
get this present test performed even when target is not really
needed. So move this target_present test directly into lvconvert.
2013-11-22 20:57:30 +01:00
3d3b8bfd1c pv_write: check for lvmcache_add_mda failure
Add missing test of failing lvmcache_add_mda() call.
2013-11-22 20:55:09 +01:00
a50a297f6e report: detect dev_get_size failure
Since dev_get_size() may fail, detect this failure.
2013-11-22 20:54:16 +01:00
08d6d81cc2 filters: drop extra slash from sysfs path
Sysfs filter was using '/sys//class/block' with double '//' inside.
Remove this extra '/'.
Also simplify code around and use loop to try those paths.
2013-11-22 20:53:31 +01:00
4c1f281b43 toollib: Avoid undefined ignore_vg parameter.
Fix process_each_segment_in_pv to always set ret before calling ignore_vg().
2013-11-22 18:11:04 +00:00
7c8abb29df liblvm/python API: Additions & fixes
Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:54:18 -06:00
5588a56391 python_lvm_unit.py: Add test for new name validate methods
Test naming validate names for VG and LV names.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:47 -06:00
370520a310 python_lvm_unit.py: Clean-up method names & scope
Changed naming of methods from camel case to all lower case with
underscores per guidelines.  Changed any methods that can be
static methods to static.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:45 -06:00
12d5e53953 lvm2app: Remove forward declarations.
Remove the forward struct declaration.  This isn't needed for
implementing opaque data pointers.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:44 -06:00
fe5b538c14 lvm2app: Reset buffer after retrieving error message
The error buffer will stack error messages which is fine.  However,
once you retrieve the error messages it doesn't make sense to keep
appending for each additional error message when running in the
context of a library call.

This patch clears and resets the buffer after the user retrieves
the error message.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:42 -06:00
0c7a7d4d84 python-lvm: VG/LV name validation.
Python portion of
https://bugzilla.redhat.com/show_bug.cgi?id=883689

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:40 -06:00
0dd247502a lvm2app: Add VG/LV name validation
C library portion for
https://bugzilla.redhat.com/show_bug.cgi?id=883689

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:39 -06:00
e54e70dc66 python-lvm: Update and enable unit test case
Added tests for lvm.pvCreate and enable the test suite.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:37 -06:00
531d85a0ee python-lvm: Add addl. PV create arguments
Added overloaded PV create arguments with defaults for PV
creation.

Addresses bug: https://bugzilla.redhat.com/show_bug.cgi?id=880395

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:36 -06:00
04304ba735 lvm2app: Add ability to create PV with args
Add a PV create which takes a paramters object that
has get/set method to configure PV creation.

Current get/set operations include:
- size
- pvmetadatacopies
- pvmetadatasize
- data_alignment
- data_alignment_offset
- zero

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

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:34 -06:00
ec7f632ce0 python-lvm: Test case change for vg.reduce
Fix reduce as newly changed vg reduce fails when you
try to remove the last pv in the vg.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:32 -06:00
5074dcc896 metadata.c: Call refactored vgreduce_single
Replace the code with the refactored vgreduce_single instead
of calling its own implementation.

Corrects bug: https://bugzilla.redhat.com/show_bug.cgi?id=989174

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:30 -06:00
fe474e1452 vgreduce: Move _vgreduce_single functionality
Moving the core functionality of vgreduce single into
lib/metadata/vg.c so that the command line and lvm2app library
can call the same core functionality.  New function is
vgreduce_single.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:28 -06:00
20ffb0f721 python-lvm: Ensure library handle is correct after python gc() call
In a previous commit we added the ability for the library to do garbage
collection, to free all the memory used by the library handle buffer by closing
and re-opening the library handle.  When we introduced this functionality we
also opened up the opportunity that the user of the python bindings to have
an object that references the old library handle.  In this case if the user
tried to use the old object a segmentation fault could occur because the
memory had been previously freed.

This patch tries to mitigate this by storing a copy of the library handle that
was used when the object was created so that it can compare the current in
use pointer with what existed when the object was created.  In the case where
they match the operation is permitted to continue, otherwise an exception is
throw, thus avoiding a segmentation fault.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:27 -06:00
1f744733a1 python-lvm: Correct names
The existing names do not follow accepted guidelines.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-11-19 14:40:25 -06:00
b0b061cdbc tests: skip raid test on 3.12.0
3.12.0 kernel prevents raid test to be usable,
leaving unremovable devices in table.

This needs to be fixed ASAP, meanwhile disable test to make
test machines at least usable.
2013-11-19 11:49:33 +01:00
fe609141a8 tests: on 32bit test with <16T devs
Add  'can_use_16T' to detect systems where we could
safely use 16T devices without causing system deadlocks.

16T size leads on those to endless loops in udevd
- it calls blkid which tries cached read from such device
- this ends in endless loop.

Related problems:
https://bugzilla.redhat.com/show_bug.cgi?id=1015028
2013-11-19 10:55:14 +01:00
c697f501c7 Makefile: fix build in non src dir
Fix 'make install' from builddir != srcdir.
2013-11-19 10:55:11 +01:00
3a6f91d713 metadata: Make the fid mda routines a little more resilient. 2013-11-18 18:00:49 +01:00
03d3e1d9c1 lvmetad: Set up device pointers in synthetic lvmcache_infos. 2013-11-18 17:53:45 +01:00
b8a6b8f467 test: Force label-based reporting in pv-duplicate.sh. 2013-11-18 17:53:06 +01:00
ae337d472e report: Print UUIDs for missing PVs when possible. 2013-11-17 22:36:13 +01:00
ecc296311f metadata: Do not throw an error in pv_label for missing PVs. 2013-11-17 22:35:16 +01:00
a5bb1b48ee dev-cache.c: Make dev_name a little more robust. 2013-11-17 22:34:56 +01:00
71b6565529 report: Convert pv_mda_size to a type "label" field. 2013-11-17 21:43:06 +01:00
14ffc9d4df reporter: Adapt pvseg reporting to label-type fields. 2013-11-17 21:43:06 +01:00
2294282184 reporter: Deal correctly with dummy PVs/labels. 2013-11-17 21:43:06 +01:00
d5095222fa toollib: Report errors on non-PV arguments to process_each_label. 2013-11-17 21:43:06 +01:00
67c563ac2b pv_label: NULL result is not always an internal error. 2013-11-17 21:43:06 +01:00
a8aa8d4b5c report: Make PV UUID into a "label" type field. 2013-11-17 21:43:06 +01:00
67a7b7a87d report: Iterate over labels instead of PVs for label-only reports. 2013-11-17 21:43:06 +01:00
99214c51eb report: Make PMdaFree into a "label" field. 2013-11-17 21:43:06 +01:00
b07fb3a641 report: Adapt _pvfmt_disp to label-based reporting. 2013-11-17 21:43:04 +01:00
7e33f50cea report: Add a proper "label" field type. 2013-11-17 21:41:27 +01:00
6b41e916ff report: Make dev_size and dev_name columns' type "label". 2013-11-17 21:41:27 +01:00
cc633c84cf label: Track a device pointer in struct label. 2013-11-17 21:41:27 +01:00
dc3a071145 metadata: Add a pv_label accessor (go from a PV to its label). 2013-11-17 21:41:27 +01:00
a2034e9a99 metadata: Add lvmcache_info_mda_free as a companion to pv_mda_free. 2013-11-17 21:41:27 +01:00
1ef2c3c4ee toollib: Implement process_each_label. 2013-11-17 21:41:27 +01:00
9b91977f4e labeller: Make the use of "private" as "fmt" explicit.
All labellers always use the "private" (void *) field as the fmt pointer. Making
this fact explicit in the type of the labeller simplifies the label reporting
code which needs to extract the format. Moreover, it removes a number of
error-prone casts from the code.
2013-11-17 21:41:27 +01:00
bead8ef5f0 metadata: Nuke the exported "pv_read" function. 2013-11-17 21:41:27 +01:00
ba6d6f0028 metadata: Fix handling of orphan PV linking & re-linking. 2013-11-17 21:41:27 +01:00
651d5093ed metadata: Avoid pv_read in find_pv_by_name. 2013-11-17 21:41:27 +01:00
2f5c12e3a8 pvremove: Avoid using pv_read in favour of scanning. 2013-11-17 21:41:27 +01:00
fc02f24178 test: Fix fallout from pv_read changes. 2013-11-17 21:41:27 +01:00
603b45e0ed pvresize: Do not use pv_read (get the PV from orphan VG). 2013-11-17 21:41:27 +01:00
0a59305c44 test: Add a test for the failing pv_read optimisation. 2013-11-17 21:41:26 +01:00
7e685e6c70 toollib: Drop the pv_read optimisation.
Only reading a single PV works correctly only in very limited circumstances.
Moreover, we can't rely on the MDA available on the PV either, since it may be
out of date in some circumstances (until now, we believed that PVs that have an
empty MDA are always orphans, but this is not 100% reliable either).
2013-11-17 21:41:26 +01:00
e1a63905d1 metadata: Do not try to check vg_name of a NULL PV. 2013-11-17 21:41:26 +01:00
803f8ca714 tests: used -n for fsck 2013-11-15 12:38:37 +01:00
3716e95354 tests: indent 2013-11-15 12:38:37 +01:00
89a8c7bea6 cleanup: share the nonremoval message
Use common goto label for not remove log error.
2013-11-15 12:38:37 +01:00
3cb9041764 cleanup: do not pass uninitialized space to selinux.
Just like with dm_prepare_selinux_context rather initialize to NULL.
2013-11-15 12:38:37 +01:00
eb4b03768f libdm: catch wrongly reported values
Add internal error warning when string value is used
as sort value for numerical field.

Using log_warn since the function itself does not return error,
so we do not confuse log_error() checker.
2013-11-15 12:38:37 +01:00
37b7c67079 thin: report thin device id
Support   lvs -o+thin_id  to report thin device id.
This device_id is connection between kernel and lvm2 user space thin
metadata.
2013-11-15 12:38:37 +01:00
6ca832ceaf report: use _field_set_percent
Use common routine for displaying percentage.
2013-11-15 11:05:03 +01:00
36d7c639d1 report: fix dereference of string as uint64_t
Fix buggy usage of "" (empty string) as a numerical string
value used for sorting.

On intel 64b platform this was typically resolve
as 0xffffff0000000000 - which is already 'close' to
UINT64_MAX which is used for _minusone64.

On other platforms it might have been giving
different numbers depends on aligment of strings.

Use proper &_minusone64 for sorting value when the reported
value is NUM.

Note: each numerical value needs to be thought about if it needs
default value &_zero64 or &_minusone64 since for cases, were
value of zero is valid, sorting should not be mixing entries
together.
2013-11-15 11:05:02 +01:00
9eb81b1bf7 report: using _field_set_value
Simple conversion to use _field_set_value() and shorteing
the code.
2013-11-15 11:05:02 +01:00
49ccf44f45 report: add wrappers to set values and percents
Add wrapper function for dm_report_field_set_value() which returns void
and return 1, so the code could be shorter.

Add wrapper function for percent display _field_set_percent().
2013-11-15 11:05:00 +01:00
322e7b3060 post-release 2013-11-13 14:11:11 +00:00
77a1efeb8e release 2.02.104
87 files changed, 1207 insertions(+), 294 deletions(-)
2013-11-13 14:02:34 +00:00
527db4645f gcc: replace #ifdef linux with __linux__ 2013-11-13 13:56:29 +00:00
d8085edf65 pvscan: retry VG refresh before autoactivation if it fails
There's a tiny race when suspending the device which is part
of the refresh because when suspend ioctl is performed, the
dm kernel driver executes (do_suspend and dm_suspend kernel fn):

  step 1: a check whether the dev is already suspended and
          if yes it returns success immediately as there's
          nothing to do
  step 2: it grabs the suspend lock
  step 3: another check whether the dev is already suspended
          and if found suspended, it exits with -EINVAL now

The race can occur in between step 1 and step 2. To prevent
premature autoactivation failure, we're using a simple retry
logic here before we fail completely. For a complete solution,
we need to fix the locking so there's no possibility for suspend
calls to interleave each other to cause this kind of race.

This is just a workaround. Remove it and replace it with proper
locking once we have that in!
2013-11-12 11:09:45 +01:00
7de533ad12 mirror: Handle failures in tmp mirror used when up-converting.
Failures in the temporary mirror used when up-converting cause dmeventd
to issue 'lvconvert --repair' on the sub-LV, <lv_name>_mimagetmp_?.  The
'lvconvert' command refuses to deal with this sub-LV outright - it
expects to be given the name of the top-level LV.  So, just like we do
with mirrored logs, we strip-off the portion of the name that is not
the top-level LV and issue the command on the top-level LV instead.
2013-11-08 09:52:00 -06:00
b6b5299d1e corosync: fix some gcc warnings
warning: function declaration isn't a prototype [-Wstrict-prototypes]
warning: old-style function definition [-Wold-style-definition]
2013-11-06 14:55:18 +01:00
fc144a3fc5 profile: add thin_pool_chunk_size_policy to default.profile
By default, thin_pool_chunk_size_policy is set to "generic".
2013-11-06 13:29:25 +01:00
14b852609b tests: testing thin lvchange
Test various thin change operation,
including activation logic - which is somewhat
limited with singlenode emulation.

More tests needs to be added.
2013-11-01 13:05:05 +01:00
52f41baedb dmsetup: report error on stderr
Send error message on stdout, since after _display_info_long()
command return errors.

Patch makes consistent behavior for command:

dmsetup info -c non-existing-dev
&
dmsetup info non-existing-dev

Now both commands report error on stderr when they return error status
for non-existing device.
2013-11-01 13:05:03 +01:00
9f6209b878 activation: improve activation
This patch fixes mostly cluster behavior but also updates
non-cluster reaction where calls like   'lvchange -aln'
lead to incorrect errors for some segment types.

Fix the implicit activation rules where some segment types could
be activated only in exclusive mode in cluster.
lvm2 command was not preserver 'local' property and incorrectly
converted local activations in to plain exclusive, so the local
activation could have activate volumes exclusively, but remotely.
2013-11-01 13:03:50 +01:00
c3e674ad30 activation: _lv_activate is ok when filtered.
If the volume_list filters out volume from activation,
it is still success result for this function.
Change the error message back to verbose level.

Detect if the volume is active localy before zeroing,
so we report error a bit later for cases, where volume
could not be activated because it doesn't pass through volume
list  (but user still could create volume when he disables
zeroing)
2013-11-01 13:02:36 +01:00
1bde9f68ce locking: activate_lv_excl return correct error code
Correct return code of activate_lv_excl().

Function is not supposed to return activation state of
activated volume, but return code of the operation.
Since i.e. when activation filter is allowing to activate
volume on current system, it is still success even though
no volume is activated.
2013-11-01 13:02:13 +01:00
de7531d384 udev: wrong line in previous commit 2013-10-30 14:28:43 +01:00
f070e3543a udev: properly trigger LVM scan for MD partitions
MD can directly create partition devices without a need to run
an extra kpartx or partprobe call. We need to react to this event in
a different way as for bare MD devices - we need to handle the ADD event
for KERNEL=="md[0-9]*p[0-9]*" kernel name and trigger the LVM scanning
to update lvmetad to trigger autoactivation and so on...

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1023250
2013-10-30 14:09:11 +01:00
264b5c2b12 udev: no need to check DM_NOSCAN in lvmetad rules
It's covered by general DM_UDEV_DISABLE_OTHER_RULES_FLAG.
2013-10-29 13:54:14 +01:00
db05a0cf6f WHATS_NEW: commit 9d06212
Other changes in previous commits 9d06212 and f1a42aa are changes
in the code that was not yet released as part of upcoming v104.
2013-10-29 13:49:55 +01:00
f1a42aa8ec lvconvert: use LV_TEMPORARY when necessary during lvconvert to thin pool
This is an addition to original patch for lvcreate - commit 039bdad.
The same principle applies to lvconvert where there are several steps
during which we need to wipe the existing LV that's being converted
to thin pool, making sure there's no other interference from outside (udev).
2013-10-29 13:33:35 +01:00
9d0621267d udev: proper reset of DM_UDEV_DISABLE_OTHER_RULES_FLAG and honour this flag in lvmetad rules
Reset the DM_UDEV_OTHER_RULES_FLAG to original value right at the
time of dropping the DM_NOSCAN flag.

When DM_NOSCAN is set, the DM_UDEV_DISABLE_OTHER_RULES_FLAG is also set
to avoid udev processing in "other/foreign" rules. If the noscan flag
is dropped, the DM_UDEV_DISABLE_OTHER_RULES_FLAG should be reset to
its original value.

Also, lvmetad should respect the DM_UDEV_DISABLE_OTHER_RULES_FLAG
because if the volume is set with this flag it:
  - definitely is not a top-level device (so makes no sense for lvmetad scanning)
  - is not supposed to be scanned further (for any stacking on top of
    it, including LVM stacking itself and any autoactivation of stacked LVs)
2013-10-29 13:31:00 +01:00
f3a6f7073b WHATS_NEW: commit 4c0db84 2013-10-29 11:04:32 +01:00
8e1f2e733e gcc: fix comparing floating point warning
Since we enabled some more gcc warnings - let's adapt for
it and check for double equals with DBL_EPSILON.

Current close_enough() is far from perfect
for more details see i.e. here:
http://randomascii.wordpress.com/2012/01/11/tricks-with-the-floating-point-format/
but fairly enough for lvm2 use-case.
2013-10-25 10:43:32 +02:00
d4e5140b52 tests: fix old-style gcc warning 2013-10-25 10:37:30 +02:00
7943a13141 configure: check more compile flags
Check for clobbered (and put few others into same league)
2013-10-25 01:00:10 +02:00
d95751cb0b configure: detect compiler flag
Use m4 macro AC_TRY_CCFLAG to detect presence of some compiler
option.
Use it to detect -Wjump-misses-init.
2013-10-25 00:41:36 +02:00
772fa460d1 clean-up: Remove redundant faulty logic
Remove conditional that boils down to "if yes or no, then do".  The
previous condition in the statement is sufficient and the extra
(always true) condition is unnecessary.
2013-10-23 22:44:04 -05:00
4c0db84948 clvmd: fix verify message rejection of REMOTE flag
This fixes a bug in commit 19baf842 where verify_message
was rejecting the CLVMD_FLAG_REMOTE flag.  It was missed
since the patch was ported from an lvm version where that
flag does not exist.
2013-10-24 11:18:22 -05:00
c9c23d4148 build: Use additional gcc warning flags. 2013-10-24 17:10:24 +01:00
d5896f0afd Mirror: Fix hangs and lock-ups caused by attempting label reads of mirrors
There is a problem with the way mirrors have been designed to handle
failures that is resulting in stuck LVM processes and hung I/O.  When
mirrors encounter a write failure, they block I/O and notify userspace
to reconfigure the mirror to remove failed devices.  This process is
open to a couple races:
1) Any LVM process other than the one that is meant to deal with the
mirror failure can attempt to read the mirror, fail, and block other
LVM commands (including the repair command) from proceeding due to
holding a lock on the volume group.
2) If there are multiple mirrors that suffer a failure in the same
volume group, a repair can block while attempting to read the LVM
label from one mirror while trying to repair the other.

Mitigation of these races has been attempted by disallowing label reading
of mirrors that are either suspended or are indicated as blocking by
the kernel.  While this has closed the window of opportunity for hitting
the above problems considerably, it hasn't closed it completely.  This is
because it is still possible to start an LVM command, read the status of
the mirror as healthy, and then perform the read for the label at the
moment after a the failure is discovered by the kernel.

I can see two solutions to this problem:
1) Allow users to configure whether mirrors can be candidates for LVM
labels (i.e. whether PVs can be created on mirror LVs).  If the user
chooses to allow label scanning of mirror LVs, it will be at the expense
of a possible hang in I/O or LVM processes.
2) Instrument a way to allow asynchronous label reading - allowing
blocked label reads to be ignored while continuing to process the LVM
command.  This would action would allow LVM commands to continue even
though they would have otherwise blocked trying to read a mirror.  They
can then release their lock and allow a repair command to commence.  In
the event of #2 above, the repair command already in progress can continue
and repair the failed mirror.

This patch brings solution #1.  If solution #2 is developed later on, the
configuration option created in #1 can be negated - allowing mirrors to
be scanned for labels by default once again.
2013-10-22 19:14:33 -05:00
039bdad732 activation: flag temporary LVs internally
Add LV_TEMPORARY flag for LVs with limited existence during command
execution. Such LVs are temporary in way that they need to be activated,
some action done and then removed immediately. Such LVs are just like
any normal LV - the only difference is that they are removed during
LVM command execution. This is also the case for LVs representing
future pool metadata spare LVs which we need to initialize by using
the usual LV before they are declared as pool metadata spare.

We can optimize some other parts like udev to do a better job if
it knows that the LV is temporary and any processing on it is just
useless.

This flag is orthogonal to LV_NOSCAN flag introduced recently
as LV_NOSCAN flag is primarily used to mark an LV for the scanning
to be avoided before the zeroing of the device happens. The LV_TEMPORARY
flag makes a difference between a full-fledged LV visible in the system
and the LV just used as a temporary overlay for some action that needs to
be done on underlying PVs.

For example: lvcreate --thinpool POOL --zero n -L 1G vg

- first, the usual LV is created to do a clean up for pool metadata
  spare. The LV is activated, zeroed, deactivated.

- between "activated" and "zeroed" stage, the LV_NOSCAN flag is used
  to avoid any scanning in udev

- betwen "zeroed" and "deactivated" stage, we need to avoid the WATCH
  udev rule, but since the LV is just a usual LV, we can't make a
  difference. The LV_TEMPORARY internal LV flag helps here. If we
  create the LV with this flag, the DM_UDEV_DISABLE_DISK_RULES
  and DM_UDEV_DISABLE_OTHER_RULES flag are set (just like as it is
  with "invisible" and non-top-level LVs) - udev is directed to
  skip WATCH rule use.

- if the LV_TEMPORARY flag was not used, there would normally be
  a WATCH event generated once the LV is closed after "zeroed"
  stage. This will make problems with immediated deactivation that
  follows.
2013-10-23 14:09:37 +02:00
1dd6626696 cleanup: for commit 546db1c
- properly clean lvm2-pvscan@.service on distclean
 - use @sbindir@ for sbin path in ExecStop
2013-10-23 09:48:33 +02:00
9883bffb04 WHATS_NEW: typo 2013-10-22 16:37:02 +02:00
b109bfc1ef blkdeactivate: fix endless loop if device(s) given and unable to umount/deactivate
The blkdeactivate script iterates over the list of devices if they're
given as an argument and it tries to umount/deactivate them one by one.

This iteration failed to proceed if any of the umount/deactivation
was unsuccessful - there was a missing "shift" call to move to the
next argument (device) for processing. As a result of this, the same
device was tried again and again, causing an endless loop, never
proceeding to the next device given.
2013-10-22 16:24:39 +02:00
c3f44a0c66 make: correct sed line in udev's Makefile 2013-10-22 15:13:58 +02:00
3fee661028 udev+systemd: refine lvm2-pvscan@.service to better track device existence
When using ENV{SYSTEMD_WANTS}=lvm2-pvscan@... to instantiate a service
for lvmetad scan when the new PV appears in the system, the service
is started and executed. However, to track device removal, we need
to bind it (the "BindsTo" systemd directive) to a certain .device
systemd unit.

In default systemd setup, the device is tracked by it's name and
sysfs path (there's normally a sysfs path .device systemd unit for
a device and then the device name .device unit as an alias for it).
Neither of these two is useful for lvmetad update as we need to bind
it to device's <major>:<minor> pair.

The /dev/block/<major>:<minor> is the essential symlink under /dev
that exists for each block device (created by default udev rules
provided by udev directly). So let's use this as an alias for
the device's .device unit as well by means of "ENV{SYSTEMD_ALIAS}"
declaration within udev rules which systemd understands (this will
create a new alias "dev-block-<major>:<minor>.device".

Then we can easily bind the "dev-block-<major>:<minor>" device
systemd unit with instantiated lvm2-pvscan@<major>:<minor>.service.
So once the device is removed from the systemd, the
lvm-pvscan@<major>:<minor>.service executes it's ExecStop action
(which in turn notifies lvmetad about the device being gone).

This completes the udev-systemd-lvmetad interaction then.
2013-10-22 14:22:40 +02:00
0a48137d39 pvscan: use major:minor as short form of --major and --minor arg for pvscan --cache
Before, pvscan recognized either:
  pvscan --cache --major <major> --minor <minor>
or
  pvscan --cache <DevicePath>

When the device is gone and we need to notify lvmetad about device
removal, only --major/--minor works as we can't translate DevicePath
into major/minor pair anymore. The device does not exist in the system
and we don't keep DevicePath index in lvmetad cache to make the
translation internally into original major/minor pair. It would be
useless to keep this index just for this one exact case.

There's nothing bad about using "--major <major> --minor <minor>",
but it makes our life a bit harder when trying to make an
interconnection with systemd units, mainly with instantiated services
where only one and only one arg can be passed (which is encoded in the
service name).

This patch tries to make this easier by adding support for recognizing
the "<major>:<minor>" as a shortcut for the longer form
"--major <major> --minor <minor>". The rule here is simple: if the argument
starts with "/", it's a DevicePath, otherwise it's a <major>:<minor> pair.
2013-10-22 13:52:18 +02:00
65456a4a29 vgimportclone: remove 2>/dev/null from three lvm commands
There is no point eating stderr for these commands.  In fact the
redirect causes confusion and hurts dubugging.

Also reword an error message if the pvs command fails so as not be
certain that a device is not a PV.  Coupled with removing the stderr
redirect this will improve the user experience in the face of errors.
2013-10-21 18:04:14 -04:00
7763607f36 TEST: Test was trying to kill 2 devices in RAID5 instead of RAID6
Segment type being used for test should have been 'raid6'.
2013-10-18 09:33:37 -05:00
546db1c4be udev+systemd: make pvscan --cache -aay run as systemd background job from udev
The new lvm2-pvscan@.service is responsible for on-demand execution
of "pvscan --cache --activate ay" which causes lvmetad to be
updated and LVM activation done if the VG is complete.

Also, use udev-systemd mechanism to instantiate the job as the
lvm2-pvscan@$devnode.service on each newly appeared PV in the system.
This prevents the background job to be killed (that would happen
if it was directly forked from udev rule - this behaviour is seen
in recent versions of udev with the help of systemd that can track
detached processes - the detached process would still be in the same
cgroup).

To enable this official udev-systemd protocol for instantiating
background jobs, use new --enable-udev-systemd-background-jobs
configure switch (it's disabled by default). This option is highly
recommended wherever systemd is used!
2013-10-18 11:38:49 +02:00
9f406ce252 tests: drop settle for old systems
Reverts previously added udevsettle call.

Seems to be unrelated, while udev on old system may take over 10
minutes, to finish it's very slow and CPU intensive work, it doesn't
interact directly with created device, only access /dev/mapper/control
node via dmsetup, so the device is ocasionaly blocked by something else.
2013-10-17 22:54:12 +02:00
7f4452a41e tests: older losetup allows only single device name
Stay compatible with only 1 arg for losetup -d
2013-10-17 17:52:42 +02:00
d9e44112c5 tests: fix last commit
It must not fail here during execution, so always check in a way
that '||' is used for call of settle.
2013-10-17 16:59:30 +02:00
66f4698a93 tests: workaround udevd compromising tests
Patch helps a bit when lvm2 is build with disabled udev_sync support,
but udevd runs in the system - so it randomly influences unrelated tests
even - so before every test wait at least till udevd is settled.
2013-10-17 16:19:06 +02:00
93a07a1b84 tests: fix exporting content of make vars
Further tune script, so it works correctly with
usable and unusable thin tools.
2013-10-17 11:57:35 +02:00
f9725503f8 tests: use bash for bash script
This script needs bash
2013-10-17 11:57:34 +02:00
ed30145f4a libdm: fix races with udev
On modern systems udev manages nodes in /dev/mapper directory.
It creates, deletes and renames the nodes according to the
state of the kernel driver.

When the dmsetup is compiled without udev support (--enable-udev_sync)
and runs on the system with running udevd it tries to manage nodes in
/dev/mapper too, so it can race with udev.
dmsetup checks if the node was created/deleted/renamed with the stat
syscall, and skips the operation if it was. However, if udev
creates/deletes/renames the node after the stat syscall and before the
mknod/unlink/rename syscall, dmsetup reports an error.

Since in the system everything happened as expected, skip reporting
error for such case.

These races can be easily provoked by inserting sleep at appropriate
places.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2013-10-17 11:57:33 +02:00
3ac7f927e1 libdm: do not show holders missing error
On older system this may not be present, so skip this error message.
2013-10-17 11:55:21 +02:00
efd1dc6bd3 headers: use __linux__ instead of linux
This file may be included by other programs, so it should be compliant
with the C standard.

* use __linux__ instead of linux - __linux__ is always defined, linux is
  not defined when gcc runs in standard-compliant mode (with -std=c89 or
  -std=c99) because the C standard doesn't allow polluting namespace
  with arbitrary defines.

Signed-off-by: Mikulas Patocka <mpatocka@redhat.com>
2013-10-17 11:54:44 +02:00
3924a041ba coverity: sscanf should use "%u" instead of "%i"
The "age" variable is unsigned:

  unsigned age = 0;
  ...
  if (argc == 2 && (sscanf(argv[1], "%i", &age) != 1))
2013-10-17 10:17:16 +02:00
9b13cb8687 tests: correct LVM_TEST_THIN_CHECK_CMD
missed to use proper shell variable
2013-10-16 15:10:03 +02:00
ee878bc52c coverity: assigned variable not used and reassigned later 2013-10-16 15:06:43 +02:00
dd3a2f13f1 thin: missed check for thin_pool in last update 2013-10-16 12:47:30 +02:00
73971e1e7b tests: test repairability of thin pool
Initial testing of thin pool's metadata with thin repairing tools.
Try to use tools from configuration settings, but allow them
to be overriden by settings of these variables:
LVM_TEST_THIN_CHECK_CMD,
LVM_TEST_THIN_DUMP_CMD,
LVM_TEST_THIN_REPAIR_CMD

FIXME: test reveals some more important bugs:
  pvremove -ff also needs --yes
  vgremove -ff doesn not remove metadata when there are no real LVs.
  vgreduce is not able to reduce VG with pool without pool's PVs
2013-10-16 10:54:59 +02:00
7ab5f29a9c tests: add wait
We need to wait till kill really kills sleep
2013-10-16 10:53:03 +02:00
1b7631101b thin: fix lvconvert for active pool.
Prohibit conversion of pool device with active thin volumes.
Properly restore active states only for active thin pool volume.
Use new LV_NOSCAN when converting volume into thin pool's metadata.
2013-10-16 10:53:01 +02:00
48df36b8c5 activation: check for open count with a timeout before removal/deactivation of an LV
This patch reinstates the lv_info call to check for open count of
the LV we're removing/deactivating - this was changed with commit 125712b
some time ago and we relied on the ioctl retry logic deeper in the libdm
while calling the exact 'remove' ioctl.

However, there are still some situations in which it's still required to
check for open count before we do any 'remove' actions - this mainly
applies to LVs which consist of several sub LVs, like it is for
virtual snapshot devices.

The commit 1146691 fixed the issue with ordering of actions during
virtual snapshot removal while the snapshot is still open. But
the check for the open status of the snapshot is still prone to
marking the snapshot as in use with an immediate exit even though
this could be a temporary asynchronous open only, most notably
because of udev and its WATCH udev rule with accompanying scans
for the event which is asynchronous. The situation where this crops
up most often is when we're closing the LV that was open for read-write
and then calling lvremove immediately.

This patch reinstates the original lv_info call for the open status
of the LV in the lv_check_not_in_use fn that gets called before
we do any LV removal/deactivation. In addition to original logic,
this patch adds its own retry loop with a delay (25x0.2 seconds)
besides the existing ioctl retry loop.
2013-10-15 12:44:42 +02:00
d97583cfd3 RAID: Better error message when attempting scrubbing op on thinpool LV
Component LVs of a thinpool can be RAID LVs.  Users who attempt a
scrubbing operation directly on a thinpool will be prompted to
specify the sub-LV they wish the operation to be performed on.  If
neither of the sub-LVs are RAID, then a message telling them that
the operation can only be performed on a RAID LV will be given.
2013-10-14 15:14:16 -05:00
f58b26b633 RAID: Report RAID images split with tracking as out-of-sync ("I").
Split image should have an out-of-sync attr ('I') - always.  Even if
the RAID LV has not been written to since the LV was split off, it is
still not part of the group that makes up the RAID and is therefore
"out-of-sync".
2013-10-14 10:48:44 -05:00
0f55d7cccc tests: lvcreate and snapshot update
Test creation really in cluster.
Update test to check removal when snapshot device is being held open.
2013-10-14 00:29:03 +02:00
9f8f6bfefe tests: harness updates
Reshape code a bit to make sockepair 'swappable' with plain old pipe
call.

Display status for FAILED error.

Increase buffer to hold always at least 1 page size.

Print error results with capitals.
2013-10-14 00:26:59 +02:00
851bba258c snapshot: rework parsing of snapshot metadata
Add better parsing code for snapshot metadata, which describe
properly errors found for snapshot segment.
2013-10-14 00:26:58 +02:00
1146691afc snapshot: deactivate virtual snapshot first
Since the virtual snapshot has no reason to stay alive once we
detach related snapshot - deactivate whole thing in front of
snapshot removal - otherwice the code would get tricky for
support in cluster.

The correct full solution would require to have transactions
for libdm operations.

Also enable to the check for snapshot being opened prior
the origin deactivation, otherwise we could easily end
with the origin being deactivate, but snapshot still kept
active, desynchronizing locking state in cluster.
2013-10-14 00:25:15 +02:00
ac961087b0 snapshot: disable merging for virtual snaps
Merging into virtual origin is not supposed to work.
2013-10-12 00:15:55 +02:00
81504ba70c snapshot: move virtsnap code from tool to lib
Move code for removal dependency from tool's remove.c
into lib's manipulation code.

Same code then works with lvm2app.
2013-10-12 00:14:52 +02:00
6b35c70e8b metadata: add INTERNAL_ERROR to "Metadata inconsistency" msg
So we can spot it better if it occurs.
2013-10-10 13:34:43 +02:00
029b8fbe76 metadata: properly register LV_NOSCAN flag
Addendum to commit ce7489e which introduced a new *internal* LV_NOSCAN
flag and so it needs to be marked that way properly otherwise it
ends up unrecognized and improperly handled during metadata export.
2013-10-10 13:24:32 +02:00
304159c99a cleanup: WHATS_NEW + compiler warning about discarding const 2013-10-10 09:09:16 +02:00
7d299ecbb3 libdaemon: Fix a subtle race in worker thread creation. 2013-10-10 00:34:35 +02:00
cb613d4c10 lvmetad: Fix a possible deadlock in pv_clear_all. 2013-10-10 00:34:35 +02:00
b5aad86710 libdm: Fix a data race in dm_pool_{create,destroy}. 2013-10-10 00:34:35 +02:00
529a13ec89 libdm: Link to libpthread unconditionally. 2013-10-10 00:34:35 +02:00
7bed6d1263 filters: Add NVM Express (nvme). 2013-10-09 20:08:07 +01:00
1b91847beb WHATS_NEW: commit 0decd75 2013-10-09 15:59:19 +02:00
bcb44281b7 lvmetad: Do not try to lock a NULL vgid. 2013-10-09 14:56:06 +02:00
17f3b8280b test: Correctly trigger inconsistent metadata repair in lvmcache-exercise.
Since lvconvert --repair sets handles_missing_pvs, it will not repair
inconsistent metadata automatically. Calling lvs instead should do the trick.
2013-10-09 14:44:15 +02:00
0decd7553a metadata: Fix metadata repair paths when lvmetad is used. 2013-10-09 14:44:01 +02:00
fbb6de845e test: Make comma a separator as in make check T=lvconvert,lvcreate 2013-10-09 14:02:34 +02:00
863be9d9c6 WHATS_NEW: commit d888a05 and 808a5d9 2013-10-09 12:11:12 +02:00
a7c73154ea cleanup: remove 'discards 'const' qualifier' compilation warning 2013-10-09 10:05:02 +02:00
808a5d945e libdaemon: Fix an invalid memory read. 2013-10-08 23:21:09 +02:00
d888a0557e lvmetad: Properly grab locks in pv_gone. 2013-10-08 23:21:09 +02:00
805f7e4042 lvmetad: Clean up pvid->vgid map when last PV in a VG disappears. 2013-10-08 23:21:09 +02:00
830d233b17 tests: needed --type mirror
Avoid testing raids here (would need kernel module)
2013-10-08 16:56:09 +02:00
2ee969e851 tests: reappering device
Simulation of problem for:
https://bugzilla.redhat.com/show_bug.cgi?id=995440
2013-10-08 16:19:14 +02:00
2f5ddfbade udev: add support for "NOSCAN" flag
Recognize DM_SUBSYSTEM_UDEV_FLAG0 which for LVM is the "LVM_NOSCAN"
flag that causes the scanning to be skipped (mainly blkid) and
also directs all the foreign rules to be skipped as well.

Important thing here is that the "watch" udev rules is still set
as well as the /dev/disk/by-id content created (which does not
require any scanning to be done). Also, the flag is dropped on
any subsequent event and scanning done...
2013-10-08 13:43:14 +02:00
ce7489ed22 activation: add support for flagging an LV to skip udev scanning during activation
A common scenario is during new LV creation when we need to wipe the
newly created LV and avoid any udev scanning before this stage otherwise
it could cause the device (the LV) to be claimed by some other subsystem
for which there were stale metadata within LV data.

This patch adds possibility to mark the LV we're just about to wipe with
a flag that gets passed to udev via DM_COOKIE as a subsystem specific
flag - DM_SUBSYSTEM_UDEV_FLAG0 (in this case the subsystem is "LVM")
so LVM udev rules will take care of handling that.
2013-10-08 13:43:14 +02:00
273373bf53 tests: lvconvert more thin extorg conversions
Add test for conversion of pool and thin lv at the same time.
2013-10-08 13:42:10 +02:00
7edf61186b tests: vgrename duplicate rename
Test for rename of duplicated vgname (with different UUID)
2013-10-08 13:42:09 +02:00
92bafade60 thin: fix lvconvert in external origin conversion
Patch 562ad293fd introduced code regression
when LV was converted to a thin LV with external origin and at the same time,
conversion of LV to a thin pool has been requested.
(RHBZ: #997704)

data_lv needs to be assigned after test for external conversion find pool.
2013-10-08 13:41:06 +02:00
30746f31dd vgrename: run fullscan
For vgrename run full scan so the command is able to properly
detect name collision.
2013-10-08 13:39:11 +02:00
4806f38d70 lvchange: improve discards when pool active error
Existing message deemed misleading:
  Cannot change discards state for active pool volume

https://bugzilla.redhat.com/show_bug.cgi?id=994315
2013-10-07 23:50:09 +01:00
761b524519 post-release 2013-10-04 14:41:32 +01:00
04d9a52684 release 2.02.103
52 files changed, 598 insertions(+), 264 deletions(-)
2013-10-04 14:32:23 +01:00
0d03503a45 lvmetad: Fix vgname->vgid hash updates w/ duplicate VG names. 2013-10-04 14:31:45 +02:00
a7ff7aee4f WHATS_NEW: renamed thin_pool_chunk_size_calculation -> policy 2013-10-04 12:36:32 +02:00
8cf0810d57 thin: rename thin_pool_chunk_size_calculation -> ..size_policy and rename "default" policy to "generic"
Just to be consistent with existing naming we use.
2013-10-04 12:30:33 +02:00
baf95bbff7 cmdline: Add --ignoreskippedcluster.
Accept --ignoreskippedcluster with pvs, vgs, lvs, pvdisplay, vgdisplay,
lvdisplay, vgchange and lvchange to avoid the 'Skipping clustered
VG' errors when requesting information about a clustered VG
without using clustered locking and still exit with success.

The messages can still be seen with -v.
2013-10-01 21:20:10 +01:00
23ce3352d7 libdm: export DM_UDEV_SUBSYSTEM_FLAG names for subystem udev flags
Just like we have symbolic names assigned to general DM udev flags
(DM_UDEV_* flags), we have the same for any subsystem flags now
(DM_SUBSYSTEM_UDEV_FLAG*), making it easier to use.
2013-09-30 11:19:09 +02:00
ec9b3dcecc udev: make subsystem rules responsible for importing subsystem flags
Each subsystem rule that needs to import any of DM_SUBSYSTEM_UDEV_FLAG*
flags is responsible for doing so. This simply moves control of these
flags from general 10-dm.rules to any subsystem rule using these flags
as each subsystem knows better how to handle these flags on its own.
2013-09-30 11:11:18 +02:00
24ffd5244f thin: better dbg msgs and avoid uninit. value on chunk size recalc 2013-09-30 08:58:57 +02:00
e02ff32260 fix: also make commit b4637 work without dmeventd 2013-09-30 08:17:56 +02:00
e4c7236c07 udev: fix 3min udev timeout so that it is applied for all LVM volumes
The timeout should be set before any volume skipping.
2013-09-27 15:37:16 +02:00
b4637bd298 fix: make it possible to compile with --disable-devmapper again
Some code has been added recently which makes it impossible to compile
when "configure --disable-devmapper" is used. This patch just shuffles
the code around so it's under proper #ifdef DEVMAPPER_SUPPORT.
2013-09-27 13:58:55 +02:00
acdc731e83 RAID: Fix _sufficient_pes_free calculation for RAID
lib/metadata/lv_manip.c:_sufficient_pes_free() was calculating the
required space for RAID allocations incorrectly due to double
accounting.  This resulted in failure to allocate when available
space was tight.

When RAID data and metadata areas are allocated together, the total
amount is stored in ah->new_extents and ah->alloc_and_split_meta is
set.  '_sufficient_pes_free' was adding the necessary metadata extents
to ah->new_extents without ever checking ah->alloc_and_split_meta.
This often led to double accounting of the metadata extents.  This
patch checks 'ah->alloc_and_split_meta' to perform proper calculations
for RAID.

This error is only present in the function that checks for the needed
space, not in the functions that do the actual allocation.
2013-09-26 11:30:07 -05:00
d6516d2f79 WHATS_NEW: description for previous commit
commit 098896fb29 failed to include
description of what was fixed.

"Conversion from linear to mirror or RAID1 now honors
 mirror_segtype_default."
2013-09-25 22:35:52 -05:00
098896fb29 mirror/RAID: Honor mirror_segtype_default when converting from linear
1) When converting from an x-way mirror/raid1 to a y-way mirror/raid1,
the default behaviour should be to stay the same segment type.

2) When converting from linear to mirror or raid1, the default behaviour
should honor the mirror_segtype_default.

3) When converting and the '--type' argument is specified, the '--type'
argument should be honored.

catch such conditions, but errors in the tests caused the issue to go
unnoticed.  The code has been fixed to perform #2 properly, the tests
have been corrected to properly test for #2, and a few other tests
were changed to explicitly specify the '--type mirror' when necessary.
2013-09-25 22:25:43 -05:00
dd796d6a94 profile: add thin-performance.profile
Define a "performance" profile for thin pools which is exactly:
  - allocation/thin_pool_zero = 0
  - thin_pool_chunk_size_calculation = "performance"
2013-09-25 16:07:35 +02:00
78cba8eb3f thin: calculate thin pool chunk size based on device IO hints
If "default" thin pool chunk size calculation method is selected,
use minimum_io_size, otherwise optimal_io_size for "performance"
device hint exposed in sysfs. If there appear to be PVs with
different hints presented, use their least common multiple.

If the hint is less than the default value defined for the
calculation method, use the default value instead.
2013-09-25 16:06:38 +02:00
cc9e65c391 thin: use appropriate default value based on allocation/thin_pool_chunk_size_calculation setting
If thin_pool_chunk_size_calculation is set to "default", use 64KiB,
otheriwse 512KiB for "performance".
2013-09-25 16:06:38 +02:00
8bf425005c conf: add allocation/thin_pool_chunk_size_calculation
Add allocation/thin_pool_chunk_size_calculation lvm.conf
option to select a method for calculating thin pool chunk
sizes and define two possible values - "default" and "performance".
2013-09-25 16:06:38 +02:00
c37c59e155 Test/clean-up: Indent clean-up and additional RAID resize test
Better indenting and a test for bug 1005434 (parity RAID should
extend in a contiguous fashion).
2013-09-24 21:32:53 -05:00
5ded7314ae RAID: Fix broken allocation policies for parity RAID types
A previous commit (b6bfddcd0a) which
was designed to prevent segfaults during lvextend when trying to
extend striped logical volumes forgot to include calculations for
RAID4/5/6 parity devices.  This was causing the 'contiguous' and
'cling_by_tags' allocation policies to fail for RAID 4/5/6.

The solution is to remember that while we can compare
	ah->area_count == prev_lvseg->area_count
for non-RAID, we should compare
	(ah->area_count + ah->parity_count) == prev_lvseg->area_count
for a general solution.
2013-09-24 21:32:10 -05:00
6553f86818 lvmconf: use_lvmetad=0 on --enable-cluster, reset to default on --disable-cluster
lvmetad is not yet supported in clustered environment so
disable it automatically if using lvmconf --enable-cluster
and reset it to default value if using lvmconf --disable-cluster.

Also, add a few comments in lvm.conf about locking_type vs. use_lvmetad
if setting it for clustered environment.
2013-09-24 14:03:42 +02:00
f050278a35 tools: don't install separate command symlink for lvm devtypes 2013-09-24 09:35:20 +02:00
11dc6a03c4 lvs: Add seg_size_pe field.
Requested
https://www.redhat.com/archives/linux-lvm/2013-July/msg00112.html
2013-09-23 21:50:14 +01:00
8de47abcd2 Merge branch 'master' of /data/agk/git/lvm2-upstream 2013-09-23 19:59:47 +01:00
194d2479f7 cmdline: Accept PE ranges as start+length. 2013-09-23 19:55:50 +01:00
b2535d0c97 pvmove: clean exit on failed pvmove restart
At present, before the pvmove command can be used to restart pvmove
polling, the LVs concerned need to be activated e.g. with lvchange
-ay.
2013-09-23 19:53:18 +01:00
7233e584ad pvmove: Accept PE ranges as start+length. 2013-09-23 19:50:34 +01:00
bbcc120e5a pvmove: clean exit on failed pvmove restart
At present, before the pvmove command can be used to restart pvmove
polling, the LVs concerned need to be activated e.g. with lvchange -ay.
2013-09-23 19:46:28 +01:00
229e0752f1 post-release 2013-09-23 15:55:11 +01:00
c8057aec36 release 2.02.102
18 files changed, 137 insertions(+), 203 deletions(-)
2013-09-23 15:43:37 +01:00
431eda63cc clvmd: Fix node up/down handing in corosync module
The corosync cluster interface for clvmd did not correctly
deal with node up/down events so that when a node was removed
from the cluster clvmd would prevent remote operations
from happening, as it thought the node was up but not
running clvmd.

This patch fixes that code by simplifying the case to node
being  up or down - which was the original intention
and is supported by pacemaker and CPG in the higher layers.

Signed-off-by: Christine Caulfield <ccaulfie@redhat.com>
2013-09-23 13:23:00 +01:00
9658032cba tests: drop extra loop
Loop was added as a result of unworking singlenode locking, since
this should be now fixed - remove this workaround.
2013-09-23 12:14:21 +02:00
151f4ba64e tests: drop pointeless test
Writing directly to thin-pool and reading it is not a good idea.
2013-09-23 12:14:21 +02:00
ec66ff818c tests: fix typo VEROSE->VERBOSE in Makefile.in 2013-09-23 12:14:21 +02:00
ced563e3a7 tests: hide expected error message 2013-09-23 12:14:20 +02:00
ebf66ac316 Makefile: add missing deps
Add missing deps for device-mapper build of scripts dir.
Cleanup multiple SUBDIR lines together.
2013-09-23 12:13:51 +02:00
1fdead8d97 activation: use improved lv_info
Call lv_info() with info == NULL to query for local active presence.
2013-09-23 12:13:08 +02:00
3b604e5c8e lvinfo: allow to use lv_info with NULL info
When NULL info struct is passed in - function is usable
as a quick query for  lv_is_active_locally() - with a bonus
we may query for layered device.

So it could be seen as a more efficient lv_is_active_locally().
2013-09-23 12:13:06 +02:00
b29adbbc4d raid: add lv_is_raid()
More readable then status bit flag masking...
2013-09-23 11:35:15 +02:00
a94e28ae01 dmeventd: simplify fifos init
Simplier code.
2013-09-23 11:35:15 +02:00
b33b618fc8 cleanup: drop unused report parameter
Do not pass unused dm_report pointer.
2013-09-23 11:35:15 +02:00
9b4bfca219 cleanup: add log_error error path messages 2013-09-23 11:35:15 +02:00
d2d61955a3 cleanup: shorter code
Put assignment on declaration line.
2013-09-23 11:35:15 +02:00
85b9c12e92 cleanup: release all memory in error path
Just ensure no memory will stay in pool even in error path.
2013-09-23 11:35:15 +02:00
30432bd604 cleanup: skip call of detect...
SInce we know the pool was locked and we want to reloc pool again,
just use '1' directly.
2013-09-23 11:35:15 +02:00
861a3b2f19 cleanup: monitoring more readable
Put continue path into one code segment.
2013-09-23 11:35:15 +02:00
cafde60890 test: Blacklist fedora-19 kernel for RAID4/5/6 dev replace tests
A know issue with kmem_cach is causing failures while testing
RAID 4/5/6 device replacement.  Blacklist the offending kernel
so that these tests are not performed there.
2013-09-20 11:33:29 -05:00
bd75844024 release 2.02.101
112 files changed, 4131 insertions(+), 1312 deletions(-)
2013-09-20 13:56:29 +01:00
f393a5c156 udev: remove unused line in 69-dm-lvm-metad.rules
The explicit check for *_raid_member is not actually needed as
this gets filtered out by the ENV{ID_FS_TYPE}!="LVM2_member|LVM1_member" rule.
2013-09-20 09:45:34 +02:00
2c41c8b886 RAID: Don't allow syncaction changes on non-RAID LVs
Don't allow syncaction or other RAID-type messages on non-RAID
logical volumes.
2013-09-19 22:33:01 -05:00
25bed99681 clvmd: Avoid a 3-way deadlock in dead-client cleanup. 2013-09-18 21:17:48 +02:00
3df50d822b vgconvert: Do not call lvmetad_vg_remove (path shared with vgcfgbackup). 2013-09-18 12:53:11 +02:00
054cf25b5f vgcfgrestore: Remove VG rom lvmetad later, to better deal with errors. 2013-09-18 11:24:58 +02:00
a6af611ae1 vgcfgrestore: Remove the VG from lvmetad before overwriting it. 2013-09-18 10:37:29 +02:00
c2dd0a832a man: lvs man page was not accurate on the volume health bit of lv_attr
The 'm'ismatches flag only shows after a "check" scrubbing operation -
not after a "check" or "repair" as indicated by the man page.
2013-09-17 23:03:57 -05:00
68f841fcda dmsetup: Detect invalid sector supplied to message.
atoll doesn't check for errors, so invalid sector numbers were silently
accepted in the "dmsetup message" command.

(Mikulas)
2013-09-18 01:24:19 +01:00
6e912d949b tools: Avoid overflow in _get_int_arg.
Use strtoull instead of strtol so that argument size is not cut
to 31 bytes on machines with 32-bit long.

(Mikulas)
2013-09-18 01:16:48 +01:00
a0ca2c11ee libdm: avoid leak if dm_task_set_* fn called again
(Mikulas)
2013-09-18 01:13:06 +01:00
a3a5f58c21 reporting: Add devtypes command.
Add internal devtypes reporting command to display built-in recognised
block device types.  (The output does not include any additional
types added by a configuration file.)

> lvm devtypes -o help
  Device Types Fields
  -------------------
    devtype_all            - All fields in this section.
    devtype_name           - Name of Device Type exactly as it appears in /proc/devices.
    devtype_max_partitions - Maximum number of partitions. (How many device minor numbers get reserved for each device.)
    devtype_description    - Description of Device Type.

> lvm devtypes
  DevType       MaxParts Description
  aoe                 16 ATA over Ethernet
  ataraid             16 ATA Raid
  bcache               1 bcache block device cache
  blkext               1 Extended device partitions
...
2013-09-18 01:09:15 +01:00
d1bcb21e02 WHATS_NEW: Better description for commit 82228ac
More correct description of changes made to disallow thin+mirror.
2013-09-16 15:37:48 -05:00
ce9a5cc257 debug: Use // for commented out debug #defines
The traditional style used for optional editable definitions
/* #define X	/* */
produces a bogus warning from gcc -Wall.

Rather than suppressing this with -Wno-comment, switch over to
the // comment style.
2013-09-16 20:20:26 +01:00
36c5bb40a2 Makefiles: Fix CC variable override.
The CC override in commit f42b2d4bbf
caused the built-in value to be used instead of the configured value
when it wasn't being overridden.

The behaviour is explained here:
	http://stackoverflow.com/questions/18007326/how-to-change-default-values-of-variables-like-cc-in-makefile
2013-09-16 19:57:14 +01:00
97ba18f4cb filters: Add bcache.
N.B. Using bcache devices as PVs is still experimental.
Problems should be reported to the appropriate mailing lists.
2013-09-16 16:56:55 +01:00
10bc19ec10 doc: add a note about device filtering while lvmetad is used 2013-09-16 16:29:33 +02:00
61427af377 tests: no activate LV
Since our current vgcfgbackup/restore doesn't deal
with difference of active volumes between current and
restored set of volumes -  run test with inactive LVs.
2013-09-16 15:38:42 +02:00
2abaf87a9b tests: update vgcfgrestore test
Test vgcfgrestore when seqno of restored mda is smaller then current
metadata on device.
2013-09-16 13:48:44 +02:00
9742c5192e systemd: run lvm2-activation-net.service after lvm2-activation.service
The lvm2-activation-net.service was ordered only with respect to iscsi
and fcoe service before. In addition to that, we also need ordering
with respect to lvm2-activation.service to prevent parallel vgchange -aay
runs which may cause some problems during activation.
See also https://bugs.gentoo.org/show_bug.cgi?id=480066.

With this patch, the ordering is firmly set to:
lvm2-activation-early.service -> lvm2-activation.service -> lvm2-activation-net.service

Thanks to Alexander Tsoy for the original patch (modified a bit here):
https://www.redhat.com/archives/lvm-devel/2013-September/msg00049.html
2013-09-16 11:47:09 +02:00
fbb732bd8e tests: enhance pvmove testing
Rewrite check lv_on  and add new  lv_tree_on
Move more pvmove test unrelated code out to check & get sections
(so they do not obfuscate trace output unnecesserily)

Use new lv_tree_on()
NOTE: unsure how the snapshot origin should be accounted here.

Split pmove-all-segments into separate tests for raid and thins
(so the test output properly shows what has been skipped in test)
2013-09-16 11:22:04 +02:00
47b7cc6850 tests: use check for raid test
Use test-suite built-in check command for this test
(creates better logs, and reduces amount of valgrind-ed commands)
2013-09-16 11:22:04 +02:00
9df27c4279 tests: update check and get
Update usage of "" around shell vars.
trim needs to trim both sides now.
trim also removes debug.log since it's only called when lvm command
has finished properly (so if something fails afterward, there
is no missleading debug trace in the log)
2013-09-16 11:22:04 +02:00
51d3667cb5 tests: update die
'die' evaluates given string - so \n could be used for
multiline error report

Also remove debug.log since the command finished properly when we
call 'die'

Note: we should not call 'die' after lvm command failure.
2013-09-16 11:22:04 +02:00
d6090a10f0 tests: add help function
Add mkdev_md5sum to create and checksum given LV.
Add dev_md5sum to verify device has matching md5 sum.
2013-09-16 11:22:04 +02:00
1d06868240 TEST: Unaccounted possible output causing failure
lvchange-raid.sh checks to ensure that the 'p'artial flag takes
precedence over the 'w'ritemostly flag by disabling and reenabling
a device in the array.  Most of the time this works fine, but
sometimes the kernel can notice the device failure before it is
reenabled.  In that case, the attr flag will not return to 'w', but
to 'r'efresh.  This is because 'r'efresh also takes precedence over
the 'w'ritemostly flag.  So, we also do a quick check for 'r' and
not just 'w'.
2013-09-12 13:23:53 -05:00
e2268aeb92 WHATS_NEW: some missing lines 2013-09-12 14:16:54 +02:00
6940e24aee udev: keep DM_ACTIVATION and DM_UDEV_PRIMARY_SOURCE_FLAG meaning as before commit 8d1d835
The DM_ACTIVATION and DM_UDEV_PRIMARY_SOURCE_FLAG needs to be kept the
way it was for backward compatibility (e.g. the old rules are still
in initramfs). This way the check in whether the device should be
scanned in 69-dm-lvmetad.rules is even easier.
2013-09-12 13:49:02 +02:00
4d54400486 tests: extend harness with output of /var/log/messages
Add a very simple hack for embeding /var/log/messages into
the tests output - it's not ideal since it sometimes breaks lines,
but still gives valuable info.
2013-09-12 13:30:12 +02:00
4dc1668467 tests: singlenode cleanup for prev commit
Add few more comments and cleanup some warnings.
2013-09-12 11:29:18 +02:00
2a6abcb80a tests: singlenode updates
Add more 'realistic' simulation of dlm locking.
Previous version was not capable to maintain multiple locks.
Current version doesn't handle multiqueues for locks,
so the ordering is different.
2013-09-12 10:40:39 +02:00
7b5f2e7f34 clvmd: add missing debug newline
Just missing new line.
2013-09-12 10:38:49 +02:00
b8ea27ac97 cleanup: hide gcc warning
Older gcc is giving misleading warning:

metadata/lv_manip.c:4018: warning: ‘seg’ may be used uninitialized in
this function

But warning free compilation is better.
2013-09-11 23:40:45 +02:00
82228acfc9 Mirror/Thin: Disallow thinpools on mirror logical volumes
The same corner cases that exist for snapshots on mirrors exist for
any logical volume layered on top of mirror.  (One example is when
a mirror image fails and a non-repair LVM command is the first to
detect it via label reading.  In this case, the LVM command will hang
and prevent the necessary LVM repair command from running.)  When
a better alternative exists, it makes no sense to allow a new target
to stack on mirrors as a new feature.  Since, RAID is now capable of
running EX in a cluster and thin is not active-active aware, it makes
sense to pair these two rather than mirror+thinpool.

As further background, here are some additional comments that I made
when addressing a bug related to mirror+thinpool:
(https://bugzilla.redhat.com/show_bug.cgi?id=919604#c9)
I am going to disallow thin* on top of mirror logical volumes.
Users will have to use the "raid1" segment type if they want this.

This bug has come down to a choice between:
1) Disallowing thin-LVs from being used as PVs.
2) Disallowing thinpools on top of mirrors.

The problem is that the code in dev_manager.c:device_is_usable() is unable
to tell whether there is a mirror device lower in the stack from the device
being checked.  Pretty much anything layered on top of a mirror will suffer
from this problem.  (Snapshots are a good example of this; and option #1
above has been chosen to deal with them.  This can also be seen in
dev_manager.c:device_is_usable().)  When a mirror failure occurs, the
kernel blocks all I/O to it.  If there is an LVM command that comes along
to do the repair (or a different operation that requires label reading), it
would normally avoid the mirror when it sees that it is blocked.  However,
if there is a snapshot or a thin-LV that is on a mirror, the above code
will not detect the mirror underneath and will issue label reading I/O.
This causes the command to hang.

Choosing #1 would mean that thin-LVs could never be used as PVs - even if
they are stacked on something other than mirrors.

Choosing #2 means that thinpools can never be placed on mirrors.  This is
probably better than we think, since it is preferred that people use the
"raid1" segment type in the first place.  However, RAID* cannot currently
be used in a cluster volume group - even in EX-only mode.  Thus, a complete
solution for option #2 must include the ability to activate RAID logical
volumes (and perform RAID operations) in a cluster volume group.  I've
already begun working on this.
2013-09-11 15:58:44 -05:00
1f4bc637b4 WHATS_NEW: one more for commit 8d1d835 2013-09-11 13:16:36 +02:00
fe227d14a5 WHATS_NEW: for commit 8d1d8350 and 72a9d4f 2013-09-11 13:01:01 +02:00
72a9d4f879 udev: override new udev default timeout of 30s to original 3min
New versions of udev changed the default event timeout to 30s
from original 3min. This causes problems with LVM processes that
starve because of the IO load caused by some LVM actions (e.g.
mirror/raid synchronization).

Reinstate the 3min udev timeout for now until we optimize this
in a way that even the 30s timeout is sufficient.
2013-09-11 12:47:38 +02:00
2691f1d764 RAID: Make RAID single-machine-exclusive capable in a cluster
Creation, deletion, [de]activation, repair, conversion, scrubbing
and changing operations are all now available for RAID LVs in a
cluster - provided that they are activated exclusively.

The code has been changed to ensure that no LV or sub-LV activation
is attempted cluster-wide.  This includes the often overlooked
operations of activating metadata areas for the brief time it takes
to clear them.  Additionally, some 'resume_lv' operations were
replaced with 'activate_lv_excl_local' when sub-LVs were promoted
to top-level LVs for removal, clearing or extraction.  This was
necessary because it forces the appropriate renaming actions the
occur via resume in the single-machine case, but won't happen in
a cluster due to the necessity of acquiring a lock first.

The *raid* tests have been updated to allow testing in a cluster.
For the most part, this meant creating devices with '-aey' if they
were to be converted to RAID.  (RAID requires the converting LV to
be EX because it is a condition of activation for the RAID LV in
a cluster.)
2013-09-10 16:33:22 -05:00
8d1d83504d udev: fix pvscan --cache -aay to trigger on relevant events
This patch fixes the way the special devices are handled
(special in this context means that they're not usable
after the usual ADD event like other generic devices):

  - DM and MD devices are pvscanned only when they are just set up.
    This is the first CHANGE event that makes the device  usable
    (the DM_UDEV_PRIMARY_SOURCE_FLAG is set for DM and the
     md/array_state sysfs attribute is present for MD).
    Whether the device is activated is remembered via
    DM_ACTIVATED (for DM) and LVM_MD_PV_ACTIVATED (for MD)
    udev environment variable. This is then used to decide
    whether we should fire the pvscan on ADD event to
    support coldplugging. For any (artificial) ADD event
    generated during coldplug, the device must be already
    set up properly to fire the pvscan on it.

  - Similar for loop devices. For loop devices, only CHANGE
    events are relevant (so there's a CHANGE after the loop
    device is set up as well as detached). Whether the loop
    has just been activated is detected via loop/backing_file
    sysfs attribute presence. The activation state is remembered
    via LVM_LOOP_PV_ACTIVATED udev environment variable.

  - Do not pvscan multipath device components (underlying paths).

  - Do not pvscan RAID device components.

  - Also, set LVM_SCANNED="1" udev environment variable for
    debug purposes (it's visible in the lvmdump -u that takes
    the current udev database). This variable is set once
    the pvscan is triggered.

The table below summarises when the pvscan is triggered
(marked with X, X* means fire only if the special dev is properly set up):

      | real ADD | real CHANGE | artificial ADD | artificial CHANGE | remove
=============================================================================
DM    |          |      X      |       X*       |                   |   X
MD    |          |      X      |       X*       |                   |
loop  |          |      X      |       X*       |                   |
other |    X     |             |       X        |                   |   X
2013-09-10 16:27:58 +02:00
9ba40da7ae udev: DM_ID_FS_TYPE should be ID_FS_TYPE when comparing with old value 2013-09-10 12:39:23 +02:00
ca51435153 Misc/RAID: Enable resume_lv to handle some renaming conflicts.
When images and their associated metadata are removed from a RAID1 LV,
the remaining sub-LVs are "shifted" down to fill the gaps.  For
example, if there is a 3-way mirror:
	[0][1][2]
and we remove device#0, the devices will be shifted down
	[1][2]
and renamed.
	[0][1]

This can create a problem for resume_lv (specifically,
dm_tree_activate_children) during the renaming process though.  This
is because it will attempt to rename the higher indexed sub-LVs first
and find that it cannot because there are currently other sub-LVs with
that name.  The solution is to check for a conflicting name before
attempting to rename.  If a conflict is found and that conflicting
sub-LV is also in the process of renaming, we can defer the current
rename until the conflicting sub-LV has renamed and cleared the
conflict.

Now that resume_lv can handle these types of rename conflicts, we can
remove the workaround in RAID that was attempting to resume a RAID1
LV from the bottom-up in order to force a proper rename in assending
order before attempting a resume on the top-level LV.  This "hack"
only worked for single machine use-cases of LVM.  Clearing this up
paves the way for exclusive activation of RAID LVs in a cluster.
2013-09-09 15:07:28 -05:00
9f2fc2471c udev: also inform lvmetad about lost LVM1 PV label
Addendum to 4d3b5724e0
which covered only LVM2 PV labels.
2013-09-09 13:48:27 +02:00
d89b514e06 cleanup: drop within comment gcc warning
toollib.c:69:24: warning: "/*" within comment
2013-09-09 12:17:11 +02:00
ac2de55d69 test: timeout when no write happens since last written line
Change current test abort after 3 minutes, to abort after 3 minutes
without written output line.
2013-09-09 12:17:11 +02:00
f5832d8c49 deactivate: drop readahead calc in deactivation
Skip readahead when device will be deactivated.
2013-09-07 09:13:20 +02:00
0670bfeb59 thin: validation catch multiseg thin pool/volumes
Multisegment thin pools and volumes are not supported.
Catch such error code path early.
2013-09-07 03:32:07 +02:00
655296609e thin: fix monitoring of thin pool volume
Properly skip unmonitoring of thin pool volume in deactivation code
path. Code makes sure if there is just any thin pool user
it stays monitored with all its resources.
2013-09-07 03:31:04 +02:00
4c001a7854 thin: fix resize of stacked thin pool volume
When the pool is created from non-linear target the more complex rules
have to be used and stacking needs to properly decode args for _tdata
LV. Also proper allocation policies are being used according to those
set in lvm2 metadata for data and metadata LVs.

Also properly check for active pool and extra code to active it
temporarily.

With this fix it's now possible to use:

lvcreate -L20 -m2 -n pool vg  --alloc anywhere
lvcreate -L10 -m2 -n poolm vg --alloc anywhere
lvconvert --thinpool vg/pool --poolmetadata vg/poolm

lvresize -L+10 vg/pool
2013-09-07 03:24:48 +02:00
fe6b19a6a3 test: Add the 64b fc17 kernel to the mirror recovery blacklist. 2013-09-06 16:50:05 +02:00
10a5838a60 toollib: tweak background forking
Log what is forked and replace #if 1 with DEBUG_CHILD.
2013-09-06 01:49:43 +01:00
96880102a3 logging: Write Completed message before resetting. 2013-09-06 01:47:41 +01:00
5face2010d tools: Use backgroundfork_ARG for pvscan -b
Change pvscan -b to use a new backgroundfork_ARG instead of
background_ARG so as not to affect pvmove -b and lvconvert -b.
2013-09-06 01:43:24 +01:00
374653f2b5 test: Include tests that timed out in the final summary. 2013-09-04 16:21:08 +02:00
cc66dedc0e pvmove: Skip pvmove of RAID, thin, snapshot, origin, and mirror LVs in cluster
pvmove of the above types should only have been enabled in single machine
mode.
2013-09-03 13:17:01 -05:00
7918217c75 test: Fix a spurious failure in skip_if_mirror_recovery_broken. 2013-09-03 20:06:24 +02:00
848e8026d6 TEST: pvmove-all-segtypes.sh should not be run in a cluster 2013-09-03 10:54:42 -05:00
3b51f298bb reinstate: commit 82d83a01ce
It now works as supposed. The source of the problem is fixed
by previous commit d2d6a9da52e04f28e1916bcea3f9fda356b6df29.
2013-09-03 16:49:21 +02:00
008c33a21b tools: add -b/--background for pvscan --cache -aay
Udev daemon has recently introduced a limit on the number of udev
processes (there was no limit before). This causes a problem
when calling pvscan --cache -aay in lvmetad udev rules which
is supposed to activate the volumes. This activation is itself
synced with udev and so it waits for the activation to complete
before the pvscan finishes. The event processing can't continue
until this pvscan call is finished.

But if we're at the limit with the udev process count, we can't
instatiate any more udev processes, all such events are queued
and so we can't process the lvm activation event for which the
pvscan is waiting.

Then we're in a deadlock since the udev process with the
pvscan --cache -aay call waits for the lvm activation udev
processing to complete, but that will never happen as there's
this limit hit with the number of udev processes.

The process with pvscan --cache -aay actually times out eventually
(3min or 30sec, depends on the version of udev).

This patch makes it possible to run the pvscan --cache -aay
in the background so the udev processing can continue and hence
we can avoid the deadlock mentioned above.
2013-09-03 16:49:21 +02:00
ea1e8166d5 test: Skip tests involving mirror recovery on known bad kernels. 2013-09-03 16:24:32 +02:00
6a5838a69c pvscan: show -aay with --cache for help 2013-09-03 09:51:30 +02:00
44c1a02c18 revert: commit 82d83a01ce
The commit 82d83a01ce
"autoactivation: refresh existing VG before autoactivation"
causes problems (dangling udev_sync cookies, slow processing
of the pvscan --cache --major --minor call from udev rules)
when the autoactivation handler is run in parallel on
several PVs that belong to the same VG. Revert this patch
until the exact source of the problem is found and then
properly fixed and handled.
2013-09-02 13:53:27 +02:00
039585bb0d tests: test pvmove behavior after restart
Simulate crash of the system and restarted pvmove after next VG
activation.

Test is catching regression introduced in 2.02.99 for partial tree
creation changes.
2013-08-31 21:40:51 +02:00
7cc36a93f6 tests: add delay_dev
Function to create slower responsive device.

Useful for testing things which needs to happen something during on
going operation - with  'delayed' device - much smaller sizes of devices
are needed and its much more deterministic (though still not optimal)
2013-08-31 21:40:51 +02:00
350cf7968c libdm: new name can't be empty
Do not allow passing '' names to kernel.

This test was missing also in kernel, so it has allowed
to create device with '' name.  This then confused dmsetup tool,
since such name is unexpected and unsupported. To remove
such name from table, user has to use -j -m to specify which device
should be removed.

This patch fixes the posibility to run this operation:

dmsetup rename existingdev ''

after this operation commands like  'dmsetup table' are failing.
This patch prohibits to use such name.
2013-08-31 21:40:28 +02:00
eee3aeeb61 test: fix process-each-duplicate-vgnames
After enable_dev, the following commands were not
consistently seeing the pv on it.

Alasdair explained, "whenever enabling/disabling devs
outside the tools (and you aren't trying to test how
the tools cope with suddenly appearing/disappering
devices) use "vgscan""
2013-08-30 11:53:10 -05:00
c36dcc1728 man: lvmdump -u -l 2013-08-29 14:20:57 +02:00
78647da1c6 toolcontext: Only reopen stdin if readable.
Don't fail when running lvm commands under versions of nohup that set
up stdin as O_WRONLY!
2013-08-28 23:55:14 +01:00
c0f987949b activation: Fix segfault with inactive pvmove LV.
Set flag to avoid recursion back through an inactive pvmove LV when
populating deptree.
2013-08-28 22:56:23 +01:00
0acd7173d1 systemd: lvm2-activation-generator: remove default dir if args not specified and require all args to be given
Remove default "/tmp" as destination directory if no args
specified for lvm2-activation-generator. Require all the
args to be specified directly for proper functionality.
2013-08-28 16:06:51 +02:00
c9258e7f2e man: lvmdump: add doc for -l and -u 2013-08-28 14:59:15 +02:00
8b3664dc8d test: Set the timeout to 3 minutes (was 5s accidentally). 2013-08-28 14:53:23 +02:00
64fe17dc94 test: Add a new "check_full" target, which also tests with real /dev.
The original "check" target stays confined to a local device directory, while
check_full does 6 flavours, 3 with a local device directory and 3 with the
global /dev directory (the latter are prefixed with "s" for
"system"). I.e.: normal, cluster, lvmetad, snormal, scluster, slvmetad.
2013-08-28 14:53:23 +02:00
b516a72b11 test: Check for flavoured variables earlier.
This is necessary to make LVM_TEST_DEVDIR flavourable, and in turn have flavours
that use the global /dev (which can in turn be managed by udev).
2013-08-28 14:53:23 +02:00
d07cf851e5 test: Remove a redundant drain() from the timeout path. 2013-08-28 14:53:23 +02:00
c1217e6881 test: Make timeouts a little more robust & verbose. 2013-08-28 14:53:23 +02:00
9a1da7b262 TEST: Add a timeout to the harness, killing tests after 2 minutes. 2013-08-28 14:53:23 +02:00
e72b2d047d TEST: Add tests for lvchange actions of RAID under thin
Patch includes RAID1,4,5,6,10 tests for:
- setting writemostly/writebehind
* syncaction changes (i.e. scrubbing operations)
- refresh (i.e. reviving devices after transient failures)
- setting recovery rate (sync I/O throttling)
while the RAID LVs are under a thin-pool (both data and metadata)

* not fully tested because I haven't found a way to force bad
  blocks to be noticed in the testsuite yet.  Works just fine
  when dealing with "real" devices.
2013-08-27 16:46:40 -05:00
0799e81ee0 test: pvmove tests for all the different segment types.
Test moving linear, mirror, snapshot, RAID1,5,10, thinpool, thin
and thin on RAID.  Perform the moves along with a dummy LV and
also without the dummy LV by specifying a logical volume name as
an argument to pvmove.
2013-08-26 16:38:54 -05:00
2ef48b91ed pvmove: Allow moving snapshot/origin. Disallow converting and merging LVs
The patch allows the user to also pvmove snapshots and origin logical
volumes.  This means pvmove should be able to move all segment types.
I have, however, disallowed moving converting or merging logical volumes.
2013-08-26 16:36:30 -05:00
caa77b33f2 pvmove: Fix inability to specify LV name when moving RAID, mirror, or thin LV
Top-level LVs (like RAID, mirror or thin) are ignored when determining which
portions of an LV to pvmove.  If the user specified the name of an LV to
move and it was one of the above types, it would be skipped.  The code would
never move on to check whether its sub-LVs needed moving because their names
did not match what the user specified.

The solution is to check whether a sub-LVs is part of the LV whose name was
specified by the user - not just if there was a name match.
2013-08-26 14:12:31 -05:00
d34ab5e0d3 WHATS_NEW: for 4d3b5724e0 2013-08-26 15:52:15 +02:00
4d3b5724e0 udev: inform lvmetad about lost PV label
In stacked environment where we have a PV layered on top of a
snapshot LV and then removing the LV, lvmetad still keeps information
about the PV:

[0] raw/~ $ pvcreate /dev/sda
  Physical volume "/dev/sda" successfully created
[0] raw/~ $ vgcreate vg /dev/sda
  Volume group "vg" successfully created
[0] raw/~ $ lvcreate -L32m vg
  Logical volume "lvol0" created
[0] raw/~ $ lvcreate -L32m -s vg/lvol0
  Logical volume "lvol1" created
[0] raw/~ $ pvcreate /dev/vg/lvol1
  Physical volume "/dev/vg/lvol1" successfully created
[0] raw/~ $ lvremove -ff vg/lvol1
  Logical volume "lvol1" successfully removed
[0] raw/~ $ pvs
  No device found for PV BdNlu2-7bHV-XcIp-mFFC-PPuR-ef6K-yffdzO.
  PV         VG         Fmt  Attr PSize   PFree
  /dev/sda   vg         lvm2 a--  124.00m 92.00m
[0] raw/~ $ pvscan --cache --major 253 --minor 3
  Device 253:3 not found. Cleared from lvmetad cache.

This is because of the reactivation that is done just before
snapshot removal as part of the process (vg/lvol1 from the example above).
This causes a CHANGE event to be generated, but any scan done
on the LV does not see the original data anymore (in this case
the stacked PV label on top) and consequently the ID_FS_TYPE="LVM2_member"
(provided by blkid scan) is not stored in udev db anymore for the LV.
Consequently, the pvscan --cache is not run anymore as the dev is not
identified as LVM PV by the "LVM2_member" id - lvmetad loses this info
and still keeps records about the PV.

We can run into a very similar problem with erasing the PV label directly:

[0] raw/~ $ lvcreate -L32m vg
  Logical volume "lvol0" created
[0] raw/~ $ pvcreate /dev/vg/lvol0
  Physical volume "/dev/vg/lvol0" successfully created
[0] raw/~ $ dd if=/dev/zero of=/dev/vg/lvol0 bs=1M
dd: error writing '/dev/vg/lvol0': No space left on device
33+0 records in
32+0 records out
33554432 bytes (34 MB) copied, 0.380921 s, 88.1 MB/s
[0] raw/~ $ pvs
  PV            VG         Fmt  Attr PSize   PFree
  /dev/sda      vg         lvm2 a--  124.00m 92.00m
  /dev/vg/lvol0            lvm2 a--   32.00m 32.00m
[0] raw/~ $ pvscan --cache --major 253 --minor 2
  No PV label found on /dev/vg/lvol0.

This patch adds detection of this change from ID_FS_LABEL="LVM2_member"
to ID_FS_LABEL="<whatever_else>" and hence informing the lvmetad
about PV being gone.
2013-08-26 15:40:16 +02:00
6b416f837f thin: support lvchange for data and metadata
Support lvchange operation on stacked thin pool data and metadata
volumes.
2013-08-26 14:55:22 +02:00
7d6a125e97 test: add process-each-vg and process-each-lv
These test the toollib functions that select
vgs/lvs to process based on command line args:
empty, vg name(s), lv names(s), vg tag(s),
lv tags(s), and combinations of all.
2013-08-23 14:38:48 -05:00
506bc045b5 test: add process-each-duplicate-vgnames
Test that vgs shows both vgs when two vgs
exist with the same name but different uuids.
2013-08-23 14:19:59 -05:00
8c511122f4 test: add vg-name-from-env
vg name should come from env var LVM_VG_NAME
for commands that take vg name and lv name,
but vg name is not specified on command line.
2013-08-23 14:10:29 -05:00
72d6bdd6b9 misc: make lv_is_on_pv use for_each_sub_lv to walk LV tree
Make lv_is_on_pv use for_each_sub_lv to walk the LV tree.  This
reduces code duplication.
2013-08-23 11:03:28 -05:00
448ff0119f pvmove: Ability to move thin volumes
The previous commit was missing the code to allow moving thin
volumes.
2013-08-23 09:13:14 -05:00
c59167ec13 pvmove: Add support for RAID, mirror, and thin
This patch allows pvmove to operate on RAID, mirror and thin LVs.
The key component is the ability to avoid moving a RAID or mirror
sub-LV onto a PV that already has another RAID sub-LV on it.
(e.g. Avoid placing both images of a RAID1 LV on the same PV.)

Top-level LVs are processed to determine which PVs to avoid for
the sake of redundancy, while bottom-level LVs are processed
to determine which segments/extents to move.

This approach does have some drawbacks.  By eliminating whole PVs
from the allocation list, we might miss the opportunity to perform
pvmove in some senarios.  For example, if we have 3 devices and
a linear uses half of the first, a RAID1 uses half of the first and
half of the second, and a linear uses half of the third (FIGURE 1);
we should be able to pvmove the first device (FIGURE 2).
	FIGURE 1:
        [ linear ] [ -RAID- ] [ linear ]
        [ -RAID- ] [        ] [        ]

	FIGURE 2:
        [  moved ] [ -RAID- ] [ linear ]
        [  moved ] [ linear ] [ -RAID- ]
However, the approach we are using would eliminate the second
device from consideration and would leave us with too little space
for allocation.  In these situations, the user does have the ability
to specify LVs and move them one at a time.
2013-08-23 08:57:16 -05:00
e5c0213168 Thin: Make 'lv_is_on_pv(s)' work with thin types
The pool metadata LV must be accounted for when determining what PVs
are in a thin-pool.  The pool LV must also be accounted for when
checking thin volumes.

This is a prerequisite for pvmove working with thin types.
2013-08-23 08:49:16 -05:00
f1e3640df3 Misc: Make get_pv_list_for_lv() available to more than just RAID
The function 'get_pv_list_for_lv' will assemble all the PVs that are
used by the specified LV.  It uses 'for_each_sub_lv' to traverse all
of the sub-lvs which may compose it.
2013-08-23 08:40:13 -05:00
be9f4c77c9 conf: more comments about use_lvmetad + autoactivation relation 2013-08-22 08:29:20 +02:00
99fe3b88d2 systemd: lvm2-activation-generator: report only error otherwise be silent
Do not print success status for lvm2-activation-generator:

  "LVM: Activation generator successfully completed."
  "LVM: Logical Volume autoactivation enabled." (if use_lvmetad=1)

Though this information is quite useful during boot, it may
be confusing for users if it happens anytime later and it
actually happens if systemd reloads. This is usually on package
update to update the systemd state and load any new units that are
newly installed in the system. The systemd reload is global and
so any existing generators are rerun at that moment too.
2013-08-22 08:27:51 +02:00
c8daa15270 filter-mpath: remove superfluous error message about mpath major not equal to dm major
This is a regression caused by commit 3bd9048854.
The error message added with that commit "mpath major %d is not dm major %d" is
superfluous.

When scanning for mpath components, we're looking for a parent device.
But this parent device is not necessarily an mpath device (so the dm device)
if it exists - it can be any other device layered on top (e.g. an MD RAID device).
2013-08-21 14:07:01 +02:00
f0be9ac904 cmirrord: Prevent secondary checkpoints from corrupting bitmaps
The bug addressed by this patch manifested itself during testing
by showing a mirror that never became 'in-sync' after creation.
The bug is isolated to distributions that do not have support
for openAIS checkpointing (i.e. > RHEL6, > F16).

When a node joins a group that is managing a mirror log, the other
machines in the group send it a checkpoint representing the current
state of the bitmap.  More than one machine can send a checkpoint,
but only the initial one should be imported.  Once the bitmap state
has been imported from the initial checkpoint, operations (such
as resync, mark, and clear operations) can begin.  When subsequent
checkpoints are allowed to be imported, it has the effect of erasing
all the log operations between the initial checkpoint and the ones
that follow.

When cmirrord was updated to handle the absence of openAIS
checkpointing (commit 62e38da133),
the new import_checkpoint() function failed to honor the 'no_read'
parameter.  This parameter was designed to avoid reading all but
the initial checkpoint.  Honoring this parameter has solved the
issue of corrupting bitmap data with secondary checkpoints.
2013-08-20 13:21:09 -05:00
99fd710cfd dumpconfig: also mention profilable type if giving hint about known types 2013-08-19 08:32:03 +02:00
d8b781e8ab dmsetup: display any message output from kernel
Recent kernels allow messages to respond with a string.
Add dm_task_get_message_response() to libdevmapper to perform some
basic sanity checks and return this.
Have 'dmsetup message' display any response.

DM statistics will make extensive use of this.

(From Mikulas.)
2013-08-16 15:25:39 +01:00
cac49725c9 udev: fix lvmetad rules to not ignore loop device configuration
If loop device is first configured on systems where /dev/loop-control
is used to dynamically create the loop device itself, there's an
ADD+CHANGE even generated. But next time the existing /dev/loop[0-9]*
is reused, there's only a CHANGE event since the device representing
it is already present in kernel (so no ADD event in this case).

We can't ignore this CHANGE event for loop devices! This is a regression
caused by 756bcabbfe. We already had
a similar problem with MD devices which was fixed by
2ac217d408 (but that one was
only an intra-release fix).
2013-08-16 15:45:00 +02:00
f1dc4d3d81 fix: ambiguity in log_sys_error call from previous commit
libdm-common.c:883:42: warning: pointer/integer type mismatch in conditional expression

define log_sys_error(x, y) log_err("%s%s%s failed: %s", y, *y ? ": " : "", x, strerror(errno))

So the "y" which was 'path ? : "SELinux context reset"' from
previous commit did not quite fit the other "? :" in the log_sys_macro.
2013-08-15 12:50:58 +02:00
0563bd0037 fix: some issues reported by coverity
- null_fd resource leak on error path in _reopen_fd_null fn
  - dead code in verify_message in clvmd code
  - dead code in _init_filter_components in toolcontext code
  - null dereference in dm_prepare_selinux_context on error path if
    setfscreatecon fails while resetting SELinux context
2013-08-15 12:23:49 +02:00
8cbbe851a8 systemd: use LVM_PATH instead of hardcoded value in activation generator 2013-08-15 09:59:19 +02:00
c29c64f20d lvm2app: lvm_list_pvs_free seg. fault when no PVs
When the system has no PVs we don't have access to
the cmd pointer and it remains NULL which causes
a seg. fault when we try to free the VG lock.

Signed-off-by: Tony Asleson <tasleson@redhat.com>
2013-08-14 15:17:39 -05:00
732e609fe2 test: Fix false positives due to open devices
Something is rather randomly keeping devices open. As it is a known udev
feature, waiting for transaction may (or may not) help.
2013-08-14 16:04:01 +02:00
82d83a01ce autoactivation: refresh existing VG before autoactivation
When autoactivating a VG, there could be an existing VG with exactly
the same PV UUIDs. The PVs could be reappeared after previous
loss/disconnect (for example disconnecting and reconnecting iscsi).

Since there's no "autodeactivation" yet, the mappings for the LVs
from the VG were left in the system even if the device was disconnected.
These mappings also hold the major:minor of the underlying device.
So if the device reappears, it is assigned a different major:minor
pair (...and kernel name). We need to cope with this during
autoactivation so any existing mappings are corrected for any changes.
The VG refresh does that (the vgchange --refresh functionality) -
call this before VG autoactivation.

(If the VG does not exist yet, the VG refresh is NOP)
2013-08-14 14:04:58 +02:00
fcbb34bdcc WHATS_NEW: for 0da72743ca 2013-08-14 10:18:02 +02:00
80bcdb93ff filters: check for mpath before opening devs
Split out the partitioned device filter that needs to open the device
and move the multipath filter in front of it.

When a device is multipathed, sending I/O to the underlying paths may
cause problems, the most obvious being I/O errors visible to lvm if a
path is down.

Revert the incorrect <backtrace> messages added when a device doesn't
pass a filter.

Log each filter initialisation to show sequence.

Avoid duplicate 'Using $device' debug messages.
2013-08-13 23:26:58 +01:00
0da72743ca vgck: Fix #894136, notice on-disk corruption in spite of lvmetad. 2013-08-13 23:25:49 +02:00
1a1d3a10ff vgchange: require confirmation with -c and no VGs
Too many people have been running 'vgchange -cy' by mistake
so add a confirmation prompt.  Use --yes to bypass this.
2013-08-13 18:20:11 +01:00
fd7cac15bc WHATS_NEW: be more precise 2013-08-13 18:25:54 +02:00
e166c00ac6 WHATS_NEW: one more for a85439 2013-08-13 18:16:05 +02:00
268b370e24 blkdeactivate: add support for bind mounts
Recent version of util-linux/umount (v2.23+) provides
umount --all-targets that can unmount all the mount targets of
the same device (the bind mounts). Use this if available when
calling the umount blkdeactivate.

Otherwise, for older versions of util-linux, use findmnt
(that is also a part of the util-linux) to iterate over all
mount targets of the same device - this is the manual way.
2013-08-13 17:51:40 +02:00
a854398764 blkdeactivate: change the way blkdeactivate reports status
The blkdeactivate now suppresses error messages from external
tools that are called. Instead, only a summary message "done"
or "skipped" is issued by blkdeactivate as any error in calling
the external tool (e.g. unmounting or deactivating a device) causes
the device to be skipped and the blkdeactivate continues with the
next device in the tree.

Add new -e/--errors switch to display any error messages from
external tools.

Also, suppress any output given by the external tools and add
new -v/--verbose switch to display it including the verbose
output of the tools called (this will enable error reporting
as well).

Also add blkdeactivate -vv for even more debug (the script's debug).
2013-08-13 17:51:23 +02:00
32148369d1 post-release 2013-08-13 11:54:48 +01:00
564 changed files with 37251 additions and 12840 deletions

View File

@ -16,7 +16,7 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SUBDIRS = conf include man
SUBDIRS = conf daemons include lib libdaemon libdm man scripts tools
ifeq ("@UDEV_RULES@", "yes")
SUBDIRS += udev
@ -26,8 +26,6 @@ ifeq ("@INTL@", "yes")
SUBDIRS += po
endif
SUBDIRS += lib tools daemons libdm libdaemon
ifeq ("@APPLIB@", "yes")
SUBDIRS += liblvm
endif
@ -36,8 +34,6 @@ ifeq ("@PYTHON_BINDINGS@", "yes")
SUBDIRS += python
endif
SUBDIRS += scripts
ifeq ($(MAKECMDGOALS),clean)
SUBDIRS += test
endif
@ -55,6 +51,7 @@ DISTCLEAN_TARGETS += config.cache config.log config.status make.tmpl
include make.tmpl
libdm: include
libdaemon: include
lib: libdm libdaemon
liblvm: lib
daemons: lib libdaemon tools
@ -67,6 +64,7 @@ libdm.device-mapper: include.device-mapper
liblvm.device-mapper: include.device-mapper
daemons.device-mapper: libdm.device-mapper
tools.device-mapper: libdm.device-mapper
scripts.device-mapper: include.device-mapper
device-mapper: tools.device-mapper daemons.device-mapper man.device-mapper
ifeq ("@INTL@", "yes")
@ -94,7 +92,7 @@ all: cscope.out
endif
DISTCLEAN_TARGETS += cscope.out
check check_cluster check_local check_lvmetad unit: all
check check_system check_cluster check_local check_lvmetad unit: all
$(MAKE) -C test $(@)
install_system_dirs:
@ -111,6 +109,7 @@ install_initscripts:
install_systemd_generators:
$(MAKE) -C scripts install_systemd_generators
$(MAKE) -C man install_systemd_generators
install_systemd_units:
$(MAKE) -C scripts install_systemd_units

View File

@ -1 +1 @@
2.02.100(2)-git (2013-08-13)
2.02.112(2)-git (2014-09-01)

View File

@ -1 +1 @@
1.02.79-git (2013-08-13)
1.02.91-git (2014-09-01)

442
WHATS_NEW
View File

@ -1,3 +1,445 @@
Version 2.02.112 -
=====================================
Disable vgchange of clustered attribute with any active LV in VG.
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.
Demote an error to a warning when devices known to lvmetad are filtered out.
Re-order filter evaluation, making component filters global.
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() error path in raid target.
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.
Introduce common code to modify metadate 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.
Fix open_count test for lvchange --refresh or mirrors and raids.
Update pvs,vgs,lvs and lvm man page for selection support.
Add -S/--select to lvm devtypes for report selection.
Add -S/--select to pvs,vgs,lvs and {pv,vg,lv}display -C for report selection.
Use dm_report_init_with_selection now, implicit "selected" field appears.
Make use of libdm's DM_REPORT_FIELD_TYPE{SIZE,PERCENT,STRING_LIST} for fields.
Support all-or-nothing pvmove --atomic.
Automatically add snapshot metadata size for -l %ORIGIN calculation.
When converting RAID origin to cache LV, properly rename sub-LVs.
Use RemoveOnStop for lvm2-lvmetad.socket systemd unit.
Add thin-generic configuration profile for generic thin settings.
Fix crash when reporting empty labels on pvs.
Use retry_deactivation also when cleaning orphan devices.
Wait for client threads when shutting down lvmetad.
Remove PV from cache on pvremove.
Avoid repeatedly reporting of failure to connect to lvmetad.
Introduce MDA_FAILED to permit metadata updates even if some mdas are missing.
Prompt when setting the VG cluster attr if the cluster is not setup.
Allow --yes to skip prompt in vgextend (worked only with -f).
Don't use name mangling for LVM - it never uses dm names with wrong char set.
Remove default.profile and add {command,metadata}_profile_template.profile.
Use proper umask for systemd units generated by lvm2-activation-generator.
Check for failing mirror_remove_missing() function.
Prompt before converting volumes to thin pool and thin pool metadata.
Add dumpconfig --type profilable-{metadata,command} to select profile type.
Exit immediately with error if command profile is found invalid.
Separate --profile cmd line arg into --commandprofile and --metadataprofile.
Strictly separate command profiles and per-VG/LV profiles referenced in mda.
Fix dumpconfig --type diff when run as second and later cmd in lvm shell.
Fix wrong profile reuse from previous run if another cmd is run in lvm shell.
Move cache description from lvm(8) to new lvmcache(7) man page.
Display skipped prompt in silent mode.
Make reporting commands show help about possible sort keys on '-O help'.
Add metadata_percent to lvs_cols.
Take account of parity areas with alloc anywhere in _calc_required_extents.
Use proper uint64 casting for calculation of cache metadata size.
Better support for nesting of blocking signals.
Use only sigaction handler and drop duplicate signal handler.
Separate signal handling and flock code out into lib/misc.
Don't start dmeventd checking seg_monitor and monitoring is disabled.
Catch CTRL-c during pvremove prompts.
Show correct availability status for snapshot origin in lvscan.
Move segment thin pool/volume info into segment display 'lvdisplay --maps'.
Display thin pool usage even when just thin volume is available.
Display monitoring status for monitorable segments in 'lvdisplay --maps'.
Display virtual extents for virtual LVs in 'lvdisplay --maps'.
Make vgsplit fail cleanly when not all PVs are specified for RAID 4/5/6.
Make vgsplit work on mirrors with logs that share PVs with images.
Use devices/ignore_suspended_devices=0 by default if not defined in lvm.conf.
Use proper libmem mempool for allocation of unknown segment name.
Add --readonly to reporting and display tools for lock-free metadata access.
Add locking_type 5 for dummy locking for tools that do not need any locks.
Fix _recover_vg() error path when lock conversion fails.
Use X for LV attributes that are unknown when activation disabled.
Only output lvdisplay 'LV Status' field when activation is enabled.
Use lvmetad_used() in pvscan instead of config_tree.
Configure --enable-udev-systemd-background-jobs if not disabled explicitly.
Add lvmdump -s to collect system info and context (currently systemd only).
Refactor allocation code to make A_POSITIONAL_FILL explicit.
Use thread-safe ctime_r() for clvmd debug logging.
Skip adding replies to already finished reply thread.
Use mutex to check number of replies in request_timed_out() in clvmd.
Drop usage of extra reply_mutex for localsock in clvmd.
Protect manipulation with finished flag with mutex in clvmd.
Shift mutex creation and destroy for localsock in clvmd to correct place.
Fix usage of --test option in clvmd.
Skip more libraries to be mlocked in memory.
Remove LOCKED flag for pvmove replaced with error target.
Return invalid command when specifying negative polling interval.
Version 2.02.106 - 10th April 2014
==================================
Fix ignored --dataalignment/dataalignment offset for pvcreate --restorefile.
Fix lost information about bootloader area when using lvmetad.
Don't require --major to be specified when using -My option on kernels > 2.4.
Add configure --disable-thin_check_needs_check to support old thin_check.
Use thin_check --clear-needs-check-flag by default.
Export lvm_even_rand() for controlled provision of random numbers.
Add lvmthin man page to section 7.
Ensure mapped device names are not too long in vg_validate and lvrename.
Ensure resume failure in lvrename results in command failure.
Add explicit error message when using lvdisplay -c -m.
Report error if superfluous argument (e.g. PV name) supplied to pvscan.
Fix error message for pvdisplay -c -m and add one for pvdisplay -c -s.
Use EINVALID_CMD_LINE correctly instead of ECMD_FAILED in vgimport/export.
Obtain list of known VGs from lvmetad for pvchange --all.
Add man page for lvm-dumpconfig to section 8.
Drop unused cmd pointer for internal function for_each_sub_lv().
Validate name for renamed sub LVs.
When lvrename fails on argument parsing return EINVALID_CMD_LINE.
Fix exit code regression in failing pvchange command (2.02.66).
Include 'lvm dumpconfig --type missing' and '--type diff' output to lvmdump.
Return failure when specifying negative size for pvresize.
Fix memory corruption in cmd context refresh if clvmd leaks opened device.
Reinitialise lvmcache properly on fork to fix premature polldaemon exit.
Add 'lvm dumpconfig --type diff' to show differences from defaults.
Fix swap signature detection for devices smaller then 2MB.
Use dm_malloc function in clvmd.c.
Resolve memory release order for clvmd shutdown.
Report error when lvm2 activation is released in critical_section.
Fix memory corruption when pvscan reports long pv names.
Do not report internal orphan VG names when reporting pvdisplay/pvscan.
Fix pvdisplay -c man page referencing KB instead of sectors.
Skip redundant synchronization calls on local clvmd.
Use correct PATH_MAX for locking dir path.
Do not check for backups when when its creation is disabled.
Don't allow --mergedconfig without --type current in dumpconfig. Fix memleak.
Make global/lvdisplay_shows_full_device_path lvm.conf setting profilable.
Make global/{units|si_unit_consistency|suffix} lvm.conf setting profilable.
Validate minimal chunk size for snapshot COW volume in lvconvert.
Disallow lvconvert of origin to snapshot COW volume.
Make report lvm.conf settings profilable.
Add existing report settings to lvm.conf.
Use VG read lock during 'pvscan --cache -aay' autoactivation.
Issue a VG refresh before autoactivation only if the PV has changed/is new.
Add flag to lvmetad protocol to indicate the PV scanned has changed/is new.
Also add vgname to lvmetad protocol when referencing VGs for PVs scanned.
Add man page for lvm2-activation-generator.
Don't print an error and accept empty value for global/thin_disabled_features.
Update API for internal function build_dm_uuid().
Do not try to check empty pool with scheduled messages.
Fix return value in pool_has_message() when quering for any message.
Cleanup all client resources on clvmd exit.
Use dm_zalloc to clear members of clvmd client struct.
Use BLKID_CFLAGS when compiling with blkid support.
Use correct rl_completion_func_t typedef for new readline.
Make lvm 'dumpconfig --type default' complete for it to be consumed by lvm.
Run pvscan --cache via systemd-run in udev if the PV label is detected lost.
Fix memleak when lvmetad discovers PV to appear on another device.
Fix calculation of maximum size of COW device for snapshot (2.02.99).
Do not allow stripe size to be bigger then extent size for lvresize.
Zero snapshot COW header when creating read-only snapshot.
Comment out config lines in dumpconfig output without default values defined.
Improve detection of clustered mirror support.
Enhance raid code with feature flags, for now checks for raid10.
Move parsing of VG metadata from vg_commit() back to vg_write() (2.02.99)
Avoid a PV label scan while in a critical section.
Remove (always 0) skip argument from lv_activation_skip().
Create /dev/disk/by-id/lvm-pv-uuid-<PV_UUID> symlink for each PV via udev.
lvcreate computes RAID4/5/6 stripes if not given from # of allocatable PVs.
Fix merging of old snapshot into thin volume origin.
Use --ignoreskippedcluster in lvm2-monitor initscript/systemd unit.
Do not use VG read/write state for LV read/write state.
Use --ignoreskippedcluster in activation systemd units if use_lvmetad=0.
Allow approximate allocation when specifying size in percentage terms.
Add basic LVM support for cache[pool] segment types.
Use local exclusive activation for creation of raid in cluster.
Use correctly signed 64b constant when selecting raid volumes.
Add systemd native service for clvmd, cmirrord and clustered LV activation.
Remove ExecReload from lvmetad systemd unit: lvmetad -R undefined. (2.02.98)
Do not fork lvmetad if running under systemd.
Wipe DM_snapshot_cow signature without prompt in new LVs with blkid wiping.
Avoid exposing temporary devices when initializing raid metadata volumes.
Add internal tags command to display any tags defined on the host.
Prohibit use of external origin with size incompatible with thin pool.
Avoid trying to convert single to thin pool and volume at the same time.
Add support for partitions on ZFS zvol.
Fix unwanted drop of hold flocks on forked children.
Respect LVM_LVMETAD_PIDFILE env var for lvm command.
Avoid exposing temporary devices when initializing thin pool volume.
Fix test when checking target version for available thin features.
Detect thin feature external_origin_extend and limit extend when missing.
Rename internal pool_can_resize_metadata() to thin_pool_feature_supported().
Issue error if libbblkid detects signature and fails to return offset/length.
Update autoconf config.guess/sub to 2014-01-01.
Online thin pool metadata resize requires 1.10 kernel thin pool target.
Version 2.02.105 - 20th January 2014
====================================
Fix thin LV flagging for udev to skip scanning only if the LV is wiped.
Replace use of xfs_check with xfs_repair in fsadm.
Mark lvm1 format metadata as FMT_OBSOLETE. Do not use it with lvmetad.
Invalidate cached VG struct after a PV in it gets orphaned. (2.02.87)
Mark pool format metadata as FMT_OBSOLETE.
Use major:minor in lvm2-pvscan@.service for proper global_filter application.
Syntax and spelling fixes in some man pages.
Dependency scan counts with snapshots and external origins.
Make sure VG extent size is always greater or equal to PV phys. block size.
Optimize double call of stat() for cached devices.
Enable support for thin provisioning for default configuration.
Improve process_each_lv_in_vg() tag processing.
Reordered and simplified logging code.
Fix SYSTEMD_READY assignment for foreign devices in lvmetad udev rules.
Disable online thin pool metadata resize for 1.9 kernel thin target.
Shortened code for initialization of raid segment types.
Cache global library dir in command context.
Return success when inserting dirs and links into device cache.
Test for remote exclusive activation after activation fails.
Support lvconvert --merge for thin snapshots.
Add support to read thin device id from table line entry.
Drop extra test for origin when testing merging origin in lv_refresh().
Extend lv_remove_single() to not print info about removed LV.
Replace open_count check with lv_check_not_in_use() for snapshot open test.
Add error messages with LV names for failing lv refresh.
Compile/link executables with new RELRO and PIE options (non-static builds).
Support per-object compilation cflags via CFLAGS_object.o.
Automatically detect support for compiler/linker options to use RELRO and PIE.
Add --splitsnapshot to lvconvert to separate out cow LV.
Reinstate origin reload to complete lvconvert -s with active LVs. (2.02.98)
Select only active volume groups if vgdisplay -A is used.
Add -p and LVM_LVMETAD_PIDFILE env var to lvmetad to change pid file.
Allow lvmetad to reuse stale socket.
Only unlink lvmetad socket on error if created by the same process.
Append missing newline to lvmetad missing socket path error message.
Check for non-zero aligment in _text_pv_add_metadata_area() to not div by 0.
Add allocation/use_blkid_wiping to lvm.conf to enable blkid wiping.
Enable blkid_wiping by default if the blkid library is present.
Add configure --disable-blkid_wiping to disable libblkid signature detection.
Add -W/--wipesignatures lvcreate option to support wiping on new LVs.
Add allocation/wipe_signatures_when_zeroing_new_lvs to lvm.conf.
Do not fail the whole autoactivation if the VG refresh done before fails.
Do not connect to lvmetad on vg/lvchange --sysinit -aay and socket absent.
Use lv_check_not_in_use() when testing device in use before merging.
Move test for target present from init_snapshot_merge() to lvconvert.
Check for failure of lvmcache_add_mda() when writing pv.
Check for failure of dev_get_size() when reporting device size.
Drop extra unneeded '/' when scanning sysfs directory.
Fix undef value if skipped clustered VG ignored for toollib PV seg. (2.02.103)
Support validation of VG/LV names in liblvm/python.
Allow creation of PVs with arguments to liblvm/python.
Ensure sufficient metadata copies retained in liblvm/python vgreduce.
Fix installation of profiles from conf subdir when not building in srcdir.
Show UUIDs for missing PVs in reports.
Change dev_size/name, pv_fmt/mda_free/mda_size/uuid fields from pv to label.
Add struct device *dev to struct label.
Introduce process_each_label.
Change void *private to struct format_type *fmt in struct labeller.
Remove pv_read.
Add reporting of thin_id device id for thin volumes.
Fix reporting of empty numerical values for recently-added fields.
Use _field_set_percent/value in reporting code.
Version 2.02.104 - 13th November 2013
=====================================
Workaround VG refresh race during autoactivation by retrying the refresh.
Handle failures in temporary mirror used when adding images to mirrors.
Fix and improve logic for implicitely exclusive activations.
Return success when LV cannot be activated because of volume_list filter.
Return proper error state for remote exclusive activation.
Fix missing lvmetad scan for PVs found on MD partitions.
Respect DM_UDEV_DISABLE_OTHER_RULES_FLAG in lvmetad udev rules.
Fix clvmd message verification to not reject REMOTE flag. (2.02.100)
Compare equality of double values with DBL_EPSILON predefined constant.
Use additional gcc warning flags by default.
Add ignore_lvm_mirrors to config file to read/ignore labels on mirrors.
Add internal flag for temporary LVs to properly direct udev to not interfere.
Fix endless loop in blkdeactivate <device>... if unable to umount/deactivate.
Add dev-block-<major>:<minor>.device systemd alias for complete PV tracking.
Use major:minor as short form of --major and --minor arg for pvscan --cache.
Remove 2>/dev/null from three lvm commands executed by vgimportclone.
Add configure --enable-udev-systemd-background-jobs.
Add lvm2-pvscan@.service to run pvscan as a service for lvmetad/autoactivation.
Use #ifdef __linux__ instead of linux throughout.
Fix lvconvert swap of poolmetadata volume for active thin pool.
Check for open count with a timeout before removal/deactivation of an LV.
Report RAID images split with tracking as out-of-sync ("I").
Improve parsing of snapshot lv segment.
Add workaround for deactivation problem of opened virtual snapshot.
Disable unsupported merge for virtual snapshot.
Move code to remove virtual snapshot from tools to lib for lvm2app.
Fix possible race during daemon worker thread creation (lvmetad).
Fix possible deadlock while clearing lvmetad cache for full rescan.
Recognise NVM Express devices in filter.
Fix failing metadata repair when lvmetad is used.
Fix incorrect memory handling when reading messages from lvmetad.
Fix locking in lvmetad when handling the PV which is gone.
Recognize new flag to skip udev scanning in udev rules and act appropriately.
Add support for flagging an LV to skip udev scanning during activation.
Improve message when unable to change discards setting on active thin pool.
Run full scan before vgrename operation to avoid any cache name collision.
Fix lvconvert when converting to a thin pool and thin LV at once. (2.02.99)
Version 2.02.103 - 4th October 2013
===================================
Ensure vgid matches before removing vgname entry from lvmetad cache.
Add --ignoreskippedcluster for exit status success when clustered VGs skipped.
Fix 3 minute udev timeout so that it is applied for all LVM volumes.
Fix thin/raid & activation config defaults with configure --disable-devmapper.
Fix RAID calculation for sufficient allocatable space.
lvconvert from linear to mirror or RAID1 now honors mirror_segtype_default.
Add thin-performance configuration profile.
Add lvm.conf allocation/thin_pool_chunk_size_policy option.
Fix contiguous & cling allocation policies for parity RAID. (2.02.100)
Have lvmconf --enable/disable-cluster reset/set use_lvmetad.
Don't install separate command symlink for 'lvm devtypes'. (2.02.101)
Add seg_size_pe field to reports.
Support start+length notation with command line PE ranges.
Exit cleanly with message when pvmove cannot restart because LV is inactive.
Version 2.02.102 - 23rd September 2013
======================================
Fix missing build dependency for scripts subdir in Makefile.
Extend lv_info() for more efficient lv_is_active_locally() check.
Fix node up/down handling in clvmd corosync module.
Version 2.02.101 - 20th September 2013
======================================
Fix 3-thread clvmd deadlock triggered by cleanup on EOF from client.
Remove VG from lvmetad before restoring it with vgcfgrestore.
Use strtoull instead of strtol in _get_int_arg.
Add devtypes report command to display built-in recognised block device types.
Fix CC Makefile override which had reverted to using built-in value. (2.02.75)
Recognise bcache block devices in filter (experimental).
Run lvm2-activation-net after lvm2-activation service to prevent parallel run.
Add man page entries for lvmdump's -u and -l options.
Fix lvm2app segfault while using lvm_list_pvs_free fn if there are no PVs.
Improve of clvmd singlenode locking simulation.
lvconvert no longer converts LVs of "mirror" segment type to thinpool.
lvconvert no longer converts thinpool sub-LVs to "mirror" segment type.
Direct udev to use 3min timeout for LVM devices. Recent udev has default 30s.
Do not scan multipath or RAID components and avoid incorrect autoactivation.
Fix MD/loop udev handling to fire autoactivation after setup or coldplug only.
Make RAID capable of single-machine exclusive operations in a cluster.
Drop calculation of read ahead for deactivated volume.
Check for exactly one lv segment in validation of thin pools and volumes.
Fix dmeventd unmonitoring of thin pools.
Fix lvresize for stacked thin pool volumes (i.e. mirrors).
Write Completed debug message before reinstating log defaults after command.
Refresh existing VG before autoactivation (event retrigger/device reappeared).
Use pvscan -b in udev rules to avoid a deadlock on udev process count limit.
Add pvscan -b/--background for the command to be processed in the background.
Don't assume stdin file descriptor is readable.
Avoid unlimited recursion when creating dtree containing inactive pvmove LV.
Require exactly 3 arguments for lvm2-activation-generator. Remove defaults.
Inform lvmetad about any lost PV label to make it in sync with system state.
Support most of lvchange operations on stacked thin pool meta/data LVs.
Enable non-clustered pvmove of snapshots and snapshot origins.
Add ability to pvmove non-clustered RAID, mirror, and thin volumes.
Make lvm2-activation-generator silent unless it's in error state.
Remove "mpath major is not dm major" msg for mpath component scan (2.02.94).
Prevent cluster mirror logs from being corrupted by redundant checkpoints.
Fix ignored lvmetad update on loop device configuration (2.02.99).
Use LVM_PATH instead of hardcoded value in lvm2 activation systemd generator.
Fix vgck to notice on-disk corruption even if lvmetad is used.
Move mpath device filter before partitioned filter (which opens devices).
Split partitioned filter out of lvm_type filter.
Merge filter*.h into a single filter.h.
Require confirmation for vgchange -c when no VGs listed explicitly.
Also skip /var and /var/log by default in blkdeactivate when unmounting.
Add support for bind mounts in blkdeactivate.
Add blkdeactivate -v/--verbose for debug output from external tools used.
Add blkdeactivate -e/--errors for error messages from external tools used.
Suppress messages from external tools called in blkdeactivate by default.
Version 2.02.100 - 13th August 2013
===================================
Fix inability to remove a VG's cluster flag if it contains a mirror.

View File

@ -1,3 +1,111 @@
Version 1.02.91 -
====================================
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.
Recognize implicit "selected" field if using dm_report_init_with_selection.
Add support for implicit reporting fields which are predefined in libdm.
Add DM_REPORT_FIELD_TYPE_PERCENT: separate number and percent fields.
Add dm_percent_range_t,dm_percent_to_float,dm_make_percent to libdm for reuse.
Add dm_report_reserved_value to libdevmapper for reserved value definition.
Also display field types when listing all fields in selection help.
Recognize "help" keyword in selection string to show brief help for selection.
Always order items reported as string list field lexicographically.
Add dm_report_field_string_list to libdevmapper for direct string list report.
Add DM_REPORT_FIELD_TYPE_STRING_LIST: separate string and string list fields.
Add dm_str_list to libdevmapper for string list type definition and its reuse.
Add dmsetup -S/--select to define selection criteria for dmsetup reports.
Add dm_report_init_with_selection to intialize report with selection criteria.
Add DM_REPORT_FIELD_TYPE_SIZE: separate number and size reporting fields.
Use RemoveOnStop for dm-event.socket systemd unit.
Document env var 'DM_DEFAULT_NAME_MANGLING_MODE' in dmsetup man page.
Warn user about incorrect use of cookie with 'dmsetup remove --force'.
Also recognize 'help'/'?' as reserved sort key name to show help.
Add dm_units_to_factor for size unit parsing.
Increase bitset size for minors for thin dmeventd plugin.
Version 1.02.85 - 10th April 2014
=================================
Check for sprintf error when building internal device path.
Check for sprintf error when creating path for dm control node.
When buffer for dm_get_library_version() is too small, return error code.
Always reinitialize _name_mangling_mode in dm_lib_init().
Add tracking flag about implicitly added devices into dm_tree.
Stop timeout thread immediately when the last worker thread is finished.
Fix dmeventd logging with parallel wait event processing.
Reuse _node_send_messages() for validation of transaction_id in preload.
Transaction_id could be lower by one only when messages are prepared.
Do not call callback when preload fails.
Wrap is_selinux_enabled() to be called just once.
Use correctly signed 64b constant when working with raid volumes.
Exit dmeventd with pidfile cleanup instead of raising SIGKILL on DIE request.
Add new DM_EVENT_GET_PARAMETERS request to dmeventd protocol.
Do not use systemd's reload for dmeventd restart, use dmeventd -R instead.
Drop cryptsetup rules from 10-dm.rules - cryptsetup >= 1.1.3 sets them.
Version 1.02.84 - 20th January 2014
===================================
Revert activation of activated nodes if a node preload callback fails.
Avoid busy looping on CPU when dmeventd reads event DM_WAIT_RETRY.
Ensure global mutex is held when working with dmeventd thread.
Drop taking timeout mutex for un/registering dmeventd monitor.
Allow section names in config file data to be quoted strings.
Close fifos before exiting in dmeventd restart() error path.
Move printf format string directly into dm_asprintf args list.
Catch invalid use of string sort values when reporting numerical fields.
Version 1.02.83 - 13th November 2013
====================================
Consistently report on stderr when device is not found for dmsetup info.
Skip race errors when non-udev dmsetup build runs on udev-enabled system.
Skip error message when holders are not present in sysfs.
Use __linux__ instead of linux define to make libdevmapper.h C compliant.
Use mutex to avoid possible race while creating/destroying memory pools.
Require libpthread to build now.
Version 1.02.82 - 4th October 2013
==================================
Define symbolic names for subsystem udev flags in libdevmapper for easier use.
Make subsystem udev rules responsible for importing DM_SUBSYSTEM_UDEV_FLAG*.
Version 1.02.81 - 23rd September 2013
=====================================
Tidy dmeventd fifo initialisation.
Version 1.02.80 - 20th September 2013
=====================================
Detect invalid sector supplied to 'dmsetup message'.
Free any previously-set string if a dm_task_set_* function is called again.
Do not allow passing empty new name for dmsetup rename.
Display any output returned by 'dmsetup message'.
Add dm_task_get_message_response to libdevmapper.
Version 1.02.79 - 13th August 2013
==================================
Create dmeventd timeout threads as "detached" so exit status is freed.

59
acinclude.m4 Normal file
View File

@ -0,0 +1,59 @@
dnl AC_GCC_VERSION
dnl check for compiler version
dnl sets COMPILER_VERSION and GCC_VERSION
AC_DEFUN([AC_CC_VERSION],
[
AC_MSG_CHECKING([C compiler version])
COMPILER_VERSION=`$CC -v 2>&1 | grep version`
case "$COMPILER_VERSION" in
*gcc*)
dnl Ok, how to turn $3 into the real $3
GCC_VERSION=`echo $COMPILER_VERSION | \
sed -e 's/[[^ ]]*\ [[^ ]]*\ \([[^ ]]*\)\ .*/\1/'` ;;
*) GCC_VERSION=unknown ;;
esac
AC_MSG_RESULT($GCC_VERSION)
])
dnl AC_TRY_CCFLAG([CCFLAG], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
dnl check if $CC supports a given flag
AC_DEFUN([AC_TRY_CCFLAG],
[
AC_REQUIRE([AC_PROG_CC])
ac_save_CFLAGS=$CFLAGS
CFLAGS=$1
AC_CACHE_CHECK([whether $CC accepts $1 flag], [ac_cv_flag_$2],
[AC_COMPILE_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET([ac_cv_flag_$2], [yes])],
[AS_VAR_SET([ac_cv_flag_$2], [no])])])
CFLAGS=$ac_save_CFLAGS
$2=AS_VAR_GET([ac_cv_flag_$2])
if test "$2" = yes; then
ifelse([$3], [], [:], [$3])
else
ifelse([$4], [], [:], [$4])
fi
])
dnl AC_TRY_LDFLAGS([LDFLAGS], [VAR], [ACTION-IF-WORKS], [ACTION-IF-FAILS])
dnl check if $CC supports given ld flags
AC_DEFUN([AC_TRY_LDFLAGS],
[
AC_REQUIRE([AC_PROG_CC])
ac_save_LDFLAGS=$LDFLAGS
LDFLAGS=$1
AC_CACHE_CHECK([whether $CC accepts $1 ld flags], [ac_cv_flag_$2],
[AC_LINK_IFELSE([AC_LANG_PROGRAM()],
[AS_VAR_SET([ac_cv_flag_$2], [yes])],
[AS_VAR_SET([ac_cv_flag_$2], [no])])])
LDFLAGS=$ac_save_LDFLAGS
$2=AS_VAR_GET([ac_cv_flag_$2])
if test "$2" = yes; then
ifelse([$3], [], [:], [$3])
else
ifelse([$4], [], [:], [$4])
fi
])

77
aclocal.m4 vendored
View File

@ -1,7 +1,7 @@
# generated automatically by aclocal 1.11.1 -*- Autoconf -*-
# generated automatically by aclocal 1.13.4 -*- Autoconf -*-
# Copyright (C) 1996-2013 Free Software Foundation, Inc.
# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
# 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
# This file is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
@ -11,6 +11,7 @@
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])])
# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*-
# serial 1 (pkg-config-0.24)
#
@ -39,7 +40,8 @@
# ----------------------------------
AC_DEFUN([PKG_PROG_PKG_CONFIG],
[m4_pattern_forbid([^_?PKG_[A-Z_]+$])
m4_pattern_allow([^PKG_CONFIG(_PATH)?$])
m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$])
m4_pattern_allow([^PKG_CONFIG_(DISABLE_UNINSTALLED|TOP_BUILD_DIR|DEBUG_SPEW)$])
AC_ARG_VAR([PKG_CONFIG], [path to pkg-config utility])
AC_ARG_VAR([PKG_CONFIG_PATH], [directories to add to pkg-config's search path])
AC_ARG_VAR([PKG_CONFIG_LIBDIR], [path overriding pkg-config's built-in search path])
@ -85,7 +87,8 @@ m4_define([_PKG_CONFIG],
pkg_cv_[]$1="$$1"
elif test -n "$PKG_CONFIG"; then
PKG_CHECK_EXISTS([$3],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`],
[pkg_cv_[]$1=`$PKG_CONFIG --[]$2 "$3" 2>/dev/null`
test "x$?" != "x0" && pkg_failed=yes ],
[pkg_failed=yes])
else
pkg_failed=untried
@ -133,9 +136,9 @@ if test $pkg_failed = yes; then
AC_MSG_RESULT([no])
_PKG_SHORT_ERRORS_SUPPORTED
if test $_pkg_short_errors_supported = yes; then
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1`
else
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors "$2" 2>&1`
$1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1`
fi
# Put the nasty error message in config.log where it belongs
echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD
@ -148,7 +151,7 @@ $$1_PKG_ERRORS
Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.
_PKG_TEXT])
_PKG_TEXT])[]dnl
])
elif test $pkg_failed = untried; then
AC_MSG_RESULT([no])
@ -159,7 +162,7 @@ path to pkg-config.
_PKG_TEXT
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])
To get pkg-config, see <http://pkg-config.freedesktop.org/>.])[]dnl
])
else
$1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS
@ -169,3 +172,59 @@ else
fi[]dnl
])# PKG_CHECK_MODULES
# PKG_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable pkgconfigdir as the location where a module
# should install pkg-config .pc files. By default the directory is
# $libdir/pkgconfig, but the default can be changed by passing
# DIRECTORY. The user can override through the --with-pkgconfigdir
# parameter.
AC_DEFUN([PKG_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${libdir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([pkgconfigdir],
[AS_HELP_STRING([--with-pkgconfigdir], pkg_description)],,
[with_pkgconfigdir=]pkg_default)
AC_SUBST([pkgconfigdir], [$with_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_INSTALLDIR
# PKG_NOARCH_INSTALLDIR(DIRECTORY)
# -------------------------
# Substitutes the variable noarch_pkgconfigdir as the location where a
# module should install arch-independent pkg-config .pc files. By
# default the directory is $datadir/pkgconfig, but the default can be
# changed by passing DIRECTORY. The user can override through the
# --with-noarch-pkgconfigdir parameter.
AC_DEFUN([PKG_NOARCH_INSTALLDIR],
[m4_pushdef([pkg_default], [m4_default([$1], ['${datadir}/pkgconfig'])])
m4_pushdef([pkg_description],
[pkg-config arch-independent installation directory @<:@]pkg_default[@:>@])
AC_ARG_WITH([noarch-pkgconfigdir],
[AS_HELP_STRING([--with-noarch-pkgconfigdir], pkg_description)],,
[with_noarch_pkgconfigdir=]pkg_default)
AC_SUBST([noarch_pkgconfigdir], [$with_noarch_pkgconfigdir])
m4_popdef([pkg_default])
m4_popdef([pkg_description])
]) dnl PKG_NOARCH_INSTALLDIR
# PKG_CHECK_VAR(VARIABLE, MODULE, CONFIG-VARIABLE,
# [ACTION-IF-FOUND], [ACTION-IF-NOT-FOUND])
# -------------------------------------------
# Retrieves the value of the pkg-config variable for the given module.
AC_DEFUN([PKG_CHECK_VAR],
[AC_REQUIRE([PKG_PROG_PKG_CONFIG])dnl
AC_ARG_VAR([$1], [value of $3 for $2, overriding pkg-config])dnl
_PKG_CONFIG([$1], [variable="][$3]["], [$2])
AS_VAR_COPY([$1], [pkg_cv_][$1])
AS_VAR_IF([$1], [""], [$5], [$4])dnl
])# PKG_CHECK_VAR
m4_include([acinclude.m4])

415
autoconf/config.guess vendored
View File

@ -1,14 +1,12 @@
#! /bin/sh
# Attempt to guess a canonical system name.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
# Copyright 1992-2014 Free Software Foundation, Inc.
timestamp='2009-11-20'
timestamp='2014-01-01'
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
@ -17,26 +15,22 @@ timestamp='2009-11-20'
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# Originally written by Per Bothner. Please send patches (context
# diff format) to <config-patches@gnu.org> and include a ChangeLog
# entry.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
#
# This script attempts to guess a canonical system name similar to
# config.sub. If it succeeds, it prints the system name on stdout, and
# exits with 0. Otherwise, it exits with 1.
# Originally written by Per Bothner.
#
# You can get the latest version of this script from:
# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
#
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
me=`echo "$0" | sed -e 's,.*/,,'`
@ -56,8 +50,7 @@ version="\
GNU config.guess ($timestamp)
Originally written by Per Bothner.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright 1992-2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -139,12 +132,33 @@ UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
case "${UNAME_SYSTEM}" in
Linux|GNU|GNU/*)
# If the system lacks a compiler, then just pick glibc.
# We could probably try harder.
LIBC=gnu
eval $set_cc_for_build
cat <<-EOF > $dummy.c
#include <features.h>
#if defined(__UCLIBC__)
LIBC=uclibc
#elif defined(__dietlibc__)
LIBC=dietlibc
#else
LIBC=gnu
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
;;
esac
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:NetBSD:*:*)
# NetBSD (nbsd) targets should (where applicable) match one or
# more of the tupples: *-*-netbsdelf*, *-*-netbsdaout*,
# more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
# *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
# switched to ELF, *-*-netbsd* would select the old
# object file format. This provides both forward
@ -180,7 +194,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
fi
;;
*)
os=netbsd
os=netbsd
;;
esac
# The OS release
@ -201,6 +215,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
echo "${machine}-${os}${release}"
exit ;;
*:Bitrig:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
exit ;;
*:OpenBSD:*:*)
UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
@ -223,7 +241,7 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
;;
*5.*)
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
;;
esac
# According to Compaq, /usr/sbin/psrinfo has been available on
@ -269,7 +287,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
exit ;;
# Reset EXIT trap before exiting to avoid spurious non-zero exit code.
exitcode=$?
trap '' 0
exit $exitcode ;;
Alpha\ *:Windows_NT*:*)
# How do we know it's Interix rather than the generic POSIX subsystem?
# Should we change UNAME_MACHINE based on the output of uname instead
@ -295,12 +316,12 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo s390-ibm-zvmoe
exit ;;
*:OS400:*:*)
echo powerpc-ibm-os400
echo powerpc-ibm-os400
exit ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
exit ;;
arm:riscos:*:*|arm:RISCOS:*:*)
arm*:riscos:*:*|arm*:RISCOS:*:*)
echo arm-unknown-riscos
exit ;;
SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
@ -394,23 +415,23 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
# MiNT. But MiNT is downward compatible to TOS, so this should
# be no problem.
atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
exit ;;
*falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
echo m68k-atari-mint${UNAME_RELEASE}
echo m68k-atari-mint${UNAME_RELEASE}
exit ;;
milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
echo m68k-milan-mint${UNAME_RELEASE}
exit ;;
hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
echo m68k-hades-mint${UNAME_RELEASE}
exit ;;
*:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
echo m68k-unknown-mint${UNAME_RELEASE}
exit ;;
m68k:machten:*:*)
echo m68k-apple-machten${UNAME_RELEASE}
exit ;;
@ -480,8 +501,8 @@ EOF
echo m88k-motorola-sysv3
exit ;;
AViiON:dgux:*:*)
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
# DG/UX returns AViiON for all architectures
UNAME_PROCESSOR=`/usr/bin/uname -p`
if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
@ -494,7 +515,7 @@ EOF
else
echo i586-dg-dgux${UNAME_RELEASE}
fi
exit ;;
exit ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
exit ;;
@ -551,7 +572,7 @@ EOF
echo rs6000-ibm-aix3.2
fi
exit ;;
*:AIX:*:[456])
*:AIX:*:[4567])
IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
IBM_ARCH=rs6000
@ -594,52 +615,52 @@ EOF
9000/[678][0-9][0-9])
if [ -x /usr/bin/getconf ]; then
sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
case "${sc_cpu_version}" in
523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
532) # CPU_PA_RISC2_0
case "${sc_kernel_bits}" in
32) HP_ARCH="hppa2.0n" ;;
64) HP_ARCH="hppa2.0w" ;;
'') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
esac ;;
esac
esac ;;
esac
fi
if [ "${HP_ARCH}" = "" ]; then
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
sed 's/^ //' << EOF >$dummy.c
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
#define _HPUX_SOURCE
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
test -z "$HP_ARCH" && HP_ARCH=hppa
@ -730,22 +751,22 @@ EOF
exit ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit ;;
exit ;;
C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
if getsysinfo -f scalar_acc
then echo c32-convex-bsd
else echo c2-convex-bsd
fi
exit ;;
exit ;;
C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
echo c34-convex-bsd
exit ;;
exit ;;
C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
echo c38-convex-bsd
exit ;;
exit ;;
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit ;;
exit ;;
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
exit ;;
@ -769,14 +790,14 @@ EOF
exit ;;
F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
5000:UNIX_System_V:4.*:*)
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit ;;
i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
@ -788,30 +809,35 @@ EOF
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit ;;
*:FreeBSD:*:*)
case ${UNAME_MACHINE} in
pc98)
echo i386-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
UNAME_PROCESSOR=`/usr/bin/uname -p`
case ${UNAME_PROCESSOR} in
amd64)
echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
esac
exit ;;
i*:CYGWIN*:*)
echo ${UNAME_MACHINE}-pc-cygwin
exit ;;
*:MINGW64*:*)
echo ${UNAME_MACHINE}-pc-mingw64
exit ;;
*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit ;;
i*:MSYS*:*)
echo ${UNAME_MACHINE}-pc-msys
exit ;;
i*:windows32*:*)
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
# uname -m includes "-pc" on this system.
echo ${UNAME_MACHINE}-mingw32
exit ;;
i*:PW*:*)
echo ${UNAME_MACHINE}-pc-pw32
exit ;;
*:Interix*:*)
case ${UNAME_MACHINE} in
case ${UNAME_MACHINE} in
x86)
echo i586-pc-interix${UNAME_RELEASE}
exit ;;
@ -848,15 +874,22 @@ EOF
exit ;;
*:GNU:*:*)
# the GNU system
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit ;;
*:GNU/*:*:*)
# other systems with GNU libc and userland
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-gnu
echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
exit ;;
i*86:Minix:*:*)
echo ${UNAME_MACHINE}-pc-minix
exit ;;
aarch64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
aarch64_be:Linux:*:*)
UNAME_MACHINE=aarch64_be
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
alpha:Linux:*:*)
case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
EV5) UNAME_MACHINE=alphaev5 ;;
@ -866,52 +899,56 @@ EOF
EV6) UNAME_MACHINE=alphaev6 ;;
EV67) UNAME_MACHINE=alphaev67 ;;
EV68*) UNAME_MACHINE=alphaev68 ;;
esac
esac
objdump --private-headers /bin/sh | grep -q ld.so.1
if test "$?" = 0 ; then LIBC="libc1" ; else LIBC="" ; fi
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC}
if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arc:Linux:*:* | arceb:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
arm*:Linux:*:*)
eval $set_cc_for_build
if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_EABI__
then
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
else
echo ${UNAME_MACHINE}-unknown-linux-gnueabi
if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
| grep -q __ARM_PCS_VFP
then
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
else
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
fi
fi
exit ;;
avr32*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
cris:Linux:*:*)
echo cris-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
crisv32:Linux:*:*)
echo crisv32-axis-linux-gnu
echo ${UNAME_MACHINE}-axis-linux-${LIBC}
exit ;;
frv:Linux:*:*)
echo frv-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
hexagon:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:Linux:*:*)
LIBC=gnu
eval $set_cc_for_build
sed 's/^ //' << EOF >$dummy.c
#ifdef __dietlibc__
LIBC=dietlibc
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC'`
echo "${UNAME_MACHINE}-pc-linux-${LIBC}"
echo ${UNAME_MACHINE}-pc-linux-${LIBC}
exit ;;
ia64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m32r*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
m68*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
mips:Linux:*:* | mips64:Linux:*:*)
eval $set_cc_for_build
@ -930,51 +967,63 @@ EOF
#endif
EOF
eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-gnu"; exit; }
test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
;;
or1k:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
or32:Linux:*:*)
echo or32-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
padre:Linux:*:*)
echo sparc-unknown-linux-gnu
echo sparc-unknown-linux-${LIBC}
exit ;;
parisc64:Linux:*:* | hppa64:Linux:*:*)
echo hppa64-unknown-linux-gnu
echo hppa64-unknown-linux-${LIBC}
exit ;;
parisc:Linux:*:* | hppa:Linux:*:*)
# Look for CPU level
case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
PA7*) echo hppa1.1-unknown-linux-gnu ;;
PA8*) echo hppa2.0-unknown-linux-gnu ;;
*) echo hppa-unknown-linux-gnu ;;
PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
*) echo hppa-unknown-linux-${LIBC} ;;
esac
exit ;;
ppc64:Linux:*:*)
echo powerpc64-unknown-linux-gnu
echo powerpc64-unknown-linux-${LIBC}
exit ;;
ppc:Linux:*:*)
echo powerpc-unknown-linux-gnu
echo powerpc-unknown-linux-${LIBC}
exit ;;
ppc64le:Linux:*:*)
echo powerpc64le-unknown-linux-${LIBC}
exit ;;
ppcle:Linux:*:*)
echo powerpcle-unknown-linux-${LIBC}
exit ;;
s390:Linux:*:* | s390x:Linux:*:*)
echo ${UNAME_MACHINE}-ibm-linux
echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
exit ;;
sh64*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sh*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
sparc:Linux:*:* | sparc64:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
tile*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
vax:Linux:*:*)
echo ${UNAME_MACHINE}-dec-linux-gnu
echo ${UNAME_MACHINE}-dec-linux-${LIBC}
exit ;;
x86_64:Linux:*:*)
echo x86_64-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
xtensa*:Linux:*:*)
echo ${UNAME_MACHINE}-unknown-linux-gnu
echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
exit ;;
i*86:DYNIX/ptx:4*:*)
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
@ -983,11 +1032,11 @@ EOF
echo i386-sequent-sysv4
exit ;;
i*86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit ;;
i*86:OS/2:*:*)
@ -1019,7 +1068,7 @@ EOF
fi
exit ;;
i*86:*:5:[678]*)
# UnixWare 7.x, OpenUNIX and OpenServer 6.
# UnixWare 7.x, OpenUNIX and OpenServer 6.
case `/bin/uname -X | grep "^Machine"` in
*486*) UNAME_MACHINE=i486 ;;
*Pentium) UNAME_MACHINE=i586 ;;
@ -1047,13 +1096,13 @@ EOF
exit ;;
pc:*:*:*)
# Left here for compatibility:
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i586.
# Note: whatever this is, it MUST be the same as what config.sub
# prints for the "djgpp" host, or else GDB configury will decide that
# this is a cross-build.
echo i586-pc-msdosdjgpp
exit ;;
exit ;;
Intel:Mach:3*:*)
echo i386-pc-mach3
exit ;;
@ -1088,8 +1137,8 @@ EOF
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& { echo i486-ncr-sysv4; exit; } ;;
NCR*:*:4.2:* | MPRAS*:*:4.2:*)
OS_REL='.3'
test -r /etc/.relid \
@ -1132,10 +1181,10 @@ EOF
echo ns32k-sni-sysv
fi
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
@ -1161,11 +1210,11 @@ EOF
exit ;;
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE}
echo mips-nec-sysv${UNAME_RELEASE}
else
echo mips-unknown-sysv${UNAME_RELEASE}
echo mips-unknown-sysv${UNAME_RELEASE}
fi
exit ;;
exit ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit ;;
@ -1178,6 +1227,9 @@ EOF
BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
echo i586-pc-haiku
exit ;;
x86_64:Haiku:*:*)
echo x86_64-unknown-haiku
exit ;;
SX-4:SUPER-UX:*:*)
echo sx4-nec-superux${UNAME_RELEASE}
exit ;;
@ -1204,19 +1256,31 @@ EOF
exit ;;
*:Darwin:*:*)
UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
case $UNAME_PROCESSOR in
i386)
eval $set_cc_for_build
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
UNAME_PROCESSOR="x86_64"
fi
fi ;;
unknown) UNAME_PROCESSOR=powerpc ;;
esac
eval $set_cc_for_build
if test "$UNAME_PROCESSOR" = unknown ; then
UNAME_PROCESSOR=powerpc
fi
if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
(CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
grep IS_64BIT_ARCH >/dev/null
then
case $UNAME_PROCESSOR in
i386) UNAME_PROCESSOR=x86_64 ;;
powerpc) UNAME_PROCESSOR=powerpc64 ;;
esac
fi
fi
elif test "$UNAME_PROCESSOR" = i386 ; then
# Avoid executing cc on OS X 10.9, as it ships with a stub
# that puts up a graphical alert prompting to install
# developer tools. Any system running Mac OS X 10.7 or
# later (Darwin 11 and later) is required to have a 64-bit
# processor. This is not true of the ARM version of Darwin
# that Apple uses in portable devices.
UNAME_PROCESSOR=x86_64
fi
echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
exit ;;
*:procnto*:*:* | *:QNX:[0123456789]*:*)
@ -1230,7 +1294,10 @@ EOF
*:QNX:*:4*)
echo i386-pc-qnx
exit ;;
NSE-?:NONSTOP_KERNEL:*:*)
NEO-?:NONSTOP_KERNEL:*:*)
echo neo-tandem-nsk${UNAME_RELEASE}
exit ;;
NSE-*:NONSTOP_KERNEL:*:*)
echo nse-tandem-nsk${UNAME_RELEASE}
exit ;;
NSR-?:NONSTOP_KERNEL:*:*)
@ -1275,13 +1342,13 @@ EOF
echo pdp10-unknown-its
exit ;;
SEI:*:*:SEIUX)
echo mips-sei-seiux${UNAME_RELEASE}
echo mips-sei-seiux${UNAME_RELEASE}
exit ;;
*:DragonFly:*:*)
echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit ;;
*:*VMS:*:*)
UNAME_MACHINE=`(uname -p) 2>/dev/null`
UNAME_MACHINE=`(uname -p) 2>/dev/null`
case "${UNAME_MACHINE}" in
A*) echo alpha-dec-vms ; exit ;;
I*) echo ia64-dec-vms ; exit ;;
@ -1299,11 +1366,11 @@ EOF
i*86:AROS:*:*)
echo ${UNAME_MACHINE}-pc-aros
exit ;;
x86_64:VMkernel:*:*)
echo ${UNAME_MACHINE}-unknown-esx
exit ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
eval $set_cc_for_build
cat >$dummy.c <<EOF
#ifdef _SEQUENT_
@ -1321,11 +1388,11 @@ main ()
#include <sys/param.h>
printf ("m68k-sony-newsos%s\n",
#ifdef NEWSOS4
"4"
"4"
#else
""
""
#endif
); exit (0);
); exit (0);
#endif
#endif

288
autoconf/config.sub vendored
View File

@ -1,38 +1,31 @@
#! /bin/sh
# Configuration validation subroutine script.
# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
# 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
# Free Software Foundation, Inc.
# Copyright 1992-2014 Free Software Foundation, Inc.
timestamp='2009-11-20'
timestamp='2014-01-01'
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
# 02110-1301, USA.
# along with this program; if not, see <http://www.gnu.org/licenses/>.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.
# the same distribution terms that you use for the rest of that
# program. This Exception is an additional permission under section 7
# of the GNU General Public License, version 3 ("GPLv3").
# Please send patches to <config-patches@gnu.org>. Submit a context
# diff and a properly formatted GNU ChangeLog entry.
# Please send patches with a ChangeLog entry to config-patches@gnu.org.
#
# Configuration subroutine to validate and canonicalize a configuration type.
# Supply the specified configuration type as an argument.
@ -75,8 +68,7 @@ Report bugs and patches to <config-patches@gnu.org>."
version="\
GNU config.sub ($timestamp)
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
2002, 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
Copyright 1992-2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
@ -123,13 +115,18 @@ esac
# Here we must recognize all the valid KERNEL-OS combinations.
maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
case $maybe_os in
nto-qnx* | linux-gnu* | linux-dietlibc | linux-newlib* | linux-uclibc* | \
uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | knetbsd*-gnu* | netbsd*-gnu* | \
nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
knetbsd*-gnu* | netbsd*-gnu* | \
kopensolaris*-gnu* | \
storm-chaos* | os2-emx* | rtmk-nova*)
os=-$maybe_os
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
;;
android-linux)
os=-linux-android
basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
;;
*)
basic_machine=`echo $1 | sed 's/-[^-]*$//'`
if [ $basic_machine != $1 ]
@ -152,12 +149,12 @@ case $os in
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
-harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
-apple | -axis | -knuth | -cray | -microblaze)
-apple | -axis | -knuth | -cray | -microblaze*)
os=
basic_machine=$1
;;
-bluegene*)
os=-cnk
-bluegene*)
os=-cnk
;;
-sim | -cisco | -oki | -wec | -winbond)
os=
@ -173,10 +170,10 @@ case $os in
os=-chorusos
basic_machine=$1
;;
-chorusrdb)
os=-chorusrdb
-chorusrdb)
os=-chorusrdb
basic_machine=$1
;;
;;
-hiux*)
os=-hiuxwe2
;;
@ -221,6 +218,12 @@ case $os in
-isc*)
basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*178)
os=-lynxos178
;;
-lynx*5)
os=-lynxos5
;;
-lynx*)
os=-lynxos
;;
@ -245,20 +248,28 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
1750a | 580 \
| a29k \
| aarch64 | aarch64_be \
| alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
| alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
| am33_2.0 \
| arc | arm | arm[bl]e | arme[lb] | armv[2345] | armv[345][lb] | avr | avr32 \
| arc | arceb \
| arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
| avr | avr32 \
| be32 | be64 \
| bfin \
| c4x | clipper \
| c4x | c8051 | clipper \
| d10v | d30v | dlx | dsp16xx \
| epiphany \
| fido | fr30 | frv \
| h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
| hexagon \
| i370 | i860 | i960 | ia64 \
| ip2k | iq2000 \
| k1om \
| le32 | le64 \
| lm32 \
| m32c | m32r | m32rle | m68000 | m68k | m88k \
| maxq | mb | microblaze | mcore | mep | metag \
| maxq | mb | microblaze | microblazeel | mcore | mep | metag \
| mips | mipsbe | mipseb | mipsel | mipsle \
| mips16 \
| mips64 | mips64el \
@ -276,34 +287,45 @@ case $basic_machine in
| mipsisa64r2 | mipsisa64r2el \
| mipsisa64sb1 | mipsisa64sb1el \
| mipsisa64sr71k | mipsisa64sr71kel \
| mipsr5900 | mipsr5900el \
| mipstx39 | mipstx39el \
| mn10200 | mn10300 \
| moxie \
| mt \
| msp430 \
| nios | nios2 \
| nds32 | nds32le | nds32be \
| nios | nios2 | nios2eb | nios2el \
| ns16k | ns32k \
| or32 \
| open8 \
| or1k | or32 \
| pdp10 | pdp11 | pj | pjl \
| powerpc | powerpc64 | powerpc64le | powerpcle | ppcbe \
| powerpc | powerpc64 | powerpc64le | powerpcle \
| pyramid \
| rx \
| rl78 | rx \
| score \
| sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
| sh64 | sh64le \
| sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
| sparcv8 | sparcv9 | sparcv9b | sparcv9v \
| spu | strongarm \
| tahoe | thumb | tic4x | tic80 | tron \
| spu \
| tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
| ubicom32 \
| v850 | v850e \
| v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
| we32k \
| x86 | xc16x | xscale | xscalee[bl] | xstormy16 | xtensa \
| x86 | xc16x | xstormy16 | xtensa \
| z8k | z80)
basic_machine=$basic_machine-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | picochip)
# Motorola 68HC11/12.
c54x)
basic_machine=tic54x-unknown
;;
c55x)
basic_machine=tic55x-unknown
;;
c6x)
basic_machine=tic6x-unknown
;;
m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
basic_machine=$basic_machine-unknown
os=-none
;;
@ -313,6 +335,21 @@ case $basic_machine in
basic_machine=mt-unknown
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;
xgate)
basic_machine=$basic_machine-unknown
os=-none
;;
xscaleeb)
basic_machine=armeb-unknown
;;
xscaleel)
basic_machine=armel-unknown
;;
# We use `pc' rather than `unknown'
# because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users.
@ -327,25 +364,31 @@ case $basic_machine in
# Recognize the basic CPU types with company name.
580-* \
| a29k-* \
| aarch64-* | aarch64_be-* \
| alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
| alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* \
| alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
| arm-* | armbe-* | armle-* | armeb-* | armv*-* \
| avr-* | avr32-* \
| be32-* | be64-* \
| bfin-* | bs2000-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* | c54x-* | c55x-* | c6x-* \
| clipper-* | craynv-* | cydra-* \
| c[123]* | c30-* | [cjt]90-* | c4x-* \
| c8051-* | clipper-* | craynv-* | cydra-* \
| d10v-* | d30v-* | dlx-* \
| elxsi-* \
| f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
| h8300-* | h8500-* \
| hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
| hexagon-* \
| i*86-* | i860-* | i960-* | ia64-* \
| ip2k-* | iq2000-* \
| k1om-* \
| le32-* | le64-* \
| lm32-* \
| m32c-* | m32r-* | m32rle-* \
| m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* | microblaze-* \
| m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
| microblaze-* | microblazeel-* \
| mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
| mips16-* \
| mips64-* | mips64el-* \
@ -363,29 +406,34 @@ case $basic_machine in
| mipsisa64r2-* | mipsisa64r2el-* \
| mipsisa64sb1-* | mipsisa64sb1el-* \
| mipsisa64sr71k-* | mipsisa64sr71kel-* \
| mipsr5900-* | mipsr5900el-* \
| mipstx39-* | mipstx39el-* \
| mmix-* \
| mt-* \
| msp430-* \
| nios-* | nios2-* \
| nds32-* | nds32le-* | nds32be-* \
| nios-* | nios2-* | nios2eb-* | nios2el-* \
| none-* | np1-* | ns16k-* | ns32k-* \
| open8-* \
| orion-* \
| pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* | ppcbe-* \
| powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
| pyramid-* \
| romp-* | rs6000-* | rx-* \
| rl78-* | romp-* | rs6000-* | rx-* \
| sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
| shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
| sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
| sparclite-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | strongarm-* | sv1-* | sx?-* \
| tahoe-* | thumb-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* | tile-* \
| sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx?-* \
| tahoe-* \
| tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
| tile*-* \
| tron-* \
| ubicom32-* \
| v850-* | v850e-* | vax-* \
| v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
| vax-* \
| we32k-* \
| x86-* | x86_64-* | xc16x-* | xps100-* | xscale-* | xscalee[bl]-* \
| x86-* | x86_64-* | xc16x-* | xps100-* \
| xstormy16-* | xtensa*-* \
| ymp-* \
| z8k-* | z80-*)
@ -410,7 +458,7 @@ case $basic_machine in
basic_machine=a29k-amd
os=-udi
;;
abacus)
abacus)
basic_machine=abacus-unknown
;;
adobe68k)
@ -480,11 +528,20 @@ case $basic_machine in
basic_machine=powerpc-ibm
os=-cnk
;;
c54x-*)
basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c55x-*)
basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c6x-*)
basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
c90)
basic_machine=c90-cray
os=-unicos
;;
cegcc)
cegcc)
basic_machine=arm-unknown
os=-cegcc
;;
@ -516,7 +573,7 @@ case $basic_machine in
basic_machine=craynv-cray
os=-unicosmp
;;
cr16)
cr16 | cr16-*)
basic_machine=cr16-unknown
os=-elf
;;
@ -674,7 +731,6 @@ case $basic_machine in
i370-ibm* | ibm*)
basic_machine=i370-ibm
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
i*86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
@ -732,11 +788,15 @@ case $basic_machine in
basic_machine=ns32k-utek
os=-sysv
;;
microblaze)
microblaze*)
basic_machine=microblaze-xilinx
;;
mingw64)
basic_machine=x86_64-pc
os=-mingw64
;;
mingw32)
basic_machine=i386-pc
basic_machine=i686-pc
os=-mingw32
;;
mingw32ce)
@ -771,10 +831,18 @@ case $basic_machine in
ms1-*)
basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
;;
msys)
basic_machine=i686-pc
os=-msys
;;
mvs)
basic_machine=i370-ibm
os=-mvs
;;
nacl)
basic_machine=le32-unknown
os=-nacl
;;
ncr3000)
basic_machine=i486-ncr
os=-sysv4
@ -839,6 +907,12 @@ case $basic_machine in
np1)
basic_machine=np1-gould
;;
neo-tandem)
basic_machine=neo-tandem
;;
nse-tandem)
basic_machine=nse-tandem
;;
nsr-tandem)
basic_machine=nsr-tandem
;;
@ -921,9 +995,10 @@ case $basic_machine in
;;
power) basic_machine=power-ibm
;;
ppc) basic_machine=powerpc-unknown
ppc | ppcbe) basic_machine=powerpc-unknown
;;
ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
ppc-* | ppcbe-*)
basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
ppcle | powerpclittle | ppc-le | powerpc-little)
basic_machine=powerpcle-unknown
@ -948,7 +1023,11 @@ case $basic_machine in
basic_machine=i586-unknown
os=-pw32
;;
rdos)
rdos | rdos64)
basic_machine=x86_64-pc
os=-rdos
;;
rdos32)
basic_machine=i386-pc
os=-rdos
;;
@ -1017,6 +1096,9 @@ case $basic_machine in
basic_machine=i860-stratus
os=-sysv4
;;
strongarm-* | thumb-*)
basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
;;
sun2)
basic_machine=m68000-sun
;;
@ -1073,20 +1155,8 @@ case $basic_machine in
basic_machine=t90-cray
os=-unicos
;;
tic54x | c54x*)
basic_machine=tic54x-unknown
os=-coff
;;
tic55x | c55x*)
basic_machine=tic55x-unknown
os=-coff
;;
tic6x | c6x*)
basic_machine=tic6x-unknown
os=-coff
;;
tile*)
basic_machine=tile-unknown
basic_machine=$basic_machine-unknown
os=-linux-gnu
;;
tx39)
@ -1156,6 +1226,9 @@ case $basic_machine in
xps | xps100)
basic_machine=xps100-honeywell
;;
xscale-* | xscalee[bl]-*)
basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
;;
ymp)
basic_machine=ymp-cray
os=-unicos
@ -1253,11 +1326,11 @@ esac
if [ x"$os" != x"" ]
then
case $os in
# First match some system type aliases
# that might get confused with valid system types.
# First match some system type aliases
# that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-auroraux)
os=-auroraux
-auroraux)
os=-auroraux
;;
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@ -1281,20 +1354,21 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
| -sym* | -kopensolaris* \
| -sym* | -kopensolaris* | -plan9* \
| -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -aos* | -aros* \
| -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
| -openbsd* | -solidbsd* \
| -bitrig* | -openbsd* | -solidbsd* \
| -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
| -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -chorusos* | -chorusrdb* | -cegcc* \
| -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -linux-gnu* | -linux-newlib* | -linux-uclibc* \
| -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
| -linux-newlib* | -linux-musl* | -linux-uclibc* \
| -uxpv* | -beos* | -mpeix* | -udk* \
| -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
| -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
@ -1341,7 +1415,7 @@ case $os in
-opened*)
os=-openedition
;;
-os400*)
-os400*)
os=-os400
;;
-wince*)
@ -1390,7 +1464,7 @@ case $os in
-sinix*)
os=-sysv4
;;
-tpf*)
-tpf*)
os=-tpf
;;
-triton*)
@ -1426,15 +1500,14 @@ case $os in
-aros*)
os=-aros
;;
-kaos*)
os=-kaos
;;
-zvmoe)
os=-zvmoe
;;
-dicos*)
os=-dicos
;;
-nacl*)
;;
-none)
;;
*)
@ -1457,10 +1530,10 @@ else
# system, and we'll never get to this point.
case $basic_machine in
score-*)
score-*)
os=-elf
;;
spu-*)
spu-*)
os=-elf
;;
*-acorn)
@ -1472,8 +1545,23 @@ case $basic_machine in
arm*-semi)
os=-aout
;;
c4x-* | tic4x-*)
os=-coff
c4x-* | tic4x-*)
os=-coff
;;
c8051-*)
os=-elf
;;
hexagon-*)
os=-elf
;;
tic54x-*)
os=-coff
;;
tic55x-*)
os=-coff
;;
tic6x-*)
os=-coff
;;
# This must come before the *-dec entry.
pdp10-*)
@ -1493,14 +1581,11 @@ case $basic_machine in
;;
m68000-sun)
os=-sunos3
# This also exists in the configure program, but was not the
# default.
# os=-sunos4
;;
m68*-cisco)
os=-aout
;;
mep-*)
mep-*)
os=-elf
;;
mips*-cisco)
@ -1509,6 +1594,9 @@ case $basic_machine in
mips*-*)
os=-elf
;;
or1k-*)
os=-elf
;;
or32-*)
os=-coff
;;
@ -1527,7 +1615,7 @@ case $basic_machine in
*-ibm)
os=-aix
;;
*-knuth)
*-knuth)
os=-mmixware
;;
*-wec)

View File

@ -18,8 +18,8 @@ top_builddir = @top_builddir@
CONFSRC=example.conf
CONFDEST=lvm.conf
DEFAULT_PROFILE=default.profile
PROFILES=$(DEFAULT_PROFILE)
PROFILE_TEMPLATES=command_profile_template.profile metadata_profile_template.profile
PROFILES=$(PROFILE_TEMPLATES) $(srcdir)/thin-generic.profile $(srcdir)/thin-performance.profile
include $(top_builddir)/make.tmpl
@ -37,4 +37,4 @@ install_lvm2: install_conf install_profiles
install: install_lvm2
DISTCLEAN_TARGETS += $(CONFSRC) $(DEFAULT_PROFILE)
DISTCLEAN_TARGETS += $(CONFSRC) $(PROFILE_TEMPLATES)

View File

@ -0,0 +1,48 @@
# This is a command profile template for the LVM2 system.
#
# It contains all configuration settings that are customizable by command
# profiles. To create a new command profile, select the settings you want
# to customize and add them in a new file named <profile_name>.profile.
# Then install the new profile in a directory as defined by config/profile_dir
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Command profiles can be referenced by using the --commandprofile option then.
#
# Refer to 'man lvm.conf' for further information about profiles and
# general configuration file layout.
#
global {
units="h"
si_unit_consistency=1
suffix=1
lvdisplay_shows_full_device_path=0
}
report {
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"
lvs_sort="vg_name,lv_name"
lvs_cols="lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
lvs_cols_verbose="lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"
vgs_sort="vg_name"
vgs_cols="vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
vgs_cols_verbose="vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"
pvs_sort="pv_name"
pvs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
pvs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
segs_sort="vg_name,lv_name,seg_start"
segs_cols="lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
segs_cols_verbose="lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
pvsegs_sort="pv_name,pvseg_start"
pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
}

View File

@ -1,20 +0,0 @@
# This is a default profile for the LVM2 system.
# It contains all configuration settings that are customizable by profiles.
#
# To create a new profile, select the settings you want to customize
# and put them in a new file named <profile_name>.profile. Then put this
# file in a directory as defined by config/profile_dir setting found in
# @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Refer to 'man lvm.conf' for further information about profiles and file layout.
allocation {
thin_pool_chunk_size = 64
thin_pool_discards = "passdown"
thin_pool_zero = 1
}
activation {
thin_pool_autoextend_threshold = 100
thin_pool_autoextend_percent = 20
}

View File

@ -53,11 +53,30 @@ devices {
# same block device and the tools need to display a name for device,
# all the pathnames are matched against each item in the following
# list of regular expressions in turn and the first match is used.
preferred_names = [ ]
# By default no preferred names are defined.
# preferred_names = [ ]
# Try to avoid using undescriptive /dev/dm-N names, if present.
# preferred_names = [ "^/dev/mpath/", "^/dev/mapper/mpath", "^/dev/[hs]d" ]
# In case no prefererred name matches or if preferred_names are not
# defined at all, builtin rules are used to determine the preference.
#
# The first builtin rule checks path prefixes and it gives preference
# based on this ordering (where "dev" depends on devices/dev setting):
# /dev/mapper > /dev/disk > /dev/dm-* > /dev/block
#
# If the ordering above cannot be applied, the path with fewer slashes
# gets preference then.
#
# If the number of slashes is the same, a symlink gets preference.
#
# Finally, if all the rules mentioned above are not applicable,
# lexicographical order is used over paths and the smallest one
# of all gets preference.
# A filter that tells LVM2 to only use a restricted set of devices.
# The filter consists of an array of regular expressions. These
# expressions can be delimited by a character of your choice, and
@ -80,9 +99,11 @@ devices {
# the cache file gets regenerated (see below).
# If it doesn't do what you expect, check the output of 'vgscan -vvvv'.
# If lvmetad is used, then see "A note about device filtering while
# lvmetad is used" comment that is attached to global/use_lvmetad setting.
# By default we accept every block device:
filter = [ "a/.*/" ]
# filter = [ "a/.*/" ]
# Exclude the cdrom drive
# filter = [ "r|/dev/cdrom|" ]
@ -184,6 +205,35 @@ devices {
# in recovery situations.
ignore_suspended_devices = 0
# ignore_lvm_mirrors: Introduced in version 2.02.104
# This setting determines whether logical volumes of "mirror" segment
# type are scanned for LVM labels. This affects the ability of
# mirrors to be used as physical volumes. If 'ignore_lvm_mirrors'
# is set to '1', it becomes impossible to create volume groups on top
# of mirror logical volumes - i.e. to stack volume groups on mirrors.
#
# Allowing mirror logical volumes to be scanned (setting the value to '0')
# can potentially cause LVM processes and I/O to the mirror to become
# blocked. This is due to the way that the "mirror" segment type handles
# failures. In order for the hang to manifest itself, an LVM command must
# be run just after a failure and before the automatic LVM repair process
# takes place OR there must be failures in multiple mirrors in the same
# volume group at the same time with write failures occurring moments
# before a scan of the mirror's labels.
#
# Note that these scanning limitations do not apply to the LVM RAID
# types, like "raid1". The RAID segment types handle failures in a
# different way and are not subject to possible process or I/O blocking.
#
# It is encouraged that users set 'ignore_lvm_mirrors' to 1 if they
# are using the "mirror" segment type. Users that require volume group
# stacking on mirrored logical volumes should consider using the "raid1"
# segment type. The "raid1" segment type is not available for
# active/active clustered volume groups.
#
# Set to 1 to disallow stacking and thereby avoid a possible deadlock.
ignore_lvm_mirrors = 1
# During each LVM operation errors received from each device are counted.
# If the counter of a particular device exceeds the limit set here, no
# further I/O is sent to that device for the remainder of the respective
@ -241,24 +291,78 @@ allocation {
# algorithm.
maximise_cling = 1
# Whether to use blkid library instead of native LVM2 code to detect
# any existing signatures while creating new Physical Volumes and
# Logical Volumes. LVM2 needs to be compiled with blkid wiping support
# for this setting to take effect.
#
# LVM2 native detection code is currently able to recognize these signatures:
# - MD device signature
# - swap signature
# - LUKS signature
# To see the list of signatures recognized by blkid, check the output
# of 'blkid -k' command. The blkid can recognize more signatures than
# LVM2 native detection code, but due to this higher number of signatures
# to be recognized, it can take more time to complete the signature scan.
use_blkid_wiping = 1
# Set to 1 to wipe any signatures found on newly-created Logical Volumes
# automatically in addition to zeroing of the first KB on the LV
# (controlled by the -Z/--zero y option).
# The command line option -W/--wipesignatures takes precedence over this
# setting.
# The default is to wipe signatures when zeroing.
#
wipe_signatures_when_zeroing_new_lvs = 1
# Set to 1 to guarantee that mirror logs will always be placed on
# different PVs from the mirror images. This was the default
# until version 2.02.85.
mirror_logs_require_separate_pvs = 0
# Set to 1 to guarantee that cache_pool metadata will always be
# placed on different PVs from the cache_pool data.
cache_pool_metadata_require_separate_pvs = 0
# Specify the minimal chunk size (in kiB) for cache pool volumes.
# Using a chunk_size that is too large can result in wasteful use of
# the cache, where small reads and writes can cause large sections of
# an LV to be mapped into the cache. However, choosing a chunk_size
# that is too small can result in more overhead trying to manage the
# numerous chunks that become mapped into the cache. The former is
# more of a problem than the latter in most cases, so we default to
# a value that is on the smaller end of the spectrum. Supported values
# range from 32(kiB) to 1048576 in multiples of 32.
# cache_pool_chunk_size = 64
# Set to 1 to guarantee that thin pool metadata will always
# be placed on different PVs from the pool data.
thin_pool_metadata_require_separate_pvs = 0
# Specify chunk size calculation policy for thin pool volumes.
# Possible options are:
# "generic" - if thin_pool_chunk_size is defined, use it.
# Otherwise, calculate the chunk size based on
# estimation and device hints exposed in sysfs:
# the minimum_io_size. The chunk size is always
# at least 64KiB.
#
# "performance" - if thin_pool_chunk_size is defined, use it.
# Otherwise, calculate the chunk size for
# performance based on device hints exposed in
# sysfs: the optimal_io_size. The chunk size is
# always at least 512KiB.
# thin_pool_chunk_size_policy = "generic"
# Specify the minimal chunk size (in KB) for thin pool volumes.
# Use of the larger chunk size may improve perfomance for plain
# Use of the larger chunk size may improve performance for plain
# thin volumes, however using them for snapshot volumes is less efficient,
# as it consumes more space and takes extra time for copying.
# When unset, lvm tries to estimate chunk size starting from 64KB
# Supported values are in range from 64 to 1048576.
# thin_pool_chunk_size = 64
# Specify discards behavior of the thin pool volume.
# Specify discards behaviour of the thin pool volume.
# Select one of "ignore", "nopassdown", "passdown"
# thin_pool_discards = "passdown"
@ -266,6 +370,9 @@ allocation {
# first use.
# N.B. zeroing larger thin pool chunk size degrades performance.
# thin_pool_zero = 1
# Default physical extent size to use for newly created VGs (in KB).
# physical_extent_size = 4096
}
# This section that allows you to configure the nature of the
@ -338,7 +445,7 @@ log {
# Configuration of metadata backups and archiving. In LVM2 when we
# talk about a 'backup' we mean making a copy of the metadata for the
# *current* system. The 'archive' contains old metadata configurations.
# Backups are stored in a human readeable text format.
# Backups are stored in a human readable text format.
backup {
# Should we maintain a backup of the current metadata configuration ?
@ -398,6 +505,11 @@ global {
# temporarily until you update them.
si_unit_consistency = 1
# Whether or not to display unit suffix for sizes. This setting has
# no effect if the units are in human-readable form (global/units="h")
# in which case the suffix is always displayed.
suffix = 1
# Whether or not to communicate with the kernel device-mapper.
# Set to 0 if you want to use the tools to manipulate LVM metadata
# without activating any logical volumes.
@ -430,6 +542,19 @@ global {
# Type 3 uses built-in clustered locking.
# Type 4 uses read-only locking which forbids any operations that might
# change metadata.
# Type 5 offers dummy locking for tools that do not need any locks.
# You should not need to set this directly: the tools will select when
# to use it instead of the configured locking_type. Do not use lvmetad or
# the kernel device-mapper driver with this locking type.
# It is used by the --readonly option that offers read-only access to
# Volume Group metadata that cannot be locked safely because it belongs to
# an inaccessible domain and might be in use, for example a virtual machine
# image or a disk that is shared by a clustered machine.
#
# N.B. Don't use lvmetad with locking type 3 as lvmetad is not yet
# supported in clustered environment. If use_lvmetad=1 and locking_type=3
# is set at the same time, LVM always issues a warning message about this
# and then it automatically disables lvmetad use.
locking_type = 1
# Set to 0 to fail when a lock request cannot be satisfied immediately.
@ -525,7 +650,7 @@ global {
# "mirror" - LVM will layer the 'mirror' and 'stripe' segment types. It
# will do this by creating a mirror on top of striped sub-LVs;
# effectively creating a RAID 0+1 array. This is suboptimal
# in terms of providing redunancy and performance. Changing to
# in terms of providing redundancy and performance. Changing to
# this setting is not advised.
# Specify the '--type <raid10|mirror>' option to override this default
# setting.
@ -541,15 +666,38 @@ global {
# Whether to use (trust) a running instance of lvmetad. If this is set to
# 0, all commands fall back to the usual scanning mechanisms. When set to 1
# *and* when lvmetad is running (it is not auto-started), the volume group
# metadata and PV state flags are obtained from the lvmetad instance and no
# scanning is done by the individual commands. In a setup with lvmetad,
# lvmetad udev rules *must* be set up for LVM to work correctly. Without
# proper udev rules, all changes in block device configuration will be
# *ignored* until a manual 'pvscan --cache' is performed.
# *and* when lvmetad is running (automatically instantiated by making use of
# systemd's socket-based service activation or run as an initscripts service
# or run manually), the volume group metadata and PV state flags are obtained
# from the lvmetad instance and no scanning is done by the individual
# commands. In a setup with lvmetad, lvmetad udev rules *must* be set up for
# LVM to work correctly. Without proper udev rules, all changes in block
# device configuration will be *ignored* until a manual 'pvscan --cache'
# is performed. These rules are installed by default.
#
# If lvmetad has been running while use_lvmetad was 0, it MUST be stopped
# before changing use_lvmetad to 1 and started again afterwards.
#
# If using lvmetad, the volume activation is also switched to automatic
# event-based mode. In this mode, the volumes are activated based on
# incoming udev events that automatically inform lvmetad about new PVs
# that appear in the system. Once the VG is complete (all the PVs are
# present), it is auto-activated. The activation/auto_activation_volume_list
# setting controls which volumes are auto-activated (all by default).
#
# A note about device filtering while lvmetad is used:
# When lvmetad is updated (either automatically based on udev events
# or directly by pvscan --cache <device> call), the devices/filter
# is ignored and all devices are scanned by default. The lvmetad always
# keeps unfiltered information which is then provided to LVM commands
# and then each LVM command does the filtering based on devices/filter
# setting itself.
# To prevent scanning devices completely, even when using lvmetad,
# the devices/global_filter must be used.
# N.B. Don't use lvmetad with locking type 3 as lvmetad is not yet
# supported in clustered environment. If use_lvmetad=1 and locking_type=3
# is set at the same time, LVM always issues a warning message about this
# and then it automatically disables lvmetad use.
use_lvmetad = 0
# Full path of the utility called to check that a thin metadata device
@ -566,9 +714,11 @@ global {
# Array of string options passed with thin_check command. By default,
# option "-q" is for quiet output.
# With thin_check version 2.1 or newer you can add "--ignore-non-fatal-errors"
# to let it pass through ignoreable errors and fix them later.
# to let it pass through ignorable errors and fix them later.
# With thin_check version 3.2 or newer you should add
# "--clear-needs-check-flag".
#
# thin_check_options = [ "-q" ]
# thin_check_options = [ "-q", "--clear-needs-check-flag" ]
# Full path of the utility called to repair a thin metadata device
# is in a state that allows it to be used.
@ -594,8 +744,39 @@ global {
# discards_non_power_2
# external_origin
# metadata_resize
# external_origin_extend
#
# thin_disabled_features = [ "discards", "block_size" ]
# Full path of the utility called to check that a cache metadata device
# is in a state that allows it to be used.
# Each time a cached LV needs to be used or after it is deactivated
# this utility is executed. The activation will only proceed if the utility
# has an exit status of 0.
# Set to "" to skip this check. (Not recommended.)
# The cache tools are available as part of the device-mapper-persistent-data
# package from https://github.com/jthornber/thin-provisioning-tools.
#
# cache_check_executable = "@CACHE_CHECK_CMD@"
# Array of string options passed with cache_check command. By default,
# option "-q" is for quiet output.
#
# cache_check_options = [ "-q" ]
# Full path of the utility called to repair a cache metadata device.
# Each time a cache metadata needs repair this utility is executed.
# See cache_check_executable how to obtain binaries.
#
# cache_repair_executable = "@CACHE_REPAIR_CMD@"
# Array of extra string options passed with cache_repair command.
# cache_repair_options = [ "" ]
# Full path of the utility called to dump cache metadata content.
# See cache_check_executable how to obtain binaries.
#
# cache_dump_executable = "@CACHE_DUMP_CMD@"
}
activation {
@ -725,7 +906,7 @@ activation {
# auto_set_activation_skip = 1
# For RAID or 'mirror' segment types, 'raid_region_size' is the
# size (in kiB) of each:
# size (in KiB) of each:
# - synchronization operation when initializing
# - each copy operation when performing a 'pvmove' (using 'mirror' segtype)
# This setting has replaced 'mirror_region_size' since version 2.02.99
@ -863,8 +1044,140 @@ activation {
# are no progress reports, but the process is awoken immediately the
# operation is complete.
polling_interval = 15
# 'activation_mode' determines how Logical Volumes are activated if
# any devices are missing. Possible settings are:
#
# "complete" - Only allow activation of an LV if all of the Physical
# Volumes it uses are present. Other PVs in the Volume
# Group may be missing.
#
# "degraded" - Like "complete", but additionally RAID Logical Volumes of
# segment type raid1, raid4, raid5, radid6 and raid10 will
# be activated if there is no data loss, i.e. they have
# sufficient redundancy to present the entire addressable
# range of the Logical Volume.
#
# "partial" - Allows the activation of any Logical Volume even if
# a missing or failed PV could cause data loss with a
# portion of the Logical Volume inaccessible.
# This setting should not normally be used, but may
# sometimes assist with data recovery.
#
# This setting was introduced in LVM version 2.02.108. It corresponds
# with the '--activationmode' option for lvchange and vgchange.
activation_mode = "degraded"
}
# Report settings.
#
# report {
# Align columns on report output.
# aligned=1
# When buffered reporting is used, the report's content is appended
# incrementally to include each object being reported until the report
# is flushed to output which normally happens at the end of command
# execution. Otherwise, if buffering is not used, each object is
# reported as soon as its processing is finished.
# buffered=1
# Show headings for columns on report.
# headings=1
# A separator to use on report after each field.
# separator=" "
# A separator to use for list items when reported.
# list_item_separator=","
# Use a field name prefix for each field reported.
# prefixes=0
# Quote field values when using field name prefixes.
# quoted=1
# Output each column as a row. If set, this also implies report/prefixes=1.
# colums_as_rows=0
# Use binary values "0" or "1" instead of descriptive literal values for
# columns that have exactly two valid values to report (not counting the
# "unknown" value which denotes that the value could not be determined).
#
# binary_values_as_numeric = 0
# Comma separated list of columns to sort by when reporting 'lvm devtypes' command.
# See 'lvm devtypes -o help' for the list of possible fields.
# devtypes_sort="devtype_name"
# Comma separated list of columns to report for 'lvm devtypes' command.
# See 'lvm devtypes -o help' for the list of possible fields.
# devtypes_cols="devtype_name,devtype_max_partitions,devtype_description"
# Comma separated list of columns to report for 'lvm devtypes' command in verbose mode.
# See 'lvm devtypes -o help' for the list of possible fields.
# devtypes_cols_verbose="devtype_name,devtype_max_partitions,devtype_description"
# Comma separated list of columns to sort by when reporting 'lvs' command.
# See 'lvs -o help' for the list of possible fields.
# lvs_sort="vg_name,lv_name"
# Comma separated list of columns to report for 'lvs' command.
# See 'lvs -o help' for the list of possible fields.
# lvs_cols="lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
# Comma separated list of columns to report for 'lvs' command in verbose mode.
# See 'lvs -o help' for the list of possible fields.
# lvs_cols_verbose="lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert
# Comma separated list of columns to sort by when reporting 'vgs' command.
# See 'vgs -o help' for the list of possible fields.
# vgs_sort="vg_name"
# Comma separated list of columns to report for 'vgs' command.
# See 'vgs -o help' for the list of possible fields.
# vgs_cols="vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
# Comma separated list of columns to report for 'vgs' command in verbose mode.
# See 'vgs -o help' for the list of possible fields.
# vgs_cols_verbose="vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"
# Comma separated list of columns to sort by when reporting 'pvs' command.
# See 'pvs -o help' for the list of possible fields.
# pvs_sort="pv_name"
# Comma separated list of columns to report for 'pvs' command.
# See 'pvs -o help' for the list of possible fields.
# pvs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
# Comma separated list of columns to report for 'pvs' command in verbose mode.
# See 'pvs -o help' for the list of possible fields.
# pvs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
# Comma separated list of columns to sort by when reporting 'lvs --segments' command.
# See 'lvs --segments -o help' for the list of possible fields.
# segs_sort="vg_name,lv_name,seg_start"
# Comma separated list of columns to report for 'lvs --segments' command.
# See 'lvs --segments -o help' for the list of possible fields.
# segs_cols="lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
# Comma separated list of columns to report for 'lvs --segments' command in verbose mode.
# See 'lvs --segments -o help' for the list of possible fields.
# segs_cols_verbose="lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
# Comma separated list of columns to sort by when reporting 'pvs --segments' command.
# See 'pvs --segments -o help' for the list of possible fields.
# pvsegs_sort="pv_name,pvseg_start"
# Comma separated list of columns to sort by when reporting 'pvs --segments' command.
# See 'pvs --segments -o help' for the list of possible fields.
# pvsegs_cols="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
# Comma separated list of columns to sort by when reporting 'pvs --segments' command in verbose mode.
# See 'pvs --segments -o help' for the list of possible fields.
# pvsegs_cols_verbose="pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
#}
####################
# Advanced section #

View File

@ -0,0 +1,24 @@
# This is a metadata profile template for the LVM2 system.
#
# It contains all configuration settings that are customizable by metadata
# profiles. To create a new metadata profile, select the settings you want
# to customize and add them in a new file named <profile_name>.profile.
# Then install the new profile in a directory as defined by config/profile_dir
# setting found in @DEFAULT_SYS_DIR@/lvm.conf file.
#
# Metadata profiles can be referenced by using the --metadataprofile LVM2
# command line option.
#
# Refer to 'man lvm.conf' for further information about profiles and
# general configuration file layout.
#
allocation {
thin_pool_zero=1
thin_pool_discards="passdown"
thin_pool_chunk_size_policy="generic"
# thin_pool_chunk_size=64
}
activation {
thin_pool_autoextend_threshold=100
thin_pool_autoextend_percent=20
}

View File

@ -0,0 +1,4 @@
allocation {
thin_pool_chunk_size_policy = "generic"
thin_pool_zero = 1
}

View File

@ -0,0 +1,4 @@
allocation {
thin_pool_chunk_size_policy = "performance"
thin_pool_zero = 0
}

3081
configure vendored

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -15,10 +15,6 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
ifeq ("@BUILD_LVMETAD@", "yes")
SUBDIRS += lvmetad
endif
.PHONY: dmeventd clvmd cmirrord lvmetad
ifneq ("@CLVMD@", "none")
@ -36,6 +32,10 @@ daemons.cflow: dmeventd.cflow
endif
endif
ifeq ("@BUILD_LVMETAD@", "yes")
SUBDIRS += lvmetad
endif
ifeq ($(MAKECMDGOALS),distclean)
SUBDIRS = clvmd cmirrord dmeventd lvmetad
endif

View File

@ -87,8 +87,8 @@ include $(top_builddir)/make.tmpl
LVMLIBS += -ldevmapper
LIBS += $(PTHREAD_LIBS)
DEFS += -D_REENTRANT
CFLAGS += -fno-strict-aliasing
CFLAGS += -fno-strict-aliasing $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
INSTALL_TARGETS = \
install_clvmd

View File

@ -23,6 +23,7 @@
#define _CLVM_H
#include "configure.h"
#include <inttypes.h>
struct clvm_header {
uint8_t cmd; /* See below */

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,9 +243,8 @@ 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)
{
destroy_lvhash();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cman_finish(c_handle);
}
@ -283,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;
@ -381,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

@ -78,9 +78,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
unsigned char lock_cmd;
unsigned char lock_flags;
/* Reset test mode before we start */
init_test(0);
/* Do the command */
switch (msg->cmd) {
/* Just a test message */
@ -112,8 +109,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
lockname = &args[2];
/* Check to see if the VG is in use by LVM1 */
status = do_check_lvm1(lockname);
if (lock_flags & LCK_TEST_MODE)
init_test(1);
do_lock_vg(lock_cmd, lock_flags, lockname);
break;
@ -122,8 +117,6 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
if (lock_flags & LCK_TEST_MODE)
init_test(1);
status = do_lock_lv(lock_cmd, lock_flags, lockname);
/* Replace EIO with something less scary */
if (status == EIO) {
@ -183,65 +176,58 @@ int do_command(struct local_client *client, struct clvm_header *msg, int msglen,
}
return status;
}
static int lock_vg(struct local_client *client)
{
struct dm_hash_table *lock_hash;
struct clvm_header *header =
(struct clvm_header *) client->bits.localsock.cmd;
unsigned char lock_cmd;
int lock_mode;
char *args = header->node + strlen(header->node) + 1;
int lkid;
int status = 0;
char *lockname;
struct dm_hash_table *lock_hash;
struct clvm_header *header =
(struct clvm_header *) client->bits.localsock.cmd;
unsigned char lock_cmd;
int lock_mode;
char *args = header->node + strlen(header->node) + 1;
int lkid;
int status;
char *lockname;
/* Keep a track of VG locks in our own hash table. In current
practice there should only ever be more than two VGs locked
if a user tries to merge lots of them at once */
if (client->bits.localsock.private) {
lock_hash = (struct dm_hash_table *)client->bits.localsock.private;
}
else {
lock_hash = dm_hash_create(3);
if (!lock_hash)
return ENOMEM;
client->bits.localsock.private = (void *)lock_hash;
}
/*
* Keep a track of VG locks in our own hash table. In current
* practice there should only ever be more than two VGs locked
* if a user tries to merge lots of them at once
*/
if (!client->bits.localsock.private) {
if (!(lock_hash = dm_hash_create(3)))
return ENOMEM;
client->bits.localsock.private = (void *) lock_hash;
} else
lock_hash = (struct dm_hash_table *) client->bits.localsock.private;
lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
lock_mode = ((int)lock_cmd & LCK_TYPE_MASK);
/* lock_flags = args[1]; */
lockname = &args[2];
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
lock_cmd = args[0] & (LCK_NONBLOCK | LCK_HOLD | LCK_SCOPE_MASK | LCK_TYPE_MASK);
lock_mode = ((int) lock_cmd & LCK_TYPE_MASK);
/* lock_flags = args[1]; */
lockname = &args[2];
DEBUGLOG("doing PRE command LOCK_VG '%s' at %x (client=%p)\n", lockname, lock_cmd, client);
if (lock_mode == LCK_UNLOCK) {
if (lock_mode == LCK_UNLOCK) {
if (!(lkid = (int) (long) dm_hash_lookup(lock_hash, lockname)))
return EINVAL;
lkid = (int)(long)dm_hash_lookup(lock_hash, lockname);
if (lkid == 0)
return EINVAL;
if ((status = sync_unlock(lockname, lkid)))
status = errno;
else
dm_hash_remove(lock_hash, lockname);
} else {
/* Read locks need to be PR; other modes get passed through */
if (lock_mode == LCK_READ)
lock_mode = LCK_PREAD;
status = sync_unlock(lockname, lkid);
if (status)
status = errno;
else
dm_hash_remove(lock_hash, lockname);
}
else {
/* Read locks need to be PR; other modes get passed through */
if (lock_mode == LCK_READ)
lock_mode = LCK_PREAD;
status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid);
if (status)
status = errno;
else
if (!dm_hash_insert(lock_hash, lockname, (void *)(long)lkid))
return ENOMEM;
}
if ((status = sync_lock(lockname, lock_mode, (lock_cmd & LCK_NONBLOCK) ? LCKF_NOQUEUE : 0, &lkid)))
status = errno;
else if (!dm_hash_insert(lock_hash, lockname, (void *) (long) lkid))
return ENOMEM;
}
return status;
return status;
}
@ -259,7 +245,6 @@ int do_pre_command(struct local_client *client)
int status = 0;
char *lockname;
init_test(0);
switch (header->cmd) {
case CLVMD_CMD_TEST:
status = sync_lock("CLVMD_TEST", LCK_EXCL, 0, &lockid);
@ -278,8 +263,6 @@ int do_pre_command(struct local_client *client)
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
if (lock_flags & LCK_TEST_MODE)
init_test(1);
status = pre_lock_lv(lock_cmd, lock_flags, lockname);
break;
@ -311,20 +294,16 @@ int do_post_command(struct local_client *client)
char *args = header->node + strlen(header->node) + 1;
char *lockname;
init_test(0);
switch (header->cmd) {
case CLVMD_CMD_TEST:
status =
sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
client->bits.localsock.private = 0;
status = sync_unlock("CLVMD_TEST", (int) (long) client->bits.localsock.private);
client->bits.localsock.private = NULL;
break;
case CLVMD_CMD_LOCK_LV:
lock_cmd = args[0];
lock_flags = args[1];
lockname = &args[2];
if (lock_flags & LCK_TEST_MODE)
init_test(1);
status = post_lock_lv(lock_cmd, lock_flags, lockname);
break;
@ -357,7 +336,7 @@ void cmd_client_cleanup(struct local_client *client)
}
dm_hash_destroy(lock_hash);
client->bits.localsock.private = 0;
client->bits.localsock.private = NULL;
}

View File

@ -20,14 +20,13 @@
#include "configure.h"
#define _REENTRANT
#define _GNU_SOURCE
#define _FILE_OFFSET_BITS 64
#include "libdevmapper.h"
#include "lvm-logging.h"
#include <unistd.h>
#include <sys/stat.h>
#endif

View File

@ -89,7 +89,7 @@ quorum_callbacks_t quorum_callbacks = {
struct node_info
{
enum {NODE_UNKNOWN, NODE_DOWN, NODE_UP, NODE_CLVMD} state;
enum {NODE_DOWN, NODE_CLVMD} state;
int nodeid;
};
@ -255,26 +255,6 @@ static void corosync_cpg_confchg_callback(cpg_handle_t handle,
ninfo->state = NODE_DOWN;
}
for (i=0; i<member_list_entries; i++) {
if (member_list[i].nodeid == 0) continue;
ninfo = dm_hash_lookup_binary(node_hash,
(char *)&member_list[i].nodeid,
COROSYNC_CSID_LEN);
if (!ninfo) {
ninfo = malloc(sizeof(struct node_info));
if (!ninfo) {
break;
}
else {
ninfo->nodeid = member_list[i].nodeid;
dm_hash_insert_binary(node_hash,
(char *)&ninfo->nodeid,
COROSYNC_CSID_LEN, ninfo);
}
}
ninfo->state = NODE_CLVMD;
}
num_nodes = member_list_entries;
}
@ -365,9 +345,6 @@ static int _init_cluster(void)
static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
destroy_lvhash();
dlm_release_lockspace(LOCKSPACE_NAME, lockspace, 1);
cpg_finalize(cpg_handle);
quorum_finalize(quorum_handle);
@ -408,7 +385,7 @@ static int _name_from_csid(const char *csid, char *name)
return 0;
}
static int _get_num_nodes()
static int _get_num_nodes(void)
{
DEBUGLOG("num_nodes = %d\n", num_nodes);
return num_nodes;
@ -440,7 +417,6 @@ static int _cluster_do_node_callback(struct local_client *master_client,
{
struct dm_hash_node *hn;
struct node_info *ninfo;
int somedown = 0;
dm_hash_iterate(hn, node_hash)
{
@ -452,12 +428,10 @@ static int _cluster_do_node_callback(struct local_client *master_client,
DEBUGLOG("down_callback. node %d, state = %d\n", ninfo->nodeid,
ninfo->state);
if (ninfo->state != NODE_DOWN)
callback(master_client, csid, ninfo->state == NODE_CLVMD);
if (ninfo->state != NODE_CLVMD)
somedown = -1;
if (ninfo->state == NODE_CLVMD)
callback(master_client, csid, 1);
}
return somedown;
return 0;
}
/* Real locking */
@ -528,7 +502,7 @@ static int _unlock_resource(const char *resource, int lockid)
return 0;
}
static int _is_quorate()
static int _is_quorate(void)
{
int quorate;
if (quorum_getquorate(quorum_handle, &quorate) == CS_OK)

View File

@ -197,9 +197,7 @@ static int add_internal_client(int fd, fd_callback_t callback)
DEBUGLOG("Add_internal_client, fd = %d\n", fd);
client = calloc(1, sizeof(struct local_client));
if (!client)
{
if (!(client = dm_zalloc(sizeof(*client)))) {
DEBUGLOG("malloc failed\n");
return -1;
}
@ -367,9 +365,6 @@ static int _init_cluster(void)
static void _cluster_closedown(void)
{
DEBUGLOG("cluster_closedown\n");
destroy_lvhash();
saLckFinalize(lck_handle);
cpg_finalize(cpg_handle);
}
@ -689,6 +684,6 @@ struct cluster_ops *init_openais_cluster(void)
{
if (!_init_cluster())
return &_cluster_openais_ops;
else
return NULL;
return NULL;
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2009 Red Hat, Inc. All rights reserved.
* Copyright (C) 2009-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -19,7 +19,6 @@
#include "locking.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "lvm-functions.h"
#include "clvmd.h"
#include <sys/un.h>
@ -32,10 +31,14 @@ static int listen_fd = -1;
static struct dm_hash_table *_locks;
static int _lockid;
static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Using one common condition for all locks for simplicity */
static pthread_cond_t _lock_cond = PTHREAD_COND_INITIALIZER;
struct lock {
struct dm_list list;
int lockid;
int mode;
int excl;
};
static void close_comms(void)
@ -105,6 +108,7 @@ static int _init_cluster(void)
r = init_comms();
if (r) {
dm_hash_destroy(_locks);
_locks = NULL;
return r;
}
@ -116,11 +120,13 @@ static void _cluster_closedown(void)
{
close_comms();
DEBUGLOG("cluster_closedown\n");
destroy_lvhash();
/* If there is any awaited resource, kill it softly */
pthread_mutex_lock(&_lock_mutex);
dm_hash_destroy(_locks);
_locks = NULL;
_lockid = 0;
pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
pthread_mutex_unlock(&_lock_mutex);
}
static void _get_our_csid(char *csid)
@ -160,63 +166,114 @@ static int _cluster_do_node_callback(struct local_client *master_client,
int _lock_file(const char *file, uint32_t flags);
static pthread_mutex_t _lock_mutex = PTHREAD_MUTEX_INITIALIZER;
/* Using one common condition for all locks for simplicity */
static pthread_cond_t _lock_cond = PTHREAD_COND_INITIALIZER;
static const char *_get_mode(int mode)
{
switch (mode) {
case LCK_NULL: return "NULL";
case LCK_READ: return "READ";
case LCK_PREAD: return "PREAD";
case LCK_WRITE: return "WRITE";
case LCK_EXCL: return "EXCLUSIVE";
case LCK_UNLOCK: return "UNLOCK";
default: return "????";
}
}
/* Real locking */
static int _lock_resource(const char *resource, int mode, int flags, int *lockid)
{
struct lock *lck;
/* DLM table of allowed transition states */
static const int _dlm_table[6][6] = {
/* Mode NL CR CW PR PW EX */
/* NL */ { 1, 1, 1, 1, 1, 1},
/* CR */ { 1, 1, 1, 1, 1, 0},
/* CW */ { 1, 1, 1, 0, 0, 0},
/* PR */ { 1, 1, 0, 1, 0, 0},
/* PW */ { 1, 1, 0, 0, 0, 0},
/* EX */ { 1, 0, 0, 0, 0, 0}
};
DEBUGLOG("Locking resource %s, flags=%d, mode=%d\n",
resource, flags, mode);
struct lock *lck = NULL, *lckt;
struct dm_list *head;
DEBUGLOG("Locking resource %s, flags=0x%02x (%s%s%s), mode=%s (%d)\n",
resource, flags,
(flags & LCKF_NOQUEUE) ? "NOQUEUE" : "",
((flags & (LCKF_NOQUEUE | LCKF_CONVERT)) ==
(LCKF_NOQUEUE | LCKF_CONVERT)) ? "|" : "",
(flags & LCKF_CONVERT) ? "CONVERT" : "",
_get_mode(mode), mode);
mode &= LCK_TYPE_MASK;
pthread_mutex_lock(&_lock_mutex);
retry:
if (!(lck = dm_hash_lookup(_locks, resource))) {
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 */
DEBUGLOG("Unlocked resource %s cannot be converted\n", resource);
goto_bad;
}
/* Add new locked resource */
if (!(lck = dm_zalloc(sizeof(struct lock))) ||
!dm_hash_insert(_locks, resource, lck))
goto bad;
if (!(head = dm_malloc(sizeof(struct dm_list))) ||
!dm_hash_insert(_locks, resource, head)) {
dm_free(head);
goto_bad;
}
lck->lockid = ++_lockid;
goto out;
dm_list_init(head);
} else /* Update/convert locked resource */
dm_list_iterate_items(lck, head) {
/* Check is all locks are compatible with requested lock */
if (flags & LCKF_CONVERT) {
if (lck->lockid != *lockid)
continue;
DEBUGLOG("Converting resource %s lockid=%d mode:%s -> %s...\n",
resource, lck->lockid, _get_mode(lck->mode), _get_mode(mode));
dm_list_iterate_items(lckt, head) {
if ((lckt->lockid != *lockid) &&
!_dlm_table[mode][lckt->mode]) {
if (!(flags & LCKF_NOQUEUE) &&
/* TODO: Real dlm uses here conversion queues */
!pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
_locks) /* End of the game? */
goto retry;
goto bad;
}
}
lck->mode = mode; /* Lock is now converted */
goto out;
} else if (!_dlm_table[mode][lck->mode]) {
DEBUGLOG("Resource %s already locked lockid=%d, mode:%s\n",
resource, lck->lockid, _get_mode(lck->mode));
if (!(flags & LCKF_NOQUEUE) &&
!pthread_cond_wait(&_lock_cond, &_lock_mutex) &&
_locks) { /* End of the game? */
DEBUGLOG("Resource %s retrying lock in mode:%s...\n",
resource, _get_mode(mode));
goto retry;
}
goto bad;
}
}
if (!(flags & LCKF_CONVERT)) {
if (!(lck = dm_malloc(sizeof(struct lock))))
goto_bad;
*lockid = lck->lockid = ++_lockid;
lck->mode = mode;
dm_list_add(head, &lck->list);
}
/* Update/convert lock */
if (flags == LCKF_CONVERT) {
if (lck->excl)
mode = LCK_EXCL;
} else if ((lck->mode == LCK_WRITE) || (lck->mode == LCK_EXCL)) {
DEBUGLOG("Resource %s already %s locked (%d)...\n", resource,
(lck->mode == LCK_WRITE) ? "write" : "exclusively", lck->lockid);
goto maybe_retry;
} else if (lck->mode > mode) {
DEBUGLOG("Resource %s already locked and %s lock requested...\n",
resource,
(mode == LCK_READ) ? "READ" :
(mode == LCK_WRITE) ? "WRITE" : "EXCLUSIVE");
goto maybe_retry;
}
out:
*lockid = lck->lockid;
lck->mode = mode;
lck->excl |= (mode == LCK_EXCL);
DEBUGLOG("Locked resource %s, lockid=%d, mode=%d\n", resource, lck->lockid, mode);
pthread_cond_broadcast(&_lock_cond); /* 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;
maybe_retry:
if (!(flags & LCK_NONBLOCK)) {
pthread_cond_wait(&_lock_cond, &_lock_mutex);
DEBUGLOG("Resource %s RETRYING lock...\n", resource);
goto retry;
}
bad:
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Failed to lock resource %s\n", resource);
@ -227,35 +284,44 @@ bad:
static int _unlock_resource(const char *resource, int lockid)
{
struct lock *lck;
struct dm_list *head;
int r = 1;
if (lockid < 0) {
DEBUGLOG("Not tracking unlock of lockid -1: %s, lockid=%d\n",
resource, lockid);
return 0;
return 1;
}
DEBUGLOG("Unlocking resource %s, lockid=%d\n", resource, lockid);
pthread_mutex_lock(&_lock_mutex);
if (!(lck = dm_hash_lookup(_locks, resource))) {
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Resource %s, lockid=%d is not locked.\n", resource, lockid);
return 1;
}
if (lck->lockid != lockid) {
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Resource %s has wrong lockid %d, expected %d.\n",
resource, lck->lockid, lockid);
return 1;
}
dm_hash_remove(_locks, resource);
pthread_cond_broadcast(&_lock_cond); /* wakeup waiters */
pthread_mutex_unlock(&_lock_mutex);
dm_free(lck);
return 0;
if (!(head = dm_hash_lookup(_locks, resource))) {
pthread_mutex_unlock(&_lock_mutex);
DEBUGLOG("Resource %s is not locked.\n", resource);
return 1;
}
dm_list_iterate_items(lck, head)
if (lck->lockid == lockid) {
dm_list_del(&lck->list);
dm_free(lck);
r = 0;
goto out;
}
DEBUGLOG("Resource %s has wrong lockid %d.\n", resource, lockid);
out:
if (dm_list_empty(head)) {
//DEBUGLOG("Resource %s is no longer hashed (lockid=%d).\n", resource, lockid);
dm_hash_remove(_locks, resource);
dm_free(head);
}
pthread_mutex_unlock(&_lock_mutex);
return r;
}
static int _is_quorate(void)

File diff suppressed because it is too large Load Diff

View File

@ -53,13 +53,12 @@ struct localsock_bits {
int finished; /* Flag to tell subthread to exit */
int all_success; /* Set to 0 if any node (or the pre_command)
failed */
int cleanup_needed; /* helper for cleanup_zombie */
struct local_client *pipe_client;
pthread_t threadid;
enum { PRE_COMMAND, POST_COMMAND, QUIT } state;
enum { PRE_COMMAND, POST_COMMAND } state;
pthread_mutex_t mutex; /* Main thread and worker synchronisation */
pthread_cond_t cond;
pthread_mutex_t reply_mutex; /* Protect reply structure */
};
/* Entries for PIPE clients */

View File

@ -17,7 +17,6 @@
#include <pthread.h>
#include "lvm-types.h"
#include "clvm.h"
#include "clvmd-comms.h"
#include "clvmd.h"
@ -131,14 +130,15 @@ static const char *decode_flags(unsigned char flags)
static char buf[128];
int len;
len = sprintf(buf, "0x%x ( %s%s%s%s%s%s%s)", flags,
len = sprintf(buf, "0x%x ( %s%s%s%s%s%s%s%s)", flags,
flags & LCK_PARTIAL_MODE ? "PARTIAL_MODE|" : "",
flags & LCK_MIRROR_NOSYNC_MODE ? "MIRROR_NOSYNC|" : "",
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_DMEVENTD_MONITOR_IGNORE ? "DMEVENTD_MONITOR_IGNORE|" : "");
flags & LCK_DMEVENTD_MONITOR_IGNORE ? "DMEVENTD_MONITOR_IGNORE|" : "",
flags & LCK_REVERT_MODE ? "REVERT|" : "");
if (len > 1)
buf[len - 2] = ' ';
@ -180,8 +180,19 @@ static int insert_info(const char *resource, struct lv_info *lvi)
static void remove_info(const char *resource)
{
int num_open;
pthread_mutex_lock(&lv_hash_lock);
dm_hash_remove(lv_hash, resource);
/* When last lock is remove, validate there are not left opened devices */
if (!dm_hash_get_first(lv_hash)) {
if (critical_section())
log_error(INTERNAL_ERROR "No volumes are locked however clvmd is in activation mode critical section.");
if ((num_open = dev_cache_check_for_open_devices()))
log_error(INTERNAL_ERROR "No volumes are locked however %d devices are still open.", num_open);
}
pthread_mutex_unlock(&lv_hash_lock);
}
@ -224,7 +235,7 @@ void destroy_lvhash(void)
if ((status = sync_unlock(resource, lvi->lock_id)))
DEBUGLOG("unlock_all. unlock failed(%d): %s\n",
status, strerror(errno));
free(lvi);
dm_free(lvi);
}
dm_hash_destroy(lv_hash);
@ -240,9 +251,6 @@ static int hold_lock(char *resource, int mode, int flags)
int saved_errno;
struct lv_info *lvi;
if (test_mode())
return 0;
/* Mask off invalid options */
flags &= LCKF_NOQUEUE | LCKF_CONVERT;
@ -256,7 +264,7 @@ static int hold_lock(char *resource, int mode, int flags)
}
if ((lvi->lock_mode == LCK_EXCL) && (mode == LCK_WRITE)) {
DEBUGLOG("hold_lock, lock already held LCK_EXCL, "
"ignoring LCK_WRITE request");
"ignoring LCK_WRITE request\n");
return 0;
}
}
@ -268,20 +276,16 @@ static int hold_lock(char *resource, int mode, int flags)
}
if (lvi) {
/* Already exists - convert it */
status =
sync_lock(resource, mode, flags, &lvi->lock_id);
status = sync_lock(resource, mode, flags, &lvi->lock_id);
saved_errno = errno;
if (!status)
lvi->lock_mode = mode;
if (status) {
else
DEBUGLOG("hold_lock. convert to %d failed: %s\n", mode,
strerror(errno));
}
errno = saved_errno;
} else {
lvi = malloc(sizeof(struct lv_info));
if (!lvi) {
if (!(lvi = dm_malloc(sizeof(struct lv_info)))) {
errno = ENOMEM;
return -1;
}
@ -290,7 +294,7 @@ static int hold_lock(char *resource, int mode, int flags)
status = sync_lock(resource, mode, flags & ~LCKF_CONVERT, &lvi->lock_id);
saved_errno = errno;
if (status) {
free(lvi);
dm_free(lvi);
DEBUGLOG("hold_lock. lock at %d failed: %s\n", mode,
strerror(errno));
} else
@ -311,9 +315,6 @@ static int hold_unlock(char *resource)
int status;
int saved_errno;
if (test_mode())
return 0;
if (!(lvi = lookup_info(resource))) {
DEBUGLOG("hold_unlock, lock not already held\n");
return 0;
@ -323,7 +324,7 @@ static int hold_unlock(char *resource)
saved_errno = errno;
if (!status) {
remove_info(resource);
free(lvi);
dm_free(lvi);
} else {
DEBUGLOG("hold_unlock. unlock failed(%d): %s\n", status,
strerror(errno));
@ -373,7 +374,7 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
* Use lock conversion only if requested, to prevent implicit conversion
* of exclusive lock to shared one during activation.
*/
if (command & LCK_CLUSTER_VG) {
if (!test_mode() && command & LCK_CLUSTER_VG) {
status = hold_lock(resource, mode, LCKF_NOQUEUE | (lock_flags & LCK_CONVERT ? LCKF_CONVERT:0));
if (status) {
/* Return an LVM-sensible error for this.
@ -401,13 +402,13 @@ static int do_activate_lv(char *resource, unsigned char command, unsigned char l
}
/* Now activate it */
if (!lv_activate(cmd, resource, exclusive, NULL))
if (!lv_activate(cmd, resource, exclusive, 0, 0, NULL))
goto error;
return 0;
error:
if (oldmode == -1 || oldmode != mode)
if (!test_mode() && (oldmode == -1 || oldmode != mode))
(void)hold_unlock(resource);
return EIO;
}
@ -471,7 +472,7 @@ static int do_deactivate_lv(char *resource, unsigned char command, unsigned char
if (!lv_deactivate(cmd, resource, NULL))
return EIO;
if (command & LCK_CLUSTER_VG) {
if (!test_mode() && command & LCK_CLUSTER_VG) {
status = hold_unlock(resource);
if (status)
return errno;
@ -483,18 +484,19 @@ static int do_deactivate_lv(char *resource, unsigned char command, unsigned char
const char *do_lock_query(char *resource)
{
int mode;
const char *type = NULL;
const char *type;
mode = get_current_lock(resource);
switch (mode) {
case LCK_NULL: type = "NL"; break;
case LCK_READ: type = "CR"; break;
case LCK_PREAD:type = "PR"; break;
case LCK_WRITE:type = "PW"; break;
case LCK_EXCL: type = "EX"; break;
case LCK_NULL: type = "NL"; break;
case LCK_READ: type = "CR"; break;
case LCK_PREAD:type = "PR"; break;
case LCK_WRITE:type = "PW"; break;
case LCK_EXCL: type = "EX"; break;
default: type = NULL;
}
DEBUGLOG("do_lock_query: resource '%s', mode %i (%s)\n", resource, mode, type ?: "?");
DEBUGLOG("do_lock_query: resource '%s', mode %i (%s)\n", resource, mode, type ?: "--");
return type;
}
@ -517,6 +519,8 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
}
pthread_mutex_lock(&lvm_lock);
init_test((lock_flags & LCK_TEST_MODE) ? 1 : 0);
if (lock_flags & LCK_MIRROR_NOSYNC_MODE)
init_mirror_in_sync(1);
@ -569,6 +573,7 @@ int do_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
/* clean the pool for another command */
dm_pool_empty(cmd->mem);
init_test(0);
pthread_mutex_unlock(&lvm_lock);
DEBUGLOG("Command return is %d, critical_section is %d\n", status, critical_section());
@ -588,7 +593,8 @@ int pre_lock_lv(unsigned char command, unsigned char lock_flags, char *resource)
DEBUGLOG("pre_lock_lv: resource '%s', cmd = %s, flags = %s\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags));
if (hold_lock(resource, LCK_WRITE, LCKF_NOQUEUE | LCKF_CONVERT))
if (!(lock_flags & LCK_TEST_MODE) &&
hold_lock(resource, LCK_WRITE, LCKF_NOQUEUE | LCKF_CONVERT))
return errno;
}
return 0;
@ -606,9 +612,8 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
(command & LCK_CLUSTER_VG)) {
int oldmode;
DEBUGLOG
("post_lock_lv: resource '%s', cmd = %s, flags = %s\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags));
DEBUGLOG("post_lock_lv: resource '%s', cmd = %s, flags = %s\n",
resource, decode_locking_cmd(command), decode_flags(lock_flags));
/* If the lock state is PW then restore it to what it was */
oldmode = get_current_lock(resource);
@ -621,11 +626,13 @@ int post_lock_lv(unsigned char command, unsigned char lock_flags,
if (!status)
return EIO;
if (lvi.exists) {
if (hold_lock(resource, LCK_READ, LCKF_CONVERT))
if (!(lock_flags & LCK_TEST_MODE)) {
if (lvi.exists) {
if (hold_lock(resource, LCK_READ, LCKF_CONVERT))
return errno;
} else if (hold_unlock(resource))
return errno;
} else if (hold_unlock(resource))
return errno;
}
}
}
return 0;
@ -689,6 +696,8 @@ void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
}
pthread_mutex_lock(&lvm_lock);
init_test((lock_flags & LCK_TEST_MODE) ? 1 : 0);
switch (lock_cmd) {
case LCK_VG_COMMIT:
DEBUGLOG("vg_commit notification for VG %s\n", vgname);
@ -703,6 +712,8 @@ void do_lock_vg(unsigned char command, unsigned char lock_flags, char *resource)
DEBUGLOG("Invalidating cached metadata for VG %s\n", vgname);
lvmcache_drop_metadata(vgname, 0);
}
init_test(0);
pthread_mutex_unlock(&lvm_lock);
}
@ -714,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;
@ -916,6 +927,6 @@ void destroy_lvm(void)
if (cmd) {
memlock_dec_daemon(cmd);
destroy_toolcontext(cmd);
cmd = NULL;
}
cmd = NULL;
}

View File

@ -28,7 +28,8 @@ include $(top_builddir)/make.tmpl
LIBS += -ldevmapper
LMLIBS += $(CPG_LIBS) $(SACKPT_LIBS)
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS)
CFLAGS += $(CPG_CFLAGS) $(SACKPT_CFLAGS) $(EXTRA_EXEC_CFLAGS)
LDFLAGS += $(EXTRA_EXEC_LDFLAGS)
cmirrord: $(OBJECTS) $(top_builddir)/lib/liblvm-internal.a
$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $(OBJECTS) \

View File

@ -25,7 +25,6 @@
#if CMIRROR_HAS_CHECKPOINT
#include <openais/saAis.h>
#include <openais/saCkpt.h>
#endif
/* Open AIS error codes */
#define str_ais_error(x) \
@ -57,6 +56,40 @@
((x) == SA_AIS_ERR_TOO_BIG) ? "SA_AIS_ERR_TOO_BIG" : \
((x) == SA_AIS_ERR_NO_SECTIONS) ? "SA_AIS_ERR_NO_SECTIONS" : \
"ais_error_unknown"
#else
#define str_ais_error(x) \
((x) == CS_OK) ? "CS_OK" : \
((x) == CS_ERR_LIBRARY) ? "CS_ERR_LIBRARY" : \
((x) == CS_ERR_VERSION) ? "CS_ERR_VERSION" : \
((x) == CS_ERR_INIT) ? "CS_ERR_INIT" : \
((x) == CS_ERR_TIMEOUT) ? "CS_ERR_TIMEOUT" : \
((x) == CS_ERR_TRY_AGAIN) ? "CS_ERR_TRY_AGAIN" : \
((x) == CS_ERR_INVALID_PARAM) ? "CS_ERR_INVALID_PARAM" : \
((x) == CS_ERR_NO_MEMORY) ? "CS_ERR_NO_MEMORY" : \
((x) == CS_ERR_BAD_HANDLE) ? "CS_ERR_BAD_HANDLE" : \
((x) == CS_ERR_BUSY) ? "CS_ERR_BUSY" : \
((x) == CS_ERR_ACCESS) ? "CS_ERR_ACCESS" : \
((x) == CS_ERR_NOT_EXIST) ? "CS_ERR_NOT_EXIST" : \
((x) == CS_ERR_NAME_TOO_LONG) ? "CS_ERR_NAME_TOO_LONG" : \
((x) == CS_ERR_EXIST) ? "CS_ERR_EXIST" : \
((x) == CS_ERR_NO_SPACE) ? "CS_ERR_NO_SPACE" : \
((x) == CS_ERR_INTERRUPT) ? "CS_ERR_INTERRUPT" : \
((x) == CS_ERR_NAME_NOT_FOUND) ? "CS_ERR_NAME_NOT_FOUND" : \
((x) == CS_ERR_NO_RESOURCES) ? "CS_ERR_NO_RESOURCES" : \
((x) == CS_ERR_NOT_SUPPORTED) ? "CS_ERR_NOT_SUPPORTED" : \
((x) == CS_ERR_BAD_OPERATION) ? "CS_ERR_BAD_OPERATION" : \
((x) == CS_ERR_FAILED_OPERATION) ? "CS_ERR_FAILED_OPERATION" : \
((x) == CS_ERR_MESSAGE_ERROR) ? "CS_ERR_MESSAGE_ERROR" : \
((x) == CS_ERR_QUEUE_FULL) ? "CS_ERR_QUEUE_FULL" : \
((x) == CS_ERR_QUEUE_NOT_AVAILABLE) ? "CS_ERR_QUEUE_NOT_AVAILABLE" : \
((x) == CS_ERR_BAD_FLAGS) ? "CS_ERR_BAD_FLAGS" : \
((x) == CS_ERR_TOO_BIG) ? "CS_ERR_TOO_BIG" : \
((x) == CS_ERR_NO_SECTIONS) ? "CS_ERR_NO_SECTIONS" : \
((x) == CS_ERR_CONTEXT_NOT_FOUND) ? "CS_ERR_CONTEXT_NOT_FOUND" : \
((x) == CS_ERR_TOO_MANY_GROUPS) ? "CS_ERR_TOO_MANY_GROUPS" : \
((x) == CS_ERR_SECURITY) ? "CS_ERR_SECURITY" : \
"cs_error_unknown"
#endif
#define _RQ_TYPE(x) \
((x) == DM_ULOG_CHECKPOINT_READY) ? "DM_ULOG_CHECKPOINT_READY": \
@ -803,6 +836,11 @@ static int import_checkpoint(struct clog_cpg *entry, int no_read,
{
int bitmap_size;
if (no_read) {
LOG_DBG("Checkpoint for this log already received");
return 0;
}
bitmap_size = (rq->u_rq.data_size - RECOVERING_REGION_SECTION_SIZE) / 2;
if (bitmap_size < 0) {
LOG_ERROR("Checkpoint has invalid payload size.");
@ -946,8 +984,16 @@ static int do_cluster_work(void *data __attribute__((unused)))
dm_list_iterate_items_safe(entry, tmp, &clog_cpg_list) {
r = cpg_dispatch(entry->handle, CS_DISPATCH_ALL);
if (r != CS_OK)
LOG_ERROR("cpg_dispatch failed: %d", r);
if (r != CS_OK) {
if ((r == CS_ERR_BAD_HANDLE) &&
((entry->state == INVALID) ||
(entry->state == LEAVING)))
/* It's ok if we've left the cluster */
r = CS_OK;
else
LOG_ERROR("cpg_dispatch failed: %s",
str_ais_error(r));
}
if (entry->free_me) {
free(entry);

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);
@ -187,7 +188,7 @@ int clog_request_from_network(void *data, size_t data_len)
switch (version) {
case 5: /* Upstream */
if (version == unconverted_version)
if (version == vp[0])
return 0;
break;
case 4: /* RHEL 5.[45] */

View File

@ -63,7 +63,7 @@ extern int log_resend_requests;
#ifdef DEBUG
#define LOG_DBG(f, arg...) LOG_OUTPUT(LOG_DEBUG, f, ## arg)
#else /* DEBUG */
#define LOG_DBG(f, arg...)
#define LOG_DBG(f, arg...) do {} while (0)
#endif /* DEBUG */
#define LOG_COND(__X, f, arg...) do {\

View File

@ -59,8 +59,10 @@ device-mapper: $(TARGETS)
LIBS += -ldevmapper
LVMLIBS += -ldevmapper-event $(PTHREAD_LIBS)
CFLAGS_dmeventd.o += $(EXTRA_EXEC_CFLAGS)
dmeventd: $(LIB_SHARED) dmeventd.o
$(CC) $(CFLAGS) $(LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
$(CC) $(CFLAGS) $(LDFLAGS) $(EXTRA_EXEC_LDFLAGS) $(ELDFLAGS) -L. -o $@ dmeventd.o \
$(DL_LIBS) $(LVMLIBS) $(LIBS) -rdynamic
dmeventd.static: $(LIB_STATIC) dmeventd.o $(interfacebuilddir)/libdevmapper.a

View File

@ -26,6 +26,7 @@
//#include "libmultilog.h"
#include "dm-logging.h"
#include <stdarg.h>
#include <dlfcn.h>
#include <errno.h>
#include <pthread.h>
@ -39,7 +40,7 @@
#include <arpa/inet.h> /* for htonl, ntohl */
#include <fcntl.h> /* for musl libc */
#ifdef linux
#ifdef __linux__
/*
* Kernel version 2.6.36 and higher has
* new OOM killer adjustment interface.
@ -55,6 +56,7 @@
# define OOM_SCORE_ADJ_MIN (-1000)
/* Systemd on-demand activation support */
# define SD_RUNTIME_UNIT_FILE_DIR DEFAULT_DM_RUN_DIR "/systemd/system/"
# define SD_ACTIVATION_ENV_VAR_NAME "SD_ACTIVATION"
# define SD_LISTEN_PID_ENV_VAR_NAME "LISTEN_PID"
# define SD_LISTEN_FDS_ENV_VAR_NAME "LISTEN_FDS"
@ -216,9 +218,9 @@ static pthread_cond_t _timeout_cond = PTHREAD_COND_INITIALIZER;
static struct thread_status *_alloc_thread_status(const struct message_data *data,
struct dso_data *dso_data)
{
struct thread_status *ret = (typeof(ret)) dm_zalloc(sizeof(*ret));
struct thread_status *ret;
if (!ret)
if (!(ret = dm_zalloc(sizeof(*ret))))
return NULL;
if (!(ret->device.uuid = dm_strdup(data->device_uuid))) {
@ -226,9 +228,6 @@ static struct thread_status *_alloc_thread_status(const struct message_data *dat
return NULL;
}
ret->current_task = NULL;
ret->device.name = NULL;
ret->device.major = ret->device.minor = 0;
ret->dso_data = dso_data;
ret->events = data->events_field;
ret->timeout = data->timeout_secs;
@ -273,7 +272,6 @@ static int _pthread_create_smallstack(pthread_t *t, void *(*fun)(void *), void *
int r;
pthread_t tmp;
pthread_attr_t attr;
pthread_attr_init(&attr);
/*
* From pthread_attr_init man page:
@ -384,7 +382,6 @@ static int _parse_message(struct message_data *message_data)
dm_free(msg->data);
msg->data = NULL;
msg->size = 0;
return ret;
}
@ -406,15 +403,12 @@ static int _fill_device_data(struct thread_status *ts)
{
struct dm_task *dmt;
struct dm_info dmi;
int ret = 0;
if (!ts->device.uuid)
return 0;
ts->device.name = NULL;
ts->device.major = ts->device.minor = 0;
dmt = dm_task_create(DM_DEVICE_INFO);
if (!dmt)
if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
return 0;
if (!dm_task_set_uuid(dmt, ts->device.uuid))
@ -423,8 +417,8 @@ static int _fill_device_data(struct thread_status *ts)
if (!dm_task_run(dmt))
goto fail;
ts->device.name = dm_strdup(dm_task_get_name(dmt));
if (!ts->device.name)
dm_free(ts->device.name);
if (!(ts->device.name = dm_strdup(dm_task_get_name(dmt))))
goto fail;
if (!dm_task_get_info(dmt, &dmi))
@ -432,16 +426,11 @@ static int _fill_device_data(struct thread_status *ts)
ts->device.major = dmi.major;
ts->device.minor = dmi.minor;
ret = 1;
fail:
dm_task_destroy(dmt);
return 1;
fail:
dm_task_destroy(dmt);
dm_free(ts->device.name);
ts->device.name = NULL;
return 0;
return ret;
}
/*
@ -464,20 +453,17 @@ static int _get_status(struct message_data *message_data)
{
struct dm_event_daemon_message *msg = message_data->msg;
struct thread_status *thread;
int i, j;
int ret = -1;
int count = dm_list_size(&_thread_registry);
int size = 0, current = 0;
char *buffers[count];
int i = 0, j;
int ret = -ENOMEM;
int count;
int size = 0, current;
size_t len;
char **buffers;
char *message;
dm_free(msg->data);
for (i = 0; i < count; ++i)
buffers[i] = NULL;
i = 0;
_lock_mutex();
count = dm_list_size(&_thread_registry);
buffers = alloca(sizeof(char*) * count);
dm_list_iterate_items(thread, &_thread_registry) {
if ((current = dm_asprintf(buffers + i, "0:%d %s %s %u %" PRIu32 ";",
i, thread->dso_data->dso_name,
@ -486,33 +472,50 @@ static int _get_status(struct message_data *message_data)
_unlock_mutex();
goto out;
}
++ i;
size += current;
++i;
size += current; /* count with trailing '\0' */
}
_unlock_mutex();
msg->size = size + strlen(message_data->id) + 1;
msg->data = dm_malloc(msg->size);
if (!msg->data)
len = strlen(message_data->id);
msg->size = size + len + 1;
dm_free(msg->data);
if (!(msg->data = dm_malloc(msg->size)))
goto out;
*msg->data = 0;
message = msg->data;
strcpy(message, message_data->id);
message += strlen(message_data->id);
*message = ' ';
message ++;
memcpy(msg->data, message_data->id, len);
message = msg->data + len;
*message++ = ' ';
for (j = 0; j < i; ++j) {
strcpy(message, buffers[j]);
message += strlen(buffers[j]);
len = strlen(buffers[j]);
memcpy(message, buffers[j], len);
message += len;
}
ret = 0;
out:
for (j = 0; j < i; ++j)
dm_free(buffers[j]);
return ret;
return ret;
}
static int _get_parameters(struct message_data *message_data) {
struct dm_event_daemon_message *msg = message_data->msg;
int size;
dm_free(msg->data);
if ((size = dm_asprintf(&msg->data, "%s pid=%d daemon=%s exec_method=%s",
message_data->id, getpid(),
_foreground ? "no" : "yes",
_systemd_activation ? "systemd" : "direct")) < 0) {
stack;
return -ENOMEM;
}
msg->size = (uint32_t) size;
return 0;
}
/* Cleanup at exit. */
@ -568,9 +571,8 @@ static int _register_for_timeout(struct thread_status *thread)
pthread_mutex_lock(&_timeout_mutex);
thread->next_time = time(NULL) + thread->timeout;
if (dm_list_empty(&thread->timeout_list)) {
thread->next_time = time(NULL) + thread->timeout;
dm_list_add(&_timeout_registry, &thread->timeout_list);
if (_timeout_running)
pthread_cond_signal(&_timeout_cond);
@ -591,6 +593,9 @@ static void _unregister_for_timeout(struct thread_status *thread)
if (!dm_list_empty(&thread->timeout_list)) {
dm_list_del(&thread->timeout_list);
dm_list_init(&thread->timeout_list);
if (dm_list_empty(&_timeout_registry))
/* No more work -> wakeup to finish quickly */
pthread_cond_signal(&_timeout_cond);
}
pthread_mutex_unlock(&_timeout_mutex);
}
@ -607,18 +612,10 @@ static void _no_intr_log(int level, const char *file, int line,
return;
va_start(ap, f);
if (level < _LOG_WARN)
vfprintf(stderr, f, ap);
else
vprintf(f, ap);
vfprintf((level < _LOG_WARN) ? stderr : stdout, f, ap);
va_end(ap);
if (level < _LOG_WARN)
fprintf(stderr, "\n");
else
fprintf(stdout, "\n");
fputc('\n', (level < _LOG_WARN) ? stderr : stdout);
}
static sigset_t _unblock_sigalrm(void)
@ -638,6 +635,7 @@ static sigset_t _unblock_sigalrm(void)
/* Wait on a device until an event occurs. */
static int _event_wait(struct thread_status *thread, struct dm_task **task)
{
static unsigned _in_event_counter = 0;
sigset_t set;
int ret = DM_WAIT_RETRY;
struct dm_task *dmt;
@ -654,12 +652,20 @@ static int _event_wait(struct thread_status *thread, struct dm_task **task)
!dm_task_set_event_nr(dmt, thread->event_nr))
goto out;
_lock_mutex();
/*
* Check if there are already some waiting events,
* in this case the logging is unmodified.
* TODO: audit libdm thread usage
*/
if (!_in_event_counter++)
dm_log_init(_no_intr_log);
_unlock_mutex();
/*
* This is so that you can break out of waiting on an event,
* either for a timeout event, or to cancel the thread.
*/
set = _unblock_sigalrm();
dm_log_init(_no_intr_log);
errno = 0;
if (dm_task_run(dmt)) {
thread->current_events |= DM_EVENT_DEVICE_ERROR;
@ -683,7 +689,10 @@ static int _event_wait(struct thread_status *thread, struct dm_task **task)
}
pthread_sigmask(SIG_SETMASK, &set, NULL);
dm_log_init(NULL);
_lock_mutex();
if (--_in_event_counter == 0)
dm_log_init(NULL);
_unlock_mutex();
out:
if (ret == DM_WAIT_FATAL || ret == DM_WAIT_RETRY) {
@ -752,10 +761,8 @@ static void _monitor_unregister(void *arg)
return;
}
thread->status = DM_THREAD_DONE;
pthread_mutex_lock(&_timeout_mutex);
UNLINK_THREAD(thread);
LINK(thread, &_thread_registry_unused);
pthread_mutex_unlock(&_timeout_mutex);
_unlock_mutex();
}
@ -783,7 +790,7 @@ static struct dm_task *_get_device_status(struct thread_status *ts)
static void *_monitor_thread(void *arg)
{
struct thread_status *thread = arg;
int wait_error = 0;
int wait_error;
struct dm_task *task;
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
@ -799,8 +806,10 @@ static void *_monitor_thread(void *arg)
thread->current_events = 0;
wait_error = _event_wait(thread, &task);
if (wait_error == DM_WAIT_RETRY)
if (wait_error == DM_WAIT_RETRY) {
usleep(100); /* avoid busy loop */
continue;
}
if (wait_error == DM_WAIT_FATAL)
break;
@ -835,10 +844,8 @@ static void *_monitor_thread(void *arg)
_unlock_mutex();
break;
}
_unlock_mutex();
if (thread->events & thread->current_events) {
_lock_mutex();
thread->processing = 1;
_unlock_mutex();
@ -850,6 +857,7 @@ static void *_monitor_thread(void *arg)
thread->processing = 0;
_unlock_mutex();
} else {
_unlock_mutex();
dm_task_destroy(task);
thread->current_task = NULL;
}
@ -892,11 +900,11 @@ static struct dso_data *_lookup_dso(struct message_data *data)
struct dso_data *dso_data, *ret = NULL;
dm_list_iterate_items(dso_data, &_dso_registry)
if (!strcmp(data->dso_name, dso_data->dso_name)) {
_lib_get(dso_data);
ret = dso_data;
break;
}
if (!strcmp(data->dso_name, dso_data->dso_name)) {
_lib_get(dso_data);
ret = dso_data;
break;
}
return ret;
}
@ -924,7 +932,7 @@ static int lookup_symbols(void *dl, struct dso_data *data)
static struct dso_data *_load_dso(struct message_data *data)
{
void *dl;
struct dso_data *ret = NULL;
struct dso_data *ret;
if (!(dl = dlopen(data->dso_name, RTLD_NOW))) {
const char *dlerr = dlerror();
@ -1003,8 +1011,6 @@ static int _register_for_event(struct message_data *message_data)
goto out;
}
_lock_mutex();
/* If creation of timeout thread fails (as it may), we fail
here completely. The client is responsible for either
retrying later or trying to register without timeout
@ -1013,8 +1019,9 @@ static int _register_for_event(struct message_data *message_data)
almost as good as dead already... */
if ((thread_new->events & DM_EVENT_TIMEOUT) &&
(ret = -_register_for_timeout(thread_new)))
goto outth;
goto out;
_lock_mutex();
if (!(thread = _lookup_thread_status(message_data))) {
_unlock_mutex();
@ -1038,8 +1045,6 @@ static int _register_for_event(struct message_data *message_data)
/* Or event # into events bitfield. */
thread->events |= message_data->events_field;
outth:
_unlock_mutex();
out:
@ -1084,17 +1089,18 @@ static int _unregister_for_event(struct message_data *message_data)
thread->events &= ~message_data->events_field;
if (!(thread->events & DM_EVENT_TIMEOUT))
if (!(thread->events & DM_EVENT_TIMEOUT)) {
_unlock_mutex();
_unregister_for_timeout(thread);
_lock_mutex();
}
/*
* In case there's no events to monitor on this device ->
* unlink and terminate its monitoring thread.
*/
if (!thread->events) {
pthread_mutex_lock(&_timeout_mutex);
UNLINK_THREAD(thread);
LINK(thread, &_thread_registry_unused);
pthread_mutex_unlock(&_timeout_mutex);
}
_unlock_mutex();
@ -1110,23 +1116,19 @@ static int _unregister_for_event(struct message_data *message_data)
static int _registered_device(struct message_data *message_data,
struct thread_status *thread)
{
struct dm_event_daemon_message *msg = message_data->msg;
const char *fmt = "%s %s %s %u";
const char *id = message_data->id;
const char *dso = thread->dso_data->dso_name;
const char *dev = thread->device.uuid;
int r;
struct dm_event_daemon_message *msg = message_data->msg;
unsigned events = ((thread->status == DM_THREAD_RUNNING) &&
thread->events) ? thread->events :
thread->events | DM_EVENT_REGISTRATION_PENDING;
dm_free(msg->data);
if ((r = dm_asprintf(&(msg->data), fmt, id, dso, dev, events)) < 0) {
msg->size = 0;
if ((r = dm_asprintf(&(msg->data), "%s %s %s %u",
message_data->id,
thread->dso_data->dso_name,
thread->device.uuid, events)) < 0)
return -ENOMEM;
}
msg->size = (uint32_t) r;
@ -1235,28 +1237,16 @@ static int _get_timeout(struct message_data *message_data)
_lock_mutex();
if ((thread = _lookup_thread_status(message_data))) {
msg->size =
dm_asprintf(&(msg->data), "%s %" PRIu32, message_data->id,
thread->timeout);
} else {
msg->size = dm_asprintf(&(msg->data), "%s %" PRIu32,
message_data->id, thread->timeout);
} else
msg->data = NULL;
msg->size = 0;
}
_unlock_mutex();
return thread ? 0 : -ENODEV;
}
/* Initialize a fifos structure with path names. */
static void _init_fifos(struct dm_event_fifos *fifos)
{
fifos->client = -1;
fifos->server = -1;
fifos->client_path = DM_EVENT_FIFO_CLIENT;
fifos->server_path = DM_EVENT_FIFO_SERVER;
}
/* Open fifos used for client communication. */
static int _open_fifos(struct dm_event_fifos *fifos)
{
@ -1390,10 +1380,10 @@ static int _client_read(struct dm_event_fifos *fifos,
if (bytes != size) {
dm_free(msg->data);
msg->data = NULL;
msg->size = 0;
return 0;
}
return bytes == size;
return 1;
}
/*
@ -1402,33 +1392,45 @@ static int _client_read(struct dm_event_fifos *fifos,
static int _client_write(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg)
{
uint32_t temp[2];
unsigned bytes = 0;
int ret = 0;
fd_set fds;
size_t size = 2 * sizeof(uint32_t) + msg->size;
uint32_t *header = alloca(size);
size_t size = 2 * sizeof(uint32_t) + ((msg->data) ? msg->size : 0);
uint32_t *header = dm_malloc(size);
char *buf = (char *)header;
header[0] = htonl(msg->cmd);
header[1] = htonl(msg->size);
if (msg->data)
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
if (!header) {
/* Reply with ENOMEM message */
header = temp;
size = sizeof(temp);
header[0] = htonl(-ENOMEM);
header[1] = 0;
} else {
header[0] = htonl(msg->cmd);
header[1] = htonl((msg->data) ? msg->size : 0);
if (msg->data)
memcpy(buf + 2 * sizeof(uint32_t), msg->data, msg->size);
}
errno = 0;
while (bytes < size && errno != EIO) {
while (bytes < size) {
do {
/* Watch client write FIFO to be ready for output. */
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
} while (select(fifos->server + 1, NULL, &fds, NULL, NULL) !=
1);
} while (select(fifos->server + 1, NULL, &fds, NULL, NULL) != 1);
ret = write(fifos->server, buf + bytes, size - bytes);
bytes += ret > 0 ? ret : 0;
if ((ret = write(fifos->server, buf + bytes, size - bytes)) > 0)
bytes += ret;
else if (errno == EIO)
break;
}
return bytes == size;
if (header != temp)
dm_free(header);
return (bytes == size);
}
/*
@ -1440,26 +1442,35 @@ static int _client_write(struct dm_event_fifos *fifos,
static int _handle_request(struct dm_event_daemon_message *msg,
struct message_data *message_data)
{
static struct request {
unsigned int cmd;
int (*f)(struct message_data *);
} requests[] = {
{ DM_EVENT_CMD_REGISTER_FOR_EVENT, _register_for_event},
{ DM_EVENT_CMD_UNREGISTER_FOR_EVENT, _unregister_for_event},
{ DM_EVENT_CMD_GET_REGISTERED_DEVICE, _get_registered_device},
{ DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE,
_get_next_registered_device},
{ DM_EVENT_CMD_SET_TIMEOUT, _set_timeout},
{ DM_EVENT_CMD_GET_TIMEOUT, _get_timeout},
{ DM_EVENT_CMD_ACTIVE, _active},
{ DM_EVENT_CMD_GET_STATUS, _get_status},
}, *req;
for (req = requests; req < requests + sizeof(requests) / sizeof(struct request); req++)
if (req->cmd == msg->cmd)
return req->f(message_data);
return -EINVAL;
switch (msg->cmd) {
case DM_EVENT_CMD_REGISTER_FOR_EVENT:
return _register_for_event(message_data);
case DM_EVENT_CMD_UNREGISTER_FOR_EVENT:
return _unregister_for_event(message_data);
case DM_EVENT_CMD_GET_REGISTERED_DEVICE:
return _get_registered_device(message_data);
case DM_EVENT_CMD_GET_NEXT_REGISTERED_DEVICE:
return _get_next_registered_device(message_data);
case DM_EVENT_CMD_SET_TIMEOUT:
return _set_timeout(message_data);
case DM_EVENT_CMD_GET_TIMEOUT:
return _get_timeout(message_data);
case DM_EVENT_CMD_ACTIVE:
return _active(message_data);
case DM_EVENT_CMD_GET_STATUS:
return _get_status(message_data);
/* dmeventd parameters of running dmeventd,
* returns 'pid=<pid> daemon=<no/yes> exec_method=<direct/systemd>'
* pid - pidfile of running dmeventd
* daemon - running as a daemon or not (foreground)?
* exec_method - "direct" if executed directly or
* "systemd" if executed via systemd
*/
case DM_EVENT_CMD_GET_PARAMETERS:
return _get_parameters(message_data);
default:
return -EINVAL;
}
}
/* Process a request passed from the communication thread. */
@ -1475,11 +1486,10 @@ static int _do_process_request(struct dm_event_daemon_message *msg)
answer = msg->data;
if (answer) {
msg->size = dm_asprintf(&(msg->data), "%s %s %d", answer,
msg->cmd == DM_EVENT_CMD_DIE ? "DYING" : "HELLO",
(msg->cmd == DM_EVENT_CMD_DIE) ? "DYING" : "HELLO",
DM_EVENT_PROTOCOL_VERSION);
dm_free(answer);
} else
msg->size = 0;
}
} else if (msg->cmd != DM_EVENT_CMD_ACTIVE && !_parse_message(&message_data)) {
stack;
ret = -EINVAL;
@ -1498,7 +1508,7 @@ static int _do_process_request(struct dm_event_daemon_message *msg)
/* Only one caller at a time. */
static void _process_request(struct dm_event_fifos *fifos)
{
int die = 0;
int die;
struct dm_event_daemon_message msg = { 0 };
/*
@ -1508,8 +1518,7 @@ static void _process_request(struct dm_event_fifos *fifos)
if (!_client_read(fifos, &msg))
return;
if (msg.cmd == DM_EVENT_CMD_DIE)
die = 1;
die = (msg.cmd == DM_EVENT_CMD_DIE) ? 1 : 0;
/* _do_process_request fills in msg (if memory allows for
data, otherwise just cmd and size = 0) */
@ -1520,7 +1529,11 @@ static void _process_request(struct dm_event_fifos *fifos)
dm_free(msg.data);
if (die) raise(9);
if (die) {
if (unlink(DMEVENTD_PIDFILE))
perror(DMEVENTD_PIDFILE ": unlink failed");
_exit(0);
}
}
static void _process_initial_registrations(void)
@ -1583,8 +1596,10 @@ static void _cleanup_unused_threads(void)
if (thread->status == DM_THREAD_DONE) {
dm_list_del(l);
_unlock_mutex();
join_ret = pthread_join(thread->thread, NULL);
_free_thread_status(thread);
_lock_mutex();
}
}
@ -1629,7 +1644,7 @@ static void _exit_handler(int sig __attribute__((unused)))
_exit_now = 1;
}
#ifdef linux
#ifdef __linux__
static int _set_oom_adj(const char *oom_adj_path, int val)
{
FILE *fp;
@ -1706,8 +1721,6 @@ static int _systemd_handover(struct dm_event_fifos *fifos)
unsigned long env_pid, env_listen_fds;
int r = 0;
memset(fifos, 0, sizeof(*fifos));
/* SD_ACTIVATION must be set! */
if (!(e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) || strcmp(e, "1"))
goto out;
@ -1748,6 +1761,7 @@ out:
unsetenv(SD_LISTEN_FDS_ENV_VAR_NAME);
return r;
}
#endif
static void _remove_files_on_exit(void)
@ -1822,7 +1836,7 @@ static void _daemonize(void)
fd = rlim.rlim_cur;
for (--fd; fd >= 0; fd--) {
#ifdef linux
#ifdef __linux__
/* Do not close fds preloaded by systemd! */
if (_systemd_activation &&
(fd == SD_FD_FIFO_SERVER || fd == SD_FD_FIFO_CLIENT))
@ -1839,17 +1853,75 @@ static void _daemonize(void)
setsid();
}
static int _reinstate_registrations(struct dm_event_fifos *fifos)
{
static const char _failed_parsing_msg[] = "Failed to parse existing event registration.\n";
static const char *_delim = " ";
struct dm_event_daemon_message msg = { 0 };
char *endp, *dso_name, *dev_name, *mask, *timeout;
unsigned long mask_value, timeout_value;
int i, ret;
ret = daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0);
dm_free(msg.data);
msg.data = NULL;
if (ret) {
fprintf(stderr, "Failed to communicate with new instance of dmeventd.\n");
return 0;
}
for (i = 0; _initial_registrations[i]; ++i) {
if (!(strtok(_initial_registrations[i], _delim)) ||
!(dso_name = strtok(NULL, _delim)) ||
!(dev_name = strtok(NULL, _delim)) ||
!(mask = strtok(NULL, _delim)) ||
!(timeout = strtok(NULL, _delim))) {
fprintf(stderr, _failed_parsing_msg);
continue;
}
errno = 0;
mask_value = strtoul(mask, &endp, 10);
if (errno || !endp || *endp) {
fprintf(stderr, _failed_parsing_msg);
continue;
}
errno = 0;
timeout_value = strtoul(timeout, &endp, 10);
if (errno || !endp || *endp) {
fprintf(stderr, _failed_parsing_msg);
continue;
}
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_REGISTER_FOR_EVENT,
dso_name,
dev_name,
(enum dm_event_mask) mask_value,
timeout_value))
fprintf(stderr, "Failed to reinstate monitoring for device %s.\n", dev_name);
}
return 1;
}
static void restart(void)
{
struct dm_event_fifos fifos = { 0 };
struct dm_event_fifos fifos = {
.server = -1,
.client = -1,
/* FIXME Make these either configurable or depend directly on dmeventd_path */
.client_path = DM_EVENT_FIFO_CLIENT,
.server_path = DM_EVENT_FIFO_SERVER
};
struct dm_event_daemon_message msg = { 0 };
int i, count = 0;
char *message;
int length;
int version;
const char *e;
/* Get the list of registrations from the running daemon. */
if (!init_fifos(&fifos)) {
fprintf(stderr, "WARNING: Could not initiate communication with existing dmeventd.\n");
exit(EXIT_FAILURE);
@ -1857,62 +1929,98 @@ static void restart(void)
if (!dm_event_get_version(&fifos, &version)) {
fprintf(stderr, "WARNING: Could not communicate with existing dmeventd.\n");
fini_fifos(&fifos);
exit(EXIT_FAILURE);
goto bad;
}
if (version < 1) {
fprintf(stderr, "WARNING: The running dmeventd instance is too old.\n"
"Protocol version %d (required: 1). Action cancelled.\n",
version);
exit(EXIT_FAILURE);
goto bad;
}
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0)) {
exit(EXIT_FAILURE);
}
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_STATUS, "-", "-", 0, 0))
goto bad;
message = msg.data;
message = strchr(message, ' ');
++ message;
length = strlen(msg.data);
for (i = 0; i < length; ++i) {
message = strchr(msg.data, ' ') + 1;
for (i = 0; msg.data[i]; ++i)
if (msg.data[i] == ';') {
msg.data[i] = 0;
++count;
}
}
if (!(_initial_registrations = dm_malloc(sizeof(char*) * (count + 1)))) {
fprintf(stderr, "Memory allocation registration failed.\n");
exit(EXIT_FAILURE);
goto bad;
}
for (i = 0; i < count; ++i) {
if (!(_initial_registrations[i] = dm_strdup(message))) {
fprintf(stderr, "Memory allocation for message failed.\n");
exit(EXIT_FAILURE);
goto bad;
}
message += strlen(message) + 1;
}
_initial_registrations[count] = 0;
_initial_registrations[count] = NULL;
if (version >= 2) {
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_GET_PARAMETERS, "-", "-", 0, 0)) {
fprintf(stderr, "Failed to acquire parameters from old dmeventd.\n");
goto bad;
}
if (strstr(msg.data, "exec_method=systemd"))
_systemd_activation = 1;
}
#ifdef __linux__
/*
* If the protocol version is old, just assume that if systemd is running,
* the dmeventd is also run as a systemd service via fifo activation.
*/
if (version < 2) {
/* This check is copied from sd-daemon.c. */
struct stat st;
if (!lstat(SD_RUNTIME_UNIT_FILE_DIR, &st) && !!S_ISDIR(st.st_mode))
_systemd_activation = 1;
}
#endif
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0)) {
fprintf(stderr, "Old dmeventd refused to die.\n");
exit(EXIT_FAILURE);
goto bad;
}
/*
* Wait for daemon to die, detected by sending further DIE messages
* until one fails.
*/
if (!_systemd_activation &&
((e = getenv(SD_ACTIVATION_ENV_VAR_NAME)) && strcmp(e, "1")))
_systemd_activation = 1;
for (i = 0; i < 10; ++i) {
if (daemon_talk(&fifos, &msg, DM_EVENT_CMD_DIE, "-", "-", 0, 0))
break; /* yep, it's dead probably */
if ((access(DMEVENTD_PIDFILE, F_OK) == -1) && (errno == ENOENT))
break;
usleep(10);
}
if (!_systemd_activation) {
fini_fifos(&fifos);
return;
}
/* Reopen fifos. */
fini_fifos(&fifos);
if (!init_fifos(&fifos)) {
fprintf(stderr, "Could not initiate communication with new instance of dmeventd.\n");
exit(EXIT_FAILURE);
}
if (!_reinstate_registrations(&fifos)) {
fprintf(stderr, "Failed to reinstate monitoring with new instance of dmeventd.\n");
goto bad;
}
fini_fifos(&fifos);
exit(EXIT_SUCCESS);
bad:
fini_fifos(&fifos);
exit(EXIT_FAILURE);
}
static void usage(char *prog, FILE *file)
@ -1929,7 +2037,12 @@ static void usage(char *prog, FILE *file)
int main(int argc, char *argv[])
{
signed char opt;
struct dm_event_fifos fifos;
struct dm_event_fifos fifos = {
.client = -1,
.server = -1,
.client_path = DM_EVENT_FIFO_CLIENT,
.server_path = DM_EVENT_FIFO_SERVER
};
int nothreads;
//struct sys_log logdata = {DAEMON_NAME, LOG_DAEMON};
@ -1970,7 +2083,7 @@ int main(int argc, char *argv[])
if (_restart)
restart();
#ifdef linux
#ifdef __linux__
_systemd_activation = _systemd_handover(&fifos);
#endif
@ -1992,7 +2105,7 @@ int main(int argc, char *argv[])
signal(SIGHUP, &_exit_handler);
signal(SIGQUIT, &_exit_handler);
#ifdef linux
#ifdef __linux__
/* Systemd has adjusted oom killer for us already */
if (!_systemd_activation && !_protect_against_oom_killer())
syslog(LOG_ERR, "Failed to protect against OOM killer");
@ -2005,9 +2118,6 @@ int main(int argc, char *argv[])
//multilog_init_verbose(std_syslog, _LOG_DEBUG);
//multilog_async(1);
if (!_systemd_activation)
_init_fifos(&fifos);
pthread_mutex_init(&_global_mutex, NULL);
if (!_systemd_activation && !_open_fifos(&fifos))

View File

@ -34,6 +34,7 @@ enum dm_event_command {
DM_EVENT_CMD_HELLO,
DM_EVENT_CMD_DIE,
DM_EVENT_CMD_GET_STATUS,
DM_EVENT_CMD_GET_PARAMETERS,
};
/* Message passed between client and daemon. */

View File

@ -20,7 +20,6 @@
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <sys/file.h>
@ -57,7 +56,7 @@ static void _dm_event_handler_clear_dev_info(struct dm_event_handler *dmevh)
struct dm_event_handler *dm_event_handler_create(void)
{
struct dm_event_handler *dmevh = NULL;
struct dm_event_handler *dmevh;
if (!(dmevh = dm_zalloc(sizeof(*dmevh)))) {
log_error("Failed to allocate event handler.");
@ -82,8 +81,7 @@ int dm_event_handler_set_dmeventd_path(struct dm_event_handler *dmevh, const cha
dm_free(dmevh->dmeventd_path);
dmevh->dmeventd_path = dm_strdup(dmeventd_path);
if (!dmevh->dmeventd_path)
if (!(dmevh->dmeventd_path = dm_strdup(dmeventd_path)))
return -ENOMEM;
return 0;
@ -93,10 +91,10 @@ int dm_event_handler_set_dso(struct dm_event_handler *dmevh, const char *path)
{
if (!path) /* noop */
return 0;
dm_free(dmevh->dso);
dmevh->dso = dm_strdup(path);
if (!dmevh->dso)
if (!(dmevh->dso = dm_strdup(path)))
return -ENOMEM;
return 0;
@ -109,9 +107,9 @@ int dm_event_handler_set_dev_name(struct dm_event_handler *dmevh, const char *de
_dm_event_handler_clear_dev_info(dmevh);
dmevh->dev_name = dm_strdup(dev_name);
if (!dmevh->dev_name)
if (!(dmevh->dev_name = dm_strdup(dev_name)))
return -ENOMEM;
return 0;
}
@ -122,9 +120,9 @@ int dm_event_handler_set_uuid(struct dm_event_handler *dmevh, const char *uuid)
_dm_event_handler_clear_dev_info(dmevh);
dmevh->uuid = dm_strdup(uuid);
if (!dmevh->uuid)
if (!(dmevh->uuid = dm_strdup(uuid)))
return -ENOMEM;
return 0;
}
@ -224,7 +222,6 @@ static int _daemon_read(struct dm_event_fifos *fifos,
unsigned bytes = 0;
int ret, i;
fd_set fds;
struct timeval tval = { 0, 0 };
size_t size = 2 * sizeof(uint32_t); /* status + size */
uint32_t *header = alloca(size);
char *buf = (char *)header;
@ -232,11 +229,10 @@ static int _daemon_read(struct dm_event_fifos *fifos,
while (bytes < size) {
for (i = 0, ret = 0; (i < 20) && (ret < 1); i++) {
/* Watch daemon read FIFO for input. */
struct timeval tval = { .tv_sec = 1 };
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
tval.tv_sec = 1;
ret = select(fifos->server + 1, &fds, NULL, NULL,
&tval);
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
if (ret < 0 && errno != EINTR) {
log_error("Unable to read from event server");
return 0;
@ -283,15 +279,13 @@ static int _daemon_read(struct dm_event_fifos *fifos,
static int _daemon_write(struct dm_event_fifos *fifos,
struct dm_event_daemon_message *msg)
{
unsigned bytes = 0;
int ret = 0;
int ret;
fd_set fds;
size_t bytes = 0;
size_t size = 2 * sizeof(uint32_t) + msg->size;
uint32_t *header = alloca(size);
char *buf = (char *)header;
char drainbuf[128];
struct timeval tval = { 0, 0 };
header[0] = htonl(msg->cmd);
header[1] = htonl(msg->size);
@ -299,17 +293,25 @@ static int _daemon_write(struct dm_event_fifos *fifos,
/* drain the answer fifo */
while (1) {
struct timeval tval = { .tv_usec = 100 };
FD_ZERO(&fds);
FD_SET(fifos->server, &fds);
tval.tv_usec = 100;
ret = select(fifos->server + 1, &fds, NULL, NULL, &tval);
if ((ret < 0) && (errno != EINTR)) {
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, 127);
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) {
@ -345,9 +347,6 @@ int daemon_talk(struct dm_event_fifos *fifos,
const char *dso_name, const char *dev_name,
enum dm_event_mask evmask, uint32_t timeout)
{
const char *dso = dso_name ? dso_name : "-";
const char *dev = dev_name ? dev_name : "-";
const char *fmt = "%d:%d %s %s %u %" PRIu32;
int msg_size;
memset(msg, 0, sizeof(*msg));
@ -355,14 +354,17 @@ int daemon_talk(struct dm_event_fifos *fifos,
* Set command and pack the arguments
* into ASCII message string.
*/
msg->cmd = cmd;
if (cmd == DM_EVENT_CMD_HELLO)
fmt = "%d:%d HELLO";
if ((msg_size = dm_asprintf(&(msg->data), fmt, getpid(), _sequence_nr,
dso, dev, evmask, timeout)) < 0) {
if ((msg_size =
((cmd == DM_EVENT_CMD_HELLO) ?
dm_asprintf(&(msg->data), "%d:%d HELLO", getpid(), _sequence_nr) :
dm_asprintf(&(msg->data), "%d:%d %s %s %u %" PRIu32,
getpid(), _sequence_nr,
dso_name ? : "-", dev_name ? : "-", evmask, timeout)))
< 0) {
log_error("_daemon_talk: message allocation failed");
return -ENOMEM;
}
msg->cmd = cmd;
msg->size = msg_size;
/*
@ -372,14 +374,13 @@ int daemon_talk(struct dm_event_fifos *fifos,
if (!_daemon_write(fifos, msg)) {
stack;
dm_free(msg->data);
msg->data = 0;
msg->data = NULL;
return -EIO;
}
do {
dm_free(msg->data);
msg->data = 0;
msg->data = NULL;
if (!_daemon_read(fifos, msg)) {
stack;
@ -425,7 +426,7 @@ static int _start_daemon(char *dmeventd_path, struct dm_event_fifos *fifos)
if (fifos->client >= 0) {
/* server is running and listening */
if (close(fifos->client))
log_sys_error("close", fifos->client_path);
log_sys_debug("close", fifos->client_path);
return 1;
} else if (errno != ENXIO) {
/* problem */
@ -468,10 +469,6 @@ int init_fifos(struct dm_event_fifos *fifos)
/* FIXME? Is fifo the most suitable method? Why not share
comms/daemon code with something else e.g. multipath? */
/* FIXME Make these either configurable or depend directly on dmeventd_path */
fifos->client_path = DM_EVENT_FIFO_CLIENT;
fifos->server_path = DM_EVENT_FIFO_SERVER;
/* Open the fifo used to read from the daemon. */
if ((fifos->server = open(fifos->server_path, O_RDWR)) < 0) {
log_sys_error("open", fifos->server_path);
@ -481,32 +478,27 @@ int init_fifos(struct dm_event_fifos *fifos)
/* Lock out anyone else trying to do communication with the daemon. */
if (flock(fifos->server, LOCK_EX) < 0) {
log_sys_error("flock", fifos->server_path);
if (close(fifos->server))
log_sys_error("close", fifos->server_path);
return 0;
goto bad;
}
/* if ((fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK)) < 0) {*/
if ((fifos->client = open(fifos->client_path, O_RDWR | O_NONBLOCK)) < 0) {
log_sys_error("open", fifos->client_path);
if (close(fifos->server))
log_sys_error("close", fifos->server_path);
return 0;
goto bad;
}
return 1;
bad:
if (close(fifos->server))
log_sys_debug("close", fifos->server_path);
fifos->server = -1;
return 0;
}
/* Initialize client. */
static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
{
/* init fifos */
memset(fifos, 0, sizeof(*fifos));
/* FIXME Make these either configurable or depend directly on dmeventd_path */
fifos->client_path = DM_EVENT_FIFO_CLIENT;
fifos->server_path = DM_EVENT_FIFO_SERVER;
if (!_start_daemon(dmeventd_path, fifos))
return_0;
@ -515,13 +507,16 @@ static int _init_client(char *dmeventd_path, struct dm_event_fifos *fifos)
void fini_fifos(struct dm_event_fifos *fifos)
{
if (flock(fifos->server, LOCK_UN))
log_error("flock unlock %s", fifos->server_path);
if (fifos->client >= 0 && close(fifos->client))
log_sys_debug("close", fifos->client_path);
if (close(fifos->client))
log_sys_error("close", fifos->client_path);
if (close(fifos->server))
log_sys_error("close", fifos->server_path);
if (fifos->server >= 0) {
if (flock(fifos->server, LOCK_UN))
log_sys_debug("flock unlock", fifos->server_path);
if (close(fifos->server))
log_sys_debug("close", fifos->server_path);
}
}
/* Get uuid of a device */
@ -560,8 +555,8 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
if (!info.exists) {
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->uuid && dmevh->dev_name) ? dmevh->dev_name : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? "(" : "",
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? dmevh->major : 0,
(!dmevh->uuid && !dmevh->dev_name && dmevh->major > 0) ? ":" : "",
@ -571,7 +566,6 @@ static struct dm_task *_get_device_info(const struct dm_event_handler *dmevh)
goto bad;
}
return dmt;
bad:
@ -585,7 +579,13 @@ static int _do_event(int cmd, char *dmeventd_path, struct dm_event_daemon_messag
enum dm_event_mask evmask, uint32_t timeout)
{
int ret;
struct dm_event_fifos fifos;
struct dm_event_fifos fifos = {
.server = -1,
.client = -1,
/* FIXME Make these either configurable or depend directly on dmeventd_path */
.client_path = DM_EVENT_FIFO_CLIENT,
.server_path = DM_EVENT_FIFO_SERVER
};
if (!_init_client(dmeventd_path, &fifos)) {
stack;
@ -612,13 +612,20 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh)
int ret = 1, err;
const char *uuid;
struct dm_task *dmt;
struct dm_event_daemon_message msg = { 0, 0, NULL };
struct dm_event_daemon_message msg = { 0 };
if (!(dmt = _get_device_info(dmevh)))
return_0;
uuid = dm_task_get_uuid(dmt);
if (!strstr(dmevh->dso, "libdevmapper-event-lvm2thin.so") &&
!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);
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",
@ -639,7 +646,7 @@ int dm_event_unregister_handler(const struct dm_event_handler *dmevh)
int ret = 1, err;
const char *uuid;
struct dm_task *dmt;
struct dm_event_daemon_message msg = { 0, 0, NULL };
struct dm_event_daemon_message msg = { 0 };
if (!(dmt = _get_device_info(dmevh)))
return_0;
@ -683,20 +690,18 @@ static char *_fetch_string(char **src, const int delimiter)
static int _parse_message(struct dm_event_daemon_message *msg, char **dso_name,
char **uuid, enum dm_event_mask *evmask)
{
char *id = NULL;
char *id;
char *p = msg->data;
if ((id = _fetch_string(&p, ' ')) &&
(*dso_name = _fetch_string(&p, ' ')) &&
(*uuid = _fetch_string(&p, ' '))) {
*evmask = atoi(p);
dm_free(id);
return 0;
}
if (id)
dm_free(id);
dm_free(id);
return -ENOMEM;
}
@ -746,8 +751,8 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
ret = -ENXIO; /* dmeventd probably gave us bogus uuid back */
goto fail;
}
dmevh->uuid = dm_strdup(reply_uuid);
if (!dmevh->uuid) {
if (!(dmevh->uuid = dm_strdup(reply_uuid))) {
ret = -ENOMEM;
goto fail;
}
@ -766,8 +771,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
dm_free(reply_uuid);
reply_uuid = NULL;
dmevh->dev_name = dm_strdup(dm_task_get_name(dmt));
if (!dmevh->dev_name) {
if (!(dmevh->dev_name = dm_strdup(dm_task_get_name(dmt)))) {
ret = -ENOMEM;
goto fail;
}
@ -807,7 +811,7 @@ int dm_event_get_registered_device(struct dm_event_handler *dmevh, int next)
int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
char *p;
struct dm_event_daemon_message msg = { 0, 0, NULL };
struct dm_event_daemon_message msg = { 0 };
if (daemon_talk(fifos, &msg, DM_EVENT_CMD_HELLO, NULL, NULL, 0, 0))
return 0;
@ -836,7 +840,7 @@ static char *_skip_string(char *src, const int delimiter)
int dm_event_set_timeout(const char *device_path, uint32_t timeout)
{
struct dm_event_daemon_message msg = { 0, 0, NULL };
struct dm_event_daemon_message msg = { 0 };
if (!device_exists(device_path))
return -ENODEV;
@ -848,22 +852,24 @@ int dm_event_set_timeout(const char *device_path, uint32_t timeout)
int dm_event_get_timeout(const char *device_path, uint32_t *timeout)
{
int ret;
struct dm_event_daemon_message msg = { 0, 0, NULL };
struct dm_event_daemon_message msg = { 0 };
if (!device_exists(device_path))
return -ENODEV;
if (!(ret = _do_event(DM_EVENT_CMD_GET_TIMEOUT, &msg, NULL, device_path,
0, 0))) {
char *p = _skip_string(msg.data, ' ');
if (!p) {
log_error("malformed reply from dmeventd '%s'\n",
msg.data);
dm_free(msg.data);
return -EIO;
}
*timeout = atoi(p);
}
if (msg.data)
dm_free(msg.data);
dm_free(msg.data);
return ret;
}
#endif

View File

@ -46,8 +46,9 @@ enum dm_event_mask {
};
#define DM_EVENT_ALL_ERRORS DM_EVENT_ERROR_MASK
#define DM_EVENT_PROTOCOL_VERSION 1
#define DM_EVENT_PROTOCOL_VERSION 2
struct dm_task;
struct dm_event_handler;
struct dm_event_handler *dm_event_handler_create(void);

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2010-2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2010-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@ -24,7 +24,7 @@ LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_builddir)/make.tmpl
LIBS += @LVM2CMD_LIB@ -ldevmapper $(PTHREAD_LIBS) $(DAEMON_LIBS)
LIBS += @LVM2CMD_LIB@ -ldevmapper $(PTHREAD_LIBS)
install_lvm2: install_lib_shared

View File

@ -143,7 +143,7 @@ struct dm_pool *dmeventd_lvm2_pool(void)
int dmeventd_lvm2_run(const char *cmdline)
{
return lvm2_run(_lvm_handle, cmdline);
return (lvm2_run(_lvm_handle, cmdline) == LVM2_COMMAND_SUCCEEDED);
}
int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
@ -159,8 +159,8 @@ int dmeventd_lvm2_command(struct dm_pool *mem, char *buffer, size_t size,
}
/* strip off the mirror component designations */
layer = strstr(lv, "_mlog");
if (layer)
if ((layer = strstr(lv, "_mimagetmp")) ||
(layer = strstr(lv, "_mlog")))
*layer = '\0';
r = dm_snprintf(buffer, size, "%s %s/%s", cmd, vg, lv);

View File

@ -22,11 +22,11 @@
* liblvm2cmd thread-safe so this can go away.
*/
#include "libdevmapper.h"
#ifndef _DMEVENTD_LVMWRAP_H
#define _DMEVENTD_LVMWRAP_H
struct dm_pool;
int dmeventd_lvm2_init(void);
void dmeventd_lvm2_exit(void);
int dmeventd_lvm2_run(const char *cmdline);

View File

@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2008-2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2005, 2008-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@ -16,8 +16,8 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/tools -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/tools -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_mirror.c
@ -30,7 +30,7 @@ CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper $(DAEMON_LIBS)
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin

View File

@ -14,7 +14,6 @@
#include "lib.h"
#include "lvm2cmd.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include "defaults.h"
@ -144,9 +143,9 @@ static int _remove_failed_devices(const char *device)
r = dmeventd_lvm2_run(cmd_str);
syslog(LOG_INFO, "Repair of mirrored device %s %s.", device,
(r == LVM2_COMMAND_SUCCEEDED) ? "finished successfully" : "failed");
(r) ? "finished successfully" : "failed");
return (r == LVM2_COMMAND_SUCCEEDED) ? 0 : -1;
return (r) ? 0 : -1;
}
void process_event(struct dm_task *dmt,

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@ -15,8 +15,8 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/tools -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/tools -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_raid.c

View File

@ -14,7 +14,6 @@
#include "lib.h"
#include "lvm2cmd.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
@ -34,16 +33,26 @@ static int run_repair(const char *device)
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))
"lvscan --cache", device))
return -1;
r = dmeventd_lvm2_run(cmd_str);
if (r != LVM2_COMMAND_SUCCEEDED)
if (!r)
syslog(LOG_INFO, "Re-scan of RAID device %s failed.", device);
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;
/* if repair goes OK, report success even if lvscan has failed */
r = dmeventd_lvm2_run(cmd_str);
if (!r)
syslog(LOG_INFO, "Repair of RAID device %s failed.", device);
return (r == LVM2_COMMAND_SUCCEEDED) ? 0 : -1;
return (r) ? 0 : -1;
}
static int _process_raid_event(char *params, const char *device)

View File

@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of the LVM2.
#
@ -16,8 +16,8 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/tools -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/tools -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_snapshot.c
@ -26,7 +26,7 @@ LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_builddir)/make.tmpl
LIBS += -ldevmapper-event-lvm2 -ldevmapper $(DAEMON_LIBS)
LIBS += -ldevmapper-event-lvm2 -ldevmapper
install_lvm2: install_dm_plugin

View File

@ -14,12 +14,12 @@
#include "lib.h"
#include "lvm2cmd.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#include <stdarg.h>
/* FIXME Missing openlog? */
/* First warning when snapshot is 80% full. */
@ -81,7 +81,7 @@ static int _run(const char *cmd, ...)
static int _extend(const char *cmd)
{
return dmeventd_lvm2_run(cmd) == LVM2_COMMAND_SUCCEEDED;
return dmeventd_lvm2_run(cmd);
}
static void _umount(const char *device, int major, int minor)

View File

@ -1,5 +1,5 @@
#
# Copyright (C) 2011 Red Hat, Inc. All rights reserved.
# Copyright (C) 2011-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@ -15,8 +15,8 @@ srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
INCLUDES += -I$(top_srcdir)/tools -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/tools -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
INCLUDES += -I$(top_srcdir)/daemons/dmeventd/plugins/lvm2
CLDFLAGS += -L$(top_builddir)/daemons/dmeventd/plugins/lvm2
SOURCES = dmeventd_thin.c

View File

@ -14,12 +14,12 @@
#include "lib.h"
#include "lvm2cmd.h"
#include "libdevmapper-event.h"
#include "dmeventd_lvm.h"
#include <sys/wait.h>
#include <syslog.h> /* FIXME Replace syslog with multilog */
#include <stdarg.h>
/* FIXME Missing openlog? */
/* First warning when thin is 80% full. */
@ -44,7 +44,7 @@ struct dso_state {
/* TODO - move this mountinfo code into library to be reusable */
#ifdef linux
#ifdef __linux__
# include "kdev_t.h"
#else
# define MAJOR(x) major((x))
@ -146,7 +146,7 @@ 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) == LVM2_COMMAND_SUCCEEDED);
return dmeventd_lvm2_run(state->cmd_str);
}
static int _run(const char *cmd, ...)
@ -218,7 +218,8 @@ static int _umount_device(char *buffer, unsigned major, unsigned minor,
*/
static void _umount(struct dm_task *dmt, const char *device)
{
static const size_t MINORS = 4096;
/* TODO: Convert to use hash to reduce memory usage */
static const size_t MINORS = (1U << 20); /* 20 bit */
struct mountinfo_s data = {
.device = device,
};

View File

@ -33,8 +33,9 @@ LVMLIBS = -ldaemonserver $(LVMINTERNAL_LIBS) -ldevmapper
LIBS += $(PTHREAD_LIBS)
LDFLAGS += -L$(top_builddir)/libdaemon/server
LDFLAGS += -L$(top_builddir)/libdaemon/server $(EXTRA_EXEC_LDFLAGS)
CLDFLAGS += -L$(top_builddir)/libdaemon/server
CFLAGS += $(EXTRA_EXEC_CFLAGS)
lvmetad: $(OBJECTS) $(top_builddir)/libdaemon/client/libdaemonclient.a \
$(top_builddir)/libdaemon/server/libdaemonserver.a

View File

@ -17,6 +17,8 @@
#include "daemon-client.h"
#define LVMETAD_SOCKET DEFAULT_RUN_DIR "/lvmetad.socket"
struct volume_group;
/* Different types of replies we may get from lvmetad. */
@ -64,7 +66,7 @@ static inline daemon_handle lvmetad_open(const char *socket)
{
daemon_info lvmetad_info = {
.path = "lvmetad",
.socket = socket ?: DEFAULT_RUN_DIR "/lvmetad.socket",
.socket = socket ?: LVMETAD_SOCKET,
.protocol = "lvmetad",
.protocol_version = 1,
.autostart = 0

View File

@ -26,6 +26,11 @@
#include <stdint.h>
#include <unistd.h>
#include <math.h> /* fabs() */
#include <float.h> /* DBL_EPSILON */
#define LVMETAD_SOCKET DEFAULT_RUN_DIR "/lvmetad.socket"
typedef struct {
log_state *log; /* convenience */
const char *log_config;
@ -52,27 +57,19 @@ static void destroy_metadata_hashes(lvmetad_state *s)
{
struct dm_hash_node *n = NULL;
n = dm_hash_get_first(s->vgid_to_metadata);
while (n) {
dm_hash_iterate(n, s->vgid_to_metadata)
dm_config_destroy(dm_hash_get_data(s->vgid_to_metadata, n));
n = dm_hash_get_next(s->vgid_to_metadata, n);
}
n = dm_hash_get_first(s->pvid_to_pvmeta);
while (n) {
dm_hash_iterate(n, s->pvid_to_pvmeta)
dm_config_destroy(dm_hash_get_data(s->pvid_to_pvmeta, n));
n = dm_hash_get_next(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->vgname_to_vgid);
n = dm_hash_get_first(s->device_to_pvid);
while (n) {
dm_hash_iterate(n, s->device_to_pvid)
dm_free(dm_hash_get_data(s->device_to_pvid, n));
n = dm_hash_get_next(s->device_to_pvid, n);
}
dm_hash_destroy(s->device_to_pvid);
dm_hash_destroy(s->pvid_to_vgid);
@ -305,8 +302,7 @@ static response pv_list(lvmetad_state *s, request r)
lock_pvid_to_pvmeta(s);
for (n = dm_hash_get_first(s->pvid_to_pvmeta); n;
n = dm_hash_get_next(s->pvid_to_pvmeta, n)) {
dm_hash_iterate(n, s->pvid_to_pvmeta) {
id = dm_hash_get_key(s->pvid_to_pvmeta, n);
cn = make_pv_node(s, id, res.cft, cn_pvs, cn);
}
@ -339,8 +335,8 @@ static response pv_lookup(lvmetad_state *s, request r)
pvid = dm_hash_lookup_binary(s->device_to_pvid, &devt, sizeof(devt));
if (!pvid) {
WARN(s, "pv_lookup: could not find device %" PRIu64, devt);
unlock_pvid_to_pvmeta(s);
WARN(s, "pv_lookup: could not find device %" PRIu64, devt);
dm_config_destroy(res.cft);
return reply_unknown("device not found");
}
@ -392,8 +388,7 @@ static response vg_list(lvmetad_state *s, request r)
lock_vgid_to_metadata(s);
n = dm_hash_get_first(s->vgid_to_vgname);
while (n) {
dm_hash_iterate(n, s->vgid_to_vgname) {
id = dm_hash_get_key(s->vgid_to_vgname, n),
name = dm_hash_get_data(s->vgid_to_vgname, n);
@ -421,8 +416,6 @@ static response vg_list(lvmetad_state *s, request r)
if (!cn_vgs->child)
cn_vgs->child = cn;
cn_last = cn;
n = dm_hash_get_next(s->vgid_to_vgname, n);
}
unlock_vgid_to_metadata(s);
@ -503,6 +496,12 @@ 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;
@ -514,7 +513,7 @@ static int compare_value(struct dm_config_value *a, struct dm_config_value *b)
switch (a->type) {
case DM_CFG_STRING: r = strcmp(a->v.str, b->v.str); break;
case DM_CFG_FLOAT: r = (a->v.f == b->v.f) ? 0 : (a->v.f > b->v.f) ? 1 : -1; 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;
}
@ -551,7 +550,7 @@ static int compare_config(struct dm_config_node *a, struct dm_config_node *b)
return result;
}
static int vg_remove_if_missing(lvmetad_state *s, const char *vgid);
static int vg_remove_if_missing(lvmetad_state *s, const char *vgid, int update_pvids);
/* 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,
@ -586,11 +585,10 @@ static int update_pvid_to_vgid(lvmetad_state *s, struct dm_config_tree *vg,
DEBUGLOG(s, "moving PV %s to VG %s", pvid, vgid);
}
for (n = dm_hash_get_first(to_check); n;
n = dm_hash_get_next(to_check, n)) {
dm_hash_iterate(n, to_check) {
check_vgid = dm_hash_get_key(to_check, n);
lock_vg(s, check_vgid);
vg_remove_if_missing(s, check_vgid);
vg_remove_if_missing(s, check_vgid, 0);
unlock_vg(s, check_vgid);
}
@ -631,7 +629,7 @@ static int remove_metadata(lvmetad_state *s, const char *vgid, int update_pvids)
}
/* The VG must be locked. */
static int vg_remove_if_missing(lvmetad_state *s, const char *vgid)
static int vg_remove_if_missing(lvmetad_state *s, const char *vgid, int update_pvids)
{
struct dm_config_tree *vg;
struct dm_config_node *pv;
@ -658,7 +656,7 @@ static int vg_remove_if_missing(lvmetad_state *s, const char *vgid)
if (missing) {
DEBUGLOG(s, "removing empty VG %s", vgid);
remove_metadata(s, vgid, 0);
remove_metadata(s, vgid, update_pvids);
}
unlock_pvid_to_pvmeta(s);
@ -753,8 +751,11 @@ static int update_metadata(lvmetad_state *s, const char *name, const char *_vgid
dm_hash_insert(s->vgid_to_vgname, vgid, cfgname) &&
dm_hash_insert(s->vgname_to_vgid, name, (void*) vgid)) ? 1 : 0;
if (retval && oldname && strcmp(name, oldname))
dm_hash_remove(s->vgname_to_vgid, oldname);
if (retval && oldname && strcmp(name, oldname)) {
const char *vgid_prev = dm_hash_lookup(s->vgname_to_vgid, oldname);
if (vgid_prev && !strcmp(vgid_prev, vgid))
dm_hash_remove(s->vgname_to_vgid, oldname);
}
if (haveseq >= 0 && haveseq < seq)
dm_config_destroy(old);
@ -777,7 +778,7 @@ 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);
struct dm_config_tree *pvmeta;
char *pvid_old;
char *pvid_old, *vgid;
DEBUGLOG(s, "pv_gone: %s / %" PRIu64, pvid, device);
@ -793,19 +794,30 @@ static response pv_gone(lvmetad_state *s, request r)
pvmeta = dm_hash_lookup(s->pvid_to_pvmeta, pvid);
pvid_old = dm_hash_lookup_binary(s->device_to_pvid, &device, sizeof(device));
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);
vg_remove_if_missing(s, dm_hash_lookup(s->pvid_to_vgid, pvid));
unlock_pvid_to_pvmeta(s);
if (pvid_old)
dm_free(pvid_old);
dm_free(pvid_old);
if (pvmeta) {
dm_config_destroy(pvmeta);
return daemon_reply_simple("OK", NULL);
} else
if (vgid) {
if (!(vgid = dm_strdup(vgid)))
return reply_fail("out of memory");
lock_vg(s, vgid);
vg_remove_if_missing(s, vgid, 1);
unlock_vg(s, vgid);
dm_free(vgid);
}
if (!pvmeta)
return reply_unknown("PVID does not exist");
dm_config_destroy(pvmeta);
return daemon_reply_simple("OK", NULL);
}
static response pv_clear_all(lvmetad_state *s, request r)
@ -813,8 +825,8 @@ static response pv_clear_all(lvmetad_state *s, request r)
DEBUGLOG(s, "pv_clear_all");
lock_pvid_to_pvmeta(s);
lock_vgid_to_metadata(s);
lock_pvid_to_vgid(s);
lock_vgid_to_metadata(s);
destroy_metadata_hashes(s);
create_metadata_hashes(s);
@ -832,13 +844,14 @@ static response pv_found(lvmetad_state *s, request r)
const char *pvid = daemon_request_str(r, "pvmeta/id", NULL);
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");
uint64_t device;
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;
int64_t seqno = -1, seqno_old = -1, changed = 0;
if (!pvid)
return reply_fail("need PV UUID");
@ -848,47 +861,60 @@ 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");
lock_pvid_to_pvmeta(s);
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);
}
pvmeta_old_pvid = dm_hash_lookup(s->pvid_to_pvmeta, pvid);
DEBUGLOG(s, "pv_found %s, vgid = %s, device = %" PRIu64 ", old = %s", pvid, vgid, device, old);
dm_free(old);
if (!(cft = dm_config_create()) ||
!(cft->root = dm_config_clone_node(cft, pvmeta, 0))) {
unlock_pvid_to_pvmeta(s);
(!(pvid_dup = dm_strdup(pvid)))) {
if (cft)
dm_config_destroy(cft);
return reply_fail("out of memory");
}
if (!(pvid_dup = dm_strdup(pvid))) {
unlock_pvid_to_pvmeta(s);
dm_config_destroy(cft);
return reply_fail("out of memory");
lock_pvid_to_pvmeta(s);
if ((pvmeta_old_pvid = dm_hash_lookup(s->pvid_to_pvmeta, pvid)))
dm_config_get_uint64(pvmeta_old_pvid->root, "pvmeta/device", &device_old_pvid);
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);
}
DEBUGLOG(s, "pv_found %s, vgid = %s, device = %" PRIu64 " (previously %" PRIu64 "), old = %s",
pvid, vgid, device, device_old_pvid, old);
if (!(cft->root = dm_config_clone_node(cft, pvmeta, 0)))
goto out_of_mem;
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)));
dm_hash_remove_binary(s->device_to_pvid, &device_old_pvid, sizeof(device_old_pvid));
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)) {
unlock_pvid_to_pvmeta(s);
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);
unlock_pvid_to_pvmeta(s);
if (metadata) {
if (!vgid)
return reply_fail("need VG UUID");
@ -900,6 +926,7 @@ static response pv_found(lvmetad_state *s, request r)
if (!update_metadata(s, vgname, vgid, metadata, &seqno_old))
return reply_fail("metadata update failed");
changed |= (seqno_old != dm_config_find_int(metadata, "metadata/seqno", -1));
} else {
lock_pvid_to_vgid(s);
vgid = dm_hash_lookup(s->pvid_to_vgid, pvid);
@ -917,12 +944,29 @@ static response pv_found(lvmetad_state *s, request r)
return reply_fail("non-orphan VG without metadata encountered");
}
unlock_vg(s, vgid);
// TODO: separate vgid->vgname lock
lock_vgid_to_metadata(s);
vgname = dm_hash_lookup(s->vgid_to_vgname, vgid);
unlock_vgid_to_metadata(s);
}
if (vgid_old && (!vgid || strcmp(vgid, vgid_old))) {
/* make a copy, because vg_remove_if_missing will deallocate the
* storage behind vgid_old */
vgid_old = dm_strdup(vgid_old);
lock_vg(s, vgid_old);
vg_remove_if_missing(s, vgid_old, 1);
unlock_vg(s, vgid_old);
dm_free((char*)vgid_old);
}
return daemon_reply_simple("OK",
"status = %s", orphan ? "orphan" :
(complete ? "complete" : "partial"),
"changed = %d", changed,
"vgid = %s", vgid ? vgid : "#orphan",
"vgname = %s", vgname ? vgname : "#orphan",
"seqno_before = %"PRId64, seqno_old,
"seqno_after = %"PRId64, seqno,
NULL);
@ -967,26 +1011,26 @@ static response vg_remove(lvmetad_state *s, request r)
static void _dump_cft(struct buffer *buf, struct dm_hash_table *ht, const char *key_addr)
{
struct dm_hash_node *n = dm_hash_get_first(ht);
while (n) {
struct dm_hash_node *n;
dm_hash_iterate(n, ht) {
struct dm_config_tree *cft = dm_hash_get_data(ht, n);
const char *key_backup = cft->root->key;
cft->root->key = dm_config_find_str(cft->root, key_addr, "unknown");
(void) dm_config_write_node(cft->root, buffer_line, buf);
cft->root->key = key_backup;
n = dm_hash_get_next(ht, n);
}
}
static void _dump_pairs(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 dm_hash_node *n;
buffer_append(buf, name);
buffer_append(buf, " {\n");
while (n) {
dm_hash_iterate(n, ht) {
const char *key = dm_hash_get_key(ht, n),
*val = dm_hash_get_data(ht, n);
buffer_append(buf, " ");
@ -998,7 +1042,6 @@ static void _dump_pairs(struct buffer *buf, struct dm_hash_table *ht, const char
buffer_append(buf, append);
buffer_append(buf, "\n");
dm_free(append);
n = dm_hash_get_next(ht, n);
}
buffer_append(buf, "}\n");
}
@ -1060,7 +1103,8 @@ static response handler(daemon_state s, client_handle h, request r)
return daemon_reply_simple("token_mismatch",
"expected = %s", state->token,
"received = %s", token,
"reason = %s", "token mismatch", NULL);
"reason = %s",
"lvmetad cache is invalid due to a global_filter change or due to a running rescan", NULL);
}
pthread_mutex_unlock(&state->token_lock);
@ -1143,18 +1187,16 @@ static int fini(daemon_state *s)
destroy_metadata_hashes(ls);
/* Destroy the lock hashes now. */
n = dm_hash_get_first(ls->lock.vg);
while (n) {
dm_hash_iterate(n, ls->lock.vg) {
pthread_mutex_destroy(dm_hash_get_data(ls->lock.vg, n));
free(dm_hash_get_data(ls->lock.vg, n));
n = dm_hash_get_next(ls->lock.vg, n);
}
dm_hash_destroy(ls->lock.vg);
return 1;
}
static void usage(char *prog, FILE *file)
static void usage(const char *prog, FILE *file)
{
fprintf(file, "Usage:\n"
"%s [-V] [-h] [-f] [-l {all|wire|debug}] [-s path]\n\n"
@ -1162,34 +1204,28 @@ static void usage(char *prog, FILE *file)
" -h Show this help information\n"
" -f Don't fork, run in the foreground\n"
" -l Logging message level (-l {all|wire|debug})\n"
" -p Set path to the pidfile\n"
" -s Set path to the socket to listen on\n\n", prog);
}
int main(int argc, char *argv[])
{
signed char opt;
lvmetad_state ls;
int _socket_override = 1;
lvmetad_state ls = { .log_config = "" };
daemon_state s = {
.daemon_fini = fini,
.daemon_init = init,
.handler = handler,
.name = "lvmetad",
.pidfile = LVMETAD_PIDFILE,
.pidfile = getenv("LVM_LVMETAD_PIDFILE") ? : LVMETAD_PIDFILE,
.private = &ls,
.protocol = "lvmetad",
.protocol_version = 1,
.socket_path = getenv("LVM_LVMETAD_SOCKET"),
.socket_path = getenv("LVM_LVMETAD_SOCKET") ? : LVMETAD_SOCKET,
};
if (!s.socket_path) {
_socket_override = 0;
s.socket_path = DEFAULT_RUN_DIR "/lvmetad.socket";
}
ls.log_config = "";
// use getopt_long
while ((opt = getopt(argc, argv, "?fhVl:s:")) != EOF) {
while ((opt = getopt(argc, argv, "?fhVl:p:s:")) != EOF) {
switch (opt) {
case 'h':
usage(argv[0], stdout);
@ -1203,9 +1239,11 @@ int main(int argc, char *argv[])
case 'l':
ls.log_config = optarg;
break;
case 'p':
s.pidfile = optarg;
break;
case 's': // --socket
s.socket_path = optarg;
_socket_override = 1;
break;
case 'V':
printf("lvmetad version: " LVM_VERSION "\n");
@ -1213,15 +1251,7 @@ int main(int argc, char *argv[])
}
}
if (s.foreground) {
if (!_socket_override) {
fprintf(stderr, "A socket path (-s) is required in foreground mode.");
exit(2);
}
s.pidfile = NULL;
}
daemon_start(s);
return 0;
}

View File

@ -11,18 +11,12 @@
@top_srcdir@/lib/config/config_settings.h
@top_srcdir@/lib/config/defaults.h
@top_srcdir@/lib/datastruct/btree.h
@top_srcdir@/lib/datastruct/lvm-types.h
@top_srcdir@/lib/datastruct/str_list.h
@top_srcdir@/lib/device/dev-cache.h
@top_srcdir@/lib/device/dev-type.h
@top_srcdir@/lib/device/device.h
@top_srcdir@/lib/device/device-types.h
@top_srcdir@/lib/display/display.h
@top_srcdir@/lib/filters/filter-composite.h
@top_srcdir@/lib/filters/filter-md.h
@top_srcdir@/lib/filters/filter-mpath.h
@top_srcdir@/lib/filters/filter-persistent.h
@top_srcdir@/lib/filters/filter-regex.h
@top_srcdir@/lib/filters/filter-sysfs.h
@top_srcdir@/lib/filters/filter.h
@top_srcdir@/lib/format1/format1.h
@top_srcdir@/lib/format_pool/format_pool.h
@ -47,17 +41,19 @@
@top_builddir@/lib/misc/configure.h
@top_srcdir@/lib/misc/crc.h
@top_srcdir@/lib/misc/intl.h
@top_srcdir@/lib/misc/util.h
@top_srcdir@/lib/misc/last-path-component.h
@top_srcdir@/lib/misc/lib.h
@top_srcdir@/lib/misc/lvm-exec.h
@top_srcdir@/lib/misc/lvm-file.h
@top_srcdir@/lib/misc/lvm-flock.h
@top_srcdir@/lib/misc/lvm-globals.h
@top_srcdir@/lib/misc/lvm-signal.h
@top_srcdir@/lib/misc/lvm-string.h
@top_builddir@/lib/misc/lvm-version.h
@top_srcdir@/lib/misc/lvm-wrappers.h
@top_srcdir@/lib/misc/lvm-percent.h
@top_srcdir@/lib/misc/lvm-wrappers.h
@top_srcdir@/lib/misc/sharedlib.h
@top_srcdir@/lib/misc/util.h
@top_srcdir@/lib/properties/prop_common.h
@top_srcdir@/lib/report/properties.h
@top_srcdir@/lib/report/report.h

View File

@ -1,6 +1,6 @@
#
# Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
# Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
# Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
@ -44,6 +44,10 @@ ifeq ("@THIN@", "shared")
SUBDIRS += thin
endif
ifeq ("@CACHE@", "shared")
SUBDIRS += cache_segtype
endif
SOURCES =\
activate/activate.c \
cache/lvmcache.c \
@ -66,7 +70,8 @@ SOURCES =\
filters/filter-sysfs.c \
filters/filter-md.c \
filters/filter-mpath.c \
filters/filter.c \
filters/filter-partitioned.c \
filters/filter-type.c \
format_text/archive.c \
format_text/archiver.c \
format_text/export.c \
@ -82,11 +87,13 @@ SOURCES =\
locking/locking.c \
locking/no_locking.c \
log/log.c \
metadata/cache_manip.c \
metadata/lv.c \
metadata/lv_manip.c \
metadata/merge.c \
metadata/metadata.c \
metadata/mirror.c \
metadata/pool_manip.c \
metadata/pv.c \
metadata/pv_manip.c \
metadata/pv_map.c \
@ -99,7 +106,9 @@ SOURCES =\
misc/crc.c \
misc/lvm-exec.c \
misc/lvm-file.c \
misc/lvm-flock.c \
misc/lvm-globals.c \
misc/lvm-signal.c \
misc/lvm-string.c \
misc/lvm-wrappers.c \
misc/lvm-percent.c \
@ -163,6 +172,10 @@ ifeq ("@THIN@", "internal")
SOURCES += thin/thin.c
endif
ifeq ("@CACHE@", "internal")
SOURCES += cache_segtype/cache.c
endif
ifeq ("@DEVMAPPER@", "yes")
SOURCES +=\
activate/dev_manager.c \
@ -197,6 +210,7 @@ ifeq ($(MAKECMDGOALS),distclean)
raid \
replicator \
thin \
cache_segtype \
locking
endif
@ -205,6 +219,8 @@ CFLOW_LIST_TARGET = $(LIB_NAME).cflow
include $(top_builddir)/make.tmpl
CFLAGS += $(BLKID_CFLAGS) $(UDEV_CFLAGS)
$(SUBDIRS): $(LIB_STATIC)
DISTCLEAN_TARGETS += misc/configure.h misc/lvm-version.h

File diff suppressed because it is too large Load Diff

View File

@ -38,23 +38,21 @@ struct lv_activate_opts {
int skip_in_use;
unsigned revert;
unsigned read_only;
unsigned noscan; /* Mark this LV to avoid its scanning. This also
directs udev to use proper udev flag to avoid
any scanning in udev. This udev flag is automatically
dropped in udev db on any spurious event that follows. */
unsigned temporary; /* Mark this LV as temporary. It means, the LV
* is created, used and deactivated within single
* LVM command execution. Such LVs are mostly helper
* LVs to do some action or cleanup before the proper
* LV is created. This also directs udev to use proper
* set of flags to avoid any scanning in udev. These udev
* flags are persistent in udev db for any spurious event
* that follows. */
};
/* target attribute flags */
#define MIRROR_LOG_CLUSTERED 0x00000001U
/* thin target attribute flags */
enum {
/* bitfields - new features from 1.1 version */
THIN_FEATURE_DISCARDS = (1 << 0),
THIN_FEATURE_EXTERNAL_ORIGIN = (1 << 1),
THIN_FEATURE_HELD_ROOT = (1 << 2),
THIN_FEATURE_BLOCK_SIZE = (1 << 3),
THIN_FEATURE_DISCARDS_NON_POWER_2 = (1 << 4),
THIN_FEATURE_METADATA_RESIZE = (1 << 5),
};
void set_activation(int activation);
void set_activation(int activation, int silent);
int activation(void);
int driver_version(char *version, size_t size);
@ -80,9 +78,10 @@ int lv_suspend_if_active(struct cmd_context *cmd, const char *lvid_s, unsigned o
int lv_resume(struct cmd_context *cmd, const char *lvid_s, unsigned origin_only, 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);
int lv_activate(struct cmd_context *cmd, const char *lvid_s, int exclusive, struct logical_volume *lv);
int lv_activate_with_filter(struct cmd_context *cmd, const char *lvid_s,
int exclusive, 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 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 lv_mknodes(struct cmd_context *cmd, const struct logical_volume *lv);
@ -113,20 +112,27 @@ int lv_check_transient(struct logical_volume *lv);
/*
* Returns 1 if percent has been set, else 0.
*/
int lv_snapshot_percent(const struct logical_volume *lv, percent_t *percent);
int lv_snapshot_percent(const struct logical_volume *lv, dm_percent_t *percent);
int lv_mirror_percent(struct cmd_context *cmd, const struct logical_volume *lv,
int wait, percent_t *percent, uint32_t *event_nr);
int lv_raid_percent(const struct logical_volume *lv, percent_t *percent);
int wait, dm_percent_t *percent, uint32_t *event_nr);
int lv_raid_percent(const struct logical_volume *lv, dm_percent_t *percent);
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_thin_pool_percent(const struct logical_volume *lv, int metadata,
percent_t *percent);
dm_percent_t *percent);
int lv_thin_percent(const struct logical_volume *lv, int mapped,
percent_t *percent);
dm_percent_t *percent);
int lv_thin_pool_transaction_id(const struct logical_volume *lv,
uint64_t *transaction_id);
int lv_thin_device_id(const struct logical_volume *lv, uint32_t *device_id);
/*
* Return number of LVs in the VG that are active.

File diff suppressed because it is too large Load Diff

View File

@ -50,26 +50,32 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
struct dm_info *info, uint32_t *read_ahead);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
percent_t *percent);
dm_percent_t *percent);
int dev_manager_mirror_percent(struct dev_manager *dm,
const struct logical_volume *lv, int wait,
percent_t *percent, uint32_t *event_nr);
dm_percent_t *percent, uint32_t *event_nr);
int dev_manager_raid_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_raid **status);
int dev_manager_raid_message(struct dev_manager *dm,
const struct logical_volume *lv,
const char *msg);
int dev_manager_cache_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_cache **status);
int dev_manager_thin_pool_status(struct dev_manager *dm,
const struct logical_volume *lv,
struct dm_status_thin_pool **status,
int noflush);
int dev_manager_thin_pool_percent(struct dev_manager *dm,
const struct logical_volume *lv,
int metadata, percent_t *percent);
int metadata, dm_percent_t *percent);
int dev_manager_thin_percent(struct dev_manager *dm,
const struct logical_volume *lv,
int mapped, percent_t *percent);
int mapped, dm_percent_t *percent);
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,
struct lv_activate_opts *laopts, int lockfs, int flush_required);
int dev_manager_activate(struct dev_manager *dm, struct logical_volume *lv,

59
lib/cache/lvmcache.c vendored
View File

@ -64,6 +64,7 @@ struct lvmcache_vginfo {
unsigned holders;
unsigned vg_use_count; /* Counter of vg reusage */
unsigned precommitted; /* Is vgmetadata live or precommitted? */
unsigned cached_vg_invalidated; /* Signal to regenerate cached_vg */
};
static struct dm_hash_table *_pvid_hash = NULL;
@ -263,9 +264,9 @@ static void _drop_metadata(const char *vgname, int drop_precommitted)
}
/*
* Remote node uses this to upgrade precommited metadata to commited state
* Remote node uses this to upgrade precommitted metadata to commited state
* when receives vg_commit notification.
* (Note that devices can be suspended here, if so, precommited metadata are already read.)
* (Note that devices can be suspended here, if so, precommitted metadata are already read.)
*/
void lvmcache_commit_metadata(const char *vgname)
{
@ -428,11 +429,15 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgname(const char *vgname, const ch
if (!vgname)
return lvmcache_vginfo_from_vgid(vgid);
if (!_vgname_hash)
if (!_vgname_hash) {
log_debug_cache(INTERNAL_ERROR "Internal cache is no yet initialized.");
return NULL;
}
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname)))
if (!(vginfo = dm_hash_lookup(_vgname_hash, vgname))) {
log_debug_cache("Metadata cache has no info for vgname: \"%s\"", vgname);
return NULL;
}
if (vgid)
do
@ -440,6 +445,10 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgname(const char *vgname, const ch
return vginfo;
while ((vginfo = vginfo->next));
if (!vginfo)
log_debug_cache("Metadata cache has not found vgname \"%s\" with vgid \"%."
DM_TO_STRING(ID_LEN) "s\".", vgname, vgid ? : "");
return vginfo;
}
@ -513,15 +522,19 @@ struct lvmcache_vginfo *lvmcache_vginfo_from_vgid(const char *vgid)
struct lvmcache_vginfo *vginfo;
char id[ID_LEN + 1] __attribute__((aligned(8)));
if (!_vgid_hash || !vgid)
if (!_vgid_hash || !vgid) {
log_debug_cache(INTERNAL_ERROR "Internal cache cannot lookup vgid.");
return NULL;
}
/* vgid not necessarily NULL-terminated */
strncpy(&id[0], vgid, ID_LEN);
id[ID_LEN] = '\0';
if (!(vginfo = dm_hash_lookup(_vgid_hash, id)))
if (!(vginfo = dm_hash_lookup(_vgid_hash, id))) {
log_debug_cache("Metadata cache has no info for vgid \"%s\"", id);
return NULL;
}
return vginfo;
}
@ -763,9 +776,11 @@ struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname
return NULL;
/* Use already-cached VG struct when available */
if ((vg = vginfo->cached_vg))
if ((vg = vginfo->cached_vg) && !vginfo->cached_vg_invalidated)
goto out;
release_vg(vginfo->cached_vg);
fic.type = FMT_INSTANCE_MDAS | FMT_INSTANCE_AUX_MDAS;
fic.context.vg_ref.vg_name = vginfo->vgname;
fic.context.vg_ref.vg_id = vgid;
@ -785,6 +800,7 @@ struct volume_group *lvmcache_get_vg(struct cmd_context *cmd, const char *vgname
vginfo->cached_vg = vg;
vginfo->holders = 1;
vginfo->vg_use_count = 0;
vginfo->cached_vg_invalidated = 0;
vg->vginfo = vginfo;
if (!dm_pool_lock(vg->vgmem, detect_internal_vg_cache_corruption()))
@ -1046,7 +1062,6 @@ static int _drop_vginfo(struct lvmcache_info *info, struct lvmcache_vginfo *vgin
return 1;
}
/* Unused
void lvmcache_del(struct lvmcache_info *info)
{
if (info->dev->pvid[0] && _pvid_hash)
@ -1055,11 +1070,11 @@ void lvmcache_del(struct lvmcache_info *info)
_drop_vginfo(info, info->vginfo);
info->label->labeller->ops->destroy_label(info->label->labeller,
info->label);
info->label);
dm_free(info);
return;
} */
}
static int _lvmcache_update_pvid(struct lvmcache_info *info, const char *pvid)
{
@ -1407,6 +1422,12 @@ int lvmcache_update_vgname_and_id(struct lvmcache_info *info,
!is_orphan_vg(info->vginfo->vgname) && critical_section())
return 1;
/* If making a PV into an orphan, any cached VG metadata may become
* invalid, incorrectly still referencing device structs.
* (Example: pvcreate -ff) */
if (is_orphan_vg(vgname) && info->vginfo && !is_orphan_vg(info->vginfo->vgname))
info->vginfo->cached_vg_invalidated = 1;
/* If moving PV from orphan to real VG, always mark it valid */
if (!is_orphan_vg(vgname))
info->status &= ~CACHE_INVALID;
@ -1450,7 +1471,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
const char *vgname, const char *vgid,
uint32_t vgstatus)
{
const struct format_type *fmt = (const struct format_type *) labeller->private;
const struct format_type *fmt = labeller->fmt;
struct dev_types *dt = fmt->cmd->dev_types;
struct label *label;
struct lvmcache_info *existing, *info;
@ -1540,7 +1561,7 @@ struct lvmcache_info *lvmcache_add(struct labeller *labeller, const char *pvid,
label = info->label;
}
info->fmt = (const struct format_type *) labeller->private;
info->fmt = labeller->fmt;
info->status |= CACHE_INVALID;
if (!_lvmcache_update_pvid(info, pvid_s)) {
@ -1599,7 +1620,7 @@ static void _lvmcache_destroy_lockname(struct dm_hash_node *n)
dm_hash_get_key(_lock_hash, n));
}
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset)
{
struct dm_hash_node *n;
log_verbose("Wiping internal VG cache");
@ -1625,8 +1646,11 @@ void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans)
}
if (_lock_hash) {
dm_hash_iterate(n, _lock_hash)
_lvmcache_destroy_lockname(n);
if (reset)
_vg_global_lock_held = 0;
else
dm_hash_iterate(n, _lock_hash)
_lvmcache_destroy_lockname(n);
dm_hash_destroy(_lock_hash);
_lock_hash = NULL;
}
@ -1683,7 +1707,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,
@ -1948,6 +1972,9 @@ int lvmcache_uncertain_ownership(struct lvmcache_info *info) {
uint64_t lvmcache_smallest_mda_size(struct lvmcache_info *info)
{
if (!info)
return UINT64_C(0);
return find_min_mda_size(&info->mdas);
}

View File

@ -42,7 +42,7 @@ struct lvmcache_vginfo;
int lvmcache_init(void);
void lvmcache_allow_reads_with_lvmetad(void);
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans);
void lvmcache_destroy(struct cmd_context *cmd, int retain_orphans, int reset);
/* Set full_scan to 1 to reread every filtered device label or
* 2 to rescan /dev for new devices */
@ -88,17 +88,17 @@ int lvmcache_vgname_is_locked(const char *vgname);
void lvmcache_seed_infos_from_lvmetad(struct cmd_context *cmd);
/* Returns list of struct str_lists containing pool-allocated copy of vgnames */
/* Returns list of struct dm_str_list containing pool-allocated copy of vgnames */
/* If include_internal is not set, return only proper vg names. */
struct dm_list *lvmcache_get_vgnames(struct cmd_context *cmd,
int include_internal);
/* Returns list of struct str_lists containing pool-allocated copy of vgids */
/* Returns list of struct dm_str_list containing pool-allocated copy of vgids */
/* If include_internal is not set, return only proper vg ids. */
struct dm_list *lvmcache_get_vgids(struct cmd_context *cmd,
int include_internal);
/* Returns list of struct str_lists containing pool-allocated copy of pvids */
/* 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);

147
lib/cache/lvmetad.c vendored
View File

@ -21,8 +21,12 @@
#include "lvmetad-client.h"
#include "format-text.h" // TODO for disk_locn, used as a DA representation
#include "crc.h"
#include "lvm-signal.h"
static daemon_handle _lvmetad;
#define SCAN_TIMEOUT_SECONDS 80
#define MAX_RESCANS 10 /* Maximum number of times to scan all PVs and retry if the daemon returns a token mismatch error */
static daemon_handle _lvmetad = { .error = 0 };
static int _lvmetad_use = 0;
static int _lvmetad_connected = 0;
@ -40,7 +44,7 @@ void lvmetad_disconnect(void)
void lvmetad_init(struct cmd_context *cmd)
{
if (!_lvmetad_use && !access(LVMETAD_PIDFILE, F_OK))
if (!_lvmetad_use && !access(getenv("LVM_LVMETAD_PIDFILE") ? : LVMETAD_PIDFILE, F_OK))
log_warn("WARNING: lvmetad is running but disabled."
" Restart lvmetad before enabling it!");
_lvmetad_cmd = cmd;
@ -64,31 +68,41 @@ void lvmetad_connect_or_warn(void)
if (!_lvmetad_use)
return;
if (!_lvmetad_connected)
if (!_lvmetad_connected && !_lvmetad.error) {
_lvmetad_connect();
if ((_lvmetad.socket_fd < 0 || _lvmetad.error))
log_warn("WARNING: Failed to connect to lvmetad: %s. Falling back to internal scanning.",
strerror(_lvmetad.error));
if ((_lvmetad.socket_fd < 0 || _lvmetad.error))
log_warn("WARNING: Failed to connect to lvmetad. Falling back to internal scanning.");
}
}
int lvmetad_used(void)
{
return _lvmetad_use;
}
int lvmetad_socket_present(void)
{
const char *socket = _lvmetad_socket ?: LVMETAD_SOCKET;
int r;
if ((r = access(socket, F_OK)) && errno != ENOENT)
log_sys_error("lvmetad_socket_present", "");
return !r;
}
int lvmetad_active(void)
{
if (!_lvmetad_use)
return 0;
if (!_lvmetad_connected)
_lvmetad_connect();
if ((_lvmetad.socket_fd < 0 || _lvmetad.error))
log_debug_lvmetad("Failed to connect to lvmetad: %s.", strerror(_lvmetad.error));
lvmetad_connect_or_warn();
return _lvmetad_connected;
}
void lvmetad_set_active(int active)
{
_lvmetad_use = active;
if (!active && lvmetad_active())
lvmetad_disconnect();
}
/*
@ -98,15 +112,14 @@ void lvmetad_set_token(const struct dm_config_value *filter)
{
int ft = 0;
if (_lvmetad_token)
dm_free(_lvmetad_token);
dm_free(_lvmetad_token);
while (filter && filter->type == DM_CFG_STRING) {
ft = calc_crc(ft, (const uint8_t *) filter->v.str, strlen(filter->v.str));
filter = filter->next;
}
if (!dm_asprintf(&_lvmetad_token, "filter:%u", ft))
if (dm_asprintf(&_lvmetad_token, "filter:%u", ft) < 0)
log_warn("WARNING: Failed to set lvmetad token. Out of memory?");
}
@ -126,7 +139,10 @@ static daemon_reply _lvmetad_send(const char *id, ...)
va_list ap;
daemon_reply repl;
daemon_request req;
int try = 0;
unsigned num_rescans = 0;
unsigned total_usecs_waited = 0;
unsigned max_remaining_sleep_times = 1;
unsigned wait_usecs;
retry:
req = daemon_request_make(id);
@ -142,13 +158,35 @@ retry:
daemon_request_destroy(req);
/*
* If another process is trying to scan, it might have the
* same future token id and it's better to wait and avoid doing
* the work multiple times. For the case where the future token is
* different, the wait is randomized so that multiple waiting
* processes do not start scanning all at once.
*
* If the token is mismatched because of global_filter changes,
* we re-scan immediately, but if we lose the potential race for
* the update, we back off for a short while (0.05-0.5 seconds) and
* try again.
*/
if (!repl.error && !strcmp(daemon_reply_str(repl, "response", ""), "token_mismatch") &&
try < 2 && !test_mode()) {
if (lvmetad_pvscan_all_devs(_lvmetad_cmd, NULL)) {
++ try;
daemon_reply_destroy(repl);
goto retry;
num_rescans < MAX_RESCANS && total_usecs_waited < (SCAN_TIMEOUT_SECONDS * 1000000) && !test_mode()) {
if (!strcmp(daemon_reply_str(repl, "expected", ""), "update in progress") ||
max_remaining_sleep_times) {
wait_usecs = 50000 + lvm_even_rand(&_lvmetad_cmd->rand_seed, 450000); /* between 0.05s and 0.5s */
(void) usleep(wait_usecs);
total_usecs_waited += wait_usecs;
if (max_remaining_sleep_times)
max_remaining_sleep_times--; /* Sleep once before rescanning the first time, then 5 times each time after that. */
} else {
/* If the re-scan fails here, we try again later. */
(void) lvmetad_pvscan_all_devs(_lvmetad_cmd, NULL);
num_rescans++;
max_remaining_sleep_times = 5;
}
daemon_reply_destroy(repl);
goto retry;
}
return repl;
@ -222,8 +260,9 @@ static int _read_mda(struct lvmcache_info *info,
return 0;
}
static struct lvmcache_info *_pv_populate_lvmcache(
struct cmd_context *cmd, struct dm_config_node *cn, dev_t fallback)
static struct lvmcache_info *_pv_populate_lvmcache(struct cmd_context *cmd,
struct dm_config_node *cn,
dev_t fallback)
{
struct device *dev;
struct id pvid, vgid;
@ -254,7 +293,11 @@ static struct lvmcache_info *_pv_populate_lvmcache(
dev = dev_cache_get_by_devt(fallback, cmd->filter);
if (!dev) {
log_error("No device found for PV %s.", pvid_txt);
dev = dev_cache_get_by_devt(devt, cmd->lvmetad_filter);
if (!dev)
log_error("No device found for PV %s.", pvid_txt);
else
log_warn("WARNING: Device %s for PV %s rejected by a filter.", dev_name(dev), pvid_txt);
return NULL;
}
@ -277,6 +320,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(
return_NULL;
lvmcache_get_label(info)->sector = label_sector;
lvmcache_get_label(info)->dev = dev;
lvmcache_set_device_size(info, devsize);
lvmcache_del_das(info);
lvmcache_del_mdas(info);
@ -304,7 +348,7 @@ static struct lvmcache_info *_pv_populate_lvmcache(
i = 0;
do {
sprintf(da_id, "ea%d", i);
sprintf(da_id, "ba%d", i);
da = dm_config_find_node(cn->child, da_id);
if (da) {
if (!dm_config_get_uint64(da->child, "offset", &offset)) return_0;
@ -323,7 +367,7 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
daemon_reply reply;
int found;
char uuid[64];
struct format_instance *fid;
struct format_instance *fid = NULL;
struct format_instance_ctx fic;
struct dm_config_node *top;
const char *name, *diag_name;
@ -392,8 +436,6 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
pvl->pv->dev = lvmcache_device(info);
if (!pvl->pv->dev)
pvl->pv->status |= MISSING_PV;
else
check_reappeared_pv(vg, pvl->pv);
if (!lvmcache_fid_add_mdas_pv(info, fid)) {
vg = NULL;
goto_out; /* FIXME error path */
@ -407,6 +449,8 @@ struct volume_group *lvmetad_vg_lookup(struct cmd_context *cmd, const char *vgna
}
out:
if (!vg && fid)
fid->fmt->ops->destroy_instance(fid);
daemon_reply_destroy(reply);
return vg;
@ -435,7 +479,6 @@ int lvmetad_vg_update(struct volume_group *vg)
struct pv_list *pvl;
struct lvmcache_info *info;
struct _fixup_baton baton;
struct dm_config_tree *vgmeta;
if (!vg)
return 0;
@ -443,13 +486,14 @@ int lvmetad_vg_update(struct volume_group *vg)
if (!lvmetad_active() || test_mode())
return 1; /* fake it */
if (!(vgmeta = export_vg_to_config_tree(vg)))
return_0;
if (!vg->cft_precommitted) {
log_error(INTERNAL_ERROR "VG update without precommited");
return 0;
}
log_debug_lvmetad("Sending lvmetad updated metadata for VG %s (seqno %" PRIu32 ")", vg->name, vg->seqno);
reply = _lvmetad_send("vg_update", "vgname = %s", vg->name,
"metadata = %t", vgmeta, NULL);
dm_config_destroy(vgmeta);
"metadata = %t", vg->cft_precommitted, NULL);
if (!_lvmetad_handle_reply(reply, "update VG", vg->name, NULL)) {
daemon_reply_destroy(reply);
@ -716,7 +760,8 @@ int lvmetad_pv_found(const struct id *pvid, struct device *dev, const struct for
daemon_reply reply;
struct lvmcache_info *info;
struct dm_config_tree *pvmeta, *vgmeta;
const char *status, *vgid;
const char *status, *vgname, *vgid;
int64_t changed;
int result;
if (!lvmetad_active() || test_mode())
@ -785,11 +830,13 @@ int lvmetad_pv_found(const struct id *pvid, struct device *dev, const struct for
if (result && handler) {
status = daemon_reply_str(reply, "status", "<missing>");
vgname = daemon_reply_str(reply, "vgname", "<missing>");
vgid = daemon_reply_str(reply, "vgid", "<missing>");
changed = daemon_reply_int(reply, "changed", 0);
if (!strcmp(status, "partial"))
handler(_lvmetad_cmd, vgid, 1, CHANGE_AAY);
handler(_lvmetad_cmd, vgname, vgid, 1, changed, CHANGE_AAY);
else if (!strcmp(status, "complete"))
handler(_lvmetad_cmd, vgid, 0, CHANGE_AAY);
handler(_lvmetad_cmd, vgname, vgid, 0, changed, CHANGE_AAY);
else if (!strcmp(status, "orphan"))
;
else
@ -881,18 +928,28 @@ int lvmetad_pvscan_single(struct cmd_context *cmd, struct device *dev,
info = (struct lvmcache_info *) label->info;
baton.vg = NULL;
baton.fid = lvmcache_fmt(info)->ops->create_instance(lvmcache_fmt(info),
&fic);
baton.fid = lvmcache_fmt(info)->ops->create_instance(lvmcache_fmt(info), &fic);
if (!baton.fid)
goto_bad;
if (baton.fid->fmt->features & FMT_OBSOLETE) {
log_error("WARNING: Ignoring obsolete format of metadata (%s) on device %s when using lvmetad",
baton.fid->fmt->name, dev_name(dev));
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);
return 0;
}
lvmcache_foreach_mda(info, _lvmetad_pvscan_single, &baton);
/* LVM1 VGs have no MDAs. */
if (!baton.vg && lvmcache_fmt(info) == get_format_by_name(cmd, "lvm1"))
baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->
ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, 0);
/*
* LVM1 VGs have no MDAs and lvmcache_foreach_mda isn't worth fixing
* to use pseudo-mdas for PVs.
* Note that the single_device parameter also gets ignored and this code
* can scan further devices.
*/
if (!baton.vg && !(baton.fid->fmt->features & FMT_MDAS))
baton.vg = ((struct metadata_area *) dm_list_first(&baton.fid->metadata_areas_in_use))->ops->vg_read(baton.fid, lvmcache_vgname_from_info(info), NULL, 1);
if (!baton.vg)
lvmcache_fmt(info)->ops->destroy_instance(baton.fid);

18
lib/cache/lvmetad.h vendored
View File

@ -23,7 +23,8 @@ struct dm_config_tree;
enum activation_change;
typedef int (*activation_handler) (struct cmd_context *cmd,
const char *vgid, int partial,
const char *vgname, const char *vgid,
int partial, int changed,
enum activation_change activate);
#ifdef LVMETAD_SUPPORT
@ -43,6 +44,19 @@ void lvmetad_set_active(int);
*/
void lvmetad_set_socket(const char *);
/*
* Check whether lvmetad is used.
*/
int lvmetad_used(void);
/*
* Check if lvmetad socket is present (either the one set by lvmetad_set_socket
* or the default one if not set). For example, this may be used before calling
* lvmetad_active() check that does connect to the socket - this would produce
* various connection errors if the socket is not present.
*/
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).
@ -149,6 +163,8 @@ int lvmetad_pvscan_all_devs(struct cmd_context *cmd, activation_handler handler)
# define lvmetad_disconnect() do { } while (0)
# define lvmetad_set_active(a) do { } while (0)
# define lvmetad_set_socket(a) do { } while (0)
# define lvmetad_used() (0)
# define lvmetad_socket_present() (0)
# define lvmetad_active() (0)
# define lvmetad_connect_or_warn() do { } while (0)
# define lvmetad_set_token(a) do { } while (0)

View File

@ -0,0 +1 @@
init_cache_segtypes

View File

@ -0,0 +1,24 @@
# Copyright (C) 2013-2014 Red Hat, Inc. All rights reserved.
#
# This file is part of LVM2.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
srcdir = @srcdir@
top_srcdir = @top_srcdir@
top_builddir = @top_builddir@
SOURCES = cache.c
LIB_SHARED = liblvm2cache.$(LIB_SUFFIX)
LIB_VERSION = $(LIB_VERSION_LVM)
include $(top_builddir)/make.tmpl
install: install_lvm2_plugin

426
lib/cache_segtype/cache.c Normal file
View File

@ -0,0 +1,426 @@
/*
* Copyright (C) 2013-2014 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
*/
#include "lib.h"
#include "toolcontext.h"
#include "segtype.h"
#include "display.h"
#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"
#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?
if (!dm_config_has_node(sn, "data"))
return SEG_LOG_ERROR("Cache data not specified in");
if (!(str = dm_config_find_str(sn, "data", NULL)))
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);
if (!dm_config_has_node(sn, "metadata"))
return SEG_LOG_ERROR("Cache metadata not specified in");
if (!(str = dm_config_find_str(sn, "metadata", NULL)))
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);
if (!dm_config_get_uint32(sn, "chunk_size", &chunk_size))
return SEG_LOG_ERROR("Couldn't read cache chunk_size in");
/*
* Read in features:
* cache_mode = {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 (!get_cache_mode(str, &seg->feature_flags))
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");
}
/*
* Read in policy:
* policy_name = "<policy_name>"
* policy_argc = <# args>
* policy_argv = "[<key> <value>]..."
*
* '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 = ""'.
*/
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 (!dm_config_get_uint32(sn, "policy_argc", &seg->policy_argc))
return SEG_LOG_ERROR("Unable to read policy_argc 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)))
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;
}
static int _cache_pool_text_import_area_count(const struct dm_config_node *sn,
uint32_t *area_count)
{
*area_count = 1;
return 1;
}
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;
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, "\"");
}
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);
}
return 1;
}
static void _destroy(struct segment_type *segtype)
{
dm_free((void *) segtype);
}
#ifdef DEVMAPPER_SUPPORT
static int _target_present(struct cmd_context *cmd,
const struct lv_segment *seg __attribute__((unused)),
unsigned *attributes __attribute__((unused)))
{
uint32_t maj, min, patchlevel;
static int _cache_checked = 0;
static int _cache_present = 0;
if (!_cache_checked) {
_cache_present = target_present(cmd, "cache", 1);
if (!target_version("cache", &maj, &min, &patchlevel)) {
log_error("Failed to determine version of cache kernel module");
return 0;
}
_cache_checked = 1;
if ((maj < 1) ||
((maj == 1) && (min < 3))) {
log_error("The cache kernel module is version %u.%u.%u."
" Version 1.3.0+ is required.",
maj, min, patchlevel);
return 0;
}
}
return _cache_present;
}
static int _modules_needed(struct dm_pool *mem,
const struct lv_segment *seg __attribute__((unused)),
struct dm_list *modules)
{
if (!str_list_add(mem, modules, "cache")) {
log_error("String list allocation failed for cache module.");
return 0;
}
return 1;
}
#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,
#ifdef DEVMAPPER_SUPPORT
.target_present = _target_present,
.modules_needed = _modules_needed,
# ifdef DMEVENTD
# endif /* DMEVENTD */
#endif
.destroy = _destroy,
};
static int _cache_text_import(struct lv_segment *seg,
const struct dm_config_node *sn,
struct dm_hash_table *pv_hash __attribute__((unused)))
{
struct logical_volume *pool_lv, *origin_lv;
const char *name = NULL;
if (!dm_config_has_node(sn, "cache_pool"))
return SEG_LOG_ERROR("cache_pool not specified in");
if (!(name = dm_config_find_str(sn, "cache_pool", NULL)))
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);
if (!dm_config_has_node(sn, "origin"))
return SEG_LOG_ERROR("Cache origin not specified in");
if (!(name = dm_config_find_str(sn, "origin", NULL)))
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);
if (!set_lv_segment_area_lv(seg, 0, origin_lv, 0, 0))
return_0;
if (!attach_pool_lv(seg, pool_lv, NULL, NULL))
return_0;
return 1;
}
static int _cache_text_import_area_count(const struct dm_config_node *sn,
uint32_t *area_count)
{
*area_count = 1;
return 1;
}
static int _cache_text_export(const struct lv_segment *seg, struct formatter *f)
{
if (!seg_lv(seg, 0))
return_0;
outf(f, "cache_pool = \"%s\"", seg->pool_lv->name);
outf(f, "origin = \"%s\"", seg_lv(seg, 0)->name);
return 1;
}
#ifdef DEVMAPPER_SUPPORT
static int _cache_add_target_line(struct dev_manager *dm,
struct dm_pool *mem,
struct cmd_context *cmd __attribute__((unused)),
void **target_state __attribute__((unused)),
struct lv_segment *seg,
const struct lv_activate_opts *laopts __attribute__((unused)),
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);
char *metadata_uuid, *data_uuid, *origin_uuid;
if (!(metadata_uuid = build_dm_uuid(mem, cache_pool_seg->metadata_lv, NULL)))
return_0;
if (!(data_uuid = build_dm_uuid(mem, seg_lv(cache_pool_seg, 0), NULL)))
return_0;
if (!(origin_uuid = build_dm_uuid(mem, seg_lv(seg, 0), NULL)))
return_0;
if (!dm_tree_node_add_cache_target(node, len,
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))
return_0;
return add_areas_line(dm, seg, node, 0u, seg->area_count);
}
#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,
#ifdef DEVMAPPER_SUPPORT
.add_target_line = _cache_add_target_line,
.target_present = _target_present,
.modules_needed = _modules_needed,
# ifdef DMEVENTD
# endif /* DMEVENTD */
#endif
.destroy = _destroy,
};
#ifdef CACHE_INTERNAL /* Shared */
int init_cache_segtypes(struct cmd_context *cmd,
struct segtype_library *seglib)
#else
int init_cache_segtypes(struct cmd_context *cmd,
struct segtype_library *seglib);
int init_cache_segtypes(struct cmd_context *cmd,
struct segtype_library *seglib)
#endif
{
struct segment_type *segtype = dm_zalloc(sizeof(*segtype));
if (!segtype) {
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->ops = &_cache_pool_ops;
segtype->private = NULL;
if (!lvm_register_segtype(seglib, segtype))
return_0;
log_very_verbose("Initialised segtype: %s", segtype->name);
segtype = dm_zalloc(sizeof(*segtype));
if (!segtype) {
log_error("Failed to allocate memory for cache segtype");
return 0;
}
segtype->cmd = cmd;
segtype->name = "cache";
segtype->flags = SEG_CACHE;
segtype->ops = &_cache_ops;
segtype->private = NULL;
if (!lvm_register_segtype(seglib, segtype))
return_0;
log_very_verbose("Initialised segtype: %s", segtype->name);
return 1;
}

View File

@ -1,6 +1,6 @@
/*
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
* Copyright (C) 2004-2014 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -20,12 +20,6 @@
#include "lvm-string.h"
#include "activate.h"
#include "filter.h"
#include "filter-composite.h"
#include "filter-md.h"
#include "filter-mpath.h"
#include "filter-persistent.h"
#include "filter-regex.h"
#include "filter-sysfs.h"
#include "label.h"
#include "lvm-file.h"
#include "format-text.h"
@ -35,7 +29,6 @@
#include "segtype.h"
#include "lvmcache.h"
#include "lvmetad.h"
#include "dev-cache.h"
#include "archiver.h"
#ifdef HAVE_LIBDL
@ -56,7 +49,7 @@
#include <syslog.h>
#include <time.h>
#ifdef linux
#ifdef __linux__
# include <malloc.h>
#endif
@ -263,29 +256,54 @@ static int _check_disable_udev(const char *msg) {
return 0;
}
static int _check_config_by_source(struct cmd_context *cmd, config_source_t source)
{
struct dm_config_tree *cft;
struct cft_check_handle *handle;
if (!(cft = get_config_tree_by_source(cmd, source)) ||
!(handle = get_config_tree_check_handle(cmd, cft)))
return 1;
return config_def_check(handle);
}
static int _check_config(struct cmd_context *cmd)
{
int abort_on_error;
if (!find_config_tree_bool(cmd, config_checks_CFG, NULL))
return 1;
if (!cmd->cft_check_handle) {
if (!(cmd->cft_check_handle = dm_pool_zalloc(cmd->libmem, sizeof(*cmd->cft_check_handle)))) {
log_error("Configuration check handle allocation failed.");
return 0;
}
}
abort_on_error = find_config_tree_bool(cmd, config_abort_on_errors_CFG, NULL);
cmd->cft_check_handle->cft = cmd->cft;
if (!config_def_check(cmd, cmd->cft_check_handle) &&
find_config_tree_bool(cmd, config_abort_on_errors_CFG, NULL)) {
log_error("LVM configuration invalid.");
if ((!_check_config_by_source(cmd, CONFIG_STRING) ||
!_check_config_by_source(cmd, CONFIG_MERGED_FILES) ||
!_check_config_by_source(cmd, CONFIG_FILE)) &&
abort_on_error) {
log_error("LVM_ configuration invalid.");
return 0;
}
return 1;
}
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))) {
log_error("Invalid units specification");
return 0;
}
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);
return 1;
}
static int _process_config(struct cmd_context *cmd)
{
mode_t old_umask;
@ -340,19 +358,10 @@ static int _process_config(struct cmd_context *cmd)
/* activation? */
cmd->default_settings.activation = find_config_tree_bool(cmd, global_activation_CFG, NULL);
set_activation(cmd->default_settings.activation);
set_activation(cmd->default_settings.activation, 0);
cmd->auto_set_activation_skip = find_config_tree_bool(cmd, activation_auto_set_activation_skip_CFG, NULL);
cmd->default_settings.suffix = find_config_tree_bool(cmd, global_suffix_CFG, NULL);
if (!(cmd->default_settings.unit_factor =
units_to_bytes(find_config_tree_str(cmd, global_units_CFG, NULL),
&cmd->default_settings.unit_type))) {
log_error("Invalid units specification");
return 0;
}
read_ahead = find_config_tree_str(cmd, activation_readahead_CFG, NULL);
if (!strcasecmp(read_ahead, "auto"))
cmd->default_settings.read_ahead = DM_READ_AHEAD_AUTO;
@ -414,8 +423,6 @@ static int _process_config(struct cmd_context *cmd)
}
}
cmd->si_unit_consistency = find_config_tree_bool(cmd, global_si_unit_consistency_CFG, NULL);
if ((cn = find_config_tree_node(cmd, activation_mlock_filter_CFG, NULL)))
for (cv = cn->v; cv; cv = cv->next)
if ((cv->type != DM_CFG_STRING) || !cv->v.str[0])
@ -432,6 +439,9 @@ static int _process_config(struct cmd_context *cmd)
/* LVM stores sizes internally in units of 512-byte sectors. */
init_pv_min_size((uint64_t)pv_min_kb * (1024 >> SECTOR_SHIFT));
if (!process_profilable_config(cmd))
return_0;
init_detect_internal_vg_cache_corruption
(find_config_tree_bool(cmd, global_detect_internal_vg_cache_corruption_CFG, NULL));
@ -571,7 +581,7 @@ static int _load_config_file(struct cmd_context *cmd, const char *tag)
return 0;
}
if (!(cfl->cft = config_file_open_and_read(config_file, CONFIG_FILE)))
if (!(cfl->cft = config_file_open_and_read(config_file, CONFIG_FILE, cmd)))
return_0;
dm_list_add(&cmd->config_files, &cfl->list);
@ -607,7 +617,7 @@ static int _init_lvm_conf(struct cmd_context *cmd)
/* Read any additional config files */
static int _init_tag_configs(struct cmd_context *cmd)
{
struct str_list *sl;
struct dm_str_list *sl;
/* Tag list may grow while inside this loop */
dm_list_iterate_items(sl, &cmd->tags) {
@ -620,30 +630,25 @@ static int _init_tag_configs(struct cmd_context *cmd)
static int _init_profiles(struct cmd_context *cmd)
{
static char default_dir[PATH_MAX];
const char *dir;
struct profile_params *pp;
if (!(pp = dm_pool_zalloc(cmd->libmem, sizeof(*pp)))) {
log_error("profile_params alloc failed");
if (!(dir = find_config_tree_str(cmd, config_profile_dir_CFG, NULL)))
return_0;
if (!cmd->profile_params) {
if (!(cmd->profile_params = dm_pool_zalloc(cmd->libmem, sizeof(*cmd->profile_params)))) {
log_error("profile_params alloc failed");
return 0;
}
dm_list_init(&cmd->profile_params->profiles_to_load);
dm_list_init(&cmd->profile_params->profiles);
}
if (!(dm_strncpy(cmd->profile_params->dir, dir, sizeof(cmd->profile_params->dir)))) {
log_error("_init_profiles: dm_strncpy failed");
return 0;
}
if (!(dir = find_config_tree_str(cmd, config_profile_dir_CFG, NULL))) {
if (dm_snprintf(default_dir, sizeof(default_dir), "%s/%s",
cmd->system_dir, DEFAULT_PROFILE_SUBDIR) == -1) {
log_error("Couldn't create default profile path '%s/%s'.",
cmd->system_dir, DEFAULT_PROFILE_SUBDIR);
return 0;
}
dir = default_dir;
}
pp->dir = dm_pool_strdup(cmd->libmem, dir);
dm_list_init(&pp->profiles_to_load);
dm_list_init(&pp->profiles);
cmd->profile_params = pp;
return 1;
}
@ -693,7 +698,7 @@ static void _destroy_config(struct cmd_context *cmd)
{
struct config_tree_list *cfl;
struct dm_config_tree *cft;
struct profile *profile;
struct profile *profile, *tmp_profile;
/*
* Configuration cascade:
@ -712,13 +717,19 @@ static void _destroy_config(struct cmd_context *cmd)
/* CONFIG_PROFILE */
if (cmd->profile_params) {
remove_config_tree_by_source(cmd, CONFIG_PROFILE);
dm_list_iterate_items(profile, &cmd->profile_params->profiles_to_load)
remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
remove_config_tree_by_source(cmd, CONFIG_PROFILE_METADATA);
/*
* Destroy config trees for any loaded profiles and
* move these profiles to profile_to_load list.
* Whenever these profiles are referenced later,
* they will get loaded again automatically.
*/
dm_list_iterate_items_safe(profile, tmp_profile, &cmd->profile_params->profiles) {
config_destroy(profile->cft);
dm_list_iterate_items(profile, &cmd->profile_params->profiles)
config_destroy(profile->cft);
dm_list_init(&cmd->profile_params->profiles_to_load);
dm_list_init(&cmd->profile_params->profiles);
profile->cft = NULL;
dm_list_move(&cmd->profile_params->profiles_to_load, &profile->list);
}
}
/* CONFIG_STRING */
@ -824,7 +835,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
#define MAX_FILTERS 5
#define MAX_FILTERS 6
static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
{
@ -850,15 +861,13 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
}
/* 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
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++;
}
/* device type filter. Required. */
if (!(filters[nr_filt] = lvm_type_filter_create(cmd->dev_types))) {
@ -867,6 +876,19 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
}
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)))
nr_filt++;
}
/* partitioned device filter. Required. */
if (!(filters[nr_filt] = partitioned_filter_create(cmd->dev_types))) {
log_error("Failed to create partitioned device filter");
goto bad;
}
nr_filt++;
/* md component filter. Optional, non-critical. */
if (find_config_tree_bool(cmd, devices_md_component_detection_CFG, NULL)) {
init_md_filtering(1);
@ -874,20 +896,11 @@ static struct dev_filter *_init_filter_components(struct cmd_context *cmd)
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)))
nr_filt++;
}
/* Only build a composite filter if we really need it. */
if (nr_filt == 1)
return filters[0];
if (!(composite = composite_filter_create(nr_filt, filters)))
goto_bad;
return composite;
bad:
while (--nr_filt >= 0)
filters[nr_filt]->destroy(filters[nr_filt]);
@ -897,48 +910,33 @@ bad:
static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache)
{
static char cache_file[PATH_MAX];
const char *dev_cache = NULL, *cache_dir, *cache_file_prefix;
const char *dev_cache;
struct dev_filter *f3 = NULL, *f4 = NULL, *toplevel_components[2] = { 0 };
struct stat st;
const struct dm_config_node *cn;
cmd->dump_filter = 0;
if (!(f3 = _init_filter_components(cmd)))
if (!(cmd->lvmetad_filter = _init_filter_components(cmd)))
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 'cache_dir' or 'cache_file_prefix' is set, ignore 'cache'.
*/
cache_dir = find_config_tree_str(cmd, devices_cache_dir_CFG, NULL);
cache_file_prefix = find_config_tree_str(cmd, devices_cache_file_prefix_CFG, NULL);
if ((cn = find_config_tree_node(cmd, devices_filter_CFG, NULL))) {
if (!(f3 = regex_filter_create(cn->v)))
goto_bad;
toplevel_components[0] = cmd->lvmetad_filter;
toplevel_components[1] = f3;
if (!(f4 = composite_filter_create(2, toplevel_components)))
goto_bad;
} else
f4 = cmd->lvmetad_filter;
if (cache_dir || cache_file_prefix) {
if (dm_snprintf(cache_file, sizeof(cache_file),
"%s%s%s/%s.cache",
cache_dir ? "" : cmd->system_dir,
cache_dir ? "" : "/",
cache_dir ? : DEFAULT_CACHE_SUBDIR,
cache_file_prefix ? : DEFAULT_CACHE_FILE_PREFIX) < 0) {
log_error("Persistent cache filename too long.");
goto bad;
}
} else if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)) &&
(dm_snprintf(cache_file, sizeof(cache_file),
"%s/%s/%s.cache",
cmd->system_dir, DEFAULT_CACHE_SUBDIR,
DEFAULT_CACHE_FILE_PREFIX) < 0)) {
log_error("Persistent cache filename too long.");
goto bad;
}
if (!(dev_cache = find_config_tree_str(cmd, devices_cache_CFG, NULL)))
goto_bad;
if (!dev_cache)
dev_cache = cache_file;
if (!(f4 = persistent_filter_create(cmd->dev_types, f3, dev_cache))) {
if (!(cmd->filter = persistent_filter_create(cmd->dev_types, f4, dev_cache))) {
log_verbose("Failed to create persistent device filter.");
goto bad;
}
@ -959,29 +957,20 @@ static int _init_filters(struct cmd_context *cmd, unsigned load_persistent_cache
load_persistent_cache && !cmd->is_long_lived &&
!stat(dev_cache, &st) &&
(st.st_ctime > config_file_timestamp(cmd->cft)) &&
!persistent_filter_load(f4, NULL))
!persistent_filter_load(cmd->filter, 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;
}
return 1;
bad:
if (f4)
if (f4) /* kills both f3 and cmd->lvmetad_filter */
f4->destroy(f4);
else if (f3)
f3->destroy(f3);
if (toplevel_components[0])
toplevel_components[0]->destroy(toplevel_components[0]);
else {
if (f3)
f3->destroy(f3);
if (cmd->lvmetad_filter)
cmd->lvmetad_filter->destroy(cmd->lvmetad_filter);
}
return 0;
}
@ -1184,6 +1173,11 @@ static int _init_segtypes(struct cmd_context *cmd)
return 0;
#endif
#ifdef CACHE_INTERNAL
if (!init_cache_segtypes(cmd, &seglib))
return 0;
#endif
#ifdef HAVE_LIBDL
/* Load any formats in shared libs unless static */
if (!is_static() &&
@ -1262,7 +1256,6 @@ static int _init_hostname(struct cmd_context *cmd)
static int _init_backup(struct cmd_context *cmd)
{
static char default_dir[PATH_MAX];
uint32_t days, min;
const char *dir;
@ -1281,16 +1274,8 @@ static int _init_backup(struct cmd_context *cmd)
min = (uint32_t) find_config_tree_int(cmd, backup_retain_min_CFG, NULL);
if (dm_snprintf
(default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
DEFAULT_ARCHIVE_SUBDIR) == -1) {
log_error("Couldn't create default archive path '%s/%s'.",
cmd->system_dir, DEFAULT_ARCHIVE_SUBDIR);
return 0;
}
if (!(dir = find_config_tree_str(cmd, backup_archive_dir_CFG, NULL)))
dir = default_dir;
return_0;
if (!archive_init(cmd, dir, days, min,
cmd->default_settings.archive)) {
@ -1301,16 +1286,8 @@ static int _init_backup(struct cmd_context *cmd)
/* set up the backup */
cmd->default_settings.backup = find_config_tree_bool(cmd, backup_backup_CFG, NULL);
if (dm_snprintf
(default_dir, sizeof(default_dir), "%s/%s", cmd->system_dir,
DEFAULT_BACKUP_SUBDIR) == -1) {
log_error("Couldn't create default backup path '%s/%s'.",
cmd->system_dir, DEFAULT_BACKUP_SUBDIR);
return 0;
}
if (!(dir = find_config_tree_str(cmd, backup_backup_dir_CFG, NULL)))
dir = default_dir;
return_0;
if (!backup_init(cmd, dir, cmd->default_settings.backup)) {
log_debug("backup_init failed.");
@ -1376,6 +1353,7 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
{
struct cmd_context *cmd;
FILE *new_stream;
int flags;
#ifdef M_MMAP_MAX
mallopt(M_MMAP_MAX, 0);
@ -1399,6 +1377,7 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
cmd->handles_missing_pvs = 0;
cmd->handles_unknown_segments = 0;
cmd->independent_metadata_areas = 0;
cmd->ignore_clustered_vgs = 0;
cmd->hosttags = 0;
dm_list_init(&cmd->arg_value_groups);
dm_list_init(&cmd->formats);
@ -1419,7 +1398,10 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
goto out;
}
if (is_valid_fd(STDIN_FILENO)) {
/* nohup might set stdin O_WRONLY ! */
if (is_valid_fd(STDIN_FILENO) &&
((flags = fcntl(STDIN_FILENO, F_GETFL)) > 0) &&
(flags & O_ACCMODE) != O_WRONLY) {
if (!_reopen_stream(stdin, STDIN_FILENO, "r", "stdin", &new_stream))
goto_out;
stdin = new_stream;
@ -1429,7 +1411,9 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
}
}
if (is_valid_fd(STDOUT_FILENO)) {
if (is_valid_fd(STDOUT_FILENO) &&
((flags = fcntl(STDOUT_FILENO, F_GETFL)) > 0) &&
(flags & O_ACCMODE) != O_RDONLY) {
if (!_reopen_stream(stdout, STDOUT_FILENO, "w", "stdout", &new_stream))
goto_out;
stdout = new_stream;
@ -1470,6 +1454,11 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
goto out;
}
if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
log_error("Command memory pool creation failed");
goto out;
}
if (!_init_lvm_conf(cmd))
goto_out;
@ -1503,11 +1492,6 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
if (!_init_filters(cmd, 1))
goto_out;
if (!(cmd->mem = dm_pool_create("command", 4 * 1024))) {
log_error("Command memory pool creation failed");
goto out;
}
memlock_init(cmd);
if (!_init_formats(cmd))
@ -1622,6 +1606,8 @@ int refresh_filters(struct cmd_context *cmd)
int refresh_toolcontext(struct cmd_context *cmd)
{
struct dm_config_tree *cft_cmdline, *cft_tmp;
const char *profile_command_name, *profile_metadata_name;
struct profile *profile;
log_verbose("Reloading config files");
@ -1631,7 +1617,7 @@ int refresh_toolcontext(struct cmd_context *cmd)
*/
activation_release();
lvmcache_destroy(cmd, 0);
lvmcache_destroy(cmd, 0, 0);
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
@ -1639,69 +1625,95 @@ int refresh_toolcontext(struct cmd_context *cmd)
cmd->filter->destroy(cmd->filter);
cmd->filter = NULL;
}
dev_cache_exit();
if (!dev_cache_exit())
stack;
_destroy_dev_types(cmd);
_destroy_tags(cmd);
/* save config string passed on the command line */
cft_cmdline = remove_config_tree_by_source(cmd, CONFIG_STRING);
/* save the global profile name used */
profile_command_name = cmd->profile_params->global_command_profile ?
cmd->profile_params->global_command_profile->name : NULL;
profile_metadata_name = cmd->profile_params->global_metadata_profile ?
cmd->profile_params->global_metadata_profile->name : NULL;
_destroy_config(cmd);
cmd->config_initialized = 0;
cmd->hosttags = 0;
cmd->lib_dir = NULL;
if (!_init_lvm_conf(cmd))
return 0;
return_0;
/* Temporary duplicate cft pointer holding lvm.conf - replaced later */
cft_tmp = cmd->cft;
if (cft_cmdline)
cmd->cft = dm_config_insert_cascaded_tree(cft_cmdline, cft_tmp);
/* Reload the global profile. */
if (profile_command_name) {
if (!(profile = add_profile(cmd, profile_command_name, CONFIG_PROFILE_COMMAND)) ||
!override_config_tree_from_profile(cmd, profile))
return_0;
}
if (profile_metadata_name) {
if (!(profile = add_profile(cmd, profile_metadata_name, CONFIG_PROFILE_METADATA)) ||
!override_config_tree_from_profile(cmd, profile))
return_0;
}
/* Uses cmd->cft i.e. cft_cmdline + lvm.conf */
_init_logging(cmd);
/* Init tags from lvm.conf. */
if (!_init_tags(cmd, cft_tmp))
return 0;
return_0;
/* Doesn't change cmd->cft */
if (!_init_tag_configs(cmd))
return 0;
return_0;
/* Merge all the tag config files with lvm.conf, returning a
* fresh cft pointer in place of cft_tmp. */
if (!(cmd->cft = _merge_config_files(cmd, cft_tmp)))
return 0;
return_0;
/* Finally we can make the proper, fully-merged, cmd->cft */
if (cft_cmdline)
cmd->cft = dm_config_insert_cascaded_tree(cft_cmdline, cmd->cft);
if (!_process_config(cmd))
return 0;
return_0;
if (!_init_profiles(cmd))
return_0;
if (!(cmd->dev_types = create_dev_types(cmd->proc_dir,
find_config_tree_node(cmd, devices_types_CFG, NULL))))
return 0;
return_0;
if (!_init_dev_cache(cmd))
return 0;
return_0;
if (!_init_filters(cmd, 0))
return 0;
return_0;
if (!_init_formats(cmd))
return 0;
return_0;
if (!init_lvmcache_orphans(cmd))
return 0;
return_0;
if (!_init_segtypes(cmd))
return 0;
return_0;
if (!_init_backup(cmd))
return 0;
return_0;
cmd->config_initialized = 1;
@ -1713,6 +1725,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
{
struct dm_config_tree *cft_cmdline;
FILE *new_stream;
int flags;
if (cmd->dump_filter && cmd->filter && cmd->filter->dump &&
!cmd->filter->dump(cmd->filter, 1))
@ -1720,7 +1733,7 @@ void destroy_toolcontext(struct cmd_context *cmd)
archive_exit(cmd);
backup_exit(cmd);
lvmcache_destroy(cmd, 0);
lvmcache_destroy(cmd, 0, 0);
label_exit();
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
@ -1745,7 +1758,9 @@ void destroy_toolcontext(struct cmd_context *cmd)
#ifndef VALGRIND_POOL
if (cmd->linebuffer) {
/* Reset stream buffering to defaults */
if (is_valid_fd(STDIN_FILENO)) {
if (is_valid_fd(STDIN_FILENO) &&
((flags = fcntl(STDIN_FILENO, F_GETFL)) > 0) &&
(flags & O_ACCMODE) != O_WRONLY) {
if (_reopen_stream(stdin, STDIN_FILENO, "r", "stdin", &new_stream)) {
stdin = new_stream;
setlinebuf(stdin);
@ -1753,7 +1768,9 @@ void destroy_toolcontext(struct cmd_context *cmd)
cmd->linebuffer = NULL; /* Leave buffer in place (deliberate leak) */
}
if (is_valid_fd(STDOUT_FILENO)) {
if (is_valid_fd(STDOUT_FILENO) &&
((flags = fcntl(STDOUT_FILENO, F_GETFL)) > 0) &&
(flags & O_ACCMODE) != O_RDONLY) {
if (_reopen_stream(stdout, STDOUT_FILENO, "w", "stdout", &new_stream)) {
stdout = new_stream;
setlinebuf(stdout);

View File

@ -19,7 +19,6 @@
#include "dev-cache.h"
#include "dev-type.h"
#include <stdio.h>
#include <limits.h>
/*
@ -87,9 +86,12 @@ struct cmd_context {
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 independent_metadata_areas:1; /* Active formats have MDAs outside PVs */
@ -105,7 +107,6 @@ struct cmd_context {
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) */
struct cft_check_handle *cft_check_handle;
/* selected settings with original default/configured value which can be changed during cmd processing */
struct config_info default_settings;
@ -118,8 +119,10 @@ struct cmd_context {
/* List of defined tags */
struct dm_list tags;
const char *report_list_item_separator;
int hosttags;
const char *lib_dir; /* Cache value global/library_dir */
char system_dir[PATH_MAX];
char dev_dir[PATH_MAX];
char proc_dir[PATH_MAX];
@ -136,6 +139,7 @@ struct cmd_context *create_toolcontext(unsigned is_long_lived,
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);

File diff suppressed because it is too large Load Diff

View File

@ -16,8 +16,7 @@
#ifndef _LVM_CONFIG_H
#define _LVM_CONFIG_H
#include "lvm-types.h"
#include "defaults.h"
#include "libdevmapper.h"
/* 16 bits: 3 bits for major, 4 bits for minor, 9 bits for patchlevel */
/* FIXME Max LVM version supported: 7.15.511. Extend bits when needed. */
@ -31,20 +30,24 @@ typedef enum {
CONFIG_FILE, /* one file config */
CONFIG_MERGED_FILES, /* config that is a result of merging more config files */
CONFIG_STRING, /* config string typed on cmdline using '--config' arg */
CONFIG_PROFILE /* profile config */
CONFIG_PROFILE_COMMAND, /* command profile config */
CONFIG_PROFILE_METADATA,/* metadata profile config */
CONFIG_FILE_SPECIAL /* special purpose file config (e.g. metadata, persistent filter...) */
} config_source_t;
struct profile {
struct dm_list list;
config_source_t source; /* either CONFIG_PROFILE_COMMAND or CONFIG_PROFILE_METADATA */
const char *name;
struct dm_config_tree *cft;
};
struct profile_params {
const char *dir; /* subdir in LVM_SYSTEM_DIR where LVM looks for profiles */
struct profile *global_profile; /* profile that overrides any other VG/LV-based profile ('--profile' cmd line arg) */
struct dm_list profiles_to_load;/* list of profiles which are only added, but still need to be loaded for any use */
struct dm_list profiles; /* list of profiles which are loaded already and which are ready for use */
char dir[PATH_MAX]; /* subdir in LVM_SYSTEM_DIR where LVM looks for profiles */
struct profile *global_command_profile; /* profile (as given by --commandprofile cmd arg) used as global command profile */
struct profile *global_metadata_profile; /* profile (as given by --metadataprofile cmd arg) that overrides any other VG/LV-based profile */
struct dm_list profiles_to_load; /* list of profiles which are only added, but still need to be loaded for any use */
struct dm_list profiles; /* list of profiles which are loaded already and which are ready for use */
};
#define CFG_PATH_MAX_LEN 64
@ -63,11 +66,26 @@ typedef enum {
CFG_TYPE_STRING = 1 << 5, /* setting */
} cfg_def_type_t;
/* function types to evaluate default value at runtime */
typedef int (*t_fn_CFG_TYPE_BOOL) (struct cmd_context *cmd, struct profile *profile);
typedef int (*t_fn_CFG_TYPE_INT) (struct cmd_context *cmd, struct profile *profile);
typedef float (*t_fn_CFG_TYPE_FLOAT) (struct cmd_context *cmd, struct profile *profile);
typedef const char* (*t_fn_CFG_TYPE_STRING) (struct cmd_context *cmd, struct profile *profile);
typedef const char* (*t_fn_CFG_TYPE_ARRAY) (struct cmd_context *cmd, struct profile *profile);
/* configuration definition item value (for item's default value) */
typedef union {
/* static value - returns a variable */
const int v_CFG_TYPE_BOOL, v_CFG_TYPE_INT;
const float v_CFG_TYPE_FLOAT;
const char *v_CFG_TYPE_STRING, *v_CFG_TYPE_ARRAY;
/* run-time value - evaluates a function */
t_fn_CFG_TYPE_BOOL fn_CFG_TYPE_BOOL;
t_fn_CFG_TYPE_INT fn_CFG_TYPE_INT;
t_fn_CFG_TYPE_FLOAT fn_CFG_TYPE_FLOAT;
t_fn_CFG_TYPE_STRING fn_CFG_TYPE_STRING;
t_fn_CFG_TYPE_ARRAY fn_CFG_TYPE_ARRAY;
} cfg_def_value_t;
/* configuration definition item flags: */
@ -82,13 +100,21 @@ typedef union {
#define CFG_UNSUPPORTED 0x08
/* whether the configuration item is customizable by a profile */
#define CFG_PROFILABLE 0x10
/* whether the configuration item is customizable by a profile */
/* and whether it can be attached to VG/LV metadata at the same time
* The CFG_PROFILABLE_METADATA flag incorporates CFG_PROFILABLE flag!!! */
#define CFG_PROFILABLE_METADATA 0x30
/* whether the default value is undefned */
#define CFG_DEFAULT_UNDEFINED 0x40
/* whether the defualt value is calculated during run time */
#define CFG_DEFAULT_RUN_TIME 0x80
/* configuration definition item structure */
typedef struct cfg_def_item {
int id; /* ID of this item */
int parent; /* ID of parent item */
const char *name; /* name of the item in configuration tree */
cfg_def_type_t type; /* configuration item type */
int type; /* configuration item type (bits of cfg_def_type_t) */
cfg_def_value_t default_value; /* default value (only for settings) */
uint16_t flags; /* configuration item definition flags */
uint16_t since_version; /* version this item appeared in */
@ -102,15 +128,21 @@ typedef enum {
CFG_DEF_TREE_COMPLETE, /* CURRENT + MISSING, the tree actually used within execution, not implemented yet */
CFG_DEF_TREE_DEFAULT, /* tree of all possible config nodes with default values */
CFG_DEF_TREE_NEW, /* tree of all new nodes that appeared in given version */
CFG_DEF_TREE_PROFILABLE /* tree of all nodes that are customizable by profiles */
CFG_DEF_TREE_PROFILABLE, /* tree of all nodes that are customizable by profiles */
CFG_DEF_TREE_PROFILABLE_CMD, /* tree of all nodes that are customizable by command profiles (subset of PROFILABLE) */
CFG_DEF_TREE_PROFILABLE_MDA, /* tree of all nodes that are customizable by metadata profiles (subset of PROFILABLE) */
CFG_DEF_TREE_DIFF, /* tree of all nodes that differ from defaults */
} cfg_def_tree_t;
/* configuration definition tree specification */
struct config_def_tree_spec {
struct cmd_context *cmd; /* command context (for run-time defaults */
cfg_def_tree_t type; /* tree type */
uint16_t version; /* tree at this LVM2 version */
int ignoreadvanced; /* do not include advanced configs */
int ignoreunsupported; /* do not include unsupported configs */
unsigned ignoreadvanced:1; /* do not include advanced configs */
unsigned ignoreunsupported:1; /* do not include unsupported configs */
unsigned withcomments:1; /* include comments */
unsigned withversions:1; /* include versions */
uint8_t *check_status; /* status of last tree check (currently needed for CFG_DEF_TREE_MISSING only) */
};
@ -119,6 +151,8 @@ struct config_def_tree_spec {
#define CFG_USED 0x01
/* flag to mark the item as valid in a config tree instance during validation */
#define CFG_VALID 0x02
/* flag to mark the item as having the value different from default one */
#define CFG_DIFF 0x04
/*
* Register ID for each possible item in the configuration tree.
@ -126,33 +160,41 @@ struct config_def_tree_spec {
enum {
#define cfg_section(id, name, parent, flags, since_version, comment) id,
#define cfg(id, name, parent, flags, type, default_value, since_version, comment) id,
#define cfg_runtime(id, name, parent, flags, type, since_version, comment) id,
#define cfg_array(id, name, parent, flags, types, default_value, since_version, comment) id,
#define cfg_array_runtime(id, name, parent, flags, types, since_version, comment) id,
#include "config_settings.h"
#undef cfg_section
#undef cfg
#undef cfg_runtime
#undef cfg_array
#undef cfg_array_runtime
};
struct profile *add_profile(struct cmd_context *cmd, const char *profile_name);
struct profile *add_profile(struct cmd_context *cmd, const char *profile_name, config_source_t source);
int load_profile(struct cmd_context *cmd, struct profile *profile);
int load_pending_profiles(struct cmd_context *cmd);
/* configuration check handle for each instance of the validation check */
struct cft_check_handle {
struct cmd_context *cmd; /* command context */
struct dm_config_tree *cft; /* the tree for which the check is done */
config_source_t source; /* configuration source */
unsigned force_check:1; /* force check even if disabled by config/checks setting */
unsigned skip_if_checked:1; /* skip the check if already done before - return last state */
unsigned suppress_messages:1; /* suppress messages during the check if config item is found invalid */
unsigned check_diff:1; /* check if the value used differs from default one */
uint8_t status[CFG_COUNT]; /* flags for each configuration item - the result of the check */
};
int config_def_get_path(char *buf, size_t buf_size, int id);
int config_def_check(struct cmd_context *cmd, struct cft_check_handle *handle);
int config_def_check(struct cft_check_handle *handle);
int override_config_tree_from_string(struct cmd_context *cmd, const char *config_settings);
int override_config_tree_from_profile(struct cmd_context *cmd, struct profile *profile);
struct dm_config_tree *get_config_tree_by_source(struct cmd_context *, config_source_t source);
struct dm_config_tree *remove_config_tree_by_source(struct cmd_context *cmd, config_source_t source);
struct cft_check_handle *get_config_tree_check_handle(struct cmd_context *cmd, struct dm_config_tree *cft);
config_source_t config_get_source_type(struct dm_config_tree *cft);
typedef uint32_t (*checksum_fn_t) (uint32_t initial, const uint8_t *buf, uint32_t size);
@ -162,9 +204,9 @@ int config_file_read_fd(struct dm_config_tree *cft, struct device *dev,
off_t offset, size_t size, off_t offset2, size_t size2,
checksum_fn_t checksum_fn, uint32_t checksum);
int config_file_read(struct dm_config_tree *cft);
struct dm_config_tree *config_file_open_and_read(const char *config_file, config_source_t source);
int config_write(struct dm_config_tree *cft,
int withcomment, int withversion,
struct dm_config_tree *config_file_open_and_read(const char *config_file, config_source_t source,
struct cmd_context *cmd);
int config_write(struct dm_config_tree *cft, struct config_def_tree_spec *tree_spec,
const char *file, int argc, char **argv);
struct dm_config_tree *config_def_create_tree(struct config_def_tree_spec *spec);
void config_destroy(struct dm_config_tree *cft);
@ -199,4 +241,17 @@ int64_t find_config_tree_int64(struct cmd_context *cmd, int id, struct profile *
float find_config_tree_float(struct cmd_context *cmd, int id, struct profile *profile);
int find_config_tree_bool(struct cmd_context *cmd, int id, struct profile *profile);
/*
* Functions for configuration settings for which the default
* value is evaluated at runtime based on command context.
*/
const char *get_default_devices_cache_dir_CFG(struct cmd_context *cmd, struct profile *profile);
const char *get_default_devices_cache_CFG(struct cmd_context *cmd, struct profile *profile);
const char *get_default_backup_backup_dir_CFG(struct cmd_context *cmd, struct profile *profile);
const char *get_default_backup_archive_dir_CFG(struct cmd_context *cmd, struct profile *profile);
const char *get_default_config_profile_dir_CFG(struct cmd_context *cmd, struct profile *profile);
const char *get_default_activation_mirror_image_fault_policy_CFG(struct cmd_context *cmd, struct profile *profile);
int get_default_allocation_thin_pool_chunk_size_CFG(struct cmd_context *cmd, struct profile *profile);
int get_default_allocation_cache_pool_chunk_size_CFG(struct cmd_context *cmd, struct profile *profile);
#endif

View File

@ -14,15 +14,24 @@
/*
* MACROS:
* cfg_section(id, name, parent, flags, since_version, comment)
* cfg(id, name, parent, flags, type, default_value, since_version, comment)
* cfg_array(id, name, parent, flags, types, default_value, since_version, comment)
* - define a configuration section:
* cfg_section(id, name, parent, flags, since_version, comment)
*
* - define a configuration setting of simple type:
* cfg(id, name, parent, flags, type, default_value, since_version, comment)
*
* - define a configuration array of one or more types:
* cfg_array(id, name, parent, flags, types, default_value, since_version, comment)
*
* If default value can't be assigned statically because it depends on some
* run-time checks or if it depends on other settings already defined,
* the configuration setting or array can be defined with the
* "{cfg|cfg_array}_runtime" macro. In this case the default value
* is evaluated by automatically calling "get_default_<id>" function.
* See config.h and "function types to evaluate default value at runtime".
*
*
* VARIABLES:
* cfg_section: define a new configuration section
* cfg: define a new configuration setting of a simple type
* cfg_array: define a new configuration setting of array type
*
* id: unique identifier
* name: configuration node name
* parent: id of parent configuration node
@ -32,6 +41,8 @@
* CFG_ADVANCED - this node belongs to advanced config set
* CFG_UNSUPPORTED - this node belongs to unsupported config set
* CFG_PROFILABLE - this node is customizable by a profile
* CFG_PROFILABLE_METADATA - profilable and attachable to VG/LV metadata
* CFG_DEFAULT_UNDEFINED - node's default value is undefined
* type: allowed type for the value of simple configuation setting, one of:
* CFG_TYPE_BOOL
* CFG_TYPE_INT
@ -55,6 +66,7 @@
* that parent nodes are consistent with versioning, no check done
* if parent node is older or the same age as any child node!)
*/
#include "defaults.h"
cfg_section(root_CFG_SECTION, "(root)", root_CFG_SECTION, 0, vsn(0, 0, 0), NULL)
@ -64,29 +76,29 @@ cfg_section(allocation_CFG_SECTION, "allocation", root_CFG_SECTION, CFG_PROFILAB
cfg_section(log_CFG_SECTION, "log", root_CFG_SECTION, 0, vsn(1, 0, 0), NULL)
cfg_section(backup_CFG_SECTION, "backup", root_CFG_SECTION, 0, vsn(1, 0, 0), NULL)
cfg_section(shell_CFG_SECTION, "shell", root_CFG_SECTION, 0, vsn(1, 0, 0), NULL)
cfg_section(global_CFG_SECTION, "global", root_CFG_SECTION, 0, vsn(1, 0, 0), NULL)
cfg_section(global_CFG_SECTION, "global", root_CFG_SECTION, CFG_PROFILABLE, vsn(1, 0, 0), NULL)
cfg_section(activation_CFG_SECTION, "activation", root_CFG_SECTION, CFG_PROFILABLE, vsn(1, 0, 0), NULL)
cfg_section(metadata_CFG_SECTION, "metadata", root_CFG_SECTION, CFG_ADVANCED, vsn(1, 0, 0), NULL)
cfg_section(report_CFG_SECTION, "report", root_CFG_SECTION, CFG_ADVANCED, vsn(1, 0, 0), NULL)
cfg_section(report_CFG_SECTION, "report", root_CFG_SECTION, CFG_ADVANCED | CFG_PROFILABLE, vsn(1, 0, 0), NULL)
cfg_section(dmeventd_CFG_SECTION, "dmeventd", root_CFG_SECTION, 0, vsn(1, 2, 3), NULL)
cfg_section(tags_CFG_SECTION, "tags", root_CFG_SECTION, 0, vsn(1, 0, 18), NULL)
cfg(config_checks_CFG, "checks", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 99), "Configuration tree check on each LVM command execution.")
cfg(config_abort_on_errors_CFG, "abort_on_errors", config_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2,2,99), "Abort LVM command execution if configuration is invalid.")
cfg(config_profile_dir_CFG, "profile_dir", config_CFG_SECTION, 0, CFG_TYPE_STRING, 0, vsn(2, 2, 99), "Directory with configuration profiles.")
cfg_runtime(config_profile_dir_CFG, "profile_dir", config_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(2, 2, 99), "Directory with configuration profiles.")
cfg(devices_dir_CFG, "dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DEV_DIR, vsn(1, 0, 0), NULL)
cfg_array(devices_scan_CFG, "scan", devices_CFG_SECTION, 0, CFG_TYPE_STRING, "#S/dev", vsn(1, 0, 0), NULL)
cfg_array(devices_loopfiles_CFG, "loopfiles", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 2, 0), NULL)
cfg_array(devices_loopfiles_CFG, "loopfiles", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 2, 0), NULL)
cfg(devices_obtain_device_list_from_udev_CFG, "obtain_device_list_from_udev", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_OBTAIN_DEVICE_LIST_FROM_UDEV, vsn(2, 2, 85), NULL)
cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(2, 2, 98), NULL)
cfg(devices_cache_CFG, "cache", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(devices_cache_dir_CFG, "cache_dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
cfg(devices_cache_file_prefix_CFG, "cache_file_prefix", devices_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
cfg_array(devices_preferred_names_CFG, "preferred_names", devices_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 2, 19), NULL)
cfg_array(devices_filter_CFG, "filter", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(devices_global_filter_CFG, "global_filter", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 98), NULL)
cfg_runtime(devices_cache_CFG, "cache", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL)
cfg_runtime(devices_cache_dir_CFG, "cache_dir", devices_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 2, 19), NULL)
cfg(devices_cache_file_prefix_CFG, "cache_file_prefix", devices_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_CACHE_FILE_PREFIX, vsn(1, 2, 19), NULL)
cfg(devices_write_cache_state_CFG, "write_cache_state", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(1, 0, 0), NULL)
cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, 0, CFG_TYPE_INT | CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(devices_types_CFG, "types", devices_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT | CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(devices_sysfs_scan_CFG, "sysfs_scan", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSFS_SCAN, vsn(1, 0, 8), NULL)
cfg(devices_multipath_component_detection_CFG, "multipath_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MULTIPATH_COMPONENT_DETECTION, vsn(2, 2, 89), NULL)
cfg(devices_md_component_detection_CFG, "md_component_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MD_COMPONENT_DETECTION, vsn(1, 0, 18), NULL)
@ -96,36 +108,43 @@ cfg(devices_data_alignment_detection_CFG, "data_alignment_detection", devices_CF
cfg(devices_data_alignment_CFG, "data_alignment", devices_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(2, 2, 45), NULL)
cfg(devices_data_alignment_offset_detection_CFG, "data_alignment_offset_detection", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION, vsn(2, 2, 50), NULL)
cfg(devices_ignore_suspended_devices_CFG, "ignore_suspended_devices", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_SUSPENDED_DEVICES, vsn(1, 2, 19), NULL)
cfg(devices_ignore_lvm_mirrors_CFG, "ignore_lvm_mirrors", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_IGNORE_LVM_MIRRORS, vsn(2, 2, 104), NULL)
cfg(devices_disable_after_error_count_CFG, "disable_after_error_count", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_DISABLE_AFTER_ERROR_COUNT, vsn(2, 2, 75), NULL)
cfg(devices_require_restorefile_with_uuid_CFG, "require_restorefile_with_uuid", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID, vsn(2, 2, 73), NULL)
cfg(devices_pv_min_size_CFG, "pv_min_size", devices_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_PV_MIN_SIZE_KB, vsn(2, 2, 85), NULL)
cfg(devices_issue_discards_CFG, "issue_discards", devices_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ISSUE_DISCARDS, vsn(2, 2, 85), NULL)
cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(2, 2, 77), NULL)
cfg_array(allocation_cling_tag_list_CFG, "cling_tag_list", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 77), NULL)
cfg(allocation_maximise_cling_CFG, "maximise_cling", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MAXIMISE_CLING, vsn(2, 2, 85), NULL)
cfg(allocation_use_blkid_wiping_CFG, "use_blkid_wiping", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 105), NULL)
cfg(allocation_wipe_signatures_when_zeroing_new_lvs_CFG, "wipe_signatures_when_zeroing_new_lvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, 1, vsn(2, 2, 105), NULL)
cfg(allocation_mirror_logs_require_separate_pvs_CFG, "mirror_logs_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_MIRROR_LOGS_REQUIRE_SEPARATE_PVS, vsn(2, 2, 85), NULL)
cfg(allocation_cache_pool_metadata_require_separate_pvs_CFG, "cache_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 106), NULL)
cfg_runtime(allocation_cache_pool_chunk_size_CFG, "cache_pool_chunk_size", allocation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 106), NULL)
cfg(allocation_thin_pool_metadata_require_separate_pvs_CFG, "thin_pool_metadata_require_separate_pvs", allocation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS, vsn(2, 2, 89), NULL)
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL)
cfg(allocation_thin_pool_discards_CFG, "thin_pool_discards", allocation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_THIN_POOL_DISCARDS, vsn(2, 2, 99), NULL)
cfg(allocation_thin_pool_chunk_size_CFG, "thin_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_INT, DEFAULT_THIN_POOL_CHUNK_SIZE, vsn(2, 2, 99), NULL)
cfg(allocation_thin_pool_zero_CFG, "thin_pool_zero", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_BOOL, DEFAULT_THIN_POOL_ZERO, vsn(2, 2, 99), NULL)
cfg(allocation_thin_pool_discards_CFG, "thin_pool_discards", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_STRING, DEFAULT_THIN_POOL_DISCARDS, vsn(2, 2, 99), NULL)
cfg(allocation_thin_pool_chunk_size_policy_CFG, "thin_pool_chunk_size_policy", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_STRING, DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY, vsn(2, 2, 101), NULL)
cfg_runtime(allocation_thin_pool_chunk_size_CFG, "thin_pool_chunk_size", allocation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, vsn(2, 2, 99), NULL)
cfg(allocation_physical_extent_size_CFG, "physical_extent_size", allocation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_EXTENT_SIZE, vsn(2, 2, 112), NULL)
cfg(log_verbose_CFG, "verbose", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_VERBOSE, vsn(1, 0, 0), NULL)
cfg(log_silent_CFG, "silent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SILENT, vsn(2, 2, 98), NULL)
cfg(log_syslog_CFG, "syslog", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SYSLOG, vsn(1, 0, 0), NULL)
cfg(log_file_CFG, "file", log_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(log_file_CFG, "file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(log_overwrite_CFG, "overwrite", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_OVERWRITE, vsn(1, 0, 0), NULL)
cfg(log_level_CFG, "level", log_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_LOGLEVEL, vsn(1, 0, 0), NULL)
cfg(log_indent_CFG, "indent", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_INDENT, vsn(1, 0, 0), NULL)
cfg(log_command_names_CFG, "command_names", log_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_CMD_NAME, vsn(1, 0, 0), NULL)
cfg(log_prefix_CFG, "prefix", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_MSG_PREFIX, vsn(1, 0, 0), NULL)
cfg(log_activation_CFG, "activation", log_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL)
cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(log_activate_file_CFG, "activate_file", log_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(log_debug_classes_CFG, "debug_classes", log_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, "#Smemory#Sdevices#Sactivation#Sallocation#Slvmetad#Smetadata#Scache#Slocking", vsn(2, 2, 99), NULL)
cfg(backup_backup_CFG, "backup", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_BACKUP_ENABLED, vsn(1, 0, 0), NULL)
cfg(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_runtime(backup_backup_dir_CFG, "backup_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL)
cfg(backup_archive_CFG, "archive", backup_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ARCHIVE_ENABLED, vsn(1, 0, 0), NULL)
cfg(backup_archive_dir_CFG, "archive_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_runtime(backup_archive_dir_CFG, "archive_dir", backup_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(1, 0, 0), NULL)
cfg(backup_retain_min_CFG, "retain_min", backup_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_ARCHIVE_NUMBER, vsn(1, 0, 0), NULL)
cfg(backup_retain_days_CFG, "retain_days", backup_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_ARCHIVE_DAYS, vsn(1, 0, 0), NULL)
@ -133,14 +152,14 @@ cfg(shell_history_size_CFG, "history_size", shell_CFG_SECTION, 0, CFG_TYPE_INT,
cfg(global_umask_CFG, "umask", global_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_UMASK, vsn(1, 0, 0), NULL)
cfg(global_test_CFG, "test", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(1, 0, 0), NULL)
cfg(global_units_CFG, "units", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_UNITS, vsn(1, 0, 0), NULL)
cfg(global_si_unit_consistency_CFG, "si_unit_consistency", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SI_UNIT_CONSISTENCY, vsn(2, 2, 54), NULL)
cfg(global_units_CFG, "units", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_UNITS, vsn(1, 0, 0), NULL)
cfg(global_si_unit_consistency_CFG, "si_unit_consistency", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_SI_UNIT_CONSISTENCY, vsn(2, 2, 54), NULL)
cfg(global_activation_CFG, "activation", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION, vsn(1, 0, 0), NULL)
cfg(global_suffix_CFG, "suffix", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_SUFFIX, vsn(1, 0, 0), NULL)
cfg(global_suffix_CFG, "suffix", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_SUFFIX, vsn(1, 0, 0), NULL)
cfg(global_fallback_to_lvm1_CFG, "fallback_to_lvm1", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LVM1, vsn(1, 0, 18), NULL)
cfg(global_format_CFG, "format", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_FORMAT, vsn(1, 0, 0), NULL)
cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg_array(global_format_libraries_CFG, "format_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(global_segment_libraries_CFG, "segment_libraries", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg(global_proc_CFG, "proc", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PROC_DIR, vsn(1, 0, 0), NULL)
cfg(global_locking_type_CFG, "locking_type", global_CFG_SECTION, 0, CFG_TYPE_INT, 1, vsn(1, 0, 0), NULL)
cfg(global_wait_for_locks_CFG, "wait_for_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_WAIT_FOR_LOCKS, vsn(2, 2, 50), NULL)
@ -148,21 +167,26 @@ cfg(global_fallback_to_clustered_locking_CFG, "fallback_to_clustered_locking", g
cfg(global_fallback_to_local_locking_CFG, "fallback_to_local_locking", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_FALLBACK_TO_LOCAL_LOCKING, vsn(2, 2, 42), NULL)
cfg(global_locking_dir_CFG, "locking_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LOCK_DIR, vsn(1, 0, 0), NULL)
cfg(global_prioritise_write_locks_CFG, "prioritise_write_locks", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_PRIORITISE_WRITE_LOCKS, vsn(2, 2, 52), NULL)
cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(global_library_dir_CFG, "library_dir", global_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(global_locking_library_CFG, "locking_library", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, DEFAULT_LOCKING_LIB, vsn(1, 0, 0), NULL)
cfg(global_abort_on_internal_errors_CFG, "abort_on_internal_errors", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ABORT_ON_INTERNAL_ERRORS, vsn(2, 2, 57), NULL)
cfg(global_detect_internal_vg_cache_corruption_CFG, "detect_internal_vg_cache_corruption", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DETECT_INTERNAL_VG_CACHE_CORRUPTION, vsn(2, 2, 96), NULL)
cfg(global_metadata_read_only_CFG, "metadata_read_only", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_METADATA_READ_ONLY, vsn(2, 2, 75), NULL)
cfg(global_mirror_segtype_default_CFG, "mirror_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_SEGTYPE, vsn(2, 2, 87), NULL)
cfg(global_raid10_segtype_default_CFG, "raid10_segtype_default", global_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_RAID10_SEGTYPE, vsn(2, 2, 99), NULL)
cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_path", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH, vsn(2, 2, 89), NULL)
cfg(global_lvdisplay_shows_full_device_path_CFG, "lvdisplay_shows_full_device_path", global_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_LVDISPLAY_SHOWS_FULL_DEVICE_PATH, vsn(2, 2, 89), NULL)
cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 93), NULL)
cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), NULL)
cfg_array(global_thin_check_options_CFG, "thin_check_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_THIN_CHECK_OPTIONS, vsn(2, 2, 96), NULL)
cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S", vsn(2, 2, 99), NULL)
cfg_array(global_thin_disabled_features_CFG, "thin_disabled_features", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(2, 2, 99), NULL)
cfg(global_thin_dump_executable_CFG, "thin_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_DUMP_CMD, vsn(2, 2, 100), NULL)
cfg(global_thin_repair_executable_CFG, "thin_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, THIN_REPAIR_CMD, vsn(2, 2, 100), NULL)
cfg_array(global_thin_repair_options_CFG, "thin_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_THIN_REPAIR_OPTIONS, vsn(2, 2, 100), NULL)
cfg(global_cache_check_executable_CFG, "cache_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_CHECK_CMD, vsn(2, 2, 108), NULL)
cfg_array(global_cache_check_options_CFG, "cache_check_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_CHECK_OPTIONS, vsn(2, 2, 108), NULL)
cfg(global_cache_dump_executable_CFG, "cache_dump_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_DUMP_CMD, vsn(2, 2, 108), NULL)
cfg(global_cache_repair_executable_CFG, "cache_repair_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, CACHE_REPAIR_CMD, vsn(2, 2, 108), NULL)
cfg_array(global_cache_repair_options_CFG, "cache_repair_options", global_CFG_SECTION, 0, CFG_TYPE_STRING, "#S" DEFAULT_CACHE_REPAIR_OPTIONS, vsn(2, 2, 108), NULL)
cfg(activation_checks_CFG, "checks", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_ACTIVATION_CHECKS, vsn(2, 2, 86), NULL)
cfg(activation_udev_sync_CFG, "udev_sync", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_UDEV_SYNC, vsn(2, 2, 51), NULL)
@ -174,66 +198,77 @@ cfg(activation_use_linear_target_CFG, "use_linear_target", activation_CFG_SECTIO
cfg(activation_reserved_stack_CFG, "reserved_stack", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RESERVED_STACK, vsn(1, 0, 0), NULL)
cfg(activation_reserved_memory_CFG, "reserved_memory", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RESERVED_MEMORY, vsn(1, 0, 0), NULL)
cfg(activation_process_priority_CFG, "process_priority", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_PROCESS_PRIORITY, vsn(1, 0, 0), NULL)
cfg_array(activation_volume_list_CFG, "volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg_array(activation_auto_activation_volume_list_CFG, "auto_activation_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(2, 2, 97), NULL)
cfg_array(activation_read_only_volume_list_CFG, "read_only_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(2, 2, 89), NULL)
cfg_array(activation_volume_list_CFG, "volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY|CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg_array(activation_auto_activation_volume_list_CFG, "auto_activation_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 97), NULL)
cfg_array(activation_read_only_volume_list_CFG, "read_only_volume_list", activation_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 89), NULL)
cfg(activation_mirror_region_size_CFG, "mirror_region_size", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RAID_REGION_SIZE, vsn(1, 0, 0), NULL)
cfg(activation_raid_region_size_CFG, "raid_region_size", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_RAID_REGION_SIZE, vsn(2, 2, 99), NULL)
cfg(activation_readahead_CFG, "readahead", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_READ_AHEAD, vsn(1, 0, 23), NULL)
cfg(activation_raid_fault_policy_CFG, "raid_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_RAID_FAULT_POLICY, vsn(2, 2, 89), NULL)
cfg(activation_mirror_device_fault_policy_CFG, "mirror_device_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_DEVICE_FAULT_POLICY, vsn(1, 2, 10), NULL)
cfg(activation_mirror_log_fault_policy_CFG, "mirror_log_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_MIRROR_LOG_FAULT_POLICY, vsn(1, 2, 18), NULL)
cfg(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(2, 2, 57), NULL)
cfg_runtime(activation_mirror_image_fault_policy_CFG, "mirror_image_fault_policy", activation_CFG_SECTION, 0, CFG_TYPE_STRING, vsn(2, 2, 57), NULL)
cfg(activation_snapshot_autoextend_threshold_CFG, "snapshot_autoextend_threshold", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_THRESHOLD, vsn(2, 2, 75), NULL)
cfg(activation_snapshot_autoextend_percent_CFG, "snapshot_autoextend_percent", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_SNAPSHOT_AUTOEXTEND_PERCENT, vsn(2, 2, 75), NULL)
cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD, vsn(2, 2, 89), NULL)
cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent", activation_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT, vsn(2, 2, 89), NULL)
cfg_array(activation_mlock_filter_CFG, "mlock_filter", activation_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(2, 2, 62), NULL)
cfg(activation_thin_pool_autoextend_threshold_CFG, "thin_pool_autoextend_threshold", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_THRESHOLD, vsn(2, 2, 89), NULL)
cfg(activation_thin_pool_autoextend_percent_CFG, "thin_pool_autoextend_percent", activation_CFG_SECTION, CFG_PROFILABLE | CFG_PROFILABLE_METADATA, CFG_TYPE_INT, DEFAULT_THIN_POOL_AUTOEXTEND_PERCENT, vsn(2, 2, 89), NULL)
cfg_array(activation_mlock_filter_CFG, "mlock_filter", activation_CFG_SECTION, CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(2, 2, 62), NULL)
cfg(activation_use_mlockall_CFG, "use_mlockall", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_USE_MLOCKALL, vsn(2, 2, 62), NULL)
cfg(activation_monitoring_CFG, "monitoring", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_DMEVENTD_MONITOR, vsn(2, 2, 63), NULL)
cfg(activation_polling_interval_CFG, "polling_interval", activation_CFG_SECTION, 0, CFG_TYPE_INT, DEFAULT_INTERVAL, vsn(2, 2, 63), NULL)
cfg(activation_auto_set_activation_skip_CFG, "auto_set_activation_skip", activation_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_AUTO_SET_ACTIVATION_SKIP, vsn(2,2,99), NULL)
cfg(activation_mode_CFG, "activation_mode", activation_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_ACTIVATION_MODE, vsn(2,2,108), NULL)
cfg(metadata_pvmetadatacopies_CFG, "pvmetadatacopies", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_PVMETADATACOPIES, vsn(1, 0, 0), NULL)
cfg(metadata_vgmetadatacopies_CFG, "vgmetadatacopies", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_VGMETADATACOPIES, vsn(2, 2, 69), NULL)
cfg(metadata_pvmetadatasize_CFG, "pvmetadatasize", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_PVMETADATASIZE, vsn(1, 0, 0), NULL)
cfg(metadata_pvmetadataignore_CFG, "pvmetadataignore", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_BOOL, DEFAULT_PVMETADATAIGNORE, vsn(2, 2, 69), NULL)
cfg(metadata_stripesize_CFG, "stripesize", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_INT, DEFAULT_STRIPESIZE, vsn(1, 0, 0), NULL)
cfg_array(metadata_dirs_CFG, "dirs", metadata_CFG_SECTION, CFG_ADVANCED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(metadata_disk_areas_CFG, "disk_areas", metadata_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_ADVANCED | CFG_UNSUPPORTED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg_array(metadata_dirs_CFG, "dirs", metadata_CFG_SECTION, CFG_ADVANCED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(report_aligned_CFG, "aligned", report_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REP_ALIGNED, vsn(1, 0, 0), NULL)
cfg(report_buffered_CFG, "buffered", report_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REP_BUFFERED, vsn(1, 0, 0), NULL)
cfg(report_headings_CFG, "headings", report_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REP_HEADINGS, vsn(1, 0, 0), NULL)
cfg(report_separator_CFG, "separator", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_REP_SEPARATOR, vsn(1, 0, 0), NULL)
cfg(report_prefixes_CFG, "prefixes", report_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REP_PREFIXES, vsn(2, 2, 36), NULL)
cfg(report_quoted_CFG, "quoted", report_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REP_QUOTED, vsn(2, 2, 39), NULL)
cfg(report_colums_as_rows_CFG, "colums_as_rows", report_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_REP_COLUMNS_AS_ROWS, vsn(1, 0, 0), NULL)
cfg(report_lvs_sort_CFG, "lvs_sort", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LVS_SORT, vsn(1, 0, 0), NULL)
cfg(report_lvs_cols_CFG, "lvs_cols", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LVS_COLS, vsn(1, 0, 0), NULL)
cfg(report_lvs_cols_verbose_CFG, "lvs_cols_verbose", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_LVS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_vgs_sort_CFG, "vgs_sort", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_VGS_SORT, vsn(1, 0, 0), NULL)
cfg(report_vgs_cols_CFG, "vgs_cols", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_VGS_COLS, vsn(1, 0, 0), NULL)
cfg(report_vgs_cols_verbose_CFG, "vgs_cols_verbose", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_VGS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_pvs_sort_CFG, "pvs_sort", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PVS_SORT, vsn(1, 0, 0), NULL)
cfg(report_pvs_cols_CFG, "pvs_cols", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PVS_COLS, vsn(1, 0, 0), NULL)
cfg(report_pvs_cols_verbose_CFG, "pvs_cols_verbose", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PVS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_segs_sort_CFG, "segs_sort", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SEGS_SORT, vsn(1, 0, 0), NULL)
cfg(report_segs_cols_CFG, "segs_cols", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SEGS_COLS, vsn(1, 0, 0), NULL)
cfg(report_segs_cols_verbose_CFG, "segs_cols_verbose", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_SEGS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_pvsegs_sort_CFG, "pvsegs_sort", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PVSEGS_SORT, vsn(1, 1, 3), NULL)
cfg(report_pvsegs_cols_CFG, "pvsegs_cols", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PVSEGS_COLS, vsn(1, 1, 3), NULL)
cfg(report_pvsegs_cols_verbose_CFG, "pvsegs_cols_verbose", report_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_PVSEGS_COLS_VERB, vsn(1, 1, 3), NULL)
cfg_section(metadata_disk_areas_CFG_SUBSECTION, "disk_areas", metadata_CFG_SECTION, CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, vsn(1, 0, 0), NULL)
cfg_section(disk_area_CFG_SUBSECTION, "disk_area", metadata_disk_areas_CFG_SUBSECTION, CFG_NAME_VARIABLE | CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, vsn(1, 0, 0), NULL)
cfg(disk_area_start_sector_CFG, "start_sector", disk_area_CFG_SUBSECTION, CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(1, 0, 0), NULL)
cfg(disk_area_size_CFG, "size", disk_area_CFG_SUBSECTION, CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_INT, 0, vsn(1, 0, 0), NULL)
cfg(disk_area_id_CFG, "id", disk_area_CFG_SUBSECTION, CFG_ADVANCED | CFG_UNSUPPORTED | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 0), NULL)
cfg(report_aligned_CFG, "aligned", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_ALIGNED, vsn(1, 0, 0), NULL)
cfg(report_buffered_CFG, "buffered", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_BUFFERED, vsn(1, 0, 0), NULL)
cfg(report_headings_CFG, "headings", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_HEADINGS, vsn(1, 0, 0), NULL)
cfg(report_separator_CFG, "separator", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_REP_SEPARATOR, vsn(1, 0, 0), NULL)
cfg(report_list_item_separator_CFG, "list_item_separator", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_REP_LIST_ITEM_SEPARATOR, vsn(2, 2, 108), NULL)
cfg(report_prefixes_CFG, "prefixes", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_PREFIXES, vsn(2, 2, 36), NULL)
cfg(report_quoted_CFG, "quoted", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_QUOTED, vsn(2, 2, 39), NULL)
cfg(report_colums_as_rows_CFG, "colums_as_rows", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, DEFAULT_REP_COLUMNS_AS_ROWS, vsn(1, 0, 0), NULL)
cfg(report_binary_values_as_numeric_CFG, "binary_values_as_numeric", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_BOOL, 0, vsn(2, 2, 108), NULL)
cfg(report_devtypes_sort_CFG, "devtypes_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_SORT, vsn(2, 2, 101), NULL)
cfg(report_devtypes_cols_CFG, "devtypes_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_COLS, vsn(2, 2, 101), NULL)
cfg(report_devtypes_cols_verbose_CFG, "devtypes_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_DEVTYPES_COLS_VERB, vsn(2, 2, 101), NULL)
cfg(report_lvs_sort_CFG, "lvs_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_LVS_SORT, vsn(1, 0, 0), NULL)
cfg(report_lvs_cols_CFG, "lvs_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_LVS_COLS, vsn(1, 0, 0), NULL)
cfg(report_lvs_cols_verbose_CFG, "lvs_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_LVS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_vgs_sort_CFG, "vgs_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_VGS_SORT, vsn(1, 0, 0), NULL)
cfg(report_vgs_cols_CFG, "vgs_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_VGS_COLS, vsn(1, 0, 0), NULL)
cfg(report_vgs_cols_verbose_CFG, "vgs_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_VGS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_pvs_sort_CFG, "pvs_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_PVS_SORT, vsn(1, 0, 0), NULL)
cfg(report_pvs_cols_CFG, "pvs_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_PVS_COLS, vsn(1, 0, 0), NULL)
cfg(report_pvs_cols_verbose_CFG, "pvs_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_PVS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_segs_sort_CFG, "segs_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_SEGS_SORT, vsn(1, 0, 0), NULL)
cfg(report_segs_cols_CFG, "segs_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_SEGS_COLS, vsn(1, 0, 0), NULL)
cfg(report_segs_cols_verbose_CFG, "segs_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_SEGS_COLS_VERB, vsn(1, 0, 0), NULL)
cfg(report_pvsegs_sort_CFG, "pvsegs_sort", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_PVSEGS_SORT, vsn(1, 1, 3), NULL)
cfg(report_pvsegs_cols_CFG, "pvsegs_cols", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_PVSEGS_COLS, vsn(1, 1, 3), NULL)
cfg(report_pvsegs_cols_verbose_CFG, "pvsegs_cols_verbose", report_CFG_SECTION, CFG_PROFILABLE, CFG_TYPE_STRING, DEFAULT_PVSEGS_COLS_VERB, vsn(1, 1, 3), NULL)
cfg(dmeventd_mirror_library_CFG, "mirror_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_MIRROR_LIB, vsn(1, 2, 3), NULL)
cfg(dmeventd_raid_library_CFG, "raid_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_RAID_LIB, vsn(2, 2, 87), NULL)
cfg(dmeventd_snapshot_library_CFG, "snapshot_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_SNAPSHOT_LIB, vsn(1, 2, 26), NULL)
cfg(dmeventd_thin_library_CFG, "thin_library", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_THIN_LIB, vsn(2, 2, 89), NULL)
cfg(dmeventd_executable_CFG, "executable", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, NULL, vsn(2, 2, 73), NULL)
cfg(dmeventd_executable_CFG, "executable", dmeventd_CFG_SECTION, 0, CFG_TYPE_STRING, DEFAULT_DMEVENTD_PATH, vsn(2, 2, 73), NULL)
cfg(tags_hosttags_CFG, "hosttags", tags_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_HOSTTAGS, vsn(1, 0, 18), NULL)
cfg_section(tag_CFG_SUBSECTION, "tag", tags_CFG_SECTION, CFG_NAME_VARIABLE, vsn(1, 0, 18), NULL)
cfg(tag_host_list_CFG, "host_list", tag_CFG_SUBSECTION, CFG_ALLOW_EMPTY, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg_section(tag_CFG_SUBSECTION, "tag", tags_CFG_SECTION, CFG_NAME_VARIABLE | CFG_DEFAULT_UNDEFINED, vsn(1, 0, 18), NULL)
cfg(tag_host_list_CFG, "host_list", tag_CFG_SUBSECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_UNDEFINED, CFG_TYPE_STRING, NULL, vsn(1, 0, 18), NULL)
cfg(CFG_COUNT, NULL, root_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL)

View File

@ -33,8 +33,9 @@
#define DEFAULT_SYSFS_SCAN 1
#define DEFAULT_MD_COMPONENT_DETECTION 1
#define DEFAULT_MD_CHUNK_ALIGNMENT 1
#define DEFAULT_IGNORE_LVM_MIRRORS 1
#define DEFAULT_MULTIPATH_COMPONENT_DETECTION 1
#define DEFAULT_IGNORE_SUSPENDED_DEVICES 1
#define DEFAULT_IGNORE_SUSPENDED_DEVICES 0
#define DEFAULT_DISABLE_AFTER_ERROR_COUNT 0
#define DEFAULT_REQUIRE_RESTOREFILE_WITH_UUID 1
#define DEFAULT_DATA_ALIGNMENT_OFFSET_DETECTION 1
@ -65,16 +66,36 @@
#define DEFAULT_DMEVENTD_MONITOR 1
#define DEFAULT_BACKGROUND_POLLING 1
#define DEFAULT_THIN_CHECK_OPTIONS "-q"
#ifndef DMEVENTD_PATH
# define DEFAULT_DMEVENTD_PATH ""
#else
# define DEFAULT_DMEVENTD_PATH DMEVENTD_PATH
#endif
#ifdef THIN_CHECK_NEEDS_CHECK
# define DEFAULT_THIN_CHECK_OPTIONS "-q --clear-needs-check-flag"
#else
# define DEFAULT_THIN_CHECK_OPTIONS "-q"
#endif
#define DEFAULT_THIN_REPAIR_OPTIONS ""
#define DEFAULT_THIN_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_THIN_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_THIN_POOL_OPTIMAL_SIZE (128 * 1024 * 1024) /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_POLICY "generic"
#define DEFAULT_THIN_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_THIN_POOL_CHUNK_SIZE_PERFORMANCE 512 /* KB */
#define DEFAULT_THIN_POOL_DISCARDS "passdown"
#define DEFAULT_THIN_POOL_ZERO 1
#define DEFAULT_POOL_METADATA_SPARE 1
#define DEFAULT_POOL_METADATA_SPARE 1 /* thin + cache */
#define DEFAULT_CACHE_CHECK_OPTIONS "-q"
#define DEFAULT_CACHE_REPAIR_OPTIONS ""
#define DEFAULT_CACHE_POOL_METADATA_REQUIRE_SEPARATE_PVS 0
#define DEFAULT_CACHE_POOL_CHUNK_SIZE 64 /* KB */
#define DEFAULT_CACHE_POOL_MIN_METADATA_SIZE 2048 /* KB */
#define DEFAULT_CACHE_POOL_MAX_METADATA_SIZE (16 * 1024 * 1024) /* KB */
#define DEFAULT_UMASK 0077
@ -135,14 +156,16 @@
#ifdef DEVMAPPER_SUPPORT
# define DEFAULT_ACTIVATION 1
# define DEFAULT_RESERVED_MEMORY 8192
# define DEFAULT_RESERVED_STACK 64 /* KB */
# define DEFAULT_PROCESS_PRIORITY -18
#else
# define DEFAULT_ACTIVATION 0
#endif
#define DEFAULT_RESERVED_MEMORY 8192
#define DEFAULT_RESERVED_STACK 64 /* KB */
#define DEFAULT_PROCESS_PRIORITY -18
#define DEFAULT_AUTO_SET_ACTIVATION_SKIP 1
#define DEFAULT_ACTIVATION_MODE "degraded"
#define DEFAULT_USE_LINEAR_TARGET 1
#define DEFAULT_STRIPE_FILLER "error"
#define DEFAULT_RAID_REGION_SIZE 512 /* KB */
@ -159,24 +182,28 @@
#define DEFAULT_REP_PREFIXES 0
#define DEFAULT_REP_QUOTED 1
#define DEFAULT_REP_SEPARATOR " "
#define DEFAULT_REP_LIST_ITEM_SEPARATOR ","
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,move_pv,mirror_log,copy_percent,convert_lv"
#define DEFAULT_LVS_COLS "lv_name,vg_name,lv_attr,lv_size,pool_lv,origin,data_percent,metadata_percent,move_pv,mirror_log,copy_percent,convert_lv"
#define DEFAULT_VGS_COLS "vg_name,pv_count,lv_count,snap_count,vg_attr,vg_size,vg_free"
#define DEFAULT_PVS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free"
#define DEFAULT_SEGS_COLS "lv_name,vg_name,lv_attr,stripes,segtype,seg_size"
#define DEFAULT_PVSEGS_COLS "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size"
#define DEFAULT_DEVTYPES_COLS "devtype_name,devtype_max_partitions,devtype_description"
#define DEFAULT_LVS_COLS_VERB "lv_name,vg_name,seg_count,lv_attr,lv_size,lv_major,lv_minor,lv_kernel_major,lv_kernel_minor,pool_lv,origin,data_percent,metadata_percent,move_pv,copy_percent,mirror_log,convert_lv,lv_uuid,lv_profile"
#define DEFAULT_VGS_COLS_VERB "vg_name,vg_attr,vg_extent_size,pv_count,lv_count,snap_count,vg_size,vg_free,vg_uuid,vg_profile"
#define DEFAULT_PVS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,dev_size,pv_uuid"
#define DEFAULT_SEGS_COLS_VERB "lv_name,vg_name,lv_attr,seg_start,seg_size,stripes,segtype,stripesize,chunksize"
#define DEFAULT_PVSEGS_COLS_VERB "pv_name,vg_name,pv_fmt,pv_attr,pv_size,pv_free,pvseg_start,pvseg_size,lv_name,seg_start_pe,segtype,seg_pe_ranges"
#define DEFAULT_DEVTYPES_COLS_VERB "devtype_name,devtype_max_partitions,devtype_description"
#define DEFAULT_LVS_SORT "vg_name,lv_name"
#define DEFAULT_VGS_SORT "vg_name"
#define DEFAULT_PVS_SORT "pv_name"
#define DEFAULT_SEGS_SORT "vg_name,lv_name,seg_start"
#define DEFAULT_PVSEGS_SORT "pv_name,pvseg_start"
#define DEFAULT_DEVTYPES_SORT "devtype_name"
#define DEFAULT_MIRROR_DEVICE_FAULT_POLICY "remove"
#define DEFAULT_MIRROR_LOG_FAULT_POLICY "allocate"

View File

@ -30,10 +30,37 @@ struct dm_list *str_list_create(struct dm_pool *mem)
return sl;
}
static int _str_list_add_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str, int as_first)
{
struct dm_str_list *sln;
if (!str)
return_0;
if (!(sln = dm_pool_alloc(mem, sizeof(*sln))))
return_0;
sln->str = str;
if (as_first)
dm_list_add_h(sll, &sln->list);
else
dm_list_add(sll, &sln->list);
return 1;
}
int str_list_add_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str)
{
return _str_list_add_no_dup_check(mem, sll, str, 0);
}
int str_list_add_h_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str)
{
return _str_list_add_no_dup_check(mem, sll, str, 1);
}
int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str)
{
struct str_list *sln;
if (!str)
return_0;
@ -41,13 +68,7 @@ int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str)
if (str_list_match_item(sll, str))
return 1;
if (!(sln = dm_pool_alloc(mem, sizeof(*sln))))
return_0;
sln->str = str;
dm_list_add(sll, &sln->list);
return 1;
return str_list_add_no_dup_check(mem, sll, str);
}
void str_list_del(struct dm_list *sll, const char *str)
@ -55,14 +76,14 @@ void str_list_del(struct dm_list *sll, const char *str)
struct dm_list *slh, *slht;
dm_list_iterate_safe(slh, slht, sll)
if (!strcmp(str, dm_list_item(slh, struct str_list)->str))
if (!strcmp(str, dm_list_item(slh, struct dm_str_list)->str))
dm_list_del(slh);
}
int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
const struct dm_list *sllold)
{
struct str_list *sl;
struct dm_str_list *sl;
dm_list_init(sllnew);
@ -79,7 +100,7 @@ int str_list_dup(struct dm_pool *mem, struct dm_list *sllnew,
*/
int str_list_match_item(const struct dm_list *sll, const char *str)
{
struct str_list *sl;
struct dm_str_list *sl;
dm_list_iterate_items(sl, sll)
if (!strcmp(str, sl->str))
@ -94,7 +115,7 @@ int str_list_match_item(const struct dm_list *sll, const char *str)
*/
int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, const char **tag_matched)
{
struct str_list *sl;
struct dm_str_list *sl;
dm_list_iterate_items(sl, sll)
if (str_list_match_item(sll2, sl->str)) {
@ -111,7 +132,7 @@ int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, c
*/
int str_list_lists_equal(const struct dm_list *sll, const struct dm_list *sll2)
{
struct str_list *sl;
struct dm_str_list *sl;
if (dm_list_size(sll) != dm_list_size(sll2))
return 0;

View File

@ -16,8 +16,13 @@
#ifndef _LVM_STR_LIST_H
#define _LVM_STR_LIST_H
struct dm_list;
struct dm_pool;
struct dm_list *str_list_create(struct dm_pool *mem);
int str_list_add(struct dm_pool *mem, struct dm_list *sll, const char *str);
int str_list_add_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str);
int str_list_add_h_no_dup_check(struct dm_pool *mem, struct dm_list *sll, const char *str);
void str_list_del(struct dm_list *sll, const char *str);
int str_list_match_item(const struct dm_list *sll, const char *str);
int str_list_match_list(const struct dm_list *sll, const struct dm_list *sll2, const char **tag_matched);

View File

@ -14,13 +14,13 @@
*/
#include "lib.h"
#include "dev-cache.h"
#include "lvm-types.h"
#include "btree.h"
#include "filter.h"
#include "config.h"
#include "toolcontext.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#endif
#include <unistd.h>
#include <sys/param.h>
#include <dirent.h>
@ -52,11 +52,13 @@ static struct {
#define _free(x) dm_pool_free(_cache.mem, (x))
#define _strdup(x) dm_pool_strdup(_cache.mem, (x))
static int _insert(const char *path, int rec, int check_with_udev_db);
static int _insert(const char *path, const struct stat *info,
int rec, int check_with_udev_db);
/* Setup non-zero members of passed zeroed 'struct device' */
static void _dev_init(struct device *dev, int max_error_count)
{
dev->phys_block_size = -1;
dev->block_size = -1;
dev->fd = -1;
dev->read_ahead = -1;
@ -67,7 +69,7 @@ static void _dev_init(struct device *dev, int max_error_count)
}
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias, int use_malloc)
struct dm_str_list *alias, int use_malloc)
{
int allocate = !dev;
@ -78,7 +80,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
return NULL;
}
if (!(alias = dm_zalloc(sizeof(*alias)))) {
log_error("struct str_list allocation failed");
log_error("struct dm_str_list allocation failed");
dm_free(dev);
return NULL;
}
@ -94,7 +96,7 @@ struct device *dev_create_file(const char *filename, struct device *dev,
return NULL;
}
if (!(alias = _zalloc(sizeof(*alias)))) {
log_error("struct str_list allocation failed");
log_error("struct dm_str_list allocation failed");
_free(dev);
return NULL;
}
@ -130,7 +132,7 @@ static struct device *_dev_create(dev_t d)
return dev;
}
void dev_set_preferred_name(struct str_list *sl, struct device *dev)
void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev)
{
/*
* Don't interfere with ordering specified in config file.
@ -305,8 +307,8 @@ static int _compare_paths(const char *path0, const char *path1)
static int _add_alias(struct device *dev, const char *path)
{
struct str_list *sl = _zalloc(sizeof(*sl));
struct str_list *strl;
struct dm_str_list *sl = _zalloc(sizeof(*sl));
struct dm_str_list *strl;
const char *oldpath;
int prefer_old = 1;
@ -324,7 +326,7 @@ static int _add_alias(struct device *dev, const char *path)
sl->str = path;
if (!dm_list_empty(&dev->aliases)) {
oldpath = dm_list_item(dev->aliases.n, struct str_list)->str;
oldpath = dm_list_item(dev->aliases.n, struct dm_str_list)->str;
prefer_old = _compare_paths(path, oldpath);
log_debug_devs("%s: Aliased to %s in device cache%s",
path, oldpath, prefer_old ? "" : " (preferred name)");
@ -444,7 +446,7 @@ static int _insert_dir(const char *dir)
return_0;
_collapse_slashes(path);
r &= _insert(path, 1, 0);
r &= _insert(path, NULL, 1, 0);
dm_free(path);
free(dirent[n]);
@ -530,14 +532,14 @@ static int _insert_udev_dir(struct udev *udev, const char *dir)
log_very_verbose("udev failed to return a device node for entry %s.",
entry_name);
else
r &= _insert(node_name, 0, 0);
r &= _insert(node_name, NULL, 0, 0);
udev_list_entry_foreach(symlink_entry, udev_device_get_devlinks_list_entry(device)) {
if (!(symlink_name = udev_list_entry_get_name(symlink_entry)))
log_very_verbose("udev failed to return a symlink name for entry %s.",
entry_name);
else
r &= _insert(symlink_name, 0, 0);
r &= _insert(symlink_name, NULL, 0, 0);
}
udev_device_unref(device);
@ -591,49 +593,49 @@ static void _insert_dirs(struct dm_list *dirs)
#endif /* UDEV_SYNC_SUPPORT */
static int _insert(const char *path, int rec, int check_with_udev_db)
static int _insert(const char *path, const struct stat *info,
int rec, int check_with_udev_db)
{
struct stat info;
int r = 0;
struct stat tinfo;
if (stat(path, &info) < 0) {
log_sys_very_verbose("stat", path);
return 0;
if (!info) {
if (stat(path, &tinfo) < 0) {
log_sys_very_verbose("stat", path);
return 0;
}
info = &tinfo;
}
if (check_with_udev_db && !_device_in_udev_db(info.st_rdev)) {
if (check_with_udev_db && !_device_in_udev_db(info->st_rdev)) {
log_very_verbose("%s: Not in udev db", path);
return 0;
}
if (S_ISDIR(info.st_mode)) { /* add a directory */
if (S_ISDIR(info->st_mode)) { /* add a directory */
/* check it's not a symbolic link */
if (lstat(path, &info) < 0) {
if (lstat(path, &tinfo) < 0) {
log_sys_very_verbose("lstat", path);
return 0;
}
if (S_ISLNK(info.st_mode)) {
if (S_ISLNK(tinfo.st_mode)) {
log_debug_devs("%s: Symbolic link to directory", path);
return 0;
return 1;
}
if (rec)
r = _insert_dir(path);
} else { /* add a device */
if (!S_ISBLK(info.st_mode)) {
log_debug_devs("%s: Not a block device", path);
return 0;
}
if (!_insert_dev(path, info.st_rdev))
if (rec && !_insert_dir(path))
return_0;
} else { /* add a device */
if (!S_ISBLK(info->st_mode)) {
log_debug_devs("%s: Not a block device", path);
return 1;
}
r = 1;
if (!_insert_dev(path, info->st_rdev))
return_0;
}
return r;
return 1;
}
static void _full_scan(int dev_scan)
@ -760,21 +762,44 @@ int dev_cache_init(struct cmd_context *cmd)
return 0;
}
static void _check_closed(struct device *dev)
/*
* Returns number of devices still open.
*/
static int _check_for_open_devices(int close_immediate)
{
if (dev->fd >= 0)
log_error("Device '%s' has been left open.", dev_name(dev));
struct device *dev;
struct dm_hash_node *n;
int num_open = 0;
dm_hash_iterate(n, _cache.names) {
dev = (struct device *) dm_hash_get_data(_cache.names, n);
if (dev->fd >= 0) {
log_error("Device '%s' has been left open (%d remaining references).",
dev_name(dev), dev->open_count);
num_open++;
if (close_immediate)
dev_close_immediate(dev);
}
}
return num_open;
}
static void _check_for_open_devices(void)
/*
* Returns number of devices left open.
*/
int dev_cache_check_for_open_devices(void)
{
dm_hash_iter(_cache.names, (dm_hash_iterate_fn) _check_closed);
return _check_for_open_devices(0);
}
void dev_cache_exit(void)
int dev_cache_exit(void)
{
int num_open = 0;
if (_cache.names)
_check_for_open_devices();
if ((num_open = _check_for_open_devices(1)) > 0)
log_error(INTERNAL_ERROR "%d device(s) were left open and have been closed.", num_open);
if (_cache.preferred_names_matcher)
_cache.preferred_names_matcher = NULL;
@ -793,6 +818,8 @@ void dev_cache_exit(void)
_cache.has_scanned = 0;
dm_list_init(&_cache.dirs);
dm_list_init(&_cache.files);
return (!num_open);
}
int dev_cache_add_dir(const char *path)
@ -861,7 +888,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
return dev_name(dev);
while ((r = stat(name = dm_list_item(dev->aliases.n,
struct str_list)->str, &buf)) ||
struct dm_str_list)->str, &buf)) ||
(buf.st_rdev != dev->dev)) {
if (r < 0) {
if (quiet)
@ -887,7 +914,7 @@ const char *dev_name_confirmed(struct device *dev, int quiet)
if (dm_list_size(&dev->aliases) > 1) {
dm_list_del(dev->aliases.n);
if (!r)
_insert(name, 0, obtain_device_list_from_udev());
_insert(name, &buf, 0, obtain_device_list_from_udev());
continue;
}
@ -909,13 +936,20 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
return d;
/* If the entry's wrong, remove it */
if (d && (stat(name, &buf) || (buf.st_rdev != d->dev))) {
if (stat(name, &buf) < 0) {
if (d)
dm_hash_remove(_cache.names, name);
log_sys_very_verbose("stat", name);
return NULL;
}
if (d && (buf.st_rdev != d->dev)) {
dm_hash_remove(_cache.names, name);
d = NULL;
}
if (!d) {
_insert(name, 0, obtain_device_list_from_udev());
_insert(name, &buf, 0, obtain_device_list_from_udev());
d = (struct device *) dm_hash_lookup(_cache.names, name);
if (!d) {
_full_scan(0);
@ -923,8 +957,11 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f)
}
}
return (d && (!f || (d->flags & DEV_REGULAR) ||
f->passes_filter(f, d))) ? d : NULL;
if (!d || (f && !(d->flags & DEV_REGULAR) && !(f->passes_filter(f, d))))
return NULL;
log_debug_devs("Using %s", dev_name(d));
return d;
}
static struct device *_dev_cache_seek_devt(dev_t dev)
@ -972,9 +1009,11 @@ struct dev_iter *dev_iter_create(struct dev_filter *f, int dev_scan)
if (dev_scan && !trust_cache()) {
/* Flag gets reset between each command */
if (!full_scan_done()) {
if (f && f->wipe)
f->wipe(f); /* Calls _full_scan(1) */
else
if (f && f->wipe) {
f->wipe(f); /* might call _full_scan(1) */
if (!full_scan_done())
_full_scan(1);
} else
_full_scan(1);
}
} else
@ -1007,8 +1046,10 @@ struct device *dev_iter_get(struct dev_iter *iter)
while (iter->current) {
struct device *d = _iter_next(iter);
if (!iter->filter || (d->flags & DEV_REGULAR) ||
iter->filter->passes_filter(iter->filter, d))
iter->filter->passes_filter(iter->filter, d)) {
log_debug_devs("Using %s", dev_name(d));
return d;
}
}
return NULL;
@ -1033,6 +1074,6 @@ int dev_fd(struct device *dev)
const char *dev_name(const struct device *dev)
{
return (dev) ? dm_list_item(dev->aliases.n, struct str_list)->str :
return (dev && dev->aliases.n) ? dm_list_item(dev->aliases.n, struct dm_str_list)->str :
"unknown device";
}

View File

@ -36,7 +36,11 @@ struct dev_filter {
*/
struct cmd_context;
int dev_cache_init(struct cmd_context *cmd);
void dev_cache_exit(void);
int dev_cache_exit(void);
/*
* Returns number of open devices.
*/
int dev_cache_check_for_open_devices(void);
/* Trigger(1) or avoid(0) a scan */
void dev_cache_scan(int do_scan);
@ -50,7 +54,7 @@ struct device *dev_cache_get(const char *name, struct dev_filter *f);
// TODO
struct device *dev_cache_get_by_devt(dev_t device, struct dev_filter *f);
void dev_set_preferred_name(struct str_list *sl, struct device *dev);
void dev_set_preferred_name(struct dm_str_list *sl, struct device *dev);
/*
* Object for iterating through the cache.

View File

@ -14,7 +14,6 @@
*/
#include "lib.h"
#include "lvm-types.h"
#include "device.h"
#include "metadata.h"
#include "lvmcache.h"
@ -27,7 +26,7 @@
#include <unistd.h>
#include <sys/ioctl.h>
#ifdef linux
#ifdef __linux__
# define u64 uint64_t /* Missing without __KERNEL__ */
# undef WNOHANG /* Avoid redefinition */
# undef WUNTRACED /* Avoid redefinition */
@ -123,23 +122,65 @@ static int _io(struct device_area *where, char *buffer, int should_write)
*---------------------------------------------------------------*/
/*
* Get the sector size from an _open_ device.
* Get the physical and logical block size for a device.
*/
static int _get_block_size(struct device *dev, unsigned int *size)
int dev_get_block_size(struct device *dev, unsigned int *physical_block_size, unsigned int *block_size)
{
const char *name = dev_name(dev);
int needs_open;
int r = 1;
needs_open = (!dev->open_count && (dev->phys_block_size == -1 || dev->block_size == -1));
if (needs_open && !dev_open_readonly(dev))
return_0;
if (dev->block_size == -1) {
if (ioctl(dev_fd(dev), BLKBSZGET, &dev->block_size) < 0) {
log_sys_error("ioctl BLKBSZGET", name);
return 0;
r = 0;
goto out;
}
log_debug_devs("%s: block size is %u bytes", name, dev->block_size);
}
*size = (unsigned int) dev->block_size;
#ifdef BLKPBSZGET
/* BLKPBSZGET is available in kernel >= 2.6.32 only */
if (dev->phys_block_size == -1) {
if (ioctl(dev_fd(dev), BLKPBSZGET, &dev->phys_block_size) < 0) {
log_sys_error("ioctl BLKPBSZGET", name);
r = 0;
goto out;
}
log_debug_devs("%s: physical block size is %u bytes", name, dev->phys_block_size);
}
#elif BLKSSZGET
/* if we can't get physical block size, just use logical block size instead */
if (dev->phys_block_size == -1) {
if (ioctl(dev_fd(dev), BLKSSZGET, &dev->phys_block_size) < 0) {
log_sys_error("ioctl BLKSSZGET", name);
r = 0;
goto out;
}
log_debug_devs("%s: physical block size can't be determined, using logical "
"block size of %u bytes", name, dev->phys_block_size);
}
#else
/* if even BLKSSZGET is not available, use default 512b */
if (dev->phys_block_size == -1) {
dev->phys_block_size = 512;
log_debug_devs("%s: physical block size can't be determined, using block "
"size of %u bytes instead", name, dev->phys_block_size);
}
#endif
return 1;
*physical_block_size = (unsigned int) dev->phys_block_size;
*block_size = (unsigned int) dev->block_size;
out:
if (needs_open && !dev_close(dev))
stack;
return r;
}
/*
@ -168,13 +209,14 @@ static int _aligned_io(struct device_area *where, char *buffer,
int should_write)
{
char *bounce, *bounce_buf;
unsigned int physical_block_size = 0;
unsigned int block_size = 0;
uintptr_t mask;
struct device_area widened;
int r = 0;
if (!(where->dev->flags & DEV_REGULAR) &&
!_get_block_size(where->dev, &block_size))
!dev_get_block_size(where->dev, &physical_block_size, &block_size))
return_0;
if (!block_size)
@ -370,36 +412,6 @@ int dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64_t size_
return _dev_discard_blocks(dev, offset_bytes, size_bytes);
}
/* FIXME Unused
int dev_get_sectsize(struct device *dev, uint32_t *size)
{
int fd;
int s;
const char *name = dev_name(dev);
if ((fd = open(name, O_RDONLY)) < 0) {
log_sys_error("open", name);
return 0;
}
if (ioctl(fd, BLKSSZGET, &s) < 0) {
log_sys_error("ioctl BLKSSZGET", name);
if (close(fd))
log_sys_error("close", name);
return 0;
}
if (close(fd))
log_sys_error("close", name);
*size = (uint32_t) s;
log_very_verbose("%s: sector size is %" PRIu32 " bytes", name, *size);
return 1;
}
*/
void dev_flush(struct device *dev)
{
if (!(dev->flags & DEV_REGULAR) && ioctl(dev->fd, BLKFLSBUF, 0) >= 0)
@ -446,9 +458,7 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
log_verbose("dev_open(%s) called while suspended",
dev_name(dev));
if (dev->flags & DEV_REGULAR)
name = dev_name(dev);
else if (!(name = dev_name_confirmed(dev, quiet)))
if (!(name = dev_name_confirmed(dev, quiet)))
return_0;
#ifdef O_DIRECT_SUPPORT
@ -573,13 +583,14 @@ static void _close(struct device *dev)
if (close(dev->fd))
log_sys_error("close", dev_name(dev));
dev->fd = -1;
dev->phys_block_size = -1;
dev->block_size = -1;
dm_list_del(&dev->open_list);
log_debug_devs("Closed %s", dev_name(dev));
if (dev->flags & DEV_ALLOCED) {
dm_free((void *) dm_list_item(dev->aliases.n, struct str_list)->
dm_free((void *) dm_list_item(dev->aliases.n, struct dm_str_list)->
str);
dm_free(dev->aliases.n);
dm_free(dev);

View File

@ -18,7 +18,7 @@
#define LUKS_SIGNATURE "LUKS\xba\xbe"
#define LUKS_SIGNATURE_SIZE 6
int dev_is_luks(struct device *dev, uint64_t *signature)
int dev_is_luks(struct device *dev, uint64_t *offset_found)
{
char buf[LUKS_SIGNATURE_SIZE];
int ret = -1;
@ -28,7 +28,8 @@ int dev_is_luks(struct device *dev, uint64_t *signature)
return -1;
}
*signature = 0;
if (offset_found)
*offset_found = 0;
if (!dev_read(dev, 0, LUKS_SIGNATURE_SIZE, buf))
goto_out;

View File

@ -18,7 +18,7 @@
#include "metadata.h"
#include "xlate.h"
#ifdef linux
#ifdef __linux__
/* Lifted from <linux/raid/md_p.h> because of difficulty including it */
@ -60,7 +60,7 @@ typedef enum {
static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
{
uint64_t uninitialized_var(sb_offset);
uint64_t sb_offset;
switch(minor_version) {
case MD_MINOR_V0:
@ -72,6 +72,10 @@ static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
case MD_MINOR_V2:
sb_offset = 4 * 2;
break;
default:
log_warn(INTERNAL_ERROR "WARNING: Unknown minor version %d.",
minor_version);
return 0;
}
sb_offset <<= SECTOR_SHIFT;
@ -81,7 +85,7 @@ static uint64_t _v1_sb_offset(uint64_t size, md_minor_version_t minor_version)
/*
* Returns -1 on error
*/
int dev_is_md(struct device *dev, uint64_t *sb)
int dev_is_md(struct device *dev, uint64_t *offset_found)
{
int ret = 1;
md_minor_version_t minor;
@ -120,8 +124,8 @@ out:
if (!dev_close(dev))
stack;
if (ret && sb)
*sb = sb_offset;
if (ret && offset_found)
*offset_found = sb_offset;
return ret;
}

View File

@ -15,7 +15,7 @@
#include "lib.h"
#include "dev-type.h"
#ifdef linux
#ifdef __linux__
#define MAX_PAGESIZE (64 * 1024)
#define SIGNATURE_SIZE 10
@ -36,7 +36,7 @@ _swap_detect_signature(const char *buf)
return 0;
}
int dev_is_swap(struct device *dev, uint64_t *signature)
int dev_is_swap(struct device *dev, uint64_t *offset_found)
{
char buf[10];
uint64_t size;
@ -53,15 +53,13 @@ int dev_is_swap(struct device *dev, uint64_t *signature)
return -1;
}
*signature = 0;
for (page = 0x1000; page <= MAX_PAGESIZE; page <<= 1) {
/*
* skip 32k pagesize since this does not seem to be supported
*/
if (page == 0x8000)
continue;
if (size < page)
if (size < (page >> SECTOR_SHIFT))
break;
if (!dev_read(dev, page - SIGNATURE_SIZE,
SIGNATURE_SIZE, buf)) {
@ -69,7 +67,8 @@ int dev_is_swap(struct device *dev, uint64_t *signature)
break;
}
if (_swap_detect_signature(buf)) {
*signature = page - SIGNATURE_SIZE;
if (offset_found)
*offset_found = page - SIGNATURE_SIZE;
ret = 1;
break;
}

View File

@ -21,6 +21,10 @@
#include <libgen.h>
#include <ctype.h>
#ifdef BLKID_WIPING_SUPPORT
#include <blkid.h>
#endif
#include "device-types.h"
struct dev_types *create_dev_types(const char *proc_dir,
@ -344,8 +348,8 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
const char *sysfs_dir = dm_sysfs_dir();
int major = (int) MAJOR(dev->dev);
int minor = (int) MINOR(dev->dev);
char path[PATH_MAX+1];
char temp_path[PATH_MAX+1];
char path[PATH_MAX];
char temp_path[PATH_MAX];
char buffer[64];
struct stat info;
FILE *fp = NULL;
@ -374,7 +378,7 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
*/
/* check if dev is a partition */
if (dm_snprintf(path, PATH_MAX, "%s/dev/block/%d:%d/partition",
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d/partition",
sysfs_dir, major, minor) < 0) {
log_error("dm_snprintf partition failed");
goto out;
@ -396,14 +400,14 @@ int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
* - basename ../../block/md0/md0 = md0
* Parent's 'dev' sysfs attribute = /sys/block/md0/dev
*/
if ((size = readlink(dirname(path), temp_path, PATH_MAX)) < 0) {
if ((size = readlink(dirname(path), temp_path, sizeof(temp_path) - 1)) < 0) {
log_sys_error("readlink", path);
goto out;
}
temp_path[size] = '\0';
if (dm_snprintf(path, PATH_MAX, "%s/block/%s/dev",
if (dm_snprintf(path, sizeof(path), "%s/block/%s/dev",
sysfs_dir, basename(dirname(temp_path))) < 0) {
log_error("dm_snprintf dev failed");
goto out;
@ -443,32 +447,233 @@ out:
return ret;
}
#ifdef linux
#ifdef BLKID_WIPING_SUPPORT
static inline int _type_in_flag_list(const char *type, uint32_t flag_list)
{
return (((flag_list & TYPE_LVM2_MEMBER) && !strcmp(type, "LVM2_member")) ||
((flag_list & TYPE_LVM1_MEMBER) && !strcmp(type, "LVM1_member")) ||
((flag_list & TYPE_DM_SNAPSHOT_COW) && !strcmp(type, "DM_snapshot_cow")));
}
static int _blkid_wipe(blkid_probe probe, struct device *dev, const char *name,
uint32_t types_to_exclude, uint32_t types_no_prompt,
int yes, force_t force)
{
static const char const _msg_failed_offset[] = "Failed to get offset of the %s signature on %s.";
static const char const _msg_failed_length[] = "Failed to get length of the %s signature on %s.";
static const char const _msg_wiping[] = "Wiping %s signature on %s.";
const char *offset = NULL, *type = NULL, *magic = NULL,
*usage = NULL, *label = NULL, *uuid = NULL;
loff_t offset_value;
size_t len;
if (!blkid_probe_lookup_value(probe, "TYPE", &type, NULL)) {
if (_type_in_flag_list(type, types_to_exclude))
return 1;
if (blkid_probe_lookup_value(probe, "SBMAGIC_OFFSET", &offset, NULL)) {
log_error(_msg_failed_offset, type, name);
return 0;
}
if (blkid_probe_lookup_value(probe, "SBMAGIC", &magic, &len)) {
log_error(_msg_failed_length, type, name);
return 0;
}
} else if (!blkid_probe_lookup_value(probe, "PTTYPE", &type, NULL)) {
if (blkid_probe_lookup_value(probe, "PTMAGIC_OFFSET", &offset, NULL)) {
log_error(_msg_failed_offset, type, name);
return 0;
}
if (blkid_probe_lookup_value(probe, "PTMAGIC", &magic, &len)) {
log_error(_msg_failed_length, type, name);
return 0;
}
usage = "partition table";
} else
return_0;
offset_value = strtoll(offset, NULL, 10);
if (!usage)
(void) blkid_probe_lookup_value(probe, "USAGE", &usage, NULL);
(void) blkid_probe_lookup_value(probe, "LABEL", &label, NULL);
(void) blkid_probe_lookup_value(probe, "UUID", &uuid, NULL);
/* Return values ignored here, in the worst case we print NULL */
log_verbose("Found existing signature on %s at offset %s: LABEL=\"%s\" "
"UUID=\"%s\" TYPE=\"%s\" USAGE=\"%s\"",
name, offset, label, uuid, type, usage);
if (!_type_in_flag_list(type, types_no_prompt)) {
if (!yes && (force == PROMPT) &&
yes_no_prompt("WARNING: %s signature detected on %s at offset %s. "
"Wipe it? [y/n]: ", type, name, offset) == 'n') {
log_error("Aborted wiping of %s.", type);
return 0;
}
log_print_unless_silent(_msg_wiping, type, name);
} else
log_verbose(_msg_wiping, type, name);
if (!dev_set(dev, offset_value, len, 0)) {
log_error("Failed to wipe %s signature on %s.", type, name);
return 0;
}
return 1;
}
static int _wipe_known_signatures_with_blkid(struct device *dev, const char *name,
uint32_t types_to_exclude,
uint32_t types_no_prompt,
int yes, force_t force)
{
blkid_probe probe = NULL;
int found = 0, wiped = 0, left = 0;
int r = 0;
/* TODO: Should we check for valid dev - _dev_is_valid(dev)? */
if (!(probe = blkid_new_probe_from_filename(dev_name(dev)))) {
log_error("Failed to create a new blkid probe for device %s.", dev_name(dev));
goto out;
}
blkid_probe_enable_partitions(probe, 1);
blkid_probe_set_partitions_flags(probe, BLKID_PARTS_MAGIC);
blkid_probe_enable_superblocks(probe, 1);
blkid_probe_set_superblocks_flags(probe, BLKID_SUBLKS_LABEL |
BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE |
BLKID_SUBLKS_USAGE |
BLKID_SUBLKS_VERSION |
BLKID_SUBLKS_MAGIC |
BLKID_SUBLKS_BADCSUM);
while (!blkid_do_probe(probe)) {
found++;
if (_blkid_wipe(probe, dev, name, types_to_exclude, types_no_prompt, yes, force))
wiped++;
}
if (!found)
r = 1;
left = found - wiped;
if (!left)
r = 1;
else
log_warn("%d existing signature%s left on the device.",
left, left > 1 ? "s" : "");
out:
if (probe)
blkid_free_probe(probe);
return r;
}
#endif /* BLKID_WIPING_SUPPORT */
static int _wipe_signature(struct device *dev, const char *type, const char *name,
int wipe_len, int yes, force_t force,
int (*signature_detection_fn)(struct device *dev, uint64_t *offset_found))
{
int wipe;
uint64_t offset_found;
wipe = signature_detection_fn(dev, &offset_found);
if (wipe == -1) {
log_error("Fatal error while trying to detect %s on %s.",
type, name);
return 0;
}
if (wipe == 0)
return 1;
/* Specifying --yes => do not ask. */
if (!yes && (force == PROMPT) &&
yes_no_prompt("WARNING: %s detected on %s. Wipe it? [y/n]: ",
type, name) == 'n') {
log_error("Aborted wiping of %s.", type);
return 0;
}
log_print_unless_silent("Wiping %s on %s.", type, name);
if (!dev_set(dev, offset_found, wipe_len, 0)) {
log_error("Failed to wipe %s on %s.", type, name);
return 0;
}
return 1;
}
static int _wipe_known_signatures_with_lvm(struct device *dev, const char *name,
uint32_t types_to_exclude __attribute__((unused)),
uint32_t types_no_prompt __attribute__((unused)),
int yes, force_t force)
{
if (!_wipe_signature(dev, "software RAID md superblock", name, 4, yes, force, dev_is_md) ||
!_wipe_signature(dev, "swap signature", name, 10, yes, force, dev_is_swap) ||
!_wipe_signature(dev, "LUKS signature", name, 8, yes, force, dev_is_luks))
return 0;
return 1;
}
int wipe_known_signatures(struct cmd_context *cmd, struct device *dev,
const char *name, uint32_t types_to_exclude,
uint32_t types_no_prompt, int yes, force_t force)
{
#ifdef BLKID_WIPING_SUPPORT
if (find_config_tree_bool(cmd, allocation_use_blkid_wiping_CFG, NULL))
return _wipe_known_signatures_with_blkid(dev, name,
types_to_exclude,
types_no_prompt,
yes, force);
#endif
return _wipe_known_signatures_with_lvm(dev, name,
types_to_exclude,
types_no_prompt,
yes, force);
}
#ifdef __linux__
static int _snprintf_attr(char *buf, size_t buf_size, const char *sysfs_dir,
const char *attribute, dev_t dev)
{
if (dm_snprintf(buf, buf_size, "%s/dev/block/%d:%d/%s", sysfs_dir,
(int)MAJOR(dev), (int)MINOR(dev),
attribute) < 0) {
log_warn("dm_snprintf %s failed.", attribute);
return 0;
}
return 1;
}
static unsigned long _dev_topology_attribute(struct dev_types *dt,
const char *attribute,
struct device *dev)
struct device *dev,
unsigned long default_value)
{
const char *sysfs_dir = dm_sysfs_dir();
static const char sysfs_fmt_str[] = "%s/dev/block/%d:%d/%s";
char path[PATH_MAX+1], buffer[64];
char path[PATH_MAX], buffer[64];
FILE *fp;
struct stat info;
dev_t uninitialized_var(primary);
unsigned long result = 0UL;
unsigned long result = default_value;
unsigned long value = 0UL;
if (!attribute || !*attribute)
return_0;
goto_out;
if (!sysfs_dir || !*sysfs_dir)
return_0;
goto_out;
if (dm_snprintf(path, PATH_MAX, sysfs_fmt_str, sysfs_dir,
(int)MAJOR(dev->dev), (int)MINOR(dev->dev),
attribute) < 0) {
log_error("dm_snprintf %s failed", attribute);
return 0;
}
if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, dev->dev))
goto_out;
/*
* check if the desired sysfs attribute exists
@ -477,77 +682,80 @@ static unsigned long _dev_topology_attribute(struct dev_types *dt,
*/
if (stat(path, &info) == -1) {
if (errno != ENOENT) {
log_sys_error("stat", path);
return 0;
log_sys_debug("stat", path);
goto out;
}
if (!dev_get_primary_dev(dt, dev, &primary))
return 0;
goto out;
/* get attribute from partition's primary device */
if (dm_snprintf(path, PATH_MAX, sysfs_fmt_str, sysfs_dir,
(int)MAJOR(primary), (int)MINOR(primary),
attribute) < 0) {
log_error("primary dm_snprintf %s failed", attribute);
return 0;
}
if (!_snprintf_attr(path, sizeof(path), sysfs_dir, attribute, primary))
goto_out;
if (stat(path, &info) == -1) {
if (errno != ENOENT)
log_sys_error("stat", path);
return 0;
log_sys_debug("stat", path);
goto out;
}
}
if (!(fp = fopen(path, "r"))) {
log_sys_error("fopen", path);
return 0;
log_sys_debug("fopen", path);
goto out;
}
if (!fgets(buffer, sizeof(buffer), fp)) {
log_sys_error("fgets", path);
goto out;
log_sys_debug("fgets", path);
goto out_close;
}
if (sscanf(buffer, "%lu", &result) != 1) {
log_error("sysfs file %s not in expected format: %s", path,
buffer);
goto out;
if (sscanf(buffer, "%lu", &value) != 1) {
log_warn("sysfs file %s not in expected format: %s", path, buffer);
goto out_close;
}
log_very_verbose("Device %s %s is %lu bytes.",
dev_name(dev), attribute, result);
log_very_verbose("Device %s: %s is %lu%s.",
dev_name(dev), attribute, result, default_value ? "" : " bytes");
result = value >> SECTOR_SHIFT;
out_close:
if (fclose(fp))
log_sys_debug("fclose", path);
out:
if (fclose(fp))
log_sys_error("fclose", path);
return result >> SECTOR_SHIFT;
return result;
}
unsigned long dev_alignment_offset(struct dev_types *dt, struct device *dev)
{
return _dev_topology_attribute(dt, "alignment_offset", dev);
return _dev_topology_attribute(dt, "alignment_offset", dev, 0UL);
}
unsigned long dev_minimum_io_size(struct dev_types *dt, struct device *dev)
{
return _dev_topology_attribute(dt, "queue/minimum_io_size", dev);
return _dev_topology_attribute(dt, "queue/minimum_io_size", dev, 0UL);
}
unsigned long dev_optimal_io_size(struct dev_types *dt, struct device *dev)
{
return _dev_topology_attribute(dt, "queue/optimal_io_size", dev);
return _dev_topology_attribute(dt, "queue/optimal_io_size", dev, 0UL);
}
unsigned long dev_discard_max_bytes(struct dev_types *dt, struct device *dev)
{
return _dev_topology_attribute(dt, "queue/discard_max_bytes", dev);
return _dev_topology_attribute(dt, "queue/discard_max_bytes", dev, 0UL);
}
unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev)
{
return _dev_topology_attribute(dt, "queue/discard_granularity", dev);
return _dev_topology_attribute(dt, "queue/discard_granularity", dev, 0UL);
}
int dev_is_rotational(struct dev_types *dt, struct device *dev)
{
return (int) _dev_topology_attribute(dt, "queue/rotational", dev, 1UL);
}
#else
int dev_get_primary_dev(struct dev_types *dt, struct device *dev, dev_t *result)
@ -580,4 +788,8 @@ unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev)
return 0UL;
}
int dev_is_rotational(struct dev_types *dt, struct device *dev)
{
return 1;
}
#endif

View File

@ -16,10 +16,11 @@
#define _LVM_DEV_TYPE_H
#include "device.h"
#include "display.h"
#define NUMBER_OF_MAJORS 4096
#ifdef linux
#ifdef __linux__
# define MAJOR(dev) ((dev & 0xfff00) >> 8)
# define MINOR(dev) ((dev & 0xff) | ((dev >> 12) & 0xfff00))
# define MKDEV(ma,mi) ((mi & 0xff) | (ma << 8) | ((mi & ~0xff) << 12))
@ -58,6 +59,14 @@ int dev_is_md(struct device *dev, uint64_t *sb);
int dev_is_swap(struct device *dev, uint64_t *signature);
int dev_is_luks(struct device *dev, uint64_t *signature);
/* Signature wiping. */
#define TYPE_LVM1_MEMBER 0x001
#define TYPE_LVM2_MEMBER 0x002
#define TYPE_DM_SNAPSHOT_COW 0x004
int wipe_known_signatures(struct cmd_context *cmd, struct device *dev, const char *name,
uint32_t types_to_exclude, uint32_t types_no_prompt,
int yes, force_t force);
/* Type-specific device properties */
unsigned long dev_md_stripe_width(struct dev_types *dt, struct device *dev);
@ -73,4 +82,6 @@ unsigned long dev_optimal_io_size(struct dev_types *dt, struct device *dev);
unsigned long dev_discard_max_bytes(struct dev_types *dt, struct device *dev);
unsigned long dev_discard_granularity(struct dev_types *dt, struct device *dev);
int dev_is_rotational(struct dev_types *dt, struct device *dev);
#endif

View File

@ -28,11 +28,13 @@ typedef struct {
* The list can be supplemented with devices/types in the config file.
*/
static const dev_known_type_t _dev_known_types[] = {
{"ide", 64, "IDE disk"},
{"sd", 16, "SCSI disk"},
{"ide", 64, "IDE disk"},
{"md", 1, "Multiple Disk (MD/SoftRAID)"},
{"mdp", 1, "Partitionable MD"},
{"loop", 1, "Loop device"},
{"ramdisk", 1, "RAM disk"},
{"device-mapper", 1, "Mapped device"},
{"mdp", 1, "Partitionable MD"},
{"dasd", 4, "DASD disk (IBM S/390, zSeries)"},
{"dac960", 8, "DAC960"},
{"nbd", 16, "Network Block Device"},
@ -46,9 +48,7 @@ static const dev_known_type_t _dev_known_types[] = {
{"i2o_block", 16, "i2o Block Disk"},
{"iseries/vd", 8, "iSeries disks"},
{"gnbd", 1, "Network block device"},
{"ramdisk", 1, "RAM disk"},
{"aoe", 16, "ATA over Ethernet"},
{"device-mapper", 1, "Mapped device"},
{"xvd", 16, "Xen virtual block device"},
{"vdisk", 8, "SUN's LDOM virtual block device"},
{"ps3disk", 16, "PlayStation 3 internal disk"},
@ -60,5 +60,8 @@ static const dev_known_type_t _dev_known_types[] = {
{"vtms", 16, "Violin Memory"},
{"skd", 16, "STEC"},
{"scm", 8, "Storage Class Memory (IBM S/390)"},
{"bcache", 1, "bcache block device cache"},
{"nvme", 64, "NVM Express"},
{"zvol", 16, "ZFS Zvols"},
{"", 0, ""}
};

View File

@ -33,7 +33,7 @@
* pointer comparisons are valid.
*/
struct device {
struct dm_list aliases; /* struct str_list from lvm-types.h */
struct dm_list aliases; /* struct dm_str_list */
dev_t dev;
/* private */
@ -41,6 +41,7 @@ struct device {
int open_count;
int error_count;
int max_error_count;
int phys_block_size;
int block_size;
int read_ahead;
uint32_t flags;
@ -65,8 +66,8 @@ struct device_area {
/*
* All io should use these routines.
*/
int dev_get_block_size(struct device *dev, unsigned int *phys_block_size, unsigned int *block_size);
int dev_get_size(const struct device *dev, uint64_t *size);
int dev_get_sectsize(struct device *dev, uint32_t *size);
int dev_get_read_ahead(struct device *dev, uint32_t *read_ahead);
int dev_discard_blocks(struct device *dev, uint64_t offset_bytes, uint64_t size_bytes);
@ -94,7 +95,7 @@ int dev_set(struct device *dev, uint64_t offset, size_t len, int value);
void dev_flush(struct device *dev);
struct device *dev_create_file(const char *filename, struct device *dev,
struct str_list *alias, int use_malloc);
struct dm_str_list *alias, int use_malloc);
/* Return a valid device name from the alias list; NULL otherwise */
const char *dev_name_confirmed(struct device *dev, int quiet);

View File

@ -20,6 +20,9 @@
#include "toolcontext.h"
#include "segtype.h"
#include "defaults.h"
#include "lvm-signal.h"
#include <stdarg.h>
#define SIZE_BUF 128
@ -39,98 +42,7 @@ static const struct {
ALLOC_INHERIT, "inherit", 'i'}
};
static const int _num_policies = sizeof(_policies) / sizeof(*_policies);
uint64_t units_to_bytes(const char *units, char *unit_type)
{
char *ptr = NULL;
uint64_t v;
double custom_value = 0;
uint64_t multiplier;
if (isdigit(*units)) {
custom_value = strtod(units, &ptr);
if (ptr == units)
return 0;
v = (uint64_t) strtoull(units, NULL, 10);
if ((double) v == custom_value)
custom_value = 0; /* Use integer arithmetic */
units = ptr;
} else
v = 1;
/* Only one units char permitted. */
if (units[0] && units[1])
return 0;
if (v == 1)
*unit_type = *units;
else
*unit_type = 'U';
switch (*units) {
case 'h':
case 'H':
multiplier = v = UINT64_C(1);
*unit_type = *units;
break;
case 'b':
case 'B':
multiplier = UINT64_C(1);
break;
#define KILO UINT64_C(1024)
case 's':
case 'S':
multiplier = (KILO/2);
break;
case 'k':
multiplier = KILO;
break;
case 'm':
multiplier = KILO * KILO;
break;
case 'g':
multiplier = KILO * KILO * KILO;
break;
case 't':
multiplier = KILO * KILO * KILO * KILO;
break;
case 'p':
multiplier = KILO * KILO * KILO * KILO * KILO;
break;
case 'e':
multiplier = KILO * KILO * KILO * KILO * KILO * KILO;
break;
#undef KILO
#define KILO UINT64_C(1000)
case 'K':
multiplier = KILO;
break;
case 'M':
multiplier = KILO * KILO;
break;
case 'G':
multiplier = KILO * KILO * KILO;
break;
case 'T':
multiplier = KILO * KILO * KILO * KILO;
break;
case 'P':
multiplier = KILO * KILO * KILO * KILO * KILO;
break;
case 'E':
multiplier = KILO * KILO * KILO * KILO * KILO * KILO;
break;
#undef KILO
default:
return 0;
}
if (custom_value)
return (uint64_t) (custom_value * multiplier);
else
return v * multiplier;
}
static const int _num_policies = DM_ARRAY_SIZE(_policies);
char alloc_policy_char(alloc_policy_t alloc)
{
@ -174,6 +86,19 @@ alloc_policy_t get_alloc_from_string(const char *str)
return ALLOC_INVALID;
}
static const char *_percent_types[7] = { "NONE", "VG", "FREE", "LV", "PVS", "ORIGIN" };
const char *get_percent_string(percent_type_t def)
{
return _percent_types[def];
}
const char *display_lvname(const struct logical_volume *lv)
{
/* On allocation failure, just return the LV name. */
return lv_fullname_dup(lv->vg->cmd->mem, lv) ? : lv->name;
}
#define BASE_UNKNOWN 0
#define BASE_SHARED 1
#define BASE_1024 8
@ -188,7 +113,7 @@ static const char *_display_size(const struct cmd_context *cmd,
{
unsigned base = BASE_UNKNOWN;
unsigned s;
int suffix = 1, precision;
int suffix, precision;
uint64_t byte = UINT64_C(0);
uint64_t units = UINT64_C(1024);
char *size_buf = NULL;
@ -347,7 +272,7 @@ void pvdisplay_colons(const struct physical_volume *pv)
}
log_print("%s:%s:%" PRIu64 ":-1:%" PRIu64 ":%" PRIu64 ":-1:%" PRIu32 ":%u:%u:%u:%s",
pv_dev_name(pv), pv->vg_name, pv->size,
pv_dev_name(pv), pv_vg_name(pv), pv->size,
/* FIXME pv->pv_number, Derive or remove? */
pv->status, /* FIXME Support old or new format here? */
pv->status & ALLOCATABLE_PV, /* FIXME remove? */
@ -508,11 +433,11 @@ int lvdisplay_full(struct cmd_context *cmd,
struct lv_segment *snap_seg = NULL, *mirror_seg = NULL;
struct lv_segment *seg = NULL;
int lvm1compat;
percent_t snap_percent;
dm_percent_t snap_percent;
int thin_data_active = 0, thin_metadata_active = 0;
percent_t thin_data_percent, thin_metadata_percent;
dm_percent_t thin_data_percent, thin_metadata_percent;
int thin_active = 0;
percent_t thin_percent;
dm_percent_t thin_percent;
if (!id_write_format(&lv->lvid.id[1], uuid, sizeof(uuid)))
return_0;
@ -558,7 +483,7 @@ int lvdisplay_full(struct cmd_context *cmd,
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
if (snap_percent == PERCENT_INVALID)
if (snap_percent == DM_PERCENT_INVALID)
snap_active = 0;
if (lvm1compat)
log_print(" %s%s/%s [%s]",
@ -575,7 +500,7 @@ int lvdisplay_full(struct cmd_context *cmd,
if (inkernel &&
(snap_active = lv_snapshot_percent(snap_seg->cow,
&snap_percent)))
if (snap_percent == PERCENT_INVALID)
if (snap_percent == DM_PERCENT_INVALID)
snap_active = 0;
if (lvm1compat)
@ -598,27 +523,28 @@ int lvdisplay_full(struct cmd_context *cmd,
if (seg->external_lv)
log_print("LV External origin name %s",
seg->external_lv->name);
if (seg->merge_lv)
log_print("LV merging to %s",
seg->merge_lv->name);
if (inkernel)
thin_active = lv_thin_percent(lv, 0, &thin_percent);
if (lv_is_merging_origin(lv))
log_print("LV merged with %s",
find_snapshot(lv)->lv->name);
} else if (lv_is_thin_pool(lv)) {
if (inkernel) {
if (lv_info(cmd, lv, 1, &info, 1, 1) && info.exists) {
thin_data_active = lv_thin_pool_percent(lv, 0, &thin_data_percent);
thin_metadata_active = lv_thin_pool_percent(lv, 1, &thin_metadata_percent);
}
/* FIXME: display thin_pool targets transid for activated LV as well */
seg = first_seg(lv);
log_print("LV Pool transaction ID %" PRIu64, seg->transaction_id);
log_print("LV Pool metadata %s", seg->metadata_lv->name);
log_print("LV Pool data %s", seg_lv(seg, 0)->name);
log_print("LV Pool chunk size %s",
display_size(cmd, seg->chunk_size));
log_print("LV Zero new blocks %s",
seg->zero_new_blocks ? "yes" : "no");
}
if (inkernel && info.suspended)
log_print("LV Status suspended");
else
else if (activation())
log_print("LV Status %savailable",
inkernel ? "" : "NOT ");
@ -635,15 +561,15 @@ int lvdisplay_full(struct cmd_context *cmd,
if (thin_data_active)
log_print("Allocated pool data %.2f%%",
percent_to_float(thin_data_percent));
dm_percent_to_float(thin_data_percent));
if (thin_metadata_active)
log_print("Allocated metadata %.2f%%",
percent_to_float(thin_metadata_percent));
dm_percent_to_float(thin_metadata_percent));
if (thin_active)
log_print("Mapped size %.2f%%",
percent_to_float(thin_percent));
dm_percent_to_float(thin_percent));
log_print("Current LE %u",
snap_seg ? snap_seg->origin->le_count : lv->le_count);
@ -655,16 +581,16 @@ int lvdisplay_full(struct cmd_context *cmd,
if (snap_active)
log_print("Allocated to snapshot %.2f%%",
percent_to_float(snap_percent));
dm_percent_to_float(snap_percent));
log_print("Snapshot chunk size %s",
display_size(cmd, (uint64_t) snap_seg->chunk_size));
}
if (lv->status & MIRRORED) {
if (lv_is_mirrored(lv)) {
mirror_seg = first_seg(lv);
log_print("Mirrored volumes %" PRIu32, mirror_seg->area_count);
if (lv->status & CONVERTING)
if (lv_is_converting(lv))
log_print("LV type Mirror undergoing conversion");
}
@ -737,11 +663,16 @@ int lvdisplay_segments(const struct logical_volume *lv)
log_print("--- Segments ---");
dm_list_iterate_items(seg, &lv->segments) {
log_print("Logical extent %u to %u:",
log_print("%s extents %u to %u:",
lv_is_virtual(lv) ? "Virtual" : "Logical",
seg->le, seg->le + seg->len - 1);
log_print(" Type\t\t%s", seg->segtype->ops->name(seg));
if (seg->segtype->ops->target_monitored)
log_print(" Monitoring\t\t%s",
lvseg_monitor_dup(lv->vg->cmd->mem, seg));
if (seg->segtype->ops->display)
seg->segtype->ops->display(seg);
}
@ -806,14 +737,14 @@ void vgdisplay_full(const struct volume_group *vg)
(uint64_t) vg->extent_count * vg->extent_size));
log_print("PE Size %s",
display_size(vg->cmd, (uint64_t) vg->extent_size));
display_size(vg->cmd, vg->extent_size));
log_print("Total PE %u", vg->extent_count);
log_print("Alloc PE / Size %u / %s",
vg->extent_count - vg->free_count,
display_size(vg->cmd,
((uint64_t) vg->extent_count - vg->free_count) *
(uint64_t) (vg->extent_count - vg->free_count) *
vg->extent_size));
log_print("Free PE / Size %u / %s", vg->free_count,
@ -906,6 +837,45 @@ void display_segtypes(const struct cmd_context *cmd)
}
}
void display_tags(const struct cmd_context *cmd)
{
const struct dm_str_list *sl;
dm_list_iterate_items(sl, &cmd->tags) {
log_print("%s", sl->str);
}
}
void display_name_error(name_error_t name_error)
{
switch(name_error) {
case NAME_VALID:
/* Valid name */
break;
case NAME_INVALID_EMPTY:
log_error("Name is zero length.");
break;
case NAME_INVALID_HYPEN:
log_error("Name cannot start with hyphen.");
break;
case NAME_INVALID_DOTS:
log_error("Name starts with . or .. and has no "
"following character(s).");
break;
case NAME_INVALID_CHARSET:
log_error("Name contains invalid character, valid set includes: "
"[a-zA-Z0-9.-_+].");
break;
case NAME_INVALID_LENGTH:
/* Report that name length - 1 to accommodate nul*/
log_error("Name length exceeds maximum limit of %d.", (NAME_LEN - 1));
break;
default:
log_error(INTERNAL_ERROR "Unknown error %d on name validation.", name_error);
break;
}
}
/*
* Prompt for y or n from stdin.
* Defaults to 'no' in silent mode.
@ -913,12 +883,9 @@ void display_segtypes(const struct cmd_context *cmd)
*/
char yes_no_prompt(const char *prompt, ...)
{
int c = 0, ret = 0;
int c = 0, ret = 0, cb = 0;
va_list ap;
if (silent_mode())
return 'n';
sigint_allow();
do {
if (c == '\n' || !c) {
@ -926,11 +893,17 @@ char yes_no_prompt(const char *prompt, ...)
vfprintf(stderr, prompt, ap);
va_end(ap);
fflush(stderr);
if (silent_mode()) {
fputc('n', stderr);
ret = 'n';
break;
}
ret = 0;
}
if ((c = getchar()) == EOF) {
ret = 'n'; /* SIGINT */
cb = 1;
break;
}
@ -946,8 +919,11 @@ char yes_no_prompt(const char *prompt, ...)
sigint_restore();
if (cb && !sigint_caught())
fputc(ret, stderr);
if (c != '\n')
fprintf(stderr, "\n");
fputc('\n', stderr);
return ret;
}

View File

@ -18,10 +18,11 @@
#include "metadata-exported.h"
#include "locking.h"
#include "lvm-string.h"
#include <stdint.h>
uint64_t units_to_bytes(const char *units, char *unit_type);
const char *display_lvname(const struct logical_volume *lv);
/* Specify size in KB */
const char *display_size(const struct cmd_context *cmd, uint64_t size);
@ -52,6 +53,9 @@ void vgdisplay_short(const struct volume_group *vg);
void display_formats(const struct cmd_context *cmd);
void display_segtypes(const struct cmd_context *cmd);
void display_tags(const struct cmd_context *cmd);
void display_name_error(name_error_t name_error);
/*
* Allocation policy display conversion routines.
@ -60,6 +64,8 @@ const char *get_alloc_string(alloc_policy_t alloc);
char alloc_policy_char(alloc_policy_t alloc);
alloc_policy_t get_alloc_from_string(const char *str);
const char *get_percent_string(percent_type_t def);
char yes_no_prompt(const char *prompt, ...) __attribute__ ((format(printf, 1, 2)));
#endif

View File

@ -63,7 +63,6 @@ static int _errseg_target_present(struct cmd_context *cmd,
_errseg_checked = 1;
return _errseg_present;
}
#endif
static int _errseg_modules_needed(struct dm_pool *mem,
const struct lv_segment *seg __attribute__((unused)),
@ -76,6 +75,7 @@ static int _errseg_modules_needed(struct dm_pool *mem,
return 1;
}
#endif
static void _errseg_destroy(struct segment_type *segtype)
{
@ -88,8 +88,8 @@ static struct segtype_handler _error_ops = {
#ifdef DEVMAPPER_SUPPORT
.add_target_line = _errseg_add_target_line,
.target_present = _errseg_target_present,
#endif
.modules_needed = _errseg_modules_needed,
#endif
.destroy = _errseg_destroy,
};

View File

@ -14,7 +14,7 @@
*/
#include "lib.h"
#include "filter-composite.h"
#include "filter.h"
static int _and_p(struct dev_filter *f, struct device *dev)
{
@ -22,9 +22,7 @@ static int _and_p(struct dev_filter *f, struct device *dev)
for (filters = (struct dev_filter **) f->private; *filters; ++filters)
if (!(*filters)->passes_filter(*filters, dev))
return_0;
log_debug_devs("Using %s", dev_name(dev));
return 0; /* No 'stack': a filter, not an error. */
return 1;
}
@ -92,5 +90,7 @@ struct dev_filter *composite_filter_create(int n, struct dev_filter **filters)
cft->use_count = 0;
cft->private = filters_copy;
log_debug_devs("Composite filter initialised.");
return cft;
}

View File

@ -1,23 +0,0 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 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_FILTER_COMPOSITE_H
#define _LVM_FILTER_COMPOSITE_H
#include "dev-cache.h"
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters);
#endif

View File

@ -14,9 +14,9 @@
*/
#include "lib.h"
#include "filter-md.h"
#include "filter.h"
#ifdef linux
#ifdef __linux__
static int _ignore_md(struct dev_filter *f __attribute__((unused)),
struct device *dev)
@ -64,6 +64,8 @@ struct dev_filter *md_filter_create(struct dev_types *dt)
f->use_count = 0;
f->private = dt;
log_debug_devs("MD filter initialised.");
return f;
}

View File

@ -1,24 +0,0 @@
/*
* Copyright (C) 2004 Luca Berra
*
* 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_FILTER_MD_H
#define _LVM_FILTER_MD_H
#include "dev-cache.h"
#include "dev-type.h"
struct dev_filter *md_filter_create(struct dev_types *dt);
#endif

View File

@ -13,16 +13,16 @@
*/
#include "lib.h"
#include "filter-mpath.h"
#include "filter.h"
#include "activate.h"
#ifdef linux
#ifdef __linux__
#include <dirent.h>
#define MPATH_PREFIX "mpath-"
static const char *get_sysfs_name(struct device *dev)
static const char *_get_sysfs_name(struct device *dev)
{
const char *name;
@ -40,7 +40,35 @@ static const char *get_sysfs_name(struct device *dev)
return name;
}
static int get_sysfs_string(const char *path, char *buffer, int max_size)
static const char *_get_sysfs_name_by_devt(const char *sysfs_dir, dev_t devno,
char *buf, size_t buf_size)
{
const char *name;
char path[PATH_MAX];
int size;
if (dm_snprintf(path, sizeof(path), "%s/dev/block/%d:%d", sysfs_dir,
(int) MAJOR(devno), (int) MINOR(devno)) < 0) {
log_error("Sysfs path string is too long.");
return NULL;
}
if ((size = readlink(path, buf, buf_size - 1)) < 0) {
log_sys_error("readlink", path);
return NULL;
}
buf[size] = '\0';
if (!(name = strrchr(buf, '/'))) {
log_error("Cannot find device name in sysfs path.");
return NULL;
}
name++;
return name;
}
static int _get_sysfs_string(const char *path, char *buffer, int max_size)
{
FILE *fp;
int r = 0;
@ -61,7 +89,7 @@ static int get_sysfs_string(const char *path, char *buffer, int max_size)
return r;
}
static int get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, int *major, int *minor)
static int _get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, int *major, int *minor)
{
char path[PATH_MAX], buffer[64];
@ -70,7 +98,7 @@ static int get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, i
return 0;
}
if (!get_sysfs_string(path, buffer, sizeof(buffer)))
if (!_get_sysfs_string(path, buffer, sizeof(buffer)))
return_0;
if (sscanf(buffer, "%d:%d", major, minor) != 2) {
@ -81,7 +109,7 @@ static int get_sysfs_get_major_minor(const char *sysfs_dir, const char *kname, i
return 1;
}
static int get_parent_mpath(const char *dir, char *name, int max_size)
static int _get_parent_mpath(const char *dir, char *name, int max_size)
{
struct dirent *d;
DIR *dr;
@ -113,13 +141,12 @@ static int get_parent_mpath(const char *dir, char *name, int max_size)
return r;
}
static int dev_is_mpath(struct dev_filter *f, struct device *dev)
static int _dev_is_mpath(struct dev_filter *f, struct device *dev)
{
struct dev_types *dt = (struct dev_types *) f->private;
const char *name;
char path[PATH_MAX+1];
char parent_name[PATH_MAX+1];
const char *part_name, *name;
struct stat info;
char path[PATH_MAX], parent_name[PATH_MAX];
const char *sysfs_dir = dm_sysfs_dir();
int major = MAJOR(dev->dev);
int minor = MINOR(dev->dev);
@ -130,38 +157,24 @@ static int dev_is_mpath(struct dev_filter *f, struct device *dev)
return 0;
switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
case 0:
/* Error. */
log_error("Failed to get primary device for %d:%d.", major, minor);
return 0;
case 1:
/* The dev is already a primary dev. Just continue with the dev. */
break;
case 2:
/* The dev is partition. */
name = dev_name(dev); /* name of original dev for log_debug msg */
/* Get primary dev from cache. */
if (!(dev = dev_cache_get_by_devt(primary_dev, NULL))) {
log_error("dev_is_mpath: failed to get device for %d:%d",
major, minor);
return 0;
}
major = (int) MAJOR(primary_dev);
minor = (int) MINOR(primary_dev);
log_debug_devs("%s: Device is a partition, using primary "
"device %s for mpath component detection",
name, dev_name(dev));
break;
case 2: /* The dev is partition. */
part_name = dev_name(dev); /* name of original dev for log_debug msg */
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, parent_name, sizeof(parent_name))))
return_0;
log_debug_devs("%s: Device is a partition, using primary "
"device %s for mpath component detection",
part_name, name);
break;
case 1: /* The dev is already a primary dev. Just continue with the dev. */
if (!(name = _get_sysfs_name(dev)))
return_0;
break;
default: /* 0, error. */
log_error("Failed to get primary device for %d:%d.", major, minor);
return 0;
}
if (!(name = get_sysfs_name(dev)))
return_0;
if (dm_snprintf(path, PATH_MAX, "%s/block/%s/holders", sysfs_dir, name) < 0) {
if (dm_snprintf(path, sizeof(path), "%s/block/%s/holders", sysfs_dir, name) < 0) {
log_error("Sysfs path to check mpath is too long.");
return 0;
}
@ -175,24 +188,21 @@ static int dev_is_mpath(struct dev_filter *f, struct device *dev)
return 0;
}
if (!get_parent_mpath(path, parent_name, PATH_MAX))
if (!_get_parent_mpath(path, parent_name, sizeof(parent_name)))
return 0;
if (!get_sysfs_get_major_minor(sysfs_dir, parent_name, &major, &minor))
if (!_get_sysfs_get_major_minor(sysfs_dir, parent_name, &major, &minor))
return_0;
if (major != dt->device_mapper_major) {
log_error("mpath major %d is not dm major %d.", major,
dt->device_mapper_major);
if (major != dt->device_mapper_major)
return 0;
}
return lvm_dm_prefix_check(major, minor, MPATH_PREFIX);
}
static int _ignore_mpath(struct dev_filter *f, struct device *dev)
{
if (dev_is_mpath(f, dev) == 1) {
if (_dev_is_mpath(f, dev) == 1) {
log_debug_devs("%s: Skipping mpath component device", dev_name(dev));
return 0;
}
@ -228,6 +238,8 @@ struct dev_filter *mpath_filter_create(struct dev_types *dt)
f->use_count = 0;
f->private = dt;
log_debug_devs("mpath filter initialised.");
return f;
}

View File

@ -0,0 +1,83 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2012 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
*/
#include "lib.h"
#include "filter.h"
static int _passes_partitioned_filter(struct dev_filter *f, struct device *dev)
{
struct dev_types *dt = (struct dev_types *) f->private;
const char *name = dev_name(dev);
int ret = 0;
uint64_t size;
/* Check it's accessible */
if (!dev_open_readonly_quiet(dev)) {
log_debug_devs("%s: Skipping: open failed", name);
return 0;
}
/* Check it's not too small */
if (!dev_get_size(dev, &size)) {
log_debug_devs("%s: Skipping: dev_get_size failed", name);
goto out;
}
if (size < pv_min_size()) {
log_debug_devs("%s: Skipping: Too small to hold a PV", name);
goto out;
}
if (dev_is_partitioned(dt, dev)) {
log_debug_devs("%s: Skipping: Partition table signature found",
name);
goto out;
}
ret = 1;
out:
if (!dev_close(dev))
stack;
return ret;
}
static void _partitioned_filter_destroy(struct dev_filter *f)
{
if (f->use_count)
log_error(INTERNAL_ERROR "Destroying partitioned filter while in use %u times.", f->use_count);
dm_free(f);
}
struct dev_filter *partitioned_filter_create(struct dev_types *dt)
{
struct dev_filter *f;
if (!(f = dm_zalloc(sizeof(struct dev_filter)))) {
log_error("Partitioned filter allocation failed");
return NULL;
}
f->passes_filter = _passes_partitioned_filter;
f->destroy = _partitioned_filter_destroy;
f->use_count = 0;
f->private = dt;
log_debug_devs("Partitioned filter initialised.");
return f;
}

View File

@ -14,7 +14,7 @@
*/
#include "lib.h"
#include "filter-persistent.h"
#include "filter.h"
#include "config.h"
#include "lvm-file.h"
#include "activate.h"
@ -114,7 +114,7 @@ int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out
return_0;
}
if (!(cft = config_open(CONFIG_FILE, pf->file, 1)))
if (!(cft = config_open(CONFIG_FILE_SPECIAL, pf->file, 1)))
return_0;
if (!config_file_read(cft))
@ -272,7 +272,7 @@ static int _lookup_p(struct dev_filter *f, struct device *dev)
{
struct pfilter *pf = (struct pfilter *) f->private;
void *l = dm_hash_lookup(pf->devices, dev_name(dev));
struct str_list *sl;
struct dm_str_list *sl;
/* Cached BAD? */
if (l == PF_BAD_DEVICE) {
@ -366,6 +366,8 @@ struct dev_filter *persistent_filter_create(struct dev_types *dt,
f->wipe = _persistent_filter_wipe;
f->dump = _persistent_filter_dump;
log_debug_devs("Persistent filter initialised.");
return f;
bad:

View File

@ -1,28 +0,0 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2006 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_FILTER_PERSISTENT_H
#define _LVM_FILTER_PERSISTENT_H
#include "dev-cache.h"
#include "dev-type.h"
struct dev_filter *persistent_filter_create(struct dev_types *dt,
struct dev_filter *f,
const char *file);
int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out);
#endif

View File

@ -14,7 +14,7 @@
*/
#include "lib.h"
#include "filter-regex.h"
#include "filter.h"
struct rfilter {
struct dm_pool *mem;
@ -149,7 +149,7 @@ static int _accept_p(struct dev_filter *f, struct device *dev)
{
int m, first = 1, rejected = 0;
struct rfilter *rf = (struct rfilter *) f->private;
struct str_list *sl;
struct dm_str_list *sl;
dm_list_iterate_items(sl, &dev->aliases) {
m = dm_regex_match(rf->engine, sl->str);
@ -212,6 +212,9 @@ struct dev_filter *regex_filter_create(const struct dm_config_value *patterns)
f->destroy = _regex_destroy;
f->use_count = 0;
f->private = rf;
log_debug_devs("Regex filter initialised.");
return f;
bad:

View File

@ -1,31 +0,0 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 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_FILTER_REGEX_H
#define _LVM_FILTER_REGEX_H
#include "dev-cache.h"
/*
* patterns must be an array of strings of the form:
* [ra]<sep><regex><sep>, eg,
* r/cdrom/ - reject cdroms
* a|loop/[0-4]| - accept loops 0 to 4
* r|.*| - reject everything else
*/
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns);
#endif

View File

@ -13,9 +13,9 @@
*/
#include "lib.h"
#include "filter-sysfs.h"
#include "filter.h"
#ifdef linux
#ifdef __linux__
#include <dirent.h>
@ -23,64 +23,61 @@ static int _locate_sysfs_blocks(const char *sysfs_dir, char *path, size_t len,
unsigned *sysfs_depth)
{
struct stat info;
unsigned i;
static const struct dir_class {
const char path[32];
int depth;
} classes[] = {
/*
* unified classification directory for all kernel subsystems
*
* /sys/subsystem/block/devices
* |-- sda -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
* |-- sda1 -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
* `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
*
*/
{ "subsystem/block/devices", 0 },
/*
* unified classification directory for all kernel subsystems
*
* /sys/subsystem/block/devices
* |-- sda -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
* |-- sda1 -> ../../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
* `-- sr0 -> ../../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
*
*/
if (dm_snprintf(path, len, "%s/%s", sysfs_dir,
"subsystem/block/devices") >= 0) {
if (!stat(path, &info)) {
*sysfs_depth = 0;
/*
* block subsystem as a class
*
* /sys/class/block
* |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
* |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
* `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
*
*/
{ "class/block", 0 },
/*
* old block subsystem layout with nested directories
*
* /sys/block/
* |-- sda
* | |-- capability
* | |-- dev
* ...
* | |-- sda1
* | | |-- dev
* ...
* |
* `-- sr0
* |-- capability
* |-- dev
* ...
*
*/
{ "block", 1 }
};
for (i = 0; i < DM_ARRAY_SIZE(classes); ++i)
if ((dm_snprintf(path, len, "%s%s", sysfs_dir, classes[i].path) >= 0) &&
(stat(path, &info) == 0)) {
*sysfs_depth = classes[i].depth;
return 1;
}
}
/*
* block subsystem as a class
*
* /sys/class/block
* |-- sda -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda
* |-- sda1 -> ../../devices/pci0000:00/0000:00:1f.2/host0/target0:0:0/0:0:0:0/block/sda/sda1
* `-- sr0 -> ../../devices/pci0000:00/0000:00:1f.2/host1/target1:0:0/1:0:0:0/block/sr0
*
*/
if (dm_snprintf(path, len, "%s/%s", sysfs_dir, "class/block") >= 0) {
if (!stat(path, &info)) {
*sysfs_depth = 0;
return 1;
}
}
/*
* old block subsystem layout with nested directories
*
* /sys/block/
* |-- sda
* | |-- capability
* | |-- dev
* ...
* | |-- sda1
* | | |-- dev
* ...
* |
* `-- sr0
* |-- capability
* |-- dev
* ...
*
*/
if (dm_snprintf(path, len, "%s/%s", sysfs_dir, "block") >= 0) {
if (!stat(path, &info)) {
*sysfs_depth = 1;
return 1;
}
}
return 0;
}
@ -324,6 +321,9 @@ struct dev_filter *sysfs_filter_create(void)
f->destroy = _destroy;
f->use_count = 0;
f->private = ds;
log_debug_devs("Sysfs filter initialised.");
return f;
bad:

View File

@ -20,8 +20,6 @@ static int _passes_lvm_type_device_filter(struct dev_filter *f, struct device *d
{
struct dev_types *dt = (struct dev_types *) f->private;
const char *name = dev_name(dev);
int ret = 0;
uint64_t size;
/* Is this a recognised device type? */
if (!dt->dev_type_array[MAJOR(dev->dev)].max_partitions) {
@ -30,36 +28,7 @@ static int _passes_lvm_type_device_filter(struct dev_filter *f, struct device *d
return 0;
}
/* Check it's accessible */
if (!dev_open_readonly_quiet(dev)) {
log_debug_devs("%s: Skipping: open failed", name);
return 0;
}
/* Check it's not too small */
if (!dev_get_size(dev, &size)) {
log_debug_devs("%s: Skipping: dev_get_size failed", name);
goto out;
}
if (size < pv_min_size()) {
log_debug_devs("%s: Skipping: Too small to hold a PV", name);
goto out;
}
if (dev_is_partitioned(dt, dev)) {
log_debug_devs("%s: Skipping: Partition table signature found",
name);
goto out;
}
ret = 1;
out:
if (!dev_close(dev))
stack;
return ret;
return 1;
}
static void _lvm_type_filter_destroy(struct dev_filter *f)
@ -84,5 +53,7 @@ struct dev_filter *lvm_type_filter_create(struct dev_types *dt)
f->use_count = 0;
f->private = dt;
log_debug_devs("LVM type filter initialised.");
return f;
}

View File

@ -1,6 +1,7 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2005 Red Hat, Inc. All rights reserved.
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004 Luca Berra
* Copyright (C) 2004-2013 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@ -19,6 +20,26 @@
#include "dev-cache.h"
#include "dev-type.h"
struct dev_filter *composite_filter_create(int n, struct dev_filter **filters);
struct dev_filter *lvm_type_filter_create(struct dev_types *dt);
struct dev_filter *md_filter_create(struct dev_types *dt);
struct dev_filter *mpath_filter_create(struct dev_types *dt);
struct dev_filter *partitioned_filter_create(struct dev_types *dt);
struct dev_filter *persistent_filter_create(struct dev_types *dt,
struct dev_filter *f,
const char *file);
struct dev_filter *sysfs_filter_create(void);
#endif
/*
* patterns must be an array of strings of the form:
* [ra]<sep><regex><sep>, eg,
* r/cdrom/ - reject cdroms
* a|loop/[0-4]| - accept loops 0 to 4
* r|.*| - reject everything else
*/
struct dev_filter *regex_filter_create(const struct dm_config_value *patterns);
int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out);
#endif /* _LVM_FILTER_H */

Some files were not shown because too many files have changed in this diff Show More