1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-10-01 21:44:22 +03:00

Compare commits

...

57 Commits

Author SHA1 Message Date
Alasdair G Kergon
3aab784aa5 pre-release 2016-04-09 02:08:44 +01:00
Zdenek Kabelac
af148a9d77 cleanup: avoid gcc warns
Some older systems may had global declaration to cause gcc warning.
Rename for cases we don't care...
2016-04-08 20:20:16 +02:00
Zdenek Kabelac
5cfa6cb347 cleanup: simplier to read condition
Make more readable what we are looking for and just test for
KERNEL version at one place.
2016-04-08 20:20:16 +02:00
Zdenek Kabelac
74e704bb44 cleanup: reuse _setup_task
Shorten code and use common code from _setup_task.
Reorder naming of major:minor sscanf (as later it's been
also used swapped there was no real bug).
2016-04-08 20:20:16 +02:00
Zdenek Kabelac
a09d65891f dev_manager: device_is_usable does not flush
When scanning if device is being usable as PV,
we call STATUS - but this status should not cause
any flushing.
Skip also open_count information as it's not needed.
2016-04-08 20:20:04 +02:00
Alasdair G Kergon
f40dfb48ad activation: Skip another non-prefixed info ioctl.
_percent() also does a lookup by dm uuid.
Also get kernel version from cmd->kernel_vsn.
2016-04-08 16:27:12 +01:00
Marian Csontos
e6768997e1 test: Fix testing of installed lvmdbusd
If lvmdbusd is missing expression triggers ERR trap instead of skipping
the test.
2016-04-08 16:26:25 +02:00
Peter Rajnoha
ed0c779bd1 report: remove superfluous SEGSSTATUS report type
We don't have any report field of this type yet. Return this patch into
the play if we really need that. Currenly we always report status
(result of "status" dm ioctl) for an LV as a whole where we choose
segment which represents the LV, not calling status for each possible
segment it contains - we don't need this now so I'm removing it to
not make the code more complex uselessly.
2016-04-08 14:21:47 +02:00
Peter Rajnoha
50866034a2 cleanup: use common init/destroy_processing_handle in _report fn and cleanup error paths 2016-04-08 11:01:19 +02:00
Peter Rajnoha
f2e59e05ed cleanup: use #define for field's quote and pair character and also for the error msg while extending output line 2016-04-08 10:55:13 +02:00
Zdenek Kabelac
248f47d489 tests: require newer cache target
Older cache target is likely not updating status at all...
2016-04-08 00:04:26 +02:00
Zdenek Kabelac
9ab53dddf5 tests: use mkfs.ext3
mkfs.ext4 is not really needed so use more widespread mkfs.ext3
so test runs on older system.
2016-04-07 22:32:09 +02:00
Zdenek Kabelac
8b2108e6b1 activation: do not check for devs without LVM-
Devices without "LVM-" uuid prefix have been generated by very old
version of lvm2 2.00 and 2.01.
Since version 2.02 all lvm2 devices are using prefix "LVM-".

However checking for present of ancient non prefixed devices does
take extra IOCTL per every call and for majority of todays user
it will not find anything new.

So use the assumption that users with kernel 3.X and newer are not
really using such old versions of lvm2 (year <2005) and with their
new kernel they are also using new version of lvm2 and skip
checking for them.

This change also makes trace logs more readable.
2016-04-07 22:32:08 +02:00
Zdenek Kabelac
097a724bda lvcreate: %FREE -> %PVS
This is hotfix for RHBZ: https://bugzilla.redhat.com/1324537
However already the %FREE is not a good fit and we need something
better. Meanwhile make  -l%PVS work at least as good as %FREE
for thin-pool.

TODO: this needs rework - it should be allocator to do all the size
decisions at one place.
2016-04-07 22:32:08 +02:00
Zdenek Kabelac
e2d4f53c82 WHATS_NEW: update
doc for previous commits.
2016-04-07 22:31:40 +02:00
Alasdair G Kergon
7dcbf1dfd0 libdm: Correct typo. 2016-04-07 01:51:09 +01:00
Alasdair G Kergon
f19ec0e36d lvmdump: If dir exists check dir perms too. 2016-04-06 22:56:45 +01:00
Alasdair G Kergon
55001ae9ec lvmdump: Allow dir to exist already if it is empty 2016-04-06 22:36:42 +01:00
Zdenek Kabelac
307ab2c179 tests: do not break teardown on failing losetup
Ignore failing 'losetup -d' - i.e. device may have disappeared...
2016-04-06 11:54:37 +02:00
Zdenek Kabelac
07c25429e2 tests: verify repair of failing mirror
Improved test script to verify lost mirror image does not
cause mirror corruption while mirror is in use.

TODO: add more cases (lost mlog...), lost image from 3leg mirror...
2016-04-06 11:54:36 +02:00
Zdenek Kabelac
9be7bca4be cleanup: indent 2016-04-06 11:31:02 +02:00
Zdenek Kabelac
0584e85736 lvconvert: show percent with %.2
lvm2 shows percent values with 2 decimal digits elsewhere so use
it consistently also for this output.
2016-04-06 11:31:02 +02:00
Zdenek Kabelac
261a85ced9 libdm: improve debug message with ioctl
Make the debug message a less difficult to read:
Ioctl shows  [ noopencount flush ] instead of cryptic [NF].
2016-04-06 11:31:02 +02:00
Zdenek Kabelac
5b2227c2c1 preload: preserve flushing state
When leaving preload routine it should not altet state of flush required
when it's been already set to 1 and drop it to 0.

The API here is unclean, but current usage expects the same
variable pointer is for all preload calls and combines 'flush_required'
across all of them.
2016-04-06 11:31:02 +02:00
Zdenek Kabelac
7c1937f8df suspend: fix suspend with noflush limitation
Commit 844b009584 tried to move
limit for usage of noflush to 'preload' however this was not
correctly processed.

Intead explicitly check for which types we do not want noflush
and also add debug message in this case.
2016-04-06 11:31:02 +02:00
Zdenek Kabelac
d4c03cf7b2 mirror: fix flushing for mirror target
Fix regression caused by commit ba41ee1dc9.
The idea was to use no_flush for changed device only for thin volumes
and thin pools but also to merge this with change made in commit
844b009584.

However the resulting condition has caused misbehavior for the mirror
suspend - as that has been before the ONLY allowed target type
that could have been suspended with noflush.

Result was badly working repair for --type mirror that has been
passing 'flush' to the repaired mirror target whenever preload
wrongly set flush_required.

The origin code has required the flush_required to be set whenever
deivce size is changed.

Now it first detects if device size got smaller
'dm_tree_node_size_changed(root) < 0' - this requires flush.
Otherwise it checks device is not thin volume nor thin pool and its
size has changed (got bigger) and requires flush.

This mean upsize of thin-pool or thin volume will not require flush.
2016-04-06 11:31:02 +02:00
Alasdair G Kergon
76fc41fb9d post-release 2016-04-01 20:36:40 +01:00
Alasdair G Kergon
2d0d58b867 pre-release 2016-04-01 20:29:52 +01:00
Alasdair G Kergon
60befab773 Revert "thin: display highest mapped sector"
This reverts commit fc7dacaa4c.

Let's put this information into a separate field.  It doesn't meet the
definition of the existing field.
2016-04-01 20:09:38 +01:00
Peter Rajnoha
42f04a0f77 dev-cache: skip VGID/LVID indexing if /sys/dev/block is not present
/sys/dev/block is available since kernel version 2.2.26 (~ 2008):
https://www.kernel.org/doc/Documentation/ABI/testing/sysfs-dev

The VGID/LVID indexing code relies on this feature so skip indexing
if it's not available to avoid error messages about inability to open
/sys/dev/block directory.

We're not going to provide fallback code to read the /sys/block/
instead in this case as that's not that efficient - it needs extra
reads for getting major:minor and reading partitions would also
pose further reads and that's not worth it.
2016-04-01 17:09:15 +02:00
Peter Rajnoha
9f28eb4c20 fix: make udev_get_library_context available also for non-udev compilations
If compiling without udev_sync support, udev_get_library_context simply
returns NULL so we don't need to remember putting ifdef UDEV_SYNC_SUPPORT
in the code all the time we just need to check whether there's any udev
context initialized or not.
2016-04-01 15:35:22 +02:00
Peter Rajnoha
15d1824fac dev-cache: iterate devices in sysfs for VGID/LVID index if obtain_device_list_from_udev=0
If obtain_device_list_from_udev=0, LVM can make use of persistent .cache
file. This cache file contains only devices which underwent filters in
previous LVM command run. But we need to iterate over all block devices
to create the VGID/LVID index completely for the device mismatch check
to be complete as well.

This patch iterates over block devices found in sysfs to generate the
VGID/LVID index in dev cache if obtain_device_list_from_udev=0
(if obtain_device_list_from_udev=1, we always read complete list of
block devices from udev and we ignore .cache file so we don't need
to look in sysfs for the complete list).
2016-04-01 14:49:39 +02:00
Peter Rajnoha
7ed5a65ee5 dev-cache: also add dev name for device found in sysfs only
For the case when we print device name associated with struct device
that was not found in /dev, but in sysfs, for example when printing
devices where LV device mismatch is found.
2016-04-01 14:48:56 +02:00
Peter Rajnoha
91d32f9d1b refactor: dev-cache: move code adding sysfs-only device into separate fn 2016-04-01 11:47:06 +02:00
Peter Rajnoha
0e774d5ae7 refactor: dev-cache: use btree instead of hash table for sysfs-only devices
major:minor btree is more convenient and more suitable than dev name
hash table here.
2016-04-01 11:42:25 +02:00
Zdenek Kabelac
c577984630 tests: fixed cache target reacts faster
After kernel fixed in 4.6 cache target reacts promptly
and switches to Fail-ed state when disk error is detected.

