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

Compare commits

..

58 Commits

Author SHA1 Message Date
David Teigland
f851d5062a lvresize: add new options and defaults for fs handling
The new option "--fs String" for lvresize/lvreduce/lvextend
controls the handling of file systems before/after resizing
the LV.  --resizefs is the same as --fs resize.

Possible --fs values:

checksize
  Only used when reducing the size, does nothing when exending.
  Check the fs size, and reduce the LV if the fs is not using
  the affected space, i.e. the fs does not need to be shrunk.
  Fail the command without reducing the fs or LV if the fs is
  using the affected space.

resize_remount | resize
  Resize the fs if needed. Mounts or unmounts the fs as
  required (avoids mounting/unmounting when possible.)
  Attempts to restore the original mount state when finished.

resize_keepmount
  Resize the fs if needed, only if it can be done without
  changing the current mount state. Fail the command without
  resizing the fs or LV if an fs resize requires mounting or
  unmounting.

resize_unmount
  Resize the fs if needed, only while unmounted. Unmount the
  fs if needed.  Fail the command without resizing the fs
  or LV if an fs resize is needed that requires the the fs
  to be mounted.

resize_fsadm
  Use the old method of calling fsadm to do handle the fs
  (deprecated).

ignore
  Resize the LV without checking for or handling a file system.

Notes on lvreduce:

When no --fs or --resizefs option is specified:
. lvextend default behavior is fs ignore.
. lvreduce default behavior is fs checksize
  (includes activating the LV.)

With the exception of --fs resize_fsadm|ignore, lvreduce requires
the recent libblkid fields FSLASTBLOCK and FSBLOCKSIZE.
FSLASTBLOCK*FSBLOCKSIZE is the last byte used by the fs on the LV,
which determines if reducing the fs is necessary.
2022-07-29 12:16:35 -05:00
David Teigland
3a1c12046f lvresize: restructure code
Rewrite top level resize function to prepare for adding
new fs resizing.
2022-07-01 13:19:46 -05:00
Tony Asleson
d0f94e763d lvmdbustest: Add test for property "Get"
We typically use "GetAll", so add test for "Get" and check values.
2022-06-30 10:55:16 -05:00
Tony Asleson
01ef2f2525 lvmdbusd: Remove try/except for mkfifo
We should never run into this error condition when using tempfile.mkdtemp.
2022-06-30 10:55:16 -05:00
Tony Asleson
0d957dcacc lvmdusd: Remove non lvm JSON output support 2022-06-30 10:55:16 -05:00
Tony Asleson
73121e3f07 lvmdbustest: Increase number of LVs
As storage is getting faster, we need to create more LVs to pass this test.
2022-06-30 10:55:16 -05:00
Tony Asleson
8fa8dfdb8c lvmdbustest: Correct comment spelling/grammar 2022-06-30 10:55:16 -05:00
Tony Asleson
55059e002a lvmdbustest: Test job remove path when job not complete 2022-06-30 10:55:16 -05:00
Tony Asleson
d393436727 lvmdbusd: Correct grammar in lvm shell proxy comments 2022-06-30 10:55:16 -05:00
Tony Asleson
6914942685 lvmdbusd: Don't require "lvm> " prompt for shell
Depending on how lvm is compiled, it may not present the "lvm> " prompt
when using the lvm shell.  Don't require it to be present.

Addresses: https://bugzilla.redhat.com/show_bug.cgi?id=2090391
2022-06-30 10:55:16 -05:00
Tony Asleson
eee89a941e lvmdbusd: Job prop. Get/GetAll exec. immediately
This allows API user the ability to check on the status of a long running
job without blocking in the request queue.
2022-06-30 10:55:16 -05:00
Tony Asleson
7a2090655d lvmdbusd: Remove the use of sub shell for lvm shell
This reduces the number of processes and improves security.
2022-06-30 10:55:16 -05:00
Tony Asleson
b3d7aff6a3 lvmdbusd: Fix env variable LVM_DBUSD_TEST_MODE
Make it more logical.
2022-06-30 10:55:16 -05:00
Tony Asleson
47c61907b4 lvmdbusd: Change unit test vdo minimum size 2022-06-30 10:55:16 -05:00
Tony Asleson
51d9b686c0 lvmdbusd: Add debug output for which lvm binary is used 2022-06-30 10:55:16 -05:00
Tony Asleson
b3407b16c1 lvmdbusd: re-work lvm shell main
Add an optional single argument "bisect" to use with git bisect for
automation.  Normal case is no arguments when running stand-alone.
2022-06-30 10:55:16 -05:00
Tony Asleson
58c6c9e9aa lvmdbusd: Simplify child process env
We don't need to duplicate the entire env from the parent, supply only what
is needed.
2022-06-30 10:55:16 -05:00
Tony Asleson
37733cd4eb lvmdbusd: Correct conditional for lvm child process running
Poll returns None when process is running, else exit value.  If poll returns
0 we will fail to exit the select loop.
2022-06-30 10:55:16 -05:00
David Teigland
db5277c971 pvdisplay: restore --reportformat option
Fixes commit b8f4ec846 "display: ignore --reportformat"
by restoring the --reportformat option to pvdisplay.
Adding -C to pvdisplay turns the command into a reporting
command (like pvs, vgs, lvs) in which --reportformat can
be useful.
2022-06-24 10:40:54 -05:00
David Teigland
3b0f9cec7e filter-mpath: get wwids from sysfs vpd_pg83
to compare with wwids in /etc/multipath/wwids when
excluding multipath components.  The wwid printed
from the sysfs wwid file may not be the wwid used
in multipath wwids.  Save the wwids found for each
device on dev->wwids to avoid repeating reading
and parsing the sysfs files.
2022-06-08 15:06:01 -05:00
Zdenek Kabelac
2bea95764e tests: skip running tests for non root user
Testing needs 'root' privileges.
Only 'make run-unit-test' can work without them.
2022-06-07 17:14:09 +02:00
Zdenek Kabelac
4a49851207 tests: update for wrapper
Update calling vdo manager since our vdo wrapper has a simple shell
arg parser so it needs args without '='

Also correct using  DM_DEV_DIR for 'pvcreate'
2022-06-07 17:14:09 +02:00
Zdenek Kabelac
2ecfd503ed tests: add lvm_vdo_wrapper
Introduce a replacement vdo manager wrapper for testing.
When using test suite on a system without vdo manager (which has got
deprecated) - we still need its functionality to prepare 'vdo volume'
for testing lvm_import_vdo.

Wrapper currently need 2 binaries from older 'vdo 6.2' package -
to be named:
oldvdoformat - format VDO metadata with older format
oldvdoprepareforlvm - shift vdo metadata by 1MiB
2022-06-07 17:14:08 +02:00
Zdenek Kabelac
1b070f366b vdo: fix conversion of vdo_slab_size_mb
When converting VDO volume, the parameter vdo_slabSize was
incorrectly copied as vdo_blockMapCacheSize, however this parameter
is then no longer used for any table line creation so the wrong
value was only stored in metadata.

Also use just single get_kb_size_with_unit_ and remove it's duplicate
functionality with get_mb_size_with_unit_.

Use $VERB for vdo remove call.
2022-06-07 17:14:08 +02:00
David Teigland
c302903dba filter-mpath: handle other wwid types in blacklist
Fixes commit 494372b4ee
  "filter-mpath: use multipath blacklist"
to handle wwids with initial type digits 1 and 2 used
for t10 and eui ids.  Originally recognized type 3 naa.
2022-06-06 11:39:02 -05:00
David Teigland
bfe072e438 devices file: fail if --devicesfile filename doesn't exist
A typo of the filename after --devicesfile should result in a
command error rather than the command falling back to using no
devices file at all.  Exception is vgcreate|pvcreate which
create a new devices file if the file name doesn't exist.
2022-05-27 14:27:03 -05:00
David Teigland
9dfa6f3879 devices file: move clean up after command is run
devices_file_exit wasn't being called between lvm_shell
commands, so the file lock wouldn't be released.
2022-05-27 12:38:43 -05:00
Marian Csontos
a30013ff4f post-release 2022-05-18 18:18:14 +02:00
Marian Csontos
6d1e894a86 pre-release 2022-05-18 18:17:06 +02:00
Marian Csontos
9aa3ea1c98 make: generate 2022-05-18 18:15:30 +02:00
Peter Rajnoha
7ec0726ce3 toollib: fix segfault when handling selection with historical LVs
When processing historical LVs inside process_each_lv_in_vg for
selection, we need to use dummy "_historical_lv" for select_match_lv.

This is because a historical LV is not an actual LV, but only a tiny
representation with subset of original properties that we recorded
(name, uuid...).

To use the same processing functions we use for full-fledged non-historical
LVs, we need to use the prefilled "_historical_lv" structure which has all
the other missing properties hard-coded.
2022-05-05 11:13:39 +02:00
Zdenek Kabelac
ff6022d400 make: generate 2022-05-03 19:09:52 +02:00
Zdenek Kabelac
5e060b8fa7 vdo: support --vdosettings
Allow to use --vdosettings with lvcreate,lvconvert,lvchange.
Support settings currenly only configurable via lvm.conf.
With lvchange we require inactivate LV for changes to be applied.

Settings block_map_era_length has supported alias block_map_period.
2022-05-03 19:09:52 +02:00
David Teigland
dd28460017 improve description of devices option 2022-05-02 09:47:02 -05:00
David Teigland
494372b4ee filter-mpath: use multipath blacklist
Explicit wwid's from these sections control whether the
same wwid in /etc/multipath/wwids is recognized as a
multipath component.  Other non-wwid keywords are not
used, and may require disabling the use of the multipath
wwids file in lvm.conf.
2022-04-22 16:07:47 -05:00
David Teigland
5c50590b22 tests: devicesfile-edit.sh fix loop file name
don't remove dash from loop file name
2022-04-21 11:31:06 -05:00
David Teigland
bee575d678 devices file: remove extraneous unlock in vgchange -u
vgchange -u exit path was unlocking the devices file in cases
when it wasn't needed, which produced an warning.
2022-04-13 12:19:04 -05:00
David Teigland
d14245c724 lvmlockd: return error from vgcreate init_vg_sanlock
in vgcreate for shared sanlock vg, if sanlock_write_resource
returns an unexpected error, then make init_vg_sanlock fail
which will cause the vgcreate to fail.
2022-04-08 11:34:04 -05:00
David Teigland
99f9bb28c9 filters: remove unused internal filter 2022-04-06 12:51:34 -05:00
David Teigland
6cb0b44cd2 filter: remove unused EAGAIN case and flag
The case of filters returning EAGAIN and using the
FILTER_AFTER_SCAN flag is no longer used.
2022-04-06 12:51:34 -05:00
David Teigland
fb7698b0ce lvmdevices: --deldev using device id
When used with --deviceidtype, --deldev can specify
a device id to remove.
2022-04-06 12:51:34 -05:00
David Teigland
151ce8b276 vgimportdevices: fix incorrect deviceidtype usage
When a VG has PVs with different device id types,
it would try to use the idtype of the previous PV
in the loop.  This would produce an unncessary warning,
or could lead to using the devname idtype when a better
idtype is available.
2022-04-06 12:20:26 -05:00
David Teigland
f840dbb320 pvscan: warn about /dev/sda excluded by devices file
In most installations, /dev/sda* or /dev/vda* should be included
in system.devices because the root, home, etc LVs are usually on
sda or vda.

Add a special case warning when a pvscan autoactivation command
sees that /dev/sda* or /dev/vda* are excluded by system.devices,
either not listed or having a different device id.
2022-04-01 13:38:21 -05:00
David Teigland
8db3b11e4e change messages about filtered devices
Change messages that refer to devices being "excluded by filters"
to say just "excluded".  This will avoid mistaking the word
"filters" with the lvm.conf filter setting.
2022-04-01 13:38:21 -05:00
David Teigland
23a9bd549a lvmdevices update: correct multipath entries
Remove multipath components.
Add multipath devs that have multipath components listed.
2022-04-01 13:38:21 -05:00
David Teigland
6e22be20c6 devices file: warn about missing multipath entry
Warn if a scsi device is listed in the devices file that
is used by a multipath device that is not listed.  This
will happen if a scsi device is listed in the devices
file and then an mpath device is set up to use it.

The way to correct this would be to remove the devices
file entry for the component device and add a new entry
for the multipath device.
2022-04-01 13:38:21 -05:00
Zdenek Kabelac
0937113146 thin: fix message processing on thin-pool extension
When thin-pool had queued some delete message on extension operation
such message has been 'lost' and thin-pool kernel metadata has been
left with a thin volume that no longer existed for lvm2 metadata.
2022-03-30 14:49:04 +02:00
David Teigland
86a0a652a9 fix args entry for nolocking
typo in previous commit
2022-03-25 17:25:29 -05:00
David Teigland
f1578b4a5d Move nolocking warning to man page
It's more logical to warn about --nolocking in the man page
before it's used rather than after it's used and too late.
Also, warnings are usually for things the user may not know.
2022-03-25 15:43:53 -05:00
David Teigland
72f0b637d2 vgchange monitor: don't use udev info
vgchange --monitor y is run during startup when udev is being
initialized and is not yet ready to be used.
2022-03-25 14:13:56 -05:00
David Teigland
c7a5b5cca0 pvscan: don't use udev for external device info
pvscan is used to populate udev info, so it can't expect
to use that udev info.
2022-03-09 11:54:59 -06:00
David Teigland
bef1363c00 writecache: check memory usage
warn if writecache neds > 50% of system memory, and
confirm if writecache needs > 90% of system memory.
2022-03-01 16:29:53 -06:00
David Teigland
cc73d99886 devices: only close PVs on LVs when scan_lvs is enabled
This code is only needed when lvm scans PVs that are stacked on LVs.
2022-03-01 14:11:05 -06:00
David Teigland
7b1a857d5a devices: use dev-cache aliases handling from label scan functions
The label scan functions where doing some device alias validation
which is now better handled by the dev-cache layer, so just use
that.
2022-02-28 17:37:12 -06:00
David Teigland
4eb04c8c05 devices: fix dev_name assumptions
dev_name(dev) returns "[unknown]" if there are no names
on dev->aliases.  It's meant mainly for log messages.

Many places assume a valid path name is returned, and
use it directly.  A caller that wants to use the path
from dev_name() must first check if the dev has any
paths with dm_list_empty(&dev->aliases).
2022-02-24 17:22:04 -06:00
David Teigland
00c3069872 devices: initial use of existing option
Use dev_cache_get_existing() in a few common, high level
locations where it's obvious that only existing dev-cache
entries are wanted.  This can be expanded and used in more
locations (or dev_cache_get can stop creating new entries.)
2022-02-24 17:22:03 -06:00
David Teigland
7e70041e32 devices: drop incorrect paths from aliases list
along with some basic checks for cases when a device
has no aliases.

lvm itself creates many situations where a struct device
has no valid paths, when it activates and opens an LV,
does something with it, e.g. zeroing, and then closes
and deactivates it.  (dev-cache is intended for PVs, and
the use of LVs should be moved out of dev-cache in a
future patch.)
2022-02-24 17:22:03 -06:00
David Teigland
1126be8f8d devices: simplify dev_cache_get_by_devt
remove unused args, and no callers need or want a
repeated dev_cache_scan if there is no dev from the
lookup.
2022-02-24 17:21:58 -06:00
129 changed files with 5602 additions and 1555 deletions

View File

@@ -1 +1 @@
2.03.16(2)-git (2022-02-07)
2.03.17(2)-git (2022-05-18)

View File

@@ -1 +1 @@
1.02.185-git (2022-02-07)
1.02.187-git (2022-05-18)

View File

@@ -1,5 +1,18 @@
Version 2.03.16 -
====================================
Version 2.03.17 -
===============================
Fix vdo_slab_size_mb value for converted VDO volume.
Version 2.03.16 - 18th May 2022
===============================
Fix segfault when handling selection with historical LVs.
Add support --vdosettings with lvcreate, lvconvert, lvchange.
Filtering multipath devices respects blacklist setting from multipath
configuration.
lvmdevices support for removing by device id using --deviceidtype and
--deldev.
Display writecache block size with lvs -o writecache_block_size.
Improve cachesettings description in man lvmcache.
Fix lossing of delete message on thin-pool extension.
Version 2.03.15 - 07th February 2022
====================================

View File

@@ -1,5 +1,8 @@
Version 1.02.185 -
=====================================
Version 1.02.187 -
================================
Version 1.02.185 - 18th May 2022
================================
Version 1.02.183 - 07th February 2022
=====================================

View File

@@ -1713,6 +1713,21 @@ AC_DEFINE_UNQUOTED(FSADM_PATH, ["$FSADM_PATH"], [Path to fsadm binary.])
LVMIMPORTVDO_PATH="$SBINDIR/lvm_import_vdo"
AC_DEFINE_UNQUOTED(LVMIMPORTVDO_PATH, ["$LVMIMPORTVDO_PATH"], [Path to lvm_import_vdo script.])
MOUNT_PATH="/usr/bin/mount"
AC_DEFINE_UNQUOTED(MOUNT_PATH, ["$MOUNT_PATH"], [Path to mount binary.])
UMOUNT_PATH="/usr/bin/umount"
AC_DEFINE_UNQUOTED(UMOUNT_PATH, ["$UMOUNT_PATH"], [Path to umount binary.])
E2FSCK_PATH="$SBINDIR/e2fsck"
AC_DEFINE_UNQUOTED(E2FSCK_PATH, ["$E2FSCK_PATH"], [Path to e2fsck binary.])
RESIZE2FS_PATH="$SBINDIR/resize2fs"
AC_DEFINE_UNQUOTED(RESIZE2FS_PATH, ["$RESIZE2FS_PATH"], [Path to resize2fs binary.])
XFS_GROWFS_PATH="$SBINDIR/xfs_growfs"
AC_DEFINE_UNQUOTED(XFS_GROWFS_PATH, ["$XFS_GROWFS_PATH"], [Path to xfs_growfs binary.])
################################################################################
dnl -- dmeventd pidfile and executable path
if test "$BUILD_DMEVENTD" = yes; then
@@ -1882,6 +1897,11 @@ AC_SUBST(DM_LIB_PATCHLEVEL)
AC_SUBST(ELDFLAGS)
AC_SUBST(FSADM)
AC_SUBST(FSADM_PATH)
AC_SUBST(MOUNT_PATH)
AC_SUBST(UMOUNT_PATH)
AC_SUBST(E2FSCK_PATH)
AC_SUBST(RESIZE2FS_PATH)
AC_SUBST(XFS_GROWFS_PATH)
AC_SUBST(BLKDEACTIVATE)
AC_SUBST(HAVE_LIBDL)
AC_SUBST(HAVE_REALTIME)

View File

@@ -220,38 +220,6 @@ def _dc(cmd, args):
return c
def parse(out):
rc = []
for line in out.split('\n'):
# This line includes separators, so process them
if SEP in line:
elem = line.split(SEP)
cleaned_elem = []
for e in elem:
e = e.strip()
cleaned_elem.append(e)
if len(cleaned_elem) > 1:
rc.append(cleaned_elem)
else:
t = line.strip()
if len(t) > 0:
rc.append(t)
return rc
def parse_column_names(out, column_names):
lines = parse(out)
rc = []
for i in range(0, len(lines)):
d = dict(list(zip(column_names, lines[i])))
rc.append(d)
return rc
def options_to_cli_args(options):
rc = []
for k, v in list(dict(options).items()):
@@ -637,46 +605,6 @@ def lvm_full_report_json():
return None
def pv_retrieve_with_segs(device=None):
d = []
err = ""
out = ""
rc = 0
columns = ['pv_name', 'pv_uuid', 'pv_fmt', 'pv_size', 'pv_free',
'pv_used', 'dev_size', 'pv_mda_size', 'pv_mda_free',
'pv_ba_start', 'pv_ba_size', 'pe_start', 'pv_pe_count',
'pv_pe_alloc_count', 'pv_attr', 'pv_tags', 'vg_name',
'vg_uuid', 'pvseg_start', 'pvseg_size', 'segtype', 'pv_missing']
# Lvm has some issues where it returns failure when querying pvs when other
# operations are in process, see:
# https://bugzilla.redhat.com/show_bug.cgi?id=1274085
for i in range(0, 10):
cmd = _dc('pvs', ['-o', ','.join(columns)])
if device:
cmd.extend(device)
rc, out, err = call(cmd)
if rc == 0:
d = parse_column_names(out, columns)
break
else:
time.sleep(0.2)
log_debug("LVM Bug workaround, retrying pvs command...")
if rc != 0:
msg = "We were unable to get pvs to return without error after " \
"trying 10 times, RC=%d, STDERR=(%s), STDOUT=(%s)" % \
(rc, err, out)
log_error(msg)
raise RuntimeError(msg)
return d
def pv_resize(device, size_bytes, create_options):
cmd = ['pvresize']
@@ -831,53 +759,6 @@ def activate_deactivate(op, name, activate, control_flags, options):
return call(cmd)
def vg_retrieve(vg_specific):
if vg_specific:
assert isinstance(vg_specific, list)
columns = ['vg_name', 'vg_uuid', 'vg_fmt', 'vg_size', 'vg_free',
'vg_sysid', 'vg_extent_size', 'vg_extent_count',
'vg_free_count', 'vg_profile', 'max_lv', 'max_pv',
'pv_count', 'lv_count', 'snap_count', 'vg_seqno',
'vg_mda_count', 'vg_mda_free', 'vg_mda_size',
'vg_mda_used_count', 'vg_attr', 'vg_tags']
cmd = _dc('vgs', ['-o', ','.join(columns)])
if vg_specific:
cmd.extend(vg_specific)
d = []
rc, out, err = call(cmd)
if rc == 0:
d = parse_column_names(out, columns)
return d
def lv_retrieve_with_segments():
columns = ['lv_uuid', 'lv_name', 'lv_path', 'lv_size',
'vg_name', 'pool_lv_uuid', 'pool_lv', 'origin_uuid',
'origin', 'data_percent',
'lv_attr', 'lv_tags', 'vg_uuid', 'lv_active', 'data_lv',
'metadata_lv', 'seg_pe_ranges', 'segtype', 'lv_parent',
'lv_role', 'lv_layout',
'snap_percent', 'metadata_percent', 'copy_percent',
'sync_percent', 'lv_metadata_size', 'move_pv', 'move_pv_uuid']
cmd = _dc('lvs', ['-a', '-o', ','.join(columns)])
rc, out, err = call(cmd)
d = []
if rc == 0:
d = parse_column_names(out, columns)
return d
if __name__ == '__main__':
pv_data = pv_retrieve_with_segs()
for p in pv_data:
print(str(p))
# Leave this for future debug as needed
pass

View File

@@ -226,3 +226,21 @@ class Job(AutomatedProperties):
def Uuid(self):
import uuid
return uuid.uuid1()
# Override the property "getters" implementation for the job interface, so a user can query a job while the queue
# is processing items. Originally all the property get methods were this way, but we changed this in
# e53454d6de07de56736303dd2157c3859f6fa848
# Properties
# noinspection PyUnusedLocal
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='ss', out_signature='v')
def Get(self, interface_name, property_name):
# Note: If we get an exception in this handler we won't know about it,
# only the side effect of no returned value!
return AutomatedProperties._get_prop(self, interface_name, property_name)
@dbus.service.method(dbus_interface=dbus.PROPERTIES_IFACE,
in_signature='s', out_signature='a{sv}')
def GetAll(self, interface_name):
return AutomatedProperties._get_all_prop(self, interface_name)

View File

@@ -19,7 +19,6 @@ import sys
import tempfile
import time
import select
import copy
try:
import simplejson as json
@@ -31,8 +30,6 @@ from lvmdbusd.cfg import LVM_CMD
from lvmdbusd.utils import log_debug, log_error, add_no_notify, make_non_block,\
read_decoded
SHELL_PROMPT = "lvm> "
def _quote_arg(arg):
if len(shlex.split(arg)) > 1:
@@ -43,10 +40,11 @@ def _quote_arg(arg):
class LVMShellProxy(object):
# Read until we get prompt back and a result
# @param: no_output Caller expects no output to report FD
# Returns stdout, report, stderr (report is JSON!)
def _read_until_prompt(self, no_output=False):
# Read REPORT FD until we have a complete and valid JSON record or give
# up trying to get one.
#
# Returns stdout, report (JSON), stderr
def _read_response(self):
stdout = ""
report = ""
stderr = ""
@@ -58,6 +56,7 @@ class LVMShellProxy(object):
# Try reading from all FDs to prevent one from filling up and causing
# a hang. Keep reading until we get the prompt back and the report
# FD does not contain valid JSON
while keep_reading:
try:
rd_fd = [
@@ -75,35 +74,36 @@ class LVMShellProxy(object):
stderr += read_decoded(self.lvm_shell.stderr)
# Check to see if the lvm process died on us
if self.lvm_shell.poll():
if self.lvm_shell.poll() is not None:
raise Exception(self.lvm_shell.returncode, "%s" % stderr)
if stdout.endswith(SHELL_PROMPT):
if no_output:
keep_reading = False
else:
cur_report_len = len(report)
if cur_report_len != 0:
# Only bother to parse if we have more data
if prev_report_len != cur_report_len:
prev_report_len = cur_report_len
# Parse the JSON if it's good we are done,
# if not we will try to read some more.
try:
report_json = json.loads(report)
keep_reading = False
except ValueError:
pass
cur_report_len = len(report)
if cur_report_len != 0:
# Only bother to parse if we have more data and the last 2 characters match expected
# complete JSON, prevents excessive JSON parsing attempts
if prev_report_len != cur_report_len and report[-2:] == "}\n":
prev_report_len = cur_report_len
if keep_reading:
extra_passes -= 1
if extra_passes <= 0:
if len(report):
raise ValueError("Invalid json: %s" %
report)
else:
raise ValueError(
"lvm returned no JSON output!")
# Parse the JSON if it's good we are done,
# if not we will try to read some more.
try:
report_json = json.loads(report)
keep_reading = False
except ValueError:
pass
# As long as lvm is spewing something on one of the FDs we will
# keep trying. If we get a few timeouts with no activity, and
# we don't have valid JSON, we will raise an error.
if len(ready) == 0 and keep_reading:
extra_passes -= 1
if extra_passes <= 0:
if len(report):
raise ValueError("Invalid json: %s" %
report)
else:
raise ValueError(
"lvm returned no JSON output!")
except IOError as ioe:
log_debug(str(ioe))
@@ -118,49 +118,48 @@ class LVMShellProxy(object):
self.lvm_shell.stdin.flush()
def __init__(self):
# Create a temp directory
tmp_dir = tempfile.mkdtemp(prefix="lvmdbus_")
tmp_file = "%s/lvmdbus_report" % (tmp_dir)
try:
# Lets create fifo for the report output
os.mkfifo(tmp_file, 0o600)
except FileExistsError:
pass
# Create a fifo for the report output
os.mkfifo(tmp_file, 0o600)
# We have to open non-blocking as the other side isn't open until
# we actually fork the process.
# Open the fifo for use to read and for lvm child process to write to.
self.report_fd = os.open(tmp_file, os.O_NONBLOCK)
self.report_stream = os.fdopen(self.report_fd, 'rb', 0)
lvm_fd = os.open(tmp_file, os.O_WRONLY)
# Setup the environment for using our own socket for reporting
local_env = copy.deepcopy(os.environ)
local_env["LVM_REPORT_FD"] = "32"
local_env["LVM_COMMAND_PROFILE"] = "lvmdbusd"
# Set up the environment for using our own socket for reporting and disable the abort
# logic if lvm logs too much, which easily happens when utilizing the lvm shell.
local_env = {"LC_ALL": "C", "LVM_REPORT_FD": "%s" % lvm_fd, "LVM_COMMAND_PROFILE": "lvmdbusd",
"LVM_LOG_FILE_MAX_LINES": "0"}
# Disable the abort logic if lvm logs too much, which easily happens
# when utilizing the lvm shell.
local_env["LVM_LOG_FILE_MAX_LINES"] = "0"
# If any env variables contain LVM we will propagate them too
for k, v in os.environ.items():
if "LVM" in k:
local_env[k] = v
# run the lvm shell
self.lvm_shell = subprocess.Popen(
[LVM_CMD + " 32>%s" % tmp_file],
[LVM_CMD],
stdin=subprocess.PIPE, stdout=subprocess.PIPE, env=local_env,
stderr=subprocess.PIPE, close_fds=True, shell=True)
stderr=subprocess.PIPE, close_fds=True, pass_fds=(lvm_fd,), shell=False)
try:
make_non_block(self.lvm_shell.stdout)
make_non_block(self.lvm_shell.stderr)
# wait for the first prompt
errors = self._read_until_prompt(no_output=True)[2]
if errors and len(errors):
raise RuntimeError(errors)
# Close our copy of the lvm_fd, child process is open in its process space
os.close(lvm_fd)
# Assume we are ready as we may not get the lvm prompt message depending on
# if we are using readline or editline.
except:
raise
finally:
# These will get deleted when the FD count goes to zero so we
# These will get deleted when the FD count goes to zero, so we
# can be sure to clean up correctly no matter how we finish
os.unlink(tmp_file)
os.rmdir(tmp_dir)
@@ -170,7 +169,7 @@ class LVMShellProxy(object):
self._write_cmd('lastlog\n')
# read everything from the STDOUT to the next prompt
stdout, report_json, stderr = self._read_until_prompt()
stdout, report_json, stderr = self._read_response()
if 'log' in report_json:
error_msg = ""
# Walk the entire log array and build an error string
@@ -204,7 +203,7 @@ class LVMShellProxy(object):
self._write_cmd(cmd)
# read everything from the STDOUT to the next prompt
stdout, report_json, stderr = self._read_until_prompt()
stdout, report_json, stderr = self._read_response()
# Parse the report to see what happened
if 'log' in report_json:
@@ -237,24 +236,34 @@ class LVMShellProxy(object):
if __name__ == "__main__":
shell = LVMShellProxy()
in_line = "start"
print("USING LVM BINARY: %s " % LVM_CMD)
try:
while in_line:
in_line = input("lvm> ")
if in_line:
start = time.time()
ret, out, err = shell.call_lvm(in_line.split())
end = time.time()
if len(sys.argv) > 1 and sys.argv[1] == "bisect":
shell = LVMShellProxy()
shell.exit_shell()
else:
shell = LVMShellProxy()
in_line = "start"
try:
while in_line:
in_line = input("lvm> ")
if in_line:
start = time.time()
ret, out, err = shell.call_lvm(in_line.split())
end = time.time()
print(("RC: %d" % ret))
print(("OUT:\n%s" % out))
print(("ERR:\n%s" % err))
print(("RC: %d" % ret))
print(("OUT:\n%s" % out))
print(("ERR:\n%s" % err))
print("Command = %f seconds" % (end - start))
except KeyboardInterrupt:
pass
except EOFError:
pass
print("Command = %f seconds" % (end - start))
except KeyboardInterrupt:
pass
except EOFError:
pass
except Exception:
traceback.print_exc(file=sys.stdout)
sys.exit(1)
sys.exit(0)

View File

@@ -13,14 +13,13 @@ from collections import OrderedDict
import pprint as prettyprint
import os
import sys
from lvmdbusd import cmdhandler
from lvmdbusd.utils import log_debug, log_error
class DataStore(object):
def __init__(self, usejson=True, vdo_support=False):
def __init__(self, vdo_support=False):
self.pvs = {}
self.vgs = {}
self.lvs = {}
@@ -35,41 +34,9 @@ class DataStore(object):
self.lvs_in_vgs = {}
self.pvs_in_vgs = {}
# self.refresh()
self.num_refreshes = 0
if usejson:
self.json = cmdhandler.supports_json()
else:
self.json = usejson
self.vdo_support = vdo_support
@staticmethod
def _insert_record(table, key, record, allowed_multiple):
if key in table:
existing = table[key]
for rec_k, rec_v in record.items():
if rec_k in allowed_multiple:
# This column name allows us to store multiple value for
# each type
if not isinstance(existing[rec_k], list):
existing_value = existing[rec_k]
existing[rec_k] = [existing_value, rec_v]
else:
existing[rec_k].append(rec_v)
else:
# If something is not expected to have changing values
# lets ensure that
if existing[rec_k] != rec_v:
raise RuntimeError(
"existing[%s]=%s != %s" %
(rec_k, str(existing[rec_k]),
str(rec_v)))
else:
table[key] = record
@staticmethod
def _pvs_parse_common(c_pvs, c_pvs_in_vgs, c_lookup):
for p in c_pvs.values():
@@ -84,22 +51,6 @@ class DataStore(object):
# Lookup for translating between /dev/<name> and pv uuid
c_lookup[p['pv_name']] = p['pv_uuid']
@staticmethod
def _parse_pvs(_pvs):
pvs = sorted(_pvs, key=lambda pk: pk['pv_name'])
c_pvs = OrderedDict()
c_lookup = {}
c_pvs_in_vgs = {}
for p in pvs:
DataStore._insert_record(
c_pvs, p['pv_uuid'], p,
['pvseg_start', 'pvseg_size', 'segtype'])
DataStore._pvs_parse_common(c_pvs, c_pvs_in_vgs, c_lookup)
return c_pvs, c_lookup, c_pvs_in_vgs
@staticmethod
def _parse_pvs_json(_all):
@@ -141,28 +92,6 @@ class DataStore(object):
return c_pvs, c_lookup, c_pvs_in_vgs
@staticmethod
def _parse_vgs(_vgs):
vgs = sorted(_vgs, key=lambda vk: vk['vg_uuid'])
c_vgs = OrderedDict()
c_lookup = {}
for i in vgs:
vg_name = i['vg_name']
# Lvm allows duplicate vg names. When this occurs, each subsequent
# matching VG name will be called vg_name:vg_uuid. Note: ':' is an
# invalid character for lvm VG names
if vg_name in c_lookup:
vg_name = "%s:%s" % (vg_name, i['vg_uuid'])
i['vg_name'] = vg_name
c_lookup[vg_name] = i['vg_uuid']
DataStore._insert_record(c_vgs, i['vg_uuid'], i, [])
return c_vgs, c_lookup
@staticmethod
def _parse_vgs_json(_all):
@@ -227,22 +156,6 @@ class DataStore(object):
return c_lvs, c_lvs_in_vgs, c_lvs_hidden, c_lv_full_lookup
@staticmethod
def _parse_lvs(_lvs):
lvs = sorted(_lvs, key=lambda vk: vk['lv_name'])
c_lvs = OrderedDict()
c_lv_full_lookup = OrderedDict()
for i in lvs:
full_name = "%s/%s" % (i['vg_name'], i['lv_name'])
c_lv_full_lookup[full_name] = i['lv_uuid']
DataStore._insert_record(
c_lvs, i['lv_uuid'], i,
['seg_pe_ranges', 'segtype'])
return DataStore._parse_lvs_common(c_lvs, c_lv_full_lookup)
def _parse_lvs_json(self, _all):
c_lvs = OrderedDict()
@@ -401,22 +314,12 @@ class DataStore(object):
log_debug("lvmdb - refresh entry")
# Grab everything first then parse it
if self.json:
# Do a single lvm retrieve for everything in json
a = cmdhandler.lvm_full_report_json()
# Do a single lvm retrieve for everything in json
a = cmdhandler.lvm_full_report_json()
_pvs, _pvs_lookup, _pvs_in_vgs = self._parse_pvs_json(a)
_vgs, _vgs_lookup = self._parse_vgs_json(a)
_lvs, _lvs_in_vgs, _lvs_hidden, _lvs_lookup = self._parse_lvs_json(a)
else:
_raw_pvs = cmdhandler.pv_retrieve_with_segs()
_raw_vgs = cmdhandler.vg_retrieve(None)
_raw_lvs = cmdhandler.lv_retrieve_with_segments()
_pvs, _pvs_lookup, _pvs_in_vgs = self._parse_pvs(_raw_pvs)
_vgs, _vgs_lookup = self._parse_vgs(_raw_vgs)
_lvs, _lvs_in_vgs, _lvs_hidden, _lvs_lookup = self._parse_lvs(_raw_lvs)
_pvs, _pvs_lookup, _pvs_in_vgs = self._parse_pvs_json(a)
_vgs, _vgs_lookup = self._parse_vgs_json(a)
_lvs, _lvs_in_vgs, _lvs_hidden, _lvs_lookup = self._parse_lvs_json(a)
# Set all
self.pvs = _pvs
@@ -527,13 +430,7 @@ class DataStore(object):
if __name__ == "__main__":
pp = prettyprint.PrettyPrinter(indent=4)
use_json = False
if len(sys.argv) != 1:
print(len(sys.argv))
use_json = True
ds = DataStore(use_json)
ds = DataStore()
ds.refresh()
print("PVS")

View File

@@ -29,7 +29,7 @@ from .utils import log_debug, log_error
import argparse
import os
import sys
from .cmdhandler import LvmFlightRecorder, supports_vdo
from .cmdhandler import LvmFlightRecorder, supports_vdo, supports_json
from .request import RequestEntry
@@ -116,6 +116,15 @@ def main():
os.environ["LC_ALL"] = "C"
cfg.args = parser.parse_args()
if not cfg.args.use_json:
log_error("Daemon no longer supports lvm without JSON support, exiting!")
sys.exit(1)
else:
if not supports_json():
log_error("Un-supported version of LVM, daemon requires JSON output, exiting!")
sys.exit(1)
cfg.create_request_entry = RequestEntry
# We create a flight recorder in cmdhandler too, but we replace it here
@@ -127,6 +136,8 @@ def main():
log_error("You cannot specify --lvmshell and --nojson")
sys.exit(1)
log_debug("Using lvm binary: %s" % cfg.LVM_CMD)
# We will dynamically add interfaces which support vdo if it
# exists.
cfg.vdo_support = supports_vdo()
@@ -155,7 +166,7 @@ def main():
cfg.om = Lvm(BASE_OBJ_PATH)
cfg.om.register_object(Manager(MANAGER_OBJ_PATH))
cfg.db = lvmdb.DataStore(cfg.args.use_json, cfg.vdo_support)
cfg.db = lvmdb.DataStore(vdo_support=cfg.vdo_support)
# Using a thread to process requests, we cannot hang the dbus library
# thread that is handling the dbus interface

View File