Handle both cases in test...
2016-03-31 12:21:40 +02:00
Zdenek Kabelac
bc5376b151 tests: do not test settings when MQ is emulated by SMQ 2016-03-31 12:21:40 +02:00
Zdenek Kabelac
5034bb8d18 cleanup: use local var to read struct 2016-03-31 12:21:40 +02:00
Zdenek Kabelac
b10253ab4d cleanup: use TARGET define 2016-03-31 12:21:40 +02:00
Zdenek Kabelac
86db143307 cleanup: debug message fix
Reported-by: Ming-Hung Tsai <mingnus gmail com>
2016-03-31 12:21:25 +02:00
Zdenek Kabelac
fc7dacaa4c thin: display highest mapped sector
Use  meta%  to expose highest mapped sector in thinLV.
so showing there 100.00% means thinLV maps latest sector.

Currently using a 'trick' with total_numerator to pass-in
device size when  'seg==NULL'

TODO: Improve device status API per target - current 'percentage'
is not really extensible.
2016-03-31 12:20:43 +02:00
Zdenek Kabelac
8bbec41bd4 thin: no thin-pool flush when reading metadata status
Previous fix missed the fact the we do query for 'percent' with
seg value either set or unset (API overload...)
When 'seg' was unset, we still issue flush with status.
Fix it by cheking segtype by target_type.

As we check for segtype - we could also skip whole percentage
if the 'segtype' is unknown by code directly.

Reported-by: Ming-Hung Tsai <mingnus gmail com
2016-03-31 12:15:47 +02:00
Peter Rajnoha
fe7ae37f5e tests: vg-check-devs-used requires driver version 4.15 at least 2016-03-31 10:38:05 +02:00
Peter Rajnoha
9a086a6607 dev-cache: fix check for already indexed dev in _index_dev_by_vgid_and_lvid 2016-03-30 15:57:57 +02:00
Peter Rajnoha
06ef7ba876 doc: describe lvmlockd/lvmpolld features as available if LVM compiled with lockd/polld support 2016-03-30 14:10:56 +02:00
Peter Rajnoha
8b258a005b dev-cache: dev_cache_index_devs fn is available unconditionally
The new dev_cache_index_devs fn was under ifdef UDEV_SYNC_SUPPORT by mistake,
move it out of this ifdef.
2016-03-30 13:06:20 +02:00
Peter Rajnoha
52e0d0db44 dev-cache: remove spurious error msg if no value found in /sys/dev/block/<major>:<minor>/dm/uuid during dev scan
It's correct to have a DM device that has no DM UUID assigned
so no need to issue error message in this case. Also, if the
device doesn't have DM UUID, it's also clear it's not an LVM LV
(...when looking for VGID/LVID while creating VGID/LVID indices
in dev cache).

For example:

$ dmsetup create test --table "0 1 linear /dev/sda 0"
And there's no PV in the system.

Before this patch (spurious error message issued):
$ pvs
  _get_sysfs_value: /sys/dev/block/253:2/dm/uuid: no value

With this patch applied (no spurious error message):
$ pvs
2016-03-30 11:30:09 +02:00
Peter Rajnoha
8c27c52749 dev-cache: also index VGIDs and LVIDs if using persistent .cache file
If we're using persistent .cache file, we're reading this file instead
of traversing the /dev content. Fix missing indexing by VGID and LVID
here - hook this into persistent_filter_load where we populate device
cache from persistent .cache file instead of scanning /dev.

For example, inducing situation in which we warn about different device
actually used than what LVM thinks should be used based on metadata:

$ lsblk -s /dev/vg/lvol0
NAME     MAJ:MIN RM  SIZE RO TYPE MOUNTPOINT
vg-lvol0 253:4    0  124M  0 lvm
`-loop1    7:1    0  128M  0 loop

$ lvmconfig --type diff

global {
	use_lvmetad=0
}
devices {
	obtain_device_list_from_udev=0
}

(obtain_device_list_from_udev=0 also means the persistent .cache file is used)

Before this patch - pvs is fine as it does the dev scan, but lvs relies
on persistent .cache file and it misses the VGID/LVID indices to check
and warn about incorrect devices used:

$ pvs
  Found duplicate PV B9gXTHkIdEIiMVwcOoT2LX3Ywh4YIHgR: using /dev/loop0 not /dev/loop1
  Using duplicate PV /dev/loop0 without holders, ignoring /dev/loop1
  WARNING: Device mismatch detected for vg/lvol0 which is accessing /dev/loop1 instead of /dev/loop0.
  PV          VG Fmt  Attr PSize   PFree
  /dev/loop0 vg lvm2 a--  124.00m    0

$ lvs
  Found duplicate PV B9gXTHkIdEIiMVwcOoT2LX3Ywh4YIHgR: using /dev/loop0 not /dev/loop1
  Using duplicate PV /dev/loop0 without holders, ignoring /dev/loop1
  LV    VG Attr       LSize
  lvol0 vg -wi-a----- 124.00m

With this patch applied - both pvs and lvs is fine - the indices are
always created correctly (lvs just an example here, other LVM commands
that rely on persistent .cache file are fixed with this patch too):

$ pvs
  Found duplicate PV B9gXTHkIdEIiMVwcOoT2LX3Ywh4YIHgR: using /dev/loop0 not /dev/loop1
  Using duplicate PV /dev/loop0 without holders, ignoring /dev/loop1
  WARNING: Device mismatch detected for vg/lvol0 which is accessing /dev/loop1 instead of /dev/loop0.
  PV          VG Fmt  Attr PSize   PFree
  /dev/loop0 vg lvm2 a--  124.00m    0

$ lvs
  Found duplicate PV B9gXTHkIdEIiMVwcOoT2LX3Ywh4YIHgR: using /dev/loop0 not /dev/loop1
  Using duplicate PV /dev/loop0 without holders, ignoring /dev/loop1
  WARNING: Device mismatch detected for vg/lvol0 which is accessing /dev/loop1 instead of /dev/loop0.
  LV    VG Attr       LSize
  lvol0 vg -wi-a----- 124.00m
2016-03-30 11:00:01 +02:00
Peter Rajnoha
91bb202ded dev-cache: handle situation where device is referenced in sysfs, but the node is not yet in dev dir
It's possible that while a device is already referenced in sysfs, the node
is not yet in /dev directory.

This may happen in some rare cases right after LVs get created - we sync
with udev (or alternatively we create /dev content ourselves) while VG
lock is held. However, dev scan is done without VG lock so devices may
already be in sysfs, but /dev may not be updated yet if we call LVM command
right after LV creation (so the fact that fs_unlock is done within VG
lock is not usable here much). This is not a problem with devtmpfs as
there's at least kernel name for device in /dev as soon as the sysfs
item exists, but we still support environments without devtmpfs or
where different directory for dev nodes is used (e.g. our test suite).

This patch covers these situations by tracking such devices in
_cache.sysfs_only_names helper hash for the vgid/lvid check to work still.

This also resolves commit 6129d2e64d
which was then reverted by commit 109b7e2095
due to performance issues it may have brought (...and it didn't resolve
the problem fully anyway).
2016-03-30 10:56:46 +02:00
Marian Csontos
bc0372cf9d test: Add missing directory
Fix commit bb93a28bc1
2016-03-29 08:24:52 +02:00
Alasdair G Kergon
d6e8f18e4d post-commit 2016-03-26 09:07:21 +00:00
Alasdair G Kergon
b9d07f7a12 pre-release 2016-03-26 09:04:50 +00:00
Alasdair G Kergon
a5d53aec83 libdm: Raid status region units are sectors 2016-03-24 17:42:36 +00:00
Tony Asleson
d243db5466 lvmdbusd: Add '-' to allowable PV device path chars 2016-03-24 12:27:02 -05:00
Peter Rajnoha
109b7e2095 revert: 6129d2e64d
Unfortunately, commit 6129d2e64d may
cause performance issue. There's going to be a better fix...
2016-03-24 14:06:12 +01:00
Peter Rajnoha
37b548c6b5 WHATS_NEW: commit 6129d2e64d 2016-03-24 12:47:35 +01:00
Peter Rajnoha
6129d2e64d monitoring: sync /dev content before contacting dmeventd for monitor/unmonitor
dmeventd daemon may call further code itself that looks at /dev, e.g.
via dmeventd_lvm2_command call. We need to have a consistent view of
the /dev content at that time. Therefore, sync /dev content before
calling monitoring hook which contacts dmeventd.

This problem was quite hidden before, but now it has manifested itself
because of recent additions to dev-cache code where we started looking
at device holders as seen in sysfs. What happened here was that the
device was already in sysfs, but not yet under /dev and this triggered
the new error message sometimes:

  log_error("%s: failed to find associated device structure for holder %s.", devname, devpath);

This problem has manifested recently in our api/pytest.sh test from
testsuite where we create thin pool LVs and thin LVs and hence it also
causes dmeventd to be used as well and these error messages were
visible there.
2016-03-24 12:40:19 +01:00
41 changed files with 532 additions and 219 deletions

View File

@@ -1 +1 @@
2.02.148(2)-git (2016-03-19)
2.02.150(2)-git (2016-04-09)

View File

@@ -1 +1 @@
1.02.121-git (2016-03-19)
1.02.122-git (2016-04-09)

View File

@@ -1,5 +1,22 @@
Version 2.02.148 -
Version 2.02.150 - 9th April 2016
=================================
Avoid using flushing dm status ioctl when checking for usable DM device.
Check for devices without LVM- uuid prefix only with kernels < 3.X.
Reuse %FREE size aproximation with lvcreate -l%PVS thin-pool.
Allow the lvmdump directory to exist already provided it is empty.
Show lvconverted percentage with 2 decimal digits.
Fix regression in suspend when repairing --type mirror (2.02.133).
Version 2.02.149 - 1st April 2016
=================================
Do not flush thin-pool when checking metadata fullness.
Remove spurious error about no value in /sys/dev/block/major:minor/dm/uuid.
Fix device mismatch detection for LV if persistent .cache file is used.
Fix holder device not being found in /dev while sysfs has it during dev scan.
Version 2.02.148 - 26th March 2016
==================================
Introduce TARGET_NAME and MODULE NAME macros.
Replace hard-coded module and target names with macros.
Add pv_major and pv_minor report fields.
Detect and warn about mismatch between devices used and assumed for an LV.

View File

@@ -1,5 +1,10 @@
Version 1.02.121 -
Version 1.02.122 - 9th April 2016
=================================
Change log_debug ioctl flags from single characters into words.
Version 1.02.121 - 26th March 2016
==================================
Adjust raid status function.
Version 1.02.120 - 11th March 2016
==================================

View File

@@ -853,11 +853,14 @@ global {
# Configuration option global/use_lvmlockd.
# Use lvmlockd for locking among hosts using LVM on shared storage.
# See lvmlockd(8) for more information.
# Applicable only if LVM is compiled with lockd support in which
# case there is also lvmlockd(8) man page available for more
# information.
use_lvmlockd = 0
# Configuration option global/lvmlockd_lock_retries.
# Retry lvmlockd lock requests this many times.
# Applicable only if LVM is compiled with lockd support
# This configuration option has an automatic default value.
# lvmlockd_lock_retries = 3
@@ -867,7 +870,8 @@ global {
# LVs have been created, the internal LV needs to be extended. lvcreate
# will automatically extend the internal LV when needed by the amount
# specified here. Setting this to 0 disables the automatic extension
# and can cause lvcreate to fail.
# and can cause lvcreate to fail. Applicable only if LVM is compiled
# with lockd support
# This configuration option has an automatic default value.
# sanlock_lv_extend = 256
@@ -1014,6 +1018,7 @@ global {
# a native systemd service, which allows it to be started on demand,
# and to use its own control group. When this option is disabled, LVM
# commands will supervise long running operations by forking themselves.
# Applicable only if LVM is compiled with lvmpolld support.
use_lvmpolld = @DEFAULT_USE_LVMPOLLD@
# Configuration option global/notify_dbus.

View File

@@ -51,6 +51,7 @@ local {
# Configuration option local/host_id.
# The lvmlockd sanlock host_id.
# This must be unique among all hosts, and must be between 1 and 2000.
# Applicable only if LVM is compiled with lockd support
# This configuration option has an automatic default value.
# host_id = 0
}

View File

@@ -855,9 +855,9 @@ int dm_event_get_version(struct dm_event_fifos *fifos, int *version) {
return 1;
}
void dm_event_log_set(int debug_level, int use_syslog)
void dm_event_log_set(int debug_log_level, int use_syslog)
{
_debug_level = debug_level;
_debug_level = debug_log_level;
_use_syslog = use_syslog;
}

View File

@@ -106,7 +106,7 @@ int dm_event_register_handler(const struct dm_event_handler *dmevh);
int dm_event_unregister_handler(const struct dm_event_handler *dmevh);
/* Set debug level for logging, and whether to log on stdout/stderr or syslog */
void dm_event_log_set(int debug_level, int use_syslog);
void dm_event_log_set(int debug_log_level, int use_syslog);
/* Log messages acroding to current debug level */
__attribute__((format(printf, 6, 0)))

View File

@@ -389,7 +389,7 @@ def round_size(size_bytes):
return size_bytes + bs - remainder
_ALLOWABLE_CH = string.ascii_letters + string.digits + '#+.:=@_\/%'
_ALLOWABLE_CH = string.ascii_letters + string.digits + '#+-.:=@_\/%'
_ALLOWABLE_CH_SET = set(_ALLOWABLE_CH)
_ALLOWABLE_VG_LV_CH = string.ascii_letters + string.digits + '.-_+'

View File

@@ -660,7 +660,7 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
/* New thin-pool has no layer, but -tpool suffix needs to be queried */
if (!use_layer && lv_is_new_thin_pool(lv)) {
/* Check if there isn't existing old thin pool mapping in the table */
if (!dev_manager_info(cmd->mem, lv, NULL, 0, 0, &dminfo, NULL, NULL))
if (!dev_manager_info(cmd, lv, NULL, 0, 0, &dminfo, NULL, NULL))
return_0;
if (!dminfo.exists)
use_layer = 1;
@@ -669,7 +669,7 @@ static int _lv_info(struct cmd_context *cmd, const struct logical_volume *lv,
if (seg_status)
seg_status->seg = seg;
if (!dev_manager_info(cmd->mem, lv,
if (!dev_manager_info(cmd, lv,
(use_layer) ? lv_layer(lv) : NULL,
with_open_count, with_read_ahead,
&dminfo, (info) ? &info->read_ahead : NULL,
@@ -1160,7 +1160,7 @@ int lv_thin_pool_transaction_id(const struct logical_volume *lv,
if (!lv_info(lv->vg->cmd, lv, 1, NULL, 0, 0))
return 0;
log_debug_activation("Checking thin-pool percent for LV %s.",
log_debug_activation("Checking thin-pool transaction id for LV %s.",
display_lvname(lv));
if (!(dm = dev_manager_create(lv->vg->cmd, lv->vg->name, 1)))
@@ -1827,7 +1827,7 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
const struct logical_volume *lv_pre_to_free = NULL;
struct logical_volume *lv_pre_tmp;
struct seg_list *sl;
struct lv_segment *snap_seg;
struct lv_segment *snap_seg;
struct lvinfo info;
int r = 0, lockfs = 0, flush_required = 0;
struct detached_lv_data detached;
@@ -1933,6 +1933,16 @@ static int _lv_suspend(struct cmd_context *cmd, const char *lvid_s,
}
}
/* Flush is ATM required for the tested cases
* NOTE: Mirror repair requires noflush for proper repair!
* TODO: Relax this limiting condition further */
if (!flush_required &&
(lv_is_pvmove(lv) ||
(!lv_is_mirror(lv) && !lv_is_thin_pool(lv) && !lv_is_thin_volume(lv)))) {
log_debug("Requiring flush for LV %s.", display_lvname(lv));
flush_required = 1;
}
if (!monitor_dev_for_events(cmd, lv, laopts, 0))
/* FIXME Consider aborting here */
stack;

View File

@@ -337,13 +337,8 @@ static int _ignore_blocked_mirror_devices(struct device *dev,
* We avoid another system call if we can, but if a device is
* dead, we have no choice but to look up the table too.
*/
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
goto_out;
if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
goto_out;
if (activation_checks() && !dm_task_enable_checks(dmt))
if (!(dmt = _setup_task(NULL, NULL, NULL, DM_DEVICE_TABLE,
MAJOR(dev->dev), MINOR(dev->dev), 0)))
goto_out;
if (!dm_task_run(dmt))
@@ -384,13 +379,8 @@ static int _device_is_suspended(int major, int minor)
struct dm_info info;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_INFO)))
return 0;
if (!dm_task_set_major_minor(dmt, major, minor, 1))
goto_out;
if (activation_checks() && !dm_task_enable_checks(dmt))
if (!(dmt = _setup_task(NULL, NULL, NULL, DM_DEVICE_INFO,
major, minor, 0)))
goto_out;
if (!dm_task_run(dmt) ||
@@ -414,13 +404,8 @@ static int _ignore_suspended_snapshot_component(struct device *dev)
int major1, minor1, major2, minor2;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
return_0;
if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
goto_out;
if (activation_checks() && !dm_task_enable_checks(dmt))
if (!(dmt = _setup_task(NULL, NULL, NULL, DM_DEVICE_TABLE,
MAJOR(dev->dev), MINOR(dev->dev), 0)))
goto_out;
if (!dm_task_run(dmt)) {
@@ -466,32 +451,29 @@ static int _ignore_unusable_thins(struct device *dev)
if (!(mem = dm_pool_create("unusable_thins", 128)))
return_0;
if (!(dmt = dm_task_create(DM_DEVICE_TABLE)))
goto_out;
if (!dm_task_no_open_count(dmt))
goto_out;
if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
if (!(dmt = _setup_task(NULL, NULL, NULL, DM_DEVICE_TABLE,
MAJOR(dev->dev), MINOR(dev->dev), 0)))
goto_out;
if (!dm_task_run(dmt)) {
log_error("Failed to get state of mapped device.");
goto out;
}
dm_get_next_target(dmt, next, &start, &length, &target_type, &params);
if (!params || sscanf(params, "%d:%d", &minor, &major) != 2) {
if (!params || sscanf(params, "%d:%d", &major, &minor) != 2) {
log_error("Failed to get thin-pool major:minor for thin device %d:%d.",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev));
goto out;
}
dm_task_destroy(dmt);
if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
if (!(dmt = _setup_task(NULL, NULL, NULL, DM_DEVICE_STATUS,
major, minor, 0)))
goto_out;
if (!dm_task_no_flush(dmt))
log_warn("Can't set no_flush.");
if (!dm_task_no_open_count(dmt))
goto_out;
if (!dm_task_set_major_minor(dmt, minor, major, 1))
goto_out;
if (!dm_task_run(dmt)) {
log_error("Failed to get state of mapped device.");
goto out;
@@ -545,15 +527,14 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check)
int only_error_target = 1;
int r = 0;
if (!(dmt = dm_task_create(DM_DEVICE_STATUS)))
return_0;
if (!dm_task_set_major_minor(dmt, MAJOR(dev->dev), MINOR(dev->dev), 1))
if (!(dmt = _setup_task(NULL, NULL, NULL, DM_DEVICE_STATUS,
MAJOR(dev->dev), MINOR(dev->dev), 0)))
goto_out;
if (activation_checks() && !dm_task_enable_checks(dmt))
goto_out;
/* Non-blocking status read */
if (!dm_task_no_flush(dmt))
log_warn("WARNING: Can't set no_flush for dm status.");
if (!dm_task_run(dmt)) {
log_error("Failed to get state of mapped device");
goto out;
@@ -674,7 +655,32 @@ int device_is_usable(struct device *dev, struct dev_usable_check_params check)
return r;
}
static int _info(const char *dlid, int with_open_count, int with_read_ahead,
/*
* If active LVs were activated by a version of LVM2 before 2.02.00 we must
* perform additional checks to find them because they do not have the LVM-
* prefix on their dm uuids.
* As of 2.02.150, we've chosen to disable this compatibility arbitrarily if
* we're running kernel version 3 or above.
*/
#define MIN_KERNEL_MAJOR 3
static int _original_uuid_format_check_required(struct cmd_context *cmd)
{
static int _kernel_major = 0;
if (!_kernel_major) {
if ((sscanf(cmd->kernel_vsn, "%d", &_kernel_major) == 1) &&
(_kernel_major >= MIN_KERNEL_MAJOR))
log_debug_activation("Skipping checks for old devices without " UUID_PREFIX
" dm uuid prefix (kernel vsn %d >= %d).", _kernel_major, MIN_KERNEL_MAJOR);
else
_kernel_major = -1;
}
return (_kernel_major == -1);
}
static int _info(struct cmd_context *cmd, const char *dlid, int with_open_count, int with_read_ahead,
struct dm_info *dminfo, uint32_t *read_ahead,
struct lv_seg_status *seg_status)
{
@@ -703,6 +709,10 @@ static int _info(const char *dlid, int with_open_count, int with_read_ahead,
}
}
/* Must we still check for the pre-2.02.00 dm uuid format? */
if (!_original_uuid_format_check_required(cmd))
return r;
/* Check for dlid before UUID_PREFIX was added */
if ((r = _info_run(seg_status ? STATUS : INFO, NULL, dlid + sizeof(UUID_PREFIX) - 1,
dminfo, read_ahead, seg_status, with_open_count,
@@ -717,7 +727,7 @@ static int _info_by_dev(uint32_t major, uint32_t minor, struct dm_info *info)
return _info_run(INFO, NULL, NULL, info, NULL, 0, 0, 0, major, minor);
}
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
int dev_manager_info(struct cmd_context *cmd, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
struct dm_info *dminfo, uint32_t *read_ahead,
@@ -726,19 +736,19 @@ int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
char *dlid, *name;
int r;
if (!(name = dm_build_dm_name(mem, lv->vg->name, lv->name, layer)))
if (!(name = dm_build_dm_name(cmd->mem, lv->vg->name, lv->name, layer)))
return_0;
if (!(dlid = build_dm_uuid(mem, lv, layer))) {
if (!(dlid = build_dm_uuid(cmd->mem, lv, layer))) {
r = 0;
goto_out;
}
log_debug_activation("Getting device info for %s [%s]", name, dlid);
r = _info(dlid, with_open_count, with_read_ahead,
r = _info(cmd, dlid, with_open_count, with_read_ahead,
dminfo, read_ahead, seg_status);
out:
dm_pool_free(mem, name);
dm_pool_free(cmd->mem, name);
return r;
}
@@ -884,20 +894,22 @@ static int _percent_run(struct dev_manager *dm, const char *name,
char *params = NULL;
const struct dm_list *segh = lv ? &lv->segments : NULL;
struct lv_segment *seg = NULL;
struct segment_type *segtype;
int first_time = 1;
dm_percent_t percent = DM_PERCENT_INVALID;
uint64_t total_numerator = 0, total_denominator = 0;
struct segment_type *segtype;
*overall_percent = percent;
if (!(segtype = get_segtype_from_string(dm->cmd, target_type)))
return_0;
if (!(dmt = _setup_task(name, dlid, event_nr,
wait ? DM_DEVICE_WAITEVENT : DM_DEVICE_STATUS, 0, 0, 0)))
return_0;
/* No freeze on overfilled thin-pool, read existing slightly outdated data */
if (lv && lv_is_thin_pool(lv) &&
if (segtype_is_thin(segtype) &&
!dm_task_no_flush(dmt))
log_warn("Can't set no_flush flag."); /* Non fatal */
@@ -926,9 +938,6 @@ static int _percent_run(struct dev_manager *dm, const char *name,
if (!type || !params)
continue;
if (!(segtype = get_segtype_from_string(dm->cmd, target_type)))
continue;
if (strcmp(type, target_type)) {
/* If kernel's type isn't an exact match is it compatible? */
if (!segtype->ops->target_status_compatible ||
@@ -986,7 +995,8 @@ static int _percent(struct dev_manager *dm, const char *name, const char *dlid,
if (_percent_run(dm, NULL, dlid, target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported))
return 1;
else if (_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
else if (_original_uuid_format_check_required(dm->cmd) &&
_percent_run(dm, NULL, dlid + sizeof(UUID_PREFIX) - 1,
target_type, wait, lv, percent,
event_nr, fail_if_percent_unsupported))
return 1;
@@ -1329,10 +1339,10 @@ int dev_manager_cache_status(struct dev_manager *dm,
* ->target_percent() API is able to transfer only a single value.
* Needs to be able to pass whole structure.
*/
if (!dm_get_status_cache(dm->mem, params, &((*status)->cache)))
if (!dm_get_status_cache(dm->mem, params, &c))
goto_out;
c = (*status)->cache;
(*status)->cache = c;
(*status)->mem = dm->mem; /* User has to destroy this mem pool later */
if (c->fail || c->error) {
(*status)->data_usage =
@@ -1435,7 +1445,7 @@ int dev_manager_thin_percent(struct dev_manager *dm,
return_0;
log_debug_activation("Getting device status percentage for %s", name);
if (!(_percent(dm, name, dlid, "thin", 0,
if (!(_percent(dm, name, dlid, TARGET_NAME_THIN, 0,
(mapped) ? NULL : lv, percent, NULL, 1)))
return_0;
@@ -1664,7 +1674,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
return_0;
log_debug_activation("Getting device info for %s [%s]", name, dlid);
if (!_info(dlid, 1, 0, &info, NULL, NULL)) {
if (!_info(dm->cmd, dlid, 1, 0, &info, NULL, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
@@ -1862,8 +1872,8 @@ static int _pool_callback(struct dm_tree_node *node,
log_sys_error("close", argv[args]);
if (ret == (int) DM_ARRAY_SIZE(buf)) {
log_debug("%s skipped, detect empty disk header on %s.",
argv[0], argv[args]);
log_debug_activation("%s skipped, detect empty disk header on %s.",
argv[0], argv[args]);
return 1;
}
}
@@ -2188,7 +2198,7 @@ static char *_add_error_device(struct dev_manager *dm, struct dm_tree *dtree,
return_NULL;
log_debug_activation("Getting device info for %s [%s]", name, dlid);
if (!_info(dlid, 1, 0, &info, NULL, NULL)) {
if (!_info(dm->cmd, dlid, 1, 0, &info, NULL, NULL)) {
log_error("Failed to get info for %s [%s].", name, dlid);
return 0;
}
@@ -3024,7 +3034,7 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
break;
case SUSPEND:
dm_tree_skip_lockfs(root);
if (!dm->flush_required && !lv_is_pvmove(lv))
if (!dm->flush_required)
dm_tree_use_no_flush_suspend(root);
/* Fall through */
case SUSPEND_WITH_LOCKFS:
@@ -3045,12 +3055,11 @@ static int _tree_action(struct dev_manager *dm, const struct logical_volume *lv,
if ((dm_tree_node_size_changed(root) < 0))
dm->flush_required = 1;
/* Currently keep the code require flush for any
* non 'thin pool/volume, mirror' or with any size change */
if (!lv_is_thin_volume(lv) &&
!lv_is_thin_pool(lv) &&
(!lv_is_mirror(lv) || dm_tree_node_size_changed(root)))
* non 'thin pool/volume' and size increase */
else if (!lv_is_thin_volume(lv) &&
!lv_is_thin_pool(lv) &&
dm_tree_node_size_changed(root))
dm->flush_required = 1;
if (action == ACTIVATE) {
@@ -3095,6 +3104,8 @@ int dev_manager_activate(struct dev_manager *dm, const struct logical_volume *lv
int dev_manager_preload(struct dev_manager *dm, const struct logical_volume *lv,
struct lv_activate_opts *laopts, int *flush_required)
{
dm->flush_required = *flush_required;
if (!_tree_action(dm, lv, laopts, PRELOAD))
return_0;

View File

@@ -45,11 +45,12 @@ void dev_manager_exit(void);
* (eg, an origin is created before its snapshot, but is not
* unsuspended until the snapshot is also created.)
*/
int dev_manager_info(struct dm_pool *mem, const struct logical_volume *lv,
int dev_manager_info(struct cmd_context *cmd, const struct logical_volume *lv,
const char *layer,
int with_open_count, int with_read_ahead,
struct dm_info *dminfo, uint32_t *read_ahead,
struct lv_seg_status *seg_status);
int dev_manager_snapshot_percent(struct dev_manager *dm,
const struct logical_volume *lv,
dm_percent_t *percent);

View File

@@ -1133,7 +1133,7 @@ struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct i
}
const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
const char *devname)
const char *devname)
{
struct device *dev;
struct label *label;

View File

@@ -108,7 +108,7 @@ const char *lvmcache_vgid_from_vgname(struct cmd_context *cmd, const char *vgnam
struct device *lvmcache_device_from_pvid(struct cmd_context *cmd, const struct id *pvid,
unsigned *scan_done_once, uint64_t *label_sector);
const char *lvmcache_pvid_from_devname(struct cmd_context *cmd,
const char *dev_name);
const char *devname);
char *lvmcache_vgname_from_pvid(struct cmd_context *cmd, const char *pvid);
const char *lvmcache_vgname_from_info(struct lvmcache_info *info);
int lvmcache_vgs_locked(void);

View File

@@ -856,10 +856,13 @@ cfg(global_use_lvmetad_CFG, "use_lvmetad", global_CFG_SECTION, 0, CFG_TYPE_BOOL,
cfg(global_use_lvmlockd_CFG, "use_lvmlockd", global_CFG_SECTION, 0, CFG_TYPE_BOOL, 0, vsn(2, 2, 124), NULL, 0, NULL,
"Use lvmlockd for locking among hosts using LVM on shared storage.\n"
"See lvmlockd(8) for more information.\n")
"Applicable only if LVM is compiled with lockd support in which\n"
"case there is also lvmlockd(8) man page available for more\n"
"information.\n")
cfg(global_lvmlockd_lock_retries_CFG, "lvmlockd_lock_retries", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_LVMLOCKD_LOCK_RETRIES, vsn(2, 2, 125), NULL, 0, NULL,
"Retry lvmlockd lock requests this many times.\n")
"Retry lvmlockd lock requests this many times.\n"
"Applicable only if LVM is compiled with lockd support\n")
cfg(global_sanlock_lv_extend_CFG, "sanlock_lv_extend", global_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, DEFAULT_SANLOCK_LV_EXTEND_MB, vsn(2, 2, 124), NULL, 0, NULL,
"Size in MiB to extend the internal LV holding sanlock locks.\n"
@@ -867,7 +870,8 @@ cfg(global_sanlock_lv_extend_CFG, "sanlock_lv_extend", global_CFG_SECTION, CFG_D
"LVs have been created, the internal LV needs to be extended. lvcreate\n"
"will automatically extend the internal LV when needed by the amount\n"
"specified here. Setting this to 0 disables the automatic extension\n"
"and can cause lvcreate to fail.\n")
"and can cause lvcreate to fail. Applicable only if LVM is compiled\n"
"with lockd support\n")
cfg(global_thin_check_executable_CFG, "thin_check_executable", global_CFG_SECTION, CFG_ALLOW_EMPTY | CFG_DEFAULT_COMMENTED, CFG_TYPE_STRING, THIN_CHECK_CMD, vsn(2, 2, 94), "@THIN_CHECK_CMD@", 0, NULL,
"The full path to the thin_check command.\n"
@@ -993,7 +997,8 @@ cfg(global_use_lvmpolld_CFG, "use_lvmpolld", global_CFG_SECTION, 0, CFG_TYPE_BOO
"manage the progress of ongoing operations. lvmpolld can be used as\n"
"a native systemd service, which allows it to be started on demand,\n"
"and to use its own control group. When this option is disabled, LVM\n"
"commands will supervise long running operations by forking themselves.\n")
"commands will supervise long running operations by forking themselves.\n"
"Applicable only if LVM is compiled with lvmpolld support.\n")
cfg(global_notify_dbus_CFG, "notify_dbus", global_CFG_SECTION, 0, CFG_TYPE_BOOL, DEFAULT_NOTIFY_DBUS, vsn(2, 2, 145), NULL, 0, NULL,
"Enable D-Bus notification from LVM commands.\n"
@@ -1779,6 +1784,7 @@ cfg_array(local_extra_system_ids_CFG, "extra_system_ids", local_CFG_SECTION, CFG
cfg(local_host_id_CFG, "host_id", local_CFG_SECTION, CFG_DEFAULT_COMMENTED, CFG_TYPE_INT, 0, vsn(2, 2, 124), NULL, 0, NULL,
"The lvmlockd sanlock host_id.\n"
"This must be unique among all hosts, and must be between 1 and 2000.\n")
"This must be unique among all hosts, and must be between 1 and 2000.\n"
"Applicable only if LVM is compiled with lockd support\n")
cfg(CFG_COUNT, NULL, root_CFG_SECTION, 0, CFG_TYPE_INT, 0, vsn(0, 0, 0), NULL, 0, NULL, NULL)

View File

@@ -42,6 +42,7 @@ static struct {
struct dm_hash_table *names;
struct dm_hash_table *vgid_index;
struct dm_hash_table *lvid_index;
struct btree *sysfs_only_devices; /* see comments in _get_device_for_sysfs_dev_name_using_devno */
struct btree *devices;
struct dm_regex *preferred_names_matcher;
const char *dev_dir;
@@ -362,7 +363,7 @@ static int _add_alias(struct device *dev, const char *path)
return 1;
}
static int _get_sysfs_value(const char *path, char *buf, size_t buf_size)
static int _get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
{
FILE *fp;
size_t len;
@@ -379,8 +380,10 @@ static int _get_sysfs_value(const char *path, char *buf, size_t buf_size)
}
if (!(len = strlen(buf)) || (len == 1 && buf[0] == '\n')) {
log_error("_get_sysfs_value: %s: no value", path);
goto out;
if (error_if_no_value) {
log_error("_get_sysfs_value: %s: no value", path);
goto out;
}
}
if (buf[len - 1] == '\n')
@@ -403,7 +406,7 @@ static int _get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int mi
return 0;
}
return _get_sysfs_value(path, buf, buf_size);
return _get_sysfs_value(path, buf, buf_size, 0);
}
static struct dm_list *_get_or_add_list_by_index_key(struct dm_hash_table *idx, const char *key)
@@ -428,26 +431,80 @@ static struct dm_list *_get_or_add_list_by_index_key(struct dm_hash_table *idx,
return list;
}
static struct device *_insert_sysfs_dev(dev_t devno, const char *devname)
{
char path[PATH_MAX];
char *path_copy;
struct device *dev;
if (dm_snprintf(path, sizeof(path), "%s%s", _cache.dev_dir, devname) < 0) {
log_error("_insert_sysfs_dev: %s: dm_snprintf failed", devname);
return NULL;
}
if (!(dev = _dev_create(devno)))
return_NULL;
if (!(path_copy = dm_pool_strdup(_cache.mem, path))) {
log_error("_insert_sysfs_dev: %s: dm_pool_strdup failed", devname);
return NULL;
}
if (!_add_alias(dev, path_copy)) {
log_error("Couldn't add alias to dev cache.");
_free(dev);
return NULL;
}
if (!btree_insert(_cache.sysfs_only_devices, (uint32_t) devno, dev)) {
log_error("Couldn't add device to binary tree of sysfs-only devices in dev cache.");
_free(dev);
return NULL;
}
return dev;
}
static struct device *_get_device_for_sysfs_dev_name_using_devno(const char *devname)
{
char path[PATH_MAX];
char buf[PATH_MAX];
int major, minor;
dev_t devno;
struct device *dev;
if (dm_snprintf(path, sizeof(path), "%sblock/%s/dev", dm_sysfs_dir(), devname) < 0) {
log_error("_get_device_for_non_dm_dev: %s: dm_snprintf failed", devname);
log_error("_get_device_for_sysfs_dev_name_using_devno: %s: dm_snprintf failed", devname);
return NULL;
}
if (!_get_sysfs_value(path, buf, sizeof(buf)))
if (!_get_sysfs_value(path, buf, sizeof(buf), 1))
return_NULL;
if (sscanf(buf, "%d:%d", &major, &minor) != 2) {
log_error("_get_device_for_non_dm_dev: %s: failed to get major and minor number", devname);
log_error("_get_device_for_sysfs_dev_name_using_devno: %s: failed to get major and minor number", devname);
return NULL;
}
return (struct device *) btree_lookup(_cache.devices, (uint32_t) MKDEV(major, minor));
devno = MKDEV(major, minor);
if (!(dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devno))) {
/*
* If we get here, it means the device is referenced in sysfs, but it's not yet in /dev.
* This may happen in some rare cases right after LVs get created - we sync with udev
* (or alternatively we create /dev content ourselves) while VG lock is held. However,
* dev scan is done without VG lock so devices may already be in sysfs, but /dev may
* not be updated yet if we call LVM command right after LV creation. This is not a
* problem with devtmpfs as there's at least kernel name for device in /dev as soon
* as the sysfs item exists, but we still support environments without devtmpfs or
* where different directory for dev nodes is used (e.g. our test suite). So track
* such devices in _cache.sysfs_only_devices hash for the vgid/lvid check to work still.
*/
if (!(dev = (struct device *) btree_lookup(_cache.sysfs_only_devices, (uint32_t) devno)) &&
!(dev = _insert_sysfs_dev(devno, devname)))
return_NULL;
}
return dev;
}
#define NOT_LVM_UUID "-"
@@ -494,6 +551,10 @@ static int _index_dev_by_vgid_and_lvid(struct device *dev)
struct device_list *dl_vgid, *dl_lvid;
int r = 0;
if (dev->flags & DEV_USED_FOR_LV)
/* already indexed */
return 1;
/* Get holders for device. */
if (dm_snprintf(path, sizeof(path), "%sdev/block/%d:%d/holders/", dm_sysfs_dir(), (int) MAJOR(dev->dev), (int) MINOR(dev->dev)) < 0) {
log_error("%s: dm_snprintf failed for path to holders directory.", devname);
@@ -623,14 +684,15 @@ static int _insert_dev(const char *path, dev_t d)
}
/* is this device already registered ? */
if (!(dev = (struct device *) btree_lookup(_cache.devices,
(uint32_t) d))) {
/* create new device */
if (loopfile) {
if (!(dev = dev_create_file(path, NULL, NULL, 0)))
if (!(dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) d))) {
if (!(dev = (struct device *) btree_lookup(_cache.sysfs_only_devices, (uint32_t) d))) {
/* create new device */
if (loopfile) {
if (!(dev = dev_create_file(path, NULL, NULL, 0)))
return_0;
} else if (!(dev = _dev_create(d)))
return_0;
} else if (!(dev = _dev_create(d)))
return_0;
}
if (!(btree_insert(_cache.devices, (uint32_t) d, dev))) {
log_error("Couldn't insert device into binary tree.");
@@ -738,6 +800,108 @@ static int _insert_file(const char *path)
return 1;
}
static int _dev_cache_iterate_devs_for_index(void)
{
struct btree_iter *iter = btree_first(_cache.devices);
struct device *dev;
int r = 1;
while (iter) {
dev = btree_get_data(iter);
if (!_index_dev_by_vgid_and_lvid(dev))
r = 0;
iter = btree_next(iter);
}
return r;
}
static int _dev_cache_iterate_sysfs_for_index(const char *path)
{
char devname[PATH_MAX];
DIR *d;
struct dirent *dirent;
int major, minor;
dev_t devno;
struct device *dev;
int partial_failure = 0;
int r = 0;
if (!(d = opendir(path))) {
log_sys_error("opendir", path);
return 0;
}
while ((dirent = readdir(d))) {
if (!strcmp(".", dirent->d_name) ||
!strcmp("..", dirent->d_name))
continue;
if (sscanf(dirent->d_name, "%d:%d", &major, &minor) != 2) {
log_error("_dev_cache_iterate_sysfs_for_index: %s: failed "
"to get major and minor number", dirent->d_name);
partial_failure = 1;
continue;
}
devno = MKDEV(major, minor);
if (!(dev = (struct device *) btree_lookup(_cache.devices, (uint32_t) devno)) &&
!(dev = (struct device *) btree_lookup(_cache.sysfs_only_devices, (uint32_t) devno))) {
if (!dm_device_get_name(major, minor, 1, devname, sizeof(devname)) ||
!(dev = _insert_sysfs_dev(devno, devname))) {
partial_failure = 1;
continue;
}
}
if (!_index_dev_by_vgid_and_lvid(dev))
partial_failure = 1;
}
r = !partial_failure;
if (closedir(d))
log_sys_error("closedir", path);
return r;
}
int dev_cache_index_devs(void)
{
static int sysfs_has_dev_block = -1;
char path[PATH_MAX];
if (dm_snprintf(path, sizeof(path), "%sdev/block", dm_sysfs_dir()) < 0) {
log_error("dev_cache_index_devs: dm_snprintf failed.");
return 0;
}
/* Skip indexing if /sys/dev/block is not available.*/
if (sysfs_has_dev_block == -1) {
struct stat info;
if (stat(path, &info) == 0)
sysfs_has_dev_block = 1;
else {
if (errno == ENOENT) {
sysfs_has_dev_block = 0;
return 1;
} else {
log_sys_error("stat", path);
return 0;
}
}
} else if (!sysfs_has_dev_block)
return 1;
int with_udev = obtain_device_list_from_udev() &&
udev_get_library_context();
return with_udev ? _dev_cache_iterate_devs_for_index()
: _dev_cache_iterate_sysfs_for_index(path);
}
#ifdef UDEV_SYNC_SUPPORT
static int _device_in_udev_db(const dev_t d)
@@ -815,24 +979,6 @@ bad:
return 0;
}
static int _add_devs_to_index(void)
{
struct btree_iter *iter = btree_first(_cache.devices);
struct device *dev;
int r = 1;
while (iter) {
dev = btree_get_data(iter);
if (!_index_dev_by_vgid_and_lvid(dev))
r = 0;
iter = btree_next(iter);
}
return r;
}
static void _insert_dirs(struct dm_list *dirs)
{
struct dir_list *dl;
@@ -854,7 +1000,7 @@ static void _insert_dirs(struct dm_list *dirs)
"device cache fully", dl->dir);
}
(void) _add_devs_to_index();
(void) dev_cache_index_devs();
}
#else /* UDEV_SYNC_SUPPORT */
@@ -1029,6 +1175,11 @@ int dev_cache_init(struct cmd_context *cmd)
goto bad;
}
if (!(_cache.sysfs_only_devices = btree_create(_cache.mem))) {
log_error("Couldn't create binary tree for sysfs-only devices in dev cache.");
goto bad;
}
if (!(_cache.dev_dir = _strdup(cmd->dev_dir))) {
log_error("strdup dev_dir failed.");
goto bad;

View File

@@ -31,6 +31,7 @@ struct dev_filter {
unsigned use_count;
};
int dev_cache_index_devs(void);
struct dm_list *dev_cache_get_dev_list_for_vgid(const char *vgid);
struct dm_list *dev_cache_get_dev_list_for_lvid(const char *lvid);

View File

@@ -129,6 +129,8 @@ int persistent_filter_load(struct dev_filter *f, struct dm_config_tree **cft_out
if (dm_hash_get_num_entries(pf->devices)) {
/* We populated dev_cache ourselves */
dev_cache_scan(0);
if (!dev_cache_index_devs())
stack;
r = 1;
}

View File

@@ -1061,7 +1061,7 @@ struct lv_segment *get_only_segment_using_this_lv(const struct logical_volume *l
* Useful functions for managing snapshots.
*/
int lv_is_origin(const struct logical_volume *lv);
int lv_is_thin_origin(const struct logical_volume *lv, unsigned *snapshot_count);
int lv_is_thin_origin(const struct logical_volume *lv, unsigned *snap_count);
int lv_is_cache_origin(const struct logical_volume *lv);
int lv_is_cow(const struct logical_volume *lv);
int lv_is_merging_cow(const struct logical_volume *cow);

View File

@@ -66,7 +66,7 @@ bad:
return 0;
}
struct udev* udev_get_library_context(void)
void *udev_get_library_context(void)
{
return _udev;
}
@@ -78,6 +78,11 @@ int udev_init_library_context(void)
return 1;
}
void *udev_get_library_context(void)
{
return NULL;
}
void udev_fin_library_context(void)
{
}

View File

@@ -16,12 +16,8 @@
#ifndef _LVM_WRAPPERS_H
#define _LVM_WRAPPERS_H
#ifdef UDEV_SYNC_SUPPORT
struct udev;
struct udev *udev_get_library_context(void);
#endif
int udev_init_library_context(void);
void *udev_get_library_context(void);
void udev_fin_library_context(void);
int udev_is_running(void);

View File

@@ -3667,7 +3667,6 @@ static const struct dm_report_object_type _report_types[] = {
{ PVS, "Physical Volume", "pv_", _obj_get_pv },
{ LABEL, "Physical Volume Label", "pv_", _obj_get_label },
{ SEGS, "Logical Volume Segment", "seg_", _obj_get_seg },
{ SEGSSTATUS, "Logical Volume Device Segment Status", "seg_", _obj_get_lv_with_info_and_seg_status },
{ PVSEGS, "Physical Volume Segment", "pvseg_", _obj_get_pvseg },
{ 0, "", "", NULL },
};

View File

@@ -28,10 +28,9 @@ typedef enum {
PVS = 16,
VGS = 32,
SEGS = 64,
SEGSSTATUS = 128,
PVSEGS = 256,
LABEL = 512,
DEVTYPES = 1024
PVSEGS = 128,
LABEL = 256,
DEVTYPES = 512
} report_type_t;
/*

View File

@@ -1814,7 +1814,7 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
}
log_debug_activation("dm %s %s%s %s%s%s %s%.0d%s%.0d%s"
"%s%c%c%s%s%s%s%s%s%s %.0" PRIu64 " %s [%u] (*%u)",
"%s[ %s%s%s%s%s%s%s%s%s] %.0" PRIu64 " %s [%u] (*%u)",
_cmd_data_v4[dmt->type].name,
dmt->new_uuid ? "UUID " : "",
dmi->name, dmi->uuid, dmt->newname ? " " : "",
@@ -1825,15 +1825,15 @@ static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
dmt->minor > 0 ? dmt->minor : 0,
dmt->major > 0 && dmt->minor == 0 ? "0" : "",
dmt->major > 0 ? ") " : "",
dmt->no_open_count ? 'N' : 'O',
dmt->no_flush ? 'N' : 'F',
dmt->read_only ? "R" : "",
dmt->skip_lockfs ? "S " : "",
dmt->retry_remove ? "T " : "",
dmt->deferred_remove ? "D " : "",
dmt->secure_data ? "W " : "",
dmt->query_inactive_table ? "I " : "",
dmt->enable_checks ? "C" : "",
dmt->no_open_count ? "noopencount " : "opencount ",
dmt->no_flush ? "noflush " : "flush ",
dmt->read_only ? "readonly " : "",
dmt->skip_lockfs ? "skiplockfs " : "",
dmt->retry_remove ? "retryremove " : "",
dmt->deferred_remove ? "deferredremove " : "",
dmt->secure_data ? "securedata " : "",
dmt->query_inactive_table ? "inactive " : "",
dmt->enable_checks ? "enablechecks " : "",
dmt->sector, _sanitise_message(dmt->message),
dmi->data_size, retry_repeat_count);
#ifdef DM_IOCTLS

View File

@@ -321,8 +321,8 @@ int dm_get_status_mirror(struct dm_pool *mem, const char *params,
/* Parse params from STATUS call for raid target */
struct dm_status_raid {
uint64_t reserved;
uint64_t total_regions;
uint64_t insync_regions;
uint64_t total_regions; /* sectors */
uint64_t insync_regions; /* sectors */
uint64_t mismatch_count;
uint32_t dev_count;
char *raid_type;

View File

@@ -4175,6 +4175,11 @@ static int _sort_rows(struct dm_report *rh)
return 1;
}
#define STANDARD_QUOTE "\'"
#define STANDARD_PAIR "="
#define UNABLE_TO_EXTEND_OUTPUT_LINE_MSG "dm_report: Unable to extend output line"
/*
* Produce report output
*/
@@ -4196,27 +4201,27 @@ static int _output_field(struct dm_report *rh, struct dm_report_field *field)
}
if (!dm_pool_grow_object(rh->mem, rh->output_field_name_prefix, 0)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
dm_free(field_id);
return 0;
}
if (!dm_pool_grow_object(rh->mem, _toupperstr(field_id), 0)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
dm_free(field_id);
return 0;
}
dm_free(field_id);
if (!dm_pool_grow_object(rh->mem, "=", 1)) {
log_error("dm_report: Unable to extend output line");
if (!dm_pool_grow_object(rh->mem, STANDARD_PAIR, 1)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
return 0;
}
if (!(rh->flags & DM_REPORT_OUTPUT_FIELD_UNQUOTED) &&
!dm_pool_grow_object(rh->mem, "\'", 1)) {
log_error("dm_report: Unable to extend output line");
!dm_pool_grow_object(rh->mem, STANDARD_QUOTE, 1)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
return 0;
}
}
@@ -4225,7 +4230,7 @@ static int _output_field(struct dm_report *rh, struct dm_report_field *field)
width = field->props->width;
if (!(rh->flags & DM_REPORT_OUTPUT_ALIGNED)) {
if (!dm_pool_grow_object(rh->mem, repstr, 0)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
return 0;
}
} else {
@@ -4248,7 +4253,7 @@ static int _output_field(struct dm_report *rh, struct dm_report_field *field)
goto bad;
}
if (!dm_pool_grow_object(rh->mem, buf, width)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
}
} else if (align & DM_REPORT_FIELD_ALIGN_RIGHT) {
@@ -4258,7 +4263,7 @@ static int _output_field(struct dm_report *rh, struct dm_report_field *field)
goto bad;
}
if (!dm_pool_grow_object(rh->mem, buf, width)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
}
}
@@ -4266,8 +4271,8 @@ static int _output_field(struct dm_report *rh, struct dm_report_field *field)
if ((rh->flags & DM_REPORT_OUTPUT_FIELD_NAME_PREFIX) &&
!(rh->flags & DM_REPORT_OUTPUT_FIELD_UNQUOTED))
if (!dm_pool_grow_object(rh->mem, "\'", 1)) {
log_error("dm_report: Unable to extend output line");
if (!dm_pool_grow_object(rh->mem, STANDARD_QUOTE, 1)) {
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
}
@@ -4345,7 +4350,7 @@ static int _output_as_rows(struct dm_report *rh)
if (!dm_list_end(&rh->rows, &row->list))
if (!dm_pool_grow_object(rh->mem, rh->separator, 0)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
}
}
@@ -4393,7 +4398,7 @@ static int _output_as_columns(struct dm_report *rh)
if (!dm_list_end(&row->fields, fh))
if (!dm_pool_grow_object(rh->mem, rh->separator, 0)) {
log_error("dm_report: Unable to extend output line");
log_error(UNABLE_TO_EXTEND_OUTPUT_LINE_MSG);
goto bad;
}

View File

@@ -373,7 +373,8 @@ is not used and metadata is read from disks.
.br
Cause the command to access shared VGs, that would otherwise be skipped
when lvmlockd is not being used. It can be used to report or display a
lockd VG without locking.
lockd VG without locking. Applicable only if LVM is compiled with lockd
support.
.
.HP
.BR \-\-addtag

View File

@@ -111,7 +111,8 @@ owned.
.B Shared:
A shared or "lockd" VG has lock_type set and no system_id.
A shared VG is meant to be used on shared storage from multiple hosts,
and is only accessible to hosts using lvmlockd.
and is only accessible to hosts using lvmlockd. Applicable only if LVM
is compiled with lockd support.
.B Clustered:
A clustered or "clvm" VG has the clustered flag set and no system_id.
@@ -308,7 +309,8 @@ extra_system_ids list.
A shared/lockd VG has no system_id set, allowing multiple hosts to
use it via lvmlockd. Changing a VG to a lockd type will clear the
existing system_id.
existing system_id. Applicable only if LVM is compiled with lockd
support.
.SS clustered VGs

View File

@@ -132,8 +132,8 @@ be used on one node at once.
For local VGs, \-ay, \-aey, and \-asy are all equivalent.
.IP
In a shared VG, lvmlockd is used for locking, and the following options
are possible:
In a shared VG, lvmlockd is used for locking if LVM is compiled with lockd
support, and the following options are possible:
With \-aey, the command activates the LV in exclusive mode, allowing a
single host to activate the LV (the host running the command). Before

View File

@@ -130,10 +130,10 @@ The 2.4 kernel has a limitation of 2TiB per block device.
.TP
.B \-\-shared
Create a shared VG using lvmlockd. lvmlockd will select lock type sanlock
or dlm depending on which lock manager is running. This allows multiple
hosts to share a VG on shared devices. lvmlockd and a lock manager must
be configured and running. See
Create a shared VG using lvmlockd if LVM is compiled with lockd support.
lvmlockd will select lock type sanlock or dlm depending on which lock
manager is running. This allows multiple hosts to share a VG on shared
devices. lvmlockd and a lock manager must be configured and running. See
.BR lvmlockd (8).
.TP

View File

@@ -99,8 +99,13 @@ else
dir="$HOME/$dirbase"
fi
test -e $dir && die 3 "Fatal: $dir already exists"
$MKDIR -p $dir || die 4 "Fatal: could not create $dir"
if test -d $dir ; then
(shopt -s nullglob dotglob; test -r $dir -a -w $dir -a -x $dir && cd $dir && files=(*) && ((! ${#files[@]}))) || \
die 5 "Fatal: directory $dir already exists and is not empty or inaccessible"
else
test -e $dir && die 3 "Fatal: $dir already exists"
$MKDIR -p $dir || die 4 "Fatal: could not create $dir"
fi
log="$dir/lvmdump.log"

View File

@@ -201,7 +201,7 @@ LIB_SHARED = check aux inittest utils get lvm-wrapper
install: .tests-stamp lib/paths-installed
@echo $(srcdir)
$(INSTALL_DIR) $(DATADIR)/{shell,api,lib} $(EXECDIR)
$(INSTALL_DIR) $(DATADIR)/{shell,api,lib,dbus} $(EXECDIR)
$(INSTALL_DATA) shell/*.sh $(DATADIR)/shell
$(INSTALL_DATA) api/*.sh $(DATADIR)/api
$(INSTALL_PROGRAM) api/*.{t,py} $(DATADIR)/api

View File

@@ -321,7 +321,7 @@ prepare_lvmdbusd() {
# Setup the python path so we can run
export PYTHONPATH=$abs_top_builddir/daemons
else
daemon="$(which lvmdbusd)"
daemon="$(which lvmdbusd || :)"
fi
[[ -n $daemon && -x $daemon ]] || skip "The daemon is missing"
@@ -431,7 +431,7 @@ teardown_devs() {
test ${#stray_loops[@]} -eq 0 || {
teardown_devs_prefixed "$COMMON_PREFIX" 1
echo "Removing stray loop devices containing $COMMON_PREFIX: ${stray_loops[@]}"
for i in "${stray_loops[@]}" ; do test ! -b $i || losetup -d $i ; done
for i in "${stray_loops[@]}" ; do test ! -b $i || losetup -d $i || true ; done
# Leave test when udev processed all removed devices
udev_wait
}

View File

@@ -48,7 +48,8 @@ get lv_field $vg/corigin kernel_cache_settings | grep 'migration_threshold=333'
lvchange --cachesettings 'migration_threshold = 233 sequential_threshold = 13' $vg/corigin
get lv_field $vg/corigin kernel_cache_settings | tee out
grep 'migration_threshold=233' out
grep 'sequential_threshold=13' out
if grep 'sequential_threshold=13' out ; then
lvchange --cachesettings 'migration_threshold = 17' $vg/corigin
get lv_field $vg/corigin kernel_cache_settings | tee out
@@ -79,4 +80,10 @@ grep 'migration_threshold=2048' out
grep 'sequential_threshold=13' out
grep 'random_threshold=4' out
else
# When MQ is emulated by SMQ policy it does not hold settings.
# So just skip testing of param changes when sequential_threshold=0
grep 'sequential_threshold=0' out
fi
vgremove -f $vg

View File

@@ -25,7 +25,7 @@ which "$FSCK" || skip
#
# Main
#
aux have_cache 1 3 0 || skip
aux have_cache 1 5 0 || skip
aux prepare_vg 4
@@ -101,13 +101,15 @@ sync
# Seriously damage cache metadata
aux error_dev "$dev1" 2054:2
# Here we usually for the 1st. notice needs_check
check lv_attr_bit state $vg/$lv1 "c"
sleep .1
# And now cache is finaly Failed
check lv_attr_bit health $vg/$lv1 "F"
# On fixed kernel we get instant Fail here
get lv_field $vg/$lv1 lv_attr | tee out
grep "Cwi-a-C-F-" out || {
# while on older unfixed we just notice needs_check
grep "Cwi-c-C---" out
sleep .1
# And now cache is finaly Failed
check lv_attr_bit health $vg/$lv1 "F"
}
check lv_field $vg/$lv1 lv_health_status "failed"
aux disable_dev "$dev1"

View File

@@ -0,0 +1,79 @@
#!/bin/sh
# Copyright (C) 2016 Red Hat, Inc. All rights reserved.
#
# This copyrighted material is made available to anyone wishing to use,
# modify, copy, or redistribute it subject to the terms and conditions
# of the GNU General Public License v.2.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
SKIP_WITH_LVMLOCKD=1
SKIP_WITH_LVMPOLLD=1
MKFS=mkfs.ext3
MOUNT_DIR=mnt
. lib/inittest
which "$MKFS" || skp
cleanup_mounted_and_teardown()
{
umount "$MOUNT_DIR" || true
aux teardown
}
aux lvmconf 'allocation/mirror_logs_require_separate_pvs = 1'
aux prepare_vg 5
################### Check lost mirror leg #################
#
# NOTE: using --regionsize 1M has major impact on my box
# on read performance while mirror is synchronized
# with the default 512K - my C2D T61 reads just couple MB/s!
#
lvcreate -aey --type mirror -L10 --regionsize 1M -m1 -n $lv1 $vg "$dev1" "$dev2" "$dev3"
"$MKFS" "$DM_DEV_DIR/$vg/$lv1"
mkdir "$MOUNT_DIR"
aux delay_dev "$dev2" 0 500 $(get first_extent_sector "$dev2"):
aux delay_dev "$dev4" 0 500 $(get first_extent_sector "$dev4"):
#
# Enforce syncronization
# ATM requires unmounted/unused LV??
#
lvchange --yes --resync $vg/$lv1
trap 'cleanup_mounted_and_teardown' EXIT
mount "$DM_DEV_DIR/$vg/$lv1" "$MOUNT_DIR"
# run 'dd' operation during failure of 'mlog/mimage' device
dd if=/dev/zero of=mnt/zero bs=4K count=100 conv=fdatasync 2>err &
PERCENT=$(get lv_field $vg/$lv1 copy_percent)
PERCENT=${PERCENT%%\.*} # cut decimal
# and check less then 50% mirror is in sync (could be unusable delay_dev ?)
test "$PERCENT" -lt 50 || skip
#lvs -a -o+devices $vg
#aux disable_dev "$dev3"
aux disable_dev "$dev2"
lvconvert --yes --repair $vg/$lv1
lvs -a $vg
aux enable_dev "$dev2"
wait
# dd MAY NOT HAVE produced any error message
not grep error err
lvs -a -o+devices $vg
umount "$MOUNT_DIR"
fsck -n "$DM_DEV_DIR/$vg/$lv1"
aux enable_dev "$dev4"
lvremove -ff $vg

View File

@@ -13,6 +13,9 @@ SKIP_WITH_LVMPOLLD=1
. lib/inittest
# We need "dm" directory for dm devices in sysfs.
aux driver_at_least 4 15 || skip
aux prepare_devs 3 8
vgcreate $vg $dev1 $dev2

View File

@@ -152,10 +152,10 @@ progress_t poll_merge_progress(struct cmd_context *cmd,
}
if (parms->progress_display)
log_print_unless_silent("%s: %s: %.1f%%", lv->name, parms->progress_title,
log_print_unless_silent("%s: %s: %.2f%%", lv->name, parms->progress_title,
100.0 - dm_percent_to_float(percent));
else
log_verbose("%s: %s: %.1f%%", lv->name, parms->progress_title,
log_verbose("%s: %s: %.2f%%", lv->name, parms->progress_title,
100.0 - dm_percent_to_float(percent));
if (percent == DM_PERCENT_0)

View File

@@ -368,7 +368,7 @@ static int _update_extents_params(struct volume_group *vg,
&lp->discards, &lp->zero))
return_0;
if (lcp->percent == PERCENT_FREE) {
if (lcp->percent == PERCENT_FREE || lcp->percent == PERCENT_PVS) {
if (lp->extents <= (2 * lp->pool_metadata_extents)) {
log_error("Not enough space for thin pool creation.");
return 0;

View File

@@ -40,10 +40,10 @@ progress_t poll_mirror_progress(struct cmd_context *cmd,
overall_percent = copy_percent(lv);
if (parms->progress_display)
log_print_unless_silent("%s: %s: %.1f%%", name, parms->progress_title,
log_print_unless_silent("%s: %s: %.2f%%", name, parms->progress_title,
dm_percent_to_float(overall_percent));
else
log_verbose("%s: %s: %.1f%%", name, parms->progress_title,
log_verbose("%s: %s: %.2f%%", name, parms->progress_title,
dm_percent_to_float(overall_percent));
if (segment_percent != DM_PERCENT_100)

View File

@@ -409,10 +409,10 @@ static int _get_final_report_type(int args_are_pvs,
*lv_info_needed = (report_type & (LVSINFO | LVSINFOSTATUS)) ? 1 : 0;
/* Do we need to acquire LV device status in addition? */
*lv_segment_status_needed = (report_type & (SEGSSTATUS | LVSSTATUS | LVSINFOSTATUS)) ? 1 : 0;
*lv_segment_status_needed = (report_type & (LVSSTATUS | LVSINFOSTATUS)) ? 1 : 0;
/* Ensure options selected are compatible */
if (report_type & (SEGS | SEGSSTATUS))
if (report_type & SEGS)
report_type |= LVS;
if (report_type & PVSEGS)
report_type |= PVS;
@@ -429,7 +429,7 @@ static int _get_final_report_type(int args_are_pvs,
else if ((report_type & PVS) ||
((report_type & LABEL) && (report_type & VGS)))
report_type = PVS;
else if (report_type & (SEGS | SEGSSTATUS))
else if (report_type & SEGS)
report_type = SEGS;
else if (report_type & (LVS | LVSINFO | LVSSTATUS | LVSINFOSTATUS))
report_type = LVS;
@@ -733,10 +733,10 @@ out:
static int _report(struct cmd_context *cmd, int argc, char **argv,
report_type_t report_type)
{
void *report_handle;
struct processing_handle handle = {0};
void *report_handle = NULL;
struct processing_handle *handle = NULL;
const char *keys = NULL, *options = NULL, *selection = NULL, *separator;
int r = ECMD_PROCESSED;
int r = ECMD_FAILED;
int aligned, buffered, headings, field_prefixes, quoted;
int columns_as_rows;
unsigned args_are_pvs;
@@ -809,13 +809,13 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
break;
default:
log_error(INTERNAL_ERROR "Unknown report type.");
return ECMD_FAILED;
goto out;
}
/* If -o supplied use it, else use default for report_type */
if (arg_count(cmd, options_ARG) &&
((r = _get_report_options(cmd, report_type, &options, &fields_to_compact) != ECMD_PROCESSED)))
return r;
goto_out;
/* -O overrides default sort settings */
keys = arg_str_value(cmd, sort_ARG, keys);
@@ -841,19 +841,24 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
if (arg_count(cmd, select_ARG))
selection = arg_str_value(cmd, select_ARG, NULL);
if (!(handle = init_processing_handle(cmd)))
goto_out;
if (!(report_handle = report_init(cmd, options, keys, &report_type,
separator, aligned, buffered,
headings, field_prefixes, quoted,
columns_as_rows, selection)))
return_ECMD_FAILED;
goto_out;
handle->internal_report_for_select = 0;
handle->include_historical_lvs = cmd->include_historical_lvs;
handle->custom_handle = report_handle;
if (!_get_final_report_type(args_are_pvs,
report_type, &lv_info_needed,
&lv_segment_status_needed,
&report_type)) {
dm_report_free(report_handle);
return ECMD_FAILED;
}
&report_type))
goto_out;
/*
* We lock VG_GLOBAL to enable use of metadata cache.
@@ -864,18 +869,13 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
lock_global = 1;
if (!lock_vol(cmd, VG_GLOBAL, LCK_VG_READ, NULL)) {
log_error("Unable to obtain global lock.");
dm_report_free(report_handle);
return ECMD_FAILED;
goto out;
}
}
handle.internal_report_for_select = 0;
handle.include_historical_lvs = cmd->include_historical_lvs;
handle.custom_handle = report_handle;
switch (report_type) {
case DEVTYPES:
r = _process_each_devtype(cmd, argc, &handle);
r = _process_each_devtype(cmd, argc, handle);
break;
case LVSINFO:
/* fall through */
@@ -884,7 +884,7 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
case LVSINFOSTATUS:
/* fall through */
case LVS:
r = process_each_lv(cmd, argc, argv, 0, &handle,
r = process_each_lv(cmd, argc, argv, 0, handle,
lv_info_needed && !lv_segment_status_needed ? &_lvs_with_info_single :
!lv_info_needed && lv_segment_status_needed ? &_lvs_with_status_single :
lv_info_needed && lv_segment_status_needed ? &_lvs_with_info_and_status_single :
@@ -892,25 +892,23 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
break;
case VGS:
r = process_each_vg(cmd, argc, argv, NULL, 0,
&handle, &_vgs_single);
handle, &_vgs_single);
break;
case LABEL:
r = process_each_label(cmd, argc, argv,
&handle, &_label_single);
handle, &_label_single);
break;
case PVS:
if (args_are_pvs)
r = process_each_pv(cmd, argc, argv, NULL,
arg_is_set(cmd, all_ARG), 0,
&handle, &_pvs_single);
handle, &_pvs_single);
else
r = process_each_vg(cmd, argc, argv, NULL, 0,
&handle, &_pvs_in_vg);
handle, &_pvs_in_vg);
break;
case SEGSSTATUS:
/* fall through */
case SEGS:
r = process_each_lv(cmd, argc, argv, 0, &handle,
r = process_each_lv(cmd, argc, argv, 0, handle,
lv_info_needed && !lv_segment_status_needed ? &_lvsegs_with_info_single :
!lv_info_needed && lv_segment_status_needed ? &_lvsegs_with_status_single :
lv_info_needed && lv_segment_status_needed ? &_lvsegs_with_info_and_status_single :
@@ -920,14 +918,14 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
if (args_are_pvs)
r = process_each_pv(cmd, argc, argv, NULL,
arg_is_set(cmd, all_ARG), 0,
&handle,
handle,
lv_info_needed && !lv_segment_status_needed ? &_pvsegs_with_lv_info_single :
!lv_info_needed && lv_segment_status_needed ? &_pvsegs_with_lv_status_single :
lv_info_needed && lv_segment_status_needed ? &_pvsegs_with_lv_info_and_status_single :
&_pvsegs_single);
else
r = process_each_vg(cmd, argc, argv, NULL, 0,
&handle, &_pvsegs_in_vg);
handle, &_pvsegs_in_vg);
break;
}
@@ -942,11 +940,13 @@ static int _report(struct cmd_context *cmd, int argc, char **argv,
dm_report_output(report_handle);
dm_report_free(report_handle);
if (lock_global)
unlock_vg(cmd, VG_GLOBAL);
out:
if (handle)
destroy_processing_handle(cmd, handle);
if (report_handle)
dm_report_free(report_handle);
return r;
}