@@ -684,10 +684,10 @@ int lm_init_vg_sanlock(char *ls_name, char *vg_name, uint32_t flags, char *vg_ar
break;
}
if (rv) {
if (rv < 0) {
log_error("clear lv resource area %llu error %d",
(unsigned long long)offset, rv);
break;
return rv;
}
offset += align_size;
}

View File

@@ -77,8 +77,10 @@ enum dm_vdo_write_policy {
struct dm_vdo_target_params {
uint32_t minimum_io_size; // in sectors
uint32_t block_map_cache_size_mb;
uint32_t block_map_era_length; // format period
union {
uint32_t block_map_era_length; // format period
uint32_t block_map_period; // supported alias
};
uint32_t check_point_frequency;
uint32_t index_memory_size_mb; // format

View File

@@ -132,8 +132,13 @@
/* Define to 1 to include the LVM editline shell. */
#undef EDITLINE_SUPPORT
/* Path to fsadm binary. */
/* Paths to binaries. */
#undef FSADM_PATH
#undef MOUNT_PATH
#undef UMOUNT_PATH
#undef E2FSCK_PATH
#undef RESIZE2FS_PATH
#undef XFS_GROWFS_PATH
/* Define to use GNU versioning in the shared library. */
#undef GNU_SYMVER

View File

@@ -40,7 +40,9 @@ SOURCES =\
device/dev-luks.c \
device/dev-dasd.c \
device/dev-lvm1-pool.c \
device/filesystem.c \
device/online.c \
device/parse_vpd.c \
display/display.c \
error/errseg.c \
unknown/unknown.c \
@@ -54,7 +56,6 @@ SOURCES =\
filters/filter-partitioned.c \
filters/filter-type.c \
filters/filter-usable.c \
filters/filter-internal.c \
filters/filter-signature.c \
filters/filter-deviceid.c \
format_text/archive.c \

19
lib/commands/cmd_enum.h Normal file
View File

@@ -0,0 +1,19 @@
#ifndef _CMD_ENUM_H
#define _CMD_ENUM_H
/*
* tools/cmds.h is generated by the Makefile. For each command definition
* in command-lines.in, cmds.h contains:
* cmd(foo_CMD, foo)
*
* This header adds each of the foo_CMD's into an enum, so there's
* a unique integer identifier for each command definition.
*/
enum {
#define cmd(a, b) a ,
#include "../tools/cmds.h"
#undef cmd
};
#endif

View File

@@ -1128,7 +1128,7 @@ static int _init_dev_cache(struct cmd_context *cmd)
return 1;
}
#define MAX_FILTERS 11
#define MAX_FILTERS 10
static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
{
@@ -1143,13 +1143,6 @@ static struct dev_filter *_init_filter_chain(struct cmd_context *cmd)
* Update MAX_FILTERS definition above when adding new filters.
*/
/* internal filter used by command processing. */
if (!(filters[nr_filt] = internal_filter_create())) {
log_error("Failed to create internal device filter");
goto bad;
}
nr_filt++;
/* global regex filter. Optional. */
if ((cn = find_config_tree_node(cmd, devices_global_filter_CFG, NULL))) {
if (!(filters[nr_filt] = regex_filter_create(cn->v, 0, 1))) {
@@ -1912,7 +1905,6 @@ int refresh_toolcontext(struct cmd_context *cmd)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
devices_file_exit(cmd);
if (!dev_cache_exit())
stack;
_destroy_dev_types(cmd);
@@ -2041,7 +2033,6 @@ void destroy_toolcontext(struct cmd_context *cmd)
_destroy_segtypes(&cmd->segtypes);
_destroy_formats(cmd, &cmd->formats);
_destroy_filters(cmd);
devices_file_exit(cmd);
dev_cache_exit();
_destroy_dev_types(cmd);
_destroy_tags(cmd);

View File

@@ -18,6 +18,7 @@
#include "lib/device/dev-cache.h"
#include "lib/device/dev-type.h"
#include "lib/commands/cmd_enum.h"
#include <limits.h>
@@ -94,6 +95,7 @@ struct cmd_context {
const char *name; /* needed before cmd->command is set */
struct command_name *cname;
struct command *command;
int command_enum; /* duplicate from command->command_enum for lib code */
char **argv;
struct arg_values *opt_arg_values;
struct dm_list arg_value_groups;

View File

@@ -80,6 +80,7 @@ static void _dev_init(struct device *dev)
dm_list_init(&dev->aliases);
dm_list_init(&dev->ids);
dm_list_init(&dev->wwids);
}
void dev_destroy_file(struct device *dev)
@@ -383,6 +384,22 @@ out:
return 1;
}
int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen)
{
int ret;
int fd;
fd = open(path, O_RDONLY);
if (fd < 0)
return 0;
ret = read(fd, buf, buf_size);
close(fd);
if (ret <= 0)
return 0;
*retlen = ret;
return 1;
}
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value)
{
FILE *fp;
@@ -1336,6 +1353,7 @@ int dev_cache_exit(void)
dm_hash_iterate(n, _cache.names) {
dev = (struct device *) dm_hash_get_data(_cache.names, n);
free_dids(&dev->ids);
free_wwids(&dev->wwids);
}
}
@@ -1410,7 +1428,7 @@ static void _remove_alias(struct device *dev, const char *name)
* deactivated LV. Those old paths are all invalid and are dropped here.
*/
static void _verify_aliases(struct device *dev)
void dev_cache_verify_aliases(struct device *dev)
{
struct dm_str_list *strl, *strl2;
struct stat st;
@@ -1459,7 +1477,7 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
_remove_alias(dev, name);
/* Remove any other names in dev->aliases that are incorrect. */
_verify_aliases(dev);
dev_cache_verify_aliases(dev);
}
return NULL;
}
@@ -1606,18 +1624,6 @@ static struct device *_dev_cache_get(struct cmd_context *cmd, const char *name,
return dev;
ret = f->passes_filter(cmd, f, dev, NULL);
/*
* This might happen if this function is called before
* filters can do i/o. I don't think this will happen
* any longer and this EAGAIN case can be removed.
*/
if (ret == -EAGAIN) {
log_debug_devs("dev_cache_get filter deferred %s", dev_name(dev));
dev->flags |= DEV_FILTER_AFTER_SCAN;
ret = 1;
}
if (!ret) {
log_debug_devs("dev_cache_get filter excludes %s", dev_name(dev));
return NULL;
@@ -1688,16 +1694,9 @@ struct device *dev_iter_get(struct cmd_context *cmd, struct dev_iter *iter)
f = iter->filter;
if (f && !(d->flags & DEV_REGULAR)) {
if (f && !(d->flags & DEV_REGULAR))
ret = f->passes_filter(cmd, f, d, NULL);
if (ret == -EAGAIN) {
log_debug_devs("get device by iter defer filter %s", dev_name(d));
d->flags |= DEV_FILTER_AFTER_SCAN;
ret = 1;
}
}
if (!f || (d->flags & DEV_REGULAR) || ret)
return d;
}
@@ -1882,6 +1881,15 @@ int setup_devices(struct cmd_context *cmd)
file_exists = devices_file_exists(cmd);
/*
* Fail if user specifies a file name that doesn't exist and
* the command is not creating a new devices file.
*/
if (!file_exists && !cmd->create_edit_devices_file && cmd->devicesfile && strlen(cmd->devicesfile)) {
log_error("Devices file not found: %s", cmd->devices_file_path);
return 0;
}
/*
* Removing the devices file is another way of disabling the use of
* a devices file, unless the command creates the devices file.

View File

@@ -55,6 +55,7 @@ int dev_cache_add_dir(const char *path);
struct device *dev_cache_get(struct cmd_context *cmd, const char *name, struct dev_filter *f);
struct device *dev_cache_get_existing(struct cmd_context *cmd, const char *name, struct dev_filter *f);
struct device *dev_cache_get_by_devt(struct cmd_context *cmd, dev_t devt);
void dev_cache_verify_aliases(struct device *dev);
struct device *dev_hash_get(const char *name);
@@ -73,6 +74,7 @@ void dev_cache_failed_path(struct device *dev, const char *path);
bool dev_cache_has_md_with_end_superblock(struct dev_types *dt);
int get_sysfs_value(const char *path, char *buf, size_t buf_size, int error_if_no_value);
int get_sysfs_binary(const char *path, char *buf, size_t buf_size, int *retlen);
int get_dm_uuid_from_sysfs(char *buf, size_t buf_size, int major, int minor);
int setup_devices_file(struct cmd_context *cmd);

View File

@@ -23,9 +23,6 @@ int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *offset_fo
char buf[LUKS_SIGNATURE_SIZE];
int ret = -1;
if (!scan_bcache)
return -EAGAIN;
if (offset_found)
*offset_found = 0;

View File

@@ -178,12 +178,6 @@ static int _dev_is_md_component_native(struct device *dev, uint64_t *offset_foun
uint64_t size, sb_offset = 0;
int ret;
/* i/o layer has not been set up */
if (!scan_bcache) {
log_error(INTERNAL_ERROR "dev_is_md_component_native requires io layer.");
return -1;
}
if (!dev_get_size(dev, &size)) {
stack;
return -1;

View File

@@ -17,12 +17,14 @@
#include "lib/activate/activate.h"
#include "lib/commands/toolcontext.h"
#include "lib/device/device_id.h"
#include "lib/datastruct/str_list.h"
#ifdef UDEV_SYNC_SUPPORT
#include <libudev.h>
#include "lib/device/dev-ext-udev-constants.h"
#endif
#include <dirent.h>
#include <ctype.h>
#define MPATH_PREFIX "mpath-"
@@ -35,21 +37,175 @@
* If dm-3 is not an mpath device, then the constant "1" is stored in
* the hash table with the key of the dm minor number.
*/
static struct dm_pool *_hash_mem;
static struct dm_pool *_wwid_mem;
static struct dm_hash_table *_minor_hash_tab;
static struct dm_hash_table *_wwid_hash_tab;
static struct dm_list _ignored;
static struct dm_list _ignored_exceptions;
#define MAX_WWID_LINE 512
/*
* do we need to check the multipath.conf blacklist?
*/
static void _read_blacklist_file(const char *path)
{
FILE *fp;
char line[MAX_WWID_LINE];
char wwid[MAX_WWID_LINE];
char *word, *p;
int section_black = 0;
int section_exceptions = 0;
int found_quote;
int found_type;
int i, j;
static void _read_wwid_file(const char *config_wwids_file)
if (!(fp = fopen(path, "r")))
return;
while (fgets(line, sizeof(line), fp)) {
word = NULL;
/* skip initial white space on the line */
for (i = 0; i < MAX_WWID_LINE; i++) {
if ((line[i] == '\n') || (line[i] == '\0'))
break;
if (isspace(line[i]))
continue;
word = &line[i];
break;
}
if (!word || word[0] == '#')
continue;
/* identify the start of the section we want to read */
if (strchr(word, '{')) {
if (!strncmp(word, "blacklist_exceptions", 20))
section_exceptions = 1;
else if (!strncmp(word, "blacklist", 9))
section_black = 1;
continue;
}
/* identify the end of the section we've been reading */
if (strchr(word, '}')) {
section_exceptions = 0;
section_black = 0;
continue;
}
/* skip lines that are not in a section we want */
if (!section_black && !section_exceptions)
continue;
/*
* read a wwid from the blacklist{_exceptions} section.
* does not recognize other non-wwid entries in the
* section, and skips those (should the entire mp
* config filtering be disabled if non-wwids are seen?
*/
if (!(p = strstr(word, "wwid")))
continue;
i += 4; /* skip "wwid" */
/*
* copy wwid value from the line.
* the wwids copied here need to match the
* wwids read from /etc/multipath/wwids,
* which are matched to wwids from sysfs.
*/
memset(wwid, 0, sizeof(wwid));
found_quote = 0;
found_type = 0;
j = 0;
for (; i < MAX_WWID_LINE; i++) {
if ((line[i] == '\n') || (line[i] == '\0'))
break;
if (!j && isspace(line[i]))
continue;
if (isspace(line[i]))
break;
/* quotes around wwid are optional */
if ((line[i] == '"') && !found_quote) {
found_quote = 1;
continue;
}
/* second quote is end of wwid */
if ((line[i] == '"') && found_quote)
break;
/* exclude initial 3/2/1 for naa/eui/t10 */
if (!j && !found_type &&
((line[i] == '3') || (line[i] == '2') || (line[i] == '1'))) {
found_type = 1;
continue;
}
wwid[j] = line[i];
j++;
}
if (j < 8)
continue;
log_debug("multipath wwid %s in %s %s",
wwid, section_exceptions ? "blacklist_exceptions" : "blacklist", path);
if (section_exceptions) {
if (!str_list_add(_wwid_mem, &_ignored_exceptions, dm_pool_strdup(_wwid_mem, wwid)))
stack;
} else {
if (!str_list_add(_wwid_mem, &_ignored, dm_pool_strdup(_wwid_mem, wwid)))
stack;
}
}
if (fclose(fp))
stack;
}
static void _read_wwid_exclusions(void)
{
char path[PATH_MAX] = { 0 };
DIR *dir;
struct dirent *de;
struct dm_str_list *sl, *sl2;
int rem_count = 0;
_read_blacklist_file("/etc/multipath.conf");
if ((dir = opendir("/etc/multipath/conf.d"))) {
while ((de = readdir(dir))) {
if (de->d_name[0] == '.')
continue;
snprintf(path, PATH_MAX-1, "/etc/multipath/conf.d/%s", de->d_name);
_read_blacklist_file(path);
}
closedir(dir);
}
/* for each wwid in ignored_exceptions, remove it from ignored */
dm_list_iterate_items_safe(sl, sl2, &_ignored) {
if (str_list_match_item(&_ignored_exceptions, sl->str))
str_list_del(&_ignored, sl->str);
}
/* for each wwid in ignored, remove it from wwid_hash */
dm_list_iterate_items(sl, &_ignored) {
dm_hash_remove_binary(_wwid_hash_tab, sl->str, strlen(sl->str));
rem_count++;
}
if (rem_count)
log_debug("multipath config ignored %d wwids", rem_count);
}
static void _read_wwid_file(const char *config_wwids_file, int *entries)
{
FILE *fp;
char line[MAX_WWID_LINE];
char *wwid, *p;
char typestr[2] = { 0 };
int count = 0;
if (config_wwids_file[0] != '/') {
@@ -71,8 +227,17 @@ static void _read_wwid_file(const char *config_wwids_file)
if (line[0] == '/')
wwid++;
/* skip the initial '3' */
wwid++;
/*
* the initial character is the id type,
* 1 is t10, 2 is eui, 3 is naa, 8 is scsi name.
* wwids are stored in the hash table without the type charater.
* It seems that sometimes multipath does not include
* the type charater (seen with t10 scsi_debug devs).
*/
typestr[0] = *wwid;
if (typestr[0] == '1' || typestr[0] == '2' || typestr[0] == '3')
wwid++;
if ((p = strchr(wwid, '/')))
*p = '\0';
@@ -85,6 +250,7 @@ static void _read_wwid_file(const char *config_wwids_file)
stack;
log_debug("multipath wwids read %d from %s", count, config_wwids_file);
*entries = count;
}
int dev_mpath_init(const char *config_wwids_file)
@@ -92,6 +258,10 @@ int dev_mpath_init(const char *config_wwids_file)
struct dm_pool *mem;
struct dm_hash_table *minor_tab;
struct dm_hash_table *wwid_tab;
int entries = 0;
dm_list_init(&_ignored);
dm_list_init(&_ignored_exceptions);
if (!(mem = dm_pool_create("mpath", 256))) {
log_error("mpath pool creation failed.");
@@ -104,7 +274,7 @@ int dev_mpath_init(const char *config_wwids_file)
return 0;
}
_hash_mem = mem;
_wwid_mem = mem;
_minor_hash_tab = minor_tab;
/* multipath_wwids_file="" disables the use of the file */
@@ -116,16 +286,24 @@ int dev_mpath_init(const char *config_wwids_file)
if (!(wwid_tab = dm_hash_create(110))) {
log_error("mpath hash table creation failed.");
dm_hash_destroy(_minor_hash_tab);
dm_pool_destroy(_hash_mem);
dm_pool_destroy(_wwid_mem);
_minor_hash_tab = NULL;
_hash_mem = NULL;
_wwid_mem = NULL;
return 0;
}
_wwid_hash_tab = wwid_tab;
if (config_wwids_file)
_read_wwid_file(config_wwids_file);
if (config_wwids_file) {
_read_wwid_file(config_wwids_file, &entries);
_read_wwid_exclusions();
}
if (!entries) {
/* reading dev wwids is skipped with null wwid_hash_tab */
dm_hash_destroy(_wwid_hash_tab);
_wwid_hash_tab = NULL;
}
return 1;
}
@@ -136,12 +314,12 @@ void dev_mpath_exit(void)
dm_hash_destroy(_minor_hash_tab);
if (_wwid_hash_tab)
dm_hash_destroy(_wwid_hash_tab);
if (_hash_mem)
dm_pool_destroy(_hash_mem);
if (_wwid_mem)
dm_pool_destroy(_wwid_mem);
_minor_hash_tab = NULL;
_wwid_hash_tab = NULL;
_hash_mem = NULL;
_wwid_mem = NULL;
}
@@ -272,10 +450,12 @@ static int _dev_is_mpath_component_udev(struct device *dev)
}
#endif
static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev)
/* mpath_devno is major:minor of the dm multipath device currently using the component dev. */
static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device *dev,
int primary_result, dev_t primary_dev, dev_t *mpath_devno)
{
struct dev_types *dt = cmd->dev_types;
const char *part_name;
const char *name; /* e.g. "sda" for "/dev/sda" */
char link_path[PATH_MAX]; /* some obscure, unpredictable sysfs path */
char holders_path[PATH_MAX]; /* e.g. "/sys/block/sda/holders/" */
@@ -289,25 +469,15 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
int dm_dev_major;
int dm_dev_minor;
struct stat info;
dev_t primary_dev;
int is_mpath_component = 0;
/* multipathing is only known to exist for SCSI or NVME devices */
if (!major_is_scsi_device(dt, dev_major) && !dev_is_nvme(dt, dev))
return 0;
switch (dev_get_primary_dev(dt, dev, &primary_dev)) {
switch (primary_result) {
case 2: /* The dev is partition. */
part_name = dev_name(dev); /* name of original dev for log_debug msg */
/* gets "foo" for "/dev/foo" where "/dev/foo" comes from major:minor */
if (!(name = _get_sysfs_name_by_devt(sysfs_dir, primary_dev, link_path, sizeof(link_path))))
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. */
@@ -426,50 +596,194 @@ static int _dev_is_mpath_component_sysfs(struct cmd_context *cmd, struct device
if (closedir(dr))
stack;
if (is_mpath_component)
*mpath_devno = MKDEV(dm_dev_major, dm_dev_minor);
return is_mpath_component;
}
static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev)
static int _read_sys_wwid(struct cmd_context *cmd, struct device *dev,
char *idbuf, int idbufsize)
{
char sysbuf[PATH_MAX] = { 0 };
char idtmp[DEV_WWID_SIZE];
if (!read_sys_block(cmd, dev, "device/wwid", idbuf, idbufsize)) {
/* the wwid file is not under device for nvme devs */
if (!read_sys_block(cmd, dev, "wwid", idbuf, idbufsize))
return 0;
}
if (!idbuf[0])
return 0;
/* in t10 id, replace series of spaces with one _ like multipath */
if (!strncmp(idbuf, "t10.", 4) && strchr(idbuf, ' ')) {
if (idbufsize < DEV_WWID_SIZE)
return 0;
memcpy(idtmp, idbuf, DEV_WWID_SIZE);
memset(idbuf, 0, idbufsize);
format_t10_id((const unsigned char *)idtmp, DEV_WWID_SIZE, (unsigned char *)idbuf, idbufsize);
}
return 1;
}
#define VPD_SIZE 4096
static int _read_sys_vpd_wwids(struct cmd_context *cmd, struct device *dev,
struct dm_list *ids)
{
unsigned char vpd_data[VPD_SIZE] = { 0 };
int vpd_datalen = 0;
if (!read_sys_block_binary(cmd, dev, "device/vpd_pg83", (char *)vpd_data, VPD_SIZE, &vpd_datalen))
return 0;
if (!vpd_datalen)
return 0;
/* adds dev_wwid entry to dev->wwids for each id in vpd data */
parse_vpd_ids(vpd_data, vpd_datalen, ids);
return 1;
}
void free_wwids(struct dm_list *ids)
{
struct dev_wwid *dw, *safe;
dm_list_iterate_items_safe(dw, safe, ids) {
dm_list_del(&dw->list);
free(dw);
}
}
static int _wwid_type_num(char *id)
{
if (!strncmp(id, "naa.", 4))
return 3;
else if (!strncmp(id, "eui.", 4))
return 2;
else if (!strncmp(id, "t10.", 4))
return 1;
else
return -1;
}
/*
* TODO: if each of the different wwid types (naa/eui/t10) were
* represented by different DEV_ID_TYPE_FOO values, and used
* as device_id types, then we could drop struct dev_wwid and
* drop dev->wwids, and just use dev->ids for each of the
* different wwids found in vpd_pg83. This would also require
* the ability to handle both the original method of replacing
* every space in the id string with _ and the new/multipath
* format_t10_id replacing series of spaces with one _.
*/
struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids)
{
struct dev_wwid *dw;
int len;
if (!id_type) {
id_type = _wwid_type_num(id);
if (id_type == -1)
log_debug("unknown wwid type %s", id);
}
if (!(dw = zalloc(sizeof(struct dev_wwid))))
return NULL;
len = strlen(id);
if (len >= DEV_WWID_SIZE)
len = DEV_WWID_SIZE - 1;
memcpy(dw->id, id, len);
dw->type = id_type;
dm_list_add(ids, &dw->list);
return dw;
}
/*
* we save ids with format: naa.<value>, eui.<value>, t10.<value>.
* multipath wwids file uses format: 3<value>, 2<value>, 1<value>.
* The values are saved in wwid_hash_tab without the type prefix.
*/
static int _dev_in_wwid_file(struct cmd_context *cmd, struct device *dev,
int primary_result, dev_t primary_dev)
{
char idbuf[DEV_WWID_SIZE] = { 0 };
struct dev_wwid *dw;
char *wwid;
long look;
if (!_wwid_hash_tab)
return 0;
if (!read_sys_block(cmd, dev, "device/wwid", sysbuf, sizeof(sysbuf)))
return 0;
if (!sysbuf[0])
return 0;
/*
* Check the primary device, not the partition.
*/
if (primary_result == 2) {
if (!(dev = dev_cache_get_by_devt(cmd, primary_dev))) {
log_debug("dev_is_mpath_component %s no primary dev", dev_name(dev));
return 0;
}
}
/*
* sysfs prints wwid as <typestr>.<value>
* multipath wwid uses '3'<value>
* does "<typestr>." always correspond to "3"?
* This function may be called multiple times for the same device, in
* particular if partitioned for each partition.
*/
if (!(wwid = strchr(sysbuf, '.')))
return 0;
if (!dm_list_empty(&dev->wwids))
goto lookup;
/* skip the type and dot, just as '3' was skipped from wwids entry */
wwid++;
look = (long) dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid));
/*
* Get all the ids for the device from vpd_pg83 and check if any of
* those are in /etc/multipath/wwids. These ids should include the
* value printed from the sysfs wwid file.
*/
_read_sys_vpd_wwids(cmd, dev, &dev->wwids);
if (!dm_list_empty(&dev->wwids))
goto lookup;
if (look) {
log_debug_devs("dev_is_mpath_component %s multipath wwid %s", dev_name(dev), wwid);
return 1;
/*
* This will read the sysfs wwid file, nvme devices in particular have
* a wwid file but not a vpd_pg83 file.
*/
if (_read_sys_wwid(cmd, dev, idbuf, sizeof(idbuf)))
add_wwid(idbuf, 0, &dev->wwids);
lookup:
dm_list_iterate_items(dw, &dev->wwids) {
if (dw->type == 1 || dw->type == 2 || dw->type == 3)
wwid = &dw->id[4];
else
wwid = dw->id;
if (dm_hash_lookup_binary(_wwid_hash_tab, wwid, strlen(wwid))) {
log_debug_devs("dev_is_mpath_component %s %s in wwids file", dev_name(dev), dw->id);
return 1;
}
}
return 0;
}
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *holder_devno)
{
if (_dev_is_mpath_component_sysfs(cmd, dev) == 1)
struct dev_types *dt = cmd->dev_types;
int primary_result;
dev_t primary_dev;
/*
* multipath only uses SCSI or NVME devices
*/
if (!major_is_scsi_device(dt, MAJOR(dev->dev)) && !dev_is_nvme(dt, dev))
return 0;
/*
* primary_result 2: dev is a partition, primary_dev is the whole device
* primary_result 1: dev is a whole device
*/
primary_result = dev_get_primary_dev(dt, dev, &primary_dev);
if (_dev_is_mpath_component_sysfs(cmd, dev, primary_result, primary_dev, holder_devno) == 1)
goto found;
if (_dev_in_wwid_file(cmd, dev))
if (_dev_in_wwid_file(cmd, dev, primary_result, primary_dev))
goto found;
if (external_device_info_source() == DEV_EXT_UDEV) {
@@ -477,6 +791,12 @@ int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev)
goto found;
}
/*
* TODO: save the result of this function in dev->flags and use those
* flags on repeated calls to avoid repeating the work multiple times
* for the same device when there are partitions on the device.
*/
return 0;
found:
return 1;

View File

@@ -42,9 +42,6 @@ int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *offset_fo
unsigned page;
int ret = 0;
if (!scan_bcache)
return -EAGAIN;
if (!dev_get_size(dev, &size)) {
stack;
return -1;

View File

@@ -674,11 +674,6 @@ static int _dev_is_partitioned_native(struct dev_types *dt, struct device *dev)
{
int r;
if (!scan_bcache) {
log_error(INTERNAL_ERROR "dev_is_partitioned_native requires i/o.");
return -1;
}
/* Unpartitioned DASD devices are not supported. */
if ((MAJOR(dev->dev) == dt->dasd_major) && dasd_is_cdl_formatted(dev))
return 1;
@@ -843,6 +838,86 @@ int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
return 0;
}
}
int fs_get_blkid(const char *pathname, struct fs_info *fsi)
{
blkid_probe probe = NULL;
const char *str;
size_t len;
uint64_t fslastblock = 0;
unsigned int fsblocksize = 0;
int no_block_size = 0, no_fslastblock = 0, no_fsblocksize = 0;
int rc;
if (!(probe = blkid_new_probe_from_filename(pathname))) {
log_error("Failed libblkid probe setup for %s", pathname);
return 0;
}
blkid_probe_enable_superblocks(probe, 1);
blkid_probe_set_superblocks_flags(probe,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_LABELRAW |
BLKID_SUBLKS_UUID | BLKID_SUBLKS_UUIDRAW |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
BLKID_SUBLKS_USAGE | BLKID_SUBLKS_VERSION |
BLKID_SUBLKS_MAGIC | BLKID_SUBLKS_FSINFO);
rc = blkid_do_safeprobe(probe);
if (rc < 0) {
log_error("Failed libblkid probe for %s", pathname);
blkid_free_probe(probe);
return 0;
} else if (rc == 1) {
/* no file system on the device */
log_print("No file system found on %s.", pathname);
fsi->nofs = 1;
blkid_free_probe(probe);
return 1;
}
if (!blkid_probe_lookup_value(probe, "TYPE", &str, &len) && len)
strncpy(fsi->fstype, str, sizeof(fsi->fstype)-1);
else {
/* any difference from blkid_do_safeprobe rc=1? */
log_print("No file system type on %s.", pathname);
fsi->nofs = 1;
blkid_free_probe(probe);
return 1;
}
if (!blkid_probe_lookup_value(probe, "BLOCK_SIZE", &str, &len) && len)
fsi->block_size_bytes = atoi(str);
else
no_block_size = 1;
if (!blkid_probe_lookup_value(probe, "FSLASTBLOCK", &str, &len) && len)
fslastblock = strtoull(str, NULL, 0);
else
no_fslastblock = 1;
if (!blkid_probe_lookup_value(probe, "FSBLOCKSIZE", &str, &len) && len)
fsblocksize = (unsigned int)atoi(str);
else
no_fsblocksize = 1;
blkid_free_probe(probe);
if (no_block_size || no_fslastblock || no_fsblocksize) {
log_print("Missing libblkid %s%s%sfor %s",
no_block_size ? "BLOCK_SIZE " : "",
no_fslastblock ? "FSLASTBLOCK " : "",
no_fsblocksize ? "FSBLOCKSIZE " : "",
pathname);
}
if (fslastblock && fsblocksize)
fsi->fs_last_byte = fslastblock * fsblocksize;
log_debug("libblkid TYPE %s BLOCK_SIZE %d FSLASTBLOCK %llu FSBLOCKSIZE %u fs_last_byte %llu",
fsi->fstype, fsi->block_size_bytes, (unsigned long long)fslastblock, fsblocksize,
(unsigned long long)fsi->fs_last_byte);
return 1;
}
#else
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
{
@@ -850,6 +925,11 @@ int get_fs_block_size(const char *pathname, uint32_t *fs_block_size)
*fs_block_size = 0;
return 0;
}
int fs_get_blkid(const char *pathname, struct fs_info *fsi)
{
log_debug("Disabled blkid for fs info.");
return 0;
}
#endif
#ifdef BLKID_WIPING_SUPPORT

View File

@@ -18,6 +18,7 @@
#include "lib/device/device.h"
#include "lib/display/display.h"
#include "lib/label/label.h"
#include "lib/device/filesystem.h"
#define NUMBER_OF_MAJORS 4096
@@ -58,7 +59,7 @@ int major_is_scsi_device(struct dev_types *dt, int major);
/* Signature/superblock recognition with position returned where found. */
int dev_is_md_component(struct cmd_context *cmd, struct device *dev, uint64_t *sb, int full);
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev);
int dev_is_mpath_component(struct cmd_context *cmd, struct device *dev, dev_t *mpath_devno);
int dev_is_swap(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full);
int dev_is_luks(struct cmd_context *cmd, struct device *dev, uint64_t *signature, int full);
int dasd_is_cdl_formatted(struct device *dev);
@@ -102,6 +103,7 @@ int dev_is_nvme(struct dev_types *dt, struct device *dev);
int dev_is_lv(struct device *dev);
int get_fs_block_size(const char *pathname, uint32_t *fs_block_size);
int fs_get_blkid(const char *pathname, struct fs_info *fsi);
int dev_is_used_by_active_lv(struct cmd_context *cmd, struct device *dev, int *used_by_lv_count,
char **used_by_dm_name, char **used_by_vg_uuid, char **used_by_lv_uuid);

View File

@@ -32,8 +32,8 @@
#define DEV_NOT_O_NOATIME 0x00000400 /* Don't use O_NOATIME */
#define DEV_IN_BCACHE 0x00000800 /* dev fd is open and used in bcache */
#define DEV_BCACHE_EXCL 0x00001000 /* bcache_fd should be open EXCL */
#define DEV_FILTER_AFTER_SCAN 0x00002000 /* apply filter after bcache has data */
#define DEV_FILTER_OUT_SCAN 0x00004000 /* filtered out during label scan */
/* unused 0x00002000 */
/* unused 0x00004000 */
#define DEV_BCACHE_WRITE 0x00008000 /* bcache_fd is open with RDWR */
#define DEV_SCAN_FOUND_LABEL 0x00010000 /* label scan read dev and found label */
#define DEV_IS_MD_COMPONENT 0x00020000 /* device is an md component */
@@ -59,6 +59,14 @@ struct dev_ext {
void *handle;
};
#define DEV_WWID_SIZE 128
struct dev_wwid {
struct dm_list list;
int type;
char id[DEV_WWID_SIZE];
};
#define DEV_ID_TYPE_SYS_WWID 0x0001
#define DEV_ID_TYPE_SYS_SERIAL 0x0002
#define DEV_ID_TYPE_MPATH_UUID 0x0003
@@ -105,6 +113,7 @@ struct dev_use {
*/
struct device {
struct dm_list aliases; /* struct dm_str_list */
struct dm_list wwids; /* struct dev_wwid, used for multipath component detection */
struct dm_list ids; /* struct dev_id, different entries for different idtypes */
struct dev_id *id; /* points to the the ids entry being used for this dev */
dev_t dev;
@@ -206,5 +215,9 @@ void dev_destroy_file(struct device *dev);
int dev_mpath_init(const char *config_wwids_file);
void dev_mpath_exit(void);
struct dev_wwid *add_wwid(char *id, int id_type, struct dm_list *ids);
void free_wwids(struct dm_list *ids);
int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids);
int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes);
#endif

View File

@@ -182,7 +182,9 @@ void free_dids(struct dm_list *ids)
}
}
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize)
static int _read_sys_block(struct cmd_context *cmd, struct device *dev,
const char *suffix, char *sysbuf, int sysbufsize,
int binary, int *retlen)
{
char path[PATH_MAX];
dev_t devt = dev->dev;
@@ -196,11 +198,17 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
return 0;
}
get_sysfs_value(path, sysbuf, sysbufsize, 0);
if (binary) {
ret = get_sysfs_binary(path, sysbuf, sysbufsize, retlen);
if (ret && !*retlen)
ret = 0;
} else {
ret = get_sysfs_value(path, sysbuf, sysbufsize, 0);
if (ret && !sysbuf[0])
ret = 0;
}
if (sysbuf[0]) {
if (prim)
log_debug("Using primary device_id for partition %s.", dev_name(dev));
if (ret) {
sysbuf[sysbufsize - 1] = '\0';
return 1;
}
@@ -220,6 +228,19 @@ int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suff
return 0;
}
int read_sys_block(struct cmd_context *cmd, struct device *dev,
const char *suffix, char *sysbuf, int sysbufsize)
{
return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 0, NULL);
}
int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
const char *suffix, char *sysbuf, int sysbufsize,
int *retlen)
{
return _read_sys_block(cmd, dev, suffix, sysbuf, sysbufsize, 1, retlen);
}
static int _dm_uuid_has_prefix(char *sysbuf, const char *prefix)
{
if (!strncmp(sysbuf, prefix, strlen(prefix)))
@@ -887,6 +908,17 @@ static int _device_ids_use_lvmlv(struct cmd_context *cmd)
return 0;
}
struct dev_use *get_du_for_devno(struct cmd_context *cmd, dev_t devno)
{
struct dev_use *du;
dm_list_iterate_items(du, &cmd->use_devices) {
if (du->dev && du->dev->dev == devno)
return du;
}
return NULL;
}
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev)
{
struct dev_use *du;
@@ -924,7 +956,7 @@ struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname)
return NULL;
}
static struct dev_use *_get_du_for_device_id(struct cmd_context *cmd, uint16_t idtype, const char *idname)
struct dev_use *get_du_for_device_id(struct cmd_context *cmd, uint16_t idtype, const char *idname)
{
struct dev_use *du;
@@ -1117,7 +1149,7 @@ id_done:
du_devname = get_du_for_devname(cmd, dev_name(dev));
/* Is there already an entry using the device_id for this device? */
du_devid = _get_du_for_device_id(cmd, id->idtype, id->idname);
du_devid = get_du_for_device_id(cmd, id->idtype, id->idname);
if (du_dev)
log_debug("device_id_add %s pvid %s matches entry %p dev %s",
@@ -1287,15 +1319,15 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
int update = 0;
if (!cmd->enable_devices_file)
goto out;
return;
/* Without this setting there is no stacking LVs on PVs. */
if (!cmd->scan_lvs)
goto out;
return;
/* Check if any devices file entries are stacked on LVs. */
if (!_device_ids_use_lvmlv(cmd))
goto out;
return;
memcpy(old_vgid, old_vg_id, ID_LEN);
memcpy(new_vgid, &vg->id, ID_LEN);
@@ -1311,7 +1343,7 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
memcpy(old_idname+4, old_vgid, ID_LEN);
memcpy(old_idname+4+ID_LEN, &lvl->lv->lvid.id[1], ID_LEN);
if ((du = _get_du_for_device_id(cmd, DEV_ID_TYPE_LVMLV_UUID, old_idname))) {
if ((du = get_du_for_device_id(cmd, DEV_ID_TYPE_LVMLV_UUID, old_idname))) {
log_debug("device_id update %s pvid %s vgid %s to %s",
du->devname ?: ".", du->pvid ?: ".", old_vgid, new_vgid);
memcpy(du->idname+4, new_vgid, ID_LEN);
@@ -1325,7 +1357,6 @@ void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg,
if (update &&
!device_ids_write(cmd))
stack;
out:
unlock_devices_file(cmd);
}
@@ -1766,7 +1797,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
* probably wants to do something about it.
*/
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
log_warn("Devices file %s is excluded by filter: %s.",
log_warn("Devices file %s is excluded: %s.",
dev_name(dev), dev_filtered_reason(dev));
continue;
}
@@ -1852,7 +1883,7 @@ void device_ids_validate(struct cmd_context *cmd, struct dm_list *scanned_devs,
continue;
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, "persistent")) {
log_warn("Devices file %s is excluded by filter: %s.",
log_warn("Devices file %s is excluded: %s.",
dev_name(dev), dev_filtered_reason(dev));
/* FIXME: what if this dev is wrongly matched and should be checked below? */
continue;
@@ -2294,7 +2325,7 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
if (!cmd->filter->passes_filter(cmd, cmd->filter, dev, NULL)) {
/* I don't think this would happen */
log_warn("WARNING: new device %s for PVID %s does not pass filter %s.",
log_warn("WARNING: new device %s for PVID %s is excluded: %s.",
dev_name(dev), dil->pvid, dev_filtered_reason(dev));
if (du) /* Should not happen 'du' is NULL */
du->dev = NULL;

View File

@@ -39,9 +39,11 @@ void device_ids_find_renamed_devs(struct cmd_context *cmd, struct dm_list *dev_l
const char *device_id_system_read(struct cmd_context *cmd, struct device *dev, uint16_t idtype);
void device_id_update_vg_uuid(struct cmd_context *cmd, struct volume_group *vg, struct id *old_vg_id);
struct dev_use *get_du_for_devno(struct cmd_context *cmd, dev_t devno);
struct dev_use *get_du_for_dev(struct cmd_context *cmd, struct device *dev);
struct dev_use *get_du_for_pvid(struct cmd_context *cmd, const char *pvid);
struct dev_use *get_du_for_devname(struct cmd_context *cmd, const char *devname);
struct dev_use *get_du_for_device_id(struct cmd_context *cmd, uint16_t idtype, const char *idname);
char *devices_file_version(void);
int devices_file_exists(struct cmd_context *cmd);
@@ -56,6 +58,8 @@ void devices_file_exit(struct cmd_context *cmd);
void unlink_searched_devnames(struct cmd_context *cmd);
int read_sys_block(struct cmd_context *cmd, struct device *dev, const char *suffix, char *sysbuf, int sysbufsize);
int read_sys_block_binary(struct cmd_context *cmd, struct device *dev,
const char *suffix, char *sysbuf, int sysbufsize, int *retlen);
int dev_has_mpath_uuid(struct cmd_context *cmd, struct device *dev, const char **idname_out);

284
lib/device/filesystem.c Normal file
View File

@@ -0,0 +1,284 @@
/*
* Copyright (C) 2022 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/commands/toolcontext.h"
#include "lib/device/device.h"
#include "lib/device/dev-type.h"
#include "lib/misc/lvm-exec.h"
#include <mntent.h>
static int _get_lv_path(struct logical_volume *lv, char *lv_path)
{
if (dm_snprintf(lv_path, PATH_MAX, "%s%s/%s", lv->vg->cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Couldn't create LV path for %s.", display_lvname(lv));
return 0;
}
return 1;
}
int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
struct fs_info *fsi, int include_mount)
{
char lv_path[PATH_MAX];
FILE *fme = NULL;
struct stat stlv;
struct stat stme;
struct mntent *me;
int ret;
if (!_get_lv_path(lv, lv_path))
return_0;
if (!fs_get_blkid(lv_path, fsi)) {
log_error("Missing libblkid file system info for %s", display_lvname(lv));
return 0;
}
if (fsi->nofs)
return 1;
if (!include_mount)
return 1;
if (stat(lv_path, &stlv) < 0)
return_0;
if (!(fme = setmntent("/etc/mtab", "r")))
return_0;
ret = 1;
while ((me = getmntent(fme))) {
if (strcmp(me->mnt_type, fsi->fstype))
continue;
if (me->mnt_dir[0] != '/')
continue;
if (me->mnt_fsname[0] != '/')
continue;
if (stat(me->mnt_dir, &stme) < 0)
continue;
if (stme.st_dev != stlv.st_rdev)
continue;
log_debug("fs_get_info %s is mounted \"%s\"", lv_path, me->mnt_dir);
fsi->mounted = 1;
strncpy(fsi->mount_dir, me->mnt_dir, PATH_MAX-1);
}
endmntent(fme);
fsi->unmounted = !fsi->mounted;
return ret;
}
#define FS_CMD_MAX_ARGS 6
int fs_fsck_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
{
char lv_path[PATH_MAX];
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
if (strncmp(fsi->fstype, "ext", 3)) {
log_error("fsck not supported for %s.", fsi->fstype);
return_0;
}
if (!_get_lv_path(lv, lv_path))
return_0;
/*
* ext234: e2fsck -f -p path
* TODO: replace -p with -y based on yes_ARG, or other?
*/
argv[0] = E2FSCK_PATH; /* defined by configure */
argv[++args] = "-f";
argv[++args] = "-p";
argv[++args] = lv_path;
argv[++args] = NULL;
log_print("Checking file system %s with %s on %s...",
fsi->fstype, E2FSCK_PATH, display_lvname(lv));
if (!exec_cmd(cmd, argv, &status, 1)) {
log_error("e2fsck failed on %s.", display_lvname(lv));
return 0;
}
log_print("Checked file system %s on %s.", fsi->fstype, display_lvname(lv));
return 1;
}
int fs_reduce_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
uint64_t newsize_bytes)
{
char lv_path[PATH_MAX];
char newsize_kb_str[16] = { 0 };
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
if (!_get_lv_path(lv, lv_path))
return_0;
if (!strncmp(fsi->fstype, "ext", 3)) {
if (dm_snprintf(newsize_kb_str, 16, "%lluk", (unsigned long long)(newsize_bytes/1024)) < 0)
return_0;
/*
* ext234 shrink: resize2fs path newsize
*/
argv[0] = RESIZE2FS_PATH; /* defined by configure */
argv[++args] = lv_path;
argv[++args] = newsize_kb_str;
argv[++args] = NULL;
} else {
log_error("fs reduce not supported for %s.", fsi->fstype);
return_0;
}
log_print("Reducing file system %s on %s...", fsi->fstype, display_lvname(lv));
if (!exec_cmd(cmd, argv, &status, 1)) {
log_error("Failed to reduce %s file system on %s.", fsi->fstype, display_lvname(lv));
return 0;
}
log_print("Reduced file system %s to %s (%llu bytes) on %s.",
fsi->fstype, display_size(cmd, newsize_bytes/512),
(unsigned long long)newsize_bytes, display_lvname(lv));
return 1;
}
int fs_extend_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
{
char lv_path[PATH_MAX];
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
if (!_get_lv_path(lv, lv_path))
return_0;
if (!strncmp(fsi->fstype, "ext", 3)) {
/* TODO: include -f if lvm command inclues -f ? */
argv[0] = RESIZE2FS_PATH; /* defined by configure */
argv[++args] = lv_path;
argv[++args] = NULL;
} else if (!strcmp(fsi->fstype, "xfs")) {
argv[0] = XFS_GROWFS_PATH; /* defined by configure */
argv[++args] = lv_path;
argv[++args] = NULL;
} else {
log_error("Extend not supported for %s file system.", fsi->fstype);
return_0;
}
log_print("Extending file system %s on %s...", fsi->fstype, display_lvname(lv));
if (!exec_cmd(cmd, argv, &status, 1)) {
log_error("Failed to extend %s file system on %s.", fsi->fstype, display_lvname(lv));
return 0;
}
log_print("Extended file system %s on %s.", fsi->fstype, display_lvname(lv));
return 1;
}
int fs_mount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
int reuse_mount_dir)
{
char lv_path[PATH_MAX];
char mountdir[PATH_MAX];
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
if (!_get_lv_path(lv, lv_path))
return_0;
if (reuse_mount_dir) {
if (!fsi->mount_dir[0]) {
log_error("Cannot remount fs without previous mount dir.");
return 0;
}
memcpy(mountdir, fsi->mount_dir, PATH_MAX);
} else {
if (dm_snprintf(mountdir, sizeof(mountdir), "/tmp/%s_XXXXXX", cmd->name) < 0)
return_0;
if (!mkdtemp(mountdir)) {
log_error("Failed to create temp dir for mount: %s", strerror(errno));
return 0;
}
memcpy(fsi->mount_dir, mountdir, PATH_MAX);
fsi->temp_mount_dir = 1;
}
argv[0] = MOUNT_PATH; /* defined by configure */
argv[++args] = lv_path;
argv[++args] = mountdir;
argv[++args] = NULL;
log_print("Mounting %s.", display_lvname(lv));
if (!exec_cmd(cmd, argv, &status, 1)) {
log_error("Failed to mount file system on %s at %s.", display_lvname(lv), mountdir);
return 0;
}
log_print("Mounted %s at %s dir %s.", display_lvname(lv),
reuse_mount_dir ? "original" : "temporary", mountdir);
return 1;
}
int fs_unmount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi)
{
char lv_path[PATH_MAX];
const char *argv[FS_CMD_MAX_ARGS + 4];
int args = 0;
int status;
if (!_get_lv_path(lv, lv_path))
return_0;
argv[0] = UMOUNT_PATH; /* defined by configure */
argv[++args] = lv_path;
argv[++args] = NULL;
log_print("Unmounting %s.", display_lvname(lv));
if (!exec_cmd(cmd, argv, &status, 1)) {
log_error("Failed to unmount file system on %s.", display_lvname(lv));
return 0;
}
log_print("Unmounted %s.", display_lvname(lv));
if (fsi->temp_mount_dir) {
if (rmdir(fsi->mount_dir) < 0)
log_print("Error removing temp dir %s", fsi->mount_dir);
fsi->mount_dir[0] = '\0';
fsi->temp_mount_dir = 0;
}
return 1;
}

46
lib/device/filesystem.h Normal file
View File

@@ -0,0 +1,46 @@
/*
* Copyright (C) 2022 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef _FILESYSTEM_H
#define _FILESYSTEM_H
struct fs_info {
char fstype[16];
char mount_dir[PATH_MAX];
unsigned int block_size_bytes; /* 512 or 4k */
uint64_t fs_last_byte; /* last byte on the device used by the fs */
unsigned nofs:1;
unsigned unmounted:1;
unsigned mounted:1;
unsigned temp_mount_dir:1;
/* for resizing */
unsigned needs_reduce:1;
unsigned needs_extend:1;
unsigned needs_fsck:1;
unsigned needs_unmount:1;
unsigned needs_mount:1;
};
int fs_get_info(struct cmd_context *cmd, struct logical_volume *lv,
struct fs_info *fsi, int include_mount);
int fs_fsck_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
int fs_reduce_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
uint64_t newsize_bytes);
int fs_extend_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
int fs_mount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi,
int reuse_mount_dir);
int fs_unmount_command(struct cmd_context *cmd, struct logical_volume *lv, struct fs_info *fsi);
#endif

199
lib/device/parse_vpd.c Normal file
View File

@@ -0,0 +1,199 @@
/*
* Copyright (C) 2022 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/device/device.h"
#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <inttypes.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>
#include <limits.h>
#include <dirent.h>
#include <errno.h>
#include <stdbool.h>
#include <assert.h>
/*
* Replace series of spaces with a single _.
*/
int format_t10_id(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
{
int in_space = 0;
int retlen = 0;
int j = 0;
int i;
for (i = 0; i < in_bytes; i++) {
if (!in[i])
break;
if (j >= (out_bytes - 2))
break;
/* skip leading spaces */
if (!retlen && (in[i] == ' '))
continue;
/* replace one or more spaces with _ */
if (in[i] == ' ') {
in_space = 1;
continue;
}
/* spaces are finished so insert _ */
if (in_space) {
out[j++] = '_';
in_space = 0;
retlen++;
}
out[j++] = in[i];
retlen++;
}
return retlen;
}
static int _to_hex(const unsigned char *in, int in_bytes, unsigned char *out, int out_bytes)
{
int off = 0;
int num;
int i;
for (i = 0; i < in_bytes; i++) {
num = sprintf((char *)out + off, "%02x", in[i]);
if (num < 0)
break;
off += num;
if (off + 2 >= out_bytes)
break;
}
return off;
}
#define ID_BUFSIZE 1024
/*
* based on linux kernel function
*/
int parse_vpd_ids(const unsigned char *vpd_data, int vpd_datalen, struct dm_list *ids)
{
char id[ID_BUFSIZE];
unsigned char tmp_str[ID_BUFSIZE];
const unsigned char *d, *cur_id_str;
size_t id_len = ID_BUFSIZE;
int id_size = -1;
uint8_t cur_id_size = 0;
memset(id, 0, ID_BUFSIZE);
for (d = vpd_data + 4;
d < vpd_data + vpd_datalen;
d += d[3] + 4) {
memset(tmp_str, 0, sizeof(tmp_str));
switch (d[1] & 0xf) {
case 0x1:
/* T10 Vendor ID */
cur_id_size = d[3];
if (cur_id_size + 4 > id_len)
cur_id_size = id_len - 4;
cur_id_str = d + 4;
format_t10_id(cur_id_str, cur_id_size, tmp_str, sizeof(tmp_str));
id_size = snprintf(id, ID_BUFSIZE, "t10.%s", tmp_str);
if (id_size < 0)
break;
if (id_size >= ID_BUFSIZE)
id_size = ID_BUFSIZE - 1;
add_wwid(id, 1, ids);
break;
case 0x2:
/* EUI-64 */
cur_id_size = d[3];
cur_id_str = d + 4;
switch (cur_id_size) {
case 8:
_to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
break;
case 12:
_to_hex(cur_id_str, 12, tmp_str, sizeof(tmp_str));
id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
break;
case 16:
_to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
id_size = snprintf(id, ID_BUFSIZE, "eui.%s", tmp_str);
break;
default:
break;
}
if (id_size < 0)
break;
if (id_size >= ID_BUFSIZE)
id_size = ID_BUFSIZE - 1;
add_wwid(id, 2, ids);
break;
case 0x3:
/* NAA */
cur_id_size = d[3];
cur_id_str = d + 4;
switch (cur_id_size) {
case 8:
_to_hex(cur_id_str, 8, tmp_str, sizeof(tmp_str));
id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
break;
case 16:
_to_hex(cur_id_str, 16, tmp_str, sizeof(tmp_str));
id_size = snprintf(id, ID_BUFSIZE, "naa.%s", tmp_str);
break;
default:
break;
}
if (id_size < 0)
break;
if (id_size >= ID_BUFSIZE)
id_size = ID_BUFSIZE - 1;
add_wwid(id, 3, ids);
break;
case 0x8:
/* SCSI name string */
cur_id_size = d[3];
cur_id_str = d + 4;
if (cur_id_size >= id_len)
cur_id_size = id_len - 1;
memcpy(id, cur_id_str, cur_id_size);
id_size = cur_id_size;
/*
* Not in the kernel version, copying multipath code,
* which checks if this string begins with naa or eui
* and if so does tolower() on the chars.
*/
if (!strncmp(id, "naa.", 4) || !strncmp(id, "eui.", 4)) {
int i;
for (i = 0; i < id_size; i++)
id[i] = tolower(id[i]);
}
add_wwid(id, 8, ids);
break;
default:
break;
}
}
return id_size;
}

View File

@@ -1,86 +0,0 @@
/*
* Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/filters/filter.h"
static DM_LIST_INIT(_allow_devs);
int internal_filter_allow(struct dm_pool *mem, struct device *dev)
{
struct device_list *devl;
if (!(devl = dm_pool_alloc(mem, sizeof(*devl)))) {
log_error("device_list element allocation failed");
return 0;
}
devl->dev = dev;
dm_list_add(&_allow_devs, &devl->list);
return 1;
}
void internal_filter_clear(void)
{
dm_list_init(&_allow_devs);
}
static int _passes_internal(struct cmd_context *cmd, struct dev_filter *f __attribute__((unused)),
struct device *dev, const char *use_filter_name)
{
struct device_list *devl;
dev->filtered_flags &= ~DEV_FILTERED_INTERNAL;
if (!internal_filtering())
return 1;
dm_list_iterate_items(devl, &_allow_devs) {
if (devl->dev == dev)
return 1;
}
dev->filtered_flags |= DEV_FILTERED_INTERNAL;
log_debug_devs("%s: Skipping for internal filtering.", dev_name(dev));
return 0;
}
static void _destroy(struct dev_filter *f)
{
if (f->use_count)
log_error(INTERNAL_ERROR "Destroying internal filter while in use %u times.", f->use_count);
free(f);
}
struct dev_filter *internal_filter_create(void)
{
struct dev_filter *f;
if (!(f = zalloc(sizeof(*f)))) {
log_error("md filter allocation failed");
return NULL;
}
f->passes_filter = _passes_internal;
f->destroy = _destroy;
f->use_count = 0;
f->name = "internal";
log_debug_devs("Internal filter initialised.");
return f;
}

View File

@@ -99,14 +99,6 @@ static int _passes_md_filter(struct cmd_context *cmd, struct dev_filter *f __att
return 1;
ret = dev_is_md_component(cmd, dev, NULL, cmd->use_full_md_check);
if (ret == -EAGAIN) {
/* let pass, call again after scan */
dev->flags |= DEV_FILTER_AFTER_SCAN;
log_debug_devs("filter md deferred %s", dev_name(dev));
return 1;
}
if (ret == 0)
return 1;

View File

@@ -15,18 +15,41 @@
#include "base/memory/zalloc.h"
#include "lib/misc/lib.h"
#include "lib/filters/filter.h"
#include "lib/device/device_id.h"
#ifdef __linux__
#include <dirent.h>
static int _lvmdevices_update_msg;
static int _ignore_mpath_component(struct cmd_context *cmd, struct dev_filter *f, struct device *dev, const char *use_filter_name)
{
dev_t mpath_devno = 0;
dev->filtered_flags &= ~DEV_FILTERED_MPATH_COMPONENT;
if (dev_is_mpath_component(cmd, dev)) {
if (dev_is_mpath_component(cmd, dev, &mpath_devno)) {
log_debug_devs("%s: Skipping mpath component device", dev_name(dev));
dev->filtered_flags |= DEV_FILTERED_MPATH_COMPONENT;
/*
* Warn about misconfig where an mpath component is
* in the devices file, but its mpath device is not.
*/
if ((dev->flags & DEV_MATCHED_USE_ID) && mpath_devno) {
if (!get_du_for_devno(cmd, mpath_devno)) {
struct device *mpath_dev = dev_cache_get_by_devt(cmd, mpath_devno);
log_warn("WARNING: devices file is missing %s (%d:%d) using multipath component %s.",
mpath_dev ? dev_name(mpath_dev) : "unknown",
(int)MAJOR(mpath_devno), (int)MINOR(mpath_devno), dev_name(dev));
if (!_lvmdevices_update_msg && strcmp(get_cmd_name(), "lvmdevices")) {
log_warn("See lvmdevices --update for devices file update.");
_lvmdevices_update_msg = 1;
}
}
}
return 0;
}

View File

@@ -30,14 +30,6 @@ static int _passes_partitioned_filter(struct cmd_context *cmd, struct dev_filter
dev->filtered_flags &= ~DEV_FILTERED_PARTITIONED;
ret = dev_is_partitioned(cmd, dev);
if (ret == -EAGAIN) {
/* let pass, call again after scan */
log_debug_devs("filter partitioned deferred %s", dev_name(dev));
dev->flags |= DEV_FILTER_AFTER_SCAN;
return 1;
}
if (ret) {
if (dev->ext.src == DEV_EXT_NONE)
log_debug_devs(MSG_SKIPPING, dev_name(dev));

View File

@@ -109,8 +109,6 @@ static int _lookup_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
/* Uncached, check filters and cache the result */
if (!l) {
dev->flags &= ~DEV_FILTER_AFTER_SCAN;
pass = pf->real->passes_filter(cmd, pf->real, dev, use_filter_name);
if (!pass) {
@@ -120,21 +118,13 @@ static int _lookup_p(struct cmd_context *cmd, struct dev_filter *f, struct devic
* because the deferred result won't change the exclude.
*/
l = PF_BAD_DEVICE;
} else if ((pass == -EAGAIN) || (dev->flags & DEV_FILTER_AFTER_SCAN)) {
/*
* When the filter result is deferred, we let the device
* pass for now, but do not cache the result. We need to
* rerun the filters later. At that point the final result
* will be cached.
*/
log_debug_devs("filter cache deferred %s", dev_name(dev));
dev->flags |= DEV_FILTER_AFTER_SCAN;
pass = 1;
goto out;
} else if (pass) {
} else if (pass == 1) {
l = PF_GOOD_DEVICE;
} else {
log_error("Ignore invalid filter result %d %s", pass, dev_name(dev));
pass = 1;
/* don't cache invalid result */
goto out;
}
if (!dev->filtered_flags) /* skipping reason already logged by filter */

View File

@@ -33,13 +33,6 @@ static int _ignore_signature(struct cmd_context *cmd, struct dev_filter *f __att
dev->filtered_flags &= ~DEV_FILTERED_SIGNATURE;
if (!scan_bcache) {
/* let pass, call again after scan */
log_debug_devs("filter signature deferred %s", dev_name(dev));
dev->flags |= DEV_FILTER_AFTER_SCAN;
return 1;
}
memset(buf, 0, BUFSIZE);
if (!dev_read_bytes(dev, 0, BUFSIZE, buf)) {

View File

@@ -32,10 +32,6 @@ struct dev_filter *sysfs_filter_create(void);
struct dev_filter *signature_filter_create(struct dev_types *dt);
struct dev_filter *deviceid_filter_create(struct cmd_context *cmd);
struct dev_filter *internal_filter_create(void);
int internal_filter_allow(struct dm_pool *mem, struct device *dev);
void internal_filter_clear(void);
/*
* patterns must be an array of strings of the form:
* [ra]<sep><regex><sep>, eg,

View File

@@ -459,7 +459,6 @@ static int _scan_dev_open(struct device *dev)
const char *name;
const char *modestr;
struct stat sbuf;
int retried = 0;
int flags = 0;
int fd, di;
@@ -479,14 +478,23 @@ static int _scan_dev_open(struct device *dev)
return 0;
}
next_name:
/*
* All the names for this device (major:minor) are kept on
* dev->aliases, the first one is the primary/preferred name.
*
* The default name preferences in dev-cache mean that the first
* name in dev->aliases is not a symlink for scsi devices, but is
* the /dev/mapper/ symlink for mpath devices.
*
* If preferred names are set to symlinks, should this
* first attempt to open using a non-symlink?
*
* dm_list_first() returns NULL if the list is empty.
*/
if (!(name_list = dm_list_first(&dev->aliases))) {
/* Shouldn't happen */
log_error("Device open %s %d:%d has no path names.",
dev_name(dev), (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
log_error("Device open %d:%d has no path names.",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev));
return 0;
}
name_sl = dm_list_item(name_list, struct dm_str_list);
@@ -514,50 +522,34 @@ static int _scan_dev_open(struct device *dev)
modestr = "ro";
}
retry_open:
fd = open(name, flags, 0777);
if (fd < 0) {
if ((errno == EBUSY) && (flags & O_EXCL)) {
log_error("Can't open %s exclusively. Mounted filesystem?",
dev_name(dev));
return 0;
} else {
int major, minor;
/*
* Shouldn't happen, if it does, print stat info to help figure
* out what's wrong.
* drop name from dev->aliases and use verify_aliases to
* drop any other invalid aliases before retrying open with
* any remaining valid paths.
*/
major = (int)MAJOR(dev->dev);
minor = (int)MINOR(dev->dev);
log_error("Device open %s %d:%d failed errno %d", name, major, minor, errno);
if (stat(name, &sbuf)) {
log_debug_devs("Device open %s %d:%d stat failed errno %d",
name, major, minor, errno);
} else if (sbuf.st_rdev != dev->dev) {
log_debug_devs("Device open %s %d:%d stat %d:%d does not match.",
name, major, minor,
(int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
}
if (!retried) {
/*
* FIXME: remove this, the theory for this retry is that
* there may be a udev race that we can sometimes mask by
* retrying. This is here until we can figure out if it's
* needed and if so fix the real problem.
*/
usleep(5000);
log_debug_devs("Device open %s retry", dev_name(dev));
retried = 1;
goto retry_open;
}
log_debug("Drop alias for %d:%d failed open %s (%d)",
(int)MAJOR(dev->dev), (int)MINOR(dev->dev), name, errno);
dev_cache_failed_path(dev, name);
dev_cache_verify_aliases(dev);
goto next_name;
}
return 0;
}
/* Verify that major:minor from the path still match dev. */
if ((fstat(fd, &sbuf) < 0) || (sbuf.st_rdev != dev->dev)) {
log_warn("Invalid path %s for device %d:%d, trying different path.",
name, (int)MAJOR(dev->dev), (int)MINOR(dev->dev));
(void)close(fd);
dev_cache_failed_path(dev, name);
dev_cache_verify_aliases(dev);
goto next_name;
}
dev->flags |= DEV_IN_BCACHE;
@@ -605,37 +597,6 @@ static int _scan_dev_close(struct device *dev)
return 1;
}
static void _drop_bad_aliases(struct device *dev)
{
struct dm_str_list *strl, *strl2;
const char *name;
struct stat sbuf;
int major = (int)MAJOR(dev->dev);
int minor = (int)MINOR(dev->dev);
int bad;
dm_list_iterate_items_safe(strl, strl2, &dev->aliases) {
name = strl->str;
bad = 0;
if (stat(name, &sbuf)) {
bad = 1;
log_debug_devs("Device path check %d:%d %s stat failed errno %d",
major, minor, name, errno);
} else if (sbuf.st_rdev != dev->dev) {
bad = 1;
log_debug_devs("Device path check %d:%d %s stat %d:%d does not match.",
major, minor, name,
(int)MAJOR(sbuf.st_rdev), (int)MINOR(sbuf.st_rdev));
}
if (bad) {
log_debug_devs("Device path check %d:%d dropping path %s.", major, minor, name);
dev_cache_failed_path(dev, name);
}
}
}
// Like bcache_invalidate, only it throws any dirty data away if the
// write fails.
static void _invalidate_di(struct bcache *cache, int di)
@@ -663,10 +624,8 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
char headers_buf[HEADERS_BUF_SIZE];
struct dm_list wait_devs;
struct dm_list done_devs;
struct dm_list reopen_devs;
struct device_list *devl, *devl2;
struct block *bb;
int retried_open = 0;
int scan_read_errors = 0;
int scan_process_errors = 0;
int scan_failed_count = 0;
@@ -677,7 +636,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
dm_list_init(&wait_devs);
dm_list_init(&done_devs);
dm_list_init(&reopen_devs);
log_debug_devs("Scanning %d devices for VG info", dm_list_size(devs));
@@ -701,9 +659,9 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
if (!_in_bcache(devl->dev)) {
if (!_scan_dev_open(devl->dev)) {
log_debug_devs("Scan failed to open %s.", dev_name(devl->dev));
log_debug_devs("Scan failed to open %d:%d %s.",
(int)MAJOR(devl->dev->dev), (int)MINOR(devl->dev->dev), dev_name(devl->dev));
dm_list_del(&devl->list);
dm_list_add(&reopen_devs, &devl->list);
devl->dev->flags |= DEV_SCAN_NOT_READ;
continue;
}
@@ -787,41 +745,6 @@ static int _scan_list(struct cmd_context *cmd, struct dev_filter *f,
if (!dm_list_empty(devs))
goto scan_more;
/*
* We're done scanning all the devs. If we failed to open any of them
* the first time through, refresh device paths and retry. We failed
* to open the devs on the reopen_devs list.
*
* FIXME: it's not clear if or why this helps.
*/
if (!dm_list_empty(&reopen_devs)) {
if (retried_open) {
/* Don't try again. */
scan_failed_count += dm_list_size(&reopen_devs);
dm_list_splice(&done_devs, &reopen_devs);
goto out;
}
retried_open = 1;
dm_list_iterate_items_safe(devl, devl2, &reopen_devs) {
_drop_bad_aliases(devl->dev);
if (dm_list_empty(&devl->dev->aliases)) {
log_warn("WARNING: Scan ignoring device %d:%d with no paths.",
(int)MAJOR(devl->dev->dev),
(int)MINOR(devl->dev->dev));
dm_list_del(&devl->list);
lvmcache_del_dev(devl->dev);
scan_failed_count++;
}
}
/* Put devs that failed to open back on the original list to retry. */
dm_list_splice(devs, &reopen_devs);
goto scan_more;
}
out:
log_debug_devs("Scanned devices: read errors %d process errors %d failed %d",
scan_read_errors, scan_process_errors, scan_failed_count);
@@ -1180,7 +1103,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
dm_list_iterate_items_safe(devl, devl2, &devs) {
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
log_print("%s excluded by filters: %s.",
log_print("%s excluded: %s.",
dev_name(devl->dev), dev_filtered_reason(devl->dev));
dm_list_del(&devl->list);
dm_list_add(&devs_drop, &devl->list);
@@ -1246,7 +1169,7 @@ int label_scan_vg_online(struct cmd_context *cmd, const char *vgname,
/* Applies all filters, including those that need data from dev. */
if (!cmd->filter->passes_filter(cmd, cmd->filter, devl->dev, NULL)) {
log_print("%s excluded by filters: %s.",
log_print("%s excluded: %s.",
dev_name(devl->dev), dev_filtered_reason(devl->dev));
dm_list_del(&devl->list);
dm_list_add(&devs_drop, &devl->list);
@@ -1738,9 +1661,11 @@ void label_scan_invalidate_lvs(struct cmd_context *cmd, struct dm_list *lvs)
dev_t devt;
/*
* FIXME: this is all unnecessary unless there are PVs stacked on LVs,
* so we can skip all of this if scan_lvs=0.
* This is only needed when the command sees PVs stacked on LVs which
* will only happen with scan_lvs=1.
*/
if (!cmd->scan_lvs)
return;
log_debug("invalidating devs for any pvs on lvs");
if (get_device_list(NULL, &devs, &devs_features)) {

View File

@@ -577,8 +577,9 @@ static int _extend_sanlock_lv(struct cmd_context *cmd, struct volume_group *vg,
(uint32_t)(new_size_sectors * SECTOR_SIZE));
lp.size = new_size_sectors;
lp.pvh = &vg->pvs;
if (!lv_resize(lv, &lp, &vg->pvs)) {
if (!lv_resize(cmd, lv, &lp)) {
log_error("Extend sanlock LV %s to size %s failed.",
display_lvname(lv), display_size(cmd, lp.size));
return 0;
@@ -2733,6 +2734,9 @@ int lockd_lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
if (!_lvmlockd_connected)
return 0;
if (lv_is_lockd_sanlock_lv(lv))
return 1;
/*
* A special case for gfs2 where we want to allow lvextend
* of an LV that has an existing shared lock, which is normally

File diff suppressed because it is too large Load Diff

View File

@@ -297,6 +297,9 @@
int lv_layout_and_role(struct dm_pool *mem, const struct logical_volume *lv,
struct dm_list **layout, struct dm_list **role);
int lv_is_linear(struct logical_volume *lv);
int lv_is_striped(struct logical_volume *lv);
/* Ordered list - see lv_manip.c */
typedef enum {
AREA_UNASSIGNED,
@@ -661,50 +664,44 @@ struct pvcreate_params {
};
struct lvresize_params {
int argc;
char **argv;
const char *vg_name; /* only-used when VG is not yet opened (in /tools) */
const char *lv_name;
const struct segment_type *segtype;
uint64_t poolmetadata_size;
sign_t poolmetadata_sign;
/* Per LV applied parameters */
enum {
LV_ANY = 0,
LV_REDUCE = 1,
LV_EXTEND = 2
} resize;
int use_policies;
alloc_policy_t alloc;
int yes;
int force;
int nosync;
int nofsck;
int resizefs;
int use_policies;
char fsopt[32]; /* set by --resizefs|--fs, empty for --fs ignore */
const struct segment_type *segtype;
unsigned mirrors;
uint32_t stripes;
uint64_t stripe_size;
uint32_t extents;
uint64_t size;
uint32_t extents;
sign_t sign;
percent_type_t percent;
percent_type_t percent; /* the type of percentage, not a value */
uint32_t percent_value; /* 0 - 100 */
uint64_t poolmetadata_size;
sign_t poolmetadata_sign;
uint32_t policy_percent_main;
uint32_t policy_percent_meta;
int approx_alloc;
int extents_are_pes; /* Is 'extents' counting PEs or LEs? */
int size_changed; /* Was there actually a size change */
int extend_fs_error; /* FS extend error after LV extend success */
const char *lockopt;
char *lockd_lv_refresh_path; /* set during resize to use for refresh at the end */
char *lockd_lv_refresh_uuid; /* set during resize to use for refresh at the end */
struct dm_list *pvh; /* list of pvs to use */
};
void pvcreate_params_set_defaults(struct pvcreate_params *pp);
@@ -745,9 +742,10 @@ int vgs_are_compatible(struct cmd_context *cmd,
struct volume_group *vg_to);
uint32_t vg_lock_newname(struct cmd_context *cmd, const char *vgname);
int lv_resize(struct logical_volume *lv,
struct lvresize_params *lp,
struct dm_list *pvh);
int lv_resize(struct cmd_context *cmd, struct logical_volume *lv,
struct lvresize_params *lp);
int lv_extend_policy_calculate_percent(struct logical_volume *lv,
uint32_t *amount, uint32_t *meta_amount);
struct volume_group *vg_read(struct cmd_context *cmd, const char *vg_name, const char *vgid,
uint32_t read_flags, uint32_t lockd_state,

View File

@@ -4533,7 +4533,7 @@ void vg_write_commit_bad_mdas(struct cmd_context *cmd, struct volume_group *vg)
* reread metadata.
*/
static bool _scan_text_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid)
bool scan_text_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid)
{
DM_LIST_INIT(mda_list);
struct mda_list *mdal, *safe;
@@ -4706,7 +4706,7 @@ static struct volume_group *_vg_read(struct cmd_context *cmd,
* probably unnecessary; all commands could likely just check a single mda.
*/
if (lvmcache_scan_mismatch(cmd, vgname, vgid) || _scan_text_mismatch(cmd, vgname, vgid)) {
if (lvmcache_scan_mismatch(cmd, vgname, vgid) || scan_text_mismatch(cmd, vgname, vgid)) {
log_debug_metadata("Rescanning devices for %s %s", vgname, writing ? "rw" : "");
if (writing)
lvmcache_label_rescan_vg_rw(cmd, vgname, vgid);
@@ -5302,3 +5302,15 @@ int get_visible_lvs_using_pv(struct cmd_context *cmd, struct volume_group *vg, s
return 1;
}
int lv_is_linear(struct logical_volume *lv)
{
struct lv_segment *seg = first_seg(lv);
return segtype_is_linear(seg->segtype);
}
int lv_is_striped(struct logical_volume *lv)
{
struct lv_segment *seg = first_seg(lv);
return segtype_is_striped(seg->segtype);
}

View File

@@ -538,5 +538,7 @@ void set_pv_devices(struct format_instance *fid, struct volume_group *vg);
int get_visible_lvs_using_pv(struct cmd_context *cmd, struct volume_group *vg, struct device *dev,
struct dm_list *lvs_list);
bool scan_text_mismatch(struct cmd_context *cmd, const char *vgname, const char *vgid);
#endif

View File

@@ -737,6 +737,7 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
extents = MAX_SIZE;
if (!lv) {
log_debug("Adding new pool metadata spare %u extents.", extents);
if (!_alloc_pool_metadata_spare(vg, extents, pvh))
return_0;
@@ -746,6 +747,8 @@ int handle_pool_metadata_spare(struct volume_group *vg, uint32_t extents,
seg = last_seg(lv);
seg_mirrors = lv_mirror_count(lv);
log_debug("Extending pool metadata spare from %u to %u extents.",
lv->le_count, extents);
/* Check spare LV is big enough and preserve segtype */
if ((lv->le_count < extents) && seg &&
!lv_extend(lv, seg->segtype,

View File

@@ -126,6 +126,8 @@ lvchange \(em Change the attributes of logical volume(s)
\fB--sysinit\fP
.br
\fB-t\fP|\fB--test\fP
.br
\fB--vdosettings\fP \fIString\fP
.br
\fB-v\fP|\fB--verbose\fP
.br
@@ -202,6 +204,8 @@ required, after which the others are optional.
\fB--\fP[\fBraid\fP]\fBminrecoveryrate\fP \fISize\fP[k|UNIT]
.br
\fB--\fP[\fBraid\fP]\fBmaxrecoveryrate\fP \fISize\fP[k|UNIT]
.br
\fB--vdosettings\fP \fIString\fP
.br
\fB--\fP[\fBraid\fP]\fBwritebehind\fP \fINumber\fP
.br
@@ -545,12 +549,13 @@ See \fBlvmcache\fP(7) for more information.
.HP
\fB--cachesettings\fP \fIString\fP
.br
Specifies tunable values for a cache LV in "Key = Value" form.
Repeat this option to specify multiple values.
(The default values should usually be adequate.)
The special string value \fBdefault\fP switches
settings back to their default kernel values and removes
them from the list of settings stored in LVM metadata.
Specifies tunable kernel options for dm-cache or dm-writecache LVs.
Use the form 'option=value' or 'option1=value option2=value', or
repeat --cachesettings for each option being set.
These settings override the default kernel behaviors which are
usually adequate. To remove cachesettings and revert to the default
kernel behaviors, use --cachesettings 'default' for dm-cache or
an empty string --cachesettings '' for dm-writecache.
See \fBlvmcache\fP(7) for more information.
.
.HP
@@ -609,8 +614,9 @@ See \fBlvm.conf\fP(5) for more information about profiles.
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -752,7 +758,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP
@@ -927,6 +934,17 @@ error messages in multi-stage operations if a tool relies on reading
back metadata it believes has changed but hasn't.
.
.HP
\fB--vdosettings\fP \fIString\fP
.br
Specifies tunable VDO options for VDO LVs.
Use the form 'option=value' or 'option1=value option2=value', or
repeat --vdosettings for each option being set.
These settings override the default VDO behaviors.
To remove vdosettings and revert to the default
VDO behaviors, use --vdosettings 'default'.
See \fBlvmvdo\fP(7) for more information.
.
.HP
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail

View File

@@ -155,6 +155,8 @@ lvconvert \(em Change logical volume layout
\fB--usepolicies\fP
.br
\fB--vdopool\fP \fILV\fP
.br
\fB--vdosettings\fP \fIString\fP
.br
\fB-v\fP|\fB--verbose\fP
.br
@@ -742,6 +744,8 @@ Convert LV to type vdopool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
[ \fB--vdosettings\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -1064,12 +1068,13 @@ The name of a cache pool.
.HP
\fB--cachesettings\fP \fIString\fP
.br
Specifies tunable values for a cache LV in "Key = Value" form.
Repeat this option to specify multiple values.
(The default values should usually be adequate.)
The special string value \fBdefault\fP switches
settings back to their default kernel values and removes
them from the list of settings stored in LVM metadata.
Specifies tunable kernel options for dm-cache or dm-writecache LVs.
Use the form 'option=value' or 'option1=value option2=value', or
repeat --cachesettings for each option being set.
These settings override the default kernel behaviors which are
usually adequate. To remove cachesettings and revert to the default
kernel behaviors, use --cachesettings 'default' for dm-cache or
an empty string --cachesettings '' for dm-writecache.
See \fBlvmcache\fP(7) for more information.
.
.HP
@@ -1131,8 +1136,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage.
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -1303,7 +1309,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP
@@ -1535,6 +1542,17 @@ The name of a VDO pool LV.
See \fBlvmvdo\fP(7) for more information about VDO usage.
.
.HP
\fB--vdosettings\fP \fIString\fP
.br
Specifies tunable VDO options for VDO LVs.
Use the form 'option=value' or 'option1=value option2=value', or
repeat --vdosettings for each option being set.
These settings override the default VDO behaviors.
To remove vdosettings and revert to the default
VDO behaviors, use --vdosettings 'default'.
See \fBlvmvdo\fP(7) for more information.
.
.HP
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
@@ -1808,6 +1826,8 @@ Convert LV to type vdopool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
[ \fB--vdosettings\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE

View File

@@ -157,6 +157,8 @@ lvcreate \(em Create a logical volume
\fB--vdo\fP
.br
\fB--vdopool\fP \fILV\fP
.br
\fB--vdosettings\fP \fIString\fP
.br
\fB-v\fP|\fB--verbose\fP
.br
@@ -537,6 +539,8 @@ Create a LV that returns VDO when used.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
[ \fB--vdosettings\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -927,12 +931,13 @@ The name of a cache pool.
.HP
\fB--cachesettings\fP \fIString\fP
.br
Specifies tunable values for a cache LV in "Key = Value" form.
Repeat this option to specify multiple values.
(The default values should usually be adequate.)
The special string value \fBdefault\fP switches
settings back to their default kernel values and removes
them from the list of settings stored in LVM metadata.
Specifies tunable kernel options for dm-cache or dm-writecache LVs.
Use the form 'option=value' or 'option1=value option2=value', or
repeat --cachesettings for each option being set.
These settings override the default kernel behaviors which are
usually adequate. To remove cachesettings and revert to the default
kernel behaviors, use --cachesettings 'default' for dm-cache or
an empty string --cachesettings '' for dm-writecache.
See \fBlvmcache\fP(7) for more information.
.
.HP
@@ -1003,8 +1008,9 @@ See \fBlvmvdo\fP(7) for more information about VDO usage.
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -1190,7 +1196,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosync\fP
@@ -1438,6 +1445,17 @@ The name of a VDO pool LV.
See \fBlvmvdo\fP(7) for more information about VDO usage.
.
.HP
\fB--vdosettings\fP \fIString\fP
.br
Specifies tunable VDO options for VDO LVs.
Use the form 'option=value' or 'option1=value option2=value', or
repeat --vdosettings for each option being set.
These settings override the default VDO behaviors.
To remove vdosettings and revert to the default
VDO behaviors, use --vdosettings 'default'.
See \fBlvmvdo\fP(7) for more information.
.
.HP
\fB-v\fP|\fB--verbose\fP ...
.br
Set verbose level. Repeat from 1 to 4 times to increase the detail
@@ -1966,6 +1984,8 @@ Create a VDO LV with VDO pool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
[ \fB--vdosettings\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -1996,6 +2016,8 @@ Create a VDO LV with VDO pool.
.br
[ \fB--deduplication\fP \fBy\fP|\fBn\fP ]
.br
[ \fB--vdosettings\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE

View File

@@ -186,8 +186,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -278,7 +279,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -328,8 +328,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -423,7 +424,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosync\fP

View File

@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -254,7 +255,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -115,8 +115,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -181,7 +182,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--polloperation\fP \fBpvmove\fP|\fBconvert\fP|\fBmerge\fP|\fBmerge_thin\fP

View File

@@ -156,8 +156,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -261,7 +262,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -85,6 +85,7 @@ is used for dm crypt devices, reported by sysfs.
.IP \[bu] 2
.B md_uuid
is used for md devices, reported by sysfs.
.IP \[bu] 2
.B lvmlv_uuid
is used if a PV is placed on top of an lvm LV, reported by sysfs.
.IP \[bu] 2

View File

@@ -24,7 +24,7 @@ lvmdevices \(em Manage the devices file
.br
\fB-d\fP|\fB--debug\fP
.br
\fB--deldev\fP \fIPV\fP
\fB--deldev\fP \fIString\fP
.br
\fB--delpvid\fP \fIString\fP
.br
@@ -152,6 +152,7 @@ is used for dm crypt devices, reported by sysfs.
.IP \[bu] 2
.B md_uuid
is used for md devices, reported by sysfs.
.IP \[bu] 2
.B lvmlv_uuid
is used if a PV is placed on top of an lvm LV, reported by sysfs.
.IP \[bu] 2
@@ -226,10 +227,12 @@ Add a device to the devices file.
Remove a device from the devices file.
.br
.P
\fBlvmdevices\fP \fB--deldev\fP \fIPV\fP
\fBlvmdevices\fP \fB--deldev\fP \fIString\fP|\fIPV\fP
.br
.RS 4
.ad l
[ \fB--deviceidtype\fP \fIString\fP ]
.br
[ COMMON_OPTIONS ]
.ad b
.RE
@@ -346,9 +349,11 @@ Set debug level. Repeat from 1 to 6 times to increase the detail of
messages sent to the log file and/or syslog (if configured).
.
.HP
\fB--deldev\fP \fIPV\fP
\fB--deldev\fP \fIString\fP
.br
Remove a device from the devices file.
When used alone, --deldev specifies a device name.
When used with --deviceidtype, --deldev specifies a device id.
.
.HP
\fB--delpvid\fP \fIString\fP
@@ -365,8 +370,9 @@ then it will override the default type that lvm would use.
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -420,7 +426,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -102,8 +102,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -162,7 +163,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -132,6 +132,19 @@ that can keep 100% incompressible data there.
# lvconvert --type vdo-pool -n vdo0 -V10G vg/ExistingLV
.fi
.
.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV
.
Disable or enable the compression and deduplication for VDOPoolLV
(the volume that maintains all VDO LV(s) associated with it).
.P
.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV
.P
.I Example
.nf
# lvchange --compression n vg/vdopool0
# lvchange --deduplication y vg/vdopool1
.fi
.
.SS \n+[step]. Change the default settings used for creating a VDOPoolLV
.
VDO allows to set a large variety of options. Lots of these settings
@@ -173,17 +186,27 @@ EOF
# lvcreate --vdo -L10G --config 'allocation/vdo_cpu_threads=4' vg/vdopool1
.fi
.
.SS \n+[step]. Change the compression and deduplication of a VDOPoolLV
.SS \n+[step]. Set or change VDO settings with option --vdosettings
.
Disable or enable the compression and deduplication for VDOPoolLV
(the volume that maintains all VDO LV(s) associated with it).
.P
.B lvchange --compression y|n --deduplication y|n VG/VDOPoolLV
Use the form 'option=value' or 'option1=value option2=value',
or repeat --vdosettings for each option being set.
Options are listed in the Example section above, for the full description see
.BR lvm.conf (5).
Options can omit 'vdo_' and 'vdo_use_' prefixes and all its underscores.
So i.e. vdo_use_metadata_hints=1 and metadatahints=1 are equivalent.
To change the option for an already existing VDOPoolLV use
.BR lvchange (8)
command. However not all option can be changed.
Only compression and deduplication options can be also changed for an active VDO LV.
Lowest priority options are specified with configuration file,
then with --vdosettings and highest are expliction option --compression
and --deduplication.
.P
.I Example
.P
.nf
# lvchange --compression n vg/vdopool0
# lvchange --deduplication y vg/vdopool1
# lvcreate --vdo -L10G --vdosettings 'ack_threads=1 hash_zone_threads=2' vg/vdopool0
# lvchange --vdosettings 'bio_threads=2 deduplication=1' vg/vdopool0
.fi
.
.SS \n+[step]. Checking the usage of VDOPoolLV

View File

@@ -130,8 +130,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -220,7 +221,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -136,8 +136,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -204,7 +205,8 @@ metadata/record_lvs_history is enabled.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -120,8 +120,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -175,7 +176,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -286,8 +286,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -376,7 +377,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosync\fP

View File

@@ -172,8 +172,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -264,7 +265,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -119,8 +119,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -180,7 +181,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -179,8 +179,9 @@ multiple tags at once. See \fBlvm\fP(8) for information about tags.
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -248,7 +249,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -351,8 +351,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -435,7 +436,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -229,8 +229,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -319,7 +320,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--norestorefile\fP

View File

@@ -183,8 +183,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -266,7 +267,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -271,7 +272,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -103,8 +103,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -164,7 +165,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -98,8 +98,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -153,7 +154,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -169,8 +169,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -254,7 +255,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -383,8 +383,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -469,7 +470,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -123,8 +123,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -197,7 +198,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -208,8 +208,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -291,7 +292,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -568,8 +568,9 @@ See \fBlvm.conf\fP(5) for more information about profiles.
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -694,7 +695,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -114,8 +114,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -169,7 +170,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -124,8 +124,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -206,7 +207,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -206,8 +206,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -313,7 +314,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB-s\fP|\fB--physicalextentsize\fP \fISize\fP[m|UNIT]

View File

@@ -180,8 +180,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -258,7 +259,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -139,8 +139,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -194,7 +195,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -147,8 +147,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -237,7 +238,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -128,8 +128,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -189,7 +190,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -113,8 +113,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -179,7 +180,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -132,8 +132,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -193,7 +194,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -107,8 +107,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -167,7 +168,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--poolmetadataspare\fP \fBy\fP|\fBn\fP

View File

@@ -108,8 +108,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -169,7 +170,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -199,8 +199,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -265,7 +266,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -109,8 +109,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -170,7 +171,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--noudevsync\fP

View File

@@ -133,8 +133,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -194,7 +195,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--profile\fP \fIString\fP

View File

@@ -166,8 +166,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -251,7 +252,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--nosuffix\fP

View File

@@ -101,8 +101,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -168,7 +169,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--notifydbus\fP

View File

@@ -175,8 +175,9 @@ messages sent to the log file and/or syslog (if configured).
.HP
\fB--devices\fP \fIPV\fP
.br
Devices that the command can use. This option can be repeated
or accepts a comma separated list of devices. This overrides
Restricts the devices that are visible and accessible to the command.
Devices not listed will appear to be missing. This option can be
repeated, or accepts a comma separated list of devices. This overrides
the devices file.
.
.HP
@@ -255,7 +256,8 @@ perform standard hint file invalidation where appropriate.
.HP
\fB--nolocking\fP
.br
Disable locking.
Disable locking. Use with caution, concurrent commands may produce
incorrect results.
.
.HP
\fB--poolmetadataspare\fP \fBy\fP|\fBn\fP

View File

@@ -125,15 +125,6 @@ get_kb_size_with_unit_() {
esac
}
get_mb_size_with_unit_() {
case "$1" in
*[mM]) echo $(( ${1%[mM]} )) ;;
*[gG]) echo $(( ${1%[gG]} * 1024 )) ;;
*[tT]) echo $(( ${1%[tT]} * 1024 * 1024 )) ;;
*[pP]) echo $(( ${1%[pP]} * 1024 * 1024 * 1024 )) ;;
esac
}
# Figure out largest possible extent size usable for VG
# $1 physical size
# $2 logical size
@@ -328,12 +319,12 @@ allocation {
vdo_use_deduplication = $(get_enabled_value_ "$vdo_deduplication")
vdo_use_metadata_hints=1
vdo_minimum_io_size = $vdo_logicalBlockSize
vdo_block_map_cache_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize")
vdo_block_map_cache_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
vdo_block_map_period = $vdo_blockMapPeriod
vdo_check_point_frequency = $vdo_indexCfreq
vdo_use_sparse_index = $(get_enabled_value_ "$vdo_indexSparse")
vdo_index_memory_size_mb = $(awk "BEGIN {print $vdo_indexMemory * 1024}")
vdo_slab_size_mb = $(get_mb_size_with_unit_ "$vdo_blockMapCacheSize")
vdo_slab_size_mb = $(( $(get_kb_size_with_unit_ "$vdo_blockMapCacheSize") / 1024 ))
vdo_ack_threads = $vdo_ackThreads
vdo_bio_threads = $vdo_bioThreads
vdo_bio_rotation = $vdo_bioRotationInterval
@@ -417,7 +408,7 @@ EOF
# Note: that this is spelled OPPOSITE the other $IS_LV checks.
if [ "$IS_LV" = "1" ]; then
verbose "Removing now-unused VDO entry from VDO config."
dry "$VDO" remove $VDOCONF --force --verbose --name "$VDONAME"
dry "$VDO" remove $VDOCONF $VERB --force --name "$VDONAME"
fi
rm -fr "$TEMPDIR"

View File

@@ -369,6 +369,7 @@ LIB = $(addprefix lib/, $(LIB_SECURETEST) $(LIB_DMSECURETEST) $(LIB_SHARED) $(LI
$(Q) $(LN_S) -f $(abs_top_srcdir)/conf/thin-performance.profile lib/
$(Q) $(LN_S) -f $(abs_top_srcdir)/scripts/fsadm.sh lib/fsadm
$(Q) $(LN_S) -f $(abs_top_srcdir)/scripts/lvm_import_vdo.sh lib/lvm_import_vdo
$(Q) which vdo || $(LN_S) -f $(abs_top_srcdir)/test/lib/lvm_vdo_wrapper.sh lib/vdo
@test "$(srcdir)" = . || \
for i in $(LIB_LVMLOCKD_CONF) $(LIB_MKE2FS_CONF); do \
test -n "$(Q)" || echo "$(LN_S) -f $(abs_top_srcdir)/test/lib/$$i lib/"; \

View File

@@ -23,6 +23,9 @@ import os
g_tmo = 0
# Approx. min size
VDO_MIN_SIZE = mib(8192)
# Prefix on created objects to enable easier clean-up
g_prefix = os.getenv('PREFIX', '')
@@ -37,9 +40,10 @@ pv_device_list = os.getenv('LVM_DBUSD_PV_DEVICE_LIST', None)
# Default is to test all modes
# 0 == Only test fork & exec mode
# 1 == Test both fork & exec & lvm shell mode (default)
# 1 == Only test lvm shell mode
# 2 == Test both fork & exec & lvm shell mode (default)
# Other == Test just lvm shell mode
test_shell = os.getenv('LVM_DBUSD_TEST_MODE', 1)
test_shell = os.getenv('LVM_DBUSD_TEST_MODE', 2)
# LVM binary to use
LVM_EXECUTABLE = os.getenv('LVM_BINARY', '/usr/sbin/lvm')
@@ -149,7 +153,7 @@ def get_objects():
rc[interface].append(proxy)
# At this point we have a full population of everything, we now need to
# prune the the objects if we are filtering PVs with a sub selection.
# prune the objects if we are filtering PVs with a sub selection.
return _prune(rc, pv_device_list), bus
@@ -673,6 +677,20 @@ class TestDbusService(unittest.TestCase):
EOD), vg, LV_BASE_INT)
self._validate_lookup("%s/%s" % (vg.Name, lv_name), lv.object_path)
def test_prop_get(self):
lv_name = lv_n()
vg = self._vg_create().Vg
lv = self._test_lv_create(
vg.LvCreate,
(dbus.String(lv_name), dbus.UInt64(mib(4)),
dbus.Array([], signature='(ott)'), dbus.Int32(g_tmo),
EOD), vg, LV_BASE_INT)
ri = RemoteInterface(lv.dbus_object, interface=LV_COMMON_INT, introspect=False)
ri.update()
for prop_name in ri.get_property_names():
self.assertEqual(ri.get_property_value(prop_name), getattr(ri, prop_name))
def test_lv_create_job(self):
lv_name = lv_n()
vg = self._vg_create().Vg
@@ -882,8 +900,19 @@ class TestDbusService(unittest.TestCase):
j.Remove()
break
else:
# Most of the time we will get this exception as expected, but there is
# a race condition between checking if it's complete and removing it (we want to try to remove while
# it's not complete to raise the exception)
# Thus, we can't reliably use self.assertRaises.
# We have included it here to test this path in the daemon.
try:
j.Remove()
except dbus.exceptions.DBusException:
pass
if j.Wait(1):
self.assertTrue(j.Wait(0))
j.update()
self.assertTrue(j.Complete)
@@ -1096,7 +1125,7 @@ class TestDbusService(unittest.TestCase):
def _test_expired_timer(self, num_lvs):
rc = False
# In small configurations lvm is pretty snappy, so lets create a VG
# In small configurations lvm is pretty snappy, so let's create a VG
# add a number of LVs and then remove the VG and all the contained
# LVs which appears to consistently run a little slow.
@@ -1155,7 +1184,7 @@ class TestDbusService(unittest.TestCase):
return
# This may not pass
for i in [48, 64, 128]:
for i in [128, 256]:
yes = self._test_expired_timer(i)
if yes:
break
@@ -1766,7 +1795,7 @@ class TestDbusService(unittest.TestCase):
self.assertTrue(ec == 0, "%s exit code = %d" % (operation, ec))
def test_external_vg_create(self):
# We need to ensure that if a user creates something outside of lvm
# We need to ensure that if a user creates something outside lvm
# dbus service that things are sequenced correctly so that if a dbus
# user calls into the service they will find the same information.
vg_name = vg_n()
@@ -1779,8 +1808,8 @@ class TestDbusService(unittest.TestCase):
self._verify_existence(cmd, cmd[0], vg_name)
def test_external_lv_create(self):
# Lets create a LV outside of service and see if we correctly handle
# it's inclusion
# Let's create a LV outside of service and see if we correctly handle
# its inclusion
vg = self._vg_create().Vg
lv_name = lv_n()
full_name = "%s/%s" % (vg.Name, lv_name)
@@ -1789,8 +1818,8 @@ class TestDbusService(unittest.TestCase):
self._verify_existence(cmd, cmd[0], full_name)
def test_external_pv_create(self):
# Lets create a PV outside of service and see if we correctly handle
# it's inclusion
# Let's create a PV outside of service and see if we correctly handle
# its inclusion
target = self.objs[PV_INT][0]
# Remove the PV
@@ -1836,7 +1865,7 @@ class TestDbusService(unittest.TestCase):
#
# NOTE: This needs an equivalent of aux extend_filter_LVMTEST
# when run from lvm2 testsuite. See dbustest.sh.
# Also if developing locally with actual devices one can achieve this
# Also, if developing locally with actual devices one can achieve this
# by editing lvm.conf with "devices/scan_lvs = 1" As testing
# typically utilizes loopback, this test is skipped in
# those environments.
@@ -1851,7 +1880,7 @@ class TestDbusService(unittest.TestCase):
pv_object_path = self._create_nested(pv_object_path)
def test_pv_symlinks(self):
# Lets take one of our test PVs, pvremove it, find a symlink to it
# Let's take one of our test PVs, pvremove it, find a symlink to it
# and re-create using the symlink to ensure we return an object
# path to it. Additionally, we will take the symlink and do a lookup
# (Manager.LookUpByLvmId) using it and the original device path to
@@ -1873,7 +1902,7 @@ class TestDbusService(unittest.TestCase):
rc = self._lookup(pv_device_path)
self.assertEqual(rc, '/')
# Lets locate a symlink for it
# Let's locate a symlink for it
devices = glob('/dev/disk/*/*')
rp_pv_device_path = os.path.realpath(pv_device_path)
for d in devices:
@@ -1907,8 +1936,8 @@ class TestDbusService(unittest.TestCase):
vdo_pool_object_path = self.handle_return(
vg_proxy.VgVdo.CreateVdoPoolandLv(
pool_name, lv_name,
dbus.UInt64(mib(4096)), # Appears to be minimum size
dbus.UInt64(mib(8192)),
dbus.UInt64(VDO_MIN_SIZE),
dbus.UInt64(VDO_MIN_SIZE * 2),
dbus.Int32(g_tmo),
EOD))
@@ -1938,7 +1967,7 @@ class TestDbusService(unittest.TestCase):
raise unittest.SkipTest('vdo not supported')
# Do this twice to ensure we are providing the correct flags to force
# the operation when if finds an existing vdo signature, which likely
# the operation when it finds an existing vdo signature, which likely
# shouldn't exist.
for _ in range(0, 2):
vg, _, _ = self._create_vdo_pool_and_lv()
@@ -1950,7 +1979,7 @@ class TestDbusService(unittest.TestCase):
vg_proxy = self._vg_create(vg_prefix="vdo_conv_")
lv = self._test_lv_create(
vg_proxy.Vg.LvCreate,
(dbus.String(pool_name), dbus.UInt64(mib(4096)),
(dbus.String(pool_name), dbus.UInt64(VDO_MIN_SIZE),
dbus.Array([], signature='(ott)'), dbus.Int32(g_tmo),
EOD), vg_proxy.Vg, LV_BASE_INT)
lv_obj_path = self._lookup("%s/%s" % (vg_proxy.Vg.Name, pool_name))
@@ -1959,7 +1988,7 @@ class TestDbusService(unittest.TestCase):
vdo_pool_path = self.handle_return(
vg_proxy.VgVdo.CreateVdoPool(
dbus.ObjectPath(lv.object_path), lv_name,
dbus.UInt64(mib(8192)),
dbus.UInt64(VDO_MIN_SIZE),
dbus.Int32(g_tmo),
EOD))
@@ -2078,15 +2107,19 @@ if __name__ == '__main__':
if mode == 0:
std_err_print('\n*** Testing only lvm fork & exec test mode ***\n')
elif mode == 1:
std_err_print('\n*** Testing only lvm shell mode ***\n')
elif mode == 2:
std_err_print('\n*** Testing fork & exec & lvm shell mode ***\n')
else:
std_err_print('\n*** Testing only lvm shell mode ***\n')
std_err_print("Unsupported \"LVM_DBUSD_TEST_MODE\"=%d, [0-2] valid" % mode)
sys.exit(1)
for g_tmo in [0, 15]:
std_err_print('Testing TMO=%d\n' % g_tmo)
if mode == 0:
if set_execution(False, r):
r.register_result(unittest.main(exit=False))
elif mode == 2:
elif mode == 1:
if set_execution(True, r):
r.register_result(unittest.main(exit=False))
else:

View File

@@ -183,6 +183,7 @@ class RemoteInterface(object):
verify_type(
vl, self.introspect[self.interface]
['properties'][kl]['p_type'])
self.p_name[kl] = True
setattr(self, kl, vl)
@property
@@ -196,6 +197,7 @@ class RemoteInterface(object):
self.interface = interface
self.introspect = introspect
self.tmo = 0
self.p_name = {}
if timelimit >= 0:
self.tmo = float(timelimit)
@@ -213,7 +215,7 @@ class RemoteInterface(object):
def _wrapper(self, _method_name, *args, **kwargs):
# Lets see how long a method takes to execute, in call cases we should
# Let's see how long a method takes to execute, in call cases we should
# return something when the time limit has been reached.
start = time.time()
result = getattr(self.dbus_interface, _method_name)(*args, **kwargs)
@@ -241,6 +243,14 @@ class RemoteInterface(object):
def update(self):
self._set_props()
def get_property_names(self):
return self.p_name.keys()
def get_property_value(self, name):
prop_interface = dbus.Interface(
self.dbus_object, 'org.freedesktop.DBus.Properties')
return prop_interface.Get(self.interface, name)
class ClientProxy(object):

353
test/lib/lvm_vdo_wrapper.sh Executable file
View File

@@ -0,0 +1,353 @@
#!/bin/bash
#
# Wrapper script for 'naive' emulation of vdo manager tool for systems
# that no longer have this tool present
#
set -euE -o pipefail
# tool for formating 'old' VDO metadata format
LVM_VDO_FORMAT=${LVM_VDO_FORMAT-"oldvdoformat"}
# tool for shifting VDO metadata header by 2MiB
LVM_VDO_PREPARE=${LVM_VDO_PREPARE-"oldvdoprepareforlvm"}
# default vdo conf file
LVM_VDO_DEFAULT_CONF=${LVM_VDO_DEFAULT_CONF-"/tmp/vdoconf.yml"}
vdo_die_() {
echo -e "$@" >&2
return 1
}
vdo_verbose_() {
test -z "$vdo_verbose" || echo "$0:" "$@"
}
vdo_dry_() {
if test -n "$vdo_dry"; then
vdo_verbose_ "Dry execution" "$@"
return 0
fi
vdo_verbose_ "Executing" "$@"
"$@"
}
vdo_get_kb_size_with_unit_() {
local sz=${2-1} # 2nd. arg as unit - default 'k'
case "$sz" in
[mM]) sz=1024 ;;
esac
case "$1" in
*[mM]) sz=1024 ;;
*[gG]) sz=$(( 1024 * 1024 )) ;;
*[tT]) sz=$(( 1024 * 1024 * 1024 )) ;;
*[pP]) sz=$(( 1024 * 1024 * 1024 * 1024 )) ;;
esac
echo $(( sz * ${1%[kKmMgGtTpP]} ))
}
#
# Emulate functionality of deprecated 'vdo create'
#
vdo_create_() {
local cachesize=
local devsize=
local emulate512=disabled
local logicalsize=
local maxdiscardsize=
local slabbits=0 # 4k
local slabsize=
local sparse=
local table=
local vdo_compression_msg=
local vdo_dry=
local vdo_index_msg=
local vdo_logicalBlockSize=
local vdo_verbose=
local vdo_ackThreads=${vdo_ackThreads-1}
local vdo_bioRotationInterval=${vdo_bioRotationInterval-64}
local vdo_bioThreads=${vdo_bioThreads-4}
local vdo_blockMapCacheSize=${vdo_blockMapCacheSize-128M}
local vdo_blockMapPeriod=${vdo_blockMapPeriod-16380}
local vdo_compression=${vdo_compression-enabled}
local vdo_confFile=$LVM_VDO_DEFAULT_CONF # place some file in /tmp
local vdo_cpuThreads=${vdo_cpuThreads-2}
local vdo_deduplication=${vdo_deduplication-enabled}
local vdo_hashZoneThreads=${vdo_hashZoneThreads-1}
local vdo_indexCfreq=${vdo_indexCfreq-0}
local vdo_indexMemory=${vdo_indexMemory-0.25}
local vdo_indexSparse=${vdo_indexSparse-disabled}
local vdo_indexThreads=${vdo_indexThreads-0}
local vdo_logicalSize=${vdo_logicalSize-0}
local vdo_logicalThreads=${vdo_logicalThreads-1}
local vdo_maxDiscardSize=${vdo_maxDiscardSize-4K}
local vdo_name=${vdo_name-VDONAME}
local vdo_physicalThreads=${vdo_physicalThreads-1}
local vdo_slabSize=${vdo_slabSize-2G}
local vdo_uuid="VDO-$(uuidgen || echo \"f7a3ecdc-40a0-4e43-814c-4a7039a75de4\")"
local vdo_writePolicy=${vdo_writePolicy-auto}
while [ "$#" -ne 0 ]
do
case "$1" in
"--blockMapCacheSize") shift; vdo_blockMapCacheSize=$1 ;;
"--blockMapPeriod") shift; vdo_blockMapPeriod=$1 ;;
"--compression") shift; vdo_compression=$1 ;;
"--confFile"|"-f") shift; vdo_confFile=$1 ;;
"--deduplication") shift; vdo_deduplication=$1 ;;
"--device") shift; vdo_device=$1 ;;
"--emulate512") shift; emulate512=$1 ;;
"--indexMem") shift; vdo_indexMemory=$1 ;;
"--maxDiscardSize") shift; vdo_maxDiscardSize=$1 ;;
"--name"|"-n") shift; vdo_name=$1 ;;
"--sparseIndex") shift; vdo_indexSparse=$1 ;;
"--uuid") shift ;; # ignored
"--vdoAckThreads") shift; vdo_ackThreads=$1 ;;
"--vdoBioRotationInterval") shift; vdo_bioRotationInterval=$1 ;;
"--vdoBioThreads") shift; vdo_bioThreads=$1 ;;
"--vdoCpuThreads") shift; vdo_cpuThreads=$1 ;;
"--vdoHashZoneThreads") shift; vdo_hashZoneThreads=$1 ;;
"--vdoLogicalSize") shift; vdo_logicalSize=$1 ;;
"--vdoLogicalThreads") shift; vdo_logicalThreads=$1 ;;
"--vdoLogLevel") shift ;; # ignored
"--vdoPhysicalThreads") shift; vdo_physicalSize=$1 ;;
"--vdoSlabSize") shift; vdo_slabSize=$1 ;;
"--verbose"|"-d"|"--debug") vdo_verbose="-v" ;;
"--writePolicy") shift; vdo_writePolicy=$1 ;;
esac
shift
done
# Convert when set
case "$emulate512" in
"enabled") vdo_logicalBlockSize=512 ;;
"disabled") vdo_logicalBlockSize=4096 ;;
*) vdo_die_ "Invalid emulate512 setting."
esac
case "$vdo_deduplication" in
"enabled") vdo_index_msg="index-enable" ;;
"disabled") vdo_index_msg="index-disable";;
*) vdo_die_ "Invalid deduplication setting."
esac
case "$vdo_compression" in
"enabled") vdo_compression_msg="compression on" ;;
"disabled") vdo_compression_msg="compression off";;
*) vdo_die_ "Invalid compression setting."
esac
test -n "${vdo_device-}" || vdo_die_ "VDO device is missing"
blkid -s UUID -o value "${vdo_device}" || true
devsize=$(blockdev --getsize64 "$vdo_device")
devsize=$(( devsize / 4096 )) # convert to 4KiB units
logicalsize=$(vdo_get_kb_size_with_unit_ "$vdo_logicalSize" M)
logicalsize=$(( logicalsize * 2 )) # 512B units
cachesize=$(vdo_get_kb_size_with_unit_ "$vdo_blockMapCacheSize" M)
cachesize=$(( cachesize / 4 )) # 4KiB units
maxdiscardsize=$(vdo_get_kb_size_with_unit_ "$vdo_maxDiscardSize" M)
maxdiscardsize=$(( maxdiscardsize / 4 )) # 4KiB units
test -e "$vdo_confFile" || {
cat > "$vdo_confFile" <<EOF
####################################################################
# THIS FILE IS MACHINE GENERATED. DO NOT EDIT THIS FILE BY HAND.
####################################################################
config: !Configuration
vdos:
EOF
}
cat >> "$vdo_confFile" <<EOF
$vdo_name: !VDOService
_operationState: finished
ackThreads: $vdo_ackThreads
activated: enabled
bioRotationInterval: $vdo_bioRotationInterval
bioThreads: $vdo_bioThreads
blockMapCacheSize: $(( cachesize * 4 ))K
blockMapPeriod: $vdo_blockMapPeriod
compression: $vdo_compression
cpuThreads: $vdo_cpuThreads
deduplication: $vdo_deduplication
device: $vdo_device
hashZoneThreads: $vdo_hashZoneThreads
indexCfreq: $vdo_indexCfreq
indexMemory: $vdo_indexMemory
indexSparse: $vdo_indexSparse
indexThreads: $vdo_indexThreads
logicalBlockSize: $vdo_logicalBlockSize
logicalSize: $(( logicalsize / 2 ))K
logicalThreads: $vdo_logicalThreads
maxDiscardSize: $(( maxdiscardsize * 4 ))K
name: $vdo_name
physicalSize: $(( devsize * 4 ))K
physicalThreads: $vdo_physicalThreads
slabSize: $vdo_slabSize
uuid: $vdo_uuid
writePolicy: $vdo_writePolicy
version: 538380551
EOF
slabsize=$(vdo_get_kb_size_with_unit_ "$vdo_slabSize")
while test "$slabsize" -gt 4 ; do
slabbits=$(( slabbits + 1 ))
slabsize=$(( slabsize / 2 ))
done
case "$vdo_indexSparse" in
"enabled") sparse="--uds-sparse" ;;
esac
vdo_dry_ "$LVM_VDO_FORMAT" $vdo_verbose $sparse\
--logical-size "$vdo_logicalSize" --slab-bits "$slabbits"\
--uds-checkpoint-frequency "$vdo_indexCfreq"\
--uds-memory-size "$vdo_indexMemory" "$vdo_device"
# V2 format
table="0 $logicalsize vdo V2 $vdo_device\
$devsize\
$vdo_logicalBlockSize\
$cachesize\
$vdo_blockMapPeriod\
on\
$vdo_writePolicy\
$vdo_name\
maxDiscard $maxdiscardsize\
ack $vdo_ackThreads\
bio $vdo_bioThreads\
bioRotationInterval $vdo_bioRotationInterval\
cpu $vdo_cpuThreads\
hash $vdo_hashZoneThreads\
logical $vdo_logicalThreads\
physical $vdo_physicalThreads"
vdo_dry_ dmsetup create "$vdo_name" --uuid "$vdo_uuid" --table "$table"
vdo_dry_ dmsetup message "$vdo_name" 0 "$vdo_index_msg"
vdo_dry_ dmsetup message "$vdo_name" 0 "$vdo_compression_msg"
}
#
# vdo stop
#
vdo_stop_() {
local vdo_confFile=$LVM_VDO_DEFAULT_CONF
local vdo_dry=
local vdo_force=
local vdo_name=
local vdo_verbose=
while [ "$#" -ne 0 ]
do
case "$1" in
"--confFile"|"-f") shift; vdo_confFile=$1 ;;
"--name"|"-n") shift; vdo_name=$1 ;;
"--verbose"|"-d"|"--debug") vdo_verbose="-v" ;;
"--force") vdo_force="--force" ;;
esac
shift
done
vdo_dry_ dmsetup status --target vdo "$vdo_name" 2>/dev/null || return 0
vdo_dry_ dmsetup remove $vdo_force "$vdo_name" || true
}
#
# vdo remove
#
vdo_remove_() {
local vdo_confFile=$LVM_VDO_DEFAULT_CONF
local vdo_name=
vdo_stop_ "$@"
while [ "$#" -ne 0 ]
do
case "$1" in
"--confFile"|"-f") shift; vdo_confFile=$1 ;;
"--name"|"-n") shift; vdo_name=$1 ;;
esac
shift
done
# remove entry from conf file
awk -v vdovolname="$vdo_name" 'BEGIN { have=0 }
$0 ~ "!VDOService" { have=0 }
$0 ~ vdovolname":" { have=1 }
{ if (have==0) { print } ;}
' "$vdo_confFile" >"${vdo_confFile}.new"
mv "${vdo_confFile}.new" "$vdo_confFile"
grep "!VDOService" "$vdo_confFile" || rm -f "$vdo_confFile"
}
#
# print_config_file
#
vdo_print_config_file_() {
local vdo_confFile=$LVM_VDO_DEFAULT_CONF
while [ "$#" -ne 0 ]
do
case "$1" in
"--confFile"|"-f") shift; vdo_confFile=$1 ;;
"--verbose"|"-d"|"--debug") ;;
"--logfile") shift ;; # ignore
esac
shift
done
cat "$vdo_confFile"
}
#
# vdo convert
#
vdo_convert_() {
local vdo_confFile=$LVM_VDO_DEFAULT_CONF
local vdo_dry=
local vdo_force=
local vdo_name=
local vdo_verbose=
local vdo_device=
while [ "$#" -ne 0 ]
do
case "$1" in
"--confFile"|"-f") shift; vdo_confFile=$1 ;;
"--name"|"-n") shift; vdo_name=$1 ;;
"--verbose"|"-d"|"--debug") vdo_verbose="-v" ;;
"--force") vdo_force="--force" ;;
esac
shift
done
vdo_device=$(awk -v vdovolname="$vdo_name" 'BEGIN { have=0 }
$0 ~ "!VDOService" { have=0 }
$0 ~ vdovolname":" { have=1 }
{ if (have==1 && $0 ~ "device:" ) { print $2 } ;}'\
"$vdo_confFile")
#dmsetup status --target vdo "$vdo_name" || true
vdo_dry_ "$LVM_VDO_PREPARE" "$vdo_device"
vdo_dry_ vdo_remove_ -f "$vdo_confFile" -n "$vdo_name" || true
}
#
# MAIN
#
case "$1" in
"create") shift; vdo_create_ "$@" ;;
"remove") shift; vdo_remove_ "$@" ;;
"stop") shift; vdo_stop_ "$@" ;;
"convert") shift; vdo_convert_ "$@" ;;
"printConfigFile") shift; vdo_print_config_file_ "$@" ;;
esac

View File

@@ -29,6 +29,12 @@
int main(int argc, const char **argv)
{
if (getuid() != 0) {
std::cout << "Skipping tests, root is required, current UID: " << getuid() << "\n";
return 0;
}
try {
return brick::shelltest::run( argc, argv, "LVM_TEST_FLAVOUR" );
} catch (std::exception const& e) {

View File

@@ -104,6 +104,10 @@ not ls "$DFDIR/system.devices"
vgs --devicesfile test.devices $vg1
not vgs --devicesfile test.devices $vg2
# misspelled override name fails
not vgs --devicesfile doesnotexist $vg1
not vgs --devicesfile doesnotexist $vg2
# devicesfile and devices cannot be used together
not vgs --devicesfile test.devices --devices "$dev1","$dev1" $vg1

View File

@@ -135,6 +135,24 @@ lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
rm $DF
# deldev using idname
lvmdevices --adddev "$LOOP1"
lvmdevices --adddev "$LOOP2"
vgcreate $vg "$LOOP1" "$LOOP2"
IDNAME1=`pvs "$LOOP1" --noheading -o deviceid | awk '{print $1}'`
IDNAME2=`pvs "$LOOP2" --noheading -o deviceid | awk '{print $1}'`
lvmdevices --deldev "$IDNAME2" --deviceidtype loop_file
not grep "$IDNAME2" $DF
not grep "$LOOP2" $DF
lvmdevices --deldev "$IDNAME1" --deviceidtype loop_file
not grep "$IDNAME1" $DF
not grep "$LOOP1" $DF
lvmdevices --adddev "$LOOP1"
lvmdevices --adddev "$LOOP2"
vgremove $vg
rm $DF
# add/delpvid with default idtype loop_file
lvmdevices --addpvid "$PVID1"
@@ -151,6 +169,7 @@ not grep "$PVID1" $DF
lvmdevices --delpvid "$PVID2"
not grep "$LOOP2" $DF
not grep "$PVID2" $DF
rm $DF
# add/deldev with non-default idtype devname
lvmdevices --adddev "$LOOP1" --deviceidtype devname
@@ -165,6 +184,7 @@ lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
rm $DF
# add/delpvid with non-default idtype devname
lvmdevices --addpvid "$PVID1" --deviceidtype devname
@@ -179,6 +199,7 @@ lvmdevices --deldev "$LOOP1"
not grep "$LOOP1" $DF
lvmdevices --deldev "$LOOP2"
not grep "$LOOP2" $DF
rm $DF
# add/deldev when dev is missing, using default idtype
lvmdevices --adddev "$LOOP1"

